stm32 笔记 UART读取及HAL库应用

news2025/1/12 22:47:47

 基本流程图

 由此图可知:
采用HAL库,中断方式接收串口,只有当RxXferCount == 0 时,也就是调用这个函数,接收指定量的数据大小完成时,才会调用回调函数HAL_UART_RxCpltCallback()。

而且,RxXferCount == 0 后,也会使得中断退出,此时需要从新设置 HAL_UART_Receive_IT() 开启中断。

这里还需要注意下面两个函数的区别,HAL_UART_Receive_IT()HAL_UART_Receive()
分别为为非阻塞模式下接受数据,和阻塞模式下接受数据。

初始化 UART

void uart_init()
{
    UART_HandleTypeDef usart1_handler;
	//UART 初始化设置
	usart1_handler.Instance=USART1;					    //USART1
	usart1_handler.Init.BaudRate=115200;				    //波特率
	usart1_handler.Init.WordLength=UART_WORDLENGTH_8B;   //字长为8位数据格式
	usart1_handler.Init.StopBits=UART_STOPBITS_1;	    //一个停止位
	usart1_handler.Init.Parity=UART_PARITY_NONE;		    //无奇偶校验位
	usart1_handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;   //无硬件流控
	usart1_handler.Init.Mode=UART_MODE_TX_RX;		    //收发模式
	HAL_UART_Init(&usart1_handler);					    //HAL_UART_Init()会使能UART1
}

 无需解释,只是 UART 的初始配置。

UART1 端口配置初始化

void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
    //GPIO端口设置
	GPIO_InitTypeDef GPIO_Initure;
	
	if(huart->Instance==USART1)//如果是串口1,进行串口1 MSP初始化
	{
		__HAL_RCC_GPIOA_CLK_ENABLE();			//使能GPIOA时钟
		__HAL_RCC_USART1_CLK_ENABLE();			//使能USART1时钟
	
		GPIO_Initure.Pin=GPIO_PIN_9;			//PA9
		GPIO_Initure.Mode=GPIO_MODE_AF_PP;		//复用推挽输出
		GPIO_Initure.Pull=GPIO_PULLUP;			//上拉
		GPIO_Initure.Speed=GPIO_SPEED_FAST;		//高速
		GPIO_Initure.Alternate=GPIO_AF7_USART1;	//复用为USART1
		HAL_GPIO_Init(GPIOA,&GPIO_Initure);	   	//初始化PA9

		GPIO_Initure.Pin=GPIO_PIN_10;			//PA10
		HAL_GPIO_Init(GPIOA,&GPIO_Initure);	   	//初始化PA10
		
		HAL_NVIC_SetPriority(USART1_IRQn,3,3);	//设置中断优先级
		HAL_NVIC_EnableIRQ(USART1_IRQn);		//使能中断
	}
}

 上一段代码最后一行 HAL_UART_Init() 会自动调用这个端口初始化函数。因为 UART1 依赖于PA9 和 PA10 所以需要初始化这两个 GPIO 的配置,在最后两行中,为UART1 设置了中断优先级并使能。

中断响应函数

void  USART1_IRQHandler (void) 函数是串口1的中断响应函数,当串口1 发生了相应的中断后,就会跳到该函数执行。

void USART1_IRQHandler(void){
	HAL_UART_IRQHandler(&usart1_handler);
	HAL_UART_Receive_IT(&usart1_handler,rdata,sizeof(rdata)); //开启中断
}

值得注意的是,每次相应中断后,就会关闭之后的相应。

需要调用 HAL_UART_Receive_IT() 从新注册这个相应中断。

中断相应回调函数

当 huart->RxXferCount 等于0时,HAL 就会帮我们调用 HAL_UART_RxCpltCallback 此函数才是真正的实现逻辑的地方。在下列函数中,会在读缓存区中取一个字符,并且通过串口回传给电脑。

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
	u8 rec;
	if(huart->Instance == USART1){
		rec = *((huart->pRxBuffPtr)-1);
		HAL_UART_Transmit(&usart1_handler,&rec,1,1000);
	}
}

代码与执行结果

#include "sys.h"
#include "delay.h"

//初始化IO 串口1 
//bound:波特率
UART_HandleTypeDef usart1_handler;
u8 rdata[1];

void uart_init()
{
	//UART 初始化设置
	usart1_handler.Instance=USART1;					    //USART1
	usart1_handler.Init.BaudRate=115200;				    //波特率
	usart1_handler.Init.WordLength=UART_WORDLENGTH_8B;   //字长为8位数据格式
	usart1_handler.Init.StopBits=UART_STOPBITS_1;	    //一个停止位
	usart1_handler.Init.Parity=UART_PARITY_NONE;		    //无奇偶校验位
	usart1_handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;   //无硬件流控
	usart1_handler.Init.Mode=UART_MODE_TX_RX;		    //收发模式
	HAL_UART_Init(&usart1_handler);					    //HAL_UART_Init()会使能UART1
}

void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
    //GPIO端口设置
	GPIO_InitTypeDef GPIO_Initure;
	
	if(huart->Instance==USART1)//如果是串口1,进行串口1 MSP初始化
	{
		__HAL_RCC_GPIOA_CLK_ENABLE();			//使能GPIOA时钟
		__HAL_RCC_USART1_CLK_ENABLE();			//使能USART1时钟
	
		GPIO_Initure.Pin=GPIO_PIN_9;			//PA9
		GPIO_Initure.Mode=GPIO_MODE_AF_PP;		//复用推挽输出
		GPIO_Initure.Pull=GPIO_PULLUP;			//上拉
		GPIO_Initure.Speed=GPIO_SPEED_FAST;		//高速
		GPIO_Initure.Alternate=GPIO_AF7_USART1;	//复用为USART1
		HAL_GPIO_Init(GPIOA,&GPIO_Initure);	   	//初始化PA9

		GPIO_Initure.Pin=GPIO_PIN_10;			//PA10
		HAL_GPIO_Init(GPIOA,&GPIO_Initure);	   	//初始化PA10
		
		HAL_NVIC_SetPriority(USART1_IRQn,3,3);	//设置中断优先级
		HAL_NVIC_EnableIRQ(USART1_IRQn);		//使能中断
	}
}

void USART1_IRQHandler(void){
	HAL_UART_IRQHandler(&usart1_handler);
	HAL_UART_Receive_IT(&usart1_handler,rdata,sizeof(rdata)); //开启中断
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){ //huart->RxXferCount 等于0 也就是读满rdata就执行这个回调函数
	u8 rec;
	if(huart->Instance == USART1){
		rec = *((huart->pRxBuffPtr)-1);
		HAL_UART_Transmit(&usart1_handler,&rec,1,1000);
	}
}


int main(void)
{
    HAL_Init();                     //初始化HAL库    
    Stm32_Clock_Init(360,25,2,8);   //设置时钟,180Mhz
	delay_init(180);
	
	uart_init();
	
	
	HAL_UART_Receive_IT(&usart1_handler,rdata,sizeof(rdata)); //开启中断
	
	while(1){ //必须卡在死循环中,程序执行完毕就不能相应中断了
		delay_ms(3000);
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/45373.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

技术资料:STM32F746NGH7,STM32L471ZGT6 IC MCU+FPU

描述:STM32F7 32 位 MCUFPU 基于高性能的 ARMCortex-M7 32 位 RISC 内核,工作频率高达 216MHz。Cortex-M7 内核具有单浮点单元(SFPU)精度,支持所有 ARM 单精度数据处理指令与数据类型。同时执行全套 DSP 指令和存储保护单元(MPU&a…

ThreadLocal源码解析 2.ThreadLocalMap内核

ThreadLocal源码解析—ThreadLocalMap内核 简介 内部类 ThreadLocalMap 才是 ThreadLocal 的真正核心。 ThreadLocalMap 与 HashMap不一样,HashMap 中的数据结构有数组,链表还有红黑树;而 ThreadLocalMap 中的数据结构只有数组。HashMap 处…

反转链表与拓展【灵神基础精讲】

来源0x3f:https://space.bilibili.com/206214 文章目录反转链表[206. 反转链表](https://leetcode.cn/problems/reverse-linked-list/)[92. 反转链表 II](https://leetcode.cn/problems/reverse-linked-list-ii/)[25. K 个一组翻转链表](https://leetcode.cn/proble…

[附源码]Python计算机毕业设计Django仓储综合管理系统

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,…

windows改linux

使用旧的windows电脑改成linux机器,不使用双系统,直接格式化 本次需要两个U盘或者两台电脑。 制作WINPE启动盘 使用U深度制作启动盘,制作完成后进入PE系统,然后使用diskGenius删除所有电脑的分区进行快速分区,格式选…

R语言主成分回归(PCR)、 多元线性回归特征降维分析光谱数据和汽车油耗、性能数据...

原文链接:http://tecdat.cn/?p24152什么是PCR?(PCR PCA MLR)(点击文末“阅读原文”获取完整代码数据)。• PCR是处理许多 x 变量的回归技术• 给定 Y 和 X 数据:• 在 X 矩阵上进行 PCA– 定…

力扣(LeetCode)116. 填充每个节点的下一个右侧节点指针(C++)

模拟 这题可以直接操作根节点,我们保存根结点,用作最终返回值。 填充每个结点的 nextnextnext 指针,其实是树的层序遍历。由于 nextnextnext 指针的存在,我们可以做到 O(1)O(1)O(1) 的空间复杂度。 算法: 从根结点出发&#xf…

自动驾驶专题介绍 ———— 动力传动系统

文章目录动力传动系统传统动力传动系统混合动力传动系统串联型并联型串并联型纯电动传动系统电机中央驱动电动轮驱动动力传动系统 汽车动力传动系统是位于发动机和驱动车轮之间的动力传动装置,其基本功用是将发动机发出的动力传输给驱动车轮,以保障汽车在…

JavaWeb简单实例——jQuery

简单介绍: 在之后的学习中,我们会接触到Ajax异步请求,这个异步请求需要我们在网页端使用JS来发送,而使用原生的Ajax请求比较复杂,所以我们就借用一个前端框架封装后的Ajax请求,这样可以简化我们的代码编写…

大坝安全动态监管预警系统 大坝安全监测平台 遥测终端机 水位雨量监测站

平升电子大坝安全动态监管预警系统/大坝安全监测平台/大坝安全监测系统根据SL551-2012《土石坝安全监测技术规范》的整编要求,设置了变形监测、渗流监测、环境量监测。借助该系统可及时了解大坝的工作性态和水库可能存在的事故隐患,为大坝安全管理与水库…

Linux 安装 ElasticSearch

注意事项: 内存不能太小,否则会启动失败JDK版本需要对应,es7 需要 Java 11不能以 root 用户启动 平台确认 大家可以自行安装虚拟机部署,有条件可以在服务器操作。 安装Java 安装 Elasticsearch 之前,你需要先安装一个较…

04. 组合总和

1.题目链接: 39. 组合总和 2.解题思路: 2.1.题目要求: 给定一个“无重复数组candidates”和一个“目标和target” ,要求在给定 数组candidates 的范围内,输出和等于 目标和target 的组合,此组合元素可重复…

Java程序员:三个月刷完1000道面试真题,没想到老板直接给我升职了

同事:前阵子听说你要跳槽,现在准备得怎么样啊?程序员T:不跳了同事:啊?为什么?程序员T:涨薪了呗?同事:真的吗?涨了多少?你自己跟老板谈…

卓豪再签洛钼集团,实现AD域自动化管理有效降低管理人员工作负荷

2022年11月,ManageEngine卓豪续签上海董禾商贸有限公司,将为“洛钼集团”部署ADManager Plus软件,助力IT管理摆脱复杂AD域管理操作,实现AD域管理自动化。 上海董禾商贸 上海董禾商贸有限公司作为洛钼集团在上海的主体公司。洛阳栾…

2.9.39:Flexmonster:网络报告数据透视表组件

用于网络报告的数据透视表组件 用于可视化业务数据的最强大的 JavaScript 工具 与任何技术堆栈集成 该组件可与任何技术堆栈无缝协作: 与Angular、React、jQuery、Vue等 完美集成 没有服务器端依赖 只需几行代码即可开始使用。 加载海量数据集 即使有超过一百万行…

珠宝商城小程序开发的价值和优势

珠宝行业的巨大利润空间就决定了行业内激烈的竞争压力,而随着时代的发展,单一的线下门店营销方式很难让珠宝行业得到更好的发展。为了防止顾客流失,挖掘潜在的消费潜力,珠宝行业开始向科技化、互联网化、移动化的方向开拓市场&…

Sentinel-2(哨兵2数据介绍)

哥白尼 Sentinel-2(哨兵 2)计划是一个由两颗相同的 Sentinel-2 极轨卫星组成的星座,两颗卫星相位差 180,运行在平均高度 786 km 的太阳同步轨道上。每颗卫星在其轨道上的位置由双频全球导航卫星系统(GNSS)接…

Kubernetes资源调度之污点与Pod容忍度

Kubernetes资源调度之污点与Pod容忍度 概述 污点是定义在节点之上的键值型属性数据,用于让节点有能力主动拒绝调度器将Pod调度运行到节点上,除非该Pod对象具有接纳节点污点的容忍度。容忍度(tolerations)则是定义在Pod对象上的键值型属性数据&#xff0c…

WAVE SUMMIT+2022明日开场,六大看点不容错过!

在2022年最后一个乐章奏响之前,WAVE SUMMIT第八届峰会将率先拉开帷幕。11月30日,由深度学习技术及应用国家工程研究中心主办、百度飞桨承办的WAVE SUMMIT2022深度学习开发者峰会将以网上直播的方式呈现。明日14点,冬日AI盛会WAVE SUMMIT2022将…

.Net 7 Native AOT 单文件 无依赖 跨平台

2022.11.18 Native AOT 正式发布,不再是 实验性项目。 .Net 7 Console App & WebApi 使用PublishAOT true,直接编译 成exe,无rutime依赖,智能裁剪,体积小,启动快。 环境: 1.更新VS2022 …