历史上的今天
今天是:2025年08月14日(星期四)
2019年08月14日 | STM32 IIC通信往24C02写数据、读数据
2019-08-14 来源:eefocus
1、24C02模块的原理图:从图中可以看出,A0、A1、A2三个引脚全部接地,说明表示器件地址7位数据后三位全部是0

注:当上一个数据写完之后,若发送停止信号,则至少停下10ms时间后,才能再发送起始信号,这个时间就叫做写周期。
3、器件寻址:

4、字节写:


5、写页:
(1)、用页写,CAT24WC01可一次写入8个字节的数据,CAT24C02/04/08/16可以一次写入16个字节的数据。
(2)、页写操作的启动和字节写一样,不同在于传送了一字节数据后并不产生停止信号,主器件还可以被允许额外再发送7或者15个字节。
(3)、每发送一个字节数据后CAT24WCxx产生一个应答位,并将字节地址低位加1,高位保持不变。
(4)、若在发送停止信号之前主器件发送超过8个或16个字节,地址计数器将自动翻转,先前写入的数据被覆盖。
(5)、接收到P+1字节数据和主器件发送的停止信号后,CAT24Cxx启动内部写周期(10ms)将数据写到数据区,所有接收的数据在一个写周期内写入CAT24Cxx.
6、字节读:
读操作允许主器件对寄存器的任意字节进行读操作。主器件首先通过发送起始信号、从器件地址和它想读取的字节数据的地址执行一个写操作。在从器件应答之后,主器件重新发送起始信号和从器件地址,此时R/W位置1,从器件响应并随机发送应答信号,然后输出所要求的一个8个字节数据,主器件不发送应答信号但产生一个停止信号。
7、连续读:
在从机给主机发送完一个8位字节数据后,主器件产生一个应答信号来响应,告诉从机主器件要求更多的数据,对应每个主机产生的应答信号,从机将发送一个8位数据字节。当主器件不发送应答信号而发送停止位时结束操作。

8、首先定义:
#define AT24C01 127
#define AT24C02 255 // AT24C02有255个字节
#define AT24C04 511
#define AT24C08 1023
#define AT24C016 2047
#define AT24C032 4095
#define AT24C064 8191
#define AT24C028 16383
#define AT24C0256 32767
#define EE_TYPE AT24C02 //从器件的类型
#define Device_Address //0xA0
9、读写字节:
(1)、读一个字节:
u8 read_OneByte(u16 addr) //addr表示主器件想读取的字节数据的地址,是16位的
{
u8 data;
I2C_Start();
if( EE_TYPE>AT24C016 ) //读数据时是双字节寻址
{
send_Byte(0xA0);
I2C_Wait_ACK();
send_Byte(addr>>8); //先发送数据地址高位
}
else //读数据时是单字节寻址
send_Byte(0xA0+((addr/256)<<1)); //器件地址+数据地址高字节(数据地址一个字节表示不完,会挤到器件地址里面)
I2C_Wait_ACK();
send_Byte(addr%256); //数据地址低字节
I2C_Wait_ACK();
//开始读数据
I2C_Start();
send_Byte(0xA1); //最后一位为“1”,表示接下来是要读数据
I2C_Wait_ACK();
data=rev_Byte(0); //"0"表示主机不需要给从机应答
I2C_Stop();
return data;
}
(2)、写一个字节

void write_OneByte(u8 data, u16 addr) //将数据data写到从器件的地址为addr的缓冲区里面
{
I2C_Start();
if( EE_TYPE>AT24C016 ) //读数据时是双字节寻址
{
send_Byte(0xA0);
I2C_Wait_ACK();
send_Byte(addr>>8); //先发送数据地址高位
}
else //读数据时是单字节寻址
send_Byte(0xA0+((addr/256)<<1)); //器件地址+数据地址高字节(数据地址一个字节表示不完,会挤到器件地址里面)
I2C_Wait_ACK();
send_Byte(addr%256); //数据地址低字节
I2C_Wait_ACK();
//开始写数据
send_Byte(data);
I2C_Wait_ACK();
I2C_Stop();
delay_ms(10ms); //延时10ms,也叫写周期
}
(3)、读两个字节:
u16 read_TwoByte(u16 addr) //addr表示主器件想读取的字节数据的地址,是16位的
{
u16 data;
I2C_Start();
if( EE_TYPE>AT24C016 ) //读数据时是双字节寻址
{
send_Byte(0xA0);
I2C_Wait_ACK();
send_Byte(addr>>8); //先发送数据地址高位
}
else //读数据时是单字节寻址
send_Byte(0xA0+((addr/256)<<1)); //器件地址+数据地址高字节(数据地址一个字节表示不完,会挤到器件地址里面)
I2C_Wait_ACK();
send_Byte(addr%256); //数据地址低字节
I2C_Wait_ACK();
//开始读数据
I2C_Start();
send_Byte(0xA1); //最后一位为“1”,表示接下来是要读数据
I2C_Wait_ACK();
//先读高字节
data=rev_Byte(1)<<8; //"1"表示主机需要给从机应答
I2C_Wait_ACK();
//读低字节
data=data|rev_Byte(1); //"0"表示主机不需要给从机应答
I2C_Stop();
return data;
}
(4)、写两个字节:
void write_OneByte(u16 data, u16 addr) //将数据data写到从器件的地址为addr的缓冲区里面
{
I2C_Start();
if(EE_TYPE>AT24C016 ) //读数据时是双字节寻址
{
send_Byte(0xA0);
I2C_Wait_ACK();
send_Byte(addr>>8); //先发送数据地址高位
史海拾趣
|
请问大家用C开发AVR时使用的是哪个开发环境,哪个更好用. 刚刚从C51转到AVR我这里有三个开发环境,AVR Studio | ICCAVR | cvavr | 其中,AVR Studio是买仿真器自带的,现在准备用Mega64做个。产品不知哪个开发环境好用更适合开发呢? 请大家指点 ...… 查看全部问答> |
|
FPGA可综合性对初学着的一些建议一、HDL不是硬件设计语言 过去笔者曾碰到过不少VHDL或Verilog HDL的初学者问一些相似的问题,诸如如何实现除法、开根号,如何写循环语句等等。在这个论坛上,也时常能看到一些网友提出这一类的问题。 对于这些问 ...… 查看全部问答> |
|
有哪位弄过ES56031混响吗? 我按照datasheet的时序,采用UCOM模式,依次发送D4,D3,D2,D1,SHEEP = 10110,但是就是得不到正确的延时啊,总是得到最小的那个延时12MS,我怀疑是一个初始值,也就是说我没有设置成功。… 查看全部问答> |
|
“外包在线”网络技术有限公司CEO喻烜为大家讲述了她鲜为人知的创业经历,从初识“外包”到立志创业,从寻求投资到初有成就,借由这朵铿锵玫瑰坚韧不拔的毅力和非凡的智慧,国内首家外包服务网络平台终于问世,自此“外包”服务更加平民化,从 ...… 查看全部问答> |
|
地址总线A15—A0(低),存储器地址空间为3000H-67FFH,按字节编址。其中3000H-4FFH为ROM区,选用EPROM芯片(4K*2b/片);5000H-67FFH为RAM区,选用DRAM芯片(2K*4位/片) 解释3000H是如何推出(A15A14为00),而 4FFFH又是如何推出(A15A14为01) ...… 查看全部问答> |
|
国内站点: 华恒公司的主页,里面有很多的相关资料,有待大家去发现 http://www.hhcn.com/chinese/embedlinux-res.html SkyEye嵌入式硬件仿真项目 www.skyeye.org http://gro.clinux.org/projects/skyeye/ 公社的SkyEye项目专栏 http://www.linuxfa ...… 查看全部问答> |




