标题: STM32F407单片机串口丢数据问题 [打印本页]

作者: cokesu    时间: 2022-5-4 16:47
标题: STM32F407单片机串口丢数据问题
不知道有没有人遇到过,最近学习系统之类的自己熟悉的单片机RAM不够,用STM的但是之前都是用标准库的,HAL库非常不习惯,这个调了一天也不知道是哪里出现问题了,发送过快的坏还会出现卡死的情况,这个程序就是接受一个字符然后马上发送回去一个同样的字符实在没想到为什么会漏数据,找了很多资料都是说数据没及时处理,但是我在回调函数里面处理了应该没有更快的方法了吧。

B~PDZY$V$){LR2])CHDF.png (14.09 KB, 下载次数: 38)

B~PDZY$V$){LR2])CHDF.png

download.png (20.49 KB, 下载次数: 61)

download.png

作者: 人工置顶员    时间: 2022-5-5 03:12
顶一下
作者:     时间: 2022-5-5 08:08
使用CubeMX配置  用DMA试试
作者: cokesu    时间: 2022-5-5 08:31
 发表于 2022-5-5 08:08
使用CubeMX配置  用DMA试试

我这个就是用CubeMx的DMA没怎么用过,主要是也没理由说串口中断就不行啊
作者: munuc_w    时间: 2022-5-5 08:33
HAL的接收函数太繁琐,可以自己写一个接收函数,中断调用,回调函数是在中断中调用的,中断中不易处理数据,中断函数月精简越好。
作者: cokesu    时间: 2022-5-5 08:55
好像找打原因了,HAL_UART_Transmit(&huart5,&RxData,1,2);HAL_UART_Receive_IT(&huart5,&RxData,1);这两个不能都&RxData,因为发送那边没有把发送的值先读出来,而是*p直接赋值到DR寄存器,如果这时候还没赋给DR前就触发了下一个读取中断的话就会导致调过了一个数据,但是新的问题又出现了,改好后确实不漏了,但是如果发送的间隔比较短会出现串口卡死的情况

作者: cokesu    时间: 2022-5-6 11:46
munuc_w 发表于 2022-5-5 08:33
HAL的接收函数太繁琐,可以自己写一个接收函数,中断调用,回调函数是在中断中调用的,中断中不易处理数据 ...

大哥你这个说对了,自己单独写一个就没问题,HAL_UART_IRQHandler(&huart5);hal库这个函数处理的太繁琐了,我168M主频的都有几率在下一个数据来前处理不完
作者: cokesu    时间: 2022-5-6 11:48
问题解决了,HAL_UART_IRQHandler(&huart5);hal库这个函数处理的时间太长了,我波特率115200一次性发多个数据后可能会在两个数据间隔时间内处理不完,导致丢失一个数据,解决方法,自己写一个中断函数不要使用回调了,void UART5_IRQHandler(void)
{
  /* USER CODE BEGIN UART5_IRQn 0 */
        if(((UART5->SR) & USART_SR_RXNE) != RESET)                     //判断读取不为空标志
        {
                Rxd[Count] = (unsigned char)(UART5->DR & 0x000000ff);        //读取对应数据
                UART5->DR = (unsigned long)Rxd[Count];                       //发送数据
                __HAL_UART_ENABLE_IT(&huart5, UART_IT_TXE);                  //打开发送空中断
                Count++;
                if(Count >= 35)
                {
                        Count = 0;
                }
                UART5->SR &= ~UART_FLAG_RXNE;                                //清除读取不为空标志
        }
       
        if(((UART5->SR) & USART_SR_TXE) != RESET)                      //判断发送空标志
        {
                UART5->SR &= ~USART_SR_TXE;                                  //清除标志
                __HAL_UART_DISABLE_IT(&huart5, UART_IT_TXE);                 //关闭发送中断
        }
  /* USER CODE END UART5_IRQn 0 */
//  HAL_UART_IRQHandler(&huart5);
  /* USER CODE BEGIN UART5_IRQn 1 */

  /* USER CODE END UART5_IRQn 1 */
}
作者: cokesu    时间: 2022-5-6 11:50
这个问题解决了,就是因为hal库这个回调函数处理时间太长了HAL_UART_IRQHandler(&huart5);我波特率为115200,两个数据间隔的时间有可能处理不完这个函数,导致会丢失一个数据,解决方法就是自己写一个中断函数,这样就不会漏数据或者触发ORE中断了
void UART5_IRQHandler(void)
{
  /* USER CODE BEGIN UART5_IRQn 0 */
        if(((UART5->SR) & USART_SR_RXNE) != RESET)                     //判断读取不为空标志
        {
                Rxd[Count] = (unsigned char)(UART5->DR & 0x000000ff);        //读取对应数据
                UART5->DR = (unsigned long)Rxd[Count];                       //发送数据
                __HAL_UART_ENABLE_IT(&huart5, UART_IT_TXE);                  //打开发送空中断
                Count++;
                if(Count >= 35)
                {
                        Count = 0;
                }
                UART5->SR &= ~UART_FLAG_RXNE;                                //清除读取不为空标志
        }
       
        if(((UART5->SR) & USART_SR_TXE) != RESET)                      //判断发送空标志
        {
                UART5->SR &= ~USART_SR_TXE;                                  //清除标志
                __HAL_UART_DISABLE_IT(&huart5, UART_IT_TXE);                 //关闭发送中断
        }
  /* USER CODE END UART5_IRQn 0 */
//  HAL_UART_IRQHandler(&huart5);
  /* USER CODE BEGIN UART5_IRQn 1 */

  /* USER CODE END UART5_IRQn 1 */
}




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1