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

標題: 單片機ADC多路轉換,有些程序語句不理解,求解釋 [打印本頁]

作者: zhth1979    時間: 2022-2-10 09:37
標題: 單片機ADC多路轉換,有些程序語句不理解,求解釋
后面注釋是我自己加上去的,不知道理解的對不對?還有if(count0<32)          //如果通道0轉換次數小于32 這個語句有沒有數據濾波功能,這有32可以是任意值嗎?

單片機源程序如下:
#include "adc.h"
#include "delay.h"

typedef unsigned char u8;
typedef unsigned int u16;

unsigned long int ADC_DATA0;        //           ADC0數據
unsigned long int ADC_DATA1;        //           ADC1數據
unsigned long int ADC_DATA2;        //           ADC2數據

u8  count0;        //        ADC通道0轉換次數記錄
u8  count1;        //        ADC通道1轉換次數記錄
u8  count2;        //        ADC通道2轉換次數記錄
u8  ADC_LINE;        //        ADC通道記錄

//ADC口初始化
void STC8ADC_INIT()                         //STC8ADC初始化
{
  P1M0=0x00;
  P1M1=0x07;        //設定P1.4567通道為高阻
//         P_SW2|=0X80;    //打開特殊功能寄存器
//   ADCTIM=0X3F;    //設置ADC內部時序
//   P_SW2&=0X7F;    //關閉特殊功能寄存器
  ADCCFG=0x2f;          //設置ADC的時鐘和轉換結果存放格式
  ADC_CONTR=0x80;//選擇ADC通道
  ADC_LINE=0x80;
  DelayXms(10);
  ADC_CONTR=ADC_CONTR|0x40;        //啟動ADC
  EADC=1;
}               

void ADC_ISR()interrupt 5
{
        ADC_CONTR=ADC_CONTR&0xdf;        //清除中斷標志位
//=============================================================================================================
        if(ADC_LINE==0x80)        //選擇通道0
                {  
                if(count0<32)          //如果通道0轉換次數小于32
                        {                        
                                 ADC_DATA0=0x00;    //ADC0數據清零
                                 count0=0x00;       //通道0轉換次數清零
                        }
                        ADC_DATA0=ADC_DATA0+(ADC_RES*256+ADC_RESL);        //ADC結果處理
                        count0++;            //通道0轉換次數加1
                        ADC_LINE=0x81;       //切換下一通道(通道1)
                        ADC_CONTR=ADC_LINE;   //下一通道值賦給配置寄存器
                }
//====================================================================
else if(ADC_LINE==0x81)      //選擇通道1
                {  
                if(count1<32)            //如果通道1轉換次數小于32
                        {
                                 ADC_DATA1=0x00;      //ADC1數據清零
                                 count1=0x00;         //通道1轉換次數清零
                        }
                        ADC_DATA1=ADC_DATA1+(ADC_RES*256+ADC_RESL);        //ADC結果處理
                        count1++;                //通道1轉換次數加1
                        ADC_LINE=0x82;           //切換下一通道(通道2)
                        ADC_CONTR=ADC_LINE;      //下一通道值賦給配置寄存器
                }
//=====================================================================
else if(ADC_LINE==0x82)     //選擇通道2
                {  
                if(count2<32)            //如果通道2轉換次數小于32
                        {
                                 ADC_DATA2=0x00;      //ADC2數據清零
                                 count2=0x00;         //通道2轉換次數清零
                        }
                        ADC_DATA2=ADC_DATA2+(ADC_RES*256+ADC_RESL);        //ADC結果處理
                        count2++;              //通道2轉換次數加1
                        ADC_LINE=0x80;         //切換下一通道(通道0)
                        ADC_CONTR=ADC_LINE;    //下一通道值賦給配置寄存器
                }

//=============================================================================================================                                   
        ADC_CONTR=ADC_CONTR|0x40;        //啟動ADC
}



作者: AUG    時間: 2022-2-10 10:37
這里是做一個累加,2個通道連續都采樣32次之后則清除ADC的數據。32你可以自己選擇。
作者: wd1988    時間: 2022-2-10 13:48
這個數值32應該是ad采樣32次后用來求平均值(濾波),每32次清零重新計數,這個數值可以根據使用調整
作者: zhth1979    時間: 2022-2-10 18:00
AUG 發表于 2022-2-10 10:37
這里是做一個累加,2個通道連續都采樣32次之后則清除ADC的數據。32你可以自己選擇。

也就是說只是獲取了32次ADC結果,但沒有對這32次結果處理?
作者: zhth1979    時間: 2022-2-10 18:00
wd1988 發表于 2022-2-10 13:48
這個數值32應該是ad采樣32次后用來求平均值(濾波),每32次清零重新計數,這個數值可以根據使用調整

也就是說只是獲取了32次ADC結果,但沒有對這32次結果處理?
作者: PEB188    時間: 2022-2-10 19:07
zhth1979 發表于 2022-2-10 18:00
也就是說只是獲取了32次ADC結果,但沒有對這32次結果處理?

為啥要加<32這句判斷。這句判斷的意義是什么?
作者: wd1988    時間: 2022-2-11 10:26
zhth1979 發表于 2022-2-10 18:00
也就是說只是獲取了32次ADC結果,但沒有對這32次結果處理?


是的,結合代碼的時意思  ADC_DATA0 變量存著32次ad采樣的值。
作者: zhth1979    時間: 2022-2-11 11:44
PEB188 發表于 2022-2-10 19:07
為啥要加

本來想三路ADC,每路讀32次結果在mian函數里求平均的,但感覺又好像不對,現在也不知道從哪處理比較合適?這個程序也是仿壇友的。
作者: wd1988    時間: 2022-2-11 13:52
zhth1979 發表于 2022-2-11 11:44
本來想三路ADC,每路讀32次結果在mian函數里求平均的,但感覺又好像不對,現在也不知道從哪處理比較合適 ...

                       if(count2<32)            //如果通道2轉換次數小于32
                        {
                                 ADC_DATA22 =ADC_DATA2/32;//可以放在清零前 用ADC_DATA22 存著求平均后的值
                                 ADC_DATA2=0x00;      //ADC2數據清零
                                 count2=0x00;         //通道2轉換次數清零
                        }
作者: Y_G_G    時間: 2022-2-11 16:38
你這代碼怎么像是我當初學C語言時的代碼?
給你一段我改過之后的代碼
注釋全在里面了,實際驗證過的/*──────────────────────────────────────────────────────────────────────────────────Stc8a4k_Adc.c文件
編寫:YGG
完成日期:20211120
功能:Stc8a系列單片機的ADC功能,采用中斷方式進行ADC
完成狀態:已經完成
──────────────────────────────────────────────────────────────────────────────────*/
#include "Stc8a.h"
#include "Stc8a_Adc.h"
#define         ADC_P10 0x80
#define         ADC_P11 0x81
#define         ADC_P12 0x82
#define         ADC_P13 0x83
#define         ADC_P14 0x84
#define         ADC_P15 0x85
#define         ADC_P16 0x86
#define         ADC_P17 0x87
#define         ADC_P1f 0x8f
#define     ADC_COUNT 32
//──────────────────────────────────────────────────────────────────────────────────────────────────
unsigned         char                  ADC_LINE;                                        //ADC通道記錄
unsigned         int                 ADC_AN0;                                        //ADC0數據
unsigned          int                 ADC_AN1;                                        //ADC1數據        
//──────────────────────────────────────────────────────────────────────────────────────────────────
void Stc8a_Adc_Init()                                                                 //ADC初始化
{
        unsigned int i;
        P1M1|=0x03;                                                                                //p1.0和p1.1用作ADC端口
        ADC_CONTR=0x80;                                                                        //打開adc電源
        ADCCFG=0x2f;                                                                        //設定ADC轉換結果保存格式,ADC時鐘選擇最慢       
        for(i=10000;i>0;i--);                                                         //延時一段時間
        ADC_CONTR=ADC_P10;                                                                //選擇P1.f端口ADC
        ADC_LINE=ADC_P10;                                                                //默認啟動的ADC通道
        ADC_CONTR|=0x40;                                                                //啟動ADC
        EADC=1;                                                                                        //ADC中斷允許
}
//─────────────────────────────────────────────────────────────────────────────────────────────
void ADC_ISR()interrupt 5                                                        //ADC中斷處理
{               
        static unsigned char                          count0;                        //ADC通道6轉換次數記錄
        static unsigned char                          count1;                        //ADC通道f轉換次數記錄,內部參考電壓通道
        static unsigned long int                 ADC_DATA0;                //ADC0數據,累加
        static unsigned long int                 ADC_DATA1;                //ADCf數據,累加       
        ADC_CONTR&=~0x20;                                                                //清除中斷標志位
        //──────────────────────────────────────────────────────────────────────────
        if(ADC_LINE==ADC_P10)                                                          //檢測觸發ADC中斷的通道
                {  
                        if(count0>=ADC_COUNT)                                         //檢測ADC轉換次數
                                {
                                         ADC_AN0=ADC_DATA0/ADC_COUNT;          //取平均值
                                         ADC_DATA0=0x00;                                          //清除ADC累加結果
                                         count0=0x00;                                          //清除ADC轉換次數記錄
                                }
                        ADC_DATA0+=ADC_RES*256+ADC_RESL;                //ADC結果累加
                        count0++;                          
                        ADC_CONTR=ADC_LINE=ADC_P11;                                //選擇下一個ADC通道
                }
        //──────────────────────────────────────────────────────────────────────────
        else if(ADC_LINE==ADC_P11)
                {  
                        if(count1>=ADC_COUNT)
                                {
                                         ADC_AN1=ADC_DATA1/ADC_COUNT;
                                         ADC_DATA1=0x00;
                                         count1=0x00;
                                }
                        ADC_DATA1+=ADC_RES*256+ADC_RESL;       
                        count1++;                                                          
                        ADC_CONTR=ADC_LINE=ADC_P10;
                }
        //──────────────────────────────────────────────────────────────────────────                 
        ADC_CONTR|=0x40;                                                                //啟動ADC
}
//─────────────────────────────────────────────────────────────────────────────────────────────


作者: zhth1979    時間: 2022-2-12 20:52
Y_G_G 發表于 2022-2-11 16:38
你這代碼怎么像是我當初學C語言時的代碼?
給你一段我改過之后的代碼
注釋全在里面了,實際驗證過的/*── ...

if(count0>=ADC_COUNT)                       //檢測ADC轉換次數             這樣寫轉換次數不是沒有限制了嗎?后面為什么還是除32,不應該是 if(count0<ADC_COUNT) 嗎?
作者: zhth1979    時間: 2022-2-12 20:54
wd1988 發表于 2022-2-11 13:52
if(count2

感覺這樣是對的,但我把32改成50次或100次結果為什么不一樣,相差很多!
作者: Y_G_G    時間: 2022-2-12 23:13
zhth1979 發表于 2022-2-12 20:52
if(count0>=ADC_COUNT)                       //檢測ADC轉換次數             這樣寫轉換次數不是沒有 ...

不是有這句嗎?
count1=0x00;
/32是因為這是累加32次的結果,想要真實的數字量,就要/32
代碼是肯定沒有問題的,實際在STC8A4K單片機上運行過的

作者: rundstedt    時間: 2022-2-13 22:32
不對啊,count0沒到32就被清零了。
作者: wd1988    時間: 2022-2-14 11:56
zhth1979 發表于 2022-2-12 20:54
感覺這樣是對的,但我把32改成50次或100次結果為什么不一樣,相差很多!

                        if(count2<32)            //如果通道2轉換次數小于32
                        {
                                 ADC_DATA2=0x00;      //ADC2數據清零
                                 count2=0x00;         //通道2轉換次數清零
                        }
                       之前沒注意看  代碼這 轉換次數count2 是不是要 count2 > 32   不是累加 次數嗎 ?
                       還是你的 count2初始值時32想要累減的。
                       if(count2>32)            //如果通道2轉換次數大于32
                        {
                                 ADC_DATA2=0x00;      //ADC2數據清零
                                 count2=0x00;         //通道2轉換次數清零
                        }
                        不然  count2 , ADC_DATA2 一直清零。
                        然后你的AD值獲取在清零后面,所以你改32 50 100得到不一樣的值,實際可能只是獲取一次ad值。

作者: zhth1979    時間: 2022-3-4 08:53
Y_G_G 發表于 2022-2-12 23:13
不是有這句嗎?
count1=0x00;
/32是因為這是累加32次的結果,想要真實的數字量,就要/32

查了一下,這個程序就是仿您的,您之前的程序是if(count0<32) 而后面卻也是 count0++;   現在這個程序是  if(count0>=ADC_COUNT) 也是 count0++;  兩者都能獲得ADC值,前者穩定,但它卻不能隨傳感器的變化而變化,后者可以,但值會跳動。是不是平均濾波不行?您能不能在后者的基礎上幫我改寫成中位置濾波?
作者: Y_G_G    時間: 2022-3-4 17:12
zhth1979 發表于 2022-3-4 08:53
查了一下,這個程序就是仿您的,您之前的程序是if(count0=ADC_COUNT) 也是 count0++;  兩者都能獲得ADC值 ...

前面的是我剛學C語言的時候寫的,沒有認真的驗證過,也不知道有沒有不對的地方
后面10#的是我驗證過的,肯定是對的了
至于跳動是肯定會有的,不管用什么濾波方式,都會跳動的,我之前就是用的中位濾波,后來發現沒什么效果,就改為平均濾波了
作者: tatachaoren    時間: 2022-3-4 18:46
if(count1<32)                                                                      //如果通道1轉換次數小于32
{
      ADC_DATA1=0x00;                                                         //ADC1數據清零
      count1=0x00;                                                                //通道1轉換次數清零
}
ADC_DATA1=ADC_DATA1+(ADC_RES*256+ADC_RESL);        //ADC結果處理
count1++;                                                                         //通道1轉換次數加1
ADC_LINE=0x82;                                                                 //切換下一通道(通道2)
ADC_CONTR=ADC_LINE;                                                      //下一通道值賦給配置寄存器

這個三個一樣功能的代碼的條件是不是有問題呢,count1<32條件每次進來判斷都是對的,count1計數和AD采集值都清零了。
count1<32這個條件如果要取平均值應該是反過來:count1>=32,當條件成立,就在if里面進行平均取值,和其他處理。

一般來說AD取值都是用平均值的,AD跳動不管哪個芯片都會有,比如近幾年來很火的芯海科技,我用過他的芯片,有時候還不如國產的AD芯片(有時候誤差在0.1V左右,不過我想誤差縮減到0.05V左右,就采用了其他的芯片),只是看人的接受范圍,誤差在0.1V內一般都是默認可以接受的。
作者: zhth1979    時間: 2022-4-29 14:45
tatachaoren 發表于 2022-3-4 18:46
if(count1

你說的對,已經改過來了,現在正常了!




歡迎光臨 (http://m.raoushi.com/bbs/) Powered by Discuz! X3.1