欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3449|回復: 16
打印 上一主題 下一主題
收起左側

關于stc15w108單片機ad平均值怎么寫好?望高手指點

  [復制鏈接]
跳轉到指定樓層
樓主
ID:65237 發表于 2021-10-7 23:18 來自觸屏版 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
手上有15w408as想做個檢測電壓的 ,PWM輸出控制  MOS管開關 再串一個0.33歐姆電阻到地 電源24伏供電.電流200ma 檢測0.33上的電壓去控制pwm脈寬讓MOS管電流保持在200左右 現在是ad檢測值想做個平均 如用for循環 5次 平均 是連續檢測5次了 還是等ad檢測時間到了算一次 等5次ad檢測完成的值加在一起平均,戓更好的檢測方法 望指高點
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:752974 發表于 2021-10-8 10:23 | 只看該作者
每次啟動AD,連續轉換需要的次數,然后關掉ad,處理數據,數字濾波可以用平均值法,或裁判法,即去掉一個最大的,去掉一個最小的,再取平均值。
回復

使用道具 舉報

板凳
ID:514901 發表于 2021-10-8 10:33 | 只看該作者
連續采集20次AD,去掉頭尾5次的AD值,中間10次的取平均值,這樣求出來的數據比較穩定
回復

使用道具 舉報

地板
ID:624769 發表于 2021-10-8 13:48 | 只看該作者
一般不會取5次……, 大多10次以上的, 不然沒有平均的意義。
正常做法,一共取10次, 前兩次拋棄, 第三次開始,每次累加,結束后右移三位,搞定收工。
回復

使用道具 舉報

5#
ID:130230 發表于 2021-10-8 15:01 | 只看該作者
平滑移動濾波,每次進一個出一個。然后取最近10次的平均值。
回復

使用道具 舉報

6#
ID:65237 發表于 2021-10-8 21:19 來自觸屏版 | 只看該作者
munuc_w 發表于 2021-10-8 10:23
每次啟動AD,連續轉換需要的次數,然后關掉ad,處理數據,數字濾波可以用平均值法,或裁判法,即去掉一個最 ...

你的意思是不是,如以10次為例正常ad起動10次,把這每次得到的值依次加在一起,放在一個變量中 然后除以10得到他的平均值
回復

使用道具 舉報

7#
ID:65237 發表于 2021-10-8 21:20 來自觸屏版 | 只看該作者
鄭漢松 發表于 2021-10-8 10:33
連續采集20次AD,去掉頭尾5次的AD值,中間10次的取平均值,這樣求出來的數據比較穩定

謝謝老師
回復

使用道具 舉報

8#
ID:65237 發表于 2021-10-8 21:30 來自觸屏版 | 只看該作者
188610329 發表于 2021-10-8 13:48
一般不會取5次……, 大多10次以上的, 不然沒有平均的意義。
正常做法,一共取10次, 前兩次拋棄, 第三 ...

為什么是右移三位了  不明白望指點 10位ad滿是1024丟前二后三剩下5次的總和,最大是5120右移3位得5不明白
回復

使用道具 舉報

9#
ID:213173 發表于 2021-10-8 21:34 | 只看該作者
ADC.C文件,適合STC15W408AS
  1. #include <STC15F2K60S2.H>
  2. #include <intrins.H>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. /*----------------------------
  6.         ADC操作相關的宏定義
  7. ----------------------------*/
  8. #define ADC_POWER   0x80            //ADC power control bit
  9. #define ADC_FLAG    0x10            //ADC complete flag
  10. #define ADC_START   0x08            //ADC start control bit
  11. #define ADC_SPEEDLL 0x00            //420 clocks
  12. #define ADC_SPEEDL  0x20            //280 clocks
  13. #define ADC_SPEEDH  0x40            //140 clocks
  14. #define ADC_SPEEDHH 0x60            //70 clocks

  15. uint ADC_mV;

  16. void Init_ADC();                                //初始化ADC
  17. uint GetADCResult(uchar CHA);        //獲取AD通道轉換結果
  18. void ADC_Average();                                //ADC平均值

  19. /*-----------------------------------------------------------------------------
  20.   InitADC 初始化ADC
  21. -----------------------------------------------------------------------------*/
  22. void Init_ADC()
  23. {
  24.         P1ASF=0x08;                                                //設置P1.3通道端口作為模擬輸入
  25.         ADC_RES=0;                                                //清除ADC_RES存儲器以前的結果
  26.         ADC_RESL=0;
  27.         ADC_CONTR=ADC_POWER|ADC_SPEEDLL;//ADC 開啟電源、轉換速度 1000 0000
  28.         delayms(1);                                                //上電延時1ms                                                                                       
  29. }
  30. /*----------------------------------------------------------------------------
  31. Get ADC Result(獲取ADC結果)
  32. ----------------------------------------------------------------------------*/
  33. uint GetADCResult(uchar CHA)                //獲取ADC結果
  34. {
  35.         ADC_CONTR=ADC_POWER|ADC_SPEEDLL|CHA|ADC_START;//啟動轉換1000 1000
  36.     _nop_();                        //延時確保正確讀到ADC_CONTR寄存器的值
  37.     _nop_();
  38.     _nop_();
  39.     _nop_();
  40.         while(!(ADC_CONTR & ADC_FLAG));        //等待ADC轉換完成標志置位 1001 1000
  41.         ADC_CONTR &=~ADC_FLAG;                        //關閉ADC
  42.         return ADC_RES<<2|ADC_RESL ;                //返回十位ADC結果
  43. }
  44. /*-------------------------------
  45.   1ms延時子程序(11.0592MHz 1T)
  46. -------------------------------*/
  47. void delayms(uint k)
  48. {
  49.         uint i,j;
  50.         for(i=k;i>0;i--)
  51.                 for(j=829;j>0;j--);
  52. }
  53. /*-------------------------------
  54.   ADC平均值
  55. -------------------------------*/
  56. void ADC_Average()
  57. {
  58.         static uint temp;
  59.         static uchar count=0;
  60.         temp+=GetADCResult(n);//n=0~7
  61.         count++;
  62.         if(count>=10)                                        //累計數十次采樣
  63.         {
  64.                 count=0;                                        //計數器清0
  65. //                ADCV=VCC*10bitAD/1024;                //換算公式
  66.                 ADCmV=(5000*(long)temp/1024+5)/10;//四舍五入
  67.                 temp=0;
  68.         }
  69. }
復制代碼
回復

使用道具 舉報

10#
ID:752974 發表于 2021-10-9 08:33 | 只看該作者
阿飛7812 發表于 2021-10-8 21:19
你的意思是不是,如以10次為例正常ad起動10次,把這每次得到的值依次加在一起,放在一個變量中 然后除以1 ...

是的,就是這個意思。
回復

使用道具 舉報

11#
ID:65237 發表于 2021-10-9 21:28 來自觸屏版 | 只看該作者
wulin 發表于 2021-10-8 21:34
ADC.C文件,適合STC15W408AS

十分感謝
回復

使用道具 舉報

12#
ID:624769 發表于 2021-10-9 21:54 | 只看該作者
阿飛7812 發表于 2021-10-8 21:30
為什么是右移三位了  不明白望指點 10位ad滿是1024丟前二后三剩下5次的總和,最大是5120右移3位得5不明白

右移3位,相當于 除以8,但是效率比除以8高很多,取10次舍棄前2次,剩下的8次累加后右移3位就是平均值,16次累加右移4位,也是一樣的性質。
回復

使用道具 舉報

13#
ID:401564 發表于 2021-10-9 23:06 | 只看該作者
188610329 發表于 2021-10-9 21:54
右移3位,相當于 除以8,但是效率比除以8高很多,取10次舍棄前2次,剩下的8次累加后右移3位就是平均值,1 ...

其實是一樣的
在Keil中,C的位移在編譯時并不是位移,而是加法減法之類的
除以8和右移3位編譯之后的匯編代碼是一樣的,效率是一樣的
你試一下就知道了
回復

使用道具 舉報

14#
ID:908826 發表于 2021-10-10 10:53 | 只看該作者
給我你的郵箱,我有個數字濾波的pdf可以給你分享。
回復

使用道具 舉報

15#
ID:554500 發表于 2021-10-12 16:14 | 只看該作者

連續取10個樣(多取一些也可以),然后就行大小排序。
最后取中間兩個相加,再除以2就可以了。


// 經典冒泡排序
void BubbleSort(u16 *arr, u8 n)
{
        int i = 0, j =0;
        for(i = 0; i < n; i++)
        for(j = 0; j < n - 1 - i; j++)
        {
                if(arr[j] > arr[j + 1])
                {
                        arr[j] = arr[j] ^ arr[j+1];
                        arr[j+1] = arr[j] ^ arr[j+1];
                        arr[j] = arr[j] ^ arr[j+1];
                }
        }
}

void ADC_Read_Switch()
{
        u16 xdata val[10];
        u8  xdata j;
       
        for(j=0;j<10;j++)
                val[j]=ADC_START(ADC_CH0); //通道0,連續采樣5次
        BubbleSort(val,10); //排序
        AD0=(val[4] + val[5])/2;
}


回復

使用道具 舉報

16#
ID:956872 發表于 2021-10-13 10:03 | 只看該作者
wulin 發表于 2021-10-8 21:34
ADC.C文件,適合STC15W408AS

我用的408AS,用這程序編譯了,為啥百位后面會跳變。還有最大有0.6V多的誤差。最高只能顯示4.99V。
回復

使用道具 舉報

17#
ID:65237 發表于 2021-10-17 10:34 | 只看該作者
Y_G_G 發表于 2021-10-9 23:06
其實是一樣的
在Keil中,C的位移在編譯時并不是位移,而是加法減法之類的
除以8和右移3位編譯之后的匯編 ...

謝謝 我試試
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表