理论基础
检波一词来自无电线,指从一段模拟波形中提取出有用信息,后来也在电子测量领域中广泛使用。检波的方式分为硬件检波与软件检波,硬件检波是让原始信号通过各种线性或者非线性的模拟电路得到期望信号,缺点是电路复杂,不灵活。软件检波是即直接把被测信号送入ADC采集,单片机通过程序计算参数,优点是精度高,集成度高,电路简单可靠,功能强大,可以实现复杂算法,并且参数调整方便,因此逐渐成为主流。本文中除了必要的模拟前端电路,都是采用算法软件检波。
峰值检波
峰值的概念最简单,即最大值。也是正弦波的幅度。
均值检波
平均值可以用来计算平均功率,注意均值是指绝对值或者整流后的平均值,不然交流电的均值是零。
均方根检波
均方根是有效值(RMS)的定义式,是应用最广泛的交流电压参数。它是从能量角度推出的,可以计算交流电的功率
在波形固定的情况下,峰值,均值和有效值有固定的比例关系。由于有效值的计算量比较大,在要求较低时可以通过测量均值或峰值间接测量有效值。有效值与均值的比称为波形因数,峰值与有效值的比例称为波形因数。
FFT
上面三种都是从时域角度计算的,根据帕塞瓦尔定理,一段确定信号的时频能量相等。有效值也可以从频域计算出。
FFT运算把被采波形分解成了几个正弦分量,各次分量的能量和即总的能量,可以直接求和得到。
FFT一般用或者DSP核(如果有)现成代码,无需开发者推导,开发者只需要注意两个方面,一是得到的结果要进行取半和频率轴归一化,二是还有只有2的整数幂的点才能做FFT。
FFT方案功能最强大,可以计算诸多电参数,评估电能质量甚至甲加以补偿等,数字电表中大多采用FFT方案。
无论是峰值,平均值还是均方根,它们都是统计量,是一段数据的参数。所以工作逻辑是分段的——连续采集N个样值,计算。再连续采集N个……。
三种方案性能对比如下
精度 |
计算量 |
内存消耗 |
|
峰值 |
低 |
低 |
低 |
平均值 |
高 |
中等 |
低 |
均方根 |
高 |
高 |
低 |
FFT |
高 |
高 |
高 |
结果与采集区段无关的条件
容易证明
其中T是正弦波的周期,t0是积分开始时刻。常数结果表明了与t0无关。
在按段采集下,要想每次的结果稳定是有条件的:
- 被采的是正弦波。
- 采集段长必须是半周期的整数倍
第二点对于均值和均方根检波方案来说很重要。当采集段长为被采正弦波的半周期的整数倍后,最后的结果与采集的区段无关,它允许我们的采样不用与被采信号同步,也能输出稳定结果。是均值和均方根检波方案的重要基础。
软件框架
进程
严格的时序是MCU开发的一个特点,这类代码往往有着很精确的时序要求。很多代码是要按周期执行的,同时还有优先级之分。
做测量的代码一般是一个循环。采集,计算和显示三个进程穿插交替。分析这三个进程,采集工作的时序优先级最高,需要以精确的周期执行,不能被打断。计算和显示的优先级次之,只要在下一段数据采集完前能做好就行。以横向为时间轴,绿色代表采样进程,橙色代表计算和显示进程,可以直观的看到CPU是怎样分配时间的。假设每次采集5个点,计算它们的平均数后显示。
方案一:采集5个数据,计算,显示,然后继续采集5个数据。(周期应是T,标错了)
此方案思路简单,采集,处理,显示依次进行。但是很明显,在采集中CPU有大量空闲,使用效率较低,其次采样不是等间隔连续的了,如果有其他累积操作的话会受到影响。
实现方法:
方案二:
计算和显示的进程并没有严格的时序要求,放到采集进程的间隔中,并允许被打断。这样做一方面提高了CPU利用率,另一方面可以让采样等间隔连续。
实现方法:采集工作结束后将标志位置1,主函数判断到后执行计算计算和显示,
- 无论采用哪种方案,采集进程长度不能超过T,并且尽量短。
- 采用第二种方案时,计算显示进程要保证在下一段前能执行完。
(一种简单且精确的测量代码执行时间的方法:在要测量的代码前后加上GPIO操作输出脉冲,用示波器测量脉宽)
ADC的使用有和查询式和中断式。为了不阻塞CPU执行其他进程,采用中断式。为了精确的采样周期,尽量使用定时器触发,ADC 结束后进入中断。
当有多通道转换时,建议使用DMA及时把转换结果转移到预设好的数组。
采样频率和N的取值
奈奎斯特准则指出了2倍采样频率,但是在工程中2倍是一个很极限的值,首先除非在时域上采集无限长的时间,否则就会在频域产生泄漏;其次要测量的波形和大概率含有其他谐波。再加上MCU内存有限,采集时间不能过长。2倍采样频率是远远不够的。市电频率很低,如果我们每次测量0.1s的数据,那么只有5个周期,“窗”非常的窄,造成信号带宽展宽,为了避免混叠影响,要尽量提高采样频率。
1kHz采集的时域效果
从时域角度一样容易理解,如果只能采集5个周期,那肯定是采样点越多,有效数据越多,结果越精确。尤其是峰值检测法,采样间隔直接影响了分辨率。
根据目前大多数MCU ADC的性能,测量工频信号时推荐采样频率不低于1kHz。
一般来说,采样点数越多,结果就越精确合稳定,但是另一方面对MCU的RAM和计算要求也就越高,还有一个重要因素是外界的需求,如果外界没有需求只是作为显示,那么0.5秒的更新周期就比较适合,采样点=0.5*1000=500个。
算法
MCU用随机存储器(RAM)充当内存,其大小一般都在KB级别,如果先采集N个数在内存里再处理的方案,RAM则显得非常紧梢,因为N一般会取很大。
会有人问为什么不用填flash?MCU的flash容量确实一般远大于RAM,但是flash工作非常慢,无法在限定是时间内完成读写。
实际上除了FFT之外,前三种算法都可以只用1-2个变量原位实现,不必使用长为N的数组。
峰值:取上次和本次的采样值进行比较,若本次的值大就更新,最后就可以得到一段数据的最大值。
If(peak<ADC_result) peak=ADC_result; //取峰值
- 峰值容易受到毛刺的影响,为了降低。可以连取多段的峰值再做平均。
- 采完一段数据后要把peak置零。
均值:用一个变量,对每次的采样结果进行累加,本段采样结束后除以采样点数求平均。
采样中:Sum=sum+ADC_result;
采样结束:Aver=Sum/N;
- 做除法的运算量较大且时序要求低,使用标志位把除法计算转移到主函数中,保证不会影响到采样。
- 注意数据大小不要溢出。
均方根:
采样中:Sum=Sum+ ADC_result^2;
采样结束:RMS=sqrt(Sum);
- 开方的计算量很大并且时序要求较低,使用标志位把除法计算转移到主函数中。
- 注意数据大小不要溢出。
- 进行平方累加时,噪声量不会被抵消,也会随着累加。因此最后求出的结果会加上一个“噪声基底”而略大于真实值。可以实际测出后在软件中减掉。
软中断介绍
通过对中断次数计数加判断的方式,可以按照中断周期的整倍数时间执行代码。比如定时器的中断频率为1ms,计数变量每次+1。
Static unsigned int cnt=0;
Void interrupt_1ms()
{
If(cnt%5==0) {} //5ms TASK
Else if(cnt%20==0) {} //20ms TASK
Else {} //1ms TASK
If(cnt==50)
{ cnt=0;
//50ms TASK
}
}
如果函数比较大,可以中断设置标志变量,在主函数加判断执行,当然这样做会有一个比较小的延迟。
软触发
前面讲到,在采样数据长度为正弦波半周期的整数倍时,采集区段和最后结果无关。这个条件对时钟的精度要求较高,微小的误差就会导致数据的抖动。MCU使用的晶振虽然稳定,但是此处需要的是与被测信号的相对值,其采样频率值一般会有误差。当然,开发者可以自己校正,通过调节触发定时器的计数周期寄存器来达到精确整数倍采样。但是对于量产的产品,每一个都去校对就很麻烦了,需要新的方案。
采用触发技术可以让采样区段和正弦波同步,每次都采集正弦波的固定区段,从而消除掉对采样频率精度的敏感性。有硬触发和软触发两种方案,硬触发就是用外部电路产生与正弦波同步的脉冲序列作为MCU的外部中断源,在没有外触发电路的情况下,可以使用软触发方案。
软触发的思路就是寻找过零点,不停计算相邻两次结果的采样结果的乘积,如果小于零就认为过零点就在这两次采样之间,完成触发,从次点开始进行计算。本段测量完后继续等待下一个过零点。
通过软触发采集固定区段(绿色区域为被采集)
提高ADC转换精度
传感器与模拟前端
ADC模拟前端是,测量需要互感器。两个基本功能,偏置与滤波。
单片机和常见的ADC只能采集正电压,测量交流信号,需要把交流电的地抬到ADC量程的中点位置,称为直流偏置。加入偏置的思路有两个,一是通过上拉,运放等方式叠加;二是利用互感器,耦合电容的隔直特性把信号的地抬到VCC/2。
AD采集前,抗混叠滤波器是必须的。我们要采集的是单频信号,信号带宽很窄,可以把截止频率设置低一些滤的更干净。对于无源方案可以使用RC,LC滤波,对于运放电路可以使用有源滤波,滤波电路和偏置电路可以画到一起。
无源方案
叠加
抬地
有源方案
叠加
抬地
有源滤波
关于ADC前端RC网络,从角度看,RC是滤波器,但是对于逐次逼近型(SAR)ADC,前端的RC网络还有特殊的作用。ADC内部在采样瞬间时,内部的采样电容会分走电荷造成电压下跌。要做到不丢码,需要满足两个条件。首先要通过计算保证电压的下跌值在ADC的最小分辨区间内,这与两个电容的取值和ADC输入阻抗有关;其次是在下次采样前一定要充电至回原信号水平,这与电阻R和采样频率有关。只有在这些参数之间做到平衡,才能真正发挥ADC的性能。想要深入了解可以参考兆易创新的这篇AN。
https://www.gd32mcu.com/data/documents/userManual/AN059_Methods_to_improve_ADC_sampling_accuracy_CN_Rev1.0.pdf
电压基准
精确的转换需要精确的电压基准,电压基准的精度就决定了最后结果的精度,其中重要性可见一斑。常见的有三种基准方案:电源基准,内部基准和外部基准。
电源基准是最简陋的方案,MCU直接取VDD作为ADC基准。如STM32F103。因为VDD还要向MCU供电,电压会受MCU功耗的影响,虽然很微小,可能只有十几毫伏,但是换算后也是可观的误差,如测量220V的市电,%3的误差就是6.6V。为了减小影响只能选取有优良电压调整率的高质量电源芯片。
有一些单片机内置了专门给ADC用的电压基准,这精度就会提升很多。但是它依然会受到单片内部信号带来的串扰和热噪声的影响,并且内部基准值往往是一个低于VDD的电压值,限制了量程利用率。
外部基准是精度最高的方案。首先它完全避开了MCU的影响,可以放在纯净的模拟域中,滤波后输入单片机,其次专门用基准芯片经过特殊设计往往有着极佳的电压调整率和极低的温漂,可被认为是理想的恒定值,最后它的使用也更加灵活,可调节基准电压来实现最大的量程利用率。缺点是增加了额外电路。适用于对精度要求很高的场合。
自校正
对于均值与均方根方案,如果偏置存在误差就会一直累积,所以结果对偏置的误差非常敏感。对于均方根算法,即使偏置电压准确,噪声的跳动也会被累积。偏置电压随着温度和时间变化,只做一次固定的校正是不够的,应该在每次开机后都要校正一次。可以读取较长的一段数求平均后减掉,作为初始化代码的一部分。
而峰值和FFT方案不需要,峰值采集的峰峰值,偏置会被差掉。FFT的算法特殊,直接从各次的分量计算,也不存在这个问题。
还有温度补偿,如果单片机有这个功能一定要用上。
典型案例
基于MCU的交流电压表
采样周期:0.1ms
每段长度:1000个点
计算结果/显示更新:0.1s
采用均方根算法