一.TIMER stm32框图
如图:
1为时钟源
● 内部时钟(CK_INT)
● 外部时钟模式1:外部输入脚(TIx)
● 外部时钟模式2:外部触发输入(ETR)
● 内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如可以 配置一个定时器Timer1而作为另一个定时器Timer2的预分频器
本历程采用内部时钟源,也就是以下的path
此处需要注意一点:如果使用内部时钟,如果TIMER所在的总线是1分频,那么就是所在总线的时钟频率,如果不是1分频,那么时钟频率就是所在总线频率*2
如系统时钟为72M,TIMER2所在APB1为1分频,那么TIMER时钟频率为72M*1
如系统时钟为72M,TIMER2所在APB1为2分频,那么TIMER时钟频率为36M*2
虽然都为72M,但是计算方法也不同,对于频率系数比较大的就能看出差异,例如stm32 f407
2为时基单元
PSC预分频数,还有重装载值,计数器CNT是寄存器根据重装载值和方向进行递增递减
3为输入捕获,最基本的用途可以计算上升沿和下降沿的时间
4为输出,即PWM,可以自己输出波形,控制占空比
二.寄存器图
Timer的寄存器比较多,本历程只是实现最基本的定时功能,输入捕获,PWM暂时不做讨论
三.编程步骤
1. 使能TIMER时钟
2. 设置重装载值和分频系数
3. 计数器清零
4. 设置触发中断的方式
5. 使能TIMER
6. 使能TIMER NVIC中断
7. TIMER中断函数编写
四.程序解析
程序调用API
Time2_Enable(19999,7199);
调试如下
RCC->APB1ENR = RCC_APB1ENR_TIM2EN; // 72M clock
1.使能TIMER时钟,为72M,如图
TIM2->ARR= arr;
TIM2->PSC= psc;
2. 设置重装载值和分频系数,如图
TIM2->EGR = TIM_EGR_UG;
3.计数器清零
TIM2->CR1= TIM_CR1_URS;
TIM2->DIER= TIM_DIER_UIE;
4. 设置触发中断的方式
5.使能TIMER,如图:
NVIC_SetPriority(TIM2_IRQn,1);
NVIC_EnableIRQ(TIM2_IRQn);
6.使能TIMER中断
voidTIM2_IRQHandler(void)
{
TIM2->SR &= ~TIM_SR_UIF;
printf("timeout! CNDTR=%d\n",DMA1_Channel5->CNDTR);
}
7.编写TIMER中断函数
程序运行图
每2s产生一次中断
72M = 72000000HZ
分频7200
72000000/7200 = 10000
所以一个周期是 1/10000
然后出发中断时20000个周期,所以2s一次中断