ADC采样信号RMS测量值的Verilog实现
术语“RMS”代表“Root-Mean-Squared”。大多数书籍将此定义为“产生与等效直流电源相同的加热效果的交流电量”,或者沿着这些线路类似的东西,但RMS值不仅仅是这个。 RMS值是瞬时值的平方函数的平均值(平均值)的平方根。
笔者的印象中第一次接触到交流电是初中,具体是初二还是初三就不太清楚了。交流电动势的表达式为e=E(m)sinωt,其中E(m)为交流电动势的最大值,那么交流电动势的有效值为 E=E(m)/√2
同理得交流电压的有效值和交流电流的有效值分别为:
U = U(m)/√2
I = I(m)/√2
以上的方法是以前中学课本里头理想情况下计算正弦余弦的有效值方法。而在实际的ADC采样中,采集到的信号可能并不是标准的正弦余弦信号,甚至可能是些杂乱的噪声信号。根据有效值的基本定义:周期量在一个周期内的均方根值。可以用以下的公式表示:
根据该公式可以把ADC采集到的信号直接用代码计算出来
1 //************************************************************************** 2 // *** file name : RMS_measure.v 3 // *** version : 1.0 4 // *** Description : ADC RMS measure 5 // *** Blogs : https://www.cnblogs.com/WenGalois123/ 6 // *** Author : Galois_V 7 // *** Date : 2022.10.26 8 // *** Changes : Initial 9 //************************************************************************** 10 `timescale 1ns/1ps 11 module RMS_measure 12 #( 13 parameter DWIDTH = 18 14 ) 15 ( 16 input i_sys_clk , 17 input i_sys_rstn , 18 input [DWIDTH-1:0] i_adc_data , 19 input i_adc_valid , 20 input i_measure_enable , 21 output reg [31:0] o_adc_data_cnt , 22 output reg [63:0] o_adc_square_sum , 23 output reg [47:0] o_adc_sum , 24 output reg o_adc_sum_valid 25 ); 26 wire [DWIDTH+1:0] w_adc_data ; 27 wire [2*(DWIDTH+1)+1:0] w_mult_data ; 28 wire w_adc_add_en ; 29 wire w_adc_notend ; 30 wire w_square_overflow ; 31 32 reg signed [DWIDTH+1:0] r_adc_data ; 33 reg signed [2*(DWIDTH+1)+1:0] r_mult_data ; 34 reg [5:0] r_adc_end_detection ; 35 36 assign w_adc_data = (i_adc_valid & i_measure_enable) ? {{2{i_adc_data[DWIDTH-1]}},i_adc_data} : 'd0; 37 assign w_square_overflow = &o_adc_square_sum[63:54]; 38 assign w_adc_notend = i_measure_enable && w_square_overflow; 39 assign w_adc_add_en = i_adc_valid && w_adc_notend; 40 /******************************************************************************\ 41 Calculate sum of squares 42 \******************************************************************************/ 43 always@(posedge i_sys_clk) 44 begin 45 if(~i_sys_rstn) 46 begin 47 r_adc_data <= 'd0; 48 r_mult_data <= 'd0; 49 end 50 else 51 begin 52 r_adc_data <= w_adc_data; 53 r_mult_data <= r_adc_data * r_adc_data; 54 end 55 end 56 57 assign w_mult_data = r_mult_data; 58 59 always@(posedge i_sys_clk) 60 begin 61 if(~i_sys_rstn) 62 begin 63 o_adc_square_sum <= 'd0; 64 end 65 else 66 begin 67 o_adc_square_sum <= o_adc_square_sum + w_mult_data; 68 end 69 end 70 /******************************************************************************\ 71 Count ADC points 72 \******************************************************************************/ 73 always@(posedge i_sys_clk) 74 begin 75 if(~i_sys_rstn) 76 begin 77 o_adc_data_cnt <= 'd0; 78 end 79 else if(w_adc_add_en) 80 begin 81 o_adc_data_cnt <= o_adc_data_cnt + 1'b1; 82 end 83 end 84 /******************************************************************************\ 85 Statistical ADC accumulation sum 86 \******************************************************************************/ 87 always@(posedge i_sys_clk) 88 begin 89 if(~i_sys_rstn) 90 begin 91 o_adc_sum <= 'd0; 92 end 93 else if(w_adc_add_en) 94 begin 95 o_adc_sum <= o_adc_sum + {{(47-DWIDTH-1){w_adc_data[DWIDTH+1]}},w_adc_data}; 96 end 97 end 98 /******************************************************************************\ 99 Output the effective signal of the result to ensure the stability of the result 100 \******************************************************************************/ 101 always@(posedge i_sys_clk) 102 begin 103 if(~i_sys_rstn) 104 begin 105 r_adc_end_detection <= 'd0; 106 end 107 else 108 begin 109 r_adc_end_detection <= {r_adc_end_detection[4:0],w_adc_notend}; 110 end 111 end 112 113 always@(posedge i_sys_clk) 114 begin 115 if(~i_sys_rstn) 116 begin 117 o_adc_sum_valid <= 'd0; 118 end 119 else if(~r_adc_end_detection[4] && r_adc_end_detection[5]) 120 begin 121 o_adc_sum_valid <= 1'b1; 122 end 123 else 124 begin 125 o_adc_sum_valid <= 'd0; 126 end 127 end 128 129 endmodule
以上代码分别算出有效时间内(i_measure_enable为时间阈值设置信号)ADC信号的点数,平方和以及ADC的累加值。计算出的这些值可以通过axi4_lite总线的传给soc,对数据根据公式进行浮点型计算得出信号的平均值,有效值。