目录
【PWM简介】
PWM(Pulse Width Modulation)就是对外输出脉宽(占空比)可调的方波信号,简称脉宽调制
信号频率由自动重装寄存器ARR 的值决定,占空比由比较寄存器CCR 的值决定
【F103C8T6 PWM资源】
高级定时器(TIM1):7路
通用定时器(TIM2~TIM4):各4路
【PWM输出模式】
在向上计数时,一旦 CNT < CCRx 时输出为有效电平,否则为无效电平
在向下计数时,一旦 CNT > CCRx 时输出为无效电平,否则为有效电平
小结: PWM模式1,无论是向上还是向下计数,当计数值小于重装载值是输出有效电平
在向上计数时,一旦 CNT < CCRx 时输出为无效电平,否则为有效电平
在向下计数时,一旦 CNT > CCRx 时输出为有效电平,否则为无效电平
小结: PWM模式2,无论是向上还是向下计数,当计数值大于重装载值是输出有效电平
【PWM周期、频率、占空比】
PWM的周期 就是 定时器的溢出时间
因为周期是完成一个动作所需的时间,此处动作为高电平到高电平,经过的时间恰为Tout
PWM的占空比由TIMx_CCRx寄存器决定
预分频系数决定了PWM的时钟速度
ARR(自动重装载值)的大小决定了PWM的周期
CRRx(捕获/比较寄存器值)决定了输出有效信号的时间
示例:Tclk = 72M 、ARR (自动重装载的值)= 9999、PSC (预分频系数)= 7199
Tpwm = ( (ARR + 1) * (PSC + 1) ) / Tclk = (7200*10000) / 72 000 000 = 1s
【demo · PWM_LED】
① STM32F103x8B数据手册/STM32F103产品手册
注意:不是所有GPIO都接到了定时器上,因PC13无法使用定时器,本demo采用PB8
Mode:PWM模式1或模式2
Pulse:占空比;对应捕获/比较寄存器2(TIMx_CCR2)中的CCR2[15:0]
Output compare preload:输出自动比较;对应捕获/比较模式寄存器1中的OC2PE位。输出比较2预装载使能
Fast Mode:PWM脉冲快速输出;对应捕获/比较模式寄存器1中的OC2FE位。输出比较2快速使能
CH Polarity:有效电平;对应捕获/比较使能寄存器(TIMx_CCER)中的CC2P位。定义输出极性
关键代码:
HAL_TIM_PWM_Start (&htim4,TIM_CHANNEL_3); //开启PWM输出
//定时器X和通道X,实际使用的哪个定时器哪个通道,就用哪个参数
__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_3,pwmVal); //设置默认的占空比值
int main(void)
{
/* USER CODE BEGIN 1 */
uint16_t pwmVal = 0; // 调整占空比
uint8_t dir = 1; // 改变方向,1:越来越亮,0:越来越暗
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM4_Init();
HAL_TIM_PWM_Start (&htim4,TIM_CHANNEL_3);
while (1)
{
if(dir)
pwmVal++;
else
pwmVal--;
if(pwmVal > 500)
dir = 0;
if(pwmVal == 0)
dir = 1;
__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_3,pwmVal);
HAL_Delay(2);
}
}
int main(void)
{
/* USER CODE BEGIN 1 */
uint16_t pwmVal = 0; // 调整占空比
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM4_Init();
HAL_TIM_PWM_Start (&htim4,TIM_CHANNEL_3);
while (1)
{
while (pwmVal < 500)
{
pwmVal++;
__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, pwmVal); //修改比较值,修改占空比
HAL_Delay(1);
}
while (pwmVal)
{
pwmVal--;
__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, pwmVal); //修改比较值,修改占空比
HAL_Delay(1);
}
HAL_Delay(200);
}
【demo · PWM_sg90】
频率: PWM波的频率不能太高,大约50Hz,即周期=1/频率=1/50=0.02s,20ms左右
计算公式:
例: 若周期为20ms,则 PSC=7199,ARR=199
计算方法:ARR+1 = 200 设CCRx为X,列比例式:以0度为例,0.5 / 20 = X / 200 , 得X=5
角度表: 角度由占空比控制
考虑到接线方便,本次使用PB9
注意:可以不开中断
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM4_Init();
HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_4);
while (1)
{
HAL_Delay(1000);
__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_4,5);
HAL_Delay(1000);
__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_4,10);
HAL_Delay(1000);
__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_4,15);
HAL_Delay(1000);
__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_4,20);
HAL_Delay(1000);
__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_4,25);
}
}
demo现象:舵机逐步旋转0°,45°,90°,135°,180°,0°
参考:STM32 HAL库 STM32CubeMX -- PWM(呼吸灯)_hal pwm_Dir_xr的博客-CSDN博客
【demo·PWM_WS2812B】
WS2812B彩灯 STM32HAL库开发:PWM+DMA(stm32f103c8t6)_ws2812编程实例-CSDN博客
STM32 HAL库 PWM+DMA 驱动WS2812B彩灯(STM32F030F4P6)_stm32 dma pwm-CSDN博客