1、STM32 入门篇之通用定时器彻底研究STM32 的定时器功能很强大,学习起来也很费劲儿,本人在这卡了 5 天才算看明白。写下下面的文字送给后来者,希望能带给你点启发。在此声明,本人也是刚入门,接触 STM32 不足 10 天,所以有失误的地方请以手册为准,欢迎大家拍砖。其实手册讲的还是挺全面的,只是无奈 TIMER 的功能太复杂,所以显得手册很难懂,我就是通过这样看手册:while(!SUCCESS)看手册才搞明白的!所以接下来我以手册的顺序为主线,增加一些自己的理解,并通过 11 个例程对TIMER 做个剖析。实验环境是 STM103V100 的实验板,MDK3.2 +Library2.东
2、西都不怎么新,凑合用TIMER 主要是由三部分组成:1、 时基单元。2、 输入捕获。3、 输出比较。还有两种模式控制功能:从模式控制和主模式控制。一、 框图让我们看下手册,一开始是定时器的框图,这里面几乎包含了所有定时器的信息,您要是能看明白,那么接下来就不用再看别的了为了方便的看图,我对里面出现的名词和符号做个注解:TIMx_ETR:TIMER 外部触发引脚 ETR:外部触发输入 ETRP:分频后的外部触发输入 ETRF:滤波后的外部触发输入ITRx:内部触发 x(由另外的定时器触发)TI1F_ED:TI1 的边沿检测器。 TI1FP1/2:滤波后定时器 1/2 的输入TRGI:触发输入 T
3、RGO:触发输出 CK_PSC:应该叫分频器时钟输入CK_CNT:定时器时钟。 (定时周期的计算就靠它)TIMx_CHx:TIMER 的输入脚 TIx:应该叫做定时器输入信号 xICx:输入比较 x ICxPS:分频后的 ICxOCx:输出捕获 x OCxREF:输出参考信号关于框图还有以下几点要注意:1、 影子寄存器。有阴影的寄存器,表示在物理上这个寄存器对应 2 个寄存器,一个是程序员可以写入或读出的寄存器,称为 preload register(预装载寄存器),另一个是程序员看不见的、但在操作中真正起作用的寄存器,称为 shadow register(影子寄存器);(详细请参考版主博客
4、http:/ 输入滤波机制在 ETR 何 TIx 输入端有个输入滤波器,它的作用是以采样频率Fdts 来采样 N 次进行滤波的。 (具体也请参考版主博客http:/ 输入引脚和输出引脚是相同的。二、时基单元 时基单元有三个部分:CNT、PSC、ARR。CNT 的计数方式分三种:向上、向下、中央对齐。通俗的说就是 0ARR、ARR 0、0(ARR-1)ARR1.三、时钟源的选择这个是难点之一。从手册上我们看到共有三种时钟源:1、 内部时钟。也就是选择 CK_INT 做时钟,这个简单,但是有一点要注意,定时器的时钟不是直接来自 APB1 或 APB2,而是来自于输入为APB1 或 APB2 的一个
5、倍频器, 当 APB1 的预分频系数为 1 时,这个倍频器不起作用,定时器的时钟频率等于 APB1 的频率;当APB1 的预分频系数为其它数值(即预分频系数为 2、4、8 或 16)时,这个倍频器起作用,定时器的时钟频率等于 APB1 的频率两倍。例如 AHP 72M,APB12 分频 36M,那么 TIMER 就是 APB1 的 2 倍频,即 72M。怎么选择时钟模式 1 呢?只要将 SMCR 中 SMS2:0弄成 000 就好了SMCR15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0ETP ECE ETPS1:0 ETF3:0 MSM TS2:0 SMS2:02、
6、 外部时钟模式 1这个比较麻烦,时钟源选择的其实就是 TRGI(触发输入) ,但触发输入选择挺多的,共 8 个。看框图,他们是:ITRx、TI1F_ED、TI1FP1、TI2FP2、ETRFITRx 的东西跟定时器的级联有关,暂时不管他。要进入这种时钟模式首先置 SMS 为 111,当然这还没完,不像内部时钟那样,什么都配好了,这里你还得配置一下别的参数,比如选择TI1FP1,自然要对输入通道 1 的参数配置好,这样时钟才能按你需要的方式进来。就是配框图这块相关寄存器CCMR1(输入)IC2F3:0 IC2PSC1:0 CC2S1:0 IC1F3:0 IC1PSC1:0 CC1S1:0CCER
7、15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0CC4P CC4E CC3P CC3E CC2P CC2E CC1P CC1ESMCR15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0ETP ECE ETPS1:0 ETF3:0 MSM TS2:0 SMS2:0在 CCMR1 寄存器里选择好相应的输入(CC1S)和滤波(IC1F)后再配置好输入极性(CCIP)然后在 SMCR 中选择触发源(TS2:0)为 TI1 这样输入通道就配好了!最后选择 SMS 为 111,开启时钟(CR1 中的 CEN) 。现在时钟就是从 TI1 上的输入了,可以接个
8、时钟源进行计数之类的。同理,如果要用 ETR 就把它相关通道配好就可以了。3、 外部时钟模式 2选择外部输入作为时钟,看框图:从图上可以看出 ETR 可以直接作为时钟输入也可以通过触发输入(TRGI)来作为时钟输入即在时钟模式 1 中触发源选择为 ETR,两个效果上是一样的,看起来好像这个外部时钟模式 2 没什么用处,实际上不是的,他可以跟一些从模式(复位、触发、门控)进行组合。比如当从模式选为触发时,我们不可能再通过触发源选择 ETR 了,因为从模式控制器被占了,好在有外部时钟模式 2,我们选择这种模式后就可以把两者组合在一起完成一些功能了。总结一下,STM32 的时钟选择比较特别,在 SF
9、R 中关于时钟选择配置位不再一块,不是说两个位在一起 00、01、11 就选择了而是由SMCR 中 SMS 和 ECE 来控制,这样感觉可以吧内部时钟与外部模式 2 同时打开(SMS:000,ECE:1) ,也可以吧外部模式 1 和外部模式 2 同时打开(SMS:111,ECE:1),实际上上述两种方式用的都是外部时钟 2.四、捕获比较通道这就是我说的定时器三个组成部分中的两个部分了。核心是那个捕获比较寄存器。看框图异或那块先不管他,好像跟编码器有关,输入有个特色就是可以把TI 的输入搞到 CC1 上去,也可以把 T2 的输入搞到 CC1 上去,其实也可以把 T1 搞到 CC1 上去同时把 T
10、1 搞到 CC2 上去,这样就有了后来的PWM 输入。输出上的特色是不直接输出,而是有个 OC1REF,这样可以定义高有效还是低有效,输出自己需要的有效电平。五、做实验讲了这么多你一定烦了吧,那么让我们搞点实际的吧,通过做实验来熟悉定时器,用到新知识时再在其中加以介绍。实验一:TIMER-1:定时器上溢,中断中取反 LED.现象:LED 周期 2 秒闪烁。主要代码如下:TIM_DeInit(TIM2);TIM_TimeBaseStructure.TIM_Period=2000; /ARR 的值TIM_TimeBaseStructure.TIM_Prescaler=0;TIM_TimeBaseS
11、tructure.TIM_ClockDivision=TIM_CKD_DIV1; /采样分频TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; /向上计数模式TIM_TimeBaseInit(TIM2, TIM_PrescalerConfig(TIM2,0x8C9F,TIM_PSCReloadMode_Immediate);/时钟分频系数 36000,所以定时器时钟为 2KTIM_ARRPreloadConfig(TIM2, DISABLE);/禁止 ARR 预装载缓冲器TIM_ITConfig(TIM2,TIM_IT_Updat
12、e,ENABLE);TIM_Cmd(TIM2, ENABLE);/开启时钟解释一下,首先得配好 ARR,这是必须地。然后配置预分频,为什么我先配为 0 再用TIM_PrescalerConfig(TIM2,0x8C9F,TIM_PSCReloadMode_Immediate)配呢,原来 PSC 也有个预装载功能,却不像 ARR 和 CRR 那样有相关的位控制立即装载或更新事件装载。也就是说只能更新事件来装载。在上面函数中手工产生了一个更新事件,使 PSC 立刻生效。CK_DIV 暂时没用到。计数模式配置为向上计数。然后在中断中做下 LED 取反就可以了。溢出周期怎么算?在这个实验里 AHB 为
13、 72M,APB1 为 36M,所以CK_INT 为 72M,36000 分频变为 2K.ARR=2000,所以 1 秒溢出 1 次。相关寄存器:CR1 9 8 7 6 5 4 3 2 1 0CKD1:0 ARPE CMS1:0 DIR OPM URS UDIS CENARRPSC接下来的 4 个实验跟输出通道有关系实验 2TIMER-2:强置输出现象:LED 常亮例子比较简单关键是配好输出通道CCER15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0CC4P CC4E CC3P CC3E CC2P CC2E CC1P CC1ECCMR(输出)OC2CE OC2M2:0
14、 OC2PE OC2FE CC2S OC1CE OC1M2:0 OC1PE OC1FE CC1S将通道 1 配为输出,输出使能,输出极性选择好,输出模式选择好就可以了。在 V100 实验板上 PC6-9 接了 LED,刚好对应着 TIMER3 重映射后的输出,注意程序里的 AFIO 函数。实验 3TIMER-3:输出比较现象:LED 2 秒的周期闪烁。跟上个实验配置大致相同,只是把输出模式改为翻转功能,并且 CRR要配好,当 CRR=CNT 时翻转输出。实验 4TIMER-4:PWM 输出现象:输出 4 种不同占空比的 PWM 波,4 个 LED 亮度不同。实验 5TIMER-7:单脉冲方式现
15、象:LED 只闪烁一次。将上个实验加一句话TIM_SelectOnePulseMode(TIM3, TIM_OPMode_Single); /设置单脉冲模式就是这个实验。其实手册上关于此实验的本意是由一个外部触发使能计数器,然后产生一个脉冲的,这里还没涉及从模式所以简化处理。涉及寄存器CR1 9 8 7 6 5 4 3 2 1 0CKD1:0 ARPE CMS1:0 DIR OPM URS UDIS CEN接下来再做两个输入的实验实验 6TIMER-5:输入捕获模式。现象:通过 V100 的 JOYSTICK 键的 SELECT 键进入捕获,硬件仿真看CRR 的值。首先是基本的配置:ARR 的
16、值、时钟 PSC、采样 CKD、计数方式。然后配置输入通道。选择输入捕获模式、输入极性、把 T1 配到 CC1 上、选好输入的滤波跟分频,就可以了。讲下输入滤波功能,在此实验中 Fdts=CK_INT/2,Fsample=Fdts/4,所以定时器时钟为 2K,所以采样周期为 4ms。才 8 次的话周期小于 32ms的干扰会滤除。相关寄存器CR1 9 8 7 6 5 4 3 2 1 0CKD1:0 ARPE CMS1:0 DIR OPM URS UDIS CENPSCARRCCMR1(输入)IC2F3:0 IC2PSC1:0 CC2S1:0 IC1F3:0 IC1PSC1:0 CC1S1:0CC
17、ER15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0CC4P CC4E CC3P CC3E CC2P CC2E CC1P CC1E实验 7TIMER-6:PWM 输入现象:由 TIMER3 输出通道 1 产生一路周期 2 秒占空比 50%的 PWM 波,飞线到 TIMER4 的输入通道 1,有 TIMER4 来测量该 PWM 得周期和占空比。在做实验之前引入三种从模式控制:复位、触发、门控。通过 SMCR 选择后可以进入这三种从模式SMCR15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0ETP ECE ETPS1:0 ETF3:0 MSM T
18、S2:0 SMS2:0SMS: 100 101 110复位 门控 触发 所谓从模式简单理解就是受控于别人了,包括何时启动、何时停止、何时复位。相关作用请看手册。提示一点就是进入这三种模式后时钟是谁的问题?肯定不是外部时钟 1 了,可以是内部时钟和外部时钟 2.接着看实验,PWM 方式的原理是这样的,如前文提到过输入时可以把T1 映射到 CC1 上去同时映射到 CC2 上,将 CC1 和 CC2 的捕获边沿搞成相反的,比如 CC1 捕获 T1 上升沿,CC2 捕获 T1 下降沿,还要再设置T1 为复位从模式,上升沿有效,这样 T1 上升沿后计数器开始计数。下降沿 CC2 捕获发生,此为 PWM
19、占空比,在来一个上升沿,CC1 捕获发生此为 PWM 周期。注意 CC1 捕获的第一次无效。这是从模式跟输入捕获的一种组合使用,从模式还可以跟输出比较组合使用。比如手册上的单脉冲实验。接着做 4 个实验跟定时器的级联和定时器同步有关系,在实验前先得说说主模式的问题。在 CR2 寄存器中的 MMS 位决定了定时器的主模式方式,即决定 TRGO.几种方式可以参看手册。要说明一点就是一个定期器既可以是主模式同时它也是从模式,这就好像你是一个中层干部一样,既可以领导别人同时又被别人领导,这个不冲突的。简单介绍下 4 个实验。实验 8TIMER-8: TIMER2 作为 TIMER3 的分频器.现象:L
20、ED 以 10 秒周期闪烁。TIMER3 配置为 PWM 输出,但是始终有 TIMER2 的溢出时间频率来提供,其溢出频率为 100Hz 所以 TIMER3 PWM 的周期为 10S. 实验 9TIMER-9:TIMER2 来使能 TIMER3.现象:LD1 前 15 秒以 1 秒的周期闪烁,后 15 秒熄掉,然后下个 15 秒再闪烁如此循环。在这个实验里 TIEMR3 输出一个周期 1 秒的 PWM 波,仍然驱动 LD1 闪烁。同时从模式配成门控模式,TIEMR2 将 OC1 作为 TRGO,OC1 是一个周期30S 占空比 50%的 PWM 波。实验 10TIMER-10: IMER2 启
21、动 TIMER3现象:上电后延迟 15 秒 LD1 以 1 秒的周期闪烁。此实验跟上个实验配置差不多只要把 TIMER3 有门控改为触发方式即可。实验 11TIMER-11: TIMER4 的通道 1 同时出发 TIMER4 和 TIMER3 两个定时器现象:按下 JOYSTICK 的“选择”键同时出发两个定时器开始。同时TIMER3 驱动 LD1 以 1 秒周期闪烁。以上 4 个实验实际上是主模式和从模式的组合以及主模式和外部时钟1 的组合。其实根据自己的需要还可以做出多种组合,这就是 STM32定时器强大的地方。最后多熟悉下库函数,关于 TIM 的库(2.0 版本) ,本人认为有两点错误:1、 TIM.C 中 CR1_CounterMode_Mask 的值为 0x039F 应该改为0x038F 这样才能覆盖 CR1 的 DIR 位。2、 TIM.C 中 TIM_PrescalerConfig 函数原文if (TIM_PSCReloadMode = TIM_PSCReloadMode_Immediate)TIMx-EGR |= TIM_EventSource_Update;elseTIMx-EGR 红色的这句好像不对吧?应该 TIMx-EGR 才对吧。