標(biāo)題: 單片機(jī)ADC多路轉(zhuǎn)換程序調(diào)試又不會(huì)了,請(qǐng)大伙幫忙指點(diǎn) [打印本頁(yè)]

作者: zhth1979    時(shí)間: 2022-8-31 15:23
標(biāo)題: 單片機(jī)ADC多路轉(zhuǎn)換程序調(diào)試又不會(huì)了,請(qǐng)大伙幫忙指點(diǎn)
這個(gè)是一路的程序(中斷方式),SGADCON 賦每一路的值都沒(méi)有問(wèn)題,現(xiàn)在我想三路輪流采集就不行了。
#include "adc.h"
bit ADready;   //24bit ADC轉(zhuǎn)換完成標(biāo)志位
unsigned long idata        ADcode_pre;

void ADC_24bit_InIt()  //24位ADC初始化
{
        EIE &= 0xfb;                        //關(guān)閉SG ADC 中斷        
        
        SGADCON = 0xc2;                //1100 0010  開(kāi)啟ADC 正常工作 通道0 關(guān)閉64倍運(yùn)放  輸出速率 10HZ   通道1:0xd2   通道3:0xf2

        SGADCON2  = 0x41;                // 0100 0011 VCOM 輸出電壓控制位 輸出1.5V

        SGADCON3X = 0x99;                //1001 1001  CCEN=1 1和2負(fù)輸入不反  GCLK=8  ACLK=4  FCCH=1

        SGADCON4X = 0x30;                //0011 0000  不輸出基準(zhǔn)電流  開(kāi)啟內(nèi)部BUF 開(kāi)啟BUF_LCAP屬性 GREF不放大 關(guān)閉上下拉電流
        
        SGADCON5X = 0x31;                //0001 1101  濾波模式3  不丟棄

        PD_CON    = 0x66;                //0110 0110 解鎖P1.1 1.2 鎖定P4.2 P4.3僅為輸入模式 解鎖寫(xiě)權(quán)限 開(kāi)啟內(nèi)部LDO 同步休眠 開(kāi)啟溫度模塊
               
        //EA = 1;                                        //打開(kāi)總中斷(總中斷在main函數(shù)中打開(kāi))
        EIE |= 0x04;                        //打開(kāi)SG ADC 中斷        
}

void data_receive()                                //從寄存器中獲取ADC內(nèi)碼
{
        union  ADpattern idata temp;
        //--ADcode_pre--賦值
        temp.b[1] = SGADC3;
        temp.b[2] = SGADC2;
        temp.b[3] = SGADC1;
        temp.b[0] = 0;                                //獲取24位ADC數(shù)據(jù)內(nèi)碼
//        temp.w ^= 0x800000;                        // 因?yàn)檩敵鰹殡p極性,+0x800000將負(fù)端平移上來(lái)
        temp.w &= 0x00ffffff;                //對(duì)25-32位清零
        ADcode_pre = temp.w;
}

//內(nèi)部 24bit SG ADC 中斷,讀取adc數(shù)據(jù)
static void sgadc_serve() interrupt 7
{               
        EIE &= 0xfb;                         //禁止中斷
        data_receive(); //讀取 SDI0818 的 轉(zhuǎn)換數(shù)據(jù)
        ADready = 1;
        EXIF &= 0xbf;
        EIE |= 0x04;                 //打開(kāi)中斷
}

unsigned long Filter_ADdata()                //讀取adc轉(zhuǎn)換數(shù)據(jù),對(duì)其進(jìn)行適當(dāng)?shù)钠交V波。
{
        unsigned long d;
// -- 將 中斷服務(wù)程序讀取出的ADC原始信息 從 緩沖 Buffer 中取出  -----
        EIE &= 0xfb;        // 關(guān)閉adc中斷,讀取 ADC原始位信息 時(shí) 禁止 中斷服務(wù)程序 改寫(xiě)
        d = ADcode_pre;
        ADready = 0;        // 表示 ADC數(shù)據(jù)已被 處理程序 響應(yīng)
        EIE |= 0x04;        // 打開(kāi)中斷
        d >>= 2;                // 將ADC數(shù)據(jù)右移兩位,簡(jiǎn)單濾波
        return d;
}

unsigned long Air_ADC_average()                                //氣壓傳感器ADC通道
{
        unsigned long ADC_code = 0;
        unsigned char j;
        unsigned long  ADcode_filter_buff[10];        //用來(lái)求平均
        
        while(~ADready);                        //等待AD轉(zhuǎn)換完成標(biāo)志
        for(j=9;j>0;j--)
        {
                ADcode_filter_buff[j] = ADcode_filter_buff[j-1];
        }
        ADcode_filter_buff[0] =Filter_ADdata();        //獲取最新ADC內(nèi)碼
        for(j=0;j<10;j++)
        {
                ADC_code += ADcode_filter_buff[j];   //10次ADC內(nèi)碼相加
        }
        ADC_code /= 10;                        //求平均
        return ADC_code;
}
下面是.H文件
#ifndef        __ADC_H_
#define        __ADC_H_
#include "SDI5229.h"
                                                                           
void ADC_24bit_InIt();
void data_receive();

unsigned long Filter_ADdata();
unsigned long Air_ADC_average();

union ADpattern                                //定義聯(lián)合體,數(shù)據(jù)可以采用字節(jié)和字兩種方式訪問(wèn);
{
        unsigned long        w ;
        unsigned char   b[4];
};

#endif

----------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------------------
下面是我嘗試用switch中切換通道,但沒(méi)成功。
#include "adc.h"
float line0,line1,line2;                     //三通道結(jié)果
bit ADready;                                 //24bit ADC轉(zhuǎn)換完成標(biāo)志位
unsigned long idata        ADcode_pre;            


void ADC_Setchannel(unsigned char channel)
  {
          switch(channel)
            {
                 case 0:  SGADCON &= 0xc2;  break;
                case 1:  SGADCON &= 0xd2;  break;
                case 2:  SGADCON &= 0xf2;  break;
                default:break;
          }
  }

void ADC_24bit_InIt(unsigned char channel)  //24位ADC初始
{
        EIE &= 0xfb;                        //關(guān)閉SG ADC 中斷        
        SGADCON &= 0xcf;                //清除ADC通道選擇位      
        ADC_Setchannel(channel);   //用此函數(shù)代替選通道寄存器
        SGADCON2  = 0x41;                // 0100 0011 VCOM 輸出電壓控制位 輸出1.5V
        SGADCON3X = 0x99;                //1001 1001  CCEN=1 1和2負(fù)輸入不反  GCLK=8  ACLK=4  FCCH=1
        SGADCON4X = 0x30;                //0011 0000  不輸出基準(zhǔn)電流  開(kāi)啟內(nèi)部BUF 開(kāi)啟BUF_LCAP屬性 GREF不放大 關(guān)閉上下接電流   
        SGADCON5X = 0x31;                //0001 1101  濾波模式3  不丟棄
        PD_CON    = 0x66;                //0110 0110 解鎖P1.1 1.2 鎖定P4.2 P4.3僅為輸入模式 解鎖寫(xiě)權(quán)限 開(kāi)啟內(nèi)部LDO 同步休眠 開(kāi)啟溫度模塊              
        //EA = 1;                                        //打開(kāi)總中斷 (main函數(shù)里打開(kāi))
        EIE |= 0x04;                        //打開(kāi)SG ADC 中斷        
}

void data_receive()                                //從寄存器中獲取ADC內(nèi)碼
{
        union  ADpattern idata temp;
        //--ADcode_pre--賦值
        temp.b[1] = SGADC3;
        temp.b[2] = SGADC2;
        temp.b[3] = SGADC1;
        temp.b[0] = 0;                                //獲取24位ADC數(shù)據(jù)內(nèi)碼
//        temp.w ^= 0x800000;                        // 因?yàn)檩敵鰹殡p極性,+0x800000將負(fù)端平移上來(lái)
        temp.w &= 0x00ffffff;                //對(duì)25-32位清零
        ADcode_pre = temp.w;
}


//內(nèi)部 24bit SG ADC 中斷,讀取adc數(shù)據(jù)
static void sgadc_serve() interrupt 7
{               
        EIE &= 0xfb;                         //禁止中斷
        data_receive(); //讀取 SDI0818 的 轉(zhuǎn)換數(shù)據(jù)
        ADready = 1;
        EXIF &= 0xbf;
        EIE |= 0x04;                 //打開(kāi)中斷
}


unsigned long Filter_ADdata()                //讀取adc轉(zhuǎn)換數(shù)據(jù),對(duì)其進(jìn)行適當(dāng)?shù)钠交V波。
{
        unsigned long d;
// -- 將 中斷服務(wù)程序讀取出的ADC原始信息 從 緩沖 Buffer 中取出  -----
        EIE &= 0xfb;        // 關(guān)閉adc中斷,讀取 ADC原始位信息 時(shí) 禁止 中斷服務(wù)程序 改寫(xiě)
        d = ADcode_pre;
        ADready = 0;        // 表示 ADC數(shù)據(jù)已被 處理程序 響應(yīng)
        EIE |= 0x04;        // 打開(kāi)中斷
        d >>= 2;                // 將ADC數(shù)據(jù)右移兩位,簡(jiǎn)單濾波
        return d;
}
unsigned long Air_ADC_average()                                //氣壓傳感器ADC通道

{
        unsigned long ADC_code = 0;
        unsigned char j;
        unsigned long  ADcode_filter_buff[10];        //用來(lái)求平均
        
        while(~ADready);                        //等待AD轉(zhuǎn)換完成標(biāo)志
        for(j=9;j>0;j--)
        {
                ADcode_filter_buff[j] = ADcode_filter_buff[j-1];
        }
        ADcode_filter_buff[0] =Filter_ADdata();        //獲取最新ADC內(nèi)碼
        for(j=0;j<10;j++)
        {
                ADC_code += ADcode_filter_buff[j];   //10次ADC內(nèi)碼相加
        }
        ADC_code /= 10;                        //求平均
        return ADC_code;
}

void ADC_channel(unsigned char channel)

  {
                switch(channel)
                {
                        case 0: line0 = Air_ADC_average();  break;  //通道0結(jié)果
                        case 1: line1 = Air_ADC_average();  break;  //通道1結(jié)果
                        case 2: line2 = Air_ADC_average();  break;  //通道2結(jié)果
                        default:break;
                }
  }

這是adc.h文件
#ifndef        __ADC_H_
#define        __ADC_H_


#include "SDI5229.h"


extern float line0;
extern float line1;
extern float line2;
void ADC_channel(unsigned char channel);


void ADC_Setchannel(unsigned char channel);                                                                           
void ADC_24bit_InIt(unsigned char channel);
void data_receive();


unsigned long Filter_ADdata();
unsigned long Air_ADC_average();


union ADpattern                                //定義聯(lián)合體,數(shù)據(jù)可以采用字節(jié)和字兩種方式訪問(wèn);
{
        unsigned long        w ;
        unsigned char   b[4];
};
#endif

main函數(shù)中調(diào)用
        while(1)
           {
                         if(ADCflag==1)      //定時(shí)1S標(biāo)志位   1S切換一個(gè)通道
                         {
                         ADCflag=0;
                         ADC_24bit_InIt(channel);
                         ADC_channel(channel);
                         channel++;
                         if(channel>2)        
                                 channel=0;
                         }
                        
      ADCBat = line0;







作者: yzwzfyz    時(shí)間: 2022-8-31 17:28
建議:
1、每個(gè)通道編寫(xiě)一個(gè)程序。
2、將各個(gè)程序輪流執(zhí)行。
作者: pdwdzz    時(shí)間: 2022-8-31 23:24
  case 0:  SGADCON &= 0xc2;  break;
  case 1:  SGADCON &= 0xd2;  break;
  case 2:  SGADCON &= 0xf2;  break;
  改
  case 0:  SGADCON = 0xc2;  break;
  case 1:  SGADCON = 0xd2;  break;
  case 2:  SGADCON = 0xf2;  break;
作者: zhth1979    時(shí)間: 2022-9-1 07:56
pdwdzz 發(fā)表于 2022-8-31 23:24
case 0:  SGADCON &= 0xc2;  break;
  case 1:  SGADCON &= 0xd2;  break;
  case 2:  SGADCON &= 0xf2 ...

之前就是沒(méi)有與,不行才改現(xiàn)在這樣的,也是不行!
作者: zhth1979    時(shí)間: 2022-9-1 07:59
yzwzfyz 發(fā)表于 2022-8-31 17:28
建議:
1、每個(gè)通道編寫(xiě)一個(gè)程序。
2、將各個(gè)程序輪流執(zhí)行。

那樣的話,1.太繁瑣不簡(jiǎn)潔  2.編譯后data內(nèi)存也會(huì)占用更多。
作者: yzwzfyz    時(shí)間: 2022-9-1 10:59
【那樣的話,1.太繁瑣不簡(jiǎn)潔  2.編譯后data內(nèi)存也會(huì)占用更多!
不要以為這樣很蠢。在你不會(huì)做的時(shí)間很有用,道理上說(shuō)得通。
當(dāng)你做了,就會(huì)知道它是如何蠢的,知道它蠢之后,你就進(jìn)步了,離成功也就不遠(yuǎn)了。
作者: Y_G_G    時(shí)間: 2022-9-1 23:53
zhth1979 發(fā)表于 2022-9-1 07:59
那樣的話,1.太繁瑣不簡(jiǎn)潔  2.編譯后data內(nèi)存也會(huì)占用更多。

如果不是你程序?qū)嵲趯?xiě)不下了,目前的主要問(wèn)題并不是代碼占用空間大的問(wèn)題
首先要保證代碼能不能正確執(zhí)行,這才是關(guān)鍵
這個(gè)片子有30K的內(nèi)存,個(gè)人感覺(jué),超過(guò)30K的8位機(jī)程序并不是很多
等到功能正常了,再想辦法精簡(jiǎn)代碼




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