找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2016|回复: 8
收起左侧

STM32F407单片机串口丢数据问题

[复制链接]
ID:404263 发表于 2022-5-4 16:47 | 显示全部楼层 |阅读模式
不知道有没有人遇到过,最近学习系统之类的自己熟悉的单片机RAM不够,用STM的但是之前都是用标准库的,HAL库非常不习惯,这个调了一天也不知道是哪里出现问题了,发送过快的坏还会出现卡死的情况,这个程序就是接受一个字符然后马上发送回去一个同样的字符实在没想到为什么会漏数据,找了很多资料都是说数据没及时处理,但是我在回调函数里面处理了应该没有更快的方法了吧。
B~PDZY$V$){LR2])CHDF.png
download.png
回复

使用道具 举报

ID:301191 发表于 2022-5-5 03:12 | 显示全部楼层
顶一下
回复

使用道具 举报

ID:405850 发表于 2022-5-5 08:08 | 显示全部楼层
使用CubeMX配置  用DMA试试
回复

使用道具 举报

ID:404263 发表于 2022-5-5 08:31 | 显示全部楼层
 发表于 2022-5-5 08:08
使用CubeMX配置  用DMA试试

我这个就是用CubeMx的DMA没怎么用过,主要是也没理由说串口中断就不行啊
回复

使用道具 举报

ID:752974 发表于 2022-5-5 08:33 | 显示全部楼层
HAL的接收函数太繁琐,可以自己写一个接收函数,中断调用,回调函数是在中断中调用的,中断中不易处理数据,中断函数月精简越好。
回复

使用道具 举报

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

大哥你这个说对了,自己单独写一个就没问题,HAL_UART_IRQHandler(&huart5);hal库这个函数处理的太繁琐了,我168M主频的都有几率在下一个数据来前处理不完
回复

使用道具 举报

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: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 */
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

Powered by 单片机教程网

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