DSP28335 SCI communication problem summary and problem summary[Copy link]
In the process of learning, it is inevitable to encounter some problems. I hope that by writing these problems down, I hope that the masters can give me some advice; I also hope that this way can help new learners who come later. The first step is always difficult, and I have a deep understanding of it; finally, I hope that everyone will actively discuss, brainstorm, and learn from each other. My literary talent is very poor, and I will try my best to express the problem clearly. Let's get to the point: I have been studying 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 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 to write on the datasheet 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, you can also propose it, 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 for a lot of information on the Internet but couldn't find it. Occasionally I saw a forum saying that if it doesn't work, use TI's own routine, which contains interrupt mode routines. TI's routine register settings are: 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; ScibRegs.SCICCR.bit.LOOPBKENA =1; // En loopable 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, 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 refer to TI routines. Many routines that come with the development board are also modified from them, and most of them do not have interrupt mode, only query mode. 3. SCI's FIFO mode does have many advantages, but I think of a problem; when using FIFO to receive data, interrupt mode is also used; how to set RXFFIL4 -0, which 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. However, there is a problem that the data I receive may be less than 16, so the receive interrupt will not be able to occur. This is a common situation. One way is to set RXFFIL4-0 to 1, which will lose the advantage of FIFO. I wonder if anyone has a good solution. I hope everyone can discuss it.
Hello, I found that the SCi FIFO send interrupt will enter two interrupts. I enabled the send interrupt in the receive interrupt, and then the send interrupt only cleared the flag bit without sending any data. I found that the send interrupt count was 2.
Details
Published on 2018-7-19 17:25
Hello, I found that the SCi FIFO send interrupt will enter two interrupts. I enabled the send interrupt in the receive interrupt, and then the send interrupt only cleared the flag bit without sending any data. I found that the send interrupt count was 2.