目录

【PWM简介】

【F103C8T6  PWM资源】

【PWM输出模式】

【PWM周期、频率、占空比】

【demo · PWM_LED】

【demo · PWM_sg90】


【PWM简介】

        PWM(Pulse Width Modulation)就是对外输出脉宽(占空比)可调的方波信号,简称脉宽调制
        信号频率由自动重装寄存器ARR 的值、PSC、Tclk决定,占空比由比较寄存器CCR 的值决定

【F103C8T6  PWM资源】

        高级定时器(TIM1):7路
        通用定时器(
TIM2~TIM4):各4

【PWM输出模式】

        PWM模式1:
        
在向上计数时,一旦 CNT < CCRx 时输出为有效电平,否则为无效电平
        在向下计数时,一旦 CNT > CCRx 时输出为无效电平,否则为有效电平
        小结:
PWM模式1,无论是向上还是向下计数,当计数值小于比较值是输出有效电平
        
        PWM模式2:
        
在向上计数时,一旦 CNT < CCRx 时输出为无效电平,否则为有效电平
        在向下计数时,一旦 CNT > CCRx 时输出为有效电平,否则为无效电平
        小结:
PWM模式2,无论是向上还是向下计数,当计数值大于比较值是输出有效电平

【PWM周期、频率、占空比】

        PWM的周期 就是 定时器的溢出时间
        因为周期是完成一个动作所需的时间,此处动作为高电平到高电平,经过的时间恰为Tout

        

        PWM占空比是指高电平时间占整个周期时间的比例,公式= (高电平时间 / 周期时间) × 100% 
        占空比的具体公式受PWM模式、有效电平极性、计数方向的影响。在PWM模式1、有效电平为高电平、向上计数的条件下,占空比公式如下:
        Duty = CCR / (ARR+1) 
       
另外常用的另一个公式是Duty = (ARR-CRR+1/ (ARR+1) 


        ARR、PSC和Tclk共同决定了PWM的周期
        CRRx(捕获/比较寄存器值)决定了输出有效信号的时间

        示例:Tclk = 72M 、ARR (自动重装载的值)= 9999、PSC (预分频系数)= 7199
        Tpwm = ( (ARR + 1) * (PSC + 1) ) / Tclk = (7200*10000) / 72 000 000 = 1s

【PWM死区设置】

        死区时间(Dead Time)用于在互补PWM信号的跳边沿之间强制加入一段延迟,用于确保同一桥臂的上下两个功率管(如MOS管)不会同时导通,从而避免短路。

死区时间一般选用几百ns,计算公式如下:
                                        ​​​​​​​

        2.STM32F407的互补PWM输出带死区控制_break and dead time management-CSDN博客

【demo · PWM_LED】

        计算参数:假如频率为 2kHz ,则: PSC=71 ARR=499
        
        查看目标GPIO接到哪个定时器的哪一路:

        ①  STM32F103x8B数据手册/STM32F103产品手册
        ② STM32CubeMX可视化配置

        注意:不是所有GPIO都接到了定时器上,因PC13无法使用定时器,本demo采用PB8

Mode:PWM模式1或模式2
Pulse:占空比;对应捕获/比较寄存器2(TIMx_CCR2)中的CCR2[15:0]
auto-reload preload:自动重装载预装载,启用时ARR的修改会延迟到当前计数周期结束后生效(缓冲写入,避免竞争风险),禁用时ARR的值立即生效,可能打断当前计数周期,适用于紧急制动等需要零延时的场景。
Output compare preload:是输出比较寄存器(CCRx) 的缓冲机制,启用时新写入的CCRx值暂存于预装载寄存器,待下次更新事件(UEV)后生效。禁用时CCRx值立即生效
Fast Mode:针对输出比较(OC)功能的加速机制,用于强制立即更新比较寄存器(CCRx)的值,而无需等待定时器更新事件(UEV)
CH Polarity:有效电平;对应捕获/比较使能寄存器(TIMx_CCER)中的CC2P位。定义输出极性

模式 占空比更新表现 响应速度
Fast Mode启用 可能产生窄脉冲毛刺(若CNT≈CCRx时写入) 响应最快
Preload禁用 占空比在周期结束时跳变,但无毛刺 响应适中
Preload启用 占空比平滑过渡,无跳变或毛刺 响应最慢

关键代码:

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.02s20ms左右

        计算公式:

        例:            若周期为20ms,则 PSC=7199ARR=199

        计算方法:ARR+1 = 200 设CCRx为X,列比例式:以0度为例,0.5 / 20 = X / 200 , 得X=5

        角度表:     角度由占空比控制

                0.5  ms-------------0度;   2.5%   对应函数中 CCRx 5
                1.0  ms------------45度;  5.0%   对应函数中 CCRx 10
                1.5  ms------------90度;  7.5%    对应函数中 CCRx 15
                2.0  ms-----------135度; 10.0% 对应函数中 CCRx 20
                2.5  ms-----------180度; 12.5% 对应函数中 CCRx 25

        考虑到接线方便,本次使用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博客

【有趣的全彩LED | 编程】用STM32 HAL库让WS2812B为你所动 - 东小东 - 博客园

【STM32】硬件SPI+DMA驱动WS2812灯珠,基于HAL库_spi驱动ws2812-CSDN博客

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐