ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-03-07 20:34:06  阅读:765  来源: 互联网

标签:输出 定时器 TIM uint16 GPIO PWM 通道


1. 作用

输出比较:用以输出PWM信号或脉冲信号
在这里插入图片描述
输入捕获和输出比较的寄存器共用,具体看初始化时的配置
在这里插入图片描述

2.PWM模式

输出比较有8种模式,其中,只有PWM输出模式最常用。
PWM输出就是对外输出脉宽(即占空比)可调的方波信号,信号频率由自动重装寄存器ARR的值决定,占空比由比较寄存器CCR的值决定。(CCR既是捕获寄存器,也是比较寄存器,是哪一个,看TIM的初始化模式)
在这里插入图片描述
一般情况下使用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是否正确

标签:输出,定时器,TIM,uint16,GPIO,PWM,通道
来源: https://blog.csdn.net/qq_42424228/article/details/114445290

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有