PWM输出正弦波

在STM32上通过PWM输出正弦波,通常需要结合PWM调制技术低通滤波电路,将数字PWM信号转换为模拟正弦波。以下是实现步骤及关键要点:


1. 硬件配置

  • PWM定时器配置 :选择一个支持PWM输出的定时器(如TIM1、TIM2等),配置其频率(通过预分频器PSC和自动重装载值ARR)。
  • PWM通道:启用定时器的PWM通道(如TIM_CH1),设置为PWM模式1或模式2。
  • 滤波电路:在PWM输出引脚后添加RC低通滤波器,滤除高频PWM载波,保留正弦波低频成分。

2. 生成正弦波数据表

  • 采样点计算:在正弦波的一个周期内生成N个采样点(如100个点),计算每个点的幅值并量化为PWM占空比值。

    复制代码
    // 示例:生成正弦波数据表(N=100)
    #define N 100
    #define AMPLITUDE 500  // 幅值(根据ARR调整)
    uint16_t sineWave[N];
    
    for (int i = 0; i < N; i++) {
      sineWave[i] = AMPLITUDE * (1 + sin(2 * M_PI * i / N));
    }

3. 动态更新PWM占空比

  • 方法1:DMA传输 (推荐)

    使用DMA将正弦波数据自动传输到定时器的捕获比较寄存器(CCR),实现无CPU干预的连续输出。

    复制代码
    // 启动DMA传输(以TIM1_CH1为例)
    HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_1, (uint32_t*)sineWave, N);
  • 方法2:定时器中断更新

    在定时器更新中断中手动更新CCR值(效率较低,适合低频波形)。


4. 频率计算

  • PWM载波频率

    f*{PWM} = \\frac{f*{TIM}}{(PSC + 1)(ARR + 1)}

  • 正弦波频率
    f*{Sine} = \\frac{f* {PWM}}{N} 调整N(采样点数)或ARR可改变正弦波频率。

5. 滤波电路设计

  • RC低通滤波器
    截止频率 (f_c = \frac{1}{2\pi RC}) 应远低于PWM频率(例如 (fc \leq \frac{1}{10}f{PWM})),以平滑波形。

6. 示例代码(基于HAL库)

复制代码
// 配置定时器(以TIM1为例)
TIM_HandleTypeDef htim1;

void PWM_Init() {
    htim1.Instance = TIM1;
    htim1.Init.Prescaler = 0;          // 预分频值
    htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim1.Init.Period = 999;           // ARR = 999,PWM频率= 72MHz / (999+1) = 72kHz
    htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    HAL_TIM_PWM_Init(&htim1);

    // 配置PWM通道
    TIM_OC_InitTypeDef sConfigOC;
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 0;  // 初始占空比
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
    HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);

    // 启动DMA传输
    HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_1, (uint32_t*)sineWave, N);
}

注意事项

  • PWM分辨率 :增加ARR可提高幅值分辨率,但会降低PWM频率。
  • 实时性 :高频正弦波需减少采样点数(N)或提高PWM频率。
  • 验证工具:用示波器观察滤波后的波形,调整RC参数优化平滑度。

通过以上步骤,即可在STM32上输出高质量的正弦波信号。