wince串口自发送问题释疑

     这两天让串口自发送的问题搞的差点疯掉。问题诡异之及,以前的一个版本,在自发送(tx和rx相连)时只能收到最后一个字节,改了下UCON之后可以自发送但是偶尔会丢发送字符串的最后一个字节(当然同时拌有另外的一些问题)。无奈又将UCON的值改为之前的一个版本,奇怪的是竟然可以自发送了。我向毛主席保证除了UCON的值之外没有动过其他的地方。

     串口自发送的目的,是为了能处理(几乎)同时接收和发送,但是从驱动的实现原理上来讲是不可能绝对同时接收和发送的,因为一个串口只有一个外部中断,通过该中断可以判断是哪个串口发生了中断。至于是读或写中断是要在IST中根据子中断源寄存器来判断。这样也就是说实际上每次只能处理一个中断,因为如果是读子中断触发的话,需要将该串口外部中断和读子中断都要屏蔽掉(也就是说在IST处理读中断的过程中不会有同级的读写中断)。
 
     写中断来的时候也是同理。

     这样就可以很好解释为什么在115200波特率的时候丢数据的频率要比在9600波特率的时候高。然而同时又有一个奇怪的问题就是在38400波特率的时候自发送:第一次发送没有显示发送了多少个字节(也就是0),但是可以正常接收到数据并显示接收了多少个字节,也就是说实际上数据已经发送成功但是com_write没有返回。之后就不能再发送了。在关闭串口的时候才会显示第一次发送的字节数。

     原因可能是因为38400的速度刚刚好。在串口发送完数据(也就是数据从fifo中到线上)会产生中断,不管这时是否已经完全发送完成,都要再处理一次这个写中断,如果确实没有数据可发了,才设置发送完成事件,这时com_write等到该事件并正常返回。如果在自发送的时候,在第一次发送的过程中,接收fifo一旦有数据就触发读中断,这样接着就要处理读操作,在读操作的过程中将发送完成所触发的中断给屏蔽了(还好这时数据已经发送完成了)。这样在SerialEventHandler中就没有机会去设置发送完成事件了。

     丢数据的可能原因是在写操作的过程中线上的数据更新了接收fifo(也就是最后几个字节的会丢发送fifo比接收fifo大)详细操作可见串口的mdd.c文件。接收和发送操作都是在SerialEventHandler这个中断派发函数中处理的。

     关于串口自发送,在UCON寄存器中有个Loopback Mode位专用来设置自发送的,不过这个东西只能用来调试,没有什么实际价值。

     最后将SerialEventHandler函数中处理接收部分加了临界区,以确保com_read(其中也有关于接收fifobuffer的临界)和SerialEventHandler中的接收fifobuffer同步。这样就都可以自发送,当然如果波特率太低,而接收的时间又太断(发送的太快)也会有部分字节丢失。而发送部分由于直接是由DoTxData来处理,而这个函数中已经有了对发送fifobuffer的同步),所以这里就不用再加同步操作了。

你可能感兴趣的:(职场,休闲,s3c2440,wince4.2)