DSP28335RS485SCI串⼝通讯出错⽆法进⼊中断项⽬上通过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 5−2: 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通讯恢复正常。⾄于为何会出现错误,由于通讯程序并没有改动,正常跑了⼤约⼀周突然连续出现错误,只能暂时理解成是环境电磁⼲扰导致的错误吧。。。
下⾯附上修改后的代码供有需要的同学取⽤
1void 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 }