久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3152|回復: 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檢測完成的值加在一起平均,戓更好的檢測方法 望指高點
回復

使用道具 舉報

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次, 前兩次拋棄, 第三次開始,每次累加,結束后右移三位,搞定收工。
回復

使用道具 舉報

ID:130230 發表于 2021-10-8 15:01 | 顯示全部樓層
平滑移動濾波,每次進一個出一個。然后取最近10次的平均值。
回復

使用道具 舉報

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

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

使用道具 舉報

ID:65237 發表于 2021-10-8 21:20 來自觸屏版 | 顯示全部樓層
鄭漢松 發表于 2021-10-8 10:33
連續采集20次AD,去掉頭尾5次的AD值,中間10次的取平均值,這樣求出來的數據比較穩定

謝謝老師
回復

使用道具 舉報

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

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

使用道具 舉報

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. }
復制代碼
回復

使用道具 舉報

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

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

使用道具 舉報

ID:65237 發表于 2021-10-9 21:28 來自觸屏版 | 顯示全部樓層
wulin 發表于 2021-10-8 21:34
ADC.C文件,適合STC15W408AS

十分感謝
回復

使用道具 舉報

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位,也是一樣的性質。
回復

使用道具 舉報

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位編譯之后的匯編代碼是一樣的,效率是一樣的
你試一下就知道了
回復

使用道具 舉報

ID:908826 發表于 2021-10-10 10:53 | 顯示全部樓層
給我你的郵箱,我有個數字濾波的pdf可以給你分享。
回復

使用道具 舉報

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;
}


回復

使用道具 舉報

ID:956872 發表于 2021-10-13 10:03 | 顯示全部樓層
wulin 發表于 2021-10-8 21:34
ADC.C文件,適合STC15W408AS

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

使用道具 舉報

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 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美一级α片 | 精品国产乱码久久久久久88av | 欧美极品在线观看 | 人人干人人玩 | www..com18午夜观看 | 亚洲国产精品一区二区三区 | 日韩电影中文字幕 | 欧美日韩在线一区二区 | 在线视频成人 | 日韩av成人 | 欧美一区二区三区在线看 | 成人精品视频免费 | 欧美日韩综合 | 综合久久av | 欧美日韩黄色一级片 | 羞羞视频一区二区 | 91看片网| 99久久久久久 | 高清视频一区二区三区 | 在线免费国产视频 | 农夫在线精品视频免费观看 | 欧美激情精品久久久久久变态 | 中文字幕欧美一区 | 亚洲欧美日韩一区二区 | 日本视频免费观看 | 天天射天天操天天干 | 精品国产1区2区3区 在线国产视频 | 在线观看国产网站 | 亚洲欧美精品国产一级在线 | 国产成人午夜电影网 | 国产精品日韩欧美一区二区三区 | 日韩精品一区二区三区中文字幕 | 日韩在线播放一区 | 国产精品久久久久久一区二区三区 | 91国产精品在线 | 日韩高清一区 | 国产免费一级一级 | 日韩av成人在线 | 国产一区二区在线免费播放 | 国产高清在线观看 | 国产成人精品免费视频大全最热 |