文章目录
本文使用stm32tubemx和HAL库完成以下任务:
- 用stm32F103核心板的GPIOA端一管脚接一个LED,GPIOB端口一引脚接一个开关(用杜邦线模拟代替)。采用中断模式编程,当开关接高电平时,LED亮灯;接低电平时,LED灭灯。
- 采用串口中断方式完成串口通信
- STM32采用串口DMA方式,用115200bps或更高速率向上位机连续发送数据
一. STM32之中断
1. 何为中断
- 中断是当CPU在处理某一事件A时,发生了另一事件B,请求CPU迅速去处理,CPU暂停当前的工作,转去处理事件B,当CPU将事件B处理完毕后,再回到事件A中被暂停的地方继续处理事件A
- 中断是由内核外部产生的,一般由硬件引起,比如外设中断和外部中断等;
异常通常是内核自身产生的,大多是软件引起的,比如除法出错异常、预取
值失败等 - 不同优先级中断的处理原则是:高级中断可以打断低级中断;低级中断不能打断高级中断
2. 实例(1)——CubeMX中断点灯
打开STM32CubeMX,File-->New Project
建立新工程,选择芯片STM32F103C8
(1)配置调试模式
- 配置RCC使用外部时钟源
- 点击
SYS
选择Serial Wire
(2)外设配置
-
点击GPIO,设置LED引脚
PA5
,设置引脚模式为输出模式GPIO_Output
-
设置按键引脚
PB5
,设置引脚为外部中断功能,PB5与外部中断线EXIT5连接GPIO_EXIT5
-
对于LED对应的PA5管脚,默认设置即可
-
对于开关对应管脚PB5,选择
pull down
,设置其触发方式为上升沿触发
-
使能对应的外部中断线,在
NVIC
下点击Enabled
(3)时钟配置
- 进入
Clock Configuration
界面,修改如下参数
(4)工程管理
- 进入
Project Manager
界面,是工程的各种配置
- 点击
GENERATE CODE
创建工程,选择Open Folder
成功打开了工程文件
(5)添加代码并编译
- 在文件中打开
LED2.uvprojx
- 在
main.c
文件的图示位置添加中断代码
代码:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
for(long i = 1;i<72000;i++){}; //消除抖动
if(HAL_GPIO_ReadPin(KEY_GPIO_Port,KEY_Pin)==1)
{
HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
}
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
}
- 生成
.hex
烧录文件
- 进行编译,没有错误
(6)电路连接并烧录
-
硬件连接
LED短脚接地,长脚接PA5,按键一端接PB5,另一端当作开关,来回接3.3V
-
电路连接好后,打开FlyMcu进行烧录
-
运行结果如下
用杜邦线当作开关控制灯的亮灭
成功!
3. 实例(2)——中断方式串口通信
(1)生成工程文件
配置调试模式、时钟配置与上面相同,下面只列举不同之处
- 设置串口
点击USART1
,设置MODE为异步通信
- 使能中断
完成上述步骤后,即可生成工程文件
(2)添加中断代码
- 打开前面创建的工程文件夹,打开
Seial Communication.uvprojx
- 在
main.c
文件的图示位置添加存放数据的数组
uint8_t a[]="Hello world!\n";
- 添加回转函数
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
HAL_UART_Transmit_IT(&huart1, a, sizeof(a));
}
- 在主函数中添加中断调用
HAL_UART_Transmit_IT(&huart1, a, sizeof(a));
生成.hex
文件后进行编译,没有错误,进行下一步程序烧录
(3)程序烧录
- 电路连接好后,打开FlyMcu进行烧录
注意烧录是boot0接1
(4)串口通信
- 打开串口调试助手,将波特率调整到115200,
打开串口
进行通信,boot0接0
成功接受到Hello world! - 串口每隔0.5s输出Hello world,当下方发送数据,例如Hey Man!,串口进入中断,发送Hey Man!,之后回到原循环,继续发送Hello world!
二. STM32之DMA通信
1. 何为DMA通信
DMA(直接存储器访问):用于在外设与存储器之间以及存储器与存储器之间进行高速数据传输。DMA传输过程的初始化和启动由CPU完成,传输过程由DMA控制器来执行,无需CPU参与,从而节省CPU资源,提高利用率
例如:希望外设A的数据拷贝到外设B,只要给两种外设提供一条数据通路,直接让数据由A拷贝到B不经过CPU的处理
- DMA传输方式:外设到内存、内存到外设、内存到内存、外设到外设
- DMA数据传输的四要素
名称 | 含义 |
---|---|
传输源 | DMA数据传输的来源 |
传输目标 | DMA数据传输的目的 |
传输数量 | DMA传输数据的数量 |
触发信号 | 启动一次DMA数据传输的动作 |
- DMA控制器特点
- STM32F411微控制器具备两个DMA控制器:DMA1和DMA2,每个
控制器有8个数据流,每个数据流可以映射到8个通道(或请求); - 每一个DMA控制器用于管理一个或多个外设的存储器访问请求,并通
过总线仲裁器来协调各个DMA请求的优先级; - 数据流(stream)是用于连接传输源和传输目标的数据通路,每个数
据流可以配置为不同的传输源和传输目标,这些传输源和传输目标称为
通道(Channel); - 具备16字节的FIFO。使能FIFO功能后,源数据先送入FIFO,达到FIFO
的触发阈值后,再传送到目标地址。
- DMA工作框图
我们可以看到STM32内核,存储器,外设及DMA的连接,这些硬件最终通过各种各样的线连接到总线矩阵中,硬件结构之间的数据转移都经过总线矩阵的协调,使各个外设和谐的使用总线来传输数据
2. DMA方式的接口函数
3. 实例——DMA串口通信
(1)工程设置
- 创建工程,选择芯片型号STM32F103C8
- 配置RCC使用外部时钟源
- 设置串口
- 点击
USATR1
- 设置MODE为异步通信(Asynchronous)
- 基础参数:波特率为115200 Bits/s。传输数据长度为8 Bit。奇偶检验无,停止位1 接收和发送都使能
- GPIO引脚自动设置
USART1_RX/USART_TX
- 使能中断
- DMA设置
点击DMA Settings
的Add
添加通道,传输速率设置为中速Medium
- 模式设置为
Normal
,右侧选择Memory
- 在
System view
下选择DMA
(2)时钟设置
(3)工程管理
- 设置工程名和IDE的版本,然后点击
GENERATE CODE
创建工程,选择Open Folder
- 成功打开了工程文件
(4)添加代码并编译
- 在文件中打开
DMA.uvprojx
- 在
main.c
文件的图示位置添加代码
uint8_t Senbuff[] = "Hello world!"; //定义数据发送数组
HAL_UART_Transmit_DMA(&huart1, (uint8_t *)Senbuff, sizeof(Senbuff));
HAL_Delay(1000);
- 生成.hex文件
- 进行编译,没有错误,进行下一步程序烧录
(5)程序烧录
- 电路连接好后,打开FlyMcu进行烧录
(6)串口发送数据
- 打开串口调试助手
boot0接0
打开串口即可接收信号
三. 总结
本文主要讲解STM32中断的相关知识、DMA通信原理和编程方法,中断方式让快速的CPU和慢速的外设可以各做各的事情,大大提高了效率;DMA传输过程由DMA控制器来执行,无需CPU参与,从而节省CPU资源,提高利用率。通过实际操作点灯与串口通信,加深了我对中断以及串口通信的理解。