PWM基础与信号特性

做霍尔传感器调试,PWM是绕不开的核心。说白了,霍尔传感器输出的就是PWM信号——占空比代表磁场强度,频率代表转速或者位置信息。这一章我把PWM的基础掰开揉碎了讲,全是实战中能用上的东西。

PWM占空比与频率

PWM信号就两个关键参数:频率和占空比。频率决定信号快慢,占空比决定有效电平占比。

占空比 = 高电平时间 / 整个周期时间 × 100%

频率 = 1 / 周期时间

举个例子。一个20kHz的PWM信号,周期就是50微秒。如果高电平占了25微秒,占空比就是50%。我调试霍尔传感器时,经常遇到占空比跳变的情况——磁场稍微一动,占空比就跟着变。这时候用万用表测不准,必须上示波器。

参数 典型值范围 霍尔传感器常见值
频率 1 Hz ~ 1 MHz 1 kHz ~ 100 kHz
占空比 0% ~ 100% 10% ~ 90%
高电平电压 3.3V / 5V 3.3V(常用)

注意:霍尔传感器输出的PWM占空比通常不会到0%或100%,因为传感器内部有死区保护。我曾经遇到过客户说占空比只有2%,以为是传感器坏了,结果一查是磁场太弱,传感器进入了最小脉宽保护模式。

PWM生成方式

生成PWM信号有两种主流方式:硬件定时器和软件模拟。两种我都用过,各有各的坑。

硬件定时器生成

这是最推荐的方式。MCU内部有专门的定时器模块,配置好预分频、自动重装载值和比较值,PWM就自动输出了,CPU不用管。

// 以STM32为例,配置TIM2输出PWM
// 预分频器:72MHz / 72 = 1MHz
// 自动重装载:50 → 20kHz
// 比较值:25 → 50%占空比

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1;
TIM_TimeBaseStructure.TIM_Period = 50 - 1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_Pulse = 25;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM2, &TIM_OCInitStructure);

TIM_Cmd(TIM2, ENABLE);

硬件定时器的好处是精准、不占CPU。我做过一个项目,同时输出4路不同频率的PWM,CPU负载几乎为零。缺点就是引脚固定,不能随便换。

软件模拟生成

有时候硬件定时器不够用,或者引脚被占用了,就得用软件模拟。原理很简单:用定时器中断,在中断里翻转IO口。

// 软件模拟PWM,50%占空比,1kHz
// 定时器中断每500微秒触发一次

volatile uint16_t pwm_count = 0;
const uint16_t pwm_period = 1000;  // 1ms周期
const uint16_t pwm_duty = 500;     // 500us高电平

void TIM_IRQHandler(void) {
    if (TIM_GetITStatus(TIM3, TIM_IT_Update)) {
        pwm_count++;
        if (pwm_count == 1) {
            GPIO_SetBits(GPIOA, GPIO_Pin_0);  // 拉高
        } else if (pwm_count == pwm_duty) {
            GPIO_ResetBits(GPIOA, GPIO_Pin_0); // 拉低
        } else if (pwm_count >= pwm_period) {
            pwm_count = 0;
        }
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
    }
}

我的经验:软件模拟PWM只适合低频场景,超过10kHz就别想了。中断响应时间、GPIO翻转速度都会引入抖动。我试过用软件模拟50kHz的PWM,结果波形抖得像心电图,根本没法用。

PWM信号测量方法

拿到霍尔传感器的PWM输出,怎么测?我常用的方法有三种。

  1. 示波器直接测量:最直观,能看到波形全貌。后面会细讲。
  2. 频率计/逻辑分析仪:适合批量测试,只看频率和占空比数值。
  3. MCU输入捕获:嵌入式系统里最常用的方法,用定时器捕获上升沿和下降沿。

输入捕获的原理很简单:配置定时器捕获通道,检测到上升沿时记录计数值,检测到下降沿时再记录一次。两个计数值一减,高电平时间就出来了。

// 输入捕获测量PWM占空比和频率
// 假设定时器时钟1MHz,每个计数1微秒

volatile uint32_t rise_time = 0;
volatile uint32_t fall_time = 0;
volatile uint32_t period = 0;
volatile uint8_t capture_done = 0;

void TIM_IRQHandler(void) {
    if (TIM_GetITStatus(TIM4, TIM_IT_CC1)) {
        uint32_t capture = TIM_GetCapture1(TIM4);
        
        if (TIM_GetFlagStatus(TIM4, TIM_FLAG_CC1OF)) {
            // 溢出处理,这里简化了
            TIM_ClearFlag(TIM4, TIM_FLAG_CC1OF);
        }
        
        if (TIM_GetCapture1(TIM4) & 0x01) {  // 假设用CC1S位判断边沿
            rise_time = capture;
        } else {
            fall_time = capture;
            period = rise_time - fall_time;  // 实际需要处理溢出
            capture_done = 1;
        }
        
        TIM_ClearITPendingBit(TIM4, TIM_IT_CC1);
    }
}

// 主循环中读取
if (capture_done) {
    uint32_t high_time = fall_time - rise_time;
    uint32_t duty = (high_time * 100) / period;
    // duty就是占空比百分比
    capture_done = 0;
}

我曾经踩过的坑:输入捕获一定要处理定时器溢出!如果PWM频率很低,周期比定时器溢出周期还长,捕获到的计数值会乱套。我有个项目测10Hz的PWM,忘了处理溢出,结果占空比一会儿30%一会儿80%,查了两天才发现是溢出没处理。

示波器使用技巧

示波器是调试PWM的利器。我见过太多工程师拿着示波器乱按,波形都看不清楚就开始分析。这里分享几个实用技巧。

自动设置 vs 手动设置

很多人上来就按Auto Set,图省事。但Auto Set有时候会误判,尤其是信号不稳定的时候。我建议先手动设置:

  • 时基:先设到1ms/div,看到波形后再调整。频率高就缩小,频率低就放大。
  • 电压档位:先设到2V/div,保证波形在屏幕中间。
  • 触发模式:用上升沿触发,触发电平设在信号幅值的一半左右。

测量占空比的正确姿势

示波器都有自动测量功能,直接调出Duty Cycle测量项就行。但要注意:

  1. 确保示波器捕捉到了完整的周期。如果时基太大,波形压缩在一起,测量结果不准。
  2. 打开平均模式(Average),可以滤掉噪声。我一般设16次或32次平均。
  3. 如果占空比跳变很快,用余辉模式(Persistence)能看到变化范围。

小技巧:测量高精度占空比时,把时基放大到只显示1~2个周期。这样示波器的采样点都集中在这几个周期上,测量精度更高。我调试一个要求占空比精度0.1%的传感器时,就是用这个方法测出来的。

常见波形问题排查

波形现象 可能原因 解决方法
上升沿/下降沿有毛刺 信号反射、地线过长 缩短地线,加100pF电容滤波
占空比抖动 电源噪声、传感器振动 检查电源纹波,加固传感器安装
频率不稳定 时钟源不准、温度影响 用外部晶振,检查温度补偿
幅值偏低 输出驱动能力不足 加缓冲器或上拉电阻

探头的正确使用

探头是示波器的一部分,用不对全白搭。我见过有人用×10档测3.3V信号,结果波形只有330mV,还以为传感器坏了。

  • 测3.3V/5V的PWM,用×1档,带宽够用。
  • 测高频PWM(>10MHz),用×10档,减少负载效应。
  • 地线夹子越短越好。长地线会引入噪声,我习惯用地弹簧。
  • 测量前先做探头补偿:把探头接到示波器自带的方波输出上,调补偿电容直到波形方正。

一句话总结:PWM调试,示波器是眼睛,输入捕获是手,硬件定时器是心脏。这三样玩转了,霍尔传感器的PWM输出调试就成功了一大半。

PWM信号调试知识体系 PWM信号调试 核心参数 生成方式 测量方法 频率 占空比 硬件定时器 软件模拟 示波器 输入捕获 核心:占空比代表磁场强度,频率代表转速/位置 调试工具:示波器 + 输入捕获 + 逻辑分析仪 示波器技巧 时基/触发/平均模式 探头补偿/地线处理 常见问题 毛刺/抖动/频率不稳 幅值偏低/溢出处理 避坑指南 死区保护/最小脉宽 定时器溢出/驱动能力