TA的每日心情 | 衰 2024-10-6 20:55 |
---|
签到天数: 1 天 [LV.1]初来乍到
二级逆天
- 积分
- 1392
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区
您需要 登录 才可以下载或查看,没有账号?立即注册
×
定时器同步
在MM32L073一个定时器有4通道PWM输出,有客户在应用中需要使用两个定时器控制6路PWM输出,为了使两个定时器的PWM输出相同的波形,所以需要两个定时器实现同步功能。
所有TIMx定时器在内部相连,用于定时器同步或链接。当一个定时器处于主模式时,它可以对另一个处于从模式的定时器的计数器进行复位、启动、停止或提供时钟等操作。
MM32L073的每个定时器都可以由另一个定时器触发启动定时器一般是通过软件设置而启动,MM32L073的每个定时器也可以通过外部信号触发而启动,还可以通过另外一个定时器的某一个条件被触发而启动。这里所谓某一个条件可以是定时到时、定时器超时、比较成功等许多条件。这种通过一个定时器触发另一个定时器的工作方式称为定时器的同步,发出触发信号的定时器工作于主模式,接受触发信号而启动的定时器工作于从模式。
主/从定时器的例子
为了实现两个定时器完全同步,使用一个定时器作为另一个定时器的预分频器。可以配置定时器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的计数器。
voidTim1_Init(u16Prescaler,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);
}
voidTIM3_Init(u16psc,u16arr)
{
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。
voidTim2_UPCount_test(void)
{
TIM_TimeBaseInitTypeDefTIM_StructInit;
NVIC_InitTypeDefNVIC_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,重新计数,以此循环往复。
voidTIM2_IRQHandler(void)
{
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
ucTim2Flag++;
} |
|