野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 139|回复: 11

用STM32CUBEMX进行串口实验,串口只能接收到一次

[复制链接]
发表于 2020-9-8 22:30:41 | 显示全部楼层 |阅读模式
1火花
本帖最后由 将心明月 于 2020-9-15 09:37 编辑

如题,用STM32CUBEMX进行串口实验,目的是程序下载成功后,复位可以用串口调试助手接收到“hello world!”
当发送“0xa1”,串口调试助手可以接收到"LED1 Open!“
当发送“0xa2”,串口调试助手可以接收到"LED1 Closed!“
实际是只能用串口调试助手发送一次,可以接收到返回值。后面再发送就接收不到返回的值了。求解,代码如下:
uint8_t Tx_str1[] = "hello world!\r\n";
uint8_t Tx_str2[] = "LED1 Open!\r\n";
uint8_t Tx_str3[] = "LED1 Closed!\r\n";
uint8_t Rx_dat = 0;

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart->Instance == USART1)
    {
        if(Rx_dat == 0xa1)
        {
            HAL_UART_Transmit(&huart1,Tx_str2,sizeof(Tx_str2),10000);
            HAL_UART_Receive_IT(&huart1,&Rx_dat,1);
        }
        else if(Rx_dat == 0xa2)
        {               
            HAL_UART_Transmit(&huart1,Tx_str3,sizeof(Tx_str3),10000);
            HAL_UART_Receive_IT(&huart1,&Rx_dat,1);
        }
    }
}
//在mian()函数中添加以下代码:
HAL_UART_Transmit(&huart1,Tx_str1,sizeof(Tx_str1),10000);    //向上位机发送“hello world!”
HAL_UART_Receive_IT(&huart1,&Rx_dat,1);                      //启动串口1接收上位机1个字节


最佳答案

查看完整内容

在 HAL_UART_Receive_IT()函数前面加上这两句试试 huart1.RxState = HAL_UART_STATE_READY; __HAL_UART_FLUSH_DRREGISTER(&huart1);
回复

使用道具 举报

 楼主| 发表于 2020-9-15 09:46:37 | 显示全部楼层
将代码修改为下面的代码就可以解决只能发送一次串口数据的问题了
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart->Instance == USART1)
    {
        if(Rx_dat == 0xa1)
        {

            HAL_UART_Transmit(&huart1,Tx_str2,sizeof(Tx_str2),10000);
            huart1.RxState = HAL_UART_STATE_READY;
                        __HAL_UART_FLUSH_DRREGISTER(&huart1);
                        HAL_UART_Receive_IT(&huart1,&Rx_dat,1);
        }
        else if(Rx_dat == 0xa2)
        {
            HAL_UART_Transmit(&huart1,Tx_str3,sizeof(Tx_str3),10000);
            huart1.RxState = HAL_UART_STATE_READY;
                        __HAL_UART_FLUSH_DRREGISTER(&huart1);
                        HAL_UART_Receive_IT(&huart1,&Rx_dat,1);
        }
    }
}
回复

使用道具 举报

发表于 2020-9-8 22:30:42 | 显示全部楼层
在      HAL_UART_Receive_IT()函数前面加上这两句试试  
huart1.RxState = HAL_UART_STATE_READY;
__HAL_UART_FLUSH_DRREGISTER(&huart1);

回复

使用道具 举报

发表于 2020-9-9 08:22:29 | 显示全部楼层
是的   每次接收完成之后都需要重新打开一次接收
回复

使用道具 举报

发表于 2020-9-9 08:25:27 | 显示全部楼层
是因为 HAL库的接收函数里面   每接收到设定次数 或空闲中断的时候  调用了关闭接收中断的函数  
得再次打开才能再次接收
回复

使用道具 举报

 楼主| 发表于 2020-9-9 11:20:51 | 显示全部楼层
wwhh 发表于 2020-9-9 08:25
是因为 HAL库的接收函数里面   每接收到设定次数 或空闲中断的时候  调用了关闭接收中断的函数  
得再次打 ...

那请问有什么方法可以一直发送接收吗,实际应用中也不可能串口发一次就重启啊
回复

使用道具 举报

发表于 2020-9-11 09:47:50 | 显示全部楼层
亲,不要使用hal库这个函数,直接在中断中处理会更优哦,hal库这些函数真的垃圾的
回复

使用道具 举报

发表于 2020-9-15 09:07:12 | 显示全部楼层
stm32hal库 uart开启中断后,默认接收和发送都是需要使用中断服务函数的,而你的回调函数里面又调用了打印,不卡死才怪
回复

使用道具 举报

 楼主| 发表于 2020-9-15 09:33:59 | 显示全部楼层
wwhh 发表于 2020-9-8 22:30
在      HAL_UART_Receive_IT()函数前面加上这两句试试  
huart1.RxState = HAL_UART_STATE_READY;
__HA ...

谢谢你的回答,完美的解决了我的问题,还有一个地方不是很理解,为什么一开始定义要发送接收的数据要用
uint8_t而不是char呢
uint8_t Tx_str1[] = "hello world!\r\n";
uint8_t Tx_str2[] = "LED1 Open!\r\n";
uint8_t Tx_str3[] = "LED1 Closed!\r\n";
uint8_t Rx_dat = 0;
回复

使用道具 举报

 楼主| 发表于 2020-9-15 09:35:01 | 显示全部楼层
初晴sama 发表于 2020-9-11 09:47
亲,不要使用hal库这个函数,直接在中断中处理会更优哦,hal库这些函数真的垃圾的 ...

可是用CUBEMX的话必须要用HAL库开发啊,毕竟是ST官方提供的库,只能去适应它了
回复

使用道具 举报

 楼主| 发表于 2020-9-15 09:35:41 | 显示全部楼层
云峰 发表于 2020-9-15 09:07
stm32hal库 uart开启中断后,默认接收和发送都是需要使用中断服务函数的,而你的回调函数里面又调用了打印 ...

恩,还是自己的理解不够深刻,要加油学习了
回复

使用道具 举报

发表于 2020-9-15 20:04:57 | 显示全部楼层
将心明月 发表于 2020-9-15 09:33
谢谢你的回答,完美的解决了我的问题,还有一个地方不是很理解,为什么一开始定义要发送接收的数据要用
u ...

因为它是在接受中断函数里接收数据 而接受中断函数的参数定义的是uint8_t 类型的指针  所以你要定义uint8_t类型的变量  如果是char类型的变量的话 会报警告的  但是基本也没问题  这两个类型占同样大小的内存空间
回复

使用道具 举报

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

本版积分规则

联系站长|手机版|站点地图|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号-2 ) 大学生ARM嵌入式2群

GMT+8, 2020-9-23 04:46 , Processed in 0.507251 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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