本帖最后由 Ryanhsiung 于 2013-6-22 16:58 编辑
环境:UC/OS-II 5个任务
中有一个任务做I2C动力(操作屏,大概占CPU 50%)
中有一个任务做串口的动作(间隔500ms)。
其它3个任务都很小
103RC没有FIFO,我也没有启用DMA
串口使用中断进行收发
问题描述:
1、在特定状态下,串口再有时只能接收到前8个数据 (概率基本几分钟就会出现1-2次)
特定状态描述:在I2C不稳定时触发,触发后问题会一直出现,只有将设备断电重启后恢复正常。
2、出现最多连续出现10次,未出现超过10次的
3、串口接收到的是前面8个数据,后面都没有接收
4、SPI操作也受到的相应的影响,有些时候写入到FLASH的数据为变与乱码
一些数据:
1、UART外设的寄存器与 正常时无异常
2、不管我将发送后等待接收的延时 调到多少,每次都只接收到8的数据
3、设备CPU占用率高时,出现频率更高
4、我将相关任务的堆栈放大的一倍,现象依旧
5、2/10的设备有这个问题,但其它设备若人为将I2C处于非正常状态,也会触发这个问题
我的怀疑:
1、I2C的不稳定引发 芯处及外设不稳定,在这个状态下SPI外设也出现有不正常的操作。
先前有出现I2C死掉,导致芯片中断异常关闭的问题。(现增加了I2C及中断的自动复位)
大家可能会说这个不就会引起接收不全的问题么,但是每次都是8个数据,且只要I2C一次不稳定,就会连续出现这个问题。
2、I2C的不稳定引起,导致任务堆栈、OS不稳定引起。最后触发相应问题
附上代码:
- // 将uart3 的变量全部封装进去
- SlaveUartStruct slave_uart;
- // 由于采用结构体初始化不方便,一初始化就全部初始化,不想初始化的也会被初始化
- // 后续扩展较麻烦
- void sUart3_VariableInit(void)
- {
- slave_uart.p_uart3_sendbuffer = slave_uart.buart3_SendBuffer;
- slave_uart.p_uart3_recbuffer = slave_uart.buart3_RecBuffer;
- slave_uart.bUart3FeedbackCount = 0;
- }
- /*****************************************************************************************
- * Function name : sUartWaitReciveOK().
- * Description :
- * Input para(s) : sstring 发送缓区
- rstring 接收缓冲区
- timeout 表示超时的时,20ms为一格.
- ack 暂无意思,本想留做是否需要回应处理
- * Output para(s): none.
- * Caller(s) : USART1_IRQHandler().
- * Note(s) : 等待接受数据完成
- sUart3SendData( slave_uart.buart3_SendBuffer,slave_uart.buart3_RecBuffer,timeout,TRUE)
- *****************************************************************************************/
- u8 sUart3SendData(const u8* sstring, u8* rstring,u8 timeout,bool ack)
- {
- uint8_t temp_delay = 0 ;
- slave_uart.bUart3FeedbackCount =0; // 回送个数清0
- slave_uart.bUartSendSlaveCount = 0; // 发送个数先清0 ,
- slave_uart.p_uart3_sendbuffer = sstring ; // 确定指针
- slave_uart.p_uart3_recbuffer = rstring ; //
- if(sstring[3]>90) // 现发送缓冲区最大为100
- {
- return FALSE;
- }
- slave_uart.bUartSendSlaveNum = sstring[3]+4 ; // 要发送的个数 bUartSendSlaveNum = bUart4RxComandBuf[3]+4 ;
- // USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); //打开串口接收中断 这个最好放到发送中断之后
- USART_SendData(USART3, slave_uart.p_uart3_sendbuffer[slave_uart.bUartSendSlaveCount++]);
- USART_ITConfig(USART3, USART_IT_TXE , ENABLE); //关闭串口中断
- while(temp_delay++ < timeout) // 最长等待的时间,超时
- {
- OSTimeDly(10);
- if(slave_uart.bUart3FeedbackCount >= 5)
- { //
- if(slave_uart.bUart3FeedbackCount > slave_uart.p_uart3_recbuffer[2]+4)
- {
- temp_delay = 99;
- break; // 提前退出
- }
- }
- }
- // 这里加入延时无做用
- // receive
- USART_ITConfig(USART3, USART_IT_TXE , DISABLE); //关闭串口中断
- USART_ITConfig(USART3, USART_IT_RXNE , DISABLE); //关闭串口中断
- if(temp_delay == 99)
- {
- return TRUE;
- }else
- {
- return FALSE;
- }
- }
- /*****************************************************************************************
- * Function name : sUart3RxInterrupt().
- * Description : USART1接收中断执行程序.
- * Input para(s) : none.
- * Output para(s): none.
- * Caller(s) : USART1_IRQHandler().
- * Note(s) : 中断接收数据,将数据放入到队列中
- *****************************************************************************************/
- void sUart3RxInterrupt(void)
- {
- if(slave_uart.bUart3FeedbackCount>200)
- { // 若大于200关中断
- USART_ITConfig(USART3, USART_IT_RXNE , DISABLE);
-
- // 打开中断放置到发送完成处,以期望解决通道故障的问题
-
- }
- slave_uart.p_uart3_recbuffer[slave_uart.bUart3FeedbackCount++] = USART_ReceiveData(USART3);
- }
- /*****************************************************************************************
- * Function name : sUart3TxInterrupt().
- * Description : USART1发送中断执行程序(send the data from data buffer to FIFO).
- * Input para(s) : none.
- * Output para(s): none.
- * Caller(s) : USART1_IRQHandler().
- * Note(s) : 串口中断发送数据,根据wTxLength发送数据
- *****************************************************************************************/
- void sUart3TxInterrupt(void)
- {
- USART_SendData(USART3,slave_uart.p_uart3_sendbuffer[slave_uart.bUartSendSlaveCount++]);
- if(slave_uart.bUartSendSlaveCount>slave_uart.bUartSendSlaveNum)
- {
- USART_ITConfig(USART3, USART_IT_TXE, DISABLE);
- USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); //打开串口接收中断
- }
- }
|