DSP 28335 RS485 SCI串口通讯 出错无法进入中断

        项目上通过RS485 SCI串口在DSP 28335和PLC之间通讯, PLC发送指令给DSP,触发DSP的SCI接收中断,进而在接收中断里执行SCI发送函数,返回给PLC对应数据,未使用FIFO。

        之前程序一直正常运行,最近在调试的过程中遇到了奇怪的现象,SCI中断会在成功进入中断一次或者若干次后(几十、几百、几千不等)再也进不去中断,而同时程序并没有跑飞,CAN的收发中断和定时器Timer0中断都在正常运行,主循环也在正常运行。查看SCI寄存器发现,在PLC发送数据的末尾,会莫名多出来一字节数据  “0x00”。当“0x00”出现之后,就再也无法进入SCI接收中断了,同时可以观察到SCI寄存器SCIRXST的第3位(OE)溢出错误标志 ,第4位(FE)帧错误标志和第7位(RX ERROR,数值为第2、3、4位寄存器或运算结果)SCI接收器错误标志为1。正常情况下三个寄存器都应该为0。

       据此判断是SCI出现接收错误,导致进不去SCI接收中断。查阅了一些资料,发现要想解决发生错误导致错误标志位置位的问题,需要执行一次完整的SW RESET((SCICTL1)的第5位)。

RX ERROR                SCI receiver error flag. The RX ERROR flag indicates that one 
                        of  the error flags in the receiver status register is set.         
                        RX  ERROR is a  logical OR of the break detect, framing  error, 
                        overrun, and parity error enable flags (bits 52: BRKDT, FE, 
                        OE, and PE). A 1 on this bit will cause an interrupt if the
                        RX ERR INT ENA bit (SCICTL1.6) is set.This bit can be used for 
                        fast error-condition checking during the interrupt service 
                        routine. This error flag cannot be cleared directly; it is cleared 
                        by an active SW RESET or by a system reset.
                      
                        1     Error flag(s) set
                        0     No error flags set


FE                     SCI framing-error flag. The SCI sets this bit when an expected 
                       stop bit is not found. Only the first stop bit is checked. The 
                       missing stop bit indicates that synchronization with the start bit 
                       has been lost and that the character is incorrectly framed. The 
                       FE bit is reset by a clearing of the SW RESET bit or by a system 
                       reset.

                       1      Framing error detected
                       0      No framing error detected

OE                     SCI overrun-error flag. The SCI sets this bit when a character 
                       is transferred into registers SCIRXEMU and SCIRXBUF before 
                       the previous character is fully read by the CPU or DMAC. The 
                       previous character is overwritten and lost. The OE flag bit is
                       reset by an active SW RESET or by a system reset.

                       1       Overrun error detected
                       0       No overrun error detected

       那么解决方案就是:

       1.使能SCI接收错误中断

       2.当发生SCI接收错误时,进入SCI接收中断,判断标志位 RX ERROR 是否置1(如果是SCI接收错误导致进入中断, RX ERROR自然为1)

       3.当  RX ERROR 置1,执行一次完整的SW RESET,退出中断

       通过这简单3步,程序就可以继续进入SCI接收中断了,SCI通讯恢复正常。至于为何会出现错误,由于通讯程序并没有改动,正常跑了大约一周突然连续出现错误,只能暂时理解成是环境电磁干扰导致的错误吧。。。

     

       下面附上修改后的代码供有需要的同学取用

 1 void Scib_echoback_init() //     SCI初始化
 2 {
 3     // Note: Clocks were turned on to the SCIA peripheral
 4     // in the InitSysCtrl() function
 5 
 6      ScibRegs.SCICCR.all =0x0007;   // 1 stop bit,  No loopback
 7                                                         // No parity,8 char bits,
 8                                                         // async mode, idle-line protocol
 9     ScibRegs.SCICTL1.all =0x0003;  // enable TX, RX, internal ScibLK,
10                                                        // Disable RX ERR, SLEEP, TXWAKE
11 
12     ScibRegs.SCICTL1.bit.RXERRINTENA=1; //使能错误接收中断
13 
14     ScibRegs.SCICTL2.all =0x0003;
15     ScibRegs.SCICTL2.bit.TXINTENA = 1;
16     ScibRegs.SCICTL2.bit.RXBKINTENA =1;
17 
18     #if (CPU_FRQ_150MHZ)
19           ScibRegs.SCIHBAUD    =0x0000;                                                   
20                                                             // 19200 baud @LSPCLK = 37.5MHz.
21           ScibRegs.SCILBAUD    =0x00F3;
22     #endif
23     #if (CPU_FRQ_100MHZ)
24       ScibRegs.SCIHBAUD    =0x0001;  // 9600 baud @LSPCLK = 20MHz.
25       ScibRegs.SCILBAUD    =0x0044;
26     #endif
27     ScibRegs.SCICTL1.all =0x0023;  // Relinquish SCI from Reset
28 }
 1 interrupt void SCIRXINTB_ISR(void)     // SCI-B中断
 2 {
 3 
 4     if(ScibRegs.SCIRXST.bit.RXERROR == 1)    //SW RESET
 5     {
 6            ScibRegs.SCICTL1.bit.SWRESET = 0;
 7            DELAY_US(1000);
 8            ScibRegs.SCICTL1.bit.SWRESET = 1;
 9     }
10 
11    
12 //   正常SCI中断函数
13 //   ...
14 //   ...
15 //   ...
16 
17     PieCtrlRegs.PIEACK.bit.ACK9 = 1;
18     EINT;
19 }
原文地址:https://www.cnblogs.com/Fangjq2020/p/13205808.html