[C8051F320]串口UART0全双工调试过…

    问题描述:由于应用需要,将C8051F320的UART0作为数据通信接口,与上位机之间进行通信并实现简单的控制功能。程序大概是:由串口定时发送数据到上位机,这个定时时间用定时器控制,可由上位机通过串口发送指定命令切换串口发送定时时间。C8051F320串口发送采用查询方式,发送一段数据之前先关串口中断,发送完毕再打开串口中断,C8051F320串口接收采用中断方式,对接收的各种命令进行分支处理。
    具体问题:程序调试过程中出现一个奇怪问题,我使用一款“串口调试助手”软件在上位机进行串口的接收显示和发送。当通过“串口调试助手”发送命令将下位机串口发送数据的速率提高到40Hz以上时,问题出现了,再用 “串口调试助手”发送命令进行控制时无效了,即此时 “串口调试助手”发送停止等命令下位机都不会有响应,而是继续发着数据。下面用图简单描述一下:
    设置下位机发送频率为20Hz时,下图中的显示数据区会不断刷新数据,这些数据都是合理的,然后在下面的串口发送区发送停止的命令时,串口接收区的数据就会停止刷新,因为此时下位机已经停止发送数据了。
[C8051F320]串口UART0全双工调试过程中一个问题及其解决
    问题就是,当在上图下面的串口发送区发送命令将下位机的数据发送频率提高到40Hz及以上时,串口调试助手的数据显示区会以相应的速度刷新数据,但继续在串口调试助手的发送区发送停止命令想停止此时下位机的发送时,没有作用,下位机还是会继续发送数据,串口调试助手也还是继续刷新显示。使用其他的命令此时也都失效了。
    问题分析:
    开始以为是不是C8051F320的UART0的功能问题,导致程序设计的流程无法执行,于是查看了其Datasheet,发现程序逻辑上应当是没问题的。
    然后又考虑到我C8051F320用UART0发送数据时是禁用了中断的,是不是此时串口接收缓冲区有数据到达时,导致会忽略掉?发送结束重新开中断时也应该会进入中断的呀,因为此时的RI0中断标志已经置位了。虽然觉得没问题,但还是有点怀疑的,于是改写程序,将发送也改成中断方式了,而且一有UART0的中断先查询是否是接收中断,那么这样就更不可能说接收区的数据被忽略或覆盖了(这样本身也是不应该发生的),但是问题还是一样的问题,没得到解决。
    此时开始怀疑是不是串口发送速率较高时,接收到的数据会受到干扰,从而上位机发送的数据无法正确接收。如果是这样那就是硬件问题了,软件上就无法解决了。但是仔细想想,这种可能性并不大,发送速率再怎么高,串口发送接收还是由波特率决定的,所以之前的数据正确,这时的波特率并未改变,也不会有什么数据干扰问题,而且电路板的串口走线很短。
    但此时UART0发送用中断方式实现的程序有点改观,当我将速率设置为40Hz时,发送一个停止命令,等上个十几秒,采集停止了!于是这时候我开始怀疑这个“串口调试助手”的底层执行效率了,连读个几十Hz的数据组都会有延迟,可能是采用的串口查询方式来进行发送和接收的,导致上位机串口本身对界面的一些事件不能及时响应。
    问题解决:
    最终问题居然就是“串口调试助手”的问题,这个程序的实现方式应当串口读取和发送都是用的查询方式来实现的,当接收数据速率较高时,串口缓冲队列会有大量数据堆积,此时串口查询会一直繁忙的读串口,而串口发送的查询估计是和接收用的同一线程,导致串口无法及时发送数据,从而下位机根本接收不到。
    为了验证这个问题,用事件驱动方式重新编写了一个串口发送和接收的调试程序,接收是用的中断方式,发送是用的查询,但将两者放在不同的线程中。然后再调试,所有通信都正常了:
[C8051F320]串口UART0全双工调试过程中一个问题及其解决     

你可能感兴趣的:([C8051F320]串口UART0全双工调试过…)