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

標(biāo)題: STC15單片機多通道ADC采集疑問 [打印本頁]

作者: wen1989jun    時間: 2024-4-7 15:50
標(biāo)題: STC15單片機多通道ADC采集疑問
各位大神,如下代碼可實現(xiàn)ADC單通道采集,已驗證OK,想要實現(xiàn)雙通道或者多通道采集應(yīng)該如何修改代碼?

如果需要在中斷中修改代碼,應(yīng)該如何做到切換,以雙通道為例子,感謝大家,謝謝!


#include "STC15.h"
#include <stdio.h>
#include "intrins.h"

#define ADC_POWER 0x80 // ADC電源控制位
#define ADC_FLAG 0x10  // ADC完成標(biāo)志
#define ADC_START 0x08 // ADC起始控制位

#define ADC_SPEEDLL 0x00 // 540個時鐘
#define ADC_SPEEDL 0x20  // 360個時鐘
#define ADC_SPEEDH 0x40  // 180個時鐘
#define ADC_SPEEDHH 0x60 // 90個時鐘
#define VCC 5000         // set ADC_REF_VCC 設(shè)置ADC基準(zhǔn)電壓為5V

typedef unsigned char BYTE;
typedef unsigned int WORD;

BYTE ch = 0;   // ADC通道號
BYTE flag = 0; // 設(shè)置轉(zhuǎn)換完成標(biāo)志位
BYTE H8bit = 0, L2bit = 0;
WORD AD10bit = 0, temp = 0, dat = 0, dat1 = 0;
unsigned long result = 0;

void InitADC();
void UartInit(void);
char putchar(char c);
void Delay(WORD n);
void DisplayData(unsigned int iData);

void main()
{
    InitADC(); //初始化ADC
    while (1)
    {
        if (flag)
        {
            flag = 0;
            AD10bit = (AD10bit | H8bit) & 0x00ff;
            AD10bit = (AD10bit << 2) | (L2bit & 0X03); //合并成10位二進(jìn)制數(shù)
            temp = AD10bit;
            AD10bit = 0;
            ADC_RES = 0;
            ADC_RESL = 0;
            printf("value_X=%d", temp);
            printf("              ");
            //注意:先把temp強制轉(zhuǎn)換成long型,再進(jìn)行電壓轉(zhuǎn)換才可獲得正確的電壓值
            result = ((long)temp * VCC / 1024);
            DisplayData(result);                                            printf("\r\n");
        }
    }
}

/*----------------------------
初始化ADC
----------------------------*/
void InitADC()
{
    P1ASF = 0x03;   //設(shè)置P1.0/P1.1口為AD口
    P1M1 = 0x03;    // set 1# chanel to AD        高阻
    P1M0 = 0x00;    // set 1# chanel to AD        高阻
    CLK_DIV = 0x00; //結(jié)果右對齊
    ADC_RES = 0;    //清除結(jié)果寄存器
    ADC_RESL = 0;
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START|ch ;
    Delay(10); // ADC上電并延時

    AUXR |= 0x10; // set EADCI
    IE = 0xa0;    // Enable ADC interrupt and Open master interrupt switch
}

/*----------------------------
軟件延時
----------------------------*/
void Delay(WORD n)
{
    WORD x;

    while (n--)
    {
        x = 5000;
        while (x--);
    }
}

void DisplayData(unsigned int iData)
{
    char NumStr[4] = {0, 0, 0, 0}, i = 0;
    NumStr[0] = iData / 1000;         // 千位
    NumStr[1] = (iData % 1000) / 100; // 百位
    NumStr[2] = iData % 100 / 10;     // 十位
    NumStr[3] = iData % 10;           // 個位
    printf("ADC1=");
    printf("%c", NumStr[0] + 0x30);
    printf("%c", NumStr[1] + 0x30);
    printf(".");
    printf("%c", NumStr[2] + 0x30);
    printf("%c", NumStr[3] + 0x30);
}

/*----------------------------
ADC中斷服務(wù)程序
----------------------------*/
void adc_isr() interrupt 5
{
    H8bit = ADC_RES;
    L2bit = ADC_RESL;
    ADC_CONTR &= !ADC_FLAG; //清除ADC中斷標(biāo)志
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch;
    flag = 1;
}

void UartInit(void)        //9600bps@11.0592MHz
{
        SCON = 0x50;                //8位數(shù)據(jù),可變波特率
        AUXR |= 0x01;                //串口1選擇定時器2為波特率發(fā)生器
        AUXR &= 0xFB;                //定時器時鐘12T模式
        T2L = 0xE8;                        //設(shè)置定時初始值
        T2H = 0xFF;                        //設(shè)置定時初始值
        AUXR |= 0x10;                //定時器2開始計時
        ES=1;                                                //允許串行口中斷
        EA=1;                                                //允許總中斷
}


char putchar(char c)
{
    UartInit();
    ES = 0;
    SBUF = c;
    while (TI == 0);
    TI = 0;
    ES = 1;
    return 0;
}




作者: wen1989jun    時間: 2024-4-7 17:35
先自頂下,有好的答案就采納了
作者: cocolala    時間: 2024-4-7 20:13
    1、你好,不知道你單片機的具體型號。我手頭正好有艾克姆的STC15開發(fā)板,單片機是STC15W4K56S4,用這個硬件我調(diào)通了多路ADC。


    2、你的如果是STC15F應(yīng)該也是可以的,具體你可以參考附件程序。


多路ADC.rar

246.18 KB, 下載次數(shù): 10


作者: wulin    時間: 2024-4-7 20:41
wen1989jun 發(fā)表于 2024-4-7 17:35
先自頂下,有好的答案就采納了

STC有現(xiàn)成的示例


作者: coody_sz    時間: 2024-4-7 23:27
改通道數(shù)就可以了啊,ADC_CONTR低3位。可以直接參考STC官方的例子。
作者: wen1989jun    時間: 2024-4-8 10:56
wulin 發(fā)表于 2024-4-7 20:41
STC有現(xiàn)成的示例

嗨,就是這個官方例程看得有點懵啊
作者: wen1989jun    時間: 2024-4-8 10:58
coody_sz 發(fā)表于 2024-4-7 23:27
改通道數(shù)就可以了啊,ADC_CONTR低3位。可以直接參考STC官方的例子。

這個寄存器ADC_CONTR我只會修改其中一路,想要如:ADC0,ADC1通道分時用就不會了
作者: wen1989jun    時間: 2024-4-8 10:58
cocolala 發(fā)表于 2024-4-7 20:13
1、你好,不知道你單片機的具體型號。我手頭正好有艾克姆的STC15開發(fā)板,單片機是STC15W4K56S4,用這個 ...

感謝大神,我先用附件程序試試
作者: wulin    時間: 2024-4-8 22:08
wen1989jun 發(fā)表于 2024-4-8 10:56
嗨,就是這個官方例程看得有點懵啊

你定義了變量  BYTE ch = 0;   // ADC通道號  ,在ADC轉(zhuǎn)換程序中使用ch時沒有改變ch值,那就只能重復(fù)采樣0通道,要想多通道采集就得改變ch值,取值范圍0-7。
作者: xiaobendan001    時間: 2024-4-9 09:36
搞個計數(shù)器,每次讀完了就++嘛
作者: wen1989jun    時間: 2024-4-9 14:42
wulin 發(fā)表于 2024-4-8 22:08
你定義了變量  BYTE ch = 0;   // ADC通道號  ,在ADC轉(zhuǎn)換程序中使用ch時沒有改變ch值,那就只能重復(fù)采樣 ...

那這個要在程序上實現(xiàn)應(yīng)該怎么寫呢?
讓ch在中斷程序中自+,比如兩通道>2就回到0?
不是太懂,望大神解惑,感謝!
作者: wen1989jun    時間: 2024-4-9 14:43
xiaobendan001 發(fā)表于 2024-4-9 09:36
搞個計數(shù)器,每次讀完了就++嘛

能稍微詳細(xì)一點說說么,大哥
作者: XIANXI    時間: 2024-4-9 14:52
你查手冊,把通道數(shù)對應(yīng)就行了
作者: wen1989jun    時間: 2024-4-9 15:03
目前在中斷里面把ch++后,可以抓取P1.0,P1.1的ADC數(shù)據(jù)了,帶來了新的問題應(yīng)該怎么區(qū)分這兩個數(shù)據(jù)呢?頭大

void adc_isr() interrupt 5
{
    H8bit = ADC_RES;
    L2bit = ADC_RESL;
    ADC_CONTR &= !ADC_FLAG; //清除ADC中斷標(biāo)志
                ch++;
                ch%=2;
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch;
    flag = 1;
}
作者: Graves    時間: 2024-4-9 15:20
wen1989jun 發(fā)表于 2024-4-9 15:03
目前在中斷里面把ch++后,可以抓取P1.0,P1.1的ADC數(shù)據(jù)了,帶來了新的問題應(yīng)該怎么區(qū)分這兩個數(shù)據(jù)呢?頭大
...

你都知道改ch換通道了,怎么就不能判斷ch是哪個通道呢
作者: xiaobendan001    時間: 2024-4-9 15:37
wen1989jun 發(fā)表于 2024-4-9 14:43
能稍微詳細(xì)一點說說么,大哥

比如
弄個ad[8],i
i=0;
讀出結(jié)果放ad[i ][ i];然后i++,啟動第i通道
下次中斷再讀出還放ad[ i],然后再i++直到i>7則i=0;
作者: felicityocihjwe    時間: 2024-4-9 16:32
ADC數(shù)模轉(zhuǎn)化配合dmA數(shù)據(jù)搬運 可以配置一些單多通道,掃描模式來完成效果

作者: wen1989jun    時間: 2024-4-9 18:35
qq475878026 發(fā)表于 2024-4-9 15:20
你都知道改ch換通道了,怎么就不能判斷ch是哪個通道呢

那我好好想想,挺懵的
作者: wen1989jun    時間: 2024-4-10 15:00
felicityocihjwe 發(fā)表于 2024-4-9 16:32
ADC數(shù)模轉(zhuǎn)化配合dmA數(shù)據(jù)搬運 可以配置一些單多通道,掃描模式來完成效果

我現(xiàn)在是用中斷做的獲取ADC的值,掃描方式還不太會
作者: wen1989jun    時間: 2024-4-10 15:00
xiaobendan001 發(fā)表于 2024-4-9 15:37
比如
弄個ad[8],i
i=0;

我試試,謝謝哥
作者: wen1989jun    時間: 2024-4-10 15:03
目前按照下面代碼方式能獲取到兩個通道的ADC值了,各位大哥幫忙看看有沒有其他問題,感謝感謝!

#include "STC15.h"
#include <stdio.h>
#include "intrins.h"

#define ADC_POWER 0x80 // ADC電源控制位
#define ADC_FLAG 0x10  // ADC完成標(biāo)志
#define ADC_START 0x08 // ADC起始控制位

#define ADC_SPEEDLL 0x00 // 540個時鐘
#define ADC_SPEEDL 0x20  // 360個時鐘
#define ADC_SPEEDH 0x40  // 180個時鐘
#define ADC_SPEEDHH 0x60 // 90個時鐘
#define VCC 5000         // set ADC_REF_VCC 設(shè)置ADC基準(zhǔn)電壓為5V

typedef unsigned char BYTE;
typedef unsigned int WORD;

BYTE ch ;   // ADC通道號
BYTE flag = 0; // 設(shè)置轉(zhuǎn)換完成標(biāo)志位
BYTE H8bit = 0, L2bit = 0;
WORD AD10bit = 0, temp = 0, dat = 0, dat1 = 0;
unsigned long result = 0;result1 = 0;

void InitADC();
void UartInit(void);
char putchar(char c);
void Delayms(unsigned xms);
void DisplayData(unsigned int iData);

void main()
{
    InitADC(); //初始化ADC
    while (1)
    {
        if (flag)
        {
                                        if(ch==1)
                                        {
            flag = 0;
            AD10bit = (AD10bit | H8bit) & 0x00ff;
            AD10bit = (AD10bit << 2) | (L2bit & 0X03); //合并成10位二進(jìn)制數(shù)
            temp = AD10bit;
            AD10bit = 0;
            ADC_RES = 0;
            ADC_RESL = 0;
//            printf("value_X=%d", temp);
//            printf("              ");
            //注意:先把temp強制轉(zhuǎn)換成long型,再進(jìn)行電壓轉(zhuǎn)換才可獲得正確的電壓值
            result = ((long)temp * VCC / 1024);
//            DisplayData(result);
//            printf("\r\n");
                                               
                                        }
                                        if(ch==0)
                                        {
                                                flag = 0;
            AD10bit = (AD10bit | H8bit) & 0x00ff;
            AD10bit = (AD10bit << 2) | (L2bit & 0X03); //合并成10位二進(jìn)制數(shù)
            dat = AD10bit;
            AD10bit = 0;
            ADC_RES = 0;
            ADC_RESL = 0;
//            printf("value_Y=%d", dat);
//            printf("              ");
            //注意:先把dat強制轉(zhuǎn)換成long型,再進(jìn)行電壓轉(zhuǎn)換才可獲得正確的電壓值
            result1 = ((long)dat * VCC / 1024);
//            DisplayData(result);
//            printf("\r\n");

                                        }
        }
    }
}

/*----------------------------
初始化ADC
----------------------------*/
void InitADC()
{
    P1ASF = 0x03;   //設(shè)置P1.0/P1.1口為AD口
    P1M1 = 0x03;    // set 1# chanel to AD        高阻
    P1M0 = 0x00;    // set 1# chanel to AD        高阻
    CLK_DIV = 0x00; //結(jié)果右對齊
    ADC_RES = 0;    //清除結(jié)果寄存器
    ADC_RESL = 0;
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START|ch ;
    Delayms(1); // ADC上電并延時1ms
    AUXR |= 0x10; // set EADCI
    IE = 0xa0;    // Enable ADC interrupt and Open master interrupt switch
}

/*----------------------------
軟件延時
----------------------------*/

void Delayms(unsigned xms)        //@11.0592MHz
{
        unsigned char data i, j;

        while(xms--)
        {
        _nop_();
        _nop_();
        _nop_();
        i = 11;
        j = 190;
        do
        {
                while (--j);
        } while (--i);
               
        }
}


void DisplayData(unsigned int iData)
{
    char NumStr[4] = {0, 0, 0, 0}, i = 0;
    NumStr[0] = iData / 1000;         // 千位
    NumStr[1] = (iData % 1000) / 100; // 百位
    NumStr[2] = iData % 100 / 10;     // 十位
    NumStr[3] = iData % 10;           // 個位
    printf("ADC1=");
    printf("%c", NumStr[0] + 0x30);
    printf("%c", NumStr[1] + 0x30);
    printf(".");
    printf("%c", NumStr[2] + 0x30);
    printf("%c", NumStr[3] + 0x30);
}

/*----------------------------
ADC中斷服務(wù)程序
----------------------------*/
void adc_isr() interrupt 5
{
    H8bit = ADC_RES;
    L2bit = ADC_RESL;
    ADC_CONTR &= !ADC_FLAG; //清除ADC中斷標(biāo)志
                ch++;
                ch%=2;
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch;
    flag = 1;
}

void UartInit(void)        //9600bps@11.0592MHz
{
        SCON = 0x50;                //8位數(shù)據(jù),可變波特率
        AUXR |= 0x01;                //串口1選擇定時器2為波特率發(fā)生器
        AUXR &= 0xFB;                //定時器時鐘12T模式
        T2L = 0xE8;                        //設(shè)置定時初始值
        T2H = 0xFF;                        //設(shè)置定時初始值
        AUXR |= 0x10;                //定時器2開始計時
        ES=1;                                                //允許串行口中斷
        EA=1;                                                //允許總中斷
}


char putchar(char c)
{
    UartInit();
    ES = 0;
    SBUF = c;
    while (TI == 0);
    TI = 0;
    ES = 1;
    return 0;
}


作者: jch352122    時間: 2024-4-10 21:22
wen1989jun 發(fā)表于 2024-4-10 15:00
我試試,謝謝哥

這個可以用,你改一下。
#include "stc8g.h"     //讀多通道ADC
#include "intrins.h"

typedef     unsigned char   u8;
typedef     unsigned int    u16;

#define ADCTIM (*(unsigned char volatile xdata *)0xfea8)

u16 Get(u8 channel); //channel = 0~15

void maindd(void)
  {          if(Get(3)>150)       
                {  P55=0;}
        else{P55=1;}}
         
void main(void)
{  P_SW2 |= 0x80;  //擴(kuò)展寄存器(XFR)訪問使能

    P3M0 &= ~0x0f; P3M1 |= 0x0f; //高阻
    P5M0 &= ~0x30; P5M1 &= ~0x30;

     ADCTIM = 0x3f;      //設(shè)置 ADC 內(nèi)部時序,ADC采樣時間建議設(shè)
    ADCCFG = 0x2f;      //設(shè)置 ADC 時鐘為系統(tǒng)時鐘/2/16
    ADC_CONTR = 0x80; //使能 ADC 模塊
       
   while(1)
   {
        maindd();
                            }}

u16 Get(u8 channel)  //channel = 0~15
{
    ADC_RES = 0;
    ADC_RESL = 0;

    ADC_CONTR = (ADC_CONTR & 0xF0) | 0x40 | channel;    //啟動 AD 轉(zhuǎn)換
    _nop_();
    _nop_();
    _nop_();
    _nop_();

    while((ADC_CONTR & 0x20) == 0)  ;   //wait for ADC finish
    ADC_CONTR &= ~0x20;     //清除ADC結(jié)束標(biāo)志
    return  (((u16)ADC_RES << 8) | ADC_RESL);
}
作者: wen1989jun    時間: 2024-4-11 10:12
jch352122 發(fā)表于 2024-4-10 21:22
這個可以用,你改一下。
#include "stc8g.h"     //讀多通道ADC
#include "intrins.h"

謝謝哥,我先去試試。




歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 天天天天操 | 欧美日韩在线免费 | 二区三区视频 | 亚洲一区久久 | 91福利网| 日韩免费1区二区电影 | 久久精品手机视频 | 粉色午夜视频 | 亚洲三级视频 | 日本爱爱| av高清毛片 | 亚洲不卡在线观看 | 国产成人综合亚洲欧美94在线 | 日韩中文字幕视频 | 日日操夜夜操天天操 | 天天干天天操天天爽 | 亚洲毛片 | 99精品国产一区二区青青牛奶 | 国产精品久久久久久久久久久新郎 | 国产精品亚洲第一区在线暖暖韩国 | 亚洲精品免费视频 | 在线视频一区二区 | 欧美区在线观看 | 九九在线视频 | 一级毛片免费看 | 日日夜夜天天干 | 国产精品av久久久久久毛片 | 久久久久一区 | 国产亚洲一区二区三区在线 | 在线观看欧美一区 | 国产女人与拘做视频免费 | 国产高清视频在线观看 | 中文字幕成人av | 欧美一区二区三区国产 | 一级欧美日韩 | 精品一区电影 | 国产精品国产精品国产专区不片 | 国产精品久久久久久久久大全 | 国产第1页 | 午夜激情影院 | 欧美网址在线观看 |