本文已参与「新人创作礼」活动,一起开启掘金创作之路。
IIC通信过程
主机
发送
- 通过将START位置1,主机会产生一个起始信号
- SB位会被硬件置1,当ITEVFEN位是1时,也就是开启了事件中断后会产生一个SB中断
- 通过对SR1寄存器进行读操作清除该中断
- 发送设备从机地址
- 设备地址会被写入到DR寄存器,ADDR位被硬件置1,当ITEVFEN位是1时,也就是开启了事件中断后会产生一个ADDR中断
- 通过对SR1寄存器进行读操作之后,再对SR2寄存器进行读操作清除该中断
- 7位地址模式下,主机会根据发送的从机地址的最后以为来决定进入进入发送模式(最后一位为0)还是接收模式(最后一位为1),可以通过TRA为进行判断处于发送模式还是接收模式
- 等待接收应答信号
- 当发送设备地址之后,再ADDR被清零后,主设备会通过内部移位寄存器将DR寄存器中的字节发送到SDA线上
- 主机等待接收应答信号,当接收到从机的应答信号后,TxE位会被硬件置1,当ITENFEN位和ITBUFEN位都为1时,才会产生一个TxE中断(通过对DR寄存器的写操作清零)
- 此时,移位寄存器为空,DR寄存器为空,也就是说在接收到TxE中断时可以将要发送的数据写入DR寄存器中开始数据通信,然后再等待应答信号,以此循环
- 停止通信
- 当TxE=1,BTF=1时,发送一个停止信号,停止通信
- 发送一个数据,当接收到应答信号时,就会产生TxE=1,所以,当发送完最后一个数据后,TxE=1
- 如果在上一次数据传输结束之前TxE位已经置1,但是数据字节尚未写入DR寄存器,则BTF位会被置1
接收
- 通过将START位置1产生一个起始信号(同发送)
- 发送设备从机地址(最后一位为1)
- 接收数据
- 当完成地址传输并将ADDR清零后,主机就会进入接收模式,在此模式下,接口会通过内部移位寄存器接收SDA线中的字节并将其保存到DR寄存器
- 每次接收一个字节的数据后,主机都会发出应答信号(如果ACK位是1),并且会在ITEVFEN和ITBUFEN位都是1的时候产生RxNE中断
- 如果上一次数据接收结束之前RxEN位已经置1,但是DR寄存器的数据尚未读取,则BTF位会被硬件置1,而接口会一直延长SCL低电平(也就是等待软件序列结束),等待DR寄存器被写入(从机返回数据到DR寄存器),以将BTF清零
- 结束通信
- 主机会针对从机发送的最后一个字节发送一个NACK
- 为了在接收最后一个字节后生成NACK,必须在读取倒数第二个RxNE事件之后,立即将ACK清零
- 从机在接收到NACK后会释放对SCL和SDA的控制
- 随后,主机可发送一个停止信号,生成停止位后,接口会自动返回从模式
- 要生成停止位,软件必须在读取到倒数第二个RxNE事件之后将STOP置1
- 主机会针对从机发送的最后一个字节发送一个NACK
主机针对2个字节的接收
- 等待ADDR=1(SCL保持低电平,直到ADDR清零)
- 将ACK复位,POS置位
- 将ADDR清零
- 等待BTF=1(第一个数据在DR中,第二个数据在移位寄存器中,SCL保持低电平,直到读取了第一个数据)
- 将STOP置位
- 读取第一个数据和第二个数据