找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

STM32F407单片机串口丢数据问题

查看数: 3101 | 评论数: 8 | 收藏 0
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2022-5-4 16:47

正文摘要:

不知道有没有人遇到过,最近学习系统之类的自己熟悉的单片机RAM不够,用STM的但是之前都是用标准库的,HAL库非常不习惯,这个调了一天也不知道是哪里出现问题了,发送过快的坏还会出现卡死的情况,这个程序就是接受 ...

回复

ID:404263 发表于 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 */
}
ID:404263 发表于 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 */
}
ID:404263 发表于 2022-5-6 11:46
munuc_w 发表于 2022-5-5 08:33
HAL的接收函数太繁琐,可以自己写一个接收函数,中断调用,回调函数是在中断中调用的,中断中不易处理数据 ...

大哥你这个说对了,自己单独写一个就没问题,HAL_UART_IRQHandler(&huart5);hal库这个函数处理的太繁琐了,我168M主频的都有几率在下一个数据来前处理不完
ID:404263 发表于 2022-5-5 08:55
好像找打原因了,HAL_UART_Transmit(&huart5,&RxData,1,2);HAL_UART_Receive_IT(&huart5,&RxData,1);这两个不能都&RxData,因为发送那边没有把发送的值先读出来,而是*p直接赋值到DR寄存器,如果这时候还没赋给DR前就触发了下一个读取中断的话就会导致调过了一个数据,但是新的问题又出现了,改好后确实不漏了,但是如果发送的间隔比较短会出现串口卡死的情况
ID:752974 发表于 2022-5-5 08:33
HAL的接收函数太繁琐,可以自己写一个接收函数,中断调用,回调函数是在中断中调用的,中断中不易处理数据,中断函数月精简越好。
ID:404263 发表于 2022-5-5 08:31
 发表于 2022-5-5 08:08
使用CubeMX配置  用DMA试试

我这个就是用CubeMx的DMA没怎么用过,主要是也没理由说串口中断就不行啊
ID:405850 发表于 2022-5-5 08:08
使用CubeMX配置  用DMA试试
ID:301191 发表于 2022-5-5 03:12
顶一下

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表