学习目的: 要想灵活使用MCU,那么定时器的使用是必须掌握的。定时器的一些基本功能,例如计数、定时、PWM输出都是入门内容,今天来研究一下定时器的级联,要想完全搞清楚定时器之间的级联妙用也不是一件容易的事情呢。希望通过这次研究学习,能彻底搞清楚定时器。 学习内容: 1. 定时器级联是什么呢?级联当然就是将两个或者两个以上的定时器串在一起,时一个定时器去触发一个或者多个定时器计数,所以定时器级联就产生了主定时器和从定时器的说法了。 2. 什么是主定时器呢?那些定时器可以作为主定时器呢?以AT32F403A这款MCU为例吧,主定时器可以是TMR1/8/15/2/3/4/5/6/7。这里就有一个疑问了,是怎么知道这些TMR能作为主定时器的呢?这个问题的答案就藏在官方提供的手册里啦,我总结出一个快速知道此问题答案的方法,此方法不局限于AT32F403A这一款MCU,其他系列MCU也是一样;答案就是看定时器的CTRL2寄存器,如果这个寄存器里面定义了MMSEL[2:0]这几个bit位,那么就是可以作为主定时的啦。 以下MMSEL[2:0]在手册上的描述,里面可选的选项会根据定时器的不同存在差异: 3. 什么是从定时器呢?那些定时器可以作为从定时器呢?哈哈!和前面找主定时器的方法一样,也是看寄存器啦,如果定时器有SMC寄存器,那么就是可以作为从定时器的哦。以下是从定时器的触发源的描述,里面可选的选项会根据定时器的不同存在差异: 4. 搞清楚了主定时器和从定时如何找到,那么他们之间的链接关系呢?是任意组合还是有特定规则呢?链接关系是有特定规则的,那么规则在哪里呢?也在手册中,其实可以作为从定时器的TMR的SMC寄存器的后面都有附上一张表格啦,这张表格就是这个TMR的链接情况,以TMR1为例,表格如下: 这张表格中的ITRx的意思是在位从定时器选择触发源,触发源的选择也在SMC寄存器内,如下: 5. 经过上面的介绍应该知道如何设置主定时器和从定时器了吧,AT32F403A的定时器很多,所以可以组合的种类也很多,十分的灵活哦。
总结: 对于主定时器可以选择多种信号源作为触发输出,对于从定时器可以选择不同的TMR作为自己的主定时器,同时从定时器也可以选择自己的模式,当收到主定时器的触发信号后做什么处理,例如启动、复位等等。
好啦,话不多说啦,我们实际coding一个例子吧! /* TMR3 Peripheral Configuration----------------------------------------*/ /*TMR3 Slave Configuration: PWM1 Mode */ TMR_TimeBaseStructInit(&TMR_TMReBaseStructure); TMR_TMReBaseStructure.TMR_Period = 2; TMR_TMReBaseStructure.TMR_DIV = 0; TMR_TMReBaseStructure.TMR_ClockDivision = 0; TMR_TMReBaseStructure.TMR_CounterMode = TMR_CounterDIR_Up; TMR_TimeBaseInit(TMR3, &TMR_TMReBaseStructure); TMR_OCStructInit(&TMR_OCInitStructure); TMR_OCInitStructure.TMR_OCMode = TMR_OCMode_PWM1; TMR_OCInitStructure.TMR_OutputState = TMR_OutputState_Enable; TMR_OCInitStructure.TMR_Pulse= 1; TMR_OC1Init(TMR3, &TMR_OCInitStructure); /*Slave Mode selection: TMR3 */ TMR_SelectSlaveMode(TMR3, TMR_SlaveMode_Gate); TMR_SelectInputTrigger(TMR3, TMR_TRGSEL_ITR0); /*TMR4 Peripheral Configuration ----------------------------------------*/ /*TMR4 Slave Configuration: PWM1 Mode */ TMR_TMReBaseStructure.TMR_Period = 1; TMR_TMReBaseStructure.TMR_DIV = 0; TMR_TMReBaseStructure.TMR_ClockDivision = 0; TMR_TMReBaseStructure.TMR_CounterMode = TMR_CounterDIR_Up; TMR_TimeBaseInit(TMR4, &TMR_TMReBaseStructure); TMR_OCInitStructure.TMR_OCMode = TMR_OCMode_PWM1; TMR_OCInitStructure.TMR_OutputState = TMR_OutputState_Enable; TMR_OCInitStructure.TMR_Pulse= 1; TMR_OC1Init(TMR4, &TMR_OCInitStructure); /*Slave Mode selection: TMR4 */ TMR_SelectSlaveMode(TMR4, TMR_SlaveMode_Gate); TMR_SelectInputTrigger(TMR4, TMR_TRGSEL_ITR0); /*TMR1 Peripheral Configuration ----------------------------------------*/ /*TMRe Base configuration */ TMR_TMReBaseStructure.TMR_DIV = 0; TMR_TMReBaseStructure.TMR_CounterMode = TMR_CounterDIR_Up; TMR_TMReBaseStructure.TMR_Period = 319; TMR_TMReBaseStructure.TMR_ClockDivision = 0; TMR_TMReBaseStructure.TMR_RepetitionCounter = 4; TMR_TimeBaseInit(TMR1, &TMR_TMReBaseStructure); /*Channel 1 Configuration in PWM mode */ TMR_OCInitStructure.TMR_OCMode = TMR_OCMode_PWM2; TMR_OCInitStructure.TMR_OutputState= TMR_OutputState_Enable; TMR_OCInitStructure.TMR_OutputNState = TMR_OutputNState_Enable; TMR_OCInitStructure.TMR_Pulse = 127; TMR_OCInitStructure.TMR_OCPolarity = TMR_OCPolarity_Low; TMR_OCInitStructure.TMR_OCNPolarity = TMR_OCNPolarity_Low; TMR_OCInitStructure.TMR_OCIdleState = TMR_OCIdleState_Set; TMR_OCInitStructure.TMR_OCNIdleState = TMR_OCIdleState_Reset; TMR_OC1Init(TMR1, &TMR_OCInitStructure); /*Automatic Output enable, Break, dead TMRe and lock configuration*/ TMR_BRKDTStructInit(&TMR_BDTRInitStructure); TMR_BDTRInitStructure.TMR_OSIMRState = TMR_OSIMRState_Enable; TMR_BDTRInitStructure.TMR_OSIMIState = TMR_OSIMIState_Enable; TMR_BDTRInitStructure.TMR_LOCKgrade = TMR_LOCKgrade_1; TMR_BDTRInitStructure.TMR_DeadTime = 5; TMR_BDTRInitStructure.TMR_Break = TMR_Break_Disable; TMR_BDTRInitStructure.TMR_BreakPolarity = TMR_BreakPolarity_High; TMR_BDTRInitStructure.TMR_AutomaticOutput = TMR_AutomaticOutput_Disable; TMR_BRKDTConfig(TMR1, &TMR_BDTRInitStructure); /*Master Mode selection */ TMR_SelectOutputTrigger(TMR1, TMR_TRGOSource_Update); /*Select the Master Slave Mode */ TMR_SelectMasterSlaveMode(TMR1, TMR_MasterSlaveMode_Enable); /*TMR1 counter enable */ TMR_Cmd(TMR1, ENABLE); /*TMR enable counter */ TMR_Cmd(TMR3, ENABLE); TMR_Cmd(TMR4, ENABLE); /*Main Output Enable */ TMR_CtrlPWMOutputs(TMR1, ENABLE);
这个例子实现了定时器1去触发定时器3和定时器4;主定时器的触发输出为update事件,两个从定时器的从模式则配置为门控模式。
|