STM32使用HAL库实现串口通讯

发布者:真诚友谊最新更新时间:2019-08-28 来源: eefocus关键字:STM32  HAL库  串口通讯 手机看文章 扫描二维码
随时随地手机看文章

一、对中断的理解。

该文章引用自单片机技术–新浪博客


为了提高CPU的工作效率以及对实时系统的快速响应,产生了中断控制方式的信息交换。


在日常生活中广泛存在着“中断”的例子。例如一个人正在看书,这时电话铃响了,于是他将书放下去接电话。为了在接完电话后继续看书,他必须记下当时的页号,接完电话后,将书取回,从刚才被打断的位置继续往下阅读。由此可见,中断是一个过程。计算机是这样处理的,当有随机中断请求后,CPU暂停执行现行程序,转去执行中断处理程序,为相应的随机事件服务,处理完毕后CPU恢复执行被暂停的现行程序。


在这个过程中,应注意如下几方面:


一、 外部或内部的中断请求是随机的,若当前程序允许处理应立即响应;


二、 在内存中必须有处理该中断的处理程序;


三、 系统怎样能正确地由现行程序转去执行中断处理程序;


四、 当中断处理程序执行完毕后怎样能正确地返回。


现在再从另一方面分析,整个中断的处理过程就像子程序调用,但是本质的差异是调用的时间是随机的,调用的形式是不同的。因此,是否可以认为处理中断的过程是一种特殊的子程序调用。如图5.1和 图5.2 所示。


在这里插入图片描述

中断有两个重要特征:程序切换(控制权的转移)和随机性。


二、中断源,中断标志等概念

中断源就是向CPU发出中断请求的来源。中断源发出请求,CPU响应中断后便转向中断服务程序。中断源引起的中断服务程序入口地址即为中断矢量地址。中断向量地址是固定的,用户不可改变。

由于两个相邻的中断服务程序入口地址间隔仅为8字节,一般的中断服务程序是容纳不下的。通常是在相应的中断服务程序入口地址中放一条长跳转指令LJMP,这样就可以转到64KB的任何可用区域了。若在2KB范围内转移,则可存放AJMP指令。


由于0003H~002BH是中断矢量地址区,因此,单片机应在程序入口地址0000H处放一条无条件转移指令(如LJMP XXXXH),转到指定的主程序地址。


中断接收

该文章参考自“狗尾巴草word”前辈


中断接收的触发流程

(以USART2为例)

串口中断接收的流程:


USART2_IRQHandler(void) -> HAL_UART_IRQHandler(UART_HandleTypeDef *huart) -> UART_Receive_IT(UART_HandleTypeDef *huart) -> HAL_UART_RxCpltCallback(huart);


Callback函数就是用户要重写在main.c里的回调函数。


再说明一下一个很重要的问题:STM32的每个串口中断有好几个(发送接收等),但是只要是与串口相关的中断发生系统都会先调用同一个函数,也就是中断向量表中的那个,比如usart2的话就是USART2_IRQHandler(void),然后这个函数再调用HAL_UART_IRQHandler,在HAL_UART_IRQHandler中去读取寄存器判断究竟是那几个位被置为1,确定好是哪个中断之后(接收还是发送)再调用不同的回调函数。


回调函数就在这个UART_Receive_IT(huart)函数里。

在回调函数上边有两行很重要的代码

在这里插入图片描述

这两行代码的作用是关闭串口接收中断,也就是说,在一次串口中断接收过程的最后,即串口接收完一组数据之后会关闭串口接收中断。(比如看书时接电话的例子中,接电话的最后,设置为电话不再响。自己目前的理解,不一定对)(这个后面还会再讲,先记住)。


如何使用接收中断。

在cube中配置完了之后并没有使能串口中断(有一个串口初始化函数,但是在这个函数中并未使能串口中断)需要用户手动使能。使能代码如下:

在这里插入图片描述

什么意思呢?

HAL库的串口接收思路是这样的:函数把这个缓存区对应到串口的接收,上面函数的意思就是把kRxBuffer(这是一个数组)作为缓存区,指定大小为10。然后usart2接收数据的时候就放到kRxBuffer这个数组中,只有当接收到10个数据之后才调用一次callback函数(回调函数)**。


当然不要忘了该函数的使能串口接收中断功能。在"中断接收的流程"1节中说到了串口接收完数据后会关闭使能,所以,在回调函数中一定要再写一次HAL_UART_Receive_IT(&huart2, (uint8_t *)kRxBuffer, 10),使能接收中断。


小小的总结下串口中断接收怎么用:

(1)指定一个缓存区(串口接收到的数据会全部堆到这个缓存区)


(2)使能串口接收中断,并把缓存区对应到串口


(3)在回调函数中实现接收到数据之后的操作(比如处理数据)并再次使能串口接收中断。


所以更具体一下串口接收的流程就是这样的:


(1)串口一个接一个的接收到数据填充到缓存区


(2)缓存区满(大小是用户定义的)程序几经辗转最后会调用到回调函数。


(3)执行用户在回调函数中实现的功能。


中断发送

该文章参考自“狗尾巴草word”前辈


中断发送的触发流程

一、由于在STM32中usart2的入口中断只有一个:

在这里插入图片描述

就是上图的中断向量表中红框标出来的。其他的所有中断其实都是从这里出发的,我们再和捋接收一样捋一遍发送。

首先是USART2_IRQHandler,找到这个函数原型(这一步和接收完全一样):

在这里插入图片描述

二、再找HAL_UART_IRQHandler(&huart2);原型:

在这里插入图片描述

到这里还是和接收完全一样,注意是完全一样,源码也就是上面接收贴出来的一样。这次我们主要注意该函数最后几行(可以翻上去看源码):

在这里插入图片描述

把中间代码收起来以后看最后红框,这就很明显了,这里触发了发送中断(软件触发)

三、接着去找这个UART_EndTransmit_IT(huart)的函数原型:

在这里插入图片描述

第一个红框里清除了发送中断使能(同接收一样,在用完之后就关掉,但是不同于接收,发送完成就不用再在回调函数中使能了,因为在中断发送的时候就会使能)

第二个红框调用回调函数。


如何使用发送中断

中断发送的意思,非常类似于中断接收,但其中有一些不同,看下面这个函数:


HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)


一个非常类似于中断接收使能的函数。接收中断使能函数的作用是绑定接收缓存区并使能接收中断,但是对于发送,该函数的作用是发送指定长度的指定数据并使能发送中断。


比如有一个unsigned char 数组a[10],HAL_UART_Transmit_IT(&huart2, a, 10),这一句的意思是用usart2(串口2)发送a数组中的10个数据,然后使能发送中断。

当发送完成之后(或者发送一半,发送一半也有个中断)就会执行回调函数。


总结一下发送中断:


使用HAL_UART_Transmit_IT函数发送指定长度的数据,并使能发送中断,发送到一半和发送结束会触发中断(相关的回调函数是HAL_UART_TxHalfCpltCallback()和HAL_UART_TxCpltCallback())中断触发后发送中断使能会被清除,然后调用回调函数,回调函数执行完成之后结束本次发送。


HAL库串口测试程序

需求:需要接收到10个字符之后原样返回,发送完成后还要改变LED状态,所以要用中断,发送接收都要。

(1)定义一个字符变量,两个缓存数组(uint8_t其实就是unsigned char类型)

在这里插入图片描述

(2)在while(1)之前先使能接收中断并绑定接收缓存数组指定大小。

在while(1)中:先发送一个字符,再发送字符数组中的字符,最后延时一下要不然一会发送的太快不利于观察。

在这里插入图片描述

(3)写回调函数(两个)

在这里插入图片描述

(4)下载验证即可

在这里插入图片描述

关键字:STM32  HAL库  串口通讯 引用地址:STM32使用HAL库实现串口通讯

上一篇:STM32使用HAL库驱动USART详解及例程
下一篇:STM32 Uart 接收不定长数据

推荐阅读最新更新时间:2024-11-06 16:03

stm32中断学习篇(1)——以定时器为例
ARM coretex_m3内核支持256个中断和可编程256级中断优先级设置。 Stm32的NVIC是coretex_m3的NVIC的子集。 Stm32目前支持84个中断和16级可编程中断优先级。仅使用中断优先级设置8位中的高四位。 每个中断对应一个外围设备,每个外围设备包括许多个引起中断的中断源或中断事件。这些中断源与中断事件都要通过指定的中断通道向内核申请中断。中断通道的优先级确定设备整体的优先级,而设备本身的多个中断执行顺序由用户的中断服务程序决定。 Stm32的68个外部中断通道固定分配给相应的外部设备。每个终端通道都具备自己的中断优先级控制字节PRI_n(8位,用高四位),每四个通道构成一个32位优先级寄存器。总共
[单片机]
<font color='red'>stm32</font>中断学习篇(1)——以定时器为例
STM32_TIM定时-中断
今天讲解STM32F103定时器定时-中断功能,在昨天定时器延时的软件工程上添加TIM3定时的功能,自己也可以试着将昨天的工程添加修改得到。 今天的软件工程下载地址(360云盘): https://yunpan.cn/cPnJ9KYcXbPsP 访问密码 acd8 工程现象:间隔(定时器定时)500ms LED变化一次, 并且串口打印 STM32F103ZE有8个定时器(TIM1 – TIM8), 改工程以TIM3定时为例。 STM32F10x的资料可以在我360云盘下载: https://yunpan.cn/crBUdUGdYKam2 访问密码 ca90 关于TIM延时,我把重要的几点在下面分别讲述
[单片机]
STM32_TIM定时-中断
STM32】stm32f407 + DS18B20 碰出不一样的火花
前言 之前在这篇文章:【STM32学习记录4】1.44寸TFT液晶屏显示字符、汉字和图片 卖了一个关子: 开发板:stm32f407VET6 开发环境:keil5 MDK 一、硬件基础——DS18B20 1.DS18B20简介 2.硬件连接 根据手册,DS18B20的硬件接法很简单,分为以下两种: 需要注意的是不管哪一种接法DQ上一定要接个上拉电阻 1.【寄生接法】 DS18B20_GND → to→ STM32F407_GND DS18B20_VCC → to→ STM32F407_GND DS18B20_DQ → to→ STM32F407_P** DQ引脚可接任意IO口 关于寄生方式,
[单片机]
【<font color='red'>STM32</font>】stm32f407 + DS18B20 碰出不一样的火花
STM32单片机常用库函数 STM32单片机系统作用
STM32单机片又被称为嵌入式单机片,靠着高性能、低成本、低功耗、可裁剪吸引着大家。 系统作用 1、集成嵌入式Flash和SRAM存储器的ARM Cortex-M3内核。 2、嵌入式Flash存储器和RAM存储器 3、可变静态存储器(FSMC 4、嵌套矢量中断控制器(NVIC) 5、外部中断/事件控制器(EXTI) 6、时钟和启动 7、Boot模式 STM32单片机常用库函数 1.GPIO初始化函数 用法: voidGPIO_Configuration(void) { GPIO_InitTypeDefGPIO_InitStructure;//GPIO状态恢复默认参数 GPIO_InitStructure.GPIO_Pin=
[单片机]
关于STM32串口printf输出调试信息问题
1,遇到的问题(使用HAL库) 在STM32使用过程中,我们程序调试时一般都会用到printf重定向串口输出调试信息来进行程序开发调试,从网上我们找到了重定向的代码部分加入到串口代码文件中,如下: UART_HandleTypeDef husart_printf; #ifdef __GNUC__ /* With GCC/RAISONANCE, small printf (option LD Linker- Libraries- Small printf set to 'Yes') calls __io_putchar() */ #define PUTCHAR_PROTOTYPE int __io_
[单片机]
STM32+FreeRTOS+CUBEMX_学习笔记(三)
一、前言和目的: 在使用freertos的过程中,难免会遇到关于任务优先级和时间片分配的问题。为了更好的使用该系统,学习了下面的一些知识。 看freertos源文档 时间片调度 抢占式调度 对比两种调度的方式 二、freertos文档: 2.0、看看源文档: 源文档是个好东西啊,虽然网上的论坛和帖子里面都存在很多的答案,但是任何转述的东西或者自己的语言都经过了一定的加工和改造。虽然可能会让人更加容易理解,但是终究是不如源文档的正式和官方。 以下为对源文档的学习和翻译: 2.1、freertos任务定义: Tasks are implemented as C functions. The only thing speci
[单片机]
STM32+FreeRTOS+CUBEMX_学习笔记(三)
STM32中断里的那些事,你都知道吗?
1.抢占优先级和响应优先级 STM32 的中断向量具有两个属性,一个为抢占属性,另一个为响应属性,其属性编号越小,表明它的优先级别越高。 抢占 是指打断其他中断的属性,即因为具有这个属性会出现嵌套中断(在执行中断服务函数A 的过程中被中断B 打断,执行完中断服务函数B 再继续执行中断服务函数A) 三.例如: 谁能打断谁? 若内核正在执行C 的中断服务函数,则它能被抢占优先级更高的中断A 打断,由于B和C 的抢占优先级相同,所以C 不能被B 打断。 但如果B 和C中断是同时到达的,内核就会首先响应响应优先级别更高的B 中断。 2.EXTI15_10_IRQn与EXTI9_5_IRQn的区别 EXTI0_IRQC
[单片机]
<font color='red'>STM32</font>中断里的那些事,你都知道吗?
STM32系列是大端还是小端?
ARM的手册上有关于大小端的描述,如下: The processor can access data words in memory in little-endian format or big-endian format. It always accesses code in little-endian format. Note: Little-endian is the default memory format for ARM processors. STM32是固定配置为小端的 The bytes are coded in memory in Little Endian format. The lowest number
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved