stm32f103c8t6输出两路PWM
时间: 2025-05-09 07:18:20 浏览: 35
### STM32F103C8T6 双通道 PWM 配置教程
#### 一、硬件资源分析
STM32F103C8T6 提供多个定时器可以用于生成 PWM 波形,其中包括 TIM1 和 TIM2 等通用定时器。这些定时器支持多路互补或独立的 PWM 输出功能[^2]。
为了实现双通道 PWM 输出,可以选择任意两个具有 PWM 功能的 GPIO 引脚并将其映射到同一个定时器的不同通道上。例如,TIM2 的 CH1 (PA0) 和 CH2 (PA1) 是常见的选择之一。
---
#### 二、软件配置流程
以下是基于 HAL 库的双通道 PWM 配置方法:
1. **初始化时钟**
使用 `RCC` 初始化外设时钟,确保目标定时器及其对应的 GPIO 处于启用状态。
2. **GPIO 配置**
将选定的 GPIO 引脚设置为复用推挽模式(Alternate Function Push-Pull),以便它们能够作为定时器输出引脚工作。
3. **定时器基础配置**
设置定时器的工作模式为向上计数模式,并定义自动重装载寄存器 (`ARR`) 值来决定 PWM 的周期长度。
4. **PWM 模式选择**
定义比较值寄存器 (`CCR`) 来调整占空比。通过修改 CCR 寄存器中的数值即可动态改变 PWM 占空比。
5. **启动 PWM 输出**
启动定时器之后,相应的 GPIO 引脚会按照设定好的参数开始输出 PWM 波形。
---
#### 三、示例代码
以下是一个完整的双通道 PWM 配置实例,假设我们使用 TIM2 的 CH1 (PA0) 和 CH2 (PA1):
```c
#include "stm32f1xx_hal.h"
// 定义全局变量
TIM_HandleTypeDef htim2;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM2_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config(); // 配置系统时钟
MX_GPIO_Init(); // 初始化 GPIO
MX_TIM2_Init(); // 初始化 TIM2
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); // 开启 TIM2_CH1 的 PWM 输出
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2); // 开启 TIM2_CH2 的 PWM 输出
while (1)
{
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 200); // 调整 CH1 占空比至 ~20%
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, 400); // 调整 CH2 占空比至 ~40%
HAL_Delay(1000); // 延迟一秒
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 600); // 调整 CH1 占空比至 ~60%
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, 800); // 调整 CH2 占空比至 ~80%
HAL_Delay(1000); // 延迟一秒
}
}
/**
* @brief 配置 TIM2 为 PWM 模式
*/
static void MX_TIM2_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
htim2.Instance = TIM2;
htim2.Init.Prescaler = 71; // 设定预分频器为 72MHz / (72 + 1) ≈ 1kHz
htim2.Init.CounterMode = TIM_COUNTERMODE_UP; // 上升计数模式
htim2.Init.Period = 999; // 自动重载值,PWM 频率为 1kHz
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1; // 选择 PWM1 模式
sConfigOC.Pulse = 0; // 初始占空比为 0%
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief 初始化 PA0 和 PA1 为复用功能
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
/* 配置 PA0 和 PA1 为复用推挽模式 */
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
```
---
#### 四、注意事项
- 如果需要更高的精度或者更低的抖动率,则可以通过增加 ARR 或者减少 Prescaler 实现更高分辨率的 PWM 控制[^1]。
- 不同型号的 STM32 微控制器可能具备不同的高级特性,比如死区时间插入等功能,在实际应用中可以根据需求进一步扩展。
---
阅读全文
相关推荐


















