| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 嵌入式 -> YIE002开发探索06-串口(中断) -> 正文阅读 |
|
[嵌入式]YIE002开发探索06-串口(中断) |
(请保留-> 作者: 罗冰 https://blog.csdn.net/luobing4365) YIE002开发探索之串口(中断)用轮询的方式获取串口数据,是一种非常低效的方法。本篇尝试使用中断的方式,来实现串口的通信。 1 STM32的串口中断在上一篇中,简单介绍过STM32的串口。轮询方式的编码中,只需要了解相关API的用法就可以了,编写相对简单。 对中断编程而言,这种程度的背景知识是不够的。STM32的Cube Library构建了完整的串口中断编程架构,也提供了相应的API函数供调用。不过,从我的角度来看,这个架构有点难以理解。需要使用者从原理上去了解,才可能自如地使用这些函数。 因此,建议开发人员对串口的寄存器、中断事件等,有了基本的了解后,仔细阅读Cube Library提供的串口函数的实现,再去构建代码较好。 1.1 STM32的中断事件和寄存器以下的内容基本来自于《STM32参考手册》,详细的内容可以在原文档中查找,我主要是将需要的内容进行了整理。 STM32的USART中断请求事情比较丰富,如表1所示。 表1 USART中断请求
表中的EIE标志位,仅当使用DMA接收数据时,才会使用。 USART的各种中断事件,被连接到同一中断向量,表中的中断事件大致可分为发送期间产生的中断事件和接收期间发生的中断事件。也即: 1)发送期间:发送完成、清除发送、发送数据寄存器空。 在实际的编程中,大部分的中断事件,是不需要关注的。编程中,主要关注的是接收数据就绪可读(也即接收数据寄存器非空)、发送完成以及检测到空闲线路。 当然,为了熟悉这些中断事件,对USART的寄存器也必须了解。图1给出了我绘制的思维导图,只对我关系的寄存器位进行了整理,更详细的资料,请参考《STM32参考手册》。 所整理的USART寄存器,在阅读Cube Library的串口代码时,很有参考作用,请大家也试试。 1.2 Cube Library中的串口中断为了解Cube Library中的API函数用法,特别是与中断相关的代码,个人认为最好把源代码通读一遍。 在这之中,需要重点关注对接收数据的处理。图2以串口1的中断函数为例,给出了相关的函数结构关系。 与中断相关的函数包括USART1_IRQHandler()、HAL_UART_IRQHandler()、UART_Receive_IT()、HAL_UART_RxCpltCallback()和UART_Transmit_IT(),它们构建了整个串口的中断架构。Cube Library中提供的中断模式接收函数HAL_UART_Receive_IT(),通过全局变量,以及操纵相应的寄存器位,与串口中断架构进行配合,获取需要的数据。 下面对这些函数的作用进行探索。注意,现在的代码是在STM32Cube_FW_F1_V1.8.4版本下的实现,其他版本的代码可能略有不同。 USART1_IRQHandler()此函数是串口1的中断处理函数,其声明可以在startup_stm32f103xb.s中找到。它是串口接收和发送数据的中断处理函数,代码位于stm32f1xx_it.c中,内容如下所示:
也就是说,在Cube Library提供的架构中,它只调用了HAL_UART_IRQHandler()。实际上,它还允许用户定义其他的功能,以实现Cube Library没有提供的串口中断事件处理,比如后面我们要用到的IDLE中断等。 HAL_UART_IRQHandler()这是串口处理的主要函数,基本的框架都在此实现。先看下函数的基本内容:
从其具体实现来看,它会对接收数据和发送数据进行处理。发送数据的处理过程相对简单,我们主要关注接收数据的处理,所调用的函数是UART_Receive_IT()。 这个函数有大量的寄存器操作,阅读的时候最好对照参考文档。不过,其脉络还是比较清晰的,理解上不会有太大的困难。 UART_Receive_IT()此函数是串口接收数据的处理函数,从其实现代码中,可以窥见与HAL_UART_Receive_IT()配合的过程。
函数中使用的huart->RxXferCount,是由用户调用HAL_UART_Receive_IT()时提供的,表示用户需要接收的串口数据数目。在拿到指定数目的数据后,此函数会关闭中断响应。同时,调用回调函数HAL_UART_RxCpltCallback(),完成数据接收后的操作。 HAL_UART_RxCpltCallback()这是Cube Library提供给用户的回调函数,由用户实现接收到数据之后的操作。其原型如下:
函数使用_weak进行描述,当用户定义时,此定义就失效了。所以用户可以对此函数重新实现和定义,实现需要的功能。 也就是说,Cube Library提供的中断框架中,会在接收到用户指定数目的数据后,禁止中断。而实现接收数据的转存处理,以及使能接收中断的操作,则在HAL_UART_Receive_IT()给出。 HAL_UART_Receive_IT()和HAL_UART_Receive_IT()
这两个函数相对比较简单,给出来用户的缓冲区、需要接收的数据量,并使能接收中断。正好与之前的中断处理函数对应起来。 在了解了上述函数的实现原理后,下面实现完整的中断接收处理示例。 2 YIE002-STM32的串口编程(中断)在实现串口编程的过程中,一直存在一个需要解决的问题:所接受的数据串什么时候结束? 如果是ASCII字符串,一般是以’\0’结尾,也有些STM32的开发板上,以此作为判断依据进行编程。但是在实际应用中,这种限定是不可能的,还得找到其他的方式来进行处理。 查看STM32的参考手册,可以知道“空闲帧”的存在。在每个数据帧接收之后,停止位开始一直为高电平,持续一帧的时间,此时会产生空闲中断。 也就是说,我们可以通过空闲中断,来判定数据帧的结束。因此,本篇的示例中,包含了串口接收和串口空闲中断处理程序的编写。 2.1 串口的Cube MX图形配置在上一篇的串口代码的基础上,添加对串口1中断的支持。需要修改的地方,在Pinout&Configuration栏的System Core下,配置NVIC中与串口1相关的全局中断即可,如图3所示。 将USART1的中断配置抢占优先级为2,子优先级为3就可以了,其他配置都不用改动。 点击GENERATE CODE按钮,生成代码。 2.2 添加应用代码为实现空闲中断,需要在几个地方添加代码。 首先修改stm32f1xx_it.c的串口1处理函数,修改为:
也即添加了对串口1的空闲中断的处理,处理函数为我们添加的MyUser_UART_IDLE_IRQHandler()。 然后在串口1的初始化函数MX_USART1_UART_Init()中,添加对空闲中断的使能代码:
完成这些后,就可以去实现自定义的数据接收和IDLE中断处理函数了。基本步骤如下: 1) 定义全局变量 所定义的全局变量为:
2) 在主程序main()中实现数据的发送处理
3) 在USER CODE BEGIN 4中实现数据的接收函数HAL_UART_RxCpltCallback()
4) 实现自定义的IDLE中断函数
至此就完成了所有的编程工作。 将程序编译下载,按照上一篇同样的方法,使用串口调试助手和USB转串的工具,在PC上进行测试即可。 |
|
嵌入式 最新文章 |
基于高精度单片机开发红外测温仪方案 |
89C51单片机与DAC0832 |
基于51单片机宠物自动投料喂食器控制系统仿 |
《痞子衡嵌入式半月刊》 第 68 期 |
多思计组实验实验七 简单模型机实验 |
CSC7720 |
启明智显分享| ESP32学习笔记参考--PWM(脉冲 |
STM32初探 |
STM32 总结 |
【STM32】CubeMX例程四---定时器中断(附工 |
|
上一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 | -2024/12/28 1:41:49- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |
数据统计 |