STM32 CUbeIDE 定时器中断使用
STM32 CUbeIDE 定时器中断使用
使用STM32F103RC定时器产生中断,在中断函数里面控制LED灯翻转,标志中断产生。
1、定时器简介
STM32的定时器功能十分强大,有 TIME1和 TIME8等高级定时器,也有 TIME2~TIME5等通用定时器,还有 TIME6和TIME7等基本定时器。
STM3的通用 TIMx (TIM2、 TIM3、 TIM4和 TIM5)定时器功能包括:
1)16位向上、向下、向上 /向下自动装载计数器( TIMx_CNT)。
2)16位可编程 (可以实时修改 )预分频器 (TIMx_PSC),计数器时钟频率的分频系数为 1~65535之间的任意数值。
3) 4个独立通道( TIMx_CH1~4),这些通道可以用来作为
A.输入捕获
B.输出比较
C PWM生成 (边缘或中间对齐模式 )
D.单脉冲模式输出
4)可使用外部信号 TIMx_ETR)控制定时器和定时器互连(可以用 1个定时器控制另外一个定时器)的同步电路。
5)如下事件发生时产生中断 /DMA
A.更新:计数器向上溢出 /向下溢出,计数器初始化 (通过软件或者内部 /外部触发 )
B.触发事件 (计数器启动、停止、初始化或者由内部 /外部触发计数 )
C.输入捕获
D.输出比较
E.支持针对定位的增量 (正交 )编码器和霍尔传感器电路
F.触发输入作为外部时钟或者按周期的电流管理
2、定时时间的计算
我们可以在STM32 定时器初始化函数里面看到,TIM1使用的时钟为 APB2的时钟,因此, TIM1的时钟为 72M。
定时计算:
Tout= ((Counter+1)*(Prescaler+1))/Tclk
Tclk = 72M
Tclk :TIM1的 输入时钟频率 (单位为 Mhz)。
Tout :TIM1溢出时间(单位为 us)。
Prescaler:分频系数。
Counter :自动重装值。
3、定时中断使用
3.1、创建工程
开始创建工程选择芯片我自己使用STM32F103RC 可以根据自己需要,选择对应的芯片。
开启调试下载
开启外部高速晶振
开启LED灯端口,LED灯端口,大家根据自己开发板原理图去选择,我自己的PA8。
开启定时器1,定时器和定时器中断,定时器自己可以随意选择,基本都是一样的操作。
根据我前面说的,设定的定时时间为1s。
3.2、 字符编码改变
如果不改变字符编码,就会出现汉字中文乱码。防止乱码出现,自己提前改一下,改为GBK,如果没有GBK自己手动输入。
想要代码分开在不同的文件夹里面,勾选这一项,提高代码的可读性。
3.3 、生成代码 编写函数
对于定时器中断,HAL库同样为我们封装了处理过程。首先,中断服务函数是不变的,定时器1的中断服务函数为:
TIM1_UP_IRQHandler();
一般情况下我们是在中断服务函数内部编写中断控制逻辑。但是HAL库为我们定义了 新的定时器中断共用处理函数 HAL_TIM_IRQHandler,在每个定时器的中断服务函数内部,我们
会调用该函数。该函数声明如下:
void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim);
而函数HAL_TIM_IRQHandler内部,会对相应的中断标志位进行详细判断,判断确定中断来源后,会自动清掉该中断标志位,同时调用不同类型中断的回调函数。所以我们的中断控制逻辑只用编写在中断回调函数中,并且中断回调函数中不需要清中断标志位。比如定时器更新中断回调函数为:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
HAL 库常用的中断回调函数;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);//更新中断
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim);//输出比较
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim);//输入捕获
void HAL_TIM_TriggerCallback(TIM_HandleTypeDef *htim);//触发中断
首先要开启定时器:
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT((TIM_HandleTypeDef *)&htim1);//定时器开启
/* USER CODE END 2 */
编写中断回调函数:
/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM1)
{
HAL_GPIO_TogglePin((GPIO_TypeDef *)GPIOA, (uint16_t) GPIO_PIN_8);//电平翻转
}
}
/* USER CODE END 4 */
定时器中断的使用就是如此的简单,现在就可以编译烧录代码了。