1. SCI FIFO发送流程
- 将内存数据放置发送缓存当中
ScibRegs.SCITXBUF=’A’;
- 发送缓存中的数据自动存到FIFO当中
ScibRegs.SCITXBUF中的数据会放入到发送FIFO中,最多16字节数据如果连续发送的字节数量大于16需要等待,否则发送的数据将会被覆盖
- 发送FIFO将数据转到发送移位寄存器TXSHF当中
FIFO会自动将数据发送到移位寄存器TXSHF中最终到TXD引脚
2. SCI FIFO接收流程
- 数据到达RXD引脚之后,检测启动位
- TXSHF移位到接收FIFO当中
当FIFO接收字节数量等于设置的接收FIFO深度ScibRegs.SCIFFRX.bit.RXFFIL = 8时产生一个中断
- 如果使能了接收中断将会产生一个中断
3 代码示例
3.1 初始化配置
该示例的主要功能
- 连续多数据发送
- 一次性接收8个字节数据并将其打印输出
void scib_xmit(char a);
void scib_msg(char *msg, Uint16 len);
volatile Uint16 g_received_flag = 0;
Uint16 g_recv_buff[256];
void main(void)
{
Uint16 i;
char *msg;
InitSysCtrl();
InitSciGpio();
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
EALLOW; // This is needed to write to EALLOW protected registers
// PieVectTable.SCIRXINTA = &sciaRxFifoIsr;
// PieVectTable.SCITXINTA = &sciaTxFifoIsr;
PieVectTable.SCIRXINTB = &scibRxFifoIsr;
PieVectTable.SCITXINTB = &scibTxFifoIsr;
EDIS; // This is needed to disable write to EALLOW protected registers
scib_fifo_init(); // Init SCI-B
// Enable interrupts required for this example
PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block
PieCtrlRegs.PIEIER9.bit.INTx3=1; // PIE Group 9, INT3
// PieCtrlRegs.PIEIER9.bit.INTx4=1; // PIE Group 9, INT4
IER = 0x100; // Enable CPU INT
EINT;
msg = "123456789012345678901234567890\n\0";
scib_msg(msg,strlen(msg));
for(;;)
{
if(g_received_flag == 1)
{
g_received_flag = 0;
scib_msg(g_recv_buff, 8);//打印出接收到的数据
}
}
}
3.2 SCI 配置
void scib_fifo_init()
{
ScibRegs.SCICCR.all =0x0007; // 1 stop bit,No loopback No parity,8 char bits,async mode, idle-line protocol
ScibRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
// ScibRegs.SCICTL2.bit.TXINTENA =1;//禁用发送中断
ScibRegs.SCICTL2.bit.RXBKINTENA =1;//使能接收中断
//波特率设置寄存器BRR = LSPCLK/(波特率*8)-1
#if (CPU_FRQ_150MHZ)
ScibRegs.SCIHBAUD =0x0001; // 9600 baud @LSPCLK = 37.5MHz.
ScibRegs.SCILBAUD =0x00E7;
#endif
ScibRegs.SCICCR.bit.LOOPBKENA = 0; // disable loop back Enable loop back
// ScibRegs.SCIFFTX.all=0xC028;
ScibRegs.SCIFFTX.bit.SCIRST = 1; //1-SCI重新开始接收和发送,0-复位SCI
ScibRegs.SCIFFTX.bit.SCIFFENA = 1; //FIFO使能
ScibRegs.SCIFFTX.bit.TXFFIL = 8; //发送FIFO8级即发送8个字节产生一次发送中断,如果使能了
// ScibRegs.SCIFFTX.bit.TXFFIENA = 1; //发送FIFO中断禁止使用
// ScibRegs.SCIFFRX.all=0x0028;
ScibRegs.SCIFFRX.bit.RXFFIENA = 1; //接收FIFO中断使能
ScibRegs.SCIFFRX.bit.RXFFIL = 8; //接收FIFO8级即接收8个字节产生一次发送中断,如果使能了
ScibRegs.SCIFFCT.all=0x00; //无发送延迟
ScibRegs.SCICTL1.bit.SWRESET =1; // 通过写1重新使能SCI,该复位每种外设都有
ScibRegs.SCIFFTX.bit.TXFIFOXRESET=1; //发送重新使能
ScibRegs.SCIFFRX.bit.RXFIFORESET=1; //接收重新使能
}
3.3 发送和接收
void scib_xmit(char a)
{
ScibRegs.SCITXBUF=a;
//在此做判断,如果发送FIFO缓冲中数据 >= 16字节,要等待下直到FIFO小于16才能再次向FIFO中存数据
while(ScibRegs.SCIFFTX.bit.TXFFST >= 16){;}
}
void scib_msg(char * msg, Uint16 len)
{
int i;
for(i = 0;i < len;i++)
{
scib_xmit(msg[i]);
}
}
__interrupt void scibRxFifoIsr(void)
{
Uint16 i;
for(i=0;i<8;i++)
{
g_recv_buff[i] =ScibRegs.SCIRXBUF.all;
}
g_received_flag = 1;
ScibRegs.SCIFFRX.bit.RXFFOVRCLR=1; // Clear Overflow flag
ScibRegs.SCIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag
PieCtrlRegs.PIEACK.all|=0x100; // Issue PIE ack
}
4 总结
- 使用FIFO发送不能连续发送超过16字节数据,所以上面的程序进行了判断
- 接收FIFO存在很明显的缺陷:只有收到指定长度的数据时才会产生中断,对于固定长度的数据通信协议而言非常有帮助;但是对于变长的数据接收只能使用一个字节中断一次的方式进行处理,这样接收FIFO没有任何的优势。
- 发送FIFO不建议中断使能,因为它会频繁中断
- 总之DSP的SCI没法做到变长数据帧中断