DSP28335 SCI communication problem summary and problem summary
[Copy link]
It is inevitable to encounter some problems in the learning process. I hope that by writing these problems down, on the one hand, I hope that the masters can give me some advice; I also hope that this method can help new learners who come later as a hint. The first step is always difficult, and I have a deep understanding of this. Finally, I also hope that everyone will actively discuss, brainstorm, and learn from each other.
Let's get to the point: I have been learning SCI communication in recent days. I thought it should not be difficult because I had experience with 51 serial ports before. But in fact, it is not as easy as I imagined.
1. First, the interrupt setting service program in non-FIFO mode cannot directly enter the sending interrupt; you need to send a byte of data before entering the interrupt;
according to the 51 mode, when sending data, directly TI = 1, directly enter the serial port data sending interrupt service program, and then set TI = 0 in the interrupt function;
void TXD_ISR() interrupt 4
{
if(TI)
{
TI = 0 ;
SBUF = xxx;
}
}
But 28335 does not have this flag bit, I don’t know if this counts as ScibRegs.SCICTL2.bit.TXRDY, how does the datasheet write if(ScibRegs.SCICTL2.bit.TXRDY == 1) ScibRegs.SCITXBUF = msg[x]; it will be automatically cleared; and this bit is always 1 when SCI is reset; according to common sense, if only the interrupt register is configured, you can directly enter the interrupt according to the 51 mode, but the fact is that this cannot enter the interrupt. Debugging the actual data found: PieCtrlRegs.PIEIFR9.bit.INTx4 = 0 is not set to 1, so the middle segment cannot occur;
I encountered such a problem, I wonder if you have found this problem; if anyone has a solution, please put it forward and learn from each other; some may say, why not use FIFO, it can reduce the CPU burden. Yes, I also want to be right, so I also wrote a FIFO interrupt program, but according to the routine on the development board, I also encountered the following problem; that is problem 2!
2. Use FIFO to interrupt incomplete data transmission.
The FIFO configuration is as follows:
void scic_fifo_init()
{
ScicRegs.SCIFFTX.all=0xE060;
ScicRegs.SCIFFRX.all=0x206f;
ScicRegs.SCIFFCT.all=0x0;
}
Interrupt service function
interrupt void SCIb_TX_FIFO_ISR()
{
unsigned char i;
if(TX_Len != 0)
{
if(TX_Len > 16)
{
for(i = 0; i < 16;i++)
{
ScibRegs.SCITXBUF = msg[txdataindex1++];
}
TX_Len -= 16;
}
else
{
for(i = 0;i < TX_Len;i++)
{
ScibRegs.SCITXBUF = msg[txdataindex1++];
}
ScibRegs.SCICTL1.bit.TXENA = 0;
ScibRegs.SCICTL1.bit.RXENA = 1;
txdataindex1 = 0;
receivefinishflag = 0x00;
}
}
ScibRegs.SCIFFTX.bit.TXFFINTCLR = 1;
PieCtrlRegs.PIEACK.bit.ACK9 = 1;
}
But there is a problem; when TX_Len > 16, the number of data sent is: temporarily marked as n = TX_Len % 16;
for example: msg = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}
if TX_Len = 10; the data sent is 0,1,2,3,4,5,6,7,8,9
If TX_Len = 10; the data sent is 0,1,2,3
Why does this happen?
for(i = 0; i < 16;i++)
{
ScibRegs.SCITXBUF = msg[txdataindex1++];//This sentence is also executed, but there is no response
}
TX_Len -= 16;//=This sentence is executed
I think there must be a problem with the register setting, but I can't tell. I have also searched a lot of information on the Internet but can't find it. Occasionally I saw a forum saying that if it doesn't work, use TI's own routine, which has an interrupt mode routine. TI's routine register setting is:
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,
// Disable RX ERR, SLEEP, TXWAKE
ScibRegs.SCICTL2.bit.TXINTENA =1;
ScibRegs.SCICTL2.bit.RXBKINTENA =1;
ScibRegs.SCIHBAUD =0x0000;
ScibRegs.SCILBAUD =SCI_PRD;
gs.SCICCR.bit.LOOPBKENA =1; // Enable loop back
ScibRegs.SCIFFTX.all=0xC028;
ScibRegs.SCIFFRX.all=0x0028;
ScibRegs.SCIFFCT.all=0x00;
ScibRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset
ScibRegs.SCIFFTX.bit.TXFIFOXRESET=1;
ScibRegs.SCIFFRX.bit.RXFIFORESET=1;
}
Compare the FIFO settings and you will find the main difference. Of course, the interrupt data comparison does not count.
In fact, the main difference is that my FIFO initialization clears
ScibRegs.SCICTL2.bit.TXRDY to zero; ScibRegs.SCIFFTX.bit.TXFFINTCLR = 1; while TI's standard routine does not clear it to zero;
reset according to TI standards; everything runs OK;
Lessons learned: As a beginner, I suggest you try to follow the TI routines. Many of the routines that come with the development board are also modified from them, and most of them do not provide interrupt mode, only query mode;
3. SCI's FIFO mode does have many advantages, but I have a question: when using FIFO to receive data, the interrupt mode is also used; how to set RXFFIL4-0, that is, the receive interrupt comparison value;
for example, if I set it to 16, an interrupt will only occur when the received data is greater than or equal to 16, but there is a problem that the data I receive may be less than 16, so it will not be able to enter the receive interrupt,
and this is a common situation.
One way is to set RXFFIL4-0 to 1, which loses the advantage of FIFO. I wonder if you have a good solution. I hope everyone can discuss it.
|