最近在调试TMS320F2812的SCI异步串口通讯时,一块DSP用于传输数据,另一块DSP用于接收数据,为节省DSP开销,采用FIFO中断的方式进行数据传输,波特率设置为115200bps,每包数据传输8个字节,实际传输过程中会出现发送FIFO队列的首个数据字buffer【0】对应的不是接收FIFO队列的首个数据字,导致DSP无法对接收到的数据进行有效处理。
由于FIFO队列有16级的收发缓冲器,目前采取的方法是,将每包要发送的8个字节复制为2份,也就是每包数据传输16个字节,buffer【0】~buffer【7】与 buffer【8】~buffer【15】发送的数据完全相同。DSP接收FIFO队列也是接收16个字节,通过对接收的数据进行查找首字节0xAA和0x55来确定具体的有效buffer区段,读取该字段即可找到正确有效数据,具体接收代码如下:
for(j=0;j<16;j++) //取SCIB接收Buffer中的数据
{
SCIRXB_buffer[j]=ScibRegs.SCIRXBUF.all;
}
for(m=0;m<16;m++)
{
if((SCIRXB_buffer[m]==0xAA)&&(SCIRXB_buffer[m+1]==0x55))
{
for(k=0;k<8;k++)
{
SCIB_JS_buffer[k]=SCIRXB_buffer[m+k];
}
}
else
flag_SCIRX_Success=0; //通讯数据接收失败
}
for(n = 0; n < 7; n++) //计算接收到字节的校验和
{
sum += SCIB_JS_buffer[n];
}
sum = sum % 256;
jyh = (char)sum;
jyh = ~jyh + 1;
jyh = jyh & 0x00FF;
if(jyh==SCIB_JS_buffer[7])
{
flag_SCIRX_Success=1;//通讯数据接收成功
}
else
flag_SCIRX_Success=0; //通讯数据接收失败
该通讯方式的缺点是每次发送数据都会丢掉一包数据,通过RingBuffer环形缓冲区可避免该问题,后续可继续研究。
在通讯过程中遇到的问题是,我们在定时器1下溢中断T1UFINT_ISR()中进行定时,设置数据发送为每10ms发送一次,波特率为115200bps,一个起始位(低),8个数据位,一个校验位,一个停止位(0),一个有16个字,也就是我们每次发送一包数据所需要的时间1/1152001116=1.528ms。
实际调试过程中接收DSP经常无法接收到数据,通过仿真器设置断点也经常进不了FIFO接收中断,但单独的通过串口与PC端进行连接时,收发DSP均可正常工作。通过示波器可以看到DSP在不断地发送数据,正常来讲DSP发送数据有1.5ms左右数据波形后会有一个8ms左右的持续高电平,但实际波形如下,可判断DSP的数据发送出现了问题。
经排查,在主周期中通过定时器1设置数据发送函数 MsgSent()的发送时间间隔是10ms,在 MsgSent()函数中将发送FIFO中断TXFFIENA设置为1。
if(ScibRegs.SCIFFTX.bit.TXFFIENA==0)
{
ScibRegs.SCIFFTX.bit.TXFFIENA=1; //使能发送FIFO中断
}
当发送FIFO字寄存器TXFFST的值和发送中断级位TXFFIL中的预设值相等时,发送FIFO产生发送中断匹配事件,发送寄存器FIFO产生发送中断TXINT信号,而发送FIFO中断使能位TXFFIENA在MsgSent()函数中已经设置为1了,此时DSP响应FIFO发送中断,最关键的是发送中断标志清除位TXINTCLR设置在FIFO发送中断函数interrupt void SCITXINTB_ISR(void) 中
ScibRegs.SCIFFTX.bit.TXINTCLR=1; //清除发送中断标志位,使其响应新的中断
在FIFO发送中断中每次将数组内的数据赋给SCITXBUF后,通过TXFFST的值和发送中断级位TXFFIL中的预设值相等,发送FIFO产生发送中断匹配事件,而FIFO发送中断内部自身将发送中断标志位清除了,导致了FIFO发送中断不停的产生中断事件。后续将清除发送中断标志位放置于 MsgSent()函数中可解决此问题。
Uint16 i;
for(i=0;i<16;i++)
{
ScibRegs.SCITXBUF=SCITXB_buffer[i];
}