历史上的今天
返回首页

历史上的今天

今天是:2024年08月28日(星期三)

正在发生

2019年08月28日 | STM32使用HAL库实现串口通讯

2019-08-28 来源:eefocus

一、对中断的理解。

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


为了提高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)下载验证即可

在这里插入图片描述

推荐阅读

史海拾趣

Continental公司的发展小趣事

随着汽车工业的发展,大陆集团开始将业务扩展到汽车轮胎领域。1901年,马牌轮胎首次与德国戴姆勒·奔驰汽车公司合作参加汽车竞赛,这标志着大陆集团正式进入汽车轮胎市场。仅仅三年后,大陆集团就生产出了全世界第一条带花纹的汽车轮胎,这一创新大大提高了轮胎的抓地力和安全性。1908年,大陆集团又生产出了全世界第一个可拆装的车轮,使车轮和车轴分开,由此大大节省了换轮胎的时间。这些技术创新使得大陆集团在汽车轮胎市场上占据了重要地位。

Altitude Technology公司的发展小趣事

Altitude Technology公司成立于一个科技迅猛发展的时代,创始人李华怀揣着对电子技术的热爱和对未来科技的憧憬,决定创立一家专注于高度集成和智能化电子产品研发的公司。初期,公司面临着资金短缺、人才匮乏等重重困难,但李华凭借对技术的深刻理解和敏锐的市场洞察力,带领团队开发出了一款具有划时代意义的智能手环,这款产品以其出色的性能和人性化的设计迅速在市场上获得了认可,为Altitude Technology公司赢得了第一桶金。

BREL International Components公司的发展小趣事

品质是BREL International Components公司发展的基石。公司从原材料采购到生产流程控制,再到产品检测,都严格遵循国际质量标准。BREL还建立了完善的品质管理体系,通过定期的质量检查和持续改进,确保每一件产品都达到客户的要求。正是这种对品质的执着追求,让BREL的产品在市场上赢得了良好的口碑,品牌价值不断提升。

DURATOOL公司的发展小趣事

在电子行业,产品质量是企业生存和发展的基石。DURATOOL公司深知这一点,因此一直将品质管理作为企业发展的核心。公司建立了严格的质量管理体系,从原材料采购到产品生产、检验、包装等各个环节都进行严格把关。此外,DURATOOL公司还积极引入国际先进的质量管理理念和方法,不断提升产品质量水平。这些努力使得DURATOOL公司的产品在市场上享有良好的口碑和信誉,赢得了广大用户的信任和支持。

ATO SOLUTION公司的发展小趣事

随着公司规模的扩大,ATO SOLUTION公司开始实施全球化战略布局。公司先后在多个国家和地区设立了研发中心和生产基地,充分利用当地资源和市场优势,提升整体竞争力。同时,公司还加强了与国际知名企业的合作,共同推动电子行业的发展和创新。

Easy Braid公司的发展小趣事

在技术创新和品质保证的基础上,Easy Braid开始积极拓展市场。公司不仅在国内市场取得了良好的业绩,还逐步将目光投向了国际市场。通过与国外知名企业的合作,Easy Braid成功地将自己的产品打入国际市场,实现了品牌的全球化布局。这一过程中,Easy Braid展现出了强大的市场竞争力和适应能力。

问答坊 | AI 解惑

什么叫DLP、LCD背投电视!

本帖最后由 jameswangsynnex 于 2015-3-3 20:00 编辑 答:DLP背投的核心就是DMD芯片,只有火柴盒大小的芯片上竟密密麻麻地排列了80万至100万面小镜子,而且每个小镜子都可以独立向正负方向翻转10度,并可以每秒钟翻转65000次。 ...…

查看全部问答>

收集到的LED点阵控制Proteus仿真实例

新手大家多支持啊,,,,,见笑了…

查看全部问答>

变频器负载匹配办法

生产机械的种类繁多,性能和工艺要求各异,其转矩特性不同,因此应用变频器前首先要搞清楚电动机所带负载的性质,即负载特性,然后再选择变频器和电动机。负载有三种类型:恒转矩负载、风机泵类负载和恒功率负载。不同的负载类型,应选择不同类型的 ...…

查看全部问答>

奥普拉在美国斯坦福大学毕业典礼上的演讲

大家都知道,奥普拉是美国著名的电视节目主持人。 过去几周,只要有人问我忙什么?我就说:我准备去斯坦福大学演讲。事实上,我连田纳西州立大学都没有毕业。 其实,这整个世界,我们所居住的宇宙,就像个大教室,等着我们一个学分、 一 ...…

查看全部问答>

Windows CE在指纹传感器设备驱动程序开发中的应用.pdf

Windows CE在指纹传感器设备驱动程序开发中的应用.pdf…

查看全部问答>

请问一个模拟电路问题

请问在基本共射放大电路里面U0=-Ic(Rc//Rl)这个式子如何来的?Rc,Rl中应该没有电流通过啊?谢谢…

查看全部问答>

I2CSB问题....有图有真相.....

下载 (56.37 KB) 2010-6-6 17:04 各种位都设好了 就是不进中断 哪位好心人帮帮俺....困扰好几天了…

查看全部问答>

avr mega16 USB下载不了了

提示什么chip enable program error   开始很好  我一个哥们拿去用他的USB下载器只写了一下熔丝位就再也不能烧程序等所有对avr 的操作了  求助大仙…

查看全部问答>

如何在msp430f161X 上实现IAP功能

我的需求是希望在程序运行过程中,实现自我升级的功能. 也就是说, 正在运行的程序会将从串口接受到的新程序写入Flash中, 而新的程序会在设备再次启动后自动加载! 那位高手从事过相关的开发,请指教,谢谢! any comment is welcomed, Thanks!…

查看全部问答>

请推荐时钟分配芯片?

不知道该发哪个版,就发这里了。能将一个时钟复制成多路然后分配给其他需要时钟的芯片。…

查看全部问答>