刚刚做完一个PIC单片机的项目,使用的是dsPIC33FGP706,其中涉及两个单片机之间的数据传输。为了减少连线,采用串行口,最初设计的是使用SPI进行通讯,一个作为Master,另一个作为Slave,可是怎么调也调不通,后来在网上一查,发现这个系列的单片机SPI模块有BUG,作为Slave模式时SS引脚无法当做片选,只能通过软件手段辅助实现,看了看网上的解决办法,感觉有点麻烦。
刚想改板子,发现这个单片机的SPI口竟然和SCI口是复用的,而且两个单片机的连线刚好可以用SCI口进行通讯,大喜,赶紧改程序,让两个单片机用串口通讯。我设计了一个小的协议,1号单片机通过串口向2号单片机发送一个字节的数据,2号单片机收到后立刻传送8个字节的数据,这样重复进行。
1号单片机通过DMA接收,2好单片机通过DMA发送,程序写好后进行调试,问题出现了,发现1号单片机有时会出现收不到数的情况,而且似乎和上电情况有关系,如果上电后能正常收发,那么就会一直正常下去;如果上电后就不能正常接收,那么以后也无法正常接收,就算强制复位也没用。还有一个怪现象就是用PICkit3仿真调试时从来不出故障。
起初以为是DMA带来的问题,随即取消DMA,但故障依旧,后来仔细翻看单片机关于串口的文档,然后调试的时候不用PICkit3,而是把1号单片机串口状态寄存器的值通过另一个串口(这个单片机有两个串口模块)发送到电脑上来。这时找到问题的根源了,发现1号单片机用于与2号通讯的那个串口的UxSTA寄存器的bit0(URXDA)和bit1(OERR)位在上电时偶尔会出现非0值,默认情况下,单片机刚上电,这两个位应该是零,表示接收缓冲区中没有数据,同时也没有溢出,这样2号单片机送过来的数值才能被1号单片机接收。如果上电以后这两位不是0,说明接收缓冲区中有数据,还可能接收缓冲区已经溢出了。
这就是问题的根源所在,当上电后出现这两位非0时,说明接收缓冲区没有清干净,新来的数无法存入缓冲区,而后续的程序又没有清理接收缓冲区的操作,这样就导致一直读不到数。
所以我在每次读书前先强制清除接收缓冲区,添加了如下代码:
while((U1STA&0x0001)==0x0001)
{
&
用户377235 2015-11-20 15:16