034 - STM32学习笔记 - TIM定时器(三) - 高级定时器2
哥们最近搞了个公众号,后面的文章会同步在公众号上发布,各位看官帮忙点点关注,后续一些其他方面的学习内容也会在公众号上发布,有兴趣的可以看看哟,扫描下方二维码(或搜索“自动化小白菜”)关注,感谢各位大佬对小弟的支持和指导!
上节内容将高级控制定时器内容都过了一遍,这节讲一下输入捕获和输出比较的应用。
一、输入捕获
输入捕获常用在脉冲跳变沿事件测量或者PWM输入测量。
1、测量脉宽或者频率
测量频率:当捕获通道TIx上出现上升沿时,发生第一次捕获,计数器CNT的值会被锁存到捕获寄存器CCR中,而且还会进入捕获中断,再中断服务子程序中记录一次捕获,并且把捕获寄存器中的值读取到value1中,当出现第二次上升沿时,发生第二次捕获,计数器CNT的值再次被锁存到捕获寄存器CCR中,并再次进入捕获中断,再捕获中断中,读取捕获寄存器的值到value3中,并清除捕获记录标志,如此就可以利用value3和value1的擦之计算信号周期(频率)。
测量脉宽:当捕获通道TIx上出现上升沿时,发生第一次捕获,计数器CNT的值会被锁存到捕获寄存器CCR中,而且还会进入捕获中断,再中断服务子程序中记录一次捕获,并且把捕获寄存器中的值读取到value1中。然后捕获边沿变更为下降沿捕获,当下降沿到来时,发生第二次捕获,计数器将CNT的值再次锁存到捕获寄存器CCR中,并再次进入捕获中断,再中断中将捕获寄存器的值读取到value3中,并清除捕获标志,然后再将捕获标志变为上升沿捕获。
测量脉宽过程中,需要不停的切换捕获边沿的极性,如果测量的脉宽时间比较长,定时器会发生溢出,并产生更新中断,可以到中断中对溢出进行记录处理。
2、PWM输入模式
除了向上面的方式去测量脉宽和频率的方法外,还可以使用PWM输入模式测量,只是上面的办法只需要一个捕获寄存器就可以,但是PWM输入模式需要一次占用两个捕获寄存器。
当使用PWM输入模式时,输入通道TIx会占用两个捕获通道ICx,上图中以TI1为例,信号被分为两路,分别为TI1FP1和TI1FP2,这两路中分别为周期和占空比,具体那一路是周期,那一路是占空比,需要在程序上设置哪一路作为触发输入,触发输入的就是周期,另外一路就是占空比。再出发输入的一路上还需要设置捕获极性是上升沿还是下降沿,配置好后,另外一路会自动配置为相反的极性捕获。
当使用PWM输入模式时,需要将从模式控制器配置为复位模式(SMCR的SMS[2:0]设置为100),该设置可在当启动触发信号开始进行捕获时,同时把计数器CNT复位清零。
PWM信号由通道TI1进入,配置TI1FP1为触发信号,上升沿开始捕获,当上升沿到达时,IC1和IC2同时捕获,CNT计数器清零,到下降沿时IC2捕获,此时计数器CNT的值被所存到捕获寄存器CCR2中,到了下一个下降沿时,IC1捕获,计数器CNT的值被锁存到捕获寄存器CCR1中,此时CCR2测量的数据就是脉宽,CCR1测量的为周期。
相比于之前说的方法,从软件实现层面上来说,PWM输入模式测量脉宽和周期会更容易一些,但是需要占用两个捕获寄存器。
二、输出比较
输出比较模式一共由8种模式,这个在上节由说过,使用哪种模式具体由寄存器CCMRx的OCxM[2:0]进行配置。这届使用常用的PWM模式,其他几种模式后面找机会再学习。
1、PWM输出模式
PWM输出就是对外输出脉宽(即占空比)可调的方波信号,信号频率由自动重装寄存器ARR的值决定,占空比由比较寄存器CCR的值决定。
PWM分为两种模式,PWM1和PWM2,两者差别看一下下表格:
模式 | 计数器CNT计算方式 | 说明 |
---|---|---|
PWM1 | 递增 | CNT<CCR,通道CH为有效,否则为无效 |
递减 | CNT>CCR,通道CH为无效,否则为有效 | |
PWM2 | 递增 | CNT<CCR,通道CH为无效,否则为有效 |
递减 | CNT>CCR,通道CH为有效,否则为无效 |
下面主要使用PWM1模式,以及暑期CNT计数的方向不同还分为边沿对齐模式和中心对齐模式。OWM信号主要都是用来控制电机,一般的电机控制用的都是边沿对其模式,FOC电机一般用中心对齐模式。
1.1、PWM边沿对齐模式
在递增计数模式下,计数器从0计数到自动重载值,然后重新从0还是计数并生成计数器上溢事件。
在边沿对齐模式下,计数器CNT只工作在一种模式,递增或者递减模式。这里我们以CNT工作在递增模式为例,ARR=8,CCR=4,CNT从0开始计数,当CNT<CCR时,OCxREF为有效的高电平,与此同时比较中断寄存器CCxIF置位。当CCR=<CNT<=ARR时,OCxREF为无效的低电平,然后CNT又从0开始计数,并生成计数器上溢事件,以此循环往复。
1.2、PWM中心对齐模式
在中心对齐模式下,CNT时工作在递增/递减模式下,开始时,计数器CNT从0来时计数到ARR-1,生成计数器上溢事件,然后从ARR值开始递减计数到1,生成计数器下溢事件,之后从0开始从新计数。
上图中ARR=8,CCR=4。第一阶段计数器CNT工作在递增模式下,从0开始计数,当CNT<CCR时,OCxREF为有效的高电平,当CCR=<CNT<ARR时,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。
三、定时器初始化结构体详解
定时器的四个初始化结构体在基本定时器那节已经学习过关于时基初始化结构体TIM_TimeBaseInitTypeDef
结构体的内容了,这节再看一下其他几个结构体
- 输出比较初始化结构体
TIM_OCInitTypeDef
- 输入捕获初始化结构体
TIM_ICInitTypeDef
- 断路和死区初始化结构体
TIM_BDTRInitTypeDef
在高级控制定时器中,这四个结构体都可以用到,通用定时器不使用TIM_BDTRInitTypeDef
结构体,基本定时器只是用时基结构体。初始化结构体成员用于设定定时器工作环境参数,并由定时器相应初始化配置函数调用。
1、输出比较初始化结构体TIM_OCInitTypeDef
输出比较初始化结构体TIM_OCInitTypeDef
用于输出比较模式,与TIM_OCxInit
函数配合使用完成指定定时器输出通道初始化配置。高级控制定时器由四个定时器通道,使用的时候必须都单独设置一下。
typedef struct {
uint16_t TIM_OCMode; // 比较输出模式
uint16_t TIM_OutputState; // 比较输出使能
uint16_t TIM_OutputNState; // 比较互补输出使能
uint32_t TIM_Pulse; // 脉冲宽度
uint16_t TIM_OCPolarity; // 输出极性
uint16_t TIM_OCNPolarity; // 互补输出极性
uint16_t TIM_OCIdleState; // 空闲状态下比较输出状态
uint16_t TIM_OCNIdleState; // 空闲状态下比较互补输出状态
}TIM_OCInitTypeDef;
参数解析:
TIM_OCMode:比较输出模式选择,在前面有提到过共有八种,常用的为PWM1/PWM2。通过设定CCMRx中OCxM[2:0]来进行配置。配置模式可以参考用户手册查询一下。
TIM_OutputState:比较输出使能,决定最终的输出比较信号OCx是否通过外部引脚输出,该成员设定TIMx_CCER的CCxE/CCxNE位的值。
TIM_OutputNState:比较互补输出使能,决定 OCx 的互补信号 OCxN 是否通过外部引脚输出。该成员设定CCER的CCxNE位的值。
TIM_Pulse:比较输出脉冲宽度,实际设定比较寄存器CCR的值,决定脉冲宽度。可设置范围为0至65535。
TIM_OCPolarity:比较输出极性,可选OCx为高电平有效或低电平有效。它决定着定时器通道有效电平。该成员设定CCER寄存器的CCxP位的值。
TIM_OCNPolarity:比较互补输出极性,可选OCxN为高电平有效或低电平有效。该成员设定 TIMx_CCER 寄存器的CCxNP位的值。
TIM_OCIdleState:空闲状态时通道输出电平设置,可选输出1或输出0,即在空闲状态(BDTR_MOE位为0)时,经过死区时间后定时器通道输出高电平或低电平。该成员设定CR2寄存器的OISx位的值。
TIM_OCNIdleState:空闲状态时互补通道输出电平设置,可选输出1或输出0,即在空闲状态(BDTR_MOE位为 0)时,经过死区时间后定时器互补通道输出高电平或低电平,设定值必须与TIM_OCIdleState
相反。该成员设定是CR2寄存器的OISxN位的值。
2、输入捕获初始化结构体TIM_ICInitTypeDef
输入捕获结构体TIM_ICInitTypeDef
用于输入捕获模式,与TIM_ICInit
函数配合使用完成定时器输入通道初始化配置。如果使用 PWM 输入模式需要与TIM_PWMIConfig
函数配合使用完成定时器输入通道初始化配置。
typedef struct {
uint16_t TIM_Channel; // 输入通道选择
uint16_t TIM_ICPolarity; // 输入捕获触发选择
uint16_t TIM_ICSelection; // 输入捕获选择
uint16_t TIM_ICPrescaler; // 输入捕获预分频器
uint16_t TIM_ICFilter; // 输入捕获滤波器
}TIM_ICInitTypeDef;
TIM_Channel:捕获通道ICx选择,可选TIM_Channel_1、TIM_Channel_2、TIM_Channel_3或TIM_Channel_4四个通道。它设定CCMRx寄存器CCxS位的值。
TIM_ICPolarity:输入捕获边沿触发选择,可选上升沿触发、下降沿触发或边沿跳变触发。它设定CCER寄存器CCxP位和CCxNP位的值。
TIM_ICSelection:输入通道选择,捕获通道ICx的信号可来自三个输入通道,分别为TIM_ICSelection_DirectTI
、 TIM_ICSelection_IndirectTI
或TIM_ICSelection_TRC
。它设定CCRMx寄存器的CCxS[1:0]位的值。
TIM_ICPrescaler:输入捕获通道预分频器,可设置1、2、4、8 分频,它设定CCMRx寄存器的ICxPSC[1:0]位的值。如果需要捕获输入信号的每个有效边沿,则设置1分频即可。
TIM_ICFilter:输入捕获滤波器设置,可选设置0x0至0x0F。它设定CCMRx寄存器ICxF[3:0]位的值。一般我们不使用滤波器,即设置为0。
3、断路和死区初始化结构体TIM_BDTRInitTypeDef
断路和死区结构体TIM_BDTRInitTypeDef
用于断路和死区参数的设置,属于高级定时器专用,用于配置断路时通道输出状态,以及死区时间。它与TIM_BDTRConfig
函数配置使用完成参数配置。 这个结构体的成员只对应BDTR这个寄存器,有关成员的具体使用配置请参考手册BDTR寄存器的详细描述。
typedef struct{
uint16_t TIM_OSSRState; // 运行模式下的关闭状态选择
uint16_t TIM_OSSIState; // 空闲模式下的关闭状态选择
uint16_t TIM_LOCKLevel; // 锁定配置
uint16_t TIM_DeadTime; // 死区时间
uint16_t TIM_Break; // 断路输入使能控制
uint16_t TIM_BreakPolarity; // 断路输入极性
uint16_t TIM_AutomaticOutput; // 自动输出使能
}TIM_BDTRInitTypeDef;
TIM_OSSRState:运行模式下的关闭状态选择,它设定BDTR寄存器OSSR位的值。
TIM_OSSIState:空闲模式下的关闭状态选择,它设定BDTR寄存器OSSI位的值。
TIM_LOCKLevel:锁定级别配置,BDTR寄存器LOCK[1:0]位的值。
TIM_DeadTime:配置死区发生器,定义死区持续时间,可选设置范围为0x0至0xFF。它设定BDTR寄存器DTG[7:0]位的值。
TIM_Break:断路输入功能选择,可选使能或禁止。它设定BDTR寄存器BKE位的值。
TIM_BreakPolarity:断路输入通道BRK极性选择,可选高电平有效或低电平有效。它设定BDTR寄存器BKP位的值。
TIM_AutomaticOutput:自动输出使能,可选使能或禁止,它设定BDTR寄存器AOE位的值。
TIM_Break:断路输入功能选择,可选使能或禁止。它设定BDTR寄存器BKE位的值。
TIM_BreakPolarity:断路输入通道BRK极性选择,可选高电平有效或低电平有效。它设定BDTR寄存器BKP位的值。
TIM_AutomaticOutput:自动输出使能,可选使能或禁止,它设定BDTR寄存器AOE位的值。