stm32hal库利用pwm波合成正弦波
时间: 2025-07-01 10:36:36 浏览: 17
### 使用STM32 HAL库生成PWM正弦波的方法
通过STM32 HAL库生成PWM正弦波,需要结合定时器中断或DMA更新占空比,并添加低通滤波器来平滑输出信号。以下是详细的实现方法和示例代码:
#### 1. 配置定时器
配置一个定时器(如TIM3),设置其参数以满足PWM频率和分辨率的需求。定时器的自动重装载值(ARR)决定PWM的周期,而捕获/比较寄存器(CCR)值决定占空比。
#### 2. 创建正弦波表
创建一个包含正弦波采样点的数组,用于动态更新PWM的占空比。例如,可以使用以下公式生成正弦波表:
```c
#define SIN_SAMPLES 100 // 正弦波采样点数
uint16_t pwm_table[SIN_SAMPLES];
for (int i = 0; i < SIN_SAMPLES; i++) {
pwm_table[i] = (uint16_t)(50 + 50 * sin(2 * M_PI * i / SIN_SAMPLES));
}
```
上述代码生成了一个范围在0到100之间的正弦波表[^4]。
#### 3. 定时器中断更新占空比
在定时器的周期中断中,依次从正弦波表中读取值并更新PWM的占空比。以下是定时器中断回调函数的示例代码:
```c
static uint8_t idx = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim->Instance == TIM3) { // 确保是TIM3的中断
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, pwm_table[idx]); // 更新CCR值
idx = (idx + 1) % SIN_SAMPLES; // 循环索引
}
}
```
#### 4. 主函数初始化
在主函数中初始化定时器、GPIO以及启动PWM输出:
```c
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM3_Init(); // 初始化TIM3
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); // 启动PWM通道1
while (1) {
// 主循环可以用于其他任务
}
}
```
#### 5. 添加低通滤波器
为了将PWM信号转换为模拟正弦波,需要在PWM输出端口连接一个低通滤波器。低通滤波器可以通过电阻和电容组成,其截止频率应低于PWM频率的一半[^4]。
---
### 示例代码完整版
以下是完整的代码示例,展示了如何使用STM32 HAL库生成PWM正弦波:
```c
#include "stm32f1xx_hal.h"
#define SIN_SAMPLES 100 // 正弦波采样点数
uint16_t pwm_table[SIN_SAMPLES]; // 正弦波表
static uint8_t idx = 0;
// 初始化正弦波表
void init_sine_table(void) {
for (int i = 0; i < SIN_SAMPLES; i++) {
pwm_table[i] = (uint16_t)(50 + 50 * sin(2 * M_PI * i / SIN_SAMPLES));
}
}
// 定时器中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim->Instance == TIM3) { // 确保是TIM3的中断
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, pwm_table[idx]); // 更新CCR值
idx = (idx + 1) % SIN_SAMPLES; // 循环索引
}
}
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM3_Init(); // 初始化TIM3
init_sine_table(); // 初始化正弦波表
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); // 启动PWM通道1
while (1) {
// 主循环可以用于其他任务
}
}
```
---
### 注意事项
- 确保定时器的PWM频率足够高,以便低通滤波器能够平滑输出信号。
- 根据实际需求调整正弦波表的采样点数和幅度范围。
- 如果需要更高的精度,可以使用DMA代替中断来更新CCR值。
---
阅读全文
相关推荐


















