"); //-->
需要做这么一个东西:三块单板通过Rs232,以38400的速度发送大量数据(帧的最后一个字节为0A)给STM32的USART2/3/4,STM32收到之后,以115200的速度通过USART1发送到上位机。同时,上位机以很低的频率发送单字节命令字到STM32,STM32需要将其转发到三块单板上。
看上去很简单的一个东西,于是在前两天熟悉了GPIO,NVIC,USART的基础上,就开工了。
一开始想得很简单,开辟Buffer[3][60],Buffer[0..2]分别为USART2/3/4的接收缓存区,定义FrameFlag[3],分别对应USART2/3/4的帧完成标志位,开辟TxBuffer[60],用作发送缓存区。
打开USART2/3/4的接收中断,不停的接收数据到对应的Buffer[x][BufCounter++]里面,一旦Buffer[x][BufCounter-1] == 0x0A则判断FrameFlag[x]为1。
而在主程序里面,则不停的检测三个标志位,只要为1,则清标志位,清计数器等,然后复制对应的Buffer里面得数据到TxBuffer里面,以查询的方式发送完TxBuffer,接着检测下个标志位。
基于这个思想,配置外设等,程序很快写完了,实测却发现有丢字节的现象,即有时候一帧不能够发完。
后来仔细考虑,发现程序有一个最大的Bug,发送一帧的数据是需要较长时间的,如果在检测到FrameFlag[0]为1,正在发送一帧数据的时候刚好出现FrameFlag[1]为1了,那么这个时候代码不能及时响应这一帧数据,该路上的数据便会出现问题。
改进方法如下:
1:采用乒乓操作
2:发送改为中断形式
2自不必说,下面详细说明一下1
开辟两个Buffer,分别为Buffer1[3][60],Buffer2[3][60],定义指针*Buffer[3]分别对应三个串口的接收缓冲区,定义指针*TxBuffer[3]及相应的指针p,q,用作发送数据队列。
具体实现的时候,一开始Buffer[x]等于Buffer1[x],在中断里面判断如果一帧接收完毕,则将Buffer[x]等于Buffer2[x]。实现接收缓存区的乒乓。
在主程序里面,当检测到FrameFlag[x]为1的时候,则将Buffer1[x]入*TxBuffer这个待发送数据队列,即TxBuffer[p] = Buffer1[x],p = p ==2 ? 0 : p++,最后如果检测到p != q,则发送TxBuffer[q]。
将代码按照上述思想修改之后,果然工作正常了。
搞这个代码花了整整两天,快20个小时。
代码在工作电脑上,表达能力着实有限,希望半年后再来看时,自己还能明白这个是什么意思,呵呵。
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。