STM32Cube配置IIC,AT24CXX芯片理解

IIC介绍

IIC:两线式串行总线,可接多个IIC设备,每个设备有一个唯一的地址,两线控制。同一时间只能有一个主设备,其他为从设备,通常MCU作为主设备。

上拉电阻为4K7或10K,总线空闲时两根线为高电平,总线上任一器件输出低电平总线都会被拉低。

 

开始信号:SCL为高电平时,SDA由高电平转变为低电平跳变,表示开始通信。

结束信号:SCL为高电平时,SDA由低电平转变为高电平跳变,结束结束通信。

应答信号:接收数据的IC在接收到一个字节数据后,向发送数据的IC发出特定的低电平脉冲,表示已收到数据。

SCL由主设备控制,为高时可以读取SDA数据,为低时SDA改变下一位数据,当传输8位后主设备释放SDA总线,SDA被电阻拉高,如果从设备正确收到数据则会发送一个应答信号。

AT24CXX介绍

AT24CXX是EEPROM,后两位表示容量,02为2K位,248字节

A0/A1/A2为地址,WP为写保护。该设备地址如下,最后一位表示读写操作

 

这里解释一下24CXX,该系列存储有两个概念,大分区和小分区,大分区256字节,小分区一个字节。并且该系列其实器件地址都是0xA0,也就是前面4位1010,后面A2A1A0其实是数据字节地址,我们在操作的时候需要发送器件地址和数据字节地址。后面会细说。先记住器件地址虽然是0xA0,但规定了8位的形式,所以我们在发送器件地址的时候得注意吧A2A1A0和RW加上,还有就是数据字节地址是16位(分高8位和低8位,A2A1A0是高八位里面的低三位)。很奇怪吧,吧数据字节地址放在了器件地址里面,但规定就是这样,得习惯。

以02为例,02容量正好一个大分区2K位,256字节,每个字节需要一个地址,地址范围0-255。正好需要8位数据来表示数据该写在哪或是从哪读,所以会有IIC_Send_Byte(ReadAddr%256);这么一句(这里的ReadAddr是16位,用来表示数据字节地址)来获得数据地址的低八位来表示读写数据的具体位置,02只需要8位数据就能表示所有数据地址。

而在这之前需要先发送器件地址才能读写,所以有IIC_Send_Byte(0XA0+((ReadAddr/256)<<1));这么一句。这里的ReadAddr/256就是获取器件地址的高八位,这个高八位有什么用呢?为什么要和0XA0相加还要左移一位呢?其实啊,这里获得的高八位用多少位是根据AT系列的型号来的,比如02容量256字节,低八位就表示完了256字节,所以对于02来说这A2A1A0一般是固定的000,没什么用。

但是对于其他信号如04,4k位,512字节,需要9位才能表示完所有字节地址,这时候04就用到了高八位,但也只用了1位(A0),所以04一般A2A1是固定的00,A0需要编程控制,这里的A0就可以决定访问04的两个大分区里的哪一个。所以IIC_Send_Byte(0XA0+((ReadAddr/256)<<1));这句代码一般都有一个条件,最多到24C16,比16容量还大的会用其他处理。而16容量16K位,2048字节,正好8个大分区,正好A2A1A0三位加上数字字节地址的低8位刚好表示完,不会影响到器件地址0xA0。那个<<1大家就是把数据字节地址/256得到的高8位左移一位,这样和器件地址相加时才不会加到RW位上去,把A2A1A0的位置放好。

而这样搞会不会在加的时候影响到前面的1010,这当然不会,因为ReadAddr的值是你自己决定的,保证它的高八位的前5位为0就好了。后面是个关于IIC_Send_Byte(0XA0+((ReadAddr/256)<<1));很丑的示意图。

之前说了AT24C系列有大分区概念,一个大分区正好用低八位表示完。A2A1A0这三个高位就可以理解为选择AT24Cxx的大分区,低八位则是选择具体大分区里的某个字节(小分区)的位置。

 

通过IIC控制25Cxx

写字节操作MCU先发送一个开始信号(START),然后发送器件写操作地址(DEVICE ADDRESS),E2PROM接收到地址后,如果地址和自身的地址一样,E2PROM就会回一个应答信号(ACK)。MCU接收到应答信号后,再发送要操作的内存地址(WORD ADDRESS),得到应答后再传输写入的数据(DATA)。再次等待E2PROM应答后发送结束信号(STOP)结束传输。下图一块表示一位

 

E2PROM支持连续写操作,操作和单个字节类似,先发送设备写操作地址(DEVICE ADDRESS),然后发送内存起始地址(WORD ADDRESS),然后不断传输数据。E2PROM的地址指针会自动递增,数据会依次保存在内存中。

E2PROM读字节操作如下,先发送设备写操作地址(DEVICE ADDRESS),然后发送要读取内存的地址(WORD ADDRESS)。然后重新发送开始信号(START),发送设备读操作地址(DEVICE ADDRESS)对E2PROM进行读操作。此时MCU释放SDA数据线,E2PROM控制SDA数据总线,将内存地址中对应的数据发送给MCU。

 

E2PROM可以连续读操作,在读一个字节后,MCU会回应一个应答信号(ACK)后,E2PROM会继续传输下一个地址的数据,MCU不断回应应答信号可以不断读取内存的数据,不应答发送结束信号后终止传输。

 

 

 

 

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
STM32中,可以使用HAL库提供的I2C底层驱动来操作24CXX系列芯片。HAL库提供了一系列函数来实现I2C通信,包括发送起始信号、发送地址、发送数据、接收数据等。你可以在main函数中使用这些函数来操作24CXX芯片。例如,你可以使用HAL_I2C_Master_Transmit函数发送起始信号和地址,然后使用HAL_I2C_Master_Transmit函数发送数据,最后使用HAL_I2C_Master_Receive函数接收数据。具体的代码可以参考HAL库的文档或者示例代码。\[2\]另外,你还可以自己编写底层时序来操作I2C总线,这样可以更加灵活地控制引脚的使用。\[2\]在你的代码中,你可以看到使用了HAL_Delay函数来延时,然后调用了AT24CXX_WriteOneByte和AT24CXX_ReadOneByte函数来写入和读取数据。这些函数应该是你自己编写的,用来操作24CXX芯片的底层驱动。\[3\] #### 引用[.reference_title] - *1* [第六节:STM32基于HAL库的IIC通信](https://blog.csdn.net/Kevin_8_Lee/article/details/105617640)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [二、STM32用HAL库写I2C底层时序](https://blog.csdn.net/weixin_42727214/article/details/126604347)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XM766

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值