文章目录
一、基本定时器简介
STM32F4xx 系列的基本定时器 TIM6 和 TIM7 包含一个 16 位自动重载计数器,该计数器由可编程预分频器驱动。此类定时器不仅可用作通用定时器以生成时基, 还可以专门用于驱动数模转换器 (DAC)。实际上,此类定时器内部连接到 DAC 并能够通过其触发输出驱动 DAC。这些定时器彼此完全独立,不共享任何资源。(来自中文参考手册)
总结:
基本定时器功能:
①延时、计数
②触发DAC转换
③计数方向:递增计数
二、基本定时器数量
从芯片数据手册可知,STM32F407VET6有两个基本定时器,分别是TIM6 和 TIM7。注意:并不是每一款芯片都会有基本定时器,如需确定所使用的芯片是否有基本定时器的话,需要查看数据手册参数表,比如M3芯片就没有基本定时器。
三、基本定时器框图
3.1基本定时器频率
由数据手册可知,TIM6和TIM7挂靠在频率为42Mhz的APB1总线上。
注意:TIM6和TIM7并不是42Mhz频率,要确定TIM6和TIM7频率需要利用时钟树(中文参考手册 RCC章节)
当APBx总线分频为1时,定时器频率为APBx频率1
当APBx总线分频不为1时,定时器频率为APBx频率2
众所周知,APBx总线频率是由AHB1总线频率分频来的,而AHB1频率:168Mhz, APB1频率:42Mhz,APB2频率:84Mhz,所以APB1和ABP2一定进行了分频。如APB1和ABP2进行了分频的话,所挂靠在这两根总线上的定时器的频率 = 挂靠总线频率 * 2。
所以,TIM6定时器频率为42 * 2 = 84Mhz
3.2 基本定时器寄存器
TIM6 和 TIM7 控制寄存器 1 (TIMx_CR1)
TIM6 和 TIM7 控制寄存器 2 (TIMx_CR2)
不需要配置
TIM6 和 TIM7 DMA/中断使能寄存器 (TIMx_DIER)
位 0 UIE:更新中断使能 (Update interrupt enable)
0:禁止更新中断。
1:使能更新中断。
TIM6 和 TIM7 状态寄存器 (TIMx_SR)
标志位
位 0 UIF:更新中断标志 (Update interrupt flag)
该位在发生更新事件时通过硬件置 1。但需要通过软件清零。
0:未发生更新。
1:更新中断挂起。该位在以下情况下更新寄存器时由硬件置 1:
— 上溢或下溢并且当 TIMx_CR1 寄存器中 UDIS = 0 时。
— 当由于 TIMx_CR1 寄存器中 URS = 0 且 UDIS = 0 而通过软件使用 TIMx_EGR 寄存器中的 UG 位重新初始化 CNT 时。
TIM6 和 TIM7 事件生成寄存器 (TIMx_EGR)
位 0 UG:更新生成 (Update generation)
该位可通过软件置 1,并由硬件自动清零。
0:不执行任何操作。
1:重新初始化定时器计数器并生成寄存器更新事件。请注意,预分频器计数器也将清零(但预分频比不受影响)
在初始化设置重装载值需要将UG位置一,加载重装载值到计数器
TIM6 和 TIM7 计数器 (TIMx_CNT)
设置初始计数值(注意:设置初始计数值只有在第一个周期有效)
TIM6 和 TIM7 预分频器 (TIMx_PSC)
设置预分频数:可设置范围 0 - 65535
TIM6 和 TIM7 自动重载寄存器 (TIMx_ARR)
设置重装载值:可设置范围0 - 65535
四、基本定时器使用
4.1实现TIM6的微秒级延时
void TIM6_Delay_ms(u16 nms)
{
//打开TIM6时钟
RCC->APB1ENR |= 1 << 4;
//初始化TIM6
TIM6->CR1 |= 1 << 7; //使能ARR寄存器影子寄存器的缓冲模式
TIM6->CR1 |= 1 << 3; //使能单脉冲模式
TIM6->CR1 &=~ (1 << 2); //更新请求源清零
TIM6->CR1 &=~ (1 << 1); //USDI清零,使能更新
//设置定时器时基单元
TIM6->PSC = 8400 - 1; //设置PSC
TIM6->ARR = nms * 10 - 1; //设置ARR
TIM6->EGR |= 1 << 0; //UG位置1,产生更新事件
TIM6->SR &=~ (1 << 0); //清除更新标志位
//定时器使能
TIM6->CR1 |= (1 << 0);
//等待更新标志位置1
while(!(TIM6->SR & (1 << 0)));
}
主函数里我用了灯闪烁的例子
LED1_ON;
TIM6_Delay_ms(500);
LED1_OFF;
TIM6_Delay_ms(500);
4.2实现每500毫秒打印1,1000毫秒打印2
/*
函数功能:TIM7 1毫秒中断初始化
返回值:void
形参:u16 nms
函数说明:
*/
void TIM7_Interrupt(u16 nms)
{
//打开TIM7时钟
RCC->APB1ENR |= 1 << 5;
//初始化TIM7
TIM7->CR1 |= 1 << 7; //使能ARR寄存器影子寄存器的缓冲模式
TIM7->CR1 &=~ (1 << 3) ; //使能连续模式
TIM7->CR1 &=~ (1 << 2); //更新请求源清零
TIM7->CR1 &=~ (1 << 1); //USDI清零,使能更新
//设置定时器时基单元
TIM7->PSC = 8400 - 1; //设置PSC
TIM7->ARR = nms * 10 - 1; //设置ARR
TIM7->EGR |= 1 << 0; //UG位置1,产生更新事件
TIM7->SR &=~ (1 << 0); //清除更新标志位
//使能TIM7更新中断
TIM7->DIER |= 1 << 0;
//配置NVIC
u32 pri = NVIC_EncodePriority(5, 3, 3);
//设置优先级
NVIC_SetPriority(TIM7_IRQn, pri);
//使能中断源
NVIC_EnableIRQ(TIM7_IRQn);
//定时器使能
TIM7->CR1 |= (1 << 0);
}
//TIM7中断服务函数
void TIM7_IRQHandler(void)
{
//清除标志位
TIM7->SR &=~ (1 << 0);
//1毫秒执行一次下面代码
tim7_flag = 1;
}
主函数代码如下:
u16 time_cnt[5] = {0};
while(1)
{
if(tim7_flag == 1)
{
tim7_flag = 0;
time_cnt[0]++;
time_cnt[1]++;
if(time_cnt[0] == 500)
{
time_cnt[0] = 0;
printf("1\r\n");
}
if(time_cnt[1] == 1000)
{
time_cnt[1] = 0;
printf("2\r\n");
}
}
}