目录
实验1:外部时钟源模式1,TI1作为时基单元的时钟,频率为1khz。
实验2:外部时钟源模式2 ,ETR作为时基单元的时钟输入,频率为1khz。
实验3.2 pwm输入模式实验:选择定时器2,输入1khz的方波,不断改变方波的占空比,可以计算出方波的占空比和周期。
实验4.1:输出比较模式:定时器2的通道2和通道1分别产生不同占空比和频率的PWM波。 通道1:1khz、50%占空比。通道2:10khz,20%占空比。
实验4.2:pwm模式:生成1khz,占空比为50%的pwm波
1.stm32通用定时器介绍
通用定时器除了基础定时器的功能外,比如定时器中断。增加了输入捕获、输出比较、PWM生成、编码器接口等功能
1. 通用定时器中有16位和32位的计数器,比如TIM2和TIM5就是32位的计数器。
2. STM32F407VET6有10个通用定时器,分别是TIM2 - TIM5 、 TIM9 - TIM14。
3. 基础定时器的计数模式只有向上计数,通用定时器的计数模式有向上、向下、中心对齐计数
4. 和基础定时器不同,通用定时器的时钟源有四个:
4.1 内部时钟:CK_INT
4.2 外部时钟源模式1 :外部输入引脚:TIx
4.3 外部时钟源模式2 : 外部触发输入: ETR,F4仅适用于 TIM2、TIM3 和 TIM4
4.4 内部触发输入 :ITRx ,使用一个定时器作为另一个定时器的预分频器
这些需要看寄存器和通用定时器的框图来理解。
外部时钟源模式1:外部输入引脚:TIx
TI2对应框图:
计数器可在选定的输入信号上出 现上升沿或下降沿时计数
要想实现TI2输入上升沿计数,过程如下:通过在 TIMx_CCMR1 寄存器中写入 CC2S=“01”来配置通道 2 为输入 。 通过在 TIMx_CCMR1 寄存器中写入 IC2F[3:0] 位来配置输入滤波时间(也可以不滤波。通过在 TIMx_CCER 寄存器中写入 CC2P=0 和 CC2NP=0 来选择上升沿极性。通过在 TIMx_SMCR 寄存器中写入 SMS=111,使定时器在外部时钟模式 1 下工作。通过在 TIMx_SMCR 寄存器中写入 TS=110 来选择 TI2 作为输入源。通过在 TIMx_CR1 寄存器中写入 CEN=1 来使能计数器。具体查看手册--404页
简单来说:
TIMx_CH2 ---->TI2---->滤波器--->极性选择--->TI2FP2作为输入源--->TRGI--->CK_PSC.
时序图:
当 TI2 出现上升沿时,计数器便会计数一次并且 TIF 标志置 1。TI2 的上升沿与实际计数器时钟之间的延迟是由于 TI2 输入的重新同步电路引起的。
外部时钟源模式2 :外部触发输入: ETR
ETR框图:
计数器可在外部触发输入 ETR 出现上升沿或下降沿时计数
要使递增计数器在 ETR 每出现 2 个上升沿时计数。步骤如下:
在 TIMx_SMCR 寄存器中写入 ETF[3:0]=0000不使用滤波器。在 TIMx_SMCR 寄存器中写入 ETPS[1:0]=01 来设置预分频器。TIMx_SMCR 寄存器中写入 ETP=0 来选择 ETR 引脚的上升沿检测。在 TIMx_SMCR 寄存器中写入 ECE=1 来使能外部时钟模式 2。TIMx_CR1 寄存器中写入 CEN=1 来使能计数器。具体查看手册405页。
简单来说:
ETR--->极性选择--->分频器--->滤波选择--->ETRF--->CK_PSC.
时序图:
ETR 每出现 2 个上升沿,计数器计数一次。 ETR 的上升沿与实际计数器时钟之间的延迟是由于 ETRP 信号的重新同步电路引起的。
补充:
定时器的主从模式:
主模式:就是定时器的TRGO(触发输出信号)作为输出
从模式:从模式是TRGI(触发输入信号)作为从模式控制器的输入:ETR、TRC、TI1FP1、TI2FP2都可以作为触发输入。
1.复位模式:当触发输入信号产生变化时,计数器及其预分频器可重新初始化。
例如:TI1 输入上出现上升沿时,递增计数器清零。计数器使用内部时钟计数,然后正常运转,直到出现 TI1 上升沿。当 TI1 出现上升沿时,计数器清零,然后重新从 0 开始计数。同时,触发标志(TIMx_SR 寄存器中的 TIF 位)置 1, 使能中断或 DMA 后,还可发送中断或 DMA 请求。
2. 门控模式:输入信号的电平可用来使能计数器
例如:递增计数器仅在 TI1 输入为低电平时计数。只要 TI1 为低电平,计数器就开始根据内部时钟计数,直到 TI1 变为高电平时停止计数。计 数器启动或停止时,TIMx_SR 寄存器中的 TIF 标志都会置 1。
3. 触发模式:所选输入上发生某一事件时可以启动计数器
例如:TI2 输入上出现上升沿时,递增计数器启动:当 TI2 出现上升沿时,计数器开始根据内部时钟计数,并且 TIF 标志置 1。
5. 捕获比较通道介绍:
每个捕获/比较通道均围绕一个捕获/比较寄存器(包括一个影子寄存器)、一个捕获输入阶 段(数字滤波、多路复用和预分频器)和一个输出阶段(比较器和输出控制)构建而成(可以看总框图)。
输入阶段:(以通道1为例)
对TIx 输入进行采样,生成一个滤波后的信号 TIxF。然后,带有极性选择功能的边沿检测器生成一个信号 (TIxFPx),该信号可用作从模式控制器的触发输入(就是上面的外部时钟源模式1),也可用作捕获命令,经过预分频后进入捕获寄存器。
捕获/比较主电路:(通道1为例)
捕获/比较模块由一个预装载寄存器和一个影子寄存器组成。始终可通过读写操作访问预装载寄存器 。
在捕获模式下,捕获实际发生在影子寄存器中,然后将影子寄存器的内容复制到预装载寄存器中。
在比较模式下,预装载寄存器的内容将复制到影子寄存器中,然后将影子寄存器的内容与计 数器进行比较
输出阶段:(以通道1为例)
6.输入捕获模式:
示例:通过TI1 输入出现上升沿时将计数器的值捕获到 TIMx_CCR1:
首先,TIMx_CCMRx寄存器是捕获/比较的模式寄存器,通道匹配、滤波、预分频都是在这个寄存器中控制。TIMx_CCER 寄存器是捕获/比较的使能寄存器,主要是对极性的控制和使能通道。TIMx_CCRx寄存器是数据寄存器,可读可写。具体看数据手册。
步骤:
1.TIMx_CCR1寄存器 必须连接到 TI1 输入。所以TIMx_CCMR1 寄存器中的 CC1S 位写入 01。
2.对输入信号的滤波时间编程(TIMx_CCMRx 寄存器中的 ICxF 位进行编程)。比如以fDTS频率(定时器时钟频率的倍数)进行采样,在检测到TI1的上升沿后,再检测到连续8 个高电平后,确认上升沿触发。就是向 TIMx_CCMR1 寄存器中的 IC1F 位写入 0011。具体看手册407,寄存器位置434.
3.TIMx_CCER 寄存器中的 CC1P 位和 CC1NP 位写入 0,选择 TI1 通道的有效转换边沿。
4.对输入预分频器进行编程。在本例中,我们希望每次有效转换时都执行捕获操作,因此 需要禁止预分频器(向 TIMx_CCMR1 寄存器中的 IC1PS 位写入 00)
5.通过将 TIMx_CCER 寄存器中的 CC1E 位置 1,允许将计数器的值捕获到捕获寄存器中。
6.如果需要,可通过将 TIMx_DIER 寄存器中的 CC1IE 位置 1 来使能相关中断请求,并且/ 或者通过将该寄存器中的 CC1DE 位置 1 来使能 DMA 请求。
简单来说:
就是检测输入信号的上升沿,检测到上升沿后,触发捕获事件,将此时计数器的值给影子寄存器,然后再将影子寄存器的值赋值给捕获/比较寄存器,然后我们就可以软件读出寄存器的值了。
原理:
该图片来自 :
(stm32f103学习总结)—输入捕获模式 - 北极星! - 博客园 (cnblogs.com)https://www.cnblogs.com/zhjblogs/p/12673427.html通过这个图片就一目了然了,外部输入上升沿时,CCRx1的值存储的就是定时器计数器的值。中间从t1时刻到t2时刻可能触发了N次定时器更新,然后极性方式改为下降沿触发,t2时刻对应的CCRx2存储的也是从0开始的计数值。如果想要获取t1到t2的时间,则可以这样
[(ARR+1-CCRx1)+ (N * (ARR+1)) + CCRx2 ] * (1/CK_INT)
ARR+1:是因为自动重装载寄存器的系数是0-65535,而计数值是65536,要的是计数值。
CK_INT:以内部时钟为例,就是内部时钟分频后的时钟频率。
N: 这个N是触发定时器更新的次数,想要获取N,开启定时器中断即可。
6.1 pwm输入模式(输入捕获模式的特例)
pwm输入模式是两个 ICx 信号被映射至同一个 TIx 输入。这两个 ICx 信号在边沿处有效,但极性相反。选择两个 TIxFP 信号之一作为触发输入(就是外部时钟源模式1),并将从模式控制器配置为复位模式(触发后,计数器复位,重新开始计数)
实现步骤:
1.选择 TIMx_CCR1 的有效输入:向 TIMx_CCMR1 寄存器中的 CC1S 位写入 01(选择 TI1)。
2.选择 TI1FP1 的有效极性(用于 TIMx_CCR1 中的捕获和计数器清零):向 CC1P 位 和 CC1NP 位写入“0”(上升沿有效)
3.选择 TIMx_CCR2 的有效输入:向 TIMx_CCMR1 寄存器中的 CC2S 写入 10(选择 TI1)。
4. 选择 TI1FP2 的有效极性(用于 TIMx_CCR2 中的捕获):向 CC2P 位和 CC2NP 位写 入“1”(下降沿有效)
5.选择有效触发输入:向 TIMx_SMCR 寄存器中的 TS 位写入 101(选择 TI1FP1)
6.将从模式控制器配置为复位模式:向 TIMx_SMCR 寄存器中的 SMS 位写入 100。
7.使能捕获:向 TIMx_CCER 寄存器中的 CC1E 位和 CC2E 位写入“1”。
简单来说:
就是TI1经过滤波和边沿检测后得到TI1FP1(上升沿)和TI1FP2(下降沿),分别进入IC1和IC2,到达边沿检测条件后触发捕获。其中TI1FP1可以触发从模式控制器配置为复位模式。
原理:
TI1上升沿时,CCR1捕获计数器的值,同时触发输入配置从模式控制器为复位模式,计数器的值被清零。 这样获取的CCR1值就是一个pwm周期的计数值。然后TI1下降沿时,CCR2捕获计数器值,计数器不清零(因为选择的TI1FP1作为触发输入),捕获到的计数值就是pwm高电平的计数值。这样就可以获得pwm的周期和占空比了。周期:CCR1 /CK_INT 占空比: CCR2/CCR1。
7.强制输出模式:
强制输出模式可直接由软件将每个输出比较 信号(OCxREF 和 OCx)强制设置为有效电平或无效电平,而无需考虑输出比较寄存器和 计数器之间的任何比较结果。
步骤:要将输出比较信号 (OCXREF/OCx) 强制设置为有效电平,只需向相应 TIMx_CCMRx 寄存器 中的 OCxM 位写入 101。ocxref 进而强制设置为高电平(OCxREF 始终为高电平有效), 同时 OCx 获取 CCxP 极性位的相反值。例如:CCxP=0(OCx 高电平有效)则 OCx 强制设置为高电平
无论如何,TIMx_CCRx 影子寄存器与计数器之间的比较仍会执行,而且允许将标志置 1。 因此可发送相应的中断和 DMA 请求。
简单来说:就是通过寄存器控制OC1ref和OC1的值。
8.输出比较模式
输出比较模式是由TIMx_CCMRx 寄存器 中的 OCxM 位来控制:冻结(不影响输出)、输出高电平、输出低电平、翻转电平、强制高电平、强制低电平、pwm模式1、pwm模式2。同时TIMx_CCER 寄存器中的 CCxP 位控制输出极性。TIMx_SR 寄存器中的 CCxIF 位可以将中断状态寄存器中的标志置 1。TIMx_DIER 寄存器中的 CCXIE 位)置 1,将生成中断。TIMx_DIER 寄存器的 CCxDE 位,TIMx_CR2 寄存器的 CCDS 位,用来选择 DMA 请求)置 1,将发送 DMA 请求。
注意:使用 TIMx_CCMRx 寄存器中的 OCxPE 位,可将 TIMx_CCRx 寄存器配置为带或不带预装 载寄存器。 不带则直接写入CCRx寄存器,带则等待更新后写入CCR寄存器。
在输出比较模式下,更新事件 UEV 对 ocxref 和 OCx 输出毫无影响。同步的精度可以达到计 数器的一个计数周期。
比如:输出比较,翻转OC1:
步骤:
1.选择计数器时钟(内部、外部、预分频器)一般用外部HSE。
2.在 TIMx_ARR (自动重装载)和 TIMx_CCRx(计数器)寄存器中写入所需数据,用来比较数据。
3.如果要生成中断和/或 DMA 请求,将 TIMx_DIER寄存器的CCxIE 位和/或 CCxDE 位置 1
4.选择输出模式。例如,当 CNT 与 CCRx 匹配、未使用预装载 CCRx 并且 OCx 使能且为 高电平有效时,必须写入 OCxM=011(翻转)、OCxPE=0(不使用预装载)、CCxP=0(OC1高电平有效)和 CCxE=1(OC1配置为输出) 来翻转 OCx 输出引脚。
5.通过将 TIMx_CR1 寄存器中的 CEN 位置 1 来使能计数器。
原理框图:
CNT的值与CCR1的值匹配时(003A),OC1REF发生电平翻转, 如果开启了中断,此时也会触发中断。 由于没有使用预装载。所以直接修改CCR1的计数值。直接进行下一次的电平翻转。
这样是不是就可以产生不同周期的方波了。
注意:输出比较模式可以方便的调节每一路PWM波的频率,可以输出四路频率不同,占空比不同的PWM。但是PWM模式如果想要调节PWM波的频率,那么就只能重新设置预分频系数或者自动重装载寄存器ARR,并且输出的四路PWM频率必定一致,所以还是输出比较模式更灵活。
9. PWM模式:
1. 脉冲宽度调制模式可以生成一个信号,该信号频率由 TIMx_ARR 寄存器值决定,其占空比则 由 TIMx_CCRx 寄存器值决定。
2. 通过向 TIMx_CCMRx 寄存器中的 OCxM 位写入 110(PWM 模式 1)或 111(PWM 模式 2),可以独立选择各通道(每个 OCx 输出对应一个 PWM)的 PWM 模式。
3. PWM模式1:在递增计数模式下,只要 TIMx_CNT<TIMx_CCR1,通道 1 便为 无效状态 (OC1REF=0),否则为有效状态 (OC1REF=1)。在递减计数模式下,只要TIMx_CNT>TIMx_CCR1,通道 1 便为 无效状态 (OC1REF=0),否则为有效状态 (OC1REF=1)
PWM模式2:在递增计数模式下,只要 TIMx_CNT<TIMx_CCR1,通道 1 便为 有效状态,否则为无效状态。在递减计数模式下,只要 TIMx_CNT>TIMx_CCR1,通道 1 便为 有效状态,否则为无效状态。
4. 在 PWM 模式(1 或 2)下,TIMx_CNT 始终与 TIMx_CCRx 进行比较,以确定是 TIMx_CCRx <= TIMx_CNT 还是 TIMx_CNT<= TIMx_CCRx(取决于计数器计数方向)。
根据 TIMx_CR1 寄存器中的 CMS 位状态,定时器能够产生边沿对齐模式或中心对齐模式的 PWM 信号:
边沿对齐模式:
递增计数配置:以 PWM 模式 1 为例。只要 TIMx_CNT < TIMx_CCRx,PWM 参考信号 OCxREF 便为 高电平,否则为低电平。如果 TIMx_CCRx 中的比较值大于自动重载值(TIMx_ARR 中), 则 OCxREF 保持为“1”。如果比较值为 0,则 OCxREF 保持为“0”。
递减计数配置 : 在 PWM 模式 1 下,只要 TIMx_CNT>TIMx_CCRx,参考信号 ocxref 便为低电平,否则为高 电平。如果 TIMx_CCRx 中的比较值大于 TIMx_ARR 中的自动重载值,则 ocxref 保持为 “1”。此模式下不可能产生 0% 的 PWM 波形。
简单来说就是:
PWM信号的周期频率由ARR决定(CK_CNT = CK_INT/PSC/(ARR+1))。PWM信号的占空比由CCRx来决定。在边沿对齐模式下选择PWM模式1或者2,选择递增计数还是递减计数。然后计数器和CCRx进行比较。根据不同结果输出不同的电平。
PWM 中心对齐模式:
根据 TIMx_CR1 寄存器中CMS 位的配置,可以在计数器递增计数、递减计数 或同时递增和递减计数时将比较标志置 1。TIMx_CR1 寄存器中的方向位 (DIR) 由硬件更 新,不得通过软件更改。
注意:
1. 启动中心对齐模式时将使用当前的递增/递减计数配置。这意味着计数器将根据写入 TIMx_CR1 寄存器中 DIR 位的值进行递增或递减计数。此外,不得同时通过软件修改 DIR 和 CMS 位。
2. 不建议在运行中心对齐模式时对计数器执行写操作,否则将发生意想不到的结果:
如果写入计数器中的值大于自动重载值 (TIMx_CNT>TIMx_ARR),计数方向不会 更新。例如,如果计数器之前递增计数,则继续递增计数。
如果向计数器写入 0 或 TIMx_ARR 的值,计数方向会更新,但不生成更新事件 UEV。
3. 使用中心对齐模式最为保险的方法是:在启动计数器前通过软件生成更新(将 TIMx_EGR 寄存器中的 UG 位置 1),并且不要在计数器运行过程中对其执行写操作。
简单来说就是:
PWM信号的周期频率由ARR决定(CK_CNT = CK_INT/PSC/ARR)。PWM信号的占空比由CCRx来决定。在中心对齐模式下选择PWM模式1或者2。先进行递增计数然后再递减计数。中间计数器和CCRx进行比较。根据不同结果输出不同的电平。
10. 编码器接口模式:
待补充:..
2. 通用定时器实验:
实验1:外部时钟源模式1,TI1作为时基单元的时钟,频率为1khz。
cubemx配置:选择定时器2(通用定时器)作为实验对象
在tim.c中编写一个更新中断:
就可以实现led灯的1s闪烁了。
实验2:外部时钟源模式2 ,ETR作为时基单元的时钟输入,频率为1khz。
cubemx配置:使用定时器2
代码和实验1相同:最后的效果也是一样的。
实验3.1:输入捕获模式:选择定时器2,TI1输入1khz的方波,上升沿触发捕获,内部时钟84MHZ进行84预分频得到定时器频率为1Mhz,自动重装载为65536.定时器的更新频率也是1khz。计算出方波的高电平时间。
思路:捕获到第一个上升沿后,将计数器清零。然后改为下降沿触发捕获,读取此时的捕获比较器的值。此时分为两种情况:1.没有发生定时器溢出,直接获取的值就是t2,t2就是高电平的时间。2.定时器发生了溢出,溢出次数N由更新中断获取,此时高电平的时间就是N*65535+t2.
cubemx配置:
代码:
以上就是所有代码,主要使用了两个中断,一个更新中断,一个IC中断,实现一直读取方波的高电平计数值。
打开Keil5的调试模式,TI1引脚输入50%占空比的1khz方波,查看high_digital_time变量。
16进制转换为10进制就是499,这里差了一个计数值,一会儿500.一会儿499。影响不是很大。
以500个计数值来算,500 * 1us = 0.5ms,对应1khz的1ms,正好是50%的占空比。
实验3.2 pwm输入模式实验:选择定时器2,输入1khz的方波,不断改变方波的占空比,可以计算出方波的占空比和周期。
cubemx配置:
这里注意通道2是作为间接输入,因为没用通道2作引脚,也不需要。
生成代码后:
编写一下代码:
定义两个变量
开启两个通道的中断,开第二个通道中断是为了捕获下降沿:TIFP2的极性是下降沿通过,进入IC2,打开通道二的中断就可以获取CCR2的值了。
1.pwm_period获取的是上升沿时的CCR1寄存器的值。就是对应pwm周期的值。因为定时器的频率为84MHZ/(PSC+1) = 1MHZ,对应周期1us, pwm_period的单位也是us,得到的就是周期。换算成ms就是pwm_period/1000;
2.pwm_duty获取的是占空比,用下降沿获取的CCR2的值 * 100 / pwm_period 获得。
打开keil5的调试模式查看结果是否一致。
根据16进制结果,pwm_period = 1000.对应的周期就是1ms。符合结果,因为输入的是1khz的方波。pwm_duty = 50.占空比是50.符合结果。
实验4.1:输出比较模式:定时器2的通道2和通道1分别产生不同占空比和频率的PWM波。 通道1:1khz、50%占空比。通道2:10khz,20%占空比。
输出比较模式中,最常用的就是翻转电平。
cubemx配置:
除此之外:
开启中断。
编写代码:
实验结果:
通道1:
通道2:
符合实验结果。
这样生成一串不同频率的方波也可以实现了。
注意:其他通道是可以使用输入捕获的。
实验4.2:pwm模式:生成1khz,占空比为50%的pwm波
cubemx配置
代码编写:
只需要在初始化的时候,启动一下pwm和设置一下ccr1的值就好。
注意:在pwm模式下也是可以开启其他通道的输出比较和输入捕获的。只不过PSC的值和ARR的值固定了。
实验5:编码器接口模式:
待补充...