STM32波形识别技术:正弦波、方波、三角波的识别与实现

RMS法

rms简介

RMS(均方根值),在电压电流中又叫做电压电流的有效值。

在数学定义中RMS通过对瞬时值的平方取平均再开方获得,公式为: RMS = \sqrt{\frac{1}{T}\int_{0}^{T}V(t)^{2}dt}

对于离散信号,公式为

RMS = \sqrt{\frac{1}{n}(V1^{2}+V2^{2}+V3^{2}+...+Vn^{2})}

在CMSIS-DSP库中,提供了RMS的计算函数,函数原形如下

void arm_rms_f32(
  const float32_t * pSrc,        //波形数据
        uint32_t blockSize,        //数据中包含的点数
        float32_t * pResult)        //指向RMS计算结果的指针

我们都知道正弦波的有效值等于峰值/根号2,而方波和三角波的有效值和峰值也有固定关系,但是和正弦波的关系不同。三种波形的峰值和有效值之间的固定关系就是判断波形种类的关键。

对于幅度为A的正弦波,其电压v(t)可表示为

v(t) = Asin( \omega t) 

代入到上述离散信号的RMS计算公式可得Vrms = \frac{A}{\sqrt{2}}

同样对于幅度为A的方波可得Vrms = A

对于幅度为A的三角波可得Vrms = \frac{A}{\sqrt{3}}

上述为理想状态下的推导公式,而在离散域中(比如我们 ADC 采集到的数据都是一个

个点,而不是连续的线,这就是离散的)采集到的点各不相同,比如我们可能在 0.1π处

采集,也可能在 0.11,0.13,0.16π处采集,当然也不可能正好采集到波形的最顶点和最底

点。所以在实际结果中,这个比值只需满足一定范围即可,总结范围大致如下

波形 正弦波 方波 三角波
有效值 0.64A-0.8A <0.63A >0.8A

求 RMS 值时,要确保数组中最少要包含波形的一整个周期内的点。可以通过 FFT 求频

率后,采样率/波形频率即为一个周期内的点数。

不同波形(正弦,三角,方波)的 RMS 值与其幅度有固定的比例关系,前提是波形必须关于时间轴对称即不能有直流偏置。去除直流偏置可以通过求 Vpp,将波形平移,也可以通过低通滤波器滤除直流信号,或者通过 FFT 将直流分量对应的复数置 0 后再逆变换得到无直流偏置的信号。

代码展示

if(adcflag)
		{
			adcflag=0;
			for(int i=0;i<length;i++)
			{
				adcinput[i*2]=dma_adcvalue[i]*3.3f/4095.0f;
				adcinput[i*2+1]=0.0f;
			}
			arm_cfft_f32(&arm_cfft_sR_f32_len4096,adcinput,0,1);//FFT变换
			arm_cmplx_mag_f32(adcinput,adcoutput,length);//求频谱幅度
			adcoutput[0]=0.0f;//直流分量置0
			arm_max_f32(adcoutput,length,&maxvalue,&max_pos);//找基波位置
			Freq=max_pos*TIMCLK*1.0f/length;//求频率
			Npoints=round(TIMCLK*1.0f/Freq);//计算一个周期内的点
			adcinput[0]=0.0f;
			adcinput[1]=0.0f;//直流分量置0
			arm_cfft_f32(&arm_cfft_sR_f32_len4096,adcinput,1,1);//FFT逆变换得到无直流分量的波形
//			for(int i=0;i<length;i++)//打印带偏置的原信号,滤除偏置后的信号,做对比
//			{
//				printf("%.3f,%.3f\n\r",dma_adcvalue[i]*3.3f/4095.0f,adcinput[i*2]);
//			}
			for(int i=0;i<length;i++)
			{
				printf("%.3f,%d\n\r",adcoutput[i],i);
			}
			for(int i=0;i<Npoints;i++)//存储无直流分量的波形
			{
				wave[i]=adcinput[i*2];
			}
			arm_max_f32(wave,Npoints,&maxvalue,&max_pos);
			arm_min_f32(wave,Npoints,&minvalue,&min_pos);
			Vp=(maxvalue-minvalue)/2.0f;//求幅度值
			arm_rms_f32(wave,Npoints,&RMS);//求RMS
			RMS=RMS*1.0f/Vp;//求RMS和幅度的比值
			HAL_ADC_Start_DMA(&hadc1,dma_adcvalue,length);
		}

频谱法

正弦波,方波,三角波有不同的谐波特性,频谱法是通过分析这些不同的谐波特性来判断波形的,频谱数据使用傅里叶变换来获得

正弦,方波,三角波的谐波特性介绍

正弦波作为最基础的波形,可以组合产生任意波形,只包含一个和自己同频率的基波,不包含其他任何谐波分量,频谱图如下

由于我使用的是复数傅里叶变换,所以频谱会有对称的现象。可以看到只包含一个频率分量也就是基波分量

方波和三角波都是奇谐信号,只包含奇次谐波分量如三次、五次谐波,方波的基波幅度是三次谐波的三倍,三角波的基波幅度是三次谐波的九倍。而正弦波不包含谐波分量,这就是频谱法判断波形的关键。

我们可以将傅里叶变换之后得到的基波幅度和三次谐波的幅度做比值,通过比值的大小即可判断不同的波形。由于是ADC采样的数据,难免会有信号干扰,即使正弦波不包含谐波分量,在其三次谐波处也会有很小的数据。

代码展示

if(adcflag)
		{
			adcflag=0;
			for(int i=0;i<length;i++)
			{
				adcinput[i*2]=dma_adcvalue[i]*3.3f/4095.0f;
				adcinput[i*2+1]=0.0f;
			}
			arm_cfft_f32(&arm_cfft_sR_f32_len4096,adcinput,0,1);//FFT变换
			arm_cmplx_mag_f32(adcinput,adcoutput,length);//求频谱幅度
			adcoutput[0]=0.0f;//直流分量置0
			arm_max_f32(adcoutput,length,&maxvalue,&max_pos);//找基波位置
			Freq=max_pos*TIMCLK*1.0f/length;//求频率
			
			if(adcoutput[max_pos] / adcoutput[max_pos * 3] > 12)
				wave_type = sin_wave;
			else if(adcoutput[max_pos] / adcoutput[max_pos * 3] < 12 && adcoutput[max_pos] / adcoutput[max_pos * 3] > 7)
				wave_type = tri_wave;
			else if(adcoutput[max_pos] / adcoutput[max_pos * 3] < 5 && adcoutput[max_pos] / adcoutput[max_pos * 3] > 2)
				wave_type = squ_wave;
			HAL_ADC_Start_DMA(&hadc1,dma_adcvalue,length);
		}

可以根据实际情况灵活调整判断条件的临界点

作者:2302_77530416

物联沃分享整理
物联沃-IOTWORD物联网 » STM32波形识别技术:正弦波、方波、三角波的识别与实现

发表回复