【STM32学习笔记】STM32 I2C读写EEPROM(AT24C02)理论知识
STM32 I2C读写EEPROM(AT24C02)个人调试Bug经验
本篇文章是本人学习野火STM32读写EEPROM的视频总结而来的笔记,上面的链接有解答关于《火哥视频中EEPROM_WaitForWriteEnd()函数检测EV6事件为什么不能用CheckEvent()函数来检测》问题的解答。
上述问题火哥视频的链接[24-I2C—读写EEPROM(第7节中)—代码详解-读写EEPROM] 进度条58:50自己去看
I2C协议介绍
物理层
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/58bf08d2a99f4d48832f15001f33f5b6.png)
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/211966f5a4384c6e8b080a413f2b8e00.png)
1.SCL 串行时钟线
2.SDA 双向串行数据线
3.每个设备有独立的地址
4.每个设备在空闲状态时都会输出高阻态,所有都为空闲状态时,则总线被上拉为高电平
5.SDA 设备用高阻态表示高电平(1),接地表示低电平(0)
6.三种传输模式:标准传输速率为100kbit/s,快速模式为400kbits/s,高速模式为3.4Mbit/s(大多数设备不支持)
协议层
1.I2C基本读写过程
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/605b347efddd4f059c7f07419ef923a8.png)
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/a6d42d3b5fe04790a1f8ad7ee042e383.png)
1. 数据和时钟线都为高时总线处于空闲状态。
2. 当SCL为高电平时SDA的下降沿为起始条件( S )。
3. 当SCL为高电平时SDA的上升沿为停止条件( P )。
4. 当SCL为高电平时,SDA的数据有效,否则无效。
2.地址及数据方向
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/b2e117d16f914160aebedd83263d52ee.png)
前七位为从机地址,最后一位为读写方向位
从高位开始传输
3.响应
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/046d448f1f414cc68d699eb59f829c99.png)
当数据端释放SDA控制权后,若接收端控制SDA为低电平时(在第9个时钟),则产生了应答信号(ACK),若为高电平,即无动作,则产生非应答信号(NACK)。
STM32的I2C架构
1.通讯引脚
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/5e747754a818448ab1bb687014ac6cb2.png)
I2C1
默认复用
SCL:PB5 SDA:PB6
重定义
SCL:PB8 SDA:PB9
I2C2
默认复用
SCL:PB10 SDA:PB11
2.时钟控制逻辑
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/d903ef71ddda44e7ae4c784cb25e90c4.png)
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/b93e18ec2b2546cabe88cb26fba88e2a.png)
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/0e3e9bbbdba1475bb26b499ffa1e5f72.png)
1.I2C模块的时钟频率必须是10MHz整数倍
2.PE为0时才能配置CCR寄存器
3.标准模式下(100kbit/s) Thigh = Tlow(注:T = Thigh + Tlow,这里的100kHz的周期应当是二者相加)
4.DUTY 位标准模式没关系,是用来设置快速模式的占空比(2:1 16:9)
5.CCR根据自己配置的I2C模式自行计算,
若PCLK = 8MHz (FREQ寄存器控制)
100kbit/s 对应的 CCR = 0x28 = 40
400kbit/s 对应的 CCR = 0x0A = 10
3.数据控制逻辑
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/3639a075012f44898dce0f54b34c378e.png)
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/4eed5acd5bac48b29db5db930956b66d.png)
4.整体控制逻辑
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/8f849285deff4e21a8e7f636dc3e38eb.png)
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/b23f45a0fe584e6b9625452f1a7502a4.png)
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/3e3b8c0356a54b0e9ea86516379a6605.png)
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/84370d0750f141499dc845d24bd3deb3.png)
I2C配置由CR1 和 CR2 寄存器配置
工作时的状态由SR1 和 SR2 寄存器显示
STM32 I2C 通讯过程
1.主发送器模式
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/7fd4b855a80f4036aaf04d598f0533d6.png)
7位主发送模式过程:
1. Start 信号产生。
2. EV5事件产生,SB = 1 ,即开始条件发送完成位置1,读SR1 寄存器,并写入DR寄存器能清除该事件。
3. 把地址写入DR寄存器。
4. 接收到ACK信号。
5. 产生EV6事件,ADDR(地址已被发送位) = 1 ,当收到地址的ACK后该位被置1,读SR1 和 SR2 会清除该位。
6. 产生EV8_1事件, TXE(数据寄存器为空位) = 1 ,移位寄存器和数据寄存器都为空,写入DR寄存器可以清除该标志位。
7. 写入DR寄存器。
8. 产生EV8事件,TXE(数据寄存器为空位) = 1 ,数据寄存器为空,移位寄存器不为空,写入DR寄存器可以清除该位。
9. 接收到ACK应答信号。
10. 写入DR寄存器(第二次发送数据)。
11. 产生EV8事件,TXE(数据寄存器为空位) = 1 ,数据寄存器为空,移位寄存器不为空,写入DR寄存器可以清除该位。
12. 所有数据发送完成后产生EV8_2事件,此时BTF 和 TXE = 1 。
13. 发送停止信号
10位主发送模式过程同理
2.主接收器模式
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/41e5fbc1f0084619878c80ff84814f57.png)
7位主接收模式过程:
1. Start 信号产生。
2. EV5事件产生,SB = 1 ,即开始条件发送完成位置1,读SR1 寄存器,并写入DR寄存器能清除该事件。
3. 把地址写入DR寄存器。
4. 接收到ACK信号。
5. 产生EV6事件,ADDR(地址已被发送位) = 1 ,当收到地址的ACK后该位被置1,读SR1 和 SR2 会清除该位。
6. 产生EV6_1事件,用于接收1个字节,需要清除响应(ACK)和停止条件(STOP)的产生位。
7. 主机产生ACK应答信号。
8. 产生EV7事件,RXNE = 1 ,此时DR寄存器不为空,需要读DR寄存器来清除该事件。
9. 主机产生ACK应答信号。
10. 产生EV7_1事件,RXNE = 1 ,此时DR寄存器不为空,需要读DR寄存器来清除该事件。并且需要设置ACK = 0 ,STOP = 1。
11. 主机产生NACK非应答信号。
12. 主机产生STOP信号。
13. 产生EV7事件。
10位主接收模式过程同理
STM32 IIC 库函数
1.I2C 初始化结构体
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/299a94df358a45faaa7c259675d3d748.png)
1.I2C_ClockSpeed
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/b22a375d6ac9486f87e04fba69810ffb.png)
注:I2C的标准和快速模式已经在这里配置完成,根据输入的时钟值来确定,小于等于100k为标准,否则为快速
2.I2C_Mode
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/167761144d1c4da98952f5a8b9a7a573.png)
3.I2C_DutyCycle
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/f7345ec5247e466bb5c6180d7ff39ece.png)
4.I2C_OwnAddress1
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/7d93b9b5359440e7875a960e3c082f4b.png)
5.I2C_Ack
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/3cecb490735e47ba881c757f83345d41.png)
6.I2C_AcknowledgedAddress
%E7%90%86%E8%AE%BA%E7%9F%A5%E8%AF%86/images/abbe6829601a43daa4c0aa17420c9982.png)
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!