江科大UART串口通讯hal库实现

article/2025/9/6 4:17:55

hal库相关库函数

初始化结构体

typedef struct
{uint32_t BaudRate;                  /*波特率设置*/uint32_t WordLength;                /*字长设置*/uint32_t StopBits;                  /*停止位设置 */uint32_t Parity;                    /*奇偶校验位设置*/uint32_t Mode;                      /*接受发送模式设置*/uint32_t HwFlowCtl;                 /*硬件流控制设置*/uint32_t OverSampling;              /*采样速度设置*/
} UART_InitTypeDef;
typedef struct __UART_HandleTypeDef
{USART_TypeDef                 *Instance;        /*选择的串口外设地址*/UART_InitTypeDef              Init;             /*串口初始化*/const uint8_t                 *pTxBuffPtr;      /*发送数据的缓冲区*/uint16_t                      TxXferSize;       /*发送数据大小*/__IO uint16_t                 TxXferCount;      /*用于记录还剩余的要发送的数据量*/uint8_t                       *pRxBuffPtr;      /*接收数据缓冲区*/uint16_t                      RxXferSize;       /*接收数据大小*/__IO uint16_t                 RxXferCount;      /*用于记录还剩余的要接收的数据量*/__IO HAL_UART_RxTypeTypeDef ReceptionType;      /*标识当前 UART 接收模式的成员变量。它决定了 UART 如何处理接收到的数据,比如说中断处理或者DMA处理*/__IO HAL_UART_RxEventTypeTypeDef RxEventType;   /*接收事件类型*/DMA_HandleTypeDef             *hdmatx;          /*发送功能DMA句柄*/DMA_HandleTypeDef             *hdmarx;          /*接受功能DMA句柄*/HAL_LockTypeDef               Lock;             /*状态锁存*/__IO HAL_UART_StateTypeDef    gState;           /*它的主要作用是存储当前 UART 的状态,方便在程序的不同部分查询 UART 的工作状态global state */__IO HAL_UART_StateTypeDef    RxState;          /*接收状态*/__IO uint32_t                 ErrorCode;        /*错误标志位*/#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)void (* TxHalfCpltCallback)(struct __UART_HandleTypeDef *huart);        /*!< UART Tx Half Complete Callback        */void (* TxCpltCallback)(struct __UART_HandleTypeDef *huart);            /*!< UART Tx Complete Callback             */void (* RxHalfCpltCallback)(struct __UART_HandleTypeDef *huart);        /*!< UART Rx Half Complete Callback        */void (* RxCpltCallback)(struct __UART_HandleTypeDef *huart);            /*!< UART Rx Complete Callback             */void (* ErrorCallback)(struct __UART_HandleTypeDef *huart);             /*!< UART Error Callback                   */void (* AbortCpltCallback)(struct __UART_HandleTypeDef *huart);         /*!< UART Abort Complete Callback          */void (* AbortTransmitCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Abort Transmit Complete Callback */void (* AbortReceiveCpltCallback)(struct __UART_HandleTypeDef *huart);  /*!< UART Abort Receive Complete Callback  */void (* WakeupCallback)(struct __UART_HandleTypeDef *huart);            /*!< UART Wakeup Callback                  */void (* RxEventCallback)(struct __UART_HandleTypeDef *huart, uint16_t Pos); /*!< UART Reception Event Callback     */void (* MspInitCallback)(struct __UART_HandleTypeDef *huart);           /*!< UART Msp Init callback                */void (* MspDeInitCallback)(struct __UART_HandleTypeDef *huart);         /*!< UART Msp DeInit callback              */
#endif  /* USE_HAL_UART_REGISTER_CALLBACKS */} UART_HandleTypeDef;

 FE帧错误,ORE过载错误,NE噪声错误

初始化相关函数

初始化,半双工,初始化 LIN 外设,多进程,恢复缺省配置

HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength);
HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod);
HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart);
void HAL_UART_MspInit(UART_HandleTypeDef *huart);
void HAL_UART_MspDeInit(UART_HandleTypeDef *huart);

发送接收相关函数 ,普通收发,中断收发,DMA收发,以及DMA暂停,DMA恢复,DMA停止

其中DMAResume得在DMAPause后面.

HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart);
扩展部分
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen,uint32_t Timeout);
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

 扩展部分是串口不断接收数据,直到空闲状态,有三种不同的接受方式

串口接收的事件获取

串口中止 UART 通信的函数,它可以同时中止发送和接收操作。

串口中止发送,中止接收,中止中断,中止发送中断,中止接受中断。

HAL_UART_RxEventTypeTypeDef HAL_UARTEx_GetRxEventType(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart);

串口的收发

根据江科大的串口设计来配置我们的CubeMX

首先使用UART1,波特率为9600,非硬件流控制,发送接收模式都要,一位停止位,八位字长,不需要奇偶校验位,开启中断,抢占优先级和响应优先级都为1,

创建完成后我们就可以完成串口的收发了,我们使用正点原子的串口调试工具

HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);

 这两个代码在while循环里面轮询收发数据,比如接收发送3位数据abc,你会发现少接收了一位a只接收到bc且发送的也是bc,数组里面a的位置我们显示出来是0D,也就是回车键的ascll码值。

这是什么原因呢?

原因在这里,他加入了回车换行导致我们的代码a变成了回车

所以对于串口工具的了解也是有必要的。

但是这是阻塞式的收发,超时时间都是1s,也就是我不发生数据,就会在接受数据函数这里卡住整整1s的时间,这对于我们的单片机程序是致命的,1s可以让他做非常多的事情了。所以我们通常使用中断收发模式。

HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

只有触发中断,才进行一次数据的接受和发送,这样就能大大的减少我们在串口收发里面花费的时间,且主程序还能正常运行,不被干扰。

我们在while循环前面进行中断的接收打开,当串口助手发送数据的时候,触发接收中断,接收到数据并进入接收中断函数里面,如果还要继续接收别的数据,我们就得在接受中断函数里面再次开启接受中断。对于接受和发送,我们得对他们进行分离处理,让他们各司其职,比如说最好不要在接收中断函数里面进行数据发送,数据发送不出来且可能和接收函数有冲突导致二者都不能正常工作。

__HAL_UART_GET_FLAG()

我们可以通过get_flag宏定义来判断中断标志位,也可以和江科的代码大一样实现串口的收发,但是那个收发函数太麻烦了,还需要我们手动判断标志位,清除标志位,发送函数也是由一位字长数据发送函数嵌套得到的字符串发送函数。而hal库直接给我们提供好了这么多便捷的串口收发函数,比如轮询式最普通的收发函数,还给我们添加了超时保护,所以我觉得在hal库这里对于江科大的串口收发函数的复现是意义不大的。

uint8_t zfc[20];//收发数组
int main(void)
{OLED_Init();//初始化OLED显示屏HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_USART1_UART_Init();OLED_ShowString(1, 1, "RxData:");HAL_UART_Receive_IT(&huart1,zfc,3);//开启中断接受while (1){OLED_ShowHexNum(1,8,zfc[0],2);//显示接收到的值OLED_ShowHexNum(1,11,zfc[1],2);OLED_ShowHexNum(1,14,zfc[2],2);HAL_UART_Transmit(&huart1,zfc,3,1000);//发送接收到的值HAL_Delay(1000);//延时1s,不然会眼花缭乱的}
}void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){if(huart == &huart1){
//        OLED_ShowString(2,1,"success");//测试中断是否成功接收HAL_UART_Receive_IT(&huart1,zfc,3);//重新启动中断接受}
}

CubeMx创建的文件注释部分太多了,我把注释部分删掉了,这样所有先关代码就能全部显示在一个界面上了。

我这里是固定长度的收发,如果要实现字符串收发,也可以用字符串相关函数,把固定长度修改成字符串的长度即可(应该是str_len函数)


http://www.hkcw.cn/article/pgWIOaclTK.shtml

相关文章

基于本地知识库的政务问答智能体

1.项目背景&#xff1a; 近年来&#xff0c;国家大力推进 “数字政府”“智慧政务” 建设&#xff0c;《“十四五” 数字经济发展规划》《关于加强数字政府建设的指导意见》等政策文件明确提出&#xff0c;要运用新一代信息技术优化政务服务流程&#xff0c;推动政务服务从 “…

python面向对象

可调用对象的范围包括&#xff1a;用户定义的函数&#xff0c;匿名函数&#xff0c;内置函数和内置方法&#xff0c;类&#xff0c;在类中定义的方法&#xff0c;生成器函数&#xff0c;如果类实现了_call 方法&#xff0c;那么类的实例对象也是可调用对象。 1 变量 1.1 类属性…

纯html,js创建一个类似excel的表格

后台是php,表中数据可编辑,可删除,可提交到数据库 <!DOCTYPE html> <html> <head><meta charset="utf-8"><style>body {font-family: Arial, sans-serif;margin: 20px;background-color: #fff;}.toolbar {margin-bottom: 10px;disp…

【测试】设计测试⽤例方法

设计测试⽤例方法 等价类 依据需求将输入&#xff08;特殊情况下会考虑输出&#xff09;划分为 若⼲个等价类 &#xff0c;从等价类中 选出⼀个测试⽤例 &#xff0c;如果 这个测试⽤例测试通过&#xff0c;则 认为所代表的等价类测试通过 &#xff0c;这样就可以⽤较少的测试…

摩尔信使MThings无法生成机器码的解决方法

在使用摩尔信使MThings的过程中&#xff0c;部分用户&#xff08;Win11操作系统&#xff09;可能会遇到无法生成机器码的问题&#xff0c;这将影响软件的正常授权。机器码是软件授权管理的关键环节&#xff0c;用于确保授权证书与特定设备的绑定。 解决步骤&#xff1a; 1、按 …

设计师如何搭建自己的素材库?

在数字化设计时代&#xff0c;设计资产已成为团队核心竞争力的重要组成部分。无论是UI组件、品牌视觉规范&#xff0c;还是交互原型和历史版本文件&#xff0c;这些资源的高效管理直接影响着设计质量和团队协作效率。然而&#xff0c;许多设计师仍深陷“文件混乱-重复劳动-版本…

AU6815集成音频DSP的2x25W数字型ClaSS D音频功率放大器(替代TAS5805)

1.特性 ● 输出配置 - 立体声 2.0: 2x25W (8Ω,21V,THD N 1%) - 立体声 2.0: 2x23W (6Ω, 18V,THD N 1%) ● 供电电压范围 - PVDD:4.5V-21V - DVDD: 1.8V 或者 3.3V ● 静态功耗 - 31.5mA at PVDD12V,BD - 18.5mA at PVDD12V,1SPW ● 音频性能指标 - Noise: ≤38uVrms - TH…

国产 BIM 软件万翼斗拱的技术突破与现实差距 —— 在创新与迭代中寻找破局之路

万翼斗拱在国产BIM领域迈出重要一步&#xff0c;凭借二三维一体化、参数化建模及AI辅助设计等功能形成差异化竞争力&#xff0c;在住宅设计场景中展现效率优势&#xff0c;但与国际主流软件相比&#xff0c;在功能完整性、性能稳定性和生态成熟度上仍有显著差距&#xff0c;需通…

企业内训系统源码开发详解:直播+录播+考试的混合式学习平台搭建

在企业数字化转型的大潮中&#xff0c;员工培训早已不再是传统教室中的一场场“走过场”&#xff0c;而是通过技术驱动的“系统化能力提升”。尤其在知识更新换代加速、竞争压力日益激烈的背景下&#xff0c;企业越来越倾向于建设自主可控、功能灵活、支持多种学习形态的内训平…

HbuilderX设置禁止import 引入模块换行

设置前效果&#xff1a; 设置&#xff1a;工具→插件配置→打开文件jsbeautifyrc.js进行配置 // 修改这个配置项 "brace_style": "collapse,preserve-inline", 配置后效果&#xff1a;

小白的进阶之路系列之七----人工智能从初步到精通pytorch自动微分优化以及载入和保存模型

本文将介绍Pytorch的以下内容 自动微分函数 优化 模型保存和载入 好了,我们首先介绍一下关于微分的内容。 在训练神经网络时,最常用的算法是反向传播算法。在该算法中,根据损失函数相对于给定参数的梯度来调整参数(模型权重)。 为了计算这些梯度,PyTorch有一个内置…

王树森推荐系统公开课 特征交叉01:Factorized Machine (FM) 因式分解机

对于FM的评价&#xff0c;引用视频底下的评论&#xff1a; FM算法在很久之前使用广泛&#xff0c;现在已逐渐淘汰。 线性模型只是加权和&#xff0c;没有考虑多个特征之间的交叉&#xff0c;在推荐系统中&#xff0c;特征交叉的作用是相当重要的。 如果 d d d 太大就不合适…

IAR无法跳转定义,IARstm8跳转显示路径出错,系统库文件文件名后有[RO]

当我们打开程序后&#xff0c;按下键盘F12无跳转或者显示路径出错 原因就是库文件是只读类型&#xff0c;在IAR里面无法跳转&#xff0c;可以看到后缀显示【RO】 解决办法就是&#xff0c;把IAR软件关闭&#xff0c;把标准库文件的只读给取消掉 重新打开IAR工程 然后修改头文件…

从零开始的云计算生活——第十一天,知识延续,程序管理。

一故事背景 今日整体内容是第十天的剩余部分再加上程序管理的开头部分&#xff0c;详细可以回到第十天看新增加内容&#xff0c;现在开始讲解新内容。 二Linux程序与进程 1程序,进程,线程的概念 程序&#xff1a;‌是一段静态的代码&#xff0c;它是应用软件执行的蓝本。程序…

STM32 单片机启动过程全解析:从上电到主函数的旅程

一、为什么要理解启动过程&#xff1f; STM32 的启动过程就像一台精密仪器的开机自检&#xff0c;它确保所有系统部件按既定方式初始化&#xff0c;才能顺利运行我们的应用代码。对初学者而言&#xff0c;理解启动过程能帮助解决常见“程序跑飞”“不进 main”“下载后无反应”…

2022 RoboCom 世界机器人开发者大赛(睿抗 caip) -高职组(国赛)解题报告 | 科学家

前言 题解 2022 RoboCom 世界机器人开发者大赛(睿抗 caip) -高职组&#xff08;国赛&#xff09;。 最后一题还考验能力&#xff0c;需要找到合适的剪枝。 RC-v1 智能管家 分值: 20分 签到题&#xff0c;map的简单实用 #include <bits/stdc.h>using namespace std;int…

typora插件下载链接和导入说明

1.引言 先看插件效果&#xff0c;本插件自带了历史文件tab切换、引用图片管理、思维导图、文档大纲、图排优化、文件模板、夜间模式等很多功能&#xff0c;插件的下载链接在本文最后。 2.安装插件 typora-0.9.98 之前的版本不推荐使用 插件解压为plugin文件夹&#xff0c;并移…

深化生态协同,宁盾身份域管完成与拓波软件兼容互认证

在信创产业蓬勃发展的浪潮下&#xff0c;行业生态的兼容适配决定了信创产品是否好用。近日&#xff0c;宁盾身份域管与拓波软件 TurboEX 邮件系统完成兼容互认证。测试结果显示宁盾身份域管&#xff08;信创版&#xff09;与 TurboEX 邮件服务器软件相互良好兼容&#xff0c;运…

Socket 编程 TCP

目录 1. TCP socket API 详解 1.1 socket 1.2 bind 1.3 listen 1.4 accept 1.5 read&&write 1.6 connect 1.7 recv 1.8 send 1.9 popen 1.10 fgets 2. EchoServer 3. 多线程远程命令执行 4. 引入线程池版本翻译 5. 验证TCP - windows作为client访问Linu…

SmolVLM2: The Smollest Video Model Ever(七)

编写测试代码与评价指标 现在的数据集里面只涉及tool的分类和手术phase的分类&#xff0c;所以编写的评价指标还是那些通用的&#xff0c;但是&#xff1a; predicted_labels:[The current surgical phase is CalotTriangleDissection, Grasper, Hook tool exists., The curre…