前言:我們需要思考在AI時代如何提升工作效率,可以把一些事情丟給AI來解放生產(chǎn)力,在AI不能完全代替人的現(xiàn)在情況下,讓它做一些打雜的事情還是可以的。于是我編寫了一段計算AC 有效值、平均值、頻率的代碼,一行注釋也沒有,發(fā)給Deepseek后,他加上了注釋,還分析了我寫的代碼,請看:
/*
* @brief 計算交流信號的RMS值、平均值和頻率,使用狀態(tài)機跟蹤過零點和半周期
* @param p 包含計算所需狀態(tài)和數(shù)據(jù)的結(jié)構(gòu)體指針
* @param ac_input 當前采樣點的交流輸入值
* @param ts 采樣時間間隔(單位:秒)
* @return float32_t 經(jīng)過濾波處理后的RMS平均值
* @note 采用滑動窗口算法和低通濾波算法提高測量穩(wěn)定性
* 狀態(tài)機實現(xiàn)過零點檢測和周期測量,支持45-65Hz動態(tài)頻率調(diào)整
*/
static inline float32_t ac_rms_avg_freq_caluc_func(AC_AVG_CALUC_DEF *p,
float32_t ac_input,
float32_t ts)
{
/* 過零檢測閾值定義(單位:伏特) */
const float32_t threshold_PZC1 = -5.0f; /* 正半周過零點1閾值 */
const float32_t threshold_PZC2 = 5.0f; /* 正半周過零點2閾值 */
const float32_t threshold_NZC1 = 5.0f; /* 負半周過零點1閾值 */
const float32_t threshold_NZC2 = -5.0f; /* 負半周過零點2閾值 */
/* 動態(tài)調(diào)整時間增益系數(shù)(基于當前平均頻率) */
if ((p->ac_freq_avg > 45.0f) && (p->ac_freq_avg < 65.0f)) {
/* 計算理論半周期增益: 2*Freq*Ts = 1/(半周期樣本數(shù)) */
p->TS_half_gain = p->ac_freq_avg * 2.0f * ts;
} else {
/* 默認增益對應50Hz: 50*2*0.0001s=0.01 → 1/0.01=100樣本/半周期 */
p->TS_half_gain = 0.02f;
}
/* 狀態(tài)機處理交流信號波形 */
switch (p->ac.enum_ac_State) {
case ac_normal: /* 初始狀態(tài):檢測首個過零點 */
if (ac_input < threshold_PZC1) {
p->ac.enum_ac_State = ac_positiveZeroCrossing1;
}
break;
case ac_positiveZeroCrossing1: /* 正半周過零階段1 */
if (ac_input > threshold_PZC1) {
p->ac.enum_ac_State = ac_positiveZeroCrossing2;
p->ac_freq_count += 1u; /* 開始周期計時 */
}
break;
case ac_positiveZeroCrossing2: /* 正半周過零階段2 */
if (ac_input > threshold_PZC2) {
p->ac.enum_ac_State = ac_positiveHalf;
p->ac_freq_count += 1u; /* 繼續(xù)周期計時 */
}
break;
case ac_positiveHalf: /* 正半周處理 */
/* 平方累加用于RMS計算 */
p->ac_rms[0] += (ac_input * ac_input);
/* 滑動窗口:保留最近4個采樣窗口的平方和 */
p->ac_rms[4] = p->ac_rms[3];
p->ac_rms[3] = p->ac_rms[2];
p->ac_rms[2] = p->ac_rms[1];
p->ac_rms[1] = p->ac_rms[0];
/* 正半周平均值計算(滑動窗口) */
p->pos_half_avg[1] += ac_input;
p->pos_half_avg[5] = p->pos_half_avg[4];
p->pos_half_avg[4] = p->pos_half_avg[3];
p->pos_half_avg[3] = p->pos_half_avg[2];
p->pos_half_avg[2] = p->pos_half_avg[1];
p->ac_freq_count += 1u; /* 累計周期采樣數(shù) */
/* 檢測負半周過零點 */
if (ac_input < threshold_NZC1) {
p->ac.enum_ac_State = ac_negativeZeroCrossing1;
/* 重置RMS歷史窗口(保留當前窗口ac_rms[0]) */
for (uint16_t i = 1; i < 4; i++) {
p->ac_rms[i] = 0;
}
/* 計算正半周平均值(5點加權(quán)平均) */
p->pos_half_avg[0] = 0.1f * p->TS_half_gain
* (p->pos_half_avg[1] + p->pos_half_avg[2]
+ p->pos_half_avg[3] + p->pos_half_avg[4]
+ p->pos_half_avg[5]);
/* 更新整體平均值 */
p->ac_avg = (p->pos_half_avg[0] + p->neg_half_avg[0]);
/* 清空負半周歷史數(shù)據(jù) */
for (uint16_t i = 1; i < 5; i++) {
p->neg_half_avg[i] = 0;
}
}
break;
case ac_negativeZeroCrossing1: /* 負半周過零階段1 */
if (ac_input < threshold_NZC1) {
p->ac.enum_ac_State = ac_negativeZeroCrossing2;
p->ac_freq_count += 1u;
}
break;
case ac_negativeZeroCrossing2: /* 負半周過零階段2 */
if (ac_input < threshold_NZC2) {
p->ac.enum_ac_State = ac_negativeHalf;
p->ac_freq_count += 1u;
}
break;
case ac_negativeHalf: /* 負半周處理 */
/* 平方累加用于RMS計算 */
p->ac_rms[0] += (ac_input * ac_input);
/* 滑動窗口更新 */
p->ac_rms[4] = p->ac_rms[3];
p->ac_rms[3] = p->ac_rms[2];
p->ac_rms[2] = p->ac_rms[1];
p->ac_rms[1] = p->ac_rms[0];
/* 負半周平均值計算(滑動窗口) */
p->neg_half_avg[1] += ac_input;
p->neg_half_avg[5] = p->neg_half_avg[4];
p->neg_half_avg[4] = p->neg_half_avg[3];
p->neg_half_avg[3] = p->neg_half_avg[2];
p->neg_half_avg[2] = p->neg_half_avg[1];
p->ac_freq_count += 1u;
/* 檢測正半周過零點(完成一個完整周期) */
if (ac_input > threshold_PZC1) {
p->ac.enum_ac_State = ac_positiveZeroCrossing1;
/* RMS計算流程:
* 1. 對5個窗口的平方和取平均(0.2系數(shù))
* 2. 乘以半周期時間增益和0.5(整合正負半周)
* 3. 取平方根得到RMS
*/
p->ac_rms_avg = sqrtf(p->TS_half_gain * 0.5f *
(0.2f * (p->ac_rms[0] + p->ac_rms[1]
+ p->ac_rms[2] + p->ac_rms[3]
+ p->ac_rms[4])));
/* 重置RMS窗口(保留當前窗口用于下次計算) */
for (uint16_t i = 0; i < 4; i++) {
p->ac_rms[i] = 0;
}
/* 計算負半周平均值(5點加權(quán)平均) */
p->neg_half_avg[0] = 0.1f * p->TS_half_gain
* (p->neg_half_avg[1] + p->neg_half_avg[2]
+ p->neg_half_avg[3] + p->neg_half_avg[4]
+ p->neg_half_avg[5]);
/* 更新整體平均值 */
p->ac_avg = (p->pos_half_avg[0] + p->neg_half_avg[0]);
/* 清空正半周歷史數(shù)據(jù) */
for (uint16_t i = 1; i < 5; i++) {
p->pos_half_avg[i] = 0;
}
/* 頻率計算流程:
* 1. 當前頻率 = 1/(總采樣數(shù) * 采樣時間)
* 2. 使用5點滑動窗口平均
* 3. 一階低通濾波平滑
*/
p->ac_freq[0] = 1.0f / (ts * p->ac_freq_count);
/* 更新頻率滑動窗口 */
p->ac_freq[4] = p->ac_freq[3];
p->ac_freq[3] = p->ac_freq[2];
p->ac_freq[2] = p->ac_freq[1];
p->ac_freq[1] = p->ac_freq[0];
/* 5點平均(權(quán)重總和為1) */
p->ac_freq_avg = 0.2f * (p->ac_freq[0] + p->ac_freq[1]
+ p->ac_freq[2] + p->ac_freq[3]
+ p->ac_freq[4]);
p->ac_freq_count = 0u; /* 重置周期計數(shù)器 */
}
break;
default: /* 異常狀態(tài)恢復 */
p->ac.enum_ac_State = ac_normal;
break;
}
/* 低通濾波處理(截止頻率20Hz) */
p->ac_freq_avg = lpf_1order_func(p->ac_freq_avg, &(p->freq_lpf), 20.0f, ts);
p->ac_rms_avg = lpf_1order_func(p->ac_rms_avg, &(p->rms_lpf_out), 20.0f, ts);
p->ac_avg = lpf_1order_func(p->ac_avg, &(p->avg_lpf_out), 20.0f, ts);
return p->ac_rms_avg; /* 返回濾波后的RMS值 */
}
下面 請看DS的解釋:
交流信號RMS與平均值計算實現(xiàn)文檔
版本:1.0 | 最后更新:2023-12-15
作者:智能助手 | 關(guān)鍵詞:交流信號處理、RMS計算、滑動窗口算法、過零檢測
目錄
-
設計目標
-
核心算法流程
-
有效值(RMS)計算方法
-
平均值計算方法
-
頻率測量原理
-
關(guān)鍵參數(shù)說明
-
應用示例
-
性能特性
1. 設計目標
本算法實現(xiàn)以下功能:
- 實時計算交流信號的:
- 有效值(True RMS)
- 整流平均值(Average Value)
- 基波頻率(Fundamental Frequency)
- 支持動態(tài)頻率跟蹤(45-65Hz自適應)
- 采用抗噪設計:
- 滑動窗口平均
- 低通濾波處理
- 滯回過零檢測
2. 核心算法流程
3. 有效值(RMS)計算方法
VRMS=1T∫0Tv(t)2dt
3.3 動態(tài)調(diào)整機制
- 窗口長度自適應:
if(freq在45-65Hz范圍){
TS_half_gain = 2 * Freq * Ts; // 動態(tài)調(diào)整
}else{
TS_half_gain = 0.02; // 50Hz默認值
}
確保不同頻率下積分時間恒定
4. 平均值計算方法
4.1 設計特點
- 分離正/負半周計算
- 采用整流平均值(Rectified Average)
- 滑動窗口降噪
4.2 計算流程
4.3 關(guān)鍵代碼
// 正半周處理
p->pos_half_avg[1] += ac_input; // 實時累加
p->pos_half_avg[0] = 0.1f * TS_half_gain * sum(pos_half_avg[1]~[5]);
// 負半周處理
p->neg_half_avg[1] += ac_input;
p->neg_half_avg[0] = 0.1f * TS_half_gain * sum(neg_half_avg[1]~[5]);
// 合并結(jié)果
p->ac_avg = pos_half_avg[0] + neg_half_avg[0];
4.4 數(shù)學關(guān)系
Vavg=2Vpπ≈0.6366V
5.1 周期測量法
實現(xiàn)步驟:
- 過零點觸發(fā)計時
- 統(tǒng)計兩個過零點間的采樣數(shù)
- 計算 Freq = 1/(N * Ts)
5.2 抗干擾設計
6. 關(guān)鍵參數(shù)說明
6.1 閾值參數(shù)
6.2 濾波器參數(shù)
7. 應用示例
7.1 輸入信號
- 波形:V(t) = 311 sin(2pi*50t) (220V RMS)
- 采樣率:10kHz(Ts=0.0001s)
7.2 計算過程
8. 性能特性
楊帥鍋時間:
總的來看,deepseek的理解了我的編寫的函數(shù)功能和實現(xiàn)原理,也給出了正確的分析,也幫我增加注釋。下面是仿真和測試,在PLECS 仿真軟件里面使用C腳本可以直接支持C99的C語言編碼,可見測試模型:
我使用一個帶高次諧波和直流偏置的多個正弦波疊加,用于測試RMS,直流偏置,頻率的數(shù)據(jù),下圖是在50HZ/峰峰值300.0,直流偏置0的標準正弦波的情況下測試,可見函數(shù)計算的頻率、有效值、直流分量都是正確的。
在考慮各種疊加高次諧波和直流偏置的情況下,可見:
波形:
通過測試可見,這代AC分析算法,可以很好的適用于各種正弦周期信號的分析和計算中,在PFC/逆變器的控制上有較多的可用性。為了優(yōu)化計算了,僅在狀態(tài)機的過零穿越點進行了一次總體數(shù)據(jù)計算,大量的簡約了CPU的時鐘開銷,對于節(jié)約成本和優(yōu)化代碼有意義。本人能力有限,如有錯誤懇請幫忙指正,感謝支持感謝幫助,謝謝。C代碼和PLECS模型下載:AC_RMS_AVG_FREQ_250302