STM32串口通讯(接收完成一整个数据帧再将数据发送出去)

STM32串口通信可以分为查询,中断,DMA三种方式进行通讯,本文主要就中断的方式进行讲解。采用中断的方式进行通讯时,可以使能接受非空中断(RXNE),当接收到一个数据时就产生一个中断,将接收到的数据通过移位寄存器移位到RDR中,此时我们可以直接将接收到的数据发送出去,则完成了一个字符的通讯,以后每次接收到一个数据就发送一个数据出去,如此便实现了接收到什么数据便发送什么数据的功能。而本文将要讨论先将其他设备发送来的数据全部接收完成,再将一整帧的数据发送出去的通讯方法。(串口通讯原理图如下)

方法一:采用定时器的方法判断一组数据帧是否接收完成。在接收到第一个字符时打开定时器,在持续接收到数据时不断更新定时器的值,当没有接收到数据时,定时器的值不再更新,会产生超时溢出,触发溢出中断,从而判断一组数据帧接收完成(注:定时器的值要设置合理,不能大于两组数据帧发送之间的间隔,如采用modbus协议时3.5个字符的时长;也不能小于两个发送字符之间的时长)。具体操作如下:首先根据波特率计算定时器设置的一个具体时间,在串口中断中接收到第一个字符开启定时器,并在每一次接收到数据进入串口中断时将定时器的计数清零,若定时器达到我们设置的时间便认为一个数据帧接收完成。

方法二:通过对数据帧的帧尾进行判断来识别一组数据帧是否接收完成;因为在电脑上按下回车键或发送新行,帧尾会出现0x0A,0X0D这两个,我们只要判断是否连续出现0A,0D便可判断一组数据帧是否传输完成。

方法三:采用STM32自带的空闲中断(IDLE)来判断一组数据帧是否接收完成;首先,在串口初始化中使能空闲中断(IDLE),再在中断服务函数中判断中断标志位(USART_FLAG_IDLE)(这里只能用中断标志位来判断而不是中断,具体原因还未查清,实操是不行),当标志位置位时,将接收到的一帧数据发送出去。另外,空闲标志位只有在RXNE再次置1时才能使能(注意,USART_FLAG_IDLE的判断在中断服务函数中,但是需要在清除RXNE标志位之后判断)。空闲标志位必须采用先读状态寄存器,再读数据寄存器才可以清除,不能采用普通的调用清除函数来清除。具体操作代码如下:

 RXNE中断和IDLE中断的区别: 
当接收到1个字节,就会产生RXNE中断,当接收到一帧数据,就会产生IDLE中断。比如给STM32一次性发送了10个字节,就会产生10次RXNE中断,1次IDLE中断。

总的来说,这三种方式都可以实现接收不定长的数据帧,接收完成,再发送的功能,但是相对来说第三种方式比较推荐,操作起来简单,且不需要占用定时器资源,另外,对于第二种方法,对从传感器接收来的数据就不太适用,可能你没办法获得其具体的数据帧格式,如此通过帧尾来判断的方法就不太适用了。相对比来说,方法三,采用空闲中断(IDLE)的方式适用性较好。

版权声明:本文为CSDN博主「jj198311」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jj198311/article/details/122221764

STM32串口通信可以分为查询,中断,DMA三种方式进行通讯,本文主要就中断的方式进行讲解。采用中断的方式进行通讯时,可以使能接受非空中断(RXNE),当接收到一个数据时就产生一个中断,将接收到的数据通过移位寄存器移位到RDR中,此时我们可以直接将接收到的数据发送出去,则完成了一个字符的通讯,以后每次接收到一个数据就发送一个数据出去,如此便实现了接收到什么数据便发送什么数据的功能。而本文将要讨论先将其他设备发送来的数据全部接收完成,再将一整帧的数据发送出去的通讯方法。(串口通讯原理图如下)

方法一:采用定时器的方法判断一组数据帧是否接收完成。在接收到第一个字符时打开定时器,在持续接收到数据时不断更新定时器的值,当没有接收到数据时,定时器的值不再更新,会产生超时溢出,触发溢出中断,从而判断一组数据帧接收完成(注:定时器的值要设置合理,不能大于两组数据帧发送之间的间隔,如采用modbus协议时3.5个字符的时长;也不能小于两个发送字符之间的时长)。具体操作如下:首先根据波特率计算定时器设置的一个具体时间,在串口中断中接收到第一个字符开启定时器,并在每一次接收到数据进入串口中断时将定时器的计数清零,若定时器达到我们设置的时间便认为一个数据帧接收完成。

方法二:通过对数据帧的帧尾进行判断来识别一组数据帧是否接收完成;因为在电脑上按下回车键或发送新行,帧尾会出现0x0A,0X0D这两个,我们只要判断是否连续出现0A,0D便可判断一组数据帧是否传输完成。

方法三:采用STM32自带的空闲中断(IDLE)来判断一组数据帧是否接收完成;首先,在串口初始化中使能空闲中断(IDLE),再在中断服务函数中判断中断标志位(USART_FLAG_IDLE)(这里只能用中断标志位来判断而不是中断,具体原因还未查清,实操是不行),当标志位置位时,将接收到的一帧数据发送出去。另外,空闲标志位只有在RXNE再次置1时才能使能(注意,USART_FLAG_IDLE的判断在中断服务函数中,但是需要在清除RXNE标志位之后判断)。空闲标志位必须采用先读状态寄存器,再读数据寄存器才可以清除,不能采用普通的调用清除函数来清除。具体操作代码如下:

 RXNE中断和IDLE中断的区别: 
当接收到1个字节,就会产生RXNE中断,当接收到一帧数据,就会产生IDLE中断。比如给STM32一次性发送了10个字节,就会产生10次RXNE中断,1次IDLE中断。

总的来说,这三种方式都可以实现接收不定长的数据帧,接收完成,再发送的功能,但是相对来说第三种方式比较推荐,操作起来简单,且不需要占用定时器资源,另外,对于第二种方法,对从传感器接收来的数据就不太适用,可能你没办法获得其具体的数据帧格式,如此通过帧尾来判断的方法就不太适用了。相对比来说,方法三,采用空闲中断(IDLE)的方式适用性较好。

版权声明:本文为CSDN博主「jj198311」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jj198311/article/details/122221764

生成海报
点赞 0

jj198311

我还没有学会写个人说明!

暂无评论

相关推荐