1.基本定时器理论知识及实战
1.1定时器原理
1.2.基本定时器框图(TIME6、TIME7)
1)时钟源:基本定时器时钟挂载在 APB1 总线,先经过一个倍频器,挂载在 APB1 总线的定时器时钟频率为 84Mhz。
2)计数器:通过设置预分频器寄存器(TIMx_PSC)的值可以得到不同频率 CK_CNT,
计算公式如下:fCK_CNT= fCK_PSC / (PSC[15:0]+1)
3)更新事件的产生有两种情况:
一:由软件产生,将 TIMx_EGR 寄存器的位UG 置 1,产生更新事件后,硬件会自动将 UG 位清零。
二、二是由硬件产生每来一个 CK_CNT 脉冲,TIMx_CNT 的值就会递增加 1。当 TIMx_CNT 值
与 TIMx_ARR 的设定值相等时,TIMx_CNT 的值就会被自动清零并且会生成更新事件(如果
开启相应的功能,就会产生 DMA 请求、产生中断信号或者触发 DAC 同步电路)。
1.3.基本定时器TIM6/TIM7 寄存器
1)控制寄存器 1(TIMx_CR1)
位 0(CEN):用于使能或者禁止计数器
位 7(APRE)用于控制自动重载寄存器 ARR 是否具有缓冲作用,
2)DMA/中断使能寄存器(TIMx_DIER)
位 0(UIE)用于使能或者禁止更新中断,
位 8(UDE)用于使能或者禁止更新 DMA 请求
3)状态寄存器(TIMx_SR)
位 0(UIF)是中断更新的标志位,当发生中断时由硬件置 1,然后就会执行中断服务函数,需要软件去清零,所以我们必须在中断服务函数里把该位清零,防止中断一直发生。
4)计数器寄存器(TIMx_CNT)
寄存器位[15:0]就是计数器的实时的计数值。
5)预分频寄存器(TIMx_PSC)
例:要 8400 分频,就往该寄存器写入 8399。
1.4.递增计数模式实力(TIME6、TIME7)
1.5.定时器溢出时间计算方法
1.6.定时器中断实验配置步骤(掌握)
1,配置定时器基础工作参数 HAL_TIM_Base_Init()
2,定时器基础MSP初始化 HAL_TIM_Base_MspInit() 配置NVIC、CLOCK等
3,使能更新中断并启动计数器 HAL_TIM_Base_Start_IT()
4,设置优先级,使能中断 HAL_NVIC_SetPriority()、 HAL_NVIC_EnableIRQ()
5,编写中断服务函数 TIMx_IRQHandler()等 --> HAL_TIM_IRQHandler()
6,编写定时器更新中断回调函数 HAL_TIM_PeriodElapsedCallback()
2.基本定时器理编程实战
2.1 btm.c
#include "./BSP/LED/led.h"
#include "./BSP/TIMER/btim.h"
TIM_HandleTypeDef g_timx_handle; /* 定时器参数句柄*/
//1.配置定时器基本工作参数
void tim_base_init(uint16_t psc,uint16_t arr)
{
g_timx_handle.Instance = TIM6; //外设寄存器基地址
g_timx_handle.Init.Prescaler= psc; //预分频系数
g_timx_handle.Init.CounterMode=TIM_COUNTERMODE_UP; //递增计数模式
g_timx_handle.Init.Period=arr; //自动重载值ARR
HAL_TIM_Base_Init(&g_timx_handle); //初始化定时器基础参数
//3.使能更新中断并启动计数器
HAL_TIM_Base_Start_IT(&g_timx_handle);
}
//2,定时器底层驱动,开启时钟,设置中断优先级,此函数会被HAL_TIM_Base_Init()函数调用
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM6)
{
__HAL_RCC_TIM6_CLK_ENABLE(); /*TIM6时钟使能*/
//4.设置优先级、使能中断
HAL_NVIC_SetPriority(TIM6_DAC_IRQn,1,3);
HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
}
}
//5.编写中断服务函数
void TIM6_DAC_IRQHandler(TIM_HandleTypeDef *htim)
{
//调用中断公用处理函数
HAL_TIM_IRQHandler(&g_timx_handle);
}
//6.编写定时器溢出中断服务函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM6)
{
LED0_TOGGLE(); /*翻转LED0红灯*/
}
}
2.2 main.c
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/TIMER/btim.h"
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */
delay_init(168); /* 延时初始化 */
usart_init(115200); /* 串口初始化为115200 */
led_init(); /* 初始化LED */
tim_base_init(8400-1,5000-1); /* 84 000 000 /8400 =10 000, 为10khz的计数频率,计数5000k为500ms*/
while(1)
{
LED1_TOGGLE();
delay_ms(200);
}
}