为了实现两个定时器完全同步,使用一个定时器作为另一个定时器的预分频器。可以配置定时器 1 作为定时器 3 的预分频器。
参考上图,进行下述操作:
配置定时器 1 为主模式,它可以在每一个更新事件 UEV 时输出一个周期性的触发信号。在TIM1_CR2寄存器的MMS = ‗010时,每当产生一个更新事件时在 TRGO1上输出一个上升沿信号。
连接定时器 1 的 TRGO1 输出至定时器 3,设置 TIM3_SMCR 寄存器的 TS = ‗000 ,配置定时器 3为使用 ITR1 作为内部触发的从模式。
然后把从模式控制器置于外部时钟模式 1(TIM3_SMCR 寄存器的 SMS = 111);这样定时器 3即可由定时器 1 周期性的上升沿(即定时器 1 的计数器溢出)信号驱动。
最后,必须设置相应(TIMx_CR1 寄存器)的 CEN 位分别启动两个定时器。
注:如果 OCx 已被选中为定时器 1 的触发输出(MMS = 1xx),它的上升沿用于驱动定时器 3 的计数器。
void Tim1_Init(u16 Prescaler,u16Period)
{
TIM_TimeBaseInitTypeDefTIM_StructInit;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
TIM_StructInit.TIM_Period=Period;
TIM_StructInit.TIM_Prescaler=Prescaler;
TIM_StructInit.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_StructInit.TIM_CounterMode=TIM_CounterMode_Up;
TIM_StructInit.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM1,&TIM_StructInit);
TIM_ClearFlag(TIM1,TIM_FLAG_Update);
}
void TIM3_Init(u16 psc,u16 arr)
{
TIM_TimeBaseInitTypeDefTIM_StructInit;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
TIM_StructInit.TIM_Period=arr;
TIM_StructInit.TIM_Prescaler=psc;
TIM_StructInit.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_StructInit.TIM_CounterMode=TIM_CounterMode_Up;
TIM_StructInit.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM3,&TIM_StructInit);
TIM_SelectOutputTrigger(TIM3,TIM_TRGOSource_Enable);
TIM_SelectInputTrigger(TIM1,TIM_TS_ITR2);
TIM_SelectSlaveMode(TIM1,TIM_SlaveMode_Gated);
TIM_SelectMasterSlaveMode(TIM1,TIM_MasterSlaveMode_Enable);
TIM3->CNT=0;
TIM1->CNT=0;
TIM_Cmd(TIM1, ENABLE);
delay_ms(300);
TIM_Cmd(TIM3, ENABLE);
delay_ms(300);
}
2、定时器精准延时
在应用中,有的需要精准的定时功能,在客户支持过程中,发现有的客户对定时器的基本定时功能的理解有些偏差,今天将与大家一起使用定时器的基本定时功能。
我们把定时器设置自动重装载寄存器 ARR 的值为1000,设置时钟预分频器为47,则驱动计数器的时钟: CK_CNT = CK_INT / (47+1)=1M,则计数器计数一次的时间等于:1/CK_CNT=1us,当计数器计数到 ARR 的值1000 时,产生一次中断,则中断一次的时间为:1/CK_CNT*ARR=1ms。
void Tim2_UPCount_test(void)
{
TIM_TimeBaseInitTypeDefTIM_StructInit;
NVIC_InitTypeDef NVIC_StructInit;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
TIM_StructInit.TIM_Period=1000;
TIM_StructInit.TIM_Prescaler=47;
TIM_StructInit.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_StructInit.TIM_CounterMode=TIM_CounterMode_Up;
TIM_StructInit.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM2,&TIM_StructInit);
NVIC_StructInit.NVIC_IRQChannel=TIM2_IRQn;
NVIC_StructInit.NVIC_IRQChannelPriority=1;
NVIC_StructInit.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_StructInit);
TIM_ClearFlag(TIM2,TIM_FLAG_Update);
TIM_ITConfig(TIM2, TIM_IT_Update,ENABLE);
TIM_Cmd(TIM2, ENABLE);
}
定时器中断一次的时间是 1ms,我们定义一个全局变量ucTim2Flag,每当进一次中断的时候,让 ucTim2Flag来记录进入中断的次数。如果我们想实现一个 1s 的定时,我们只需要判断time是否等于1000 即可,1000 个 1ms 就是1s。然后把ucTim2Flag清 0,重新计数,以此循环往复。
void TIM2_IRQHandler(void)
{
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
ucTim2Flag++;
}
0