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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6212|回復: 11
收起左側

關于STC15W408AS單片機的ADC程序疑問

[復制鏈接]
ID:590194 發表于 2020-11-3 12:38 | 顯示全部樓層 |閱讀模式
ADC是模轉數.用的芯片是15W408AS 我是按照范例 用的是ADC查詢..

芯片是5V供電

P1.2作為ADC腳

然后P1.2短接GND 為啥讀出來的還是FF?

/* 如果要在程序中使用此代碼,請在程序中注明使用了STC的資料及程序        */
/* 如果要在文章中應用此代碼,請在文章中注明使用了STC的資料及程序        */
/*---------------------------------------------------------------------*/

//本示例在Keil開發環境下請選擇Intel的8058芯片型號進行編譯
//若無特別說明,工作頻率一般為11.0592MHz


#include "reg51.h"
#include "intrins.h"

#define FOSC    11059200L
#define BAUD    115200

typedef unsigned char BYTE;
typedef unsigned int WORD;

#define     URMD    0           //0:使用定時器2作為波特率發生器
                                //1:使用定時器1的模式0(16位自動重載模式)作為波特率發生器
                                //2:使用定時器1的模式2(8位自動重載模式)作為波特率發生器

sfr T2H   = 0xd6;               //定時器2高8位
sfr T2L   = 0xd7;               //定時器2低8位

sfr P1M1 = 0x91;    //PxM1.n,PxM0.n     =00--->Standard,    01--->push-pull
sfr P1M0 = 0x92;    //                  =10--->pure input,  11--->open drain
sfr P0M1 = 0x93;
sfr P0M0 = 0x94;
sfr P2M1 = 0x95;
sfr P2M0 = 0x96;
sfr P3M1 = 0xB1;
sfr P3M0 = 0xB2;
sfr P4M1 = 0xB3;
sfr P4M0 = 0xB4;
sfr P5M1 = 0xC9;
sfr P5M0 = 0xCA;
sfr P6M1 = 0xCB;
sfr P6M0 = 0xCC;
sfr P7M1 = 0xE1;
sfr P7M0 = 0xE2;

sfr  AUXR       =   0x8e;       //輔助寄存器                              

sfr ADC_CONTR   =   0xBC;           //ADC控制寄存器
sfr ADC_RES     =   0xBD;           //ADC高8位結果
sfr ADC_LOW2    =   0xBE;           //ADC低2位結果
sfr P1ASF       =   0x9D;           //P1口第2功能控制寄存器

#define ADC_POWER   0x80            //ADC電源控制位
#define ADC_FLAG    0x10            //ADC完成標志
#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個時鐘

void InitUart();
void InitADC();
void SendData(BYTE dat);
BYTE GetADCResult(BYTE ch);
void Delay(WORD n);
void ShowResult(BYTE ch);

void main()
{
    P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;
    P1M1 = 0x00;
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;
    P3M1 = 0x00;
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;
    P6M0 = 0x00;
    P6M1 = 0x00;
    P7M0 = 0x00;
    P7M1 = 0x00;

    InitUart();                     //初始化串口
    InitADC();                      //初始化ADC
    while (1)
    {
        ShowResult(0);              //顯示通道0
                        Delay(100);
        ShowResult(1);              //顯示通道1
                        Delay(100);
        ShowResult(2);              //顯示通道2
                        Delay(100);
        ShowResult(3);              //顯示通道3
                        Delay(100);
        ShowResult(4);              //顯示通道4
                        Delay(100);
        ShowResult(5);              //顯示通道5

                        Delay(500);
                        
    }
}

/*----------------------------
發送ADC結果到PC
----------------------------*/
void ShowResult(BYTE ch)
{
    SendData(ch);                   //顯示通道號
    SendData(GetADCResult(ch));     //顯示ADC高8位結果

//    SendData(ADC_LOW2);           //顯示低2位結果
}

/*----------------------------
讀取ADC結果
----------------------------*/
BYTE GetADCResult(BYTE ch)
{
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
    _nop_();                        //等待4個NOP
    _nop_();
    _nop_();
    _nop_();
    while (!(ADC_CONTR & ADC_FLAG));//等待ADC轉換完成
    ADC_CONTR &= ~ADC_FLAG;         //Close ADC

    return ADC_RES;                 //返回ADC結果
}

/*----------------------------
初始化串口
----------------------------*/
void InitUart()
{
    SCON = 0x5a;                //設置串口為8位可變波特率
#if URMD == 0
    T2L = (65536 - (FOSC/4/BAUD));
    T2H = (65536 - (FOSC/4/BAUD)) >> 8;
    AUXR = 0x14;                //T2為1T模式, 并啟動定時器2
    AUXR |= 0x01;               //選擇定時器2為串口1的波特率發生器
#elif URMD == 1
    AUXR = 0x40;                //定時器1為1T模式
    TMOD = 0x00;                //定時器1為模式0(16位自動重載)
    TL1 = (65536 - (FOSC/4/BAUD));
    TH1 = (65536 - (FOSC/4/BAUD)) >> 8;
    TR1 = 1;                    //定時器1開始啟動
#else
    TMOD = 0x20;                //設置定時器1為8位自動重裝載模式
    AUXR = 0x40;                //定時器1為1T模式
    TH1 = TL1 = (256 - (FOSC/32/BAUD));
    TR1 = 1;
#endif
}

/*----------------------------
初始化ADC
----------------------------*/
void InitADC()
{
    P1ASF = 0xff;                   //設置P1口為AD口
    ADC_RES = 0;                    //清除結果寄存器
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
    Delay(2);                       //ADC上電并延時
}

/*----------------------------
發送串口數據
----------------------------*/
void SendData(BYTE dat)
{
    while (!TI);                    //等待前一個數據發送完成
    TI = 0;                         //清除發送標志
    SBUF = dat;                     //發送當前數據
}

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

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


回復

使用道具 舉報

ID:213173 發表于 2020-11-3 15:22 | 顯示全部樓層
        P1M1 = 0xff;                                         //設置P1.0~1.7高阻:1111 1111 ADC輸入高阻
        P1M0 = 0x00;                                         //設置P1.0~1.7高阻:0000 0000 ADC輸入高阻
回復

使用道具 舉報

ID:47286 發表于 2020-11-3 22:25 | 顯示全部樓層
你試試把P1口設置成高阻
回復

使用道具 舉報

ID:590194 發表于 2020-11-4 11:01 | 顯示全部樓層
wulin 發表于 2020-11-3 15:22
P1M1 = 0xff;                                         //設置P1.0~1.7高阻:1111 1111 ADC輸入高阻
        P1M0 = 0x00;                                         //設置P1.0~1.7高阻 ...

修改了還是不行.是跟GND短接嗎?我跟GND 跟VDD 短接讀出來的都是FF FE
回復

使用道具 舉報

ID:401564 發表于 2020-11-4 11:45 | 顯示全部樓層
一步一步去找問題
1:在開發板或者是現成的板子上進行測試:設定一個輸出,不管是數碼管還是8個LED都可以,只要能大概顯示一個輸出就行
2:P1.2接上一個可調電壓,調節電壓輸出有變化,就說明你ADC設置是可以進行ADC的了,如果是有完整的顯示就更好了
3:只有完成前面兩個測試,證明ADC可以正常轉換之后,再進行串口顯示,
有的串口軟件并不成正常的顯示8051發送的數據的,如果你已經證明ADC可以正常進行,并且可以輸出可以變化的數據,但串口還是FF,那就說明是串口這一塊有問題,不是代碼就是串口軟件不行,慢慢找 就可以的了
回復

使用道具 舉報

ID:590194 發表于 2020-11-4 12:06 | 顯示全部樓層
Y_G_G 發表于 2020-11-4 11:45
一步一步去找問題
1:在開發板或者是現成的板子上進行測試:設定一個輸出,不管是數碼管還是8個LED都可以,只 ...

謝謝了.我本以為串口輸出會比較好..我最開始用的就是4個LED來讀去的但是讀去的一直是1655所以才嘗試用串口輸出的..我再試試
回復

使用道具 舉報

ID:401564 發表于 2020-11-4 13:53 | 顯示全部樓層
sq8422779 發表于 2020-11-4 12:06
謝謝了.我本以為串口輸出會比較好..我最開始用的就是4個LED來讀去的但是讀去的一直是1655所以才嘗試用串 ...

只要是IO能夠隨著P1.2的電壓變動,這就說明ADC已經在正常轉換了,數據不對就只是ADC格式或者算法不對而已
加了串口就不一樣了,STC串口實際上是有好幾個的,要去設定,而且電腦端的串口軟件有一些并不是通用的,無形中增加了出現問題的可能性
回復

使用道具 舉報

ID:590194 發表于 2020-11-5 09:03 | 顯示全部樓層
Y_G_G 發表于 2020-11-4 13:53
只要是IO能夠隨著P1.2的電壓變動,這就說明ADC已經在正常轉換了,數據不對就只是ADC格式或者算法不對而已
...

謝謝.已經能正常顯示了..有個問題請教一下.這個數值,我用的是平均值..線路設計的時候.光感直接2個角接在P1.2和GND嗎?中間不用加電阻,和電容嗎??
回復

使用道具 舉報

ID:401564 發表于 2020-11-5 09:25 | 顯示全部樓層
sq8422779 發表于 2020-11-5 09:03
謝謝.已經能正常顯示了..有個問題請教一下.這個數值,我用的是平均值..線路設計的時候.光感直接2個角接在P ...

如果光敏電阻,就是串聯一個電阻,分壓取ADC
進入ADC端口串聯不串聯的,沒什么影響,你可以試一下就知道了,實際感覺不到它有什么用,但是,如果是實際的項目,一定是要用個串聯的電阻的,大概100歐左右就可以了,焊盤可以靠近一點,方便以后焊接元件或者直接短路
P1.2端口一定要并聯一個104電容到地,這是最基本的,如果你的電源用的是開關電源,可以換成102或者103的都行,電池或者變壓器就用104的.這個電容一定要有
這104電容就這樣:它有作用的時候,你感覺不到它存在,它沒有的時候你才感覺它有作用
回復

使用道具 舉報

ID:590194 發表于 2020-11-10 08:22 | 顯示全部樓層
Y_G_G 發表于 2020-11-5 09:25
如果光敏電阻,就是串聯一個電阻,分壓取ADC
進入ADC端口串聯不串聯的,沒什么影響,你可以試一下就知道了, ...

嗯.我試了下.串聯一個500k電阻剛好所有量程都在..10bit能采集到.然后這個并的電容.起到什么作用呢?除了這個光感外,還有一個音量采集...這個好像直接接在P1.2上采集不到..是不是要放大電路?
回復

使用道具 舉報

ID:401564 發表于 2020-11-10 08:55 | 顯示全部樓層
sq8422779 發表于 2020-11-10 08:22
嗯.我試了下.串聯一個500k電阻剛好所有量程都在..10bit能采集到.然后這個并的電容.起到什么作用呢?除了這 ...

104電容是抗干擾用的
音頻采樣是要整流才能采樣的,這個我沒有玩過,你上網找一下,自己測試一下
回復

使用道具 舉報

ID:146782 發表于 2020-11-10 09:25 | 顯示全部樓層
并聯電容是起到濾波的作用吧
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美在线一区二区三区四区 | 午夜av电影 | 日韩av免费在线电影 | 亚洲三级在线观看 | 久久免费视频在线 | 99精品一区二区三区 | jav成人av免费播放 | 国产精品福利一区二区三区 | www亚洲精品 | 久久国产精品视频 | 久久综合狠狠综合久久综合88 | 日韩欧美高清 | 国产精品成人国产乱 | 欧美精品久久久久久久久老牛影院 | 国产免费视频 | 日本精品视频 | 精品美女在线观看 | 久久久久国产精品一区二区 | 在线观看视频亚洲 | 一区二区在线免费观看视频 | 成人综合一区 | 欧美13videosex性极品 | 一区二区高清 | 欧美日韩视频网站 | 亚洲精品一区二区三区蜜桃久 | 2020亚洲天堂 | 特黄毛片视频 | 亚洲a级 | 在线国产一区 | 97久久久久久 | 亚洲欧洲国产视频 | 午夜久久av | 欧美一级片黄色 | 亚洲网在线| 日本中出视频 | 粉嫩国产精品一区二区在线观看 | 亚洲精品视频免费 | 天天久| 日韩精品一区二区久久 | 亚洲精品2 | 欧美精品一区二区免费 |