PWM输出接低通滤波的探讨
:beginner:一路PWM三阶RC滤波语音输出-噪声问题
项目场景:
很多MCU内部没有DAC,但是芯片应用在需要DAC的场景,此时需要用PWM波模拟DAC输出。
有一路PWM和多路PWM波实现方式,取决于项目要求以及MCU性能
单路PWM波:MCU主频相对较高,项目对DAC精度要求低。
多路PWM波,MCU主频相对较低,项目对DAC精度要求高。
问题描述
使用单路PWM输出时,有噪音输出。输出结构如下:
PWM波 -> RC滤波电路 -> 功放芯片/8002 -> 喇叭
PWM波:一路PWM,由一个8位定时器产生,频率在64K
RC滤波电路:使用三阶RC滤波,其中R1C1=R2C2=R3C3=RC,所以截止频率
功放芯片:使用8002喇叭:8欧1W
原因分析:
噪声来源一:定时器输出频率波动 噪声来源二:功放输出不稳定 噪声来源三:滤波电路对PWM波处理有杂波
如果直接输出一段音频,有噪音的出现,此时无法很好的定位问题来源是哪一点。
这里采用一些方法来排除一些噪声源。
1.输出正弦波,通过示波器观察RC滤波后的波形,分析滤波电路对PWM波处理有杂波
PWM数据;
示波器显示:
RC滤波后:
可以看出RC滤波后正弦波是正常的,稍微有点变形,但是并无异形和封底顶。
2.输出基准电平(50%的占空比方波),分析定时器输出频率波动和功放输出问题
2.1查看语音wav转的bin文件,索引信息后数据都是0x80.
2.2烧录文件和程序后,测量PWM输出,波形如下图,是正常的。此时喇叭周期性的有噪音输出。功放使能和PWM波同时输出。
2.3 保持功放使能,循环播放语音。此时喇叭周期性的有噪音输出。
检查发现采用FIFO方式在定时器里面读出并更新PWM,由于FIFO读出时间不稳定导致更新PWM波的频率有波动,从而产生噪音。
解决方法:把FIFO读出数据放到外面,提前准备好,修改后喇叭周期性的噪音没有了。
进一步测试发现上电时有一点噪音输出。
2.4分析上电瞬间有噪音输出
原因分析可能是PWM刚开始输出的跳变或者功放刚上电不稳定输出导致。
进一步测试:
1.上电后先输出PWM波5s后打开功放使能,此时功放使能瞬间有一个噪声
2.上电后先打开功放使能5s后输出PWM波,此时有两个噪声,刚上电时以及5s后输出PWM时。
通过波形和结果可以分析出:上电噪声有两个原因
A.功放使能时功放内部输出的噪声。
B.PWM波刚输出时产生一个跳变信号,从而产生的噪声。
功放的上电噪音可以在输出端加入滤波电容进行消除,因为这个和具体的功放有关系,可能有些功放没有上电噪音,没有进一步测试。
解决方案:
1.同过正弦波调整RC滤波,使得波形尽量如同正弦波 2.使用时先输出PWM波后在开功能使能,这样只有一个功放使能时内部噪声。
:beginner:软件实现低通滤波 未测试
一阶RC低通滤波算法是一种电路模拟滤波器,它通过将高频部分的信号衰减来消除噪声。这种滤波器由一个电阻和一个电容组成,因此被称为RC低通滤波器。
具体来说,低通滤波器通过将高频部分的信号衰减来消除噪声。高频部分的信号是指频率高于截止频率的信号,而截止频率是指滤波器对高频部分信号的衰减开始的频率。
低通滤波器的输入信号通过电阻传递到电容上,电容会滞后于电阻而导致信号衰减。在一阶RC低通滤波器中,截止频率是由电阻和电容共同决定的。 具体来说,截止频率 fc = 1 / (2πRC)。
以下是一个使用C语言编写的一阶RC低通滤波器的代码示例:
#include <stdio.h>
#define PI 3.14159265
float lowpass(float input, float output_prev, float RC, float dt) {
float alpha = dt / (RC + dt);
return output_prev + alpha * (input - output_prev);
}
int main() {
float RC = 1 / (2 * PI * 1000); // 1000 Hz cutoff frequency
float dt = 1 / 44100; // sample rate is 44.1 kHz
float input = 0.5; // input signal
float output_prev = 0; // previous output
float output = lowpass(input, output_prev, RC, dt);
printf("%f", output);
return 0;
}
该代码示例定义了一个lowpass()
函数,该函数接受输入信号,上一次输出,RC时间常数和采样时间间隔作为参数。在函数中,alpha被定义为dt / (RC + dt)
,用于计算新的输出值。
新的输出值是通过将上一次的输出与输入信号之间的差值乘以alpha来计算的。这样,如果输入信号与上一次的输出相同,则新的输出将与上一次的输出相同,否则新的输出将接近输入信号。
在main()
函数中,我们设置了截止频率为1000 Hz,采样率为44.1 kHz,输入信号为0.5。我们调用lowpass()
函数,将上一次的输出设置为0。最后,我们打印出新的输出。
一阶RC低通滤波算法是一种简单而有效的滤波方法,可以有效消除高频噪声。但是需要注意的是,这种滤波方法有时会对信号的时域性能造成影响,因此需要根据具体应用场景进行权衡。
:beginner:PWM通过RC低通滤波器模拟DAC
当我们电路需要DAC而单片机并没有DAC外设时,则可采用PWM通过RC低通滤波器来模拟实现DAC功能。
RC低通滤波器
当采用低通滤波器模拟DAC时,PWM频率应远大于RC低通滤波电路的截止频率fc=1/2πRC
(10倍以上)。输出电压为Vout=Vcc*Duty
。
在使用此电路时,应注意:
-
一般情况下,当电容C较小,电阻R较大时,输出电压损耗较小,纹波较大;当电容C较大,电阻R较小时,输出电压损耗较大,纹波较小。所以,为了获取线性度较高的精确DA转换,一般采用较小电容并尽量不要使用电解电容。
-
为了提高输出的驱动能力,一般会在RC低通滤波器器之后还会加一级高性能的电压跟随,并在跟随器输出的地方加上一个滤波用的电解电容,使输出电压进一步变得光滑。但是需要注意的是,这时的输出电压里可能含有较多的交流 谐波成分,如果处理不当,电压跟随器有可能自激。解决的办法就是使用一个小的去藕电容。而且这里电容的放置顺序必须是电解电容在前,去藕电容在后!
RC低通滤波器+电压跟随器
3、如果输出电压精度和线性度要求不高,但是对纹波要求却很高,或者这个电压比较固定时,可以使用电容较大的滤波组合。因为,虽然大电容的直流损耗较大,但是我们可以通过调节PWM占空比来达到要求的输出电压,或者通过一级AD转换的反馈来实现精确的固定电压输出。只是这里仍然要加一级电压跟随器,以便于后级采集电路使用,且AD采集点放置在跟随器输出处。
4、如果一级RC低通滤波器达不到效果,则可使用多级RC低通滤波器进一步提高输出平滑度。
下图为 二级RC低通滤波器
完结