IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 正点原子IIC例程讲解笔记(三)——24cxx.c中函数理解 -> 正文阅读

[嵌入式]正点原子IIC例程讲解笔记(三)——24cxx.c中函数理解

目录

一、24C02 简介

二、在 AT24CXX 指定地址写入一个数据:

三、在ATC24XX指定地址读出一个数据

四、检查AT24CXX是否正常:u8 AT24CXX_Check(void)

五、在 AT24CXX 里面的指定地址开始写入长度为 Len 的数据

六、在 AT24CXX 里面的指定地址开始读出长度为 Len 的数据

七、在 AT24CXX 里面的指定地址开始写入指定个数的数据

八、在 AT24CXX 里面的指定地址开始读出指定个数的数据

一、24C02 简介

????????设备地址:

? ? ? ? ?在IIC开始时,首先由主机设备向从机设备发送其从机设备地址,选择与哪个从机设备进行通讯,24C02作为从机时,地址前四位为1010,转为16进制后为A,后三位在硬件中全部拉低为低电平,用0表示;第八位为读/写选择位,0表示写入,1表示读取;用16进制表示为0xA0或者0xA1;

? ? ? ? 写入时序图:

? ? ? ? ?读取时序图:

二、在 AT24CXX 指定地址写入一个数据:

void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)

函数源码:

void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
{
    IIC_Start();
    if(EE_TYPE>AT24C16)
    {
        IIC_Send_Byte(0XA0); //发送写命令
        IIC_Wait_Ack();
        IIC_Send_Byte(WriteAddr>>8);//发送高地址
    }
    else
    { 
        IIC_Send_Byte(0XA0+((WriteAddr/256)<<1)); //发送器件地址 0XA0,写数据
    }
    IIC_Wait_Ack();
    IIC_Send_Byte(WriteAddr%256); //发送低地址
    IIC_Wait_Ack();
    IIC_Send_Byte(DataToWrite);   //发送字节
    IIC_Wait_Ack();
    IIC_Stop();//产生一个停止条件
    delay_ms(10);                 //EEPROM 写入过程比较慢,需等待一点时间,再写下一次
}

其中:

????????形参 u16 WriteAddr 表示写入数据的目的地址;

????????形参 u8?DataToWrite 表示要写入的数据;

根据24C02的写入时序编写程序,操作步骤如下:

? ? ? ? (1)发送开始START信号

????????(2)发送器件器件地址0XA0,最后一位为0,表示由主机发送数据,从机接收数据;

????????(3)从机检测到主机发送的地址与自己的地址相同时发送一个应答信号ACK;

????????(4)发送待操作的字节地址

????????(5)等待一个ACK信号;

????????(6)发送字节数据;

????????(7)等待一个ACK信号;

????????(8)产生一个停止信号,I2C停止;

? ? ? ? 代码中,首先对设备型号进行了判断,当存储单元大于256个字节的时候,存储地址分两次发送:第一次把地址向左移8位—WriteAddr>>8,发送地址的高8位;第二次将地址与256取余—WriteAddr%256,得到的余数即为低八位的地址(可以随便取两个大于256的数验证一下)。

????????如果设备的存储单元小于256个字节,按照步骤直接发送地址与256的余数(等于地址本身,写成取余数的形式是为了兼容高于256个字节的情况),后面按照步骤一次进行。

三、在ATC24XX指定地址读出一个数据

u8 AT24CXX_ReadOneByte(u16 ReadAddr)

函数源码:

u8 AT24CXX_ReadOneByte(u16 ReadAddr)
{
    u8 temp=0;
    IIC_Start();
    if(EE_TYPE>AT24C16)
    {
        IIC_Send_Byte(0XA0); //发送写命令
        IIC_Wait_Ack();
        IIC_Send_Byte(ReadAddr>>8);//发送高地址
    }
    else
    { 
        IIC_Send_Byte(0XA0+((ReadAddr/256)<<1)); //发送器件地址 0XA0,写数据
    }
    IIC_Wait_Ack();
    IIC_Send_Byte(ReadAddr%256); //发送低地址
    IIC_Wait_Ack();
    IIC_Start();
    IIC_Send_Byte(0XA1); //进入接收模式
    IIC_Wait_Ack();
    temp=IIC_Read_Byte(0);
    IIC_Stop();//产生一个停止条件
    return temp;
}

其中:

? ? ? ? 形参?u16 ReadAddr 为所读字节的地址;

? ? ? ? 返回值 temp 为所要读取地址中的数据;

根据24C02的读取时序编写程序,操作步骤如下:

? ? ? ? (1)发送开始START信号;

????????(2)发送器件器件地址0XA0,最后一位为0,表示由主机发送数据,从机接收数据;

????????(3)从机检测到主机发送的地址与自己的地址相同时发送一个应答信号ACK,而主机等待ACK;

????????(4)发送等待操作的字节地址;

????????(5)等待一个ACK信号;

????????(6)重新发送START起始信号;

????????(7)发送7位器件地址,最后一位为1,表示读EEPROM;

????????(8)等待一个ACK信号;

????????(9)读取指定地址中的一个字节的数据;

????????(10)产生一个停止信号,I2C停止,返回读取的数据;

四、检查AT24CXX是否正常:u8 AT24CXX_Check(void)

函数源码:

u8 AT24CXX_Check(void)
{
    u8 temp;
    temp=AT24CXX_ReadOneByte(255);   //避免每次开机都写 AT24CXX
    if(temp==0X55)return 0;
    else                             //排除第一次初始化的情况
    {
        AT24CXX_WriteOneByte(255,0X55);
        temp=AT24CXX_ReadOneByte(255);
        if(temp==0X55)return 0;
    }
    return 1;
}

? ? ? ? 函数的功能为检查24C02设备是否正常,这里用了24XX的最后一个地址(255)来存储标志字, 返回0表示正常、返回1错误

? ? ? ? 函数首先读取存储设备的第255个存储单元,查看里面的值是否为0x55(可以定义你想要的值),如果是,直接返回;否则,在第255个存储单元写入0x55,然后再读取出来;如果读取成功,则设备正常,读取失败,设备异常;

五、在 AT24CXX 里面的指定地址开始写入长度为 Len 的数据

void AT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len)

函数源码:

void AT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len)
{
    u8 t;
    for(t=0;t<Len;t++)
    {
        AT24CXX_WriteOneByte(WriteAddr+t,(DataToWrite>>(8*t))&0xff);
    }
}

?函数功能:

????????在存储指定地址开始写入长度为Len的数据(Len=2或4);

????????形参?u16 WriteAddr:开始写入的地址;

????????形参?u32 DataToWrite:数据数组首地址;

????????形参?u8 Len:要写入数据的长度,值为2或4;

? ? ? ? 函数中,不管Len的值取多少,都需要将存储的数值拆分成8位来进行存储,先存储低位,后存储高位,通过反复的调用AT24CXX_WriteOneByte()函数来实现;

????????(DataToWrite>>(8*t))&0xff语句中,先将所需要写入的数据DataToWrite根据t的值进行左移8位,然后和0xFF相与,保留低8位的数值并存储到指定地址中;在下一个循环中继续存储高8位的数据;最终实现长度为Len的数据的写入。

六、在 AT24CXX 里面的指定地址开始读出长度为 Len 的数据

u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len)

函数源码:

u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len)
{
    u8 t; 
    u32 temp=0;
    for(t=0;t<Len;t++)
    {
        temp<<=8;
        temp+=AT24CXX_ReadOneByte(ReadAddr+Len-t-1);
    }
    return temp;
}

函数功能:

????????在 AT24CXX 里面的指定地址开始读出长度为 Len 的数据,该函数用于读出 16bit 或者 32bit 的数据;

? ? ? ? 形参 u16 ReadAddr:开始读数的地址;

? ? ? ? 形参?u8 Len:要读出数据的长度;

? ? ? ? 返回值temp:读取的数据;

? ? ? ? 由于数据写入存储单元时是从低8位位开始写入,高位8位数据存储在低8位数据的下一个存储单元,所以在读取的时候先读取高位8位数据;语句 ReadAddr+Len-t-1 求取的就是高位的存储单元的地址;在for循环中以8位位单位依次从高位到到低位进行读数。

七、在 AT24CXX 里面的指定地址开始写入指定个数的数据

void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)

函数源码:

void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
{
    while(NumToWrite--)
    {
        AT24CXX_WriteOneByte(WriteAddr,*pBuffer);
        WriteAddr++; pBuffer++;
    }
}

其中:

? ? ? ? 形参?u16 WriteAddr :开始写入的地址,24C02的地址范围为0-255;

? ? ? ? 形参?u8 *pBuffer:数据数组首地址;

? ? ? ? 形参?u16 NumToWrite:要写入数据的个数;

? ? ? ? 程序中 pBuffer 定义为指针变量,可以将事先定义的数组首地址赋给它,数组所占的字节用sizeof函数可以得到,例如:定义一个u8型数组: u8?a[5] = {0,1,2,3,4},在调用次函数时应该写成:AT24CXX_Write( 0,(u8 *)a ,sizeof(a))。

? ? ? ? 其中涉及到C语言知识:a++和++a区别

????????语句 while(NumToWrite--):

????????while循环中用的是NumToWrite--,操作过程为:先判断NumToWrite是否为0,然后再执行--操作,而不是直接判断NumToWrite-1的值;如果改为while(--NumToWrite),则是先执行NumToWrite-1操作,然后在判断;

八、在 AT24CXX 里面的指定地址开始读出指定个数的数据

void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)

函数源码:

void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
{
    while(NumToRead)
    {
        *pBuffer++=AT24CXX_ReadOneByte(ReadAddr++);
        NumToRead--;
    }
}

其中:

? ? ? ? 形参?u16ReadAddr :开始读取数据的地址,24C02的地址范围为0-255;

? ? ? ? 形参?u8 *pBuffer:数据数组首地址;

? ? ? ? 形参?u16 NumToRead:要读取数据的个数;

语句 *pBuffer++=AT24CXX_ReadOneByte(ReadAddr++)理解:

????????pBuffer表示存储数据的数组首地址,也表示??pBuffer[0]的地址,pBuffer+1表示pBuffer[1]的地址, *pBuffe表示pBuffer[0]的值(*和++的优先级相同,*P++可看成*(P++),即先执行P++,后执行*P,但由于这里的“++”号是后加加号,所以会在整条语句执行完后再对P自加1);将读取到的值保存在数组元素中。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-09-15 02:09:57  更:2022-09-15 02:12:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 22:45:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码