【stm32】UART串口中断方式收发任意长度数据(HAL库开发,中断中不使用库函数 使用寄存器和自定义存储函数)

2023-05-16

一、起因

为什么要写一个串口接收不定长数据,还要把数据保存起来??

因为存起来的数据要用要判断要根据数据做不同的处理,要把数据拿到后解析。

但是,最开始想当然的使用HAL库中的HAL_UART_Receive_IT() 和 HAL_UART_Receive(),调用函数发现怎么也不对,总是有bug。网上查了一堆,博客很多,解决不了我的问题啊,按照他们的方法我还是不能接收到数据。

后来参考了野火的教程,直接用寄存器,自己再单独写了个函数解决。

 

二、代码

main.c 直接写while循环就OK了 其他的都一样

    while (1)
    {
        HAL_Delay(1000);
        
        //测试串口数据保存
        Test_Usart_Recv();
        
    }

stm32f10x_it.c

串口1的中断:数据打印到上位机后,对ch数据做保存

这里有个坑,就是不能调用printf,真的是个坑啊,调用printf("%c",ch)根本不能把所有ch数据打印出来,只能打印2个

串口接收数据是一个字节一个字节接收的,所以每接收一个字节就会进入一次中断。我是怎么知道的,测试时我在中断函数中用一个全局的变量记录进入次数,主函数中再打印出来,这样就知道进入函数的次数了。没办法,不能用printf,用printf就只打印两次,我以为只进入两次中断,其实不是的,printf函数中会调底层的寄存器,和上面的寄存器操作冲突了,这里用printf就有bug.

//串口1中断函数:stm32接收到上位机的数据
void DEBUG_USART_IRQHandler(void)
{
    uint8_t ch = 1;

    if (__HAL_UART_GET_FLAG( &DebugUartHandle, UART_FLAG_RXNE ) != RESET) 
    {
        HAL_UART_IRQHandler(&DebugUartHandle);
        
        //读寄存器
        ch = ( uint16_t)READ_REG(DebugUartHandle.Instance->DR);
        //printf("%c\n",ch); //这里不能使用printf 会有bug 因为printf中调用HAL_UART_Transmit中同样使用了DebugUartHandle.Instance->DR        
        //打印到上位机
        WRITE_REG ( DebugUartHandle.Instance->DR,ch);
        
        //保存数据到缓冲区
        Usart_Save_Data(ch);
    }
}

bsp_uart.c  bsp_uart.h

/**************************************************/
/*              .h头文件                         */

//串口1接收数据结构体
#define USART1_RECV_BUFFR_SIZE    256

typedef struct Usart1_Recv_Data
{   
    uint8_t data_buff[USART1_RECV_BUFFR_SIZE];
    uint8_t recv_flag;//1:接收完毕    0:未接收数据、未接收完数据
    uint16_t recv_size;//当前接收数据的个数(数组下标 0~255)        
}Usart1_Recv_Data_t;

//测试串口1 接收不定长数据
void Test_Usart_Recv(void);

extern UART_HandleTypeDef DebugUartHandle;
extern Usart1_Recv_Data_t Usart_Recv_Data_Buff;







/**************************************************/
/*              .c源文件                         */
//初始化 结构体
void Usart_Recv_Buff_Init(void)
{
    Usart_Recv_Data_Buff.recv_flag = 0;
    Usart_Recv_Data_Buff.recv_size = 0;
}

//保存数据 到 buff
void Usart_Save_Data(uint8_t ch)
{
    if(ch == '\n')//表示接受完毕
    {
        Usart_Recv_Data_Buff.data_buff[Usart_Recv_Data_Buff.recv_size++] = ch;
        Usart_Recv_Data_Buff.recv_flag = 1;
        
    }
    else
    {
        Usart_Recv_Data_Buff.data_buff[Usart_Recv_Data_Buff.recv_size++] = ch;
    }    
}

//main调用 测试使用
void Test_Usart_Recv(void)
{
    if(Usart_Recv_Data_Buff.recv_flag)
    {
        printf("usart1 recv data = %s\n",Usart_Recv_Data_Buff.data_buff);
        
        Usart_Recv_Buff_Init();//清零size 和 flag
        memset(Usart_Recv_Data_Buff.data_buff,0,USART1_RECV_BUFFR_SIZE);//清空
    }
}

源程序工程代码链接:

 

三、效果

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【stm32】UART串口中断方式收发任意长度数据(HAL库开发,中断中不使用库函数 使用寄存器和自定义存储函数) 的相关文章

  • Python——sqlalchemy.exc.ArgumentError

    报错信息 xff1a sqlalchemy exc ArgumentError Mapper mapped class XmjbqZby gt xmjbq zby could not assemble any primary key col
  • VirtualBox虚拟机ping不通主机,但是主机可以ping通虚拟机

    解决VirtualBox虚拟机不能ping通宿主机的问题 问题描述 在VirtualBox虚拟中 xff0c 无法ping通宿主机 xff0c 宿主机可以ping通虚拟机 虚拟机的网络已经设置为 桥接网卡 xff0c 也可以正常上网 解决方
  • RTThread-W25Q128的驱动基于SPI和SFUD

    文章目录 前言一 kconfig的配置1 配置对应的SPI和SFUD 二 SFUD的使用W25Q128的读写操作 三 关于写入的问题 前言 本文是一个初学者的学习记录 xff0c 可能有误 SFUD是针对flash的一种通用的组件 xff0
  • RT-Thread 基于QSPI驱动LY68L6400-SRAM

    前言 使用的是RTThread 标准版 xff0c 主控是STM32H743 xff0c SRAM是LY68L6400 xff0c 使用QSPI QSPI和SPI的区别 个人理解最大的区别就是SPI是串行 xff0c 数据输出 xff0c
  • 关于学习RTThread的随笔

    认识操作系统 关于单片机的学习是从51到ARM xff0c 慢慢的接触到了操作系统 xff0c 开始也不明白是什么 xff0c 就跟着原子哥的例程学 xff0c 也不知道哪个好 xff1f 开始学UCOS xff0c 后来又用学了FreeR
  • RT-Thread 串口的使用

    1 配置选用的串口 在kconfig文件中增加ENV的串口选项 xff0c 这边选择的是uart2 menuconfig BSP USING UART bool span class token string 34 Enable UART
  • 关于驱动中景园LCD和LVGL踩的一些坑

    背景介绍 我使用的是中景园的1 3寸 xff0c 240 240的LCD xff0c 主控是STM32L152系列 https item taobao com item htm spm 61 3688y 1 14 16 1916264bJ5
  • 使用物联网卡无法通讯

    在使用阿里云的物联网卡时 xff0c 遇到一个电信卡无法通讯的问题 xff0c 数据只能发不能收 xff0c 后来客服跟踪调查后发现 xff0c 物联网卡有一个IP地址的白名单 xff0c 需要让客服把通讯平台的IP地址加到这个白名单才行
  • ESP32+PIO+LGVL+gui_guider

    简介 本文基于VScode上安装platform插件 xff08 简称PIO xff09 来开发ESP32 xff0c 屏幕显示使用LVGL 43 gui guider 关于VScode上使用platfrom也是一把辛酸泪 很多朋友会安装不
  • ESP32+PIO+LGVL+gui_guider之【BUTTON实体按键】

    LVGL的Button外部按键 这个Button是没有触摸屏的情况下用外部的按键来对应屏幕上的按键 xff0c 比如屏幕上有个确定键 xff0c 你按下外部某个按键 xff0c 屏幕的确定键也相应显示按下 工作原理其实就是LVGL把外部按键
  • KEIL工程报错问题解决记录

    1 no section to be FIRST LAST 在一次下载了别人的工程后 xff08 来自51黑论坛STm32L低功耗测试的一个工程 xff09 xff0c 由于其他工程用的DPF包有所不同 xff0c 记得是按照提示更新了固件
  • Linux——centos7搭建node + Nginx + vue + mysql 的服务安装详细步骤

    一 安装所需的软件 二 进行具体配置 三 使用 以下配置及安装为已运行实测的笔记整理 xff0c 严格按照该步骤进行配置 xff0c 大概率上不会有问题 不懂linux的小白也可配置使用 当然 xff0c 最好还是了解一些linux基本的命
  • ONOS应用示例开发

    ONOS应用示例开发 风继续吹 15 04 09 9239 人围观 本文主要是提供了有关ONOS的基于意图的流量转发应用如何开发 构建及部署等方面的实战经验 xff0c 并且详细讲解了如何在命令行上调用服务的过程 最后 xff0c 介绍了在
  • 测试1234

    String mStaticDns 61 34 static com 34 34 static net 34 34 cdn bcebos com 34 34 pic cn 34 34 pic com 34 34 sina net 34 34
  • ubuntu共享文件夹权限问题

    新建的共享文件夹 xff0c 只有切换成root用户组时才能访问 xff0c 其他用户却没有权限 原因 xff1a 共享文件夹属于vboxsf组 解决方案 xff1a 把当前用户添加到vboxsf组 sudo adduser userNam
  • Bad owner or permissions on .ssh/config的解决

    Bad owner or permissions on ssh config的解决 当为本机配一个固定用户名远程登录某主机时 xff0c 配置了一个config文件 xff0c 但是在执行ssh免密码登录时报如下的错误 xff1a Bad
  • MobiCom‘21

    1 Vaibhav Singh Akarsh Prabhakara Diana Zhang Osman Ya an and Swarun Kumar 2021 A community driven approach to democrati
  • 学习日志之STM32固件库

    对固件库结构的理解 stm32固件库分为4层 xff1a 应用层 xff08 application layer xff09 板级支持包BSP xff08 BSP xff08 board specific package xff09 硬件抽
  • Navicat Premium 15 注册出现 No All Pattern Found! File Already Patched?

    Navicat Premium 注册出现 No All Pattern Found File Already Patched 解决方法方法一方法二 解决方法 方法一 直接打开你的 Navicat Premium 15 再次安装一遍后 xff
  • win10 + Ubuntu 20.04 LTS 双系统安装 (UEFI + GPT)(图文,多图预警)

    原文地址 xff1a https zhangzhicheng com archives 122 html win10 43 Ubuntu 20 04 LTS 双系统安装 xff08 UEFI 43 GPT xff09 win10 安装 xf

随机推荐