当执行 SCI 通信时、如果在末尾发送多个带有多个空值的数据段、则会出现数据无法正常接收的问题。
SCI 端口寄存器的复位不会解决问题。
由于在复位 CPU 并重新执行后可以正常接收数据、因此认为原因是 SCI 驱动程序。
可能的原因是什么?
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
当执行 SCI 通信时、如果在末尾发送多个带有多个空值的数据段、则会出现数据无法正常接收的问题。
SCI 端口寄存器的复位不会解决问题。
由于在复位 CPU 并重新执行后可以正常接收数据、因此认为原因是 SCI 驱动程序。
可能的原因是什么?
尊敬的 Ryo:
感谢您的提问。
我立即怀疑的是下面这个主题中的最后一个"建议答案": https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1198816/tms320f280025-sci-communications-byte-timing
基本上、如果您要背靠背发送大量数据(使用中断、特定情况下仅发生中断)、C2000器件必须接收数据字节之间有2个停止位的数据。 原因在该主题中进行了说明。
在向 C2000器件发送数据时、请向 C2000器件发送2个停止位。 请告诉我这是否解决了此问题!
此致、
Vince
您好 Vince。
感谢您的回答。
首先、我将停止位设置为2、这样该方法没有解决问题。
另外、即使速度降低到9600bps、结果也没有变化、因此事实证明这不是速度问题。
我的 SCI 设置是115200bps、字大小8位、秒2位、偶校验。
我要发送到 SCI 端口的数据是 ASCII 字符串和二进制数据的组合。
下面是一个示例命令。
例如、<53><49><47><3A><4D><4E><49><02><00><00><00><00><00>
首先、数据传输/接收使用通用 LAN 串行适配器与 PC 通信。
数据接收频率使得上述命令每3秒发出一次。
然后、数据采集使用 FIFO 中断每个字符并将其存储在其自己的缓冲区中。
之后、使用计时器实现超时并执行任务处理。
事件发生后、从 LAN 串行适配器执行一次传输。
在接收操作中、任务处理被输入两次。
当我检查数据时、第一次在中途收到命令、第二次收到的却没有正常数据。 (或无数据)
关于开始时问题的内容、执行上述命令大约8次即会发生此问题。
有其他命令、但我认为其他命令不太可能导致问题、因为只有很少的0x00数据为 NULL。
谢谢你。
Ryo。
尊敬的 Ryo:
首先,我将停止位设置为2,这样该方法就不能解决问题。
此外,即使速度降低到9600bps ,结果没有改变,因此它证明这不是一个速度问题。[/报价]正如我在该线程中提到的、这不是波特率速度的问题、而是计时的问题。 使用少于2个停止位的时间是问题所在。 您可以使用4800或更低的波特率、并且仍然可以看到此问题。
我将停止位设置为2如果您在 C2000器件上设置了2个停止位、这不会解决问题。
您必须在另一个器件(PC)上设置2个停止位。
此致、
Vince
[/quote]
您好 Vince。
正常时发送通信捕获、发生异常时发送捕获。
这是我创建的应用程序正常时的通信和发生错误时的通信。
这是正常情况下的缓冲区数据。
这是异常时的缓冲区数据。(1次)
这是异常时的缓冲区数据。(2次)
发生错误时、这是寄存器的 RX 部分。
这是与 SCI 通信相关的完整代码。
void Hwi_PCConnect_RX(){ char rx_data; // Message_queue("PCConnect",0); if(Ext_File_WR_Flag||SPI_W_Flag){ SCI_Timeout_Flag_Post(PCConnect_BASE); SCI_ReadChar(PCConnect_BASE,&rx_data); SPI_SendData_Buf[PC_Read_Count]=rx_data; SCI_clearInterruptStatus(PCConnect_BASE, SCI_INT_RXFF); if(PC_Read_Count==4095){ if(Ext_File_WR_Flag)Semaphore_post(Semaphore_PCConnect); else if(SPI_W_Flag)Semaphore_post(Semaphore_SPI); } else PC_Read_Count++; } else{ SCI_Timeout_Flag_Post(PCConnect_BASE); SCI_ReadChar(PCConnect_BASE,&rx_data); SCI_Buffer_Input(PCConnect_BASE,rx_data); SCI_clearInterruptStatus(PCConnect_BASE, SCI_INT_RXFF); } if((*((uint16_t*)(PCConnect_BASE+SCI_O_RXST))&(SCI_RXST_BRKDT|SCI_RXST_FE))!=0){ SCI_disableModule(PCConnect_BASE); SCI_clearInterruptStatus(PCConnect_BASE, SCI_INT_RXFF | SCI_INT_TXFF | SCI_INT_FE | SCI_INT_OE | SCI_INT_PE | SCI_INT_RXERR | SCI_INT_RXRDY_BRKDT | SCI_INT_TXRDY); SCI_clearOverflowStatus(PCConnect_BASE); SCI_resetTxFIFO(PCConnect_BASE); SCI_resetRxFIFO(PCConnect_BASE); SCI_resetChannels(PCConnect_BASE); SCI_setConfig(PCConnect_BASE, DEVICE_LSPCLK_FREQ, PCConnect_BAUDRATE, (SCI_CONFIG_WLEN_8|SCI_CONFIG_STOP_TWO|SCI_CONFIG_PAR_ODD)); SCI_disableLoopback(PCConnect_BASE); SCI_performSoftwareReset(PCConnect_BASE); SCI_enableInterrupt(PCConnect_BASE, SCI_INT_RXFF | SCI_INT_TXFF); SCI_setFIFOInterruptLevel(PCConnect_BASE, SCI_FIFO_TX5, SCI_FIFO_RX1); SCI_enableFIFO(PCConnect_BASE); SCI_enableModule(PCConnect_BASE); } } /// /// PCConnect_Swi_Function /// void Swi_PCConnect_WriteData(){ if(Ext_File_WR_Flag&&Access_Mode==0) SCI_writeCharArray(PCConnect_BASE,(uint16_t*)SPI_ReadData_Buf,SPI_ReadDataSize); else SCI_writeCharArray(PCConnect_BASE, (uint16_t*)Ret ,Send_Byte); } /// /// PCConnect_Task_Function /// void Task_PCConnect(){ uint16_t size; uint16_t fail_comm_size=0; uint16_t error=0; while(1){ if(Init_Flag) break; } while(1){ Semaphore_pend(Semaphore_PCConnect,BIOS_WAIT_FOREVER); Message_queue("PCConnect",3); do{ if(Ext_File_WR_Flag||SPI_W_Flag){ if(Access_Mode){ //Write PC_Read_Count++; if(File_Size>PC_Read_Count)File_Size-=PC_Read_Count; else{ PC_Read_Count=File_Size; File_Size=0; File_WR_EndFlag=1; } size=PC_Read_Count; PC_Read_Count=0; SD_Use_Data_Address=SPI_SendData_Buf; SD_Size=size; Swi_post(swi_File); if(File_WR_EndFlag==1){ ffcio_close(SD_FileNo); Ext_File_WR_Flag=0; } } else{ //Read Semaphore_post(semaphore_FileRead); Semaphore_pend(semaphore_ReadWait,BIOS_WAIT_FOREVER); if(File_Size>SPI_ReadDataSize)File_Size-=SPI_ReadDataSize; else{ SPI_ReadDataSize=File_Size; File_Size=0; File_WR_EndFlag=1; } Swi_post(swi_PCConnect); if(File_WR_EndFlag==1){ ffcio_close(SD_FileNo); Ext_File_WR_Flag=0; if(SD_FileNo<=1){ if(SD_FileNo){ strcpy(FilePath,LOG_DIR); strcpy(FilePath,"LOG"); strcpy(FilePath,uint16_t_to_string(Start_Count)); strcpy(FilePath,".LOG"); ffcio_open(FilePath,O_RDWR|O_APPEND,0); } else{ strcpy(FilePath,STREAM_DIR); strcpy(FilePath,"STREAM"); strcpy(FilePath,uint16_t_to_string(Start_Count)); strcpy(FilePath,".LOG"); ffcio_open(FilePath,O_RDWR|O_APPEND,0); } } } } } else{ command=(Module_Command){0}; if(fail_comm_size!=0&&PCConnect_Buf.Position<6){ memcpy(&PC_Readdata[fail_comm_size],PCConnect_Buf.Buf_Data,PCConnect_Buf.Position); if(PCConnect_Separate_CommandData(PC_Readdata,fail_comm_size+10,&command)==0){ Command_queue(&command); } memset(PC_Readdata, 0, 400); fail_comm_size=0; } else{ memcpy(PC_Readdata,PCConnect_Buf.Buf_Data,PCConnect_Buf.Position); if(PCConnect_Separate_CommandData(PC_Readdata,PCConnect_Buf.Position,&command)==0){ Command_queue(&command); memset(PC_Readdata, 0, 400); } else{ fail_comm_size=PCConnect_Buf.Position; error++; } } SCI_Buffer_Clear(PCConnect_BASE); // Response_Queue(&command,1); } }while(0); if(error>1){ SCI_disableModule(PCConnect_BASE); SCI_clearInterruptStatus(PCConnect_BASE, SCI_INT_RXFF | SCI_INT_TXFF | SCI_INT_FE | SCI_INT_OE | SCI_INT_PE | SCI_INT_RXERR | SCI_INT_RXRDY_BRKDT | SCI_INT_TXRDY); SCI_clearOverflowStatus(PCConnect_BASE); SCI_resetTxFIFO(PCConnect_BASE); SCI_resetRxFIFO(PCConnect_BASE); SCI_resetChannels(PCConnect_BASE); SCI_setConfig(PCConnect_BASE, DEVICE_LSPCLK_FREQ, PCConnect_BAUDRATE, (SCI_CONFIG_WLEN_8|SCI_CONFIG_STOP_TWO|SCI_CONFIG_PAR_ODD)); SCI_disableLoopback(PCConnect_BASE); SCI_performSoftwareReset(PCConnect_BASE); SCI_enableInterrupt(PCConnect_BASE, SCI_INT_RXFF | SCI_INT_TXFF); SCI_setFIFOInterruptLevel(PCConnect_BASE, SCI_FIFO_TX5, SCI_FIFO_RX1); SCI_enableFIFO(PCConnect_BASE); SCI_enableModule(PCConnect_BASE); error=0; } } } void SCI_Buffer_Input(uint32_t Base,char Data){ SCI_Read_Buf *buffer=0; buffer=SCI_Module_Identify_ReadBuf(Base); if(buffer->Position<SCI_BUFFER_SIZE){ buffer->Buf_Data[buffer->Position]=Data; } buffer->Position++; } void SCI_Get_Buffer_String(uint32_t Base,char *Data){ SCI_Read_Buf *buffer=0; buffer=SCI_Module_Identify_ReadBuf(Base); buffer->Buf_Data[buffer->Position]=0; strcpy(Data,buffer->Buf_Data); buffer->Position=0; } void SCI_Buffer_Clear(uint32_t Base){ SCI_Read_Buf *buffer=0; buffer=SCI_Module_Identify_ReadBuf(Base); buffer->Position=0; } void Timer_SCI_RX_Timeout(){ int i; uint32_t base; ti_sysbios_knl_Semaphore_Handle Semaphore=0; SCI_Read_Buf *buffer=0; for(i=0;i<4;i++){ base=SCI_BASE[i]; buffer=SCI_Module_Identify_ReadBuf(base); Semaphore=SCI_Module_Identify_Semaphore(base); if(buffer->RX_Flag){ if(buffer->RX_Interval>=buffer->RX_Timeout){ buffer->RX_Flag=0; buffer->RX_Interval=0; Semaphore_post(Semaphore); } buffer->RX_Interval++; } SCI_Repeat_Send_Post(base); } }
谢谢你。
Ryo
Ryo、
我是专门要求的 SCIRXST 寄存器在问题发生期间、您已经提供了其他寄存器、SCIRXST 将告诉我们 SCI-RX 引脚正在检测到哪些问题并可以快速诊断问题。
此外、请提供数据的示波器捕获、由于"Command Data"视图不够充分、表明有不良数据到达、但没有在 C2000器件的 SCI-RX 引脚显示波形。 我们需要了解数据为何看起来很糟糕(看看这是否是硬件或软件问题)
此致、
Vince
Ryo、
感谢您的跟进。 这两个问题中的一个可能是原因:
第一个可能的问题:奇偶校验不匹配
您最初说过:
我的 SCI 设置是115200bps,字大小8位,Stopbit 2位,偶校验。
您提供的代码中的奇偶校验是奇数("SCI_CONFIG_PAR_ODD")
请更正此问题、然后查看问题是否消失。 如果没有、请转至下面的第二个可能问题。
第二个可能的问题:ISR 较长导致移位
1.设置奇偶校验错误位(SCIRXST.PE)、表示假设奇偶校验位错误、表示它未检测到字节的正确部分
2.输入的数据是错误的数据(它从应该的位置被移动,并在错误的时间检测到错误的位,位是早期引入)。 这意味着它没有检测到字节的正确部分。
Action1:您可以尝试在从 PC 发送的字节之间添加较长的延迟(1ms)吗? 因此每次 PC 发送一个字节时、PC 都会等待1ms 再发送另一个字节。
由于 SCI ISR 的时间可能长于~200us、因此2个停止位在字节之间可能不够。
操作2:还请再次使用字节间额外的1ms 延迟来捕获数据。
此致、
Vince
您提供的代码中的奇偶校验语句错误。
Ryo、
我提供的代码就是您提供的代码、您是否在代码中更正了此代码? 请提供更新后的代码。 这是您之前提供的内容、并且使用了错误的奇偶校验:
void Hwi_PCConnect_RX(){ char rx_data; // Message_queue("PCConnect",0); if(Ext_File_WR_Flag||SPI_W_Flag){ SCI_Timeout_Flag_Post(PCConnect_BASE); SCI_ReadChar(PCConnect_BASE,&rx_data); SPI_SendData_Buf[PC_Read_Count]=rx_data; SCI_clearInterruptStatus(PCConnect_BASE, SCI_INT_RXFF); if(PC_Read_Count==4095){ if(Ext_File_WR_Flag)Semaphore_post(Semaphore_PCConnect); else if(SPI_W_Flag)Semaphore_post(Semaphore_SPI); } else PC_Read_Count++; } else{ SCI_Timeout_Flag_Post(PCConnect_BASE); SCI_ReadChar(PCConnect_BASE,&rx_data); SCI_Buffer_Input(PCConnect_BASE,rx_data); SCI_clearInterruptStatus(PCConnect_BASE, SCI_INT_RXFF); } if((*((uint16_t*)(PCConnect_BASE+SCI_O_RXST))&(SCI_RXST_BRKDT|SCI_RXST_FE))!=0){ SCI_disableModule(PCConnect_BASE); SCI_clearInterruptStatus(PCConnect_BASE, SCI_INT_RXFF | SCI_INT_TXFF | SCI_INT_FE | SCI_INT_OE | SCI_INT_PE | SCI_INT_RXERR | SCI_INT_RXRDY_BRKDT | SCI_INT_TXRDY); SCI_clearOverflowStatus(PCConnect_BASE); SCI_resetTxFIFO(PCConnect_BASE); SCI_resetRxFIFO(PCConnect_BASE); SCI_resetChannels(PCConnect_BASE); SCI_setConfig(PCConnect_BASE, DEVICE_LSPCLK_FREQ, PCConnect_BAUDRATE, (SCI_CONFIG_WLEN_8|SCI_CONFIG_STOP_TWO|SCI_CONFIG_PAR_ODD)); SCI_disableLoopback(PCConnect_BASE); SCI_performSoftwareReset(PCConnect_BASE); SCI_enableInterrupt(PCConnect_BASE, SCI_INT_RXFF | SCI_INT_TXFF); SCI_setFIFOInterruptLevel(PCConnect_BASE, SCI_FIFO_TX5, SCI_FIFO_RX1); SCI_enableFIFO(PCConnect_BASE); SCI_enableModule(PCConnect_BASE); } } /// /// PCConnect_Swi_Function /// void Swi_PCConnect_WriteData(){ if(Ext_File_WR_Flag&&Access_Mode==0) SCI_writeCharArray(PCConnect_BASE,(uint16_t*)SPI_ReadData_Buf,SPI_ReadDataSize); else SCI_writeCharArray(PCConnect_BASE, (uint16_t*)Ret ,Send_Byte); } /// /// PCConnect_Task_Function /// void Task_PCConnect(){ uint16_t size; uint16_t fail_comm_size=0; uint16_t error=0; while(1){ if(Init_Flag) break; } while(1){ Semaphore_pend(Semaphore_PCConnect,BIOS_WAIT_FOREVER); Message_queue("PCConnect",3); do{ if(Ext_File_WR_Flag||SPI_W_Flag){ if(Access_Mode){ //Write PC_Read_Count++; if(File_Size>PC_Read_Count)File_Size-=PC_Read_Count; else{ PC_Read_Count=File_Size; File_Size=0; File_WR_EndFlag=1; } size=PC_Read_Count; PC_Read_Count=0; SD_Use_Data_Address=SPI_SendData_Buf; SD_Size=size; Swi_post(swi_File); if(File_WR_EndFlag==1){ ffcio_close(SD_FileNo); Ext_File_WR_Flag=0; } } else{ //Read Semaphore_post(semaphore_FileRead); Semaphore_pend(semaphore_ReadWait,BIOS_WAIT_FOREVER); if(File_Size>SPI_ReadDataSize)File_Size-=SPI_ReadDataSize; else{ SPI_ReadDataSize=File_Size; File_Size=0; File_WR_EndFlag=1; } Swi_post(swi_PCConnect); if(File_WR_EndFlag==1){ ffcio_close(SD_FileNo); Ext_File_WR_Flag=0; if(SD_FileNo<=1){ if(SD_FileNo){ strcpy(FilePath,LOG_DIR); strcpy(FilePath,"LOG"); strcpy(FilePath,uint16_t_to_string(Start_Count)); strcpy(FilePath,".LOG"); ffcio_open(FilePath,O_RDWR|O_APPEND,0); } else{ strcpy(FilePath,STREAM_DIR); strcpy(FilePath,"STREAM"); strcpy(FilePath,uint16_t_to_string(Start_Count)); strcpy(FilePath,".LOG"); ffcio_open(FilePath,O_RDWR|O_APPEND,0); } } } } } else{ command=(Module_Command){0}; if(fail_comm_size!=0&&PCConnect_Buf.Position<6){ memcpy(&PC_Readdata[fail_comm_size],PCConnect_Buf.Buf_Data,PCConnect_Buf.Position); if(PCConnect_Separate_CommandData(PC_Readdata,fail_comm_size+10,&command)==0){ Command_queue(&command); } memset(PC_Readdata, 0, 400); fail_comm_size=0; } else{ memcpy(PC_Readdata,PCConnect_Buf.Buf_Data,PCConnect_Buf.Position); if(PCConnect_Separate_CommandData(PC_Readdata,PCConnect_Buf.Position,&command)==0){ Command_queue(&command); memset(PC_Readdata, 0, 400); } else{ fail_comm_size=PCConnect_Buf.Position; error++; } } SCI_Buffer_Clear(PCConnect_BASE); // Response_Queue(&command,1); } }while(0); if(error>1){ SCI_disableModule(PCConnect_BASE); SCI_clearInterruptStatus(PCConnect_BASE, SCI_INT_RXFF | SCI_INT_TXFF | SCI_INT_FE | SCI_INT_OE | SCI_INT_PE | SCI_INT_RXERR | SCI_INT_RXRDY_BRKDT | SCI_INT_TXRDY); SCI_clearOverflowStatus(PCConnect_BASE); SCI_resetTxFIFO(PCConnect_BASE); SCI_resetRxFIFO(PCConnect_BASE); SCI_resetChannels(PCConnect_BASE); SCI_setConfig(PCConnect_BASE, DEVICE_LSPCLK_FREQ, PCConnect_BAUDRATE, (SCI_CONFIG_WLEN_8|SCI_CONFIG_STOP_TWO|SCI_CONFIG_PAR_ODD)); SCI_disableLoopback(PCConnect_BASE); SCI_performSoftwareReset(PCConnect_BASE); SCI_enableInterrupt(PCConnect_BASE, SCI_INT_RXFF | SCI_INT_TXFF); SCI_setFIFOInterruptLevel(PCConnect_BASE, SCI_FIFO_TX5, SCI_FIFO_RX1); SCI_enableFIFO(PCConnect_BASE); SCI_enableModule(PCConnect_BASE); error=0; } } } void SCI_Buffer_Input(uint32_t Base,char Data){ SCI_Read_Buf *buffer=0; buffer=SCI_Module_Identify_ReadBuf(Base); if(buffer->Position<SCI_BUFFER_SIZE){ buffer->Buf_Data[buffer->Position]=Data; } buffer->Position++; } void SCI_Get_Buffer_String(uint32_t Base,char *Data){ SCI_Read_Buf *buffer=0; buffer=SCI_Module_Identify_ReadBuf(Base); buffer->Buf_Data[buffer->Position]=0; strcpy(Data,buffer->Buf_Data); buffer->Position=0; } void SCI_Buffer_Clear(uint32_t Base){ SCI_Read_Buf *buffer=0; buffer=SCI_Module_Identify_ReadBuf(Base); buffer->Position=0; } void Timer_SCI_RX_Timeout(){ int i; uint32_t base; ti_sysbios_knl_Semaphore_Handle Semaphore=0; SCI_Read_Buf *buffer=0; for(i=0;i<4;i++){ base=SCI_BASE[i]; buffer=SCI_Module_Identify_ReadBuf(base); Semaphore=SCI_Module_Identify_Semaphore(base); if(buffer->RX_Flag){ if(buffer->RX_Interval>=buffer->RX_Timeout){ buffer->RX_Flag=0; buffer->RX_Interval=0; Semaphore_post(Semaphore); } buffer->RX_Interval++; } SCI_Repeat_Send_Post(base); } }
㎳由于数据包而插入250 μ s 的延迟。
每个数据包之间的延迟是否为250ms? 还是每个字节? 如果是每个数据包、那么它不会解决问题。 必须位于每个字节之后。
如果它介于每个字节之间、则 PC 上可能存在波特率不匹配或设置不匹配。
此致、
Vince