在STM32单片机里,TIM定时器简单来说就是用来定时的设备,是STM32单片机的一个外设。STM32总共有8个定时器,分别是2个高级定时器(TIM1、TIM8),4个通用定时器(TIM2、TIM3、TIM4、TIM5)和2个基本定时器(TIM5、TIM6)。
下图为几种定时器的部分分类,在本实验中我们不做详细介绍,在介绍讲解笔记中我们再做介绍。
STM32计时器的输出时间由公式Tout=(Arr+1)*(PSC+1)/Ft计算。其中PSC是预分频系数,Arr是自动装载系数,Ft是对应的总线时钟频率,TIM的时钟频率是72MHz。
在本实验中,我们要求用TIM6实现500ms定时器更新中断,在中断中反转LED0。
接下来我们介绍实验代码。
我们先写头文件btim.h:
#ifndef __BTIM_H
#define __BTIM_H
#include "./SYSTEM/sys/sys.h"
#include "./BSP/LED/led.h"
extern TIM_HandleTypeDef g_timx_handle;
void btim_timx_init(uint16_t arr, uint16_t psc);
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim);
void TIM6_IRQHandler(void);
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
#endif
接下来再写函数文件btim.c:
#include "./BSP/BTIM/btim.h"
TIM_HandleTypeDef g_timx_handle;
void btim_timx_init(uint16_t arr, uint16_t psc){
g_timx_handle.Instance = TIM6;
g_timx_handle.Init.Prescaler = psc;
g_timx_handle.Init.Period = arr;
HAL_TIM_Base_Init(&g_timx_handle);
HAL_TIM_Base_Start_IT(&g_timx_handle);
}
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim){
if(htim->Instance == TIM6){
__HAL_RCC_TIM6_CLK_ENABLE();
HAL_NVIC_SetPriority(TIM6_IRQn, 1, 3);
HAL_NVIC_EnableIRQ(TIM6_IRQn);
}
}
void TIM6_IRQHandler(void){
HAL_TIM_IRQHandler(&g_timx_handle);
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if(htim->Instance == TIM6){
LED0_TOGGLE();
}
}
我们需要先编写计时器初始化文件,配置好我们的TIM6的GPIO口,接下来使用HAL_TIM_Base_Start_IT函数启动定时器并打开中断。再接下来我们编写初始化定时器的时基(Time Base)的回调函数HAL_TIM_Base_MspInit,并在其中设置中断优先级。最后写我们的callback回调函数。
最后再编写我们的主函数main.c:
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/BTIM/btim.h"
int main(void){
HAL_Init();
sys_stm32_clock_init(RCC_PLL_MUL9);
delay_init(72);
led_init();
btim_timx_init(5000-1,7200-1);
while(1){
delay_ms(500);
}
}
到这里我们的代码就编写完成了。