前言
本文记录下我学习STM32CubeMX时的流程,方便以后回忆。系统板是基于STM32F103C6T6。本章记录定时器事件,中断轮询模式的配置内容。
步骤
实验目标:利用定时器TIM2装载计数,1S的定时中断事件,事件是LED(PC13)的亮灭。
中断模式
在中断模式下,当定时器事件发生时,CPU会暂停当前正在执行的任务,转而去执行预先定义好的中断服务程序(ISR)。一旦中断服务程序执行完毕,程序会回到中断发生前的状态继续执行。
-
配置时钟源为外部高速源(HSE),流程省略,配置LED(PC13)为输出管脚省略,工程文件输出keil工程配置省略。
-
配置TIM2中断。
-
修改时钟主频,不同的定时器,在的桥接(APBx)不一样。APB2:TIM1,TIM8 APB1:除了1,8其余的都在。
-
配置TIM2,主要配置时钟源,和分频系数之类的
-
使能NVCI TIM2,完成后生成代码。
-
-
在keil中打开工程。所用到关键函数,原型可在右击函数后,跳转声明查看。
// 启动TIM2(非阻塞模式:中断) HAL_TIM_Base_Start_IT(&htim2); // 重写定时中断函数 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { // 判断信号是否来自TIM2 if(htim->Instance==TIM2) { // LED(PC13)端口反转 HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13); } }
轮询模式
在轮询模式下,程序不断地检查定时器的状态,看是否到达了预定的时间点或事件。这意味着程序需要不断查询定时器的状态寄存器来确定是否发生了事件。
// 启动TIM2(阻塞方式:轮询)
HAL_TIM_Base_Start(&htim2);
// 轮询判断以及清除(触发后若不清除中断标志,下次轮询到会直接进入)
if (__HAL_TIM_GET_FLAG(&htim2, TIM_FLAG_UPDATE) != RESET)
{
// ...功能代码
// 清除中断标志
__HAL_TIM_CLEAR_FLAG(&htim2, TIM_FLAG_UPDATE);
}
轮询模式/中断模式
轮询模式
优点
- 简单:实现相对简单,不需要复杂的中断配置。
- 实时性控制:可以在主循环中直接控制程序的执行流程,对于简单的实时控制任务来说比较方便。
缺点
-
效率低:需要频繁地查询状态,这会导致CPU资源的浪费。
-
阻塞程序:在等待事件发生时,程序会被阻塞,无法执行其他任务。
-
不适合多任务:不利于实现多任务调度,因为程序需要不断查询状态。
中断模式
优点
- 高效:不需要频繁查询定时器状态,提高了CPU的利用率。
- 非阻塞:程序不会被阻塞,可以执行其他任务。
- 适合多任务:适用于多任务操作系统,可以更好地管理多个任务和中断。
缺点
- 配置复杂:需要配置中断向量、中断优先级等,相对于轮询模式来说更加复杂。
- 中断上下文切换开销:每次中断发生时都需要保存和恢复CPU寄存器状态,这会产生一定的开销。
总结
上文用到,基础定时器的相关函数以及单词解析:
HAL
HAL库,TIM
定时器外设,Base
基础的用法,Start
开启(控制状态),IT
中断模式,没有则默认轮询模式。
/* 阻塞方式:轮询 */
HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_HandleTypeDef *htim);
HAL_StatusTypeDef HAL_TIM_Base_Stop(TIM_HandleTypeDef *htim);
/* 非阻塞模式:中断 */
HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim);
HAL_StatusTypeDef HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim);
导出宏。GET
获取或SET
设置参数。通常在于控制TIM_HandleTypeDef
结构内以及子结构的参数配置。
__HAL_TIM_GET_FLAG(__HANDLE__, __FLAG__); // 检查指定的TIM中断标志是否设置。
__HAL_TIM_CLEAR_FLAG(__HANDLE__, __FLAG__); // 清除指定的TIM中断标志。
__HAL_TIM_GET_COUNTER(__HANDLE__); // 在运行时获取TIM计数器寄存器值。
__HAL_TIM_SET_COUNTER(__HANDLE__, __COUNTER__); // 在运行时设置TIM计数器寄存器值。