標題: STC8A8K單片機多路ADC采集得到的結(jié)果一模一樣,可能會是什么問題? [打印本頁]

作者: zqz1345444061    時間: 2021-7-25 15:37
標題: STC8A8K單片機多路ADC采集得到的結(jié)果一模一樣,可能會是什么問題?
單片機程序如下,求大神指導
  1. #include  <stc8.h>
  2. #include  <delay.h>
  3. #include  <uart.h>
  4. #include  <adc12.h>
  5. #include  <adc13.h>        
  6. #include  <adc14.h>

  7. //float R;

  8. void main()
  9. {
  10.         P3M1 &= 0xFE;        P3M0 &= 0xFE;                          //設(shè)置P3.0為準雙向口
  11.         P3M1 &= 0xFD;        P3M0 |= 0x02;                          //設(shè)置P3.1為推挽輸出
  12.                
  13.         ADC12_config();         
  14.         ADC13_config();
  15.   ADC14_config();                             //ADC初始化

  16.         Uart1_Init();                                 //串口1初始化         
  17.         EA = 1;                                       //使能總中斷
  18.   Delay10ms();                                  //初始化后延時
  19.         
  20. //        R=(HandleADC13()*3000)/(2*HandleADC12()-HandleADC13());  //輸入電阻計算
  21.         
  22.   while (1)
  23.         {
  24.                  printf("\r\n P0.4上的電壓: %.3f\r\n",HandleADC12());      //輸入電壓1        
  25.                  printf("\r\n P0.5上的電壓: %.3f\r\n",HandleADC13());      //輸入電壓2        
  26.                  printf("\r\n P0.6上的電壓: %.3f\r\n",HandleADC14());      //輸出電壓               
  27. //                  printf("\r\n 電壓增益: %.3f\r\n",HandleADC14()/HandleADC13());     //串口打印上傳的采集的電壓值
  28. //           printf("\r\n 輸入電阻: %.1f\r\n",R);        
  29.      Delay1000ms();
  30.         }
  31. }

復制代碼


差分放大電路電壓放大倍數(shù)ADC測量.zip

89.73 KB, 下載次數(shù): 40


作者: Y_G_G    時間: 2021-7-25 23:38
你看一下你的ADC程序里面有沒有這個查詢ADC完成標志位的我是沒有在你程序里找到
ADC是要一個過程的,啟動ADC之后,如果是查詢方式的話,是要一直等待ADC完成才能正確的得到ADC結(jié)果的



作者: zqz1345444061    時間: 2021-7-26 09:12
Y_G_G 發(fā)表于 2021-7-25 23:38
你看一下你的ADC程序里面有沒有這個查詢ADC完成標志位的我是沒有在你程序里找到
ADC是要一個過程的,啟動AD ...

但是我在實際測試中,ADC已經(jīng)發(fā)揮作用了,也能得到端口檢測到的值,只是多路使用的時候無法實現(xiàn)
作者: jhczy    時間: 2021-7-26 09:40
貼上來的程序不完整,不好分析原因,可以肯定地說是程序的問題
作者: zqz1345444061    時間: 2021-7-26 09:48
jhczy 發(fā)表于 2021-7-26 09:40
貼上來的程序不完整,不好分析原因,可以肯定地說是程序的問題

ADC初始化及采集程序如下
void        ADC_config(void)   //ADC 初始化
{       
        ADC_CONTR|=0x80;              //開AD轉(zhuǎn)換電源
        delay_ms(10);           //適當延時等待AD轉(zhuǎn)換供電穩(wěn)定
        ADC_CONTR|=0x0E;                          //選擇P0.6作為模擬功能AD使用
        ADC_CONTR&=0xFE;                          //選擇P0.6作為模擬功能AD使用
       
        ADCCFG&=0xFC;             //AD轉(zhuǎn)換速度為416個時鐘數(shù)轉(zhuǎn)換一次
        ADCCFG|=0x0C;             //AD轉(zhuǎn)換速度為416個時鐘數(shù)轉(zhuǎn)換一次
        ADC_CONTR&=0xDF;          //清AD轉(zhuǎn)換完成標志
               
        EADC=0;                   //禁止ADC轉(zhuǎn)換中斷
        ADCCFG|=0x20;             //ADC轉(zhuǎn)換結(jié)果ADC_RES存高4位,ADC_RESL存低8位

}

uint16        Get_ADC12bitResult(void)        //得到ADC12位結(jié)果
{       
        ADC_CONTR|=0x40;          //啟動AD轉(zhuǎn)換,ADC_START=1
        delay_ms(10);
        while(!(ADC_CONTR&0x20));    //查詢ADC完成標志
  ADC_CONTR&=0xDF;              // 將ADC_FLAG完成標志清0
        ADC_CONTR&=0xBF;        //關(guān)閉AD轉(zhuǎn)換,ADC_START=0
        //12位AD結(jié)果的高4位放ADC_RES的低4位,低8位在ADC_RESL
        AD_Dat = ADC_RES;                       //將ADC_RES低4位移到應(yīng)在的第9位至第12位
        AD_Dat <<= 8;
        AD_Dat|= ADC_RESL;               //將ADC_RESL的8位移到應(yīng)在的低8位
       
  ADC_CONTR|=0x40;           //啟動AD轉(zhuǎn)換,ADC_START=1
        return        AD_Dat;       
}
作者: jhczy    時間: 2021-7-26 10:00
本帖最后由 jhczy 于 2021-7-26 10:07 編輯
zqz1345444061 發(fā)表于 2021-7-26 09:48
ADC初始化及采集程序如下
void        ADC_config(void)   //ADC 初始化
{        

這個程序確實有問題,STC8與STC15的ADC程序有點小區(qū)別,請詳細看STC8的手冊
作者: zqz1345444061    時間: 2021-7-26 10:07
jhczy 發(fā)表于 2021-7-26 10:00
這個程序確實有問題,STC8與STC15的ADC程序有點小區(qū)別,請詳細看STC8G的手冊

可是它的確也能實現(xiàn)ADC的功能
作者: jhczy    時間: 2021-7-26 10:10
zqz1345444061 發(fā)表于 2021-7-26 10:07
可是它的確也能實現(xiàn)ADC的功能

采集的數(shù)據(jù)可能就是某一個通道上的
作者: zqz1345444061    時間: 2021-7-26 10:12
jhczy 發(fā)表于 2021-7-26 10:10
采集的數(shù)據(jù)可能就是某一個通道上的

確實是,我這個程序是選擇固定通道,我的問題就在于不知道如何選擇多個通道
作者: yzwzfyz    時間: 2021-7-26 10:14
在AD的硬件中,有一個采樣電容,當你下達采樣命令后,會經(jīng)歷如下的過程:
1、將這個電容與端口連通,并保持若干個時鐘。目的讓電容上得到與端口一樣的電壓。
2、再切斷與端口的連接,防止在進行電壓比較時,電壓有波動,影響、絞亂逐次逼近的邏輯。
3、接下來才進行真正的AD轉(zhuǎn)換(逐次逼近),需要N個時鐘周期,得到AD值。
所以,采樣時要注意(這是精華):
切換端口后,要過一段時間再下達采樣命令,因為剛切換后,采樣電容上是上一個通道的電壓,需要有一個充放電的過程,才能變?yōu)樾峦ǖ蓝丝谏系碾妷。這一點相當重要。!新手一般不會考慮到這一點,許多高手也吃它的苦。表現(xiàn)為采樣電壓的數(shù)據(jù)不穩(wěn)定,其實是部分地受上個通道的電壓“殘余”影響了。
解決的方案很簡單:估計樓主想到了……
作者: jhczy    時間: 2021-7-26 10:17
zqz1345444061 發(fā)表于 2021-7-26 10:07
可是它的確也能實現(xiàn)ADC的功能

我的STC8G的某一個端口的ADC程序(STC8G1K08的),12MHz
void W1_ADC()                                                //P3.4檢測
{
//        TR0=0;
        P3M1=0x10;                          //P3.4高阻輸入模式,P3.0-3.1-3.3為準雙向
        P3M0=0x04;
        P_SW2|=0x80;
        ADCTIM=0x3f;
        P_SW2&=0x7f;
        ADCCFG=0x0f;                  //設(shè)置ADC時鐘為系統(tǒng)頻率的/2/16
        ADC_CONTR=0x80;               //使能ADC模塊
        _nop_();
        _nop_();
        ADC_RES=0;                           //清除結(jié)果
        ADC_CONTR|=0x0c;               // 設(shè)定轉(zhuǎn)換的通道,P3.4是1100(0x0c)
        ADC_CONTR|=0x40;                     // 開始AD轉(zhuǎn)換,即ADC_START=1
        _nop_();
        _nop_();
        while(!(ADC_CONTR & 0x20));    //  等待轉(zhuǎn)換完成 ,即ADC_FLAG=1
        ADC_CONTR&=~0x20;              //  清零 即D3位start清零,D4位轉(zhuǎn)換結(jié)束標志位ADC_flag清零
        shuj=ADC_RES;                  //  取高八位
//        TR0=1;
        P3M1=0x00;
        P3M0=0x04;
}
作者: jhczy    時間: 2021-7-26 10:18
zqz1345444061 發(fā)表于 2021-7-26 10:12
確實是,我這個程序是選擇固定通道,我的問題就在于不知道如何選擇多個通道

一個通道一個程序,端口狀態(tài)要設(shè)置改變的
作者: zqz1345444061    時間: 2021-7-26 10:23
jhczy 發(fā)表于 2021-7-26 10:17
我的STC8G的某一個端口的ADC程序(STC8G1K08的),12MHz
void W1_ADC()                                                //P3.4檢測
{

好的,謝謝,我再試一下
作者: Y_G_G    時間: 2021-7-26 12:17
ADC用中斷比較好,不用一直等待,程序也可以做其它的事
STC8A4k不需要設(shè)定轉(zhuǎn)換時鐘個數(shù)的,ADC時鐘用最慢的時鐘頻率就可以了
我這個是自己寫的,可以在有字庫的12864上顯示
你參考一下
STC8A4K_12864.rar (1.92 KB, 下載次數(shù): 90)


作者: zqz1345444061    時間: 2021-7-26 14:43
Y_G_G 發(fā)表于 2021-7-26 12:17
ADC用中斷比較好,不用一直等待,程序也可以做其它的事
STC8A4k不需要設(shè)定轉(zhuǎn)換時鐘個數(shù)的,ADC時鐘用最慢的時 ...

好的,感謝幫助
作者: zqz1345444061    時間: 2021-7-26 14:50
Y_G_G 發(fā)表于 2021-7-26 12:17
ADC用中斷比較好,不用一直等待,程序也可以做其它的事
STC8A4k不需要設(shè)定轉(zhuǎn)換時鐘個數(shù)的,ADC時鐘用最慢的時 ...

好的感謝幫助
作者: wulin    時間: 2021-7-26 16:49
zqz1345444061 發(fā)表于 2021-7-26 10:12
確實是,我這個程序是選擇固定通道,我的問題就在于不知道如何選擇多個通道

對ADC_CONTR寄存器低4位賦值選擇ADC通道。


作者: univers    時間: 2021-7-27 16:43
按我的經(jīng)驗,8系列分時復用IO口檢測ADC, 剛打開IO口的時候也要延時1-2ms的,不然測出來也不準
作者: 河邊洗腳人    時間: 2021-12-11 17:41
兄弟,請問這個問題解決了嗎?
我按照之前10樓大佬說的解決辦法,延遲采集似乎沒有效果...
作者: 河邊洗腳人    時間: 2021-12-11 17:52
河邊洗腳人 發(fā)表于 2021-12-11 17:41
兄弟,請問這個問題解決了嗎?
我按照之前10樓大佬說的解決辦法,延遲采集似乎沒有效果...

是我切換通道時設(shè)置錯了。


作者: 小劉要加油    時間: 2021-12-24 21:47
同問,我也是這個問題,我配置了2個ADC初始化,選的不同的口,但是還是只顯示1個的值

作者: univers    時間: 2021-12-29 10:15
你的邏輯步驟很重要,STC8A8K系列ADC有幾種工作方式的,中斷是比較實用的。因為中斷不要CPU去等待,判斷。你要先把單個口的ADC代碼寫OK才行,測好單個口的ADC代碼沒問題之后,再擴展多個IO口,那么這多個口怎么分時復用去掃描也是很簡單的,可以定義一個掃描完成的標志位FLAG ,再定義一個多口數(shù)字變量,幾個標志一起參寫判斷。簡單的來就就是第一個口掃描完志成了,CPU自動進入第二個口掃描,掃完第二個,自動描掃第三個,以此反復循環(huán),在寫碼的時候是很靈活的。重點是你要把小個的函數(shù)寫好,把小個的湊成一個整體。小的局部沒寫好,大的找起來就一頭亂。
作者: univers    時間: 2021-12-29 10:18
還有一個就是CPU硬件AVCC這個ADC供電接口 接了沒有?我以前試過畫板時沒有接上,找了我一個星期。
作者: CHEN461107759    時間: 2022-10-14 15:02
Y_G_G 發(fā)表于 2021-7-26 12:17
ADC用中斷比較好,不用一直等待,程序也可以做其它的事
STC8A4k不需要設(shè)定轉(zhuǎn)換時鐘個數(shù)的,ADC時鐘用最慢的時 ...

ganx,,
作者: chenshandeng    時間: 2022-11-9 15:03
采集到的數(shù)值是不變的嗎,不變可能采集不到,變了的話就是所有采集到的數(shù)據(jù)都在一個通道里




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