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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

關于STC8G1K08多路ADC電壓采集問題

[復制鏈接]
跳轉到指定樓層
樓主
ID:1114732 發表于 2024-3-29 22:04 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
由于項目需要用到5路的ADC采樣,但是我發現多路通道之間的采樣值會互相影響,是需要在程序上進行處理嗎
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:213173 發表于 2024-3-30 07:13 | 只看該作者
端口模式要設置高阻,切換通道后丟棄前兩次采樣值
int ADC_rotate(char ch)
{
        int Vin;
        ADC_Read(ch);                 //丟掉兩次檢測
        ADC_Read(ch);
        VADC=ADC_Read(ch);            //取第ch通道ADC結果
        Vin=VCC*(long)VADC/4096;    //計算輸入電壓mV
        return Vin;
}
回復

使用道具 舉報

板凳
ID:1109793 發表于 2024-3-30 10:45 | 只看該作者
怎么個影響?我用兩個通道,沒感覺到問題啊
回復

使用道具 舉報

地板
ID:230500 發表于 2024-3-30 14:10 | 只看該作者
STC還有一個坑要注意; 由于內部電容充電時間的問題; 采集數據切換端口候不能馬上立即采集; 需要稍微等待幾十個US后等待電容充電穩定后再采集;也就是前面采集的幾次數據要丟掉;
回復

使用道具 舉報

5#
ID:401564 發表于 2024-3-30 14:58 | 只看該作者
程序只要是對的,就不會有什么影響的,我試有有多加了幾個不要結果的ADC,對實際的結果并沒有什么改善
一樣的抖動,ADC加個濾波就可以了
你也可以把你的代碼上傳上來,看一下怎么回事
回復

使用道具 舉報

6#
ID:1109793 發表于 2024-3-30 16:02 | 只看該作者
建議把采樣速度降到較低水平,不要用很高的速度,高速就不怎么穩定。
回復

使用道具 舉報

7#
ID:1114732 發表于 2024-3-30 16:34 | 只看該作者
xiaobendan001 發表于 2024-3-30 10:45
怎么個影響?我用兩個通道,沒感覺到問題啊

我貼一下程序麻煩幫我看一下,詳見9樓

                        if((i==6)&&(j<512))
                                {
                                                P37=0;          //這里只有我一上電給通道6低于512的電壓他才會給P37置低,后面給電壓他就沒反應
                                }
                        if((i==7)&&(j<512))
                                {
                                                  P37=0;        //同上
                                }

回復

使用道具 舉報

8#
ID:1114732 發表于 2024-3-30 16:35 | 只看該作者
a399288395 發表于 2024-3-30 14:10
STC還有一個坑要注意; 由于內部電容充電時間的問題; 采集數據切換端口候不能馬上立即采集; 需要稍微等待 ...

丟棄了一次可以嗎,我把ADC的采樣速度設置得比較快,上面貼了一下程序可以幫忙看一下嗎
回復

使用道具 舉報

9#
ID:1114732 發表于 2024-3-30 16:39 | 只看該作者
Y_G_G 發表于 2024-3-30 14:58
程序只要是對的,就不會有什么影響的,我試有有多加了幾個不要結果的ADC,對實際的結果并沒有什么改善
一 ...

好的代碼如下:/*************        PCA配置函數        **************//*****************************************/

void        PCA_config( u8 clk, u8 wide)
{
        CR = 0;   //停止PCA定時器
        CMOD = (CMOD & ~0x0E) | ((clk & 7) << 1);                // PCA時鐘選擇, 0: 12T,  1: 2T, 2: Timer0溢出率, 3: ECI引腳輸入, 4: 1T,  5: 4T,  6: 6T,  7: 8T
        PCA0_PWM(wide);        //PWM寬度        0: 8位PWM,  1: 7位PWM,  2: 6位PWM,  3: 10位PWM                       
        P_SW1 = (P_SW1 & ~0x30) | 0x00;        // 將PCA/PWM切換到 P5.5(ECI) P3.1(CCP0) P3.3(CCP1) P5.4(CCP2)
        P1n_push_pull(0x02);        //頭文件的宏, P1.1 設置為推挽輸出                       
        CH = 0;
        CL = 0;
        CR   = 1;        // 運行PCA定時器
}

void        UpdatePwm( u16 pwm_value)
{
                PCA_PWM0 = (PCA_PWM0 & ~0x32) | (u8)((pwm_value >> 4) & 0x30);
                CCAP0H = (u8)pwm_value;
        //        PWM0_NORMAL();               
}
/*****************************************/
/*****************************************/

/*************        PID函數        ******************/
/*****************************************/

typedef struct PID_Value
{
    int   KP;
    int   KI;
    int          KD;
    int   Inck;
    int   EkSum;
    int   Vref;
    int   Vin;
    int   Ek;
    int   Ek_1;
    int   Ek_2;
    int   dacOutAmp;
    int   Acutual_pidout;
}PID_ValueStr;

PID_ValueStr pidStr;

void PID_initial(void)
{
    pidStr.KP=10;
    pidStr.KI=1;

}

void PID_Caculate()
{                        
    pidStr.Ek=243-VCC ;                                                          
        pidStr.Inck=pidStr.KP*(pidStr.Ek  - pidStr.Ek_1) + pidStr.KI*pidStr.Ek  ;
    pidStr.Ek_2 = pidStr.Ek_1;                                          
    pidStr.Ek_1 = pidStr.Ek;                                                                                                    
        pidStr.dacOutAmp -= pidStr.Inck;                         
        if(pidStr.dacOutAmp<128)                                                          
    pidStr.dacOutAmp = 128;
    if(pidStr.dacOutAmp>243)
    pidStr.dacOutAmp = 243;                                                                                                                  
    pwm_value=pidStr.dacOutAmp;                                                         
}


/*****************************************/
/*****************************************/


/*************        中斷INT0函數        **********/
/*****************************************/
void INT0_Isr() interrupt 0
{   
         P37=0;
         FLAG=30;                                           
}
/*****************************************/
/*****************************************/
/*************        ADC函數        **************/
/*************************************/

uint Get_ADCResult(u8 channel)
{       
           ADC_RES = 0;
        ADC_RESL = 0;
        ADC_CONTR = (ADC_CONTR & 0xf0) | 0x40 | channel;
        //delay1us();                        //對ADC_CONTR操作后等待會兒再訪問
        while ((ADC_CONTR & 0x20)==0);
        ADC_CONTR &=~0x20;  
        ADC1_DATA=(ADC_RES<<8)|ADC_RESL;
    return ADC1_DATA;       
}

void ADC_Isr() interrupt 5
{       
        EADC=0;
    ADC_CONTR &= ~0x20;                         //清中斷標志
           VCC=(ADC_RES<<8)|ADC_RESL;               
        PID_Caculate();                                                                           
        UpdatePwm(pwm_value);                                                //更新PWM       
}

/*****************************************/
/*****************************************/
/*********************************************
/*函數名稱:Timer0_Config(u8 mode, u16 time)
/*函數功能:Timer0配置函數
/*輸入參數:mode:速度模式
/*                                        mode=1, 1T模式; mode=2,12T模式
/*                                        time:定時時間
/*        1T模式(max=5.9ms):1ms=1000,2ms=500,5ms=200
/*        12T模式(max=71ms):1ms=1000,10ms=100
/*返回值:無
*********************************************/
void Timer0_Config()
{
         
        AUXR |= 0x80;                //定時器0為1T模式
        TH0 = 0xFD;
        TL0 = 0xE4;
        TMOD &= 0xF0;                //設置定時器為模式0,16位自動重裝載
        TR0 = 1;                                //啟動定時器
        ET0 = 1;                                //打開定時器中斷
}



void Timer0() interrupt TIMER0_VECTOR
{       
        ADC_RES = 0;
        ADC_RESL = 0;
        ADC_CONTR = (ADC_CONTR & 0xf0) | 0x40 | 4;
        while ((ADC_CONTR & 0x20)==0);
        ADC_CONTR &=~0x20;
        EADC=1;       
        ADC_RES = 0;
        ADC_RESL = 0;
        ADC_CONTR = (ADC_CONTR & 0xf0) | 0x40 | 4;     
}




/*************************************
/*函數名稱:LED_Init()
/*函數功能:LED初始化函數
/*輸入參數:無
/*返回值:無
*************************************/
void LED_Init(void)
{
        //P1M1 &= ~(1<<2);        P1M0 |= (1<<2);        //設置P1.2為推挽輸出
        //P1M1 &= ~(1<<3);        P1M0 |= (1<<3);        //設置P1.3為推挽輸出
        LED1 = 1;                //初始化LED1
        LED2 = 1;                //初始化LED2
}

/*************************************
/*函數名稱:LED_Toggle(unsigned char led_id)
/*函數功能:LED狀態取反函數
/*輸入參數:LED序號(led_id=1~n)
/*返回值:無
*************************************/
void LED_Toggle(unsigned char led_id)
{
        switch(led_id)
        {
                case 1:
                        LED1 = ~LED1;                //LED1狀態取反
                        break;
                case 2:
                        LED2 = ~LED2;                //LED2狀態取反
                        break;
        }
}


/******************** 主函數 **************************/
void main(void)
{
        P0M1 = 0;   P0M0 = 0;   //設置為準雙向口
        P1M1 = 0;   P1M0 = 0;   //設置為準雙向口
        P2M1 = 0;   P2M0 = 0;   //設置為準雙向口
        P3M1 = 0;   P3M0 = 0;   //設置為準雙向口
    P1M0 = (P1M0 & ~0xf8) | 0x04; P1M1 = (P1M1 & ~0x04) | 0xf8;           //P1.2推挽輸出 P1.3 P1.4 P1.5 P1.6 P1.7 高阻輸入
    P3M0 |= 0xac; P3M1 &= ~0xac;             //        P3.2 P3.3 P3.5 P3.7  推挽輸出
        PID_initial();
        PCA_config(4,0);
        LED_Init();                                        //LED初始化函數
        Timer0_Config();                        //定時器0配置,12T模式,time=10ms                                                                                                     
        P_SW2 |= 0x80;                               
    ADCTIM = 0x0a;                              
    P_SW2 &= 0x7f;                                                                //設置ADC內部時序
    ADCCFG = 0x20;                              //設置ADC時鐘為系統時鐘/2/16
    ADC_CONTR = 0x80;                           //使能ADC模塊
    IT0 = 1;                                    //使能INT0下降沿中斷
    EX0 = 1;                                    //使能INT0中斷
        IPH=0x03;
        IP=0x21;
    EA = 1;                                                                                //允許總中斷       
       
        while(1)
        { u8 i ;
          u16 j ;
                 for(i=5; i<8; i++)
                {
                        Get_ADCResult(i);
                        j=Get_ADCResult(i);
                        if((i==6)&&(j<512))
                                {
                                P37=0;   //主要是這里,只有一開始上電給低于512的電壓他才能給P37置低,如果開始電壓比較高,后續再給低電壓也不行
                                }
                        if((i==7)&&(j<512))
                                {
                                                  P37=0;  //這里同上
                                }
                }                     
        }
}


回復

使用道具 舉報

10#
ID:1114732 發表于 2024-3-30 16:40 | 只看該作者
xiaobendan001 發表于 2024-3-30 16:02
建議把采樣速度降到較低水平,不要用很高的速度,高速就不怎么穩定。

主要是有一路要用來穩住電壓,對adc的采樣速度要求較高
回復

使用道具 舉報

11#
ID:401564 發表于 2024-3-31 15:11 | 只看該作者
你在定時器中斷中打開了ADC中斷,卻又在主程序中使用了輪詢的方式進行ADC
但STC的ADC實際上只有一個
而且,在定時器中斷中,你又有了
ADC_RES = 0;
ADC_RESL = 0;
這兩個是ADC結果的寄存器,它會影響Get_ADCResult返回值的

要么是ADC都用中斷的方式,要么就都用輪詢的方式
ADC用輪詢方式的話,ADC對主程序的影響不大,但ADC優先權就不大
ADC用中斷的方式,ADC對主程序影響就很大,因為每次ADC完成,都要進入ADC中斷一次,最終還是要看你整個程序的需求
回復

使用道具 舉報

12#
ID:1034262 發表于 2024-3-31 19:23 | 只看該作者
a399288395 發表于 2024-3-30 14:10
STC還有一個坑要注意; 由于內部電容充電時間的問題; 采集數據切換端口候不能馬上立即采集; 需要稍微等待 ...

說法不對,不采樣時是斷開連接的,等多久都沒用。
正確方法是設置采樣時間,用稍長的采樣時間,一般到3us以上就沒問題了。
或者切換通道后先做一次ADC并丟棄結果。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 精品国产欧美一区二区三区不卡 | 日本不卡高字幕在线2019 | 天堂一区二区三区四区 | 精品国产青草久久久久福利 | 成人精品鲁一区一区二区 | 国产真实乱对白精彩久久小说 | www.婷婷| 一区二区三区视频 | 91麻豆蜜桃一区二区三区 | 天天色综 | 日韩中文字幕一区 | 国产精品一区二区三区在线 | 久久亚洲精品久久国产一区二区 | 最新中文字幕在线 | 精品一二三区视频 | 欧美人成在线视频 | 成人亚洲性情网站www在线观看 | 国产精品一区在线观看 | 国产无人区一区二区三区 | 黄色三级免费网站 | 日韩欧美在线一区二区 | 91福利网址 | 午夜精品久久久久久久久久久久久 | 久久天堂网 | 久久一区视频 | 久久精品超碰 | 国产丝袜一区二区三区免费视频 | 野狼在线社区2017入口 | 一级毛片免费 | 国产精品久久久久一区二区三区 | 一区二区三区成人 | 久久久久国产一区二区三区四区 | 日韩爱爱网| 久久久久久久久99精品 | 久久丝袜视频 | 男女羞羞视频在线观看 | 欧美一区二区三区国产 | 久久久久国 | av天天干 | 一区二区精品 | 成人在线一区二区三区 |