|
發布時間: 2025-6-26 11:51
正文摘要:AC220交流電采集方案 交流電峰值311除以220=1.41伏 最大值為1.4伏,有效值為1.4除以根號2等于0.997伏 |
| 很給力! |
|
#define SAMPLE_RATE 500 // 每500us采樣一次(2kHz) u16 adc_samples[40]; // 采樣緩沖區(20ms/500us=40個樣本) u8 sample_index = 0; u32 sample_sum = 0; // 采樣總和 u8 full_window = 0; // 窗口是否填滿標志 // 全局變量用于平滑濾波 #define FILTER_SHIFT 5 // 使用5位右移實現1/32系數 // 定時器1中斷(500us周期) void Timer1_ISR(void) interrupt 3 { static uint adc_timer = 0; uint raw_adc; uint filtered_adc = 0; // 濾波后的ADC值(累加形式) u16 raw_value; // ====== 校準完成處理 ====== if (cal_ok_display) { cal_ok_counter++; if (cal_ok_counter >= 2000) { // 2000 * 500us = 1秒 cal_ok_display = 0; in_calibration = 0; // 退出校準模式 } } // 顯示刷新 Display(); // ADC采樣控制 if(++adc_timer >= (SAMPLE_RATE/500)) { adc_timer = 0; // 啟動ADC轉換 ADC_RES = 0; ADC_RESL = 0; ADC_CONTR = (ADC_CONTR & 0xF0) | 0x40 | 11; // 通道11 } // 讀取上次ADC結果 if(ADC_CONTR & 0x20) { raw_adc = ((ADC_RES & 0x03) << 8) | ADC_RESL; ADC_CONTR &= ~0x20; // 滑動窗口處理 if(full_window) { sample_sum -= adc_samples[sample_index]; } sample_sum += raw_adc; adc_samples[sample_index] = raw_adc; if(++sample_index >= sizeof(adc_samples)/sizeof(adc_samples[0])) { sample_index = 0; full_window = 1; } // 當窗口滿時計算平均值 if(sample_index == 0 && full_window) { u16 avg = sample_sum / 40; // 40個樣本平均 raw_avg = avg; // 保存原始平均值用于校準 // 原始ADC值轉換 (0-1023 -> 0-250) raw_value = (u16)((unsigned long)avg * calibration / 1023); /********** IIR低通濾波 **********/ if (filtered_adc == 0) { filtered_adc = (uint)raw_value << FILTER_SHIFT; } else { filtered_adc = filtered_adc - (filtered_adc >> FILTER_SHIFT) + raw_value; } // 獲取濾波后的值并四舍五入 pv_value = (filtered_adc + (1 << (FILTER_SHIFT-1))) >> FILTER_SHIFT; } } } // ====== 校準相關變量 ====== bit is_calibrated = 0; // 校準標志位 0-未校準 1-已校準 bit in_calibration = 0; // 校準模式標志 bit cal_ok_display = 0; // 顯示OK標志 uint cal_ok_counter = 0; // OK顯示計數器 uint raw_avg = 0; // 原始ADC平均值(0-1023) uint calibration = 250; // 校準系數 // ====== 校準模式按鍵處理 ====== if (in_calibration && !cal_ok_display) { // KEY4: 確認校準 if(key_pressed[3]) { key_pressed[3] = 0; // 清除按鍵標志 // 執行校準計算 if (raw_avg != 0) { calibration = (220 * 1023UL) / raw_avg; is_calibrated = 1; // 設置校準標志 cal_ok_display = 1; // 顯示OK cal_ok_counter = 0; // 重置計數器 } } } |
交流取樣.PNG (19.94 KB, 下載次數: 0)
cr8526 發表于 2025-6-30 23:11 存在這個隱患。所以我最終采用了電壓互感器和電流互感器的方式來采樣。 |
| 萬一其中一個電阻燒了,會不會把人給電到的 |
| 能說說電路的原理嗎? |