目录
【定时器工作原理】

【定时器分类】

【通用定时器介绍】
【基本定时器框图】
【定时中断基本结构】
【定时器计数模式】
【定时器时钟源】
【定时器溢出时间计算公式】
T_out = (ARR+1) * (PSC+1) / T_clk
Tout: 定时器溢出时间
PSC: 预分频寄存器的值,预分频系数=PSC+1
ARR: 自动重装载寄存器的值,自动重装载值=ARR+1
Tclk: 即Ft,定时器时钟源频率,经APB1预分频器后提供,APB1总线最大工作频率为36MHz。若APB1 预分频系数为1,则Tclk不变(为PCLK1的频率)。若APB1 预分频系数为2,则Tclk等于PCLK1的频率×2
CNT: 计数器,CNT是16位计数器,仅向上计数,最大计数值为65535。当计数值达到自动重装载寄存器设定值时产生更新事件,并清零从头开始计数
计数频率:Ft / (PSC+1)
计数器周期:计数器完成一次计数所需的时间,(PSC+1) / Ft
定时器的定时时间:计数器的中断周期 × 中断的次数
定时器溢出时间:Tout = (ARR+1) * (PSC+1) / Ft
要定时1ms ,则:PSC=7199,ARR= 0 ,Tclk=72MHz
参考:第3讲 定时器寄存器 溢出时间计算方法_哔哩哔哩_bilibili
【外部中断调用流程】
① stm32f1xx_it.c中的 TIMX_IRQHandler(void)
② stm32f1xx_hal_tim.c中的 HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)
③ 自己找位置重写的 HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
...........................................................................................................................................................
【demo · Timer_LED】
功能:每0.5s点亮 / 熄灭LED
/* Timer2.c */
#include "Timer2.h"
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM2)
HAL_GPIO_TogglePin (GPIOC,GPIO_PIN_13);
}
/* main.c */
HAL_TIM_Base_Start_IT(&htim2); // 添加启动定时器代码
/* 其余代码为初始化生成代码 */
demo现象:每0.5s点亮 / 熄灭LED
【demo · Timer_HC-SR04】
HC-SR04用法:
实现功能:当超声波传感器前方5cm以内有障碍物遮挡时,LED点亮,否则LED熄灭
接线:
微秒级函数:我
void TIM2_Dealy_us(uint16_t n_us)
{
__HAL_TIM_ENABLE(&htim2);
__HAL_TIM_SetCounter(&htim2,0);
while(__HAL_TIM_GetCounter(&htim2) < ((1 * n_us)-1));
__HAL_TIM_DISABLE(&htim2);
}
超声波测距函数:
double get_distnce()
{
int cnt = 0; // 存放定时器计次次数
// 1.给Trig端口20us(至少10us)高电平
HAL_GPIO_WritePin(Trig_GPIO_Port,Trig_Pin,GPIO_PIN_SET);
TIM2_Dealy_us(20);
HAL_GPIO_WritePin(Trig_GPIO_Port,Trig_Pin,GPIO_PIN_RESET);
// 2.波发出去时启动定时器
while(HAL_GPIO_ReadPin(Echo_GPIO_Port,Echo_Pin)==GPIO_PIN_RESET);
HAL_TIM_Base_Start(&htim2);
__HAL_TIM_SetCounter(&htim2,0); // 将Timer2的值重置为指定值0
// 3.由高电平到低电平表示波已返回,关闭定时器
while(HAL_GPIO_ReadPin(Echo_GPIO_Port,Echo_Pin)==GPIO_PIN_SET);
HAL_TIM_Base_Stop(&htim2);
cnt = __HAL_TIM_GetCounter(&htim2); // 获取Timer2当前计数值
// 4.计算时间和距离
// cnt为计数次数,1次1us,cnt次即cntus,×0.000001转换为s,×340÷2得到距离,单位为m,×100转换为cm
return (cnt*340/2*0.000001*100); // 单位为cm
}
主函数:
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM2_Init();
while (1)
{
float dis = 0; // 存放测距距离
dis = get_distnce();
if(dis < 5) // 距离小于5cm亮灯
HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_RESET);
else
HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_SET);
HAL_Delay(500); // 0.5s测量一次
}
}
【小试牛刀:感应开关垃圾桶】
项目功能:
① 有人靠近时,垃圾桶自动开盖并伴随滴一声,2秒后关盖
② 发生震动时,垃圾桶自动开盖并伴随滴一声,2秒后关盖
③ 按下按键时,垃圾桶自动开盖并伴随滴一声,2秒后关盖
项目框图:
参考:
STM32 HAL库 STM32CubeMX -- TIM(定时器中断)_stm32cubemx tim_Dir_xr的博客-优快云博客