STM32·HAL库开发(七)PWM脉宽调制——案例:LED呼吸灯+sg90舵机

本文介绍了STM32F103C8T6单片机的PWM资源、工作模式、周期、频率和占空比设置,以及如何通过PWM控制LED和舵机的案例,展示了如何使用HAL库进行配置和编程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

【PWM简介】

【F103C8T6  PWM资源】

【PWM输出模式】

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

【demo · PWM_LED】

【demo · PWM_sg90】


【PWM简介】

        PWM(Pulse Width Modulation)就是对外输出脉宽(占空比)可调的方波信号,简称脉宽调制

        信号频率由自动重装寄存器ARR 的值决定,占空比由比较寄存器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的占空比 Duty = CCR (ARR+1) 


        预分频系数决定了PWM的时钟速度 
        ARR(自动重装载值)的大小决定了PWM的周期
        CRRx(捕获/比较寄存器值)决定了输出有效信号的时间

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

【PWM死区设置】

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

【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]
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.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的博客-优快云博客

【demo·PWM_WS2812B】

WS2812B彩灯 STM32HAL库开发:PWM+DMA(stm32f103c8t6)_ws2812编程实例-优快云博客

STM32 HAL库 PWM+DMA 驱动WS2812B彩灯(STM32F030F4P6)_stm32 dma pwm-优快云博客

https://www.cnblogs.com/dongxiaodong/p/14362196.html

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

<think>好的,我需要帮助用户使用STM32F103C8T6和HAL配置PWM控制舵机。首先,我得回忆一下STM32PWM配置步骤和相关知识。根据用户提供的引用资料,特别是引用3和4,配置PWM需要设置定时器的预分频系数和重装载值,以生成正确的周期。舵机通常需要50Hz的信号,周期20ms,所以关键是如何计算这两个参数。 用户提到使用HAL,所以应该通过STM32CubeMX来配置定时器。首先选择正确的定时器,比如TIM4,然后启用PWM通道。接着设置预分频器(Prescaler)和计数器周期(Counter Period)。根据引用3,如果时钟频率是36MHz,预分频设为360-1,计数器周期设为2000-1,可以得到20ms的周期。但要注意不同定时器的时钟源可能不同,需要确认时钟树配置是否正确。 接下来是占空比的设置。舵机的角度由高电平时间决定,通常是0.5ms到2.5ms对应0°到180°。例如,在20ms周期下,0.5ms占空比对应的脉冲宽度是0.5/20=2.5%,所以比较值应该设为计数器周期的2.5%。如果计数器周期是2000,则0°对应50,90°对应150,180°对应250。不过引用5中提到使用__HAL_TIM_SET_COMPARE设置50对应0°,150对应90°,这说明他们的计数器周期可能是2000,因为50是2000的2.5%(但2000的2.5%是50,正确)。所以用户需要根据实际计算的计数器周期来调整比较值。 还需要注意GPIO的配置是否正确,PWM输出通道对应的引脚是否映射正确。例如,TIM4的通道1可能对应某个特定GPIO,用户需要根据硬件连接选择正确的引脚。 可能的问题包括时钟配置错误导致PWM频率不对,或者比较值计算错误导致舵机角度不准。需要确保所有参数正确,并在代码中正确调用HAL_TIM_PWM_Start函数启动PWM,以及使用__HAL_TIM_SET_COMPARE来动态调整占空比。 最后,生成代码后,用户可能需要调试,用示波器检查实际输出的PWM信号是否符合预期,或者通过串口打印调试信息确认配置是否正确。</think>### STM32F103C8T6 HAL配置PWM驱动舵机步骤 #### 1. **CubeMX配置定时器** - **选择定时器**:选择支持PWM输出的定时器(如TIM2/TIM3/TIM4等),根据硬件连接选择对应通道的GPIO引脚[^3][^5]。 - **配置时钟源**:确认定时器时钟频率(例如TIM4时钟为36MHz)[^3]。 - **设置预分频(Prescaler)和计数器周期(Counter Period)**: - **目标周期**:舵机PWM信号周期为20ms(50Hz),计算公式: $$ \text{周期} = \frac{(\text{Prescaler} +1) \times (\text{Counter Period} +1)}{\text{定时器时钟频率}} $$ 例如:若定时器时钟为36MHz,设置`Prescaler=360-1`,`Counter Period=2000-1`,则周期为: $$ \frac{360 \times 2000}{36,000,000} = 0.02s = 20ms $$ [^4] #### 2. **配置PWM通道参数** - **Pulse(占空比初值)**:设置初始脉冲宽度(例如90°对应1.5ms,计算值为`150`)。 - **极性(Polarity)**:选择高电平有效(High)。 #### 3. **生成代码并初始化** - 生成代码后,在`main()`函数中启动PWM输出: ```c HAL_TIM_PWM_Start(&htimx, TIM_CHANNEL_y); //替换x为定时器编号,y为通道号 ``` #### 4. **动态调整占空比** - 使用HAL函数设置比较值(对应角度): ```c // 设置0°(0.5ms高电平) __HAL_TIM_SET_COMPARE(&htimx, TIM_CHANNEL_y, 50); //50 = (0.5ms/20ms) * 2000 // 设置90°(1.5ms高电平) __HAL_TIM_SET_COMPARE(&htimx, TIM_CHANNEL_y, 150); // 设置180°(2.5ms高电平) __HAL_TIM_SET_COMPARE(&htimx, TIM_CHANNEL_y, 250); ``` #### 5. **验证与调试** - 用示波器测量输出引脚波形,确认周期为20ms且高电平时间符合预期。 - 若舵机不响应,检查GPIO复用功能是否启用或接线是否正确。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值