久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

標(biāo)題: 關(guān)于MCU USART-DMA數(shù)據(jù)傳輸?shù)囊粋(gè)bug請(qǐng)教 [打印本頁(yè)]

作者: liuchao626    時(shí)間: 2023-4-28 15:59
標(biāo)題: 關(guān)于MCU USART-DMA數(shù)據(jù)傳輸?shù)囊粋(gè)bug請(qǐng)教
問(wèn)題描述:奇怪的MCU bug
16進(jìn)制給板子發(fā)送數(shù)據(jù)
比如:
串口助手:發(fā)-04 03 01 02 03 0A C5 98
板子          收-04 03 01 02 03 0A C5 98
就能完成的完成數(shù)據(jù)傳輸
但是發(fā)
發(fā)-04 03 00 00 00 0A C5 98時(shí)


收到的就是
收-04 03 00 00 00 00 00 00

數(shù)據(jù)流收發(fā)沒(méi)問(wèn)題,但是只要是00,就會(huì)把后面的數(shù)據(jù)給抹掉
串口中斷:
  1. void USART1_IRQHandler(void)
  2. {
  3.     OSIntEnter();

  4.     HAL_UART_IRQHandler(&huart1);

  5.         user_uart1IT_ReceiveCallback();
  6.    
  7.     OSIntExit();
  8. }

  9. void user_uart1IT_ReceiveCallback(void)
  10. {
  11.         uint8_t temp;
  12.         if((__HAL_UART_GET_FLAG(UART_DEBUG, UART_FLAG_IDLE) != RESET))  //獲取IDLE標(biāo)志位,idle標(biāo)志被置位
  13.         {
  14.                 __HAL_UART_CLEAR_IDLEFLAG(&huart1);                                                                                                                //清除空閑中斷標(biāo)志位
  15.                 HAL_UART_DMAStop(UART_DEBUG);                                                                                                                                        //停止串口DMA功能
  16.                
  17.                 temp = huart1.hdmarx->Instance->CNDTR;                                                                                                //得到當(dāng)前還剩余多少個(gè)數(shù)據(jù)
  18.                 uartDMA_data.bits.recive_count = BUFFER_SIZE - temp;                                        //接收數(shù)據(jù)計(jì)數(shù)
  19.                
  20.                 uartDMA_data.bits.interrupt_idle = ON;                                                                                                // 接受完成標(biāo)志位置1        
  21.                
  22.         }
  23. }
復(fù)制代碼
數(shù)據(jù)接收服務(wù),放在一個(gè)5ms定時(shí)一次的定時(shí)器中斷里
  1. void USART1DMA_rx_service(void)
  2. {
  3.    
  4.     /*在72MHZ系統(tǒng)時(shí)鐘工況下,此函數(shù)運(yùn)行時(shí)間為無(wú)空閑中斷0.78ms-0.81ms;
  5.                                              有空閑中斷,需要處理 運(yùn)行時(shí)間為72.114ms*/

  6.     /*將此接收服務(wù)判定函數(shù)置于中斷中,有較小概率產(chǎn)生數(shù)據(jù)丟包BUG*/
  7.     /*此任務(wù)函數(shù)置于定時(shí)中斷中,進(jìn)行循環(huán)檢測(cè)*/
  8.     if(uartDMA_data.bits.interrupt_idle == ON)                //有空閑中斷
  9.     {
  10.         uartDMA_data.bits.interrupt_idle = OFF;

  11.         /*加入臨界段保護(hù)-----------------------------------------------------------------------------------------------------------------*/
  12.         CPU_SR_ALLOC();
  13.         CPU_CRITICAL_ENTER();  
  14.         
  15.         memset(uartDMA_data.bits.uart_buffer, 0, sizeof(uartDMA_data.bits.uart_buffer));                                    //清除緩存數(shù)據(jù)數(shù)組
  16.         memcpy(uartDMA_data.bits.uart_buffer, uartDMA_data.bits.rx_buffer, strlen((char *)uartDMA_data.bits.rx_buffer));    //取出數(shù)據(jù)
  17.         memset(uartDMA_data.bits.rx_buffer, 0, sizeof(uartDMA_data.bits.rx_buffer));                                        //清空數(shù)組
  18.         HAL_UART_Receive_DMA(UART_DEBUG, uartDMA_data.bits.rx_buffer, sizeof(uartDMA_data.bits.rx_buffer));                 //重新啟動(dòng)串口DMA功能
  19.         
  20.         CPU_CRITICAL_EXIT();
  21.          /*加入臨界段保護(hù)-----------------------------------------------------------------------------------------------------------------*/
  22.         
  23.         if((DEBUG_USART_ENABLE==1)&&(Modbus_ENABLE==0)){
  24.             /*測(cè)試模式,向PC發(fā)送接收到的數(shù)據(jù)*/
  25.             
  26.         }
  27.         if((Modbus_ENABLE==1)&&(DEBUG_USART_ENABLE==0)){     /*進(jìn)入MODBUS通訊模式*/
  28.             
  29.             uint8_t icnt;
  30.             /*空閑中斷發(fā)生,將DMA接收緩存數(shù)據(jù)轉(zhuǎn)存至MODBUS數(shù)據(jù)緩存中*/
  31.             Modbus_data_len =  uartDMA_data.bits.recive_count;
  32.             //HAL_UART_Transmit_DMA(UART_DEBUG, (uint8_t *)uartDMA_data.bits.uart_buffer, strlen((char *)uartDMA_data.bits.uart_buffer));        //打印接收到的數(shù)據(jù)
  33.             ModbusbuffAllow = 0;    //modbus緩存寫(xiě)保護(hù)
  34.             for(icnt=0;icnt<Modbus_data_len;icnt++)
  35.             {
  36.                 modbus_Rx_buff[icnt] = uartDMA_data.bits.uart_buffer[icnt];
  37.             }
  38.             
  39.             ModbusbuffAllow = 1;    //modbus緩存解除寫(xiě)保護(hù)
  40.             /*數(shù)據(jù)已經(jīng)寫(xiě)入modbus緩存*/
  41.             //HAL_UART_Transmit_DMA(UART_DEBUG,modbus_Rx_buff,Modbus_data_len);
  42.         }
  43.         
  44.         
  45. //                Debug_Printf(UART_DEBUG, "\r\n*******************************串口 DMA方式接收打印如下 *****************************\r\n ");         HAL_Delay(100);
  46. //                        
  47. //                        Debug_Printf(UART_DEBUG, "\r\n HAL_UART_Transmit_DMA 庫(kù)函數(shù)打印\t:");         HAL_Delay(100);
  48. //                        HAL_UART_Transmit_DMA(UART_DEBUG, (uint8_t *)uartDMA_data.bits.uart_buffer, strlen((char *)uartDMA_data.bits.uart_buffer));        //打印接收到的數(shù)據(jù)
  49. //                        HAL_Delay(100);
  50. //                        Debug_Printf(UART_DEBUG, "\r\nDebug_Printf函數(shù)打印數(shù)組\t\t:");                                         HAL_Delay(100);
  51. //                        Debug_Printf(UART_DEBUG, (char *)uartDMA_data.bits.uart_buffer);        
  52. //                        HAL_Delay(100);
  53. //                        Debug_Printf(UART_DEBUG, "\r\nDebug_Printf函數(shù)打印字符\t\t:");                                         HAL_Delay(100);
  54. //                        Debug_Printf(UART_DEBUG, "uart MDA Debug printf function");
  55. //                        HAL_Delay(100);
  56. //                        Debug_Printf(UART_DEBUG, "\r\nDebug_Printf函數(shù)打印串口接收計(jì)數(shù)值\t:");                                         HAL_Delay(100);
  57. //                        Debug_Printf(UART_DEBUG, "recive_count: %d\r\n", uartDMA_data.bits.recive_count);
  58.     }
  59. }
復(fù)制代碼

源碼奉上: test.7z (818.38 KB, 下載次數(shù): 4)


作者: liuchao626    時(shí)間: 2023-4-28 17:30
初步查到問(wèn)題是在HAL_UART_IRQHandler里,0x00會(huì)導(dǎo)致數(shù)據(jù)停止接收。
作者: xuyaqi    時(shí)間: 2023-4-28 19:27
看來(lái)你是MODBUS協(xié)議沒(méi)搞明白。
作者: liuchao626    時(shí)間: 2023-5-4 09:23
xuyaqi 發(fā)表于 2023-4-28 19:27
看來(lái)你是MODBUS協(xié)議沒(méi)搞明白。

并不是,里面雖然有MODBUS的前置處理函數(shù),問(wèn)題并不在modbus里面,協(xié)議硬件部分是純手?jǐn)]的,HAL庫(kù)的回調(diào)函數(shù)會(huì)把0x00判定為命令。停止接收。
作者: liuchao626    時(shí)間: 2023-5-4 11:27
  1.         memset(uartDMA_data.bits.uart_buffer, 0, sizeof(uartDMA_data.bits.uart_buffer));                                    //清除緩存數(shù)據(jù)數(shù)組
  2.         memcpy(uartDMA_data.bits.uart_buffer, uartDMA_data.bits.rx_buffer, strlen((char *)uartDMA_data.bits.rx_buffer));    //取出數(shù)據(jù)
  3.         memset(uartDMA_data.bits.rx_buffer, 0, sizeof(uartDMA_data.bits.rx_buffer));                                        //清空數(shù)組
  4.         HAL_UART_Receive_DMA(UART_DEBUG, uartDMA_data.bits.rx_buffer, sizeof(uartDMA_data.bits.rx_buffer));                 //重新啟動(dòng)串口DMA功能
  5.         
復(fù)制代碼


問(wèn)題已找到,strlen會(huì)把0x00識(shí)別為\0結(jié)束符,導(dǎo)致提前結(jié)束取出數(shù)據(jù)
作者: Longan.Wang    時(shí)間: 2023-5-4 11:38
估計(jì)問(wèn)題出在這里了:
memcpy(uartDMA_data.bits.uart_buffer, uartDMA_data.bits.rx_buffer, strlen((char *)uartDMA_data.bits.rx_buffer));    //取出數(shù)據(jù)
你是不熟悉strlen這個(gè)函數(shù)的用法,它是用于獲取字符串長(zhǎng)度的,再想想,字符串是以什么結(jié)尾的?是不是'\0',這個(gè)東西轉(zhuǎn)成熟悉的十六進(jìn)制是為是0x00?,所以遇到0x00就已經(jīng)表示字符串結(jié)束了,后面的字節(jié)理所當(dāng)然的就被拋棄了啊!
你不是在總線空閑中斷處獲取了接收數(shù)據(jù)長(zhǎng)度么,直接用那個(gè)長(zhǎng)度就好了。
作者: liuchao626    時(shí)間: 2023-5-5 09:15
Longan.Wang 發(fā)表于 2023-5-4 11:38
估計(jì)問(wèn)題出在這里了:
memcpy(uartDMA_data.bits.uart_buffer, uartDMA_data.bits.rx_buffer, strlen((cha ...

大哥正解,通過(guò)這個(gè)BUG,感覺(jué)自己的C基礎(chǔ)還有待提高




歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 成人精品毛片国产亚洲av十九禁 | 91青娱乐在线 | h视频在线免费 | 国产精品不卡 | 国产一区 | 亚洲成人激情在线观看 | 色偷偷888欧美精品久久久 | 伊伊综合网 | 天天干com | 亚洲97| 亚洲天堂av网 | 日韩欧美在线播放 | 狠狠狠色丁香婷婷综合久久五月 | 日本精品裸体写真集在线观看 | 久久精品亚洲 | 中文字幕国产在线 | 亚洲成人黄色 | 国产精品美女久久久久久久久久久 | www.亚洲精品 | 国产成人免费在线 | 成人免费一区二区 | 一区二区三区国产 | 在线一区视频 | www.天天操 | 最新中文字幕在线 | 美国十次成人欧美色导视频 | 亚洲福利一区二区 | 国产成人久久精品 | 欧美三级在线 | 日韩欧美一级精品久久 | 日本精品一区二区三区在线观看视频 | 精品国产欧美 | 日本中文字幕日韩精品免费 | 久久黄视频 | 在线观看中文字幕 | 91伊人网| 99久久精品国产一区二区三区 | 日韩精品一区二区三区在线观看 | 亚洲成人一区二区 | 色婷婷久久久久swag精品 | 久久激情视频 |