STM32-Project32:高级定时器TIM1/8功能框图寄存器固件库理解,PWM互补输出比较实验

一 高级定时器功能框图

高级控制定时器时基单元包含一个 16 位自动重装载寄存器 ARR ,一个 16 位的计数器
CNT ,可向上 / 下计数,一个 16 位可编程预分频器 PSC ,预分频器时钟源有多种可选,有
内部的时钟、外部时钟。还有一个 8 位的重复计数器 RCR ,这样最高可实现 40 位的可编
程定时。
STM32F103ZET6 的高级 / 通用定时器的 IO 分配具体见表 。配套开发板因为 IO
源紧缺,定时器的 IO 很多已经复用它途,故下表中的 IO 只有部分可用于定时器的实验。因为只有几个定时器IO是纯净的
STM32-Project32:高级定时器TIM1/8功能框图寄存器固件库理解,PWM互补输出比较实验_第1张图片

STM32-Project32:高级定时器TIM1/8功能框图寄存器固件库理解,PWM互补输出比较实验_第2张图片

1  ①时钟源  高级控制定时器有四个时钟源可选:
内部时钟源 CK_INT
外部时钟模式 1 :外部输入引脚 TIx x=1,2,3,4
外部时钟模式 2 :外部触发输入 ETR
内部触发输入 (ITRx)
内部时钟源 (CK_INT)
内部时钟 CK_INT 即来自于芯片内部RCC外设,等于 72M ,一般情况下,我们都是使用内部时
钟。当从模式控制寄存器 TIMx_SMCR SMS 位等于 000 时,则使用内部时钟。
外部时钟模式 1
STM32-Project32:高级定时器TIM1/8功能框图寄存器固件库理解,PWM互补输出比较实验_第3张图片
①:时钟信号输入引脚
当使用外部时钟模式 1 的时候,时钟信号来自于定时器的输入通道,总共有 4 个,分
别为 TI1/2/3/4 ,即 TIMx_CH1/2/3/4 。具体使用哪一路信号,由 TIM_CCMRx 的位
CCxS[1:0] 配置,其中 CCMR1 控制 TI1/2 CCMR2 控制 TI3/4
②:滤波器
如果来自外部的时钟信号的频率过高或者混杂有高频干扰信号的话,我们就需要使用
滤波器对信号重新采样,来达到降频或者去除高频干扰的目的,具体的由 TIMx_CCMRx
的位 ICxF[3:0] 配置。
③:边沿检测
边沿检测的信号来自于滤波器的输出,在成为触发信号之前,需要进行边沿检测,决
定是上升沿有效还是下降沿有效,具体的由 TIMx_CCER 的位 CCxP CCxNP 配置。
④:触发选择
当使用外部时钟模式 1 时,触发源有两个,一个是滤波后的定时器输入 1 TI1FP1
和滤波后的定时器输入 2 TI2FP2 ),具体的由 TIMxSMCR 的位 TS[2:0] 配置。
⑤:从模式选择
选定了触发源信号后,最后我们需把信号连接到 TRGI 引脚,让触发信号成为外部时
钟模式 1 的输入,最终等于 CK_PSC ,然后驱动计数器 CNT 计数。具体的配置
TIMx_SMCR 的位 SMS[2:0] 000 即可选择外部时钟模式 1
⑥:使能计数器
经过上面的 5 个步骤之后,最后我们只需使能计数器开始计数,外部时钟模式 1 的配
置就算完成。使能计数器由 TIMx_CR1 的位 CEN 配置
外部时钟模式 2
STM32-Project32:高级定时器TIM1/8功能框图寄存器固件库理解,PWM互补输出比较实验_第4张图片
①:时钟信号输入引脚
当使用外部时钟模式 2 的时候,时钟信号来自于定时器的特定输入通道 TIMx_ETR
只有 1 个。
②:外部触发极性
来自 ETR 引脚输入的信号可以选择为上升沿或者下降沿有效,具体的由 TIMx_SMCR
的位 ETP 配置。
③:外部触发预分频器
由于 ETRP 的信号的频率不能超过 TIMx_CLK 72M )的 1/4 ,当触发信号的频率很高
的情况下,就必须使用分频器来降频,具体的由 TIMx_SMCR 的位 ETPS[1:0] 配置。
④:滤波器
如果 ETRP 的信号的频率过高或者混杂有高频干扰信号的话,我们就需要使用滤波器
ETRP 信号重新采样,来达到降频或者去除高频干扰的目的。具体的由 TIMx_SMCR
ETF[3:0] 配置,其中的 f DTS 是由内部时钟 CK_INT 分频得到,具体的由 TIMx_CR1 的位
CKD[1:0] 配置。
⑤:从模式选择
经过滤波器滤波的信号连接到 ETRF 引脚后,触发信号成为外部时钟模式 2 的输入,
最终等于 CK_PSC ,然后驱动计数器 CNT 计数。具体的配置 TIMx_SMCR 的位 ECE 1
即可选择外部时钟模式 2
⑥:使能计数器
经过上面的 5 个步骤之后,最后我们只需使能计数器开始计数,外部时钟模式 2 的配
置就算完成。使能计数器由 TIMx_CR1 的位 CEN 配置。
内部触发输入
内部触发输入是使用一个定时器作为另一个定时器的预分频器。硬件上高级控制定时
器和通用定时器在内部连接在一起,可以实现定时器同步或级联。主模式的定时器可以对
从模式定时器执行复位、启动、停止或提供时钟。
2. ②控制器
高级控制定时器控制器部分包括触发控制器、从模式控制器以及编码器接口。触发控
制器用来针对片内外设输出触发信号,比如为其它定时器提供时钟和触发 DAC/ADC 转换。
编码器接口专门针对编码器计数而设计。从模式控制器可以控制计数器复位、启动、递增 /
递减、计数。有关控制器部分只需熟练阅读寄存器描述即可。
3. ③时基单元
STM32-Project32:高级定时器TIM1/8功能框图寄存器固件库理解,PWM互补输出比较实验_第5张图片

高级控制定时器时基单元功能包括四个寄存器,分别是计数器寄存器 (CNT) 、预分频
器寄存器 (PSC) 、自动重载寄存器 (ARR) 和重复计数器寄存器 (RCR) 。其中重复计数器 RCR
是高级定时器独有,通用和基本定时器没有。前面三个寄存器都是 16 位有效, TIMx_RCR
寄存器是 8 位有效。
预分频器 PSC
预分频器 PSC ,有一个输入时钟 CK_PSC 和一个输出时钟 CK_CNT 。输入时钟
CK_PSC 就是上面时钟源的输出,输出 CK_CNT 则用来驱动计数器 CNT 计数。通过设置
预 分 频 器 PSC 的 值 可 以 得 到 不 同 的 CK_CNT ,实际计算为: f CK_CNT 等 于
f CK_PSC /(PSC[15:0]+1) ,可以实现 1 65536 分频。
计数器 CNT
高级控制定时器的计数器有三种计数模式,分别为递增计数模式、递减计数模式和递
/ 递减 ( 中心对齐 ) 计数模式。
(1) 递增计数模式下,计数器从 0 开始计数,每来一个 CK_CNT 脉冲计数器就增加 1 ,直
到计数器的值与自动重载寄存器 ARR 值相等,然后计数器又从 0 开始计数并生成计数
器上溢事件,计数器总是如此循环计数。如果禁用重复计数器,在计数器生成上溢事
件就马上生成更新事件 (UEV) ;如果使能重复计数器,每生成一次上溢事件重复计数
器内容就减 1 ,直到重复计数器内容为 0 时才会生成更新事件。
(2) 递减计数模式下,计数器从自动重载寄存器 ARR 值开始计数,每来一个 CK_CNT
冲计数器就减 1 ,直到计数器值为 0 ,然后计数器又从自动重载寄存器 ARR 值开始递
减计数并生成计数器下溢事件,计数器总是如此循环计数。如果禁用重复计数器,在
计数器生成下溢事件就马上生成更新事件;如果使能重复计数器,每生成一次下溢事
件重复计数器内容就减 1 ,直到重复计数器内容为 0 时才会生成更新事件。
(3) 中心对齐模式下,计数器从 0 开始递增计数,直到计数值等于 (ARR-1) 值生成计数器上
溢事件,然后从 ARR 值开始递减计数直到 1 生成计数器下溢事件。然后又从 0 开始计
数,如此循环。每次发生计数器上溢和下溢事件都会生成更新事件。
自动重载寄存器 ARR
自动重载寄存器 ARR 用来存放与计数器 CNT 比较的值,如果两个值相等就递减重复
计数器。可以通过 TIMx_CR1 寄存器的 ARPE 位控制自动重载影子寄存器功能,如果
ARPE 位置 1 ,自动重载影子寄存器有效,只有在事件更新时才把 TIMx_ARR 值赋给影子
寄存器。如果 ARPE 位为 0 ,则修改 TIMx_ARR 值马上有效。
重复计数器 RCR
在基本 / 通用定时器发生上 / 下溢事件时直接就生成更新事件,但对于高级控制定时器
却不是这样,高级控制定时器在硬件结构上多出了重复计数器,在定时器发生上溢或下溢
事件是递减重复计数器的值,只有当重复计数器为 0 时才会生成更新事件。在发生 N+1
上溢或下溢事件 (N RCR 的值 ) 时产生更新事件。
4. ④输入捕获
STM32-Project32:高级定时器TIM1/8功能框图寄存器固件库理解,PWM互补输出比较实验_第6张图片

输入捕获可以对输入的信号的上升沿,下降沿或者双边沿进行捕获,常用的有测量输
入信号的脉宽和测量 PWM 输入信号的频率和占空比这两种。
输入捕获的大概的原理就是,当捕获到信号的跳变沿的时候,把计数器 CNT 的值锁存
到捕获寄存器 CCR 中,把前后两次捕获到的 CCR 寄存器中的值相减,就可以算出脉宽或
者频率。如果捕获的脉宽的时间长度超过你的捕获定时器的周期,就会发生溢出,这个我
们需要做额外的处理。
①输入通道
需要被测量的信号从定时器的外部引脚 TIMx_CH1/2/3/4 进入,通常叫 TI1/2/3/4 ,在后
面的捕获讲解中对于要被测量的信号我们都以 TIx 为标准叫法。
②输入滤波器和边沿检测器
当输入的信号存在高频干扰的时候,我们需要对输入信号进行滤波,即进行重新采样,
根据采样定律,采样的频率必须大于等于两倍的输入信号。比如输入的信号为 1M ,又存
在高频的信号干扰,那么此时就很有必要进行滤波,我们可以设置采样频率为 2M ,这样
可以在保证采样到有效信号的基础上把高于 2M 的高频干扰信号过滤掉。
滤波器的配置由 CR1 寄存器的位 CKD[1:0] CCMR1/2 的位 ICxF[3:0] 控制。从 ICxF
位的描述可知,采样频率 f SAMPLE 可以由 f CK_INT f DTS 分频后的时钟提供,其中是 f CK_INT
部时钟, f DTS f CK_INT 经过分频后得到的频率,分频因子由 CKD[1:0] 决定,可以是不分频,
2 分频或者是 4 分频。
边沿检测器用来设置信号在捕获的时候是什么边沿有效,可以是上升沿,下降沿,或
者是双边沿,具体的由 CCER 寄存器的位 CCxP CCxNP 决定。
③捕获通道
捕获通道就是图中的 IC1/2/3/4 ,每个捕获通道都有相对应的捕获寄存器 CCR1/2/3/4
当发生捕获的时候,计数器 CNT 的值就会被锁存到捕获寄存器中。
这里我们要搞清楚输入通道和捕获通道的区别,输入通道是用来输入信号的,捕获通
道是用来捕获输入信号的通道,一个输入通道的信号可以同时输入给两个捕获通道。比如
输入通道 TI1 的信号经过滤波边沿检测器之后的 TI1FP1 TI1FP2 可以进入到捕获通道
IC1 IC2 ,其实这就是我们后面要讲的 PWM 输入捕获,只有一路输入信号( TI1 )却占
用了两个捕获通道( IC1 IC2 ),一个测量脉冲宽度,一个测量周期。当只需要测量输入信号的脉宽时候,用一个捕获通道即
可。输入通道和捕获通道的映射关系具体由寄存器 CCMRx 的位 CCxS[1:0] 配置。
④预分频器
ICx 的输出信号会经过一个预分频器,用于决定发生多少个事件时进行一次捕获。具
体的由寄存器 CCMRx 的位 ICxPSC 配置,如果希望捕获信号的每一个边沿,则不分频。
⑤捕获寄存器
经过预分频器的信号 ICxPS 是最终被捕获的信号,当发生捕获时(第一次),计数器
CNT 的值会被锁存到捕获寄存器 CCR 中,还会产生 CCxI 中断,相应的中断位 CCxIF (在
SR 寄存器中)会被置位,通过软件或者读取 CCR 中的值可以将 CCxIF 0 。如果发生第
二次捕获(即重复捕获: CCR 寄存器中已捕获到计数器值且 CCxIF 标志已置 1 ),则捕获
溢出标志位 CCxOF (在 SR 寄存器中)会被置位, CCxOF 只能通过软件清零
5. ⑤输出比较
STM32-Project32:高级定时器TIM1/8功能框图寄存器固件库理解,PWM互补输出比较实验_第7张图片

输出比较就是通过定时器的外部引脚对外输出控制信号,有冻结、将通道 X
x=1,2,3,4 )设置为匹配时输出有效电平、将通道 X 设置为匹配时输出无效电平、翻转、
强制变为无效电平、强制变为有效电平、 PWM1 PWM2 这八种模式,具体使用哪种模式
由寄存器 CCMRx 的位 OCxM[2:0] 配置。其中 PWM 模式是输出比较中的特例,使用的也
最多。
①比较寄存器
当计数器 CNT 的值跟比较寄存器 CCR 的值相等的时候,输出参考信号 OCxREF 的信
号的极性就会改变,其中 OCxREF=1 (高电平)称之为有效电平, OCxREF=0 (低电平)
称之为无效电平,并且会产生比较中断 CCxI ,相应的标志位 CCxIF SR 寄存器中)会置
位。然后 OCxREF 再经过一系列的控制之后就成为真正的输出信号 OCx/OCxN
②死区发生器
在生成的参考波形 OCxREF 的基础上,可以插入死区时间,用于生成两路互补的输出
信号 OCx OCxN ,死区时间的大小具体由 BDTR 寄存器的位 DTG[7:0] 配置。死区时间
的大小必须根据 与输出信号相连接的器件及其特性来调整。下面我们简单举例说明下带死区的
PWM 信号的应用,我们以一个板桥驱动电路为例。
STM32-Project32:高级定时器TIM1/8功能框图寄存器固件库理解,PWM互补输出比较实验_第8张图片

 ③输出控制 STM32-Project32:高级定时器TIM1/8功能框图寄存器固件库理解,PWM互补输出比较实验_第9张图片

在输出比较的输出控制中,参考信号 OCxREF 在经过死区发生器之后会产生两路带死
区的互补信号 OCx_DT OCxN_DT (通道 1~3 才有互补信号,通道 4 没有,其余跟通道
1~3 一样),这两路带死区的互补信号然后就进入输出控制电路,如果没有加入死区控制,
那么进入输出控制电路的信号就直接是 OCxREF
进入输出控制电路的信号会被分成两路,一路是原始信号,一路是被反向的信号,具
体的由寄存器 CCER 的位 CCxP CCxNP 控制。经过极性选择的信号是否由 OCx 引脚输
出到外部引脚 CHx/CHxN 则由寄存器 CCER 的位 CxE/CxNE 配置。
如果加入了断路(刹车)功能,则断路和死区寄存器 BDTR MOE OSSI OSSR
这三个位会共同影响输出的信号。
④输出引脚
输出比较的输出信号最终是通过定时器的外部 IO 来输出的,分别为 CH1/2/3/4 ,其中
前面三个通道还有互补的输出通道 CH1/2/3N 。更加详细的 IO 说明还请查阅相关的数据手

册。

6. ⑥断路功能
断路功能就是电机控制的刹车功能,使能断路功能时,根据相关控制位状态修改输出
信号电平。在任何情况下, OCx OCxN 输出都不能同时为有效电平,这关系到电机控制
常用的 H 桥电路结构原因。
断路源可以是时钟故障事件,由内部复位时钟控制器中的时钟安全系统 (CSS) 生成,也
可以是外部断路输入 IO ,两者是或运算关系。
系统复位启动都默认关闭断路功能,将断路和死区寄存器 (TIMx_BDTR) BKE 为置 1
使能断路功能。可通过 TIMx_BDTR 寄存器的 BKP 位设置设置断路输入引脚的有效电平,
设置为 1 时输入 BRK 为高电平有效,否则低电平有效。
发送断路时,将产生以下效果:
TIMx_BDTR 寄存器中主输出模式使能 (MOE) 位被清零,输出处于无效、空闲或
复位状态;
根据相关控制位状态控制输出通道引脚电平;当使能通道互补输出时,会根据情
况自动控制输出通道电平;
TIMx_SR 寄存器中的 BIF 位置 1 ,并可产生中断和 DMA 传输请求。
如果 TIMx_BDTR 寄存器中的 自动输出使能 (AOE) 位置 1 ,则 MOE 位会在发生下
一个 UEV 事件时自动再次置 1
一  . 一 输入捕获应用
输入捕获一般应用在两个方面,一个方面是脉冲跳变沿时间测量,另一方面是 PWM
输入测量
测量脉宽或者频率
STM32-Project32:高级定时器TIM1/8功能框图寄存器固件库理解,PWM互补输出比较实验_第10张图片

 

1. 测量频率
当捕获通道 TIx 上出现上升沿时,发生第一次捕获,计数器 CNT 的值会被锁存到捕获
寄存器 CCR 中,而且还会进入捕获中断,在中断服务程序中记录一次捕获(可以用一个标
志变量来记录),并把捕获寄存器中的值读取到 value1 中。当出现第二次上升沿时,发生
第二次捕获,计数器 CNT 的值会再次被锁存到捕获寄存器 CCR 中,并再次进入捕获中断,
在捕获中断中,把捕获寄存器的值读取到 value3 中,并清除捕获记录标志。利用 value3
value1 的差值我们就可以算出信号的周期(频率)。
2. 测量脉宽
当捕获通道 TIx 上出现上升沿时,发生第一次捕获,计数器 CNT 的值会被锁存到捕获
寄存器 CCR 中,而且还会进入捕获中断,在中断服务程序中记录一次捕获(可以用一个标
志变量来记录),并把捕获寄存器中的值读取到 value1 中。然后把捕获边沿改变为下降沿
捕获,目的是捕获后面的下降沿。当下降沿到来的时候,发生第二次捕获,计数器 CNT
值会再次被锁存到捕获寄存器 CCR 中,并再次进入捕获中断,在捕获中断中,把捕获寄存
器的值读取到 value3 中,并清除捕获记录标志。然后把捕获边沿设置为上升沿捕获。
3.PWM 输入模式
测量脉宽和频率还有一个更简便的方法就是使用 PWM 输入模式,该模式是输入捕获
的特例,只能使用通道 1 和通道 2 ,通道 3 和通道 4 使用不了。与上面那种只使用一个捕
获寄存器测量脉宽和频率的方法相比, PWM 输入模式需要占用两个捕获寄存器。
STM32-Project32:高级定时器TIM1/8功能框图寄存器固件库理解,PWM互补输出比较实验_第11张图片
当使用 PWM 输入模式的时候,因为一个输入通道 (TIx) 会占用两个捕获通道 (ICx) ,所
以一个定时器在使用 PWM 输入的时候最多只能使用两个输入通道 (TIx)
我们以输入通道 TI1 工作在 PWM 输入模式为例来讲解下具体的工作原理,其他通道
以此类推即可。
PWM 信号由输入通道 TI1 进入,因为是 PWM 输入模式的缘故,信号会被分为两路,
一路是 TI1FP1 ,另外一路是 TI2FP2 。其中一路是周期,另一路是占空比,具体哪一路信
号对应周期还是占空比,得从程序上设置哪一路信号作为触发输入,作为触发输入的哪一
路信号对应的就是周期,另一路就是对应占空比。作为触发输入的那一路信号还需要设置
极性,是上升沿还是下降沿捕获,一旦设置好触发输入的极性,另外一路硬件就会自动配
置为相反的极性捕获,无需软件配置。一句话概括就是:选定输入通道,确定触发信号,
然后设置触发信号的极性即可,因为是 PWM 输入的缘故,另一路信号则由硬件配置,无
需软件配置。
当使用 PWM 输入模式的时候必须将从模式控制器配置为复位模式(配置寄存器
SMCR 的位 SMS[2:0] 来实现),即当我们启动触发信号开始进行捕获的时候,同时把计数
CNT 复位清零
一  . 二 输出比较应用
输出比较模式总共有 8 种,具体的由寄存器 CCMRx 的位 OCxM[2:0] 配置。我们这里
只讲解最常用的 PWM 模式,其他几种模式具体的看数据手册即可。
32.4.1 PWM 输出模式
PWM 输出就是对外输出脉宽(即占空比)可调的方波信号,信号频率由自动重装寄
存器 ARR 的值决定,占空比由比较寄存器 CCR 的值决定。
PWM 模式分为两种, PWM1 PWM2 ,总得来说是差不多,就看你怎么用而已,具
体的区别见表 STM32-Project32:高级定时器TIM1/8功能框图寄存器固件库理解,PWM互补输出比较实验_第12张图片

 

1. PWM 边沿对齐模式
在递增计数模式下,计数器从 0 计数到自动重载值(
TIMx_ARR 寄存器的内容),然后重新
0 开始计数并生成计数器上溢事件
32-13 PWM1 模式的边沿对齐波形
在边沿对齐模式下,计数器 CNT 只工作在一种模式,递增或者递减模式。这里我们以
CNT 工作在递增模式为例,在中, ARR=8 CCR=4 CNT 0 开始计数,当 CNT
值时, OCxREF 为 有 效的 高 电平 ,于 此同 时, 比 较中 断寄 存器 CCxIF 置位。当
CCR= 时, OCxREF 为无效的低电平。然后 CNT 又从 0 开始计数并生成计数
器上溢事件,以此循环往复。
2. PWM 中心对齐模式
32-14 PWM1 模式的中心对齐波形
在中心对齐模式下,计数器 CNT 是工作做递增 / 递减模式下。开始的时候,计数器
CNT 0 开始计数到自动重载值减 1(ARR-1) ,生成计数器上溢事件;然后从自动重载值开
始向下计数到 1 并生成计数器下溢事件。之后从 0 开始重新计数。
32-14 PWM1 模式的中心对齐波形, ARR=8 CCR=4 。第一阶段计数器 CNT
作在递增模式下,从 0 开始计数,当 CNT 的值时, OCxREF 为有效的高电平,当
CCR= 时, OCxREF 为无效的低电平。第二阶段计数器 CNT 工作在递减模式
ARR 的值开始递减,当 CNT>CCR 时, OCxREF 为无效的低电平,当 CCR=>CNT>=1
时, OCxREF 为有效的高电平。
在波形图上我们把波形分为两个阶段,第一个阶段是计数器 CNT 工作在递增模式的波
形,这个阶段我们又分为①和②两个阶段,第二个阶段是计数器 CNT 工作在递减模式的波
形,这个阶段我们又分为③和④两个阶段。要说中心对齐模式下的波形有什么特征的话,
那就是①和③阶段的时间相等,②和④阶段的时间相等。
中心对齐模式又分为中心对齐模式 1/2/3 三种,具体由寄存器 CR1 CMS[1:0] 配置。
具体的区别就是比较中断中断标志位 CCxIF 在何时置 1 :中心模式 1 CNT 递减计数的时
候置 1 ,中心对齐模式 2 CNT 递增计数时置 1 ,中心模式 3 CNT 递增和递减计数时都
1
二   定时器初始化结构体详解
在标准库函数头文件 stm32f4xx_tim.h 中对定时器外设建立了四个初始化结构体,分别
为 时 基 初 始 化 结 构 体 TIM_TimeBaseInitTypeDef 、 输 出 比 较 初 始 化 结 构 体
TIM_OCInitTypeDef 、输入捕获初始化结构体 TIM_ICInitTypeDef 和断路和死区初始化结构
TIM_BDTRInitTypeDef ,高级控制定时器可以用到所有初始化结构体,通用定时器不能
使用 TIM_BDTRInitTypeDef 结构体,基本定时器只能使用时基结构体。接下来我们具体讲
解下这四个结构体。
1. TIM_TimeBaseInitTypeDef
时 基 结 构 体 TIM_TimeBaseInitTypeDef 用 于 定 时 器 基 础 参 数 设 置 , 与
TIM_TimeBaseInit 函数配合使用完成配置。
代码清单 32-1 定时器基本初始化结构体
1 typedef struct {
2 uint16_t TIM_Prescaler; // 预分频器
3 uint16_t TIM_CounterMode; // 计数模式
4 uint32_t TIM_Period; // 定时器周期
5 uint16_t TIM_ClockDivision; // 时钟分频
6 uint8_t TIM_RepetitionCounter; // 重复计算器
7 } TIM_TimeBaseInitTypeDef;
(5) TIM_Prescaler :定时器预分频器设置,时钟源经该预分频器才是定时器计数时钟
CK_CNT ,它设定 PSC 寄存器的值。计算公式为:计数器时钟频率 (f CK_CNT ) 等于
f CK_PSC / (PSC[15:0] + 1) ,可实现 1 65536 分频。
(6) TIM_CounterMode :定时器计数方式,可设置为向上计数、向下计数以及中心对齐。
高级控制定时器允许选择任意一种。
(7) TIM_Period :定时器周期,实际就是设定自动重载寄存器 ARR 的值, ARR 为要装载
到实际自动重载寄存器(即影子寄存器)的值,可设置范围为 0 65535
(8) TIM_ClockDivision :时钟分频,设置定时器时钟 CK_INT 频率与死区发生器以及数字
滤波器采样时钟频率分频比。可以选择 1 2 4 分频。
(9) TIM_RepetitionCounter :重复计数器,只有 8 位,只存在于高级定时器。
2. TIM_OCInitTypeDef
输出比较结构体 TIM_OCInitTypeDef 用于输出比较模式,与 TIM_OCxInit 函数配合使
用完成指定定时器输出通道初始化配置。高级控制定时器有四个定时器通道,使用时都必
须单独设置。
代码清单 32-2 定时器比较输出初始化结构体
1 typedef struct {
2 uint16_t TIM_OCMode; // 比较输出模式
3 uint16_t TIM_OutputState; // 比较输出使能
4 uint16_t TIM_OutputNState; // 比较互补输出使能
5 uint32_t TIM_Pulse; // 脉冲宽度
6 uint16_t TIM_OCPolarity; // 输出极性
7 uint16_t TIM_OCNPolarity; // 互补输出极性
8 uint16_t TIM_OCIdleState; // 空闲状态下比较输出状态
9 uint16_t TIM_OCNIdleState; // 空闲状态下比较互补输出状态
10 } TIM_OCInitTypeDef;
(1) TIM_OCMode :比较输出模式选择,总共有八种,常用的为 PWM1/PWM2 。它设定
CCMRx 寄存器 OCxM[2:0] 位的值。
(2) TIM_OutputState :比较输出使能,决定最终的输出比较信号 OCx 是否通过外部引脚输
出。它设定 TIMx_CCER 寄存器 CCxE/CCxNE 位的值。
(3) TIM_OutputNState: 比较互补输出使能,决定 OCx 的互补信号 OCxN 是否通过外部引脚
输出。它设定 CCER 寄存器 CCxNE 位的值。
(4) TIM_Pulse :比较输出脉冲宽度,实际设定比较寄存器 CCR 的值,决定脉冲宽度。可
设置范围为 0 65535
(5) TIM_OCPolarity :比较输出极性,可选 OCx 为高电平有效或低电平有效。它决定着定
时器通道有效电平。它设定 CCER 寄存器的 CCxP 位的值。
(6) TIM_OCNPolarity :比较互补输出极性,可选 OCxN 为高电平有效或低电平有效。它
设定 TIMx_CCER 寄存器的 CCxNP 位的值。
(7) TIM_OCIdleState :空闲状态时通道输出电平设置,可选输出 1 或输出 0 ,即在空闲状
(BDTR_MOE 位为 0) 时,经过死区时间后定时器通道输出高电平或低电平。它设定
CR2 寄存器的 OISx 位的值。
(8) TIM_OCNIdleState :空闲状态时互补通道输出电平设置,可选输出 1 或输出 0 ,即在
空闲状态 (BDTR_MOE 位为 0) 时,经过死区时间后定时器互补通道输出高电平或低电
平,设定值必须与 TIM_OCIdleState 相反。它设定是 CR2 寄存器的 OISxN 位的值。
3. TIM_ICInitTypeDef
输入捕获结构体 TIM_ICInitTypeDef 用于输入捕获模式,与 TIM_ICInit 函数配合使用
完成定时器输入通道初始化配置。如果使用 PWM 输入模式需要与 TIM_PWMIConfig 函数
配合使用完成定时器输入通道初始化配置。
代码清单 32-3 定时器输入捕获初始化结构体
1 typedef struct {
2 uint16_t TIM_Channel; // 输入通道选择
3 uint16_t TIM_ICPolarity; // 输入捕获触发选择
4 uint16_t TIM_ICSelection; // 输入捕获选择
5 uint16_t TIM_ICPrescaler; // 输入捕获预分频器
6 uint16_t TIM_ICFilter; // 输入捕获滤波器
(1) TIM_Channel :捕获通道 ICx 选择,可选 TIM_Channel_1 TIM_Channel_2
TIM_Channel_3 TIM_Channel_4 四个通道。它设定 CCMRx 寄存器 CCxS 位 的值。
(2) TIM_ICPolarity :输入捕获边沿触发选择,可选上升沿触发、下降沿触发或边沿跳变触
发。它设定 CCER 寄存器 CCxP 位和 CCxNP 位的值。
(3) TIM_ICSelection :输入通道选择,捕获通道 ICx 的信号可来自三个输入通道,分别为
TIM_ICSelection_DirectTI TIM_ICSelection_IndirectTI TIM_ICSelection_TRC ,具
体的区别见图 32-15 。如果是普通的输入捕获, 4 个通道都可以使用,如果是 PWM
入则只能使用通道 1 和通道 2 。它设定 CCRMx 寄存器的 CCxS[1:0]位的值。 STM32-Project32:高级定时器TIM1/8功能框图寄存器固件库理解,PWM互补输出比较实验_第13张图片
(4) TIM_ICPrescaler :输入捕获通道预分频器,可设置 1 2 4 8 分频,它设定 CCMRx
寄存器的 ICxPSC[1:0] 位的值。如果需要捕获输入信号的每个有效边沿,则设置 1 分频
即可。
(5) TIM_ICFilter :输入捕获滤波器设置,可选设置 0x0 0x0F 。它设定 CCMRx 寄存器

ICxF[3:0]位的值。一般我们不使用滤波器,即设置为 0。

4. TIM_BDTRInitTypeDef
断路和死区结构体 TIM_BDTRInitTypeDef 用于断路和死区参数的设置,属于高级定时
器专用,用于配置断路时通道输出状态,以及死区时间。它与 TIM_BDTRConfig 函数配置
使用完成参数配置。这个结构体的成员只对应 BDTR 这个寄存器,有关成员的具体使用配
置请参考手册 BDTR 寄存器的详细描述。
代码清单 32-4 断路和死区初始化结构体
1 typedef struct {
2 uint16_t TIM_OSSRState; // 运行模式下的关闭状态选择
3 uint16_t TIM_OSSIState; // 空闲模式下的关闭状态选择
4 uint16_t TIM_LOCKLevel; // 锁定配置
5 uint16_t TIM_DeadTime; // 死区时间
6 uint16_t TIM_Break; // 断路输入使能控制
7 uint16_t TIM_BreakPolarity; // 断路输入极性
8 uint16_t TIM_AutomaticOutput; // 自动输出使能
9 } TIM_BDTRInitTypeDef;
(1) TIM_OSSRState :运行模式下的关闭状态选择,它设定 BDTR 寄存器 OSSR 位的值。
(2) TIM_OSSIState :空闲模式下的关闭状态选择,它设定 BDTR 寄存器 OSSI 位的值。
(3) TIM_LOCKLevel :锁定级别配置, BDTR 寄存器 LOCK[1:0] 位的值。
(4) TIM_DeadTime :配置死区发生器,定义死区持续时间,可选设置范围为 0x0 0xFF
它设定 BDTR 寄存器 DTG[7:0] 位的值。
(5) TIM_Break :断路输入功能选择,可选使能或禁止。它设定 BDTR 寄存器 BKE 位的值。
(6) TIM_BreakPolarity :断路输入通道 BRK 极性选择,可选高电平有效或低电平有效。它
设定 BDTR 寄存器 BKP 位的值。
(7) TIM_AutomaticOutput :自动输出使能,可选使能或禁止,它设定 BDTR 寄存器 AOE
位的值。

三 PWM互补输出实验
输出比较模式比较多,这里我们以 PWM 输出为例讲解,并通过示波器来观察波形。
实验中不仅在主输出通道输出波形,还在互补通道输出与主通道互补的的波形,并且添加
了断路和死区功能。
硬件设计
根据开发板引脚使用情况,并且参考 中定时器引脚信息 ,使用高级定时器
TIM1 的通道 1 及其互补通道作为本实验的波形输出通道,对应选择 PA8 PB13 引脚。将
示波器的两个输入通道分别与 PA8 PB13 引脚连接,用于观察波形,还有注意共地。
为增加断路功能,需要用到 TIM1_BKIN 引脚,这里选择 PB12 引脚。程序我们设置该
引脚为高电平有效,当 BKIN 引脚被置高低电平的时候,两路互补的 PWM 输出就被停止,
就好像是刹车一样。
32.6.2 软件设计
1. 编程要点
(1) 定时器用到的 GP IO 初始化
(2) 定时器时基结构体 TIM_TimeBaseInitTypeDef 初始化
(3) 定时器输出比较结构体 TIM_OCInitTypeDef 初始化
(4) 定时器刹车和死区结构体 TIM_BDTRInitTypeDef 初始化
#include "advancetime.h"



//先把TIM1的gpio进行初始化:推挽复用输出
static void ADVANCE_TIM_GPIO_Config(void) 
{
  GPIO_InitTypeDef GPIO_InitStructure;

  // 输出比较通道PA8初始化
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  GPIO_InitStructure.GPIO_Pin =   GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  // 输出比较通道互补通道PB13初始化
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_13;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  // 输出比较通道刹车通道 PB12 初始化
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  GPIO_InitStructure.GPIO_Pin =   GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_ResetBits(GPIOB,GPIO_Pin_12);// BKIN引脚默认先输出低电平	
}


//再配置定时器结构体成员初始化
static void ADVANCE_TIM_Mode_Config(void)
{
  
	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);// 开启定时器时钟,即内部时钟CK_INT=72M

/*--------------------时基结构体初始化:确定计数器时钟频率与周期-------------------------*/
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_TimeBaseStructure.TIM_Period=  (8-1);// 自动重装载ARR寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断
	TIM_TimeBaseStructure.TIM_Prescaler=  (9-1);	// 驱动CNT计数器的时钟 = Fck_int/(psc+1)  72/(8+1) = 8M   信号频率:(8-1+1)/8 = 1M 
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;// 时钟分频因子,不分频 ,配置死区时间时需要用到,随便配也可以 详见TIMxCR1寄存器8-9位		
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;		// 计数器计数模式,设置为向上计数	
	TIM_TimeBaseStructure.TIM_RepetitionCounter=0;// 重复计数器的值,没用到不用管	
	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);// 初始化定时器

	/*--------------------输出比较结构体初始化-------------------*/		
	TIM_OCInitTypeDef  TIM_OCInitStructure;//设置c99标准支持任意地方初始化这个变量
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;// 配置为PWM模式1:平时用它
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;	// 输出使能
	TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; 	// 互补输出使能
	TIM_OCInitStructure.TIM_Pulse = 4;// 设置占空比大小
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;// 输出通道电平极性配置
	TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;// 互补输出通道电平极性配置
	TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;// 输出通道空闲电平极性配置:当pwm用刹车时候会被禁止电平,这时候用这个set1电平
	TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;// 互补输出通道空闲电平极性配置
	TIM_OC1Init(TIM1, &TIM_OCInitStructure);
	TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);

	/*-------------------刹车和死区结构体初始化-------------------*/
	// 有关刹车和死区结构体的成员具体可参考BDTR寄存器的描述
	TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
  TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
  TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
  TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
	// 输出比较信号死区时间配置,具体如何计算可参考 BDTR:UTG[7:0]的描述
	// 这里配置的死区时间为152ns
  TIM_BDTRInitStructure.TIM_DeadTime = 11;//写入寄存器值11 即1011
  TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;
	// 当BKIN引脚检测到高电平的时候,输出比较信号被禁止,就好像是刹车一样
  TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
  TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
  TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
	
	TIM_Cmd(TIM1, ENABLE);	// 使能计数器
	TIM_CtrlPWMOutputs(TIM1, ENABLE);// 主输出使能,当使用的是通用定时器时,这句不需要
}

void ADVANCE_TIM_Init(void)
{
	ADVANCE_TIM_GPIO_Config();
	ADVANCE_TIM_Mode_Config();		
}

#include "stm32f10x.h"  
#include "led.h" 
#include "key.h"
#include "rcc.h"
#include "exti.h"
#include "systick.h"
#include "usart.h"
#include 
#include "basetime.h"
#include "advancetime.h"

//高级定时器1的通道1与互补通道输出1Mh 占空比50%的pwm,带刹车功能与死区时间。

int main(void)
{
	ADVANCE_TIM_Init();
	
	   while (1){
	 
 }	
}



你可能感兴趣的:(STM32裸板-基本外设开发,stm32)