STM32通用定时器(TIM2-TIM5)是一个可编程预分频器驱动的16位自动装载计数器构成。它能测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM)
使用定时器预分频器和RCC时钟控制器预分频器,脉冲长度和波形周期可以从几个us到几个ms之间调整。
每个定时器都是完全独立的,没有互相共享任何资源。
使用定时器需要配置控制寄存器(TIMx_CRx)、DMA/中断使能寄存器(TIMx_DIER)、预分频寄存器(TIMx
_PSC)、重装载寄存器(TIMx_ARR)四个寄存器:
控制寄存器(TIMx_CRx),低10位有效。
DMA/中断使能寄存器(TIMx_DIER),这是一个16位的寄存器,我们需要使用的是第6位和第0位。第6位TIE为出发中断使能位,通过将该位置1,使能TIMx的中断触发,注意:只要是TIMx需要使用中断,该位必须为1。而第0位,是与徐更新中断位,通过置1,来允许由于更新事件而产生的中断。
预分频寄存器(TIMx_PSC),改寄存器用来设置对时钟进行分频,然后提供给计数器,作为计数器的时钟。而时钟来源是:
1)内部时钟(CK_INT);
2)外部时钟模式1:外部输出脚(TIx);
3)外部时钟模式2:外部触发输入(ETR);
4内部触发输出(ITRx):使用A定时器作为B定时器的预分频器(A为B提供时钟)。
重装载寄存器(TIMx_ARR),该寄存器在物理上实际对应着2个寄存器,一个是程序员可以直接操作的寄存器,另一个是不能直接操作的影子寄存器。
使用通用定时器,需要进行以下几个步骤的设置:
1)TIMx时钟使能;
2)设置TIMx_ARR和TIMx_PSC的值(通过这两个寄存器,设置自动重装载的值,以及分频系数。这两个参数加上时钟分频就决定了定时器的溢出时间);
3)设置TIMx_DIER允许更新中断(使用TIMx的更新中断,要设置DIER的UIE位,并使能触发中断);
4)允许TIMx工作(通过TIMx_CRx的CEN位来设置,开启定时器);
5)TIMx中断分组设置(设置NVIC相关寄存器,使能TIMx中断);
6)编写中断服务参数。
现在分享一下程序大家一起参考:
/*==================================================================
* Function : Timerx_Init
* Description : Init MSTimer
* Input Para : arr: autio reload value.
* psc: time prescaler
* Output Para : void
* Return Value: void
* Author: penny
* Date: 2013/06/21
==================================================================*/
void Timerx_Init(u16 arr, u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 5000; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000为500ms
TIM_TimeBaseStructure.TIM_Prescaler = (7200-1); //设置用来作为TIMx时钟频率除数的预分频值 10Khz的计数频率
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStructure中指定的参数初始化TIMx的时间基数单位
TIM_ITConfig(TIM3, TIM_IT_Update|TIM_IT_Trigger, ENABLE); //使能触发中断
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //中断分组
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init( &NVIC_InitStructure);
TIM_Cmd(TIM3, ENABLE); //使能定时器
}
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) !=RESET )
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
LED1 = !LED1;
}
}
文章评论(0条评论)
登录后参与讨论