热度 14
2013-7-3 16:01
1035 次阅读|
0 个评论
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; } }