**
STM32 IIC从机的使用注意点,解决IIC发送第一个字节的数据错误
**
相关中断标志位
使用STM32 IIC作为从机,不可避免的就要用到中断对接收和发送数据进行处理。
下面讲下常用的中断标志,这里以STM32F072RB为例,在IIC的中断寄存器IIC-ISR有如下标志位
ADDR: 当主机发送地址,作为从机的STM32匹配上了地址,该位会置位为1,同时如果此时开了IIC的中断就会进入中断函数。
RXNE:当主机是发送数据给从机的,则每一次的接收数据寄存器有一个字节的数据时,该位会置1。如果此时开了IIC的中断就会进入中断函数。当从接收寄存器读取数据后,该位会由硬件清0。
TXE:当主机是接收数据的一方,作为从机的STM32在发送数据寄存器为空的时候。该位会置1,如果此时开了IIC的中断就会进入中断函数。一般我们会在中断函数中将数据填入数据发送寄存器,此时,这个标志位会被硬件清0.
STOPF:当主机发送停止信号结束通讯,从机接收到此型号时,该位会置1,如果此时开了IIC的中断就会进入中断函数。
从机的数据发送机制以及注意点
在主机发送地址以及读取数据的方向给从机之后,从机的TXE就会被置位。这里需要注意两个寄存器,发送数据寄存器以及移位寄存器。
发送数据寄存器:发送的数据每一个字节一开始会存在这个寄存器。
移位寄存器:发送数据寄存器将数据发给移位寄存器,移位寄存器再发给主机。
笔者在发送一帧数据(4个字节的数据)发现,主机接收到的新一帧的第一个字节的数据总是上一帧的最后要发送一个字节的数据。
比如上一帧数据为(0x00, 0x01,0x02,0x04)
新的一帧的数据为(0x05,0x06,0x07,0x08)
结果主机接收到的新的一帧数据为(0x04,0x05,0x06,0x07)
一开始还以为MCU出错,后来跟某宝的店主讨论后恍然开朗,问题出在了如下:
一开始在主机发送地址以及读取数据的方向给从机之后,此时,如果发送寄存器原来就存在上一帧的最后一个字节的数据,则这一字节的数据会直接从发送寄存器发给移位寄存器,移位寄存器再把它发给主机,从而主机接收到的新一帧的第一个字节的数据总是上一帧的最后要发送一个字节的数据放。
为什么发送寄存器会存在上一帧最后一个字节的数据呢?
还是某宝的店主告诉我的:因为MCU的IIC处理机制就是当从机IIC发送一个字节的数据给主机时,主机要应答,从机才会把存在发送寄存器的新的一个字节的数据发送给移位寄存器。
并且,一开始在主机发送地址以及读取数据的方向给从机之后,从机的发送寄存器如果存在一个字节的数据,则这一字节的数据会直接从发送寄存器发给移位寄存器,移位寄存器再把它发给主机,这第一个字节不需要主机先应答从机再发送出去。
比如这个例子:
在主机发送地址以及读取数据的方向给从机之后。如果发送寄存器原来就存在未知的一个字节的数据a,这个数据会被发送给移位寄存器(这一步是硬件自动进行的),发送寄存器为空了,此时从机的TXE位才被置位为1,产生中断事件,0x00被接着放入发送寄存器,主机接收到字节a,发送(ack)应答给从机,这个0x00才会被发送给移位寄存器。
因此,主机在接收到a,0x00,0x01,0x02,后,发现四个数据够了,就发送非应答(NACK)再接着发送停止信号,而不是应答(ack),因此0x04就被放在发送寄存器没有发送出去。
在新的一帧数据开始发送时,此时这个0x04就是上面的未知字节a了。
重点总结
1.从机产生IIC发送中断是因为发送寄存器为空,只要发送寄存器的数据发送给移位寄存器就会产生TXE置位,如果此时开了IIC的中断就会进入中断函数。
2.一开始在主机发送地址以及读取数据的方向给从机之后,从机的发送寄存器如果存在一个字节的数据,则这一字节的数据会直接从发送寄存器发给移位寄存器,移位寄存器再把它发给主机。
3.主机在接收到一个字节的数据后要应答(ack),从机才会继续把发送寄存器的数据发给移位寄存器,第一个字节除外,见2.
解决办法
实际上解决的就是在匹配到正确的地址后,就把发送寄存器的数据清空,让发送寄存器的数值重新填写,某宝的店主给我看了这段话:
这里的意思就是,在进入地址匹配的中断后,让IIC-ISR寄存器的TXE位置1,软件直接写I2C1->ISR |= I2C_ISR_TXE,此时会让MCU进入发送中断,从而往发送寄存器写入新的一个字节数据即可。
偷偷帮店主打个广告,祝店主生意兴隆,某宝搜多多林电子:https://shop486079607.taobao.com/category-1442399460.htm?spm=a1z10.3-c-s.w401021301227193.8.20a33ebcDBMpB2&search=y&parentCatId=1442399459&parentCatName=��������������&catName=ST(�ⷨ�뵼�壩#bd
大家有问题可以下面留言,需要元器件或者有问题就联系某宝店主,我也是在哪里买了东西,不会用才去问,发现原来某宝也有好多高手