Crotex-M4基本定时器
定时器概述
STM32的定时器
STM32中的定时器曾在系统滴答定时器提到过,有内核级定时器系统滴答定时器、基本定时器、通用定时器、高级定时器。
而单片机中对应得定时器如下:
基本定时器:TIM6/7
通用定时器:TIM2~5 ,TIM9~14
高级定时器:TIM1/TIM8
Ps: 有些芯片是没有那么多定时器的、部分没有基本定时器
基本定时器介绍
基本定时器主要用于做定时、延时功能,还能触发D/A转换,其TIM6/TIM7包含一个16位自动重载计数器,该计数器由可编程预分频器驱动。此类定时器不仅可用作通用定时器以生成时基(提供时钟源),还可以专门用于驱动数模转换器(DAC),本章中不做讲解。实际上,此类定时器内部连接到DAC并能够通过其触发输出驱动DAC。
Ps: 这些定时器彼此独立,不共享任何资源,它们都有属于它们自己得寄存器。
基本定时器特征
- 16位的重装载值
- 计数方向:递增
- 预分频器:16位,支持的分频系数1~ 65536之间,分频系数不能为0,故在0~65535的范围上加1,寄存器中写0代表1分频,以此类推。
基本定时器框架
在这里可以注意到,自动重载寄存器和预分频器的下方有阴影部分,这肯定不是为了画图好看而设计的,而是ARR寄存器与PSC寄存器的影子寄存器,它们看不见摸不着、工程师不能进行操作、但是真正起作用的就是影子寄存器、上层寄存器的值加载给影子寄存器。
Ps:
1.PSC预分频器一定有影子寄存器,ARR重载寄存器可有可无(程序员自行选择)。
2.有影子寄存器写入的信值会在下次更新(计数器上溢、下溢等)事件产生值得更新。
3.无影子寄存器写入的新值会立马更新。
下面通过相应的时序图来理解影子寄存器的作用
基本定时器预装载过程分析
预分频器
在这里可以看出,当计数器寄存器当前计数还未完成时,预分频器控制寄存器更改分频,但是,计数器并未立即更改计数周期,基准时钟也未变化,当当前计数完成后,基准时钟变化为原来的二分之一,并且计数器计一个数的时间变为原来的两倍,然而下方影子寄存器的变化却刚好对应计数器和基准时钟的变化,即说真正起作用的就是影子寄存器
自动重载寄存器
通过以上两图可以对比当有无影子寄存器时,寄存器相应的变化。
当自动重载预装载寄存器写入新值时,无影子寄存器的计数器寄存器会从当前计数值递增到写入的新值的重载值,而有影子寄存器的计数寄存器会将上次重载值计数完成后才会产生值得更新。
因为我所使用得STM32F401单片机并无基本定时器,而通用定时器具有基本定时器得所有功能,所以本案例用通用定时器TIM5来代替。
配置流程:
- 打开时钟(TIM5) 84MHz
- 更新禁止
- 更新请求源
- 单脉冲
- 无缓冲区
- 中断使能
- 配置时基单元(CNT ARR PSC)
- 优先级
- 使能
- 中断服务函数
- 延时函数
/*
函 数 名:Time5_Config
函数功能:基本定时器初始化(利用TIM5)
返 回 值:无
形 参:u32 psc,u32 arr -- psc分频比 -- arr重装载值
备 注:
401单片机中无基本定时器,用通用定时器代替
84MHz -- 84分频 1us -- 重装载值1000 -- 1ms
*/
void Time5_Config(u32 psc,u32 arr)
{
RCC->APB1ENR |= (1<<3); //打开TIME5时钟
TIM5->CR1 &= ~(1<<1); //使能UVE(取消更新禁止)
TIM5->CR1 &= ~(1<<2); //选择更新请求源
TIM5->CR1 &= ~(1<<3); //禁止单脉冲模式
TIM5->CR1 &= ~(1<<4); //计数器计数方向递增
TIM5->CR1 &= ~(1<<7); //ARR寄存器无缓冲(无影子寄存器)
TIM5->DIER |= (1<<0); //更新中断使能
TIM5->CNT = 0; //计数器清零
TIM5->PSC = psc-1; //预分频器 84分频
TIM5->ARR = arr-1; //重装载值1000
NVIC_SetPriority(TIM5_IRQn,NVIC_EncodePriority(7-5,1,2)); //设置优先级
NVIC_EnableIRQ(TIM5_IRQn); //使能优先级响应
TIM5->CR1 |= (1<<0); //使能计数器
}
/*
函 数 名:TIM5_IRQHandler
函数功能:TIM5定时器中断服务函数
返 回 值:无
形 参:无
备 注:
*/
u32 ptime;
void TIM5_IRQHandler(void)
{
if(TIM5->SR & (1<<0))
{
TIM5->SR &= ~(1<<0);
ptime--;
}
}
/*
函 数 名:TIM5_Delay_ms
函数功能:TIM5延时函数
返 回 值:无
形 参:无
备 注:
*/
void TIM5_Delay_ms(u32 mtime)
{
ptime = mtime;
while(ptime>0);
}