蓝桥杯嵌入式PWM占空比
时间: 2025-05-14 13:35:43 浏览: 26
### 蓝桥杯嵌入式PWM占空比实现方法
在嵌入式开发中,PWM(Pulse Width Modulation)是一种常见的信号调制技术,用于控制电机速度、LED亮度以及其他电子设备的功能。以下是基于蓝桥杯竞赛场景下如何实现PWM占空比调整的具体方法。
#### 配置GPIO引脚
为了通过PA6和PA7两个引脚输出PWM脉冲,首先需要初始化这些引脚作为TIM外设的复用功能引脚。这可以通过设置相应的寄存器或者使用HAL库函数完成[^1]。
```c
// 初始化 GPIO 引脚 PA6 和 PA7 为 TIM 复用功能
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; // 设置为复用推挽模式
GPIO_InitStruct.Pull = GPIO_NOPULL; // 不启用上下拉电阻
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; // 高速模式
GPIO_InitStruct.Alternate = GPIO_AF2_TIM3; // 使用 TIM3 的 AF 功能
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
```
#### 定时器配置
接下来,配置定时器以生成指定频率的PWM信号。假设目标频率分别是100MHz和200MHz,则需计算预分频器值以及自动重装载值。
对于100MHz的情况:
- 系统时钟假定为80MHz。
- 计算公式:`ARR = (SystemClock / Prescaler) / Frequency - 1`。
因此,
- `Prescaler = 80 - 1 = 79` (即分频系数为80)
- `ARR = (80e6 / 80) / 100e6 - 1 ≈ 0.99` 取整为0。
实际应用中可能无法达到如此高的频率,这里仅作理论说明。
```c
// 配置 TIM3 生成 PWM 波形
__HAL_RCC_TIM3_CLK_ENABLE();
TIM_HandleTypeDef htim3;
htim3.Instance = TIM3;
htim3.Init.Prescaler = 79; // 分频系数
htim3.Init.CounterMode = TIM_COUNTERMODE_UP; // 向上计数模式
htim3.Init.Period = 0; // 自动重载值
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_PWM_Init(&htim3);
TIM_OC_InitTypeDef sConfigOC;
sConfigOC.OCMode = TIM_OCMODE_PWM1; // PWM 模式 1
sConfigOC.Pulse = 0; // 初始占空比为 0%
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1); // 配置 CH1 (PA6)
HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2); // 配置 CH2 (PA7)
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); // 开始 CH1 输出
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); // 开始 CH2 输出
```
#### 占空比调节逻辑
当按下按键时,可以触发中断服务程序,在其中修改对应通道的比较值(`CCR`),从而改变占空比。例如,每次按下一个键增加10%,则新的比较值应更新为当前周期长度乘以相应百分比。
```c
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
static uint8_t duty_cycle_ch1 = 0, duty_cycle_ch2 = 0;
if(GPIO_Pin == KEY1_PIN){ // 键盘1 控制CH1
duty_cycle_ch1 += 10;
if(duty_cycle_ch1 > 100) duty_cycle_ch1 = 100;
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, (uint32_t)(duty_cycle_ch1 * ARR / 100));
}
if(GPIO_Pin == KEY2_PIN){ // 键盘2 控制CH2
duty_cycle_ch2 += 10;
if(duty_cycle_ch2 > 100) duty_cycle_ch2 = 100;
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, (uint32_t)(duty_cycle_ch2 * ARR / 100));
}
}
```
上述代码片段展示了如何利用外部中断回调函数动态调整PWM信道的占空比。
---
阅读全文
相关推荐


















