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

article/2025/9/19 19:40:41

目录

一、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);   //避免每次开机都写 AT24CXXif(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);将读取到的值保存在数组元素中。


http://chatgpt.dhexx.cn/article/Bywgy8wf.shtml

相关文章

windows用VS2019下编译log4cxx日志库

一、下载相关库文件 获取log4cxx源码包&#xff1a;http://logging.apache.org/log4cxx/index.html 获取依赖库apr和apr-util源码包:http://archive.apache.org/dist/apr/apr-1.2.11-win32-src.zip http://archive.apache.org/dist/apr/apr-util-1.2.10-win32-src.zip 编译apr…

log4cxx编译

本人进行过win7 64位操作系统和win10家庭版的log4cxx编译&#xff0c;使用的是vs2015&#xff0c;下面是详情。 1.sed下载 sed-4.2.1-bin.zip、sed-4.2.1-dep.zip下载地址&#xff1a;http://gnuwin32.sourceforge.net/packages/sed.htm 下载后&#xff0c;将sed的两个压缩包解…

【RT-Thread Master】at24cxx软件包使用笔记

硬件介绍 RT-Thread版本&#xff1a;V4.1.0软件包名称&#xff1a;at24cxxMCU型号&#xff1a;AT32F407VET7EEPROM型号&#xff1a;AT24C16 使用说明 1、使用menuconfig将软件包添加进入工程&#xff0c;路径如下所示。 2、把IIC总线打开&#xff0c;这里使用软件IIC&#…

linux下编译和安装log4cxx,ubuntu下log4cxx安装使用

需要安装log4cxx&#xff0c;安装的过程中可是充满了坎坷。。。最大的问题是在make log4cxx时&#xff0c;总是报undefined XML什么什么的错误&#xff0c;查了一下也没解决了&#xff0c;然后把apr-utils删了重新装了一下就好了。。 log4cxx现在是apache的一个项目&#xff0c…

linux下编译和安装log4cxx,RedHat如何安装log4cxx日志库

log4cxx日志库是一种动态库&#xff0c;用于记录c的日志&#xff0c;那么RedHat系统下要如何安装log4cxx日志库呢&#xff1f;下面小编就给大家介绍下RedHat安装log4cxx日志库的步骤&#xff0c;感兴趣的朋友不妨来了解下吧。 首先&#xff0c;我得到信息&#xff0c;安装这个库…

AT24Cxx读写全面理解

AT24Cxx - 电可擦可写E2PROM 芯片介绍 基础介绍\引脚介绍 AT24Cxx系列EEPROM是由美国Mcrochip公司出品&#xff0c;1-512K位的支持I2C总线数据传送协议的串行CMOS E2PROM&#xff0c;可用电擦除&#xff0c;可编程自定时写周期&#xff08;包括自动擦除时间不超过10ms&#…

mongodb-cxx-driver使用

mongocxx driver 是构建在 MongoDB C driver 之上的 1.首先需要安装mongo-c-driver wget https://github.com/mongodb/mongo-c-driver/releases/download/ 1.23.1/mongo-c-driver-1.23.1.tar.gz tar xzf mongo-c-driver-1.23.1.tar.gz cd mongo-c-driver-1.23.1 mkdir cmak…

老胡的周刊(第095期)

老胡的信息周刊[1]&#xff0c;记录这周我看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。 &#x1f3af; 项目 tabby[2] 自托管的 AI 编码助手&#xff0c;…

程序员养生指北

吴小胖第八次推送 阅读时间预计3分钟~ 熬夜篇 互联网人熬夜是不能避免的&#xff0c;原因却各不相同。 不加班的时候&#xff0c;总会对自己说&#xff0c;今天一定早睡&#xff0c;然鹅... 午休篇 熬夜的程序员总想依靠午休补觉&#xff0c;然鹅... 更不幸的是&#xff0c;互联…

老杨说运维 | 中国IT运维市场的现状与趋势

文章内容来源《第一新声》 对擎创科技CEO杨辰(老杨)的专访 前言&#xff1a; 中国目前正面临百年未有之大变局&#xff0c;在这个变局中&#xff0c;不稳定性和不确定性正在增强。疫情持续反复、国际形势变化多端&#xff0c;导致国内多个行业出现发展增速下降、产供销节奏打…

老杨说运维 | 非常重要,事关转型

《荀子》有云&#xff1a;“水能载舟&#xff0c;亦能覆舟。”在公司日常运营过程中&#xff0c;数据指标就像是水&#xff0c;孕育着生命&#xff0c;承载着万物。科学的数据指标能指引公司在正确的道路上不断前进&#xff0c;使平淡无常的业务焕发新生&#xff0c;而不合理的…

学习springcloud的一些心得体会——老卫的天气预报系统

1&#xff1a;建立天气预报springboot系统 首先先建立一个天气预报的springboot系统&#xff0c;具体流程如下&#xff1a; &#xff08;1&#xff09;从cityList.xml中获取城市信息&#xff0c; &#xff08;2&#xff09;然后根据下面的链接获取各个城市的天气预报信息&am…

学习springboot项目的一些心得-----老卫的博客系统

去年年底接触了springboot框架&#xff0c;这两天复习了一遍&#xff0c;主要是跟着老卫博客系统这个课程学习的。 springboot介绍&#xff1a;总的感觉springboot就是基于spring开发的一套框架&#xff0c;好处就是不用配置复杂的依赖包&#xff0c;xml的一些文件&#xff0c…

thymeleaf和spring boot的集成踩坑总结(练习项目是老卫的博客项目)

bug1: 2019-08-08 16:44:38.102 ERROR 19810 — [nio-8080-exec-8] org.thymeleaf.TemplateEngine : [THYMELEAF][http-nio-8080-exec-8] Exception processing template “users/list”: Error resolving template “users/list”, template might not exist or might not be …

《跟老卫学 HarmonyOS 开发》:以父之名・码力全开!写段 HarmonyOS 祝父亲节

#父亲节祝福语# 爸爸在我心中就像旗帜 他教会我做人与处事的方向 在父亲节这个特别的日子里 我想对爸爸说长大以后我就要成为您 使用ArkUI开发“父亲节的祝福” 使用ArkUI开发“父亲节的祝福”&#xff0c;效果如下&#xff1a; 使用DevEco Studio整体开发HarmonyOS整体时…

【老卫搞机】090期:键盘?主机?全功能键盘主机!

这是一台我个人DIY的第二代键盘主机&#xff08;第一代见&#xff1a;【老卫搞机】074期&#xff1a;键盘&#xff1f;主机&#xff1f;键盘主机&#xff01;_哔哩哔哩_bilibili&#xff09;。相比与第一代的作品&#xff0c;第二代产品除了USB 3接口、USB 2接口、mini HDMI接口…

【老卫拆书】009期:Vue+Node肩挑全栈!《Node.js+Express+MongoDB+Vue.js全栈开发实战》开箱

今天刚拿到一本新书&#xff0c;叫做《Node.jsExpressMongoDBVue.js全栈开发实战》&#xff0c;做个开箱。 外观 先从外观上讲&#xff0c;这本是全新的未开封的&#xff0c;膜还在。 这本书介绍从技术原理到整合开发实战&#xff0c;以丰富的项目展现全栈开发的一个技巧。 …

【老卫搬砖】034期:HarmonyOS 3.1 Beta 1初体验,我在本地模拟器里面刷短视频

今天啊打开这个DevEco Studio的话&#xff0c;已经提示有3.1Beta1版本的一个更新啊。然后看一下它的一些特性。本文也演示了如何在本地模拟器里面运行HarmonyOS版短视频。 主要特性 新特性包括&#xff1a; Added support for Windows 11 64-bit and macOS 13.x OSs, as well…

【老卫搞机】135期:华为开发者联盟社区2022年牛人之星奖品开箱!

首先祝大家兔年大吉&#xff0c;身体安康&#xff0c;钱兔似锦&#xff01;今天咱们来开箱一件特殊的奖品&#xff0c;来自华为开发者联盟社区的新年祝福——2022年牛人之星。 华为有钱&#xff01;惯例用的是顺丰快递&#xff0c;各位看一下这里面是有很多件的 有这两件。第一…

【老卫搞机】136期:华为开发者联盟社区2022年度战码先锋2期开源贡献之星

首先祝大家兔年大吉&#xff0c;身体安康&#xff0c;钱兔似锦&#xff01;接上次的“2022年牛人之星”&#xff08; https://developer.huawei.com/consumer/cn/forum/topic/0203109930647268095&#xff09;&#xff0c;今天咱们来开箱另外一件特殊的奖品&#xff0c;来自华为…