1、配置
计数模式分为向上计数或者向下计数
自动装载值即ARR,即PWM周期
计数比较器CCRx,即占空比
极性,出差有效是高电平还是低电平
PWM 模式1
PWM模式2
输出电平与输出极性、PWM模式有关
向上计数:
如果PWM mode1 极性H ;按照上面红线输出
如果PWM mode1 极性L ;按照上面绿线输出
如果PWM mode2 极性H ;按照上面绿线输出
如果PWM mode2 极性L ;按照上面红线输出
直接生成代码
2、代码
bsp_pwm.c
#include "bsp_pwm.h"
/*
*********************************************************************************************************
* 函 数 名: PWM_TIM3_CH4_EN
* 功能说明: 使能PWM
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void PWM_TIM3_CH4_EN(void)
{
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);
}
/*
*********************************************************************************************************
* 函 数 名: bsp_SetPWM_ARR
* 功能说明: 设置PWM频率 即ARR自动重装载值
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_SetPWM_ARR(uint16_t _ARR)
{
__HAL_TIM_SET_AUTORELOAD(&htim3,_ARR-1);
// TIM3->ARR = _ARR-1;
}
/*
*********************************************************************************************************
* 函 数 名: bsp_InitPWM
* 功能说明: 使能PWM
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_InitPWM(void)
{
PWM_TIM3_CH4_EN();
bsp_SetPWM_ARR(_TIM3_ARR);//周期
bsp_SetPWM_CCRx(500);//占空比
}
/*
*********************************************************************************************************
* 函 数 名: bsp_SetPWM_CCRx
* 功能说明: 设置占空比 即ARR
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_SetPWM_CCRx(uint16_t duty)
{
if(duty <= _TIM3_ARR)
{
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, duty);
// TIM3->CCR4 = dutyCycle;
}
}
bsp_pwm.h
#ifndef _BSP_PWM_H
#define _BSP_PWM_H
#include "stm32f4xx_hal.h"
#include "main.h"
#include "pub_gpio.h"
#include "tim.h"
/*PWM周期 单位us 84M/84 Prescaler*/
#define _TIM3_ARR 1000
void bsp_InitPWM(void);
void bsp_SetPWM_CCRx(uint16_t duty);
void bsp_BLE_Control(uint8_t repeat);
#endif
void motor_task (void * arg)
{
osStatus_t status;
bsp_InitPWM(); /*pwm PB1*/
while(1)
{
#ifdef BLN_ //呼吸灯
uint16_t pwmValue;
while (pwmValue < _TIM3_ARR)
{
pwmValue ++;
bsp_SetPWM_CCRx(pwmValue);
osDelay(1);
}
while (pwmValue > _TIM3_ARR/2)
{
pwmValue --;
bsp_SetPWM_CCRx(pwmValue);
osDelay(1);
}
#endif
osThreadYield();
}
}
3、原理
脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽
度的控制,PWM 原理如图
如图为向上计数:
定时器重装载值为ARR,比较值CCRx
t时刻对计数器值和比较值进行比较
如果计数器值小于CCRx值,输出低电平
如果计数器值大于CCRx值,输出高电平
PWM的一个周期
定时器从0开始向上计数
当0-t1段,定时器计数器TIMx_CNT值小于CCRx值,输出低电平
t1-t2段,定时器计数器TIMx_CNT值大于CCRx值,输出高电平
当TIMx_CNT值达到ARR时,定时器溢出,重新向上计数…循环此过程
至此一个PWM周期完成
影响因素
ARR : 决定PWM周期(在时钟频率一定的情况下,当前为默认内部时钟CK_INT)
CCRx : 决定PWM占空比(高低电平所占整个周期比例)