概念+代码
一、输出比较
OC(Output Compare)输出比较
输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形
每个高级定时器和通用定时器都拥有4个输出比较通道
高级定时器的前3个通道额外拥有死区生成和互补输出的功能
二、PWM原理
PWM(Pulse Width Modulation)脉冲宽度调制
在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速等领域
PWM参数:
频率 = 1 / TS
占空比 = TON / TS(高电平占总时间的比率),如占空比为50%,高电平=5V,低电平=0V,则模拟电压为2.5V.
分辨率 = 占空比变化步距,即精度。
PWM基本结构:
当CNT计数小于CCR时,置高电平,当CNT大于CCR时,置低电平,当CNT=ARR时触发事件,计数值归零,又开始新的一轮周期,这样就可以不断的输出PWM信号。因此,可以看出,CCR值的设置与占空比密切相关。
PWM频率: Freq = CK_PSC / (PSC + 1) / (ARR + 1)
CK_PSC是预分频频率,一般是系统频率。PSC是分频系数,ARR是自动重装载寄存器最大计数值。
PWM占空比: Duty = CCR / (ARR + 1)
CCR是输出比较输出PWM的一个限定比较值。
PWM分辨率: Reso = 1 / (ARR + 1)
三、输出PWM
以正点原子PWM实验为例:使用TIM3的CH2通道,在PB5端口输出PWM波。
1.PWM初始化
void TIM3_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外设和AFIO复用功能模块时钟
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射 TIM3_CH2->PB5
//设置该引脚为复用输出功能,输出TIM3 CH2的PWM脉冲波形 GPIOB.5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //TIM_CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
//初始化TIM3
//溢出时间time=(arr+1)*(psc+1)/144000000
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
//初始化TIM3 Channel2 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OCInitStructure.TIM_Pulse = 50;
TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC2
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器
TIM_Cmd(TIM3, ENABLE); //使能TIM3
}
这里最重要的是:
1.该函数的参数为 arr 和 psc,分别表示自动重载寄存器的值和预分频系数。根据这两个参数,可以计算出 PWM 的频率和占空比。
2.在函数中,首先使能了定时器 TIM3 和 GPIOB 外设的时钟,以及 GPIO 的复用功能模块时钟。然后,通过 GPIO_PinRemapConfig 函数将 TIM3_CH2 信号映射到 GPIOB.5 引脚上。
这里有一个问题:为什么要配置AFIO复用功能模块时钟?如下图:
可以看到:PB5的默认复用功能是I2C1_SMBA/ SPI3_MOSI,I2S3_SD,而其重定义功能才是TIM3_CH2,所以不能简单直接的复用它,必须要配置重映射。
3.通过 TIM_OCInitTypeDef 结构体对 TIM3 的通道 2 进行初始化,选择定时器模式为 PWM2,使能比较输出,设置输出极性为高电平,设置占空比为 50%。
最后,通过 TIM_OC2PreloadConfig 函数使能 TIM3 在 CCR2 上的预装载寄存器,并通过TIM_Cmd 函数使能 TIM3。
2.输出指定频率PWM波
TIM3_Int_Init(5999,0);
//TIM3_PWM_Init(5999,0);//不分频。PWM 频率=96000/(5999+1)=16KHz
参考PWM频率: Freq = CK_PSC / (PSC + 1) / (ARR + 1),这里我的芯片系统频率是96MHz,对应CK_PSC,ARR是计数值,PSC是预分频值,代入公式,得:频率F=16000Hz=16KHz。
因此,这个代码输出了一个频率固定为16KHz的PWM波。文章来源:https://www.toymoban.com/news/detail-766633.html
3.输出占空比可变的PWM波
TIM3_Int_Init(5999,0);
u16 pulse=400;
TIM_SetCompare2(TIM3,pulse);
对于定时器 TIM3,CCR2 寄存器的取值范围是 0 到 ARR,即比较寄存器的值不能大于自动重载寄存器的值。因此,在设置占空比时,输入的占空比值需要通过计算转换为相应的比较寄存器的值。也就是说,pulse的值只能在0-5999之间设置,并且注意,这里调用的函数是TIM_SetCompare2()函数,是比较寄存器CCR2对应通道2,如果是ch3,则要调用TIM_SetCompare3()函数。如此,便实现了修改PWM波的占空比。文章来源地址https://www.toymoban.com/news/detail-766633.html
到了这里,关于STM32(7)-定时器输出PWM的原理分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!