SPAN>
高级控制定时器时基单元功能包括四个寄存器,分别是
计数器寄存器(CNT)、
预分频器寄存器(PSC)、
自动重载寄存器(ARR)和
重复计数器寄存器(RCR)。其中重复计数器
RCR是高级定时器独有,通用和基本定时器没有。前面三个寄存器都是 16 位有效, TIMx_RCR寄存器是 8 位有效。
2.输入捕获功能框图
输入捕获可以对输入的信号的上升沿,下降沿或者双边沿进行捕获,常用的有测量输入信号的脉宽和测量 PWM
输入信号的频率和占空比这两种。
输入捕获的大概的原理就是,当捕获到信号的跳变沿的时候,把计数器 CNT 的值锁存到捕获寄存器 CCR 中,把前后两次捕获到的 CCR
寄存器中的值相减,就可以算出脉宽或零死角玩转
者频率。
如果捕获的脉宽的时间长度超过你的捕获定时器的周期,就会发生溢出,这个我们需要做额外的处理。
3.输出比较功能框图
输出比较就是通过定时器的外部引脚对外输出控制信号,有冻结、将通道 X(x=1,2,3,4)设置为匹配时输出有效电平、将通道 X
设置为匹配时输出无效电平、翻转、强制变为无效电平、强制变为有效电平、 PWM1 和 PWM2 这八种模式,具体使用哪种模式由寄存器
CCMRx 的位 OCxM[2:0]配置。其中 PWM 模式是输出比较中的特例,使用的也最多。
二,输出比较应用
PWM就是对外输出脉宽(即占空比)可调的方波信号,信号频率由自动重装载寄存器ARR的值决定,信号占空比由比较寄存器CCR的值决定。
1. TIM_TimeBaseInitTypeDef
时基结构体 TIM_TimeBaseInitTypeDef用于定时器基础参数设置,与
TIM_TimeBaseInit函数配合使用完成配置。
代码清单 33-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;
2. TIM_OCInitTypeDef
输出比较结构体 TIM_OCInitTypeDef 用于输出比较模式,与 TIM_OCxInit
函数配合使用完成指定定时器输出通道初始化配置。高级控制定时器有四个定时器通道,使用时都必须单独设置。
代码清单 33-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;
3. TIM_ICInitTypeDef
输入捕获结构体 TIM_ICInitTypeDef 用于输入捕获模式,与 TIM_ICInit
函数配合使用完成定时器输入通道初始化配置。如果使用 PWM 输入模式需要与 TIM_PWMIConfig
函数配合使用完成定时器输入通道初始化配置。
代码清单 33-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;
|
|
// 输入捕获滤波器
|
7 } TIM_ICInitTypeDef;
4. TIM_BDTRInitTypeDef
断路和死区结构体 TIM_BDTRInitTypeDef
用于断路和死区参数的设置,属于高级定时器专用,用于配置断路时通道输出状态,以及死区时间。
它与 TIM_BDTRConfig
函数配置使用完成参数配置。 这个结构体的成员只对应 BDTR 这个寄存器,有关成员的具体使用配置请参考手册 BDTR
寄存器的详细描述。
代码清单 33-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;
三,PWM 互补输出实验
1. 编程要点
(1) 定时器用到的 GP IO 初始化
(2) 定时器时基结构体 TIM_TimeBaseInitTypeDef 初始化
(3) 定时器输出比较结构体 TIM_OCInitTypeDef 初始化
(4) 定时器刹车和死区结构体 TIM_BDTRInitTypeDef 初始化
2.Advance_timer.c源文件程序代码
#include 'Advance_timer.h'
static void ADVANCE_TIM_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//输出比较通道GPIO初始化
RCC_APB2PeriphClockCmd(ADVANCE_TIM_CH1_GPIO_CLK,ENABLE);
GPIO_InitStructure.GPIO_Pin = ADVANCE_TIM_CH1_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(ADVANCE_TIM_CH1_PORT, &GPIO_InitStructure);
//输出比较通道的互补通道GPIO初始化
RCC_APB2PeriphClockCmd(ADVANCE_TIM_CH1N_GPIO_CLK,ENABLE);
GPIO_InitStructure.GPIO_Pin = ADVANCE_TIM_CH1N_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(ADVANCE_TIM_CH1N_PORT, &GPIO_InitStructure);
//输出比较通道的刹车通道GPIO初始化
RCC_APB2PeriphClockCmd(ADVANCE_TIM_BKIN_GPIO_CLK,ENABLE);
GPIO_InitStructure.GPIO_Pin = ADVANCE_TIM_BKIN_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(ADVANCE_TIM_BKIN_PORT, &GPIO_InitStructure);
//BKIN引脚默认输出低电平
GPIO_ResetBits(ADVANCE_TIM_BKIN_PORT,ADVANCE_TIM_BKIN_PIN);
}
static void ADVANCE_TIM_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
//设置中断组为0
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
//设置中断来源
NVIC_InitStructure.NVIC_IRQChannel = ADVANCE_TIM_IRQ;
//设置抢占优先级
NVIC_InitStructure.NVIC_IRQChannelPreemptionPrio
rity =
0;
//设置子优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
// ARR :自动重装载寄存器的值
// CLK_cnt:计数器的时钟,等于 Fck_int /
(psc+1) = 72M/(psc+1)
// PWM 信号的周期 T = ARR * (1/CLK_cnt)
= ARR*(PSC+1) / 72M
// 占空比P=CCR/(ARR+1)
static void ADVANCE_TIM_MODE_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef
TIM_OCInitStructure;
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
//开启定时器时钟,即内部Fck_int =
72M
ADVANCE_TIM_APBxClock_FUN(ADVANCE_TIM_CLK,ENABLE);
//自动重装载寄存器的值,累计TIM_Period+1个计数后产生一个更新或中断
TIM_TimeBaseStructure.TIM_Period = ADVANCE_TIM_PERIOD;
//驱动CNT计数器的时钟 =
Fck_int / (psc+1) = 72M/(psc+1)
TIM_TimeBaseStructure.TIM_Prescaler = ADVANCE_TIM_PSC;
//时钟分频因子,配置死区时间时用到
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
//计数器计数模式,配置为向上计数
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(ADVANCE_TIM, & TIM_TimeBaseStructure);
//
配置为PWM模式1
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
// 输出使能
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
// 互补输出使能
TIM_OCInitStructure.TIM_OutputNState =
TIM_OutputNState_Enable;
// 设置占空比大小
TIM_OCInitStructure.TIM_Pulse = ADVANCE_TIM_PULSE;
// 输出通道电平极性配置
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
// 互补输出通道电平极性配置
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
// 输出通道空闲电平极性配置
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
// 互补输出通道空闲电平极性配置
TIM_OCInitStructure.TIM_OCNIdleState =
TIM_OCNIdleState_Reset;
TIM_OC1Init(ADVANCE_TIM, &TIM_OCInitStructure);
//使能TIMx在CCR1上的预装载寄存器
TIM_OC1PreloadConfig(ADVANCE_TIM, TIM_OCPreload_Enable);
//
有关刹车和死区结构体的成员具体可参考BDTR寄存器的描述
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;
TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;
//
当BKIN引脚检测到高电平的时候,输出比较信号被禁止,就好像是刹车一样
TIM_BDTRInitStructure.TIM_BreakPolarity =
TIM_BreakPolarity_High;
TIM_BDTRInitStructure.TIM_AutomaticOutput =
TIM_AutomaticOutput_Enable;
TIM_BDTRConfig(ADVANCE_TIM, &TIM_BDTRInitStructure);
// 使能计数器
TIM_Cmd(ADVANCE_TIM, ENABLE);
// 主输出使能,当使用的是通用定时器时,这句不需要
TIM_CtrlPWMOutputs(ADVANCE_TIM, ENABLE);
}
void ADVANCE_TIM_Init(void)
{
ADVANCE_TIM_GPIO_Config();
ADVANCE_TIM_NVIC_Config();
ADVANCE_TIM_MODE_Config();
}