代码仓库 -【传送门】
之前认识了GPIO的输入输出功能,现在学习一下定时器的功能,相比于输入捕获与输出比较,还是用作延时来的简单一些。
查看数据手册,TIM2是挂载在APB1总线上,最大频率为50MHz,这个数据之后要用到。

1,新建delay.c与delay.h文件,把delay.c加入外设组中。
2,初始化定时器配置。可以理解为在不分频的情况下,就是50MHz,数一个数需要1/50Mhz=20ns,数50个数就需要1us。
void Delay_TIMx_Init(void)
{
// 1. 使能定时器2时钟
RCC_APB1PeriphClockCmd(DELAY_TIMx_CLK, ENABLE);
// 2. 配置定时器2
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 50 -1; // 自动重装载寄存器值,APB1的最大频率就是50MHz
TIM_TimeBaseStructure.TIM_Prescaler = 0; // 不分频
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 时钟分频因子
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
TIM_TimeBaseInit(DELAY_TIMx, &TIM_TimeBaseStructure);
}
3,微秒延时函数与毫秒延时函数实现
void delay_us(uint32_t us)
{
TIM_Cmd(DELAY_TIMx, ENABLE);
for (uint32_t i = 0; i < us; i++)
{
TIM_SetCounter(DELAY_TIMx, 0); // 清零计数器
while (TIM_GetFlagStatus(DELAY_TIMx, TIM_FLAG_Update) == RESET); // 等待更新事件(等待计数值到达装载值)
TIM_ClearFlag(DELAY_TIMx, TIM_FLAG_Update); // 清除更新事件标志
}
TIM_Cmd(DELAY_TIMx, DISABLE);
}
void delay_ms(uint32_t ms)
{
for (uint32_t i = 0; i < ms; i++)
{
delay_us(1000); // 1ms = 1000us
}
}
之后可以替代滴答定时器了。
while (1)
{
key_event = KEY_User_Scan();
if(key_event == KEY_EVENT_SHORT_PRESS)
LED_Toggle();
else if(key_event == KEY_EVENT_LONG_PRESS)
{
for(int i = 0; i<5;i++)
{
LED_Toggle();
delay_ms(500);
}
}
delay_ms(10);
}