CubeMX配置STM32F103PWM连续频率输出

要求:

输出2-573Hz频率,输出频率步长小于1Hz

一、CubeMX配置

auto-reload preload在下个周期加载ARR

Output compare preload 在下个周期加载CCR

二、 程序

1.启动PWM输出

HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);

2.根据频率调整PSC、ARR、CCR

/**
  * @brief  设置高精度PWM输出
  * @param  htim: 定时器句柄
  * @param  freq_hz: 目标频率(2.0~573.0Hz)
  * @param  duty_ratio: 占空比(0.0~1.0)
  * @retval 无
  */
void Set_PWM_Precision(TIM_HandleTypeDef *htim, float freq_hz) 
{
    uint32_t arr, psc, ccr;
		float duty_ratio = 0.5;
//    float calc_freq;
    
    // 参数安全检查
    if(freq_hz < 2.0f) freq_hz = 2.0f;
    if(freq_hz > 573.0f) freq_hz = 573.0f;
    if(duty_ratio < 0.0f) duty_ratio = 0.0f;
    if(duty_ratio > 1.0f) duty_ratio = 1.0f;

    // 自动选择最优ARR值
    if(freq_hz <= 300.1f)
		{
        // 低频模式
        psc = 720-1;  // ARR+1=720
        arr = (uint32_t)(1e5/freq_hz) - 1;
        ccr = (uint32_t)((arr + 1) >> 1);
    }
    else
		{
        // 高频模式
        psc = 72-1;  // ARR+1=1200
        arr = (uint32_t)(1e6/freq_hz) - 1;
        ccr = (uint32_t)((arr + 1) >> 1);
    }
		
    // 参数限幅保护
    if(psc > 65535) psc = 65535;
    if(psc < 1) psc = 1;
		
		
    // 更新定时器配置
		
    __HAL_TIM_SET_PRESCALER(htim, psc);
    __HAL_TIM_SET_AUTORELOAD(htim, arr);
    __HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_1, ccr);
		
//		if(old != psc)
//		{
//			htim->Instance->EGR |= 1;
//		}
		
    // 调试输出(可选)
//		printf("%d,%0.3f\r\n",psc,AS5600_info.PWM_out);
//    calc_freq = 72000000.0f/((psc+1)*(arr+1));
//    printf("Set %.1fHz: ARR=%lu, PSC=%lu, Actual=%.3fHz\n", 
//           freq_hz, arr, psc, calc_freq);
}

3.连续输出

		for(int16_t a = 2;a<573;a++)
		{
			Set_PWM_Precision(&htim2,a);
			HAL_Delay(500);
		}

三、备注

1、注意点

1、若auto-reload preload配置为Enable,则ARR数据的修改发生在更新事件发生时;配置为Disable,则ARR数据的修改会立即影响TIMx_ARR的影子寄存器。

2、若Output compare preload配置为Enable,则CCR数据的修改发生在更新事件发生时;配置为Disable,则CCR数据的修改会立即影响TIMx_CCR的影子寄存器。

3、当需要同时修改PSC和ARR时,需要将两者使能,即将上一个周期发送完成后,更新事件触发,使两个影子寄存器同时更新,避免因两个影子寄存器更新不同步造成的问题。

2、定时器知识拓展

1、stm32的定时器中有4个带影子特性的寄存器组:TIMx_PSC(分频寄存器)、TIMx_ARR(自动重装载寄存器)、TIMx_CCR(捕获寄存器)、TIMx_RCR(重复计数寄存器)。

2、以上4个寄存器组分别由影子寄存器和预装载寄存器组成,影子寄存器是真正起作用的控制寄存器,但用户访问不到它。预装载寄存器是用户可以访问的,它为实际影子寄存器准备数据或指令。

3、TIMx_ARR、TIMx_CCR有预装载使能控制位。TIMx_PSC、TIMx_RCR不带预装载使能控制位,这两者影子寄存器的预装载功能始终开启。

4、当开启预装载功能时,此时影子寄存器的数据更新必须且只能通过更新事件(在TIMx_EGR寄存器中(通过软件方式或者使用从模式控制器)设置UG位也同样可以产生一个更
新事件。)实现从预装载寄存器到影子寄存器的数据拷贝;当关闭预装载功能时,用户修改预装载寄存器的数据会立即拷贝进影子寄存器。

<think>好的,用户想用STM32CubeMXSTM32F103上生成PWM波形。首先我需要回忆一下相关的配置步骤。根据引用中的信息,比如引用[1]和[2]都提到了Cube MX创建工程和PWM模式配置。首先,用户需要选择正确的定时器,因为STM32PWM通常通过定时器的PWM模式生成。例如,引用[2]提到使用HAL_TIM_PWM_Start函数来初始化通道,所以配置定时器并启用相应的通道是关键。 接下来,用户需要确定使用哪个定时器和哪个引脚。不同的定时器有不同的通道和引脚映射,比如引用[3]中使用了TIM1,而引用[2]用了PB8和PB9对应的通道3和4。因此,在CubeMX中选择正确的定时器,并配置对应的引脚为PWM输出模式是第一步。 然后,设置定时器的参数,如预分频器(Prescaler)、自动重载值(Counter Period)以及脉冲宽度(Pulse)。这些参数决定了PWM频率和占空比。例如,引用[3]中设置Period为50-1,这可能与频率有关,而占空比则是通过__HAL_TIM_SET_COMPARE来调整的。需要注意的是,预分频器的作用是将系统时钟分频,得到定时器的计数频率,再结合自动重载值,计算出PWM的周期。 用户可能还需要生成代码后,在代码中启动PWM输出,使用HAL_TIM_PWM_Start函数。另外,动态调整占空比可能需要使用__HAL_TIM_SET_COMPARE宏,如引用[3]中的示例。 需要提醒用户注意定时器的时钟配置是否正确,是否与实际硬件匹配。比如STM32F103的定时器时钟源可能来自APB1或APB2,不同定时器的时钟频率不同,这会影响到PWM频率的计算。例如,如果系统时钟是72MHz,定时器2挂在APB1上,而APB1的分频系数可能是2,所以定时器的时钟频率是36MHz,这时候预分频器的设置需要根据这个来计算。 此外,用户可能需要知道如何计算PWM频率和占空比。频率计算公式应该是:定时器时钟频率 / (Prescaler + 1) / (Counter Period + 1)。占空比则是Pulse / (Counter Period + 1)。比如,如果定时器时钟是72MHz,Prescaler设为71,Counter Period设为999,那么频率是72MHz / 72 / 1000 = 1kHz,占空比为Pulse/1000。 还要考虑是否使用中断或者DMA,不过对于基本PWM生成可能不需要。另外,检查引脚配置是否正确,比如是否复用功能正确,有没有冲突。 最后,用户可能需要测试生成的PWM信号,可以用示波器或者逻辑分析仪,如引用[3]中提到的。如果频率或占空比不符合预期,需要回头检查定时器参数设置是否正确,或者是否有代码中的配置错误。 总结步骤:打开CubeMX,选择型号,配置时钟,选择定时器和通道,设置参数,生成代码,编写启动和占空比调整代码,编译下载测试。</think>### STM32F103使用STM32CubeMX生成PWM波形配置步骤 #### 一、工程创建与时钟配置 1. **创建工程** - 打开STM32CubeMX,选择MCU型号`STM32F103C8T6`(或对应型号) - 进入`Pinout & Configuration`选项卡 2. **系统时钟配置** - 在`RCC`中设置高速时钟(HSE)为外部晶振(如使用外部8MHz晶振) - 在`Clock Configuration`中配置系统时钟树,确保定时器时钟源正确(例如APB1/APB2总线时钟) #### 二、定时器与PWM配置 1. **选择定时器** - 例如使用`TIM1`(高级定时器)或`TIM2/3/4`(通用定时器),支持PWM输出的通道[^2] - 在`Timers`选项卡中选择对应定时器(如TIM3) 2. **配置PWM模式** - 选择`Clock Source`为内部时钟(Internal Clock) - 在通道配置中选择`PWM Generation CHx`(如CH1)并绑定到目标引脚(如PA6)[^1] 3. **参数设置** - **Prescaler(预分频器)**:决定定时器计数频率,公式为$f_{定时器} = f_{时钟}/(Prescaler+1)$ - **Counter Period(自动重载值)**:决定PWM周期,公式为$T_{PWM} = (Prescaler+1) \times (CounterPeriod+1)/f_{时钟}$ - **Pulse(脉冲值)**:初始占空比,占空比计算公式为$DutyCycle = Pulse/(CounterPeriod+1)$ $$示例:若f_{时钟}=72MHz, Prescaler=71, CounterPeriod=999,则PWM频率为1kHz,占空比为50%时Pulse=500$$ #### 三、代码生成与功能实现 1. **生成代码** - 点击`Project Manager`设置工程路径和IDE类型(如Keil MDK) - 生成代码后打开工程 2. **启动PWM输出** - 在`main.c`的初始化代码后添加: ```c HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); // 启动TIM3通道1的PWM输出 ``` 3. **动态调整占空比** - 使用宏定义修改脉冲值: ```c __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, new_pulse); // 修改占空比 ``` #### 四、验证与调试 1. **硬件连接** - 使用示波器或逻辑分析仪测量配置引脚(如PA6)的PWM波形[^3] 2. **常见问题** - 若无波形输出,检查定时器时钟是否启用 - 若频率不符,重新计算Prescaler和CounterPeriod
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值