TIM高级定时器(2)输出比较(互补输出)

1. 作用

输出比较:用以输出PWM信号或脉冲信号
TIM高级定时器(2)输出比较(互补输出)
输入捕获和输出比较的寄存器共用,具体看初始化时的配置
TIM高级定时器(2)输出比较(互补输出)

2.PWM模式

输出比较有8种模式,其中,只有PWM输出模式最常用。
PWM输出就是对外输出脉宽(即占空比)可调的方波信号,信号频率由自动重装寄存器ARR的值决定,占空比由比较寄存器CCR的值决定。(CCR既是捕获寄存器,也是比较寄存器,是哪一个,看TIM的初始化模式)
TIM高级定时器(2)输出比较(互补输出)
一般情况下使用PWM1模式,CNT递增,并配置高电平有效
PWM1模式,默认低电平,满足条件使得通道有效,跳变到高电平
PWM2模式,默认高电平,满足条件使得通道有效,跳变到低电平

3.带互补输出的PWM输出比较

只有通道1~3带互补输出,通道4无互补输出
带死区时间和刹车控制
选用通道CH1,CH1N,BKIN

PWM信号的频率为:
F=TIM_CLK/[(ARR+1)(PSC+1)]
PWM信号的占空比为:
占空比=CCR/(ARR+1)*100%
时基初始化结构体

typedef struct
{
  uint16_t TIM_Prescaler;        //分频因子    PSC                            72-1     即频率为1MHz,即1us    
  uint16_t TIM_CounterMode;      //计数模式,向上/向下(基本定时器可以不配置
                                 //TIM_CounterMode_Up|TIM_CounterMode_Down 
  uint16_t TIM_Period;           //自动重装载值 ARR                            1000-1   计数1000次,即1ms 
  uint16_t TIM_ClockDivision;    //外部输入时钟分频因子(基本定时器没有),只有使用死区时间时才使用,如果不使用,随便配置
  uint8_t TIM_RepetitionCounter; //重复计数器(高级定时器专属)       100,则每次重装载不触发中断,重装载100次以后才触发中断,即100ms
} TIM_TimeBaseInitTypeDef;       //时基初始化结构体

输出比较结构体

typedef struct
{
  uint16_t TIM_OCMode;        //PWM模式,TIM_OCMode_PWM1|TIM_OCMode_PWM2
  uint16_t TIM_OutputState;   //输出通道是否使能
  uint16_t TIM_OutputNState;  //互补通道是否使能
  uint16_t TIM_Pulse;         //CCR寄存器的值,占空比
  uint16_t TIM_OCPolarity;    //输出通道 高|低 电平有效
  uint16_t TIM_OCNPolarity;   //互补输出通道 高|低 电平有效
  uint16_t TIM_OCIdleState;   //空闲状态输出通道的电平
  uint16_t TIM_OCNIdleState;  //空闲状态互补输出通道的电平
} TIM_OCInitTypeDef;//输出比较结构体初始化

刹车和死区时间结构体

typedef struct
{

  uint16_t TIM_OSSRState;       //运行模式下“关闭状态”
  uint16_t TIM_OSSIState;        //空闲模式下“关闭状态”
  uint16_t TIM_LOCKLevel;      //锁定级别设置  
  uint16_t TIM_DeadTime;       //死区时间,参考数据手册 BDTR:UTG[7:0]描述
  uint16_t TIM_Break;          //刹车功能是否使能 
  uint16_t TIM_BreakPolarity;  //刹车输入 高/低 电平有效
  uint16_t TIM_AutomaticOutput;// 自动输出使能
} TIM_BDTRInitTypeDef;//刹车和死区结构体初始化
void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);//通道1 输出比较结构体初始化
void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);//通道1 是否允许自动重装载
void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState);//主输出使能
void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);//设置通道1 输出比较的极性(空闲状态下的极性)
void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);//设置通道1 互补输出的极性

4.PWM输出

tim.c

void PWM_IO_Config(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 ; //CH1
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13;//BKIN、CH1N
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_ResetBits(GPIOB,GPIO_Pin_12);//BKIN引脚默认先输出低电平
}
void PWM_Mode_Config(void)
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
	//初始化时基结构体
	TIM_TimeBaseStructure.TIM_Period = 7;  
	TIM_TimeBaseStructure.TIM_Prescaler = 8;
	//此处,要使PWM信号周期为1us,即频率为1Hz。
	//则根据(PSC+1)/72M为CNT计数器记一次数的时间,则(ARR+1)(PSC+1)/72M为一个PWM周期计数所需时间
	//则,72M/(ARR+1)(PSC+1)为PWM信号的频率,即(ARR+1)(PSC+1)=72,此时PWM频率为1MHz
	//PSC+1是官方规定,ARR+1是因为CNT从0开始计数
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;  //只有使用死区时间时才使用
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); 
	//初始化输出比较结构体
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;               //PWM1模式
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   //输出通道有效
	TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; //互补输出通道有效
	TIM_OCInitStructure.TIM_Pulse = 4;                              //占空比为4(周期为8,所以占空比为50%)  
	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_OCIdleState_Reset;	//空闲状态互补输出通道呈低电平
	
	TIM_OC1Init(TIM1, &TIM_OCInitStructure);    //TIM1使用通道OC1作为输出通道(也可以使用OC2、OC3)
	TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //允许TIM自动重装载
	
	//初始化刹车和死区结构体
	TIM_BDTRInitStructure.TIM_OSSRState=TIM_OSSRState_Enable;
	TIM_BDTRInitStructure.TIM_OSSIState=TIM_OSSIState_Enable;
	TIM_BDTRInitStructure.TIM_LOCKLevel=TIM_LOCKLevel_1;
	TIM_BDTRInitStructure.TIM_DeadTime=11;
	//由于	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;因此时钟为72HZ,所以死区时间为11/72M=152us;
	TIM_BDTRInitStructure.TIM_Break=TIM_Break_Enable;
	TIM_BDTRInitStructure.TIM_BreakPolarity=TIM_BreakPolarity_High;
	TIM_BDTRInitStructure.TIM_AutomaticOutput=TIM_AutomaticOutput_Enable;
	
	
	TIM_Cmd(TIM1,ENABLE); //	TIM计数器使能
	TIM_CtrlPWMOutputs(TIM1,ENABLE);//主输出使能,仅高级定时器才使用
}
void PWM_Init(void)
{
	PWM_IO_Config();
	PWM_Mode_Config();
}

主函数只要写上PWM_Init()函数即可。

示波器应该连接相应引脚才行。
刹车功能检测:BKIN引脚连接电源正极(TIM_BreakPolarity_High)即可,看图像TIM_OCIdleState_Set、TIM_OCIdleState_Reset是否正确

上一篇:对《模拟管道算法的一次实际应用》一文的思考和修改


下一篇:STM32F103标准库 旋转编码器测速和读取脉冲