![]() |
發布時間: 2018-4-2 10:36
正文摘要:1、ADC采集出現+-1的偏移量; 例:采集到的數值始終在570 571 572 三個數值中跳變 2、采集目標為NTC溫感電阻 3、原理圖如下 4、ADC采集及濾波代碼如下 <div>#include <adc.h> #inclu ... |
最近我也在調試一個AD相關的項目,剛好測試了這段濾波代碼,感覺確實波動很大。用了一個最基本的平均數濾波也比這個效果好。樓主可以試一試。 u16 Get_Adc_Average(u8 ch,u8 times) { u32 temp_val=0; u8 t; for(t=0;t<times;t++) { temp_val+= Get_ADC10bitResult(ch); delay_us(10); } return temp_val/times; } |
snchj 發表于 2019-11-26 21:23 這個硬件同我的想法一樣,我的AD也用了47uF,對反應不用太快的檢測大電容確實有效。 |
bh2030693 發表于 2019-11-23 22:50 其實我司在做項目時都是這樣做,一般做鋰電池電量檢測開關保護都是在單片機采樣腳前(盡量離IC腳要近)串個1K再用一個106P濾波,效果很好。如果要實時顯示,做個一表或取個平均值就行。一個項目要軟硬結合才是最好解決方法。 |
我也遇到這樣的問題 我是用溫度來控制繼電器的打開和關閉 因為跳變導致繼電器一直嗒嗒嗒 |
哪個并在上拉電阻上的電容有點詭異,并到NTC上倒可以理解! |
這是誤差之內的數字可以接受啊,后起處理就行了 |
剛才看了這位朋友的程序,大概過程看明白了,那個溫度函數沒用過,詳細原理暫時不了解。對這段程序做了個簡單的修改。 主要是對ADC做了一點修改:因為每次要關閉ADC,所以下次打開應該等待穩定延時; 對計算函數做了一點簡化:因為偏置電阻阻值10K等于Rp,所以抵消了一步計算; 對濾波做了一點修改:因為用左移代替除法能更快一點; 以上修改對結果估計也沒啥幫助,只是共師兄習一下。因為沒有條件測試,如有錯誤望網友及時指正。 #include <adc.h> #include "math.h" #define ADC_POWER 0x80 // ADC電源控制位 #define ADC_FLAG 0x10 // ADC完成標志位 #define ADC_START 0x08 // ADC起始控制位 #define ADC_SPEEDLL 0x00 // 540個時鐘周期 // #define BUFF_LENGTH 12 const float Rp = 10000.0; // 10K const float T2 = (273.15 + 25.0); // T2 const float Bx = 3950.0; // B const float Ka = 273.15; /*---------------------------- 讀取ADC結果 ----------------------------*/ uint GetADCResult(uchar ch) { ADC_CONTR = ADC_POWER | ADC_SPEEDLL; Delay2(2); // ADC上電延時 ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START; while (!(ADC_CONTR & ADC_FLAG)) { } //等待ADC轉換完成 ADC_CONTR &= ~ADC_FLAG; // Close ADC return ((uint)ADC_RES << 2 | ADC_RESL); //返回ADC結果 } /****************濾波*****************/ #define BUFF_LENGTH 18 // 過濾函數數組長度 uint filter(uchar chnn) { uint i; uint j; uint uiTemp; uint uiSum; uint uiBuf[BUFF_LENGTH]; for (i = 0; i < BUFF_LENGTH; i++) { uiBuf[i] = GetADCResult(chnn); Delay2(2); } // 排序:把最大值移到數組最后,最小值留到數組最前 for (j = 0; j < BUFF_LENGTH - 1; j++) { for (i = 0; i < BUFF_LENGTH - 1 - j; i++) { if (uiBuf[i] > uiBuf[i + 1]) { uiTemp = uiBuf[i]; uiBuf[i] = uiBuf[i + 1]; uiBuf[i + 1] = uiTemp; } } } // 取中間(BUFF_LENGTH - 2)個數,求平均值 for (i = 1; i < BUFF_LENGTH - 1; i++) { uiSum += uiBuf[i]; } // uiSum = uiSum / (BUFF_LENGTH - 2); uiSum >>= 4; // uiSum / 16 return uiSum; } /********AD數值轉換阻值**********/ /*double AD_R(uchar chn) { double adcDataTR; // 溫敏電阻上的分壓數據 double adcDataR; // 偏置電阻上的分壓數據 double rT; // 溫敏電阻阻值 adcDataTR = filter(chn); adcDataR = 1023 - adcDataTR; rT = 10000 / adcDataR * adcDataTR; return rT; }*/ /************阻值轉換溫度******************/ float Get_Temp(uchar chhhh) { // float Rt; float adcDataTr; // 溫敏電阻上的分壓的ADC數據 float temp; // Rt = AD_R(chhhh); adcDataTr = filter(chhhh); // like this R=5000, T2=273.15+25,B=3470, // RT=5000*EXP(3470*(1/T1-1/(273.15+25)), // temp = Rt / Rp; // = 10000 / adcDataR * adcDataTr / Rp; // 因為(Rp=上拉偏置電阻10000) // temp = adcDataTr / adcDataR; temp = adcDataTr / (1023 - adcDataTr); temp = log(temp); // ln(Rt/Rp) temp /= Bx; // ln(Rt/Rp)/B temp += (1 / T2); temp = 1 / (temp); temp -= Ka; temp += 0.5; // 加0.5誤差矯正 temp = temp * 10; return temp; } /*---------------------------- 初始化ADC ----------------------------*/ void InitADC(void) { P1ASF = 0xff; //設置P1口為AD口 CLK_DIV &= ~0x20; ADC_RES = 0; //清除結果寄存器 ADC_RESL = 0; } /*---------------------------- 延時 ----------------------------*/ void Delay2(uint n) { uint x; while (n--) { x = 5000; while (x--); } } |
你這個是硬件問題,103P不要串聯在電阻上,換成106P一邊接地當濾波電容,這樣就不會跳了。 |
鄧文雄ABC 發表于 2018-4-8 09:35 并不是每次都是這樣的,采集三次 可能出現的全都是572 572 572 也可能是573 572 572 |
求學,跟著各位大佬學習 |
三個值相加,取平均值使用。 |
如果數值在一個范圍內穩定變化,可以在三個值取平均值,那不就很穩定了嗎? |
NTC熱敏電阻的溫阻曲線是非線性的,用浮點計算的方法誤差很大。一般用廠家提供的溫阻表為基礎制作數組表格,用ADC轉換結果通過查表法獲取溫度值為佳。 與7樓意見相同! |
可以查表,然后換個算法試試。 |
大米飯 發表于 2018-4-7 10:00 不管你采用什么方法濾波都不容易得到非常穩定的數值,“采集數值一直在570 571 572 中來回跳轉”說明你得到的數據已經足夠穩定了,只是你對數據的后期處理不到位,才致使你感覺不穩定。 |
HEIZI555 發表于 2018-4-5 13:47 代碼中已經包含濾波算法,并且嘗試了多種濾波算法 均不能保證每次濾波后出現穩定數值 |
15861476366 發表于 2018-4-5 13:18 有濾波算法,依舊出現溫度跳變,這個不知道怎么樣才能解決,或者有什么更好的濾波算法 |
nklug 發表于 2018-4-4 20:53 我的代碼中,包含了軟濾波,主要是ADC采集數值一直在570 571 572 中來回跳轉,致使計算得出的溫度一直跳變 |
wulin 發表于 2018-4-4 15:42 討論的問題并不是溫度是否準確,而是ADC采集的數據出現浮動漂移,謝謝你的回答 |
網上有詳細的濾波器算法說明,找找下 |
采用查表法,并使用較穩定電源。 |
不是說好了 24小時必答嗎???求指教啊……那位前輩高人上帝老大來幫我一下 卡了好多天了 |
那位大神來幫幫我啊 怎么一個人都沒有呢 求救啊 |