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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

如何將電池電壓通過ADC轉換顯示到液晶屏上?附單片機代碼

[復制鏈接]
跳轉到指定樓層
樓主
怎么將電池電壓通過AD轉換顯示到液晶上。液晶屏字模已經顯示好。一個液晶初始化代碼和ADC轉換查詢代碼東拼西湊組成的程序。顯示電壓顯示0.
芯片型號STC15F2K60S2.輸入腳接的P1.7通過兩個1K電阻分壓


單片機代碼如下
#include "REG51.h"
#include "oled.h"
#include "bmp.h"
#include "intrins.h"
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 InitADC();//初始化ADC
typedef unsigned char BYTE;//串口通道名稱聲明
BYTE ch = 7;                        //ADC通道號
BYTE GetADCResult(BYTE ch);//讀取adc結果
void ShowResult(BYTE ch);
void nem(BYTE dat);

int main(void)
{        
        Init_ssd1327();
        while(1)
        {
                OLED_ShowChinese(0,48,0,16);
                OLED_ShowChinese(16,48,1,16);
                OLED_ShowNum(40,36,nem,4,32);
                OLED_ShowString(112,36,"V",32);
                delay_ms(1000);
                ShowResult(7);              //顯示通道7
        }
}

/*----------------------------
發送ADC結果到液晶顯示
----------------------------*/
void ShowResult(BYTE ch)
{
    nem(ch);                   //顯示通道號
    nem(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結果
}

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

        

51hei圖片20221229113832.jpg (3.33 MB, 下載次數: 96)

OLED接線測試

OLED接線測試

51hei圖片20221229114122.png (361.49 KB, 下載次數: 93)

STC15F2K60S2管腳圖

STC15F2K60S2管腳圖

51hei圖片20221229114128.png (158.42 KB, 下載次數: 93)

STC15內部ADC結構

STC15內部ADC結構
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:301191 發表于 2022-12-30 06:04 | 只看該作者
頂一下
回復

使用道具 舉報

板凳
ID:161164 發表于 2022-12-30 09:17 | 只看該作者
這代碼編譯時沒報錯嗎?
nem是什么gui??
回復

使用道具 舉報

地板
ID:190152 發表于 2022-12-30 11:03 來自手機 | 只看該作者
lkc8210 發表于 2022-12-30 09:17
這代碼編譯時沒報錯嗎?
nem是什么gui??

報了幾個錯,被我解決了。nem是我想顯示的電壓數值
回復

使用道具 舉報

5#
ID:161164 發表于 2022-12-30 11:39 | 只看該作者
高低都不調 發表于 2022-12-30 11:03
報了幾個錯,被我解決了。nem是我想顯示的電壓數值

為啥不把新代碼貼上來?
回復

使用道具 舉報

6#
ID:190152 發表于 2022-12-30 11:48 來自手機 | 只看該作者
lkc8210 發表于 2022-12-30 11:39
為啥不把新代碼貼上來?

這個代碼就是改好的,編譯器可以通過編譯就是不知道哪里錯了顯示屏不顯示電壓值
回復

使用道具 舉報

7#
ID:213173 發表于 2022-12-30 15:06 | 只看該作者
高低都不調 發表于 2022-12-30 11:48
這個代碼就是改好的,編譯器可以通過編譯就是不知道哪里錯了顯示屏不顯示電壓值

ADC轉換結果不是電壓,還要通過公式計算才能得到電壓值。模擬信號輸入端口要設置高阻模式。
  1. /*----------------------------
  2. 發送ADC結果到液晶顯示
  3. ----------------------------*/
  4. void ShowResult(BYTE ch)
  5. {
  6.         unsigned int mV;
  7.         unsigned char temp;
  8.     nem(ch);                   //顯示通道號
  9.         temp=GetADCResult(ch);
  10.         //毫伏=(參考電壓VCC*八位ADC結果*1000/256)*分壓比
  11.         mV=5*(long)temp*1000/256*2;
  12.         nem(mV);     //顯示電壓毫伏
  13. }
  14. /*----------------------------
  15. 初始化ADC
  16. ----------------------------*/
  17. void InitADC()
  18. {
  19.         P1M0 = 0x80;                                         //設置P1.7高阻 1000 0000
  20.         P1M1 = 0x00;
  21.     P1ASF = 0x80;                   //設置P1.7口為模擬輸入
  22.     ADC_RES = 0;                    //清除結果寄存器
  23.     ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
  24.     delay_ms(2);                       //ADC上電并延時
  25. }
  26. /*----------------------------
  27. 讀取ADC結果
  28. ----------------------------*/
  29. BYTE GetADCResult(BYTE ch)
  30. {
  31.     ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
  32.     _nop_();                        //等待4個NOP
  33.     _nop_();
  34.     _nop_();
  35.     _nop_();
  36.     while (!(ADC_CONTR & ADC_FLAG));//等待ADC轉換完成
  37.     ADC_CONTR &= ~ADC_FLAG;         //Close ADC
  38.     return ADC_RES;                 //返回8位ADC結果
  39. }
復制代碼

回復

使用道具 舉報

8#
ID:190152 發表于 2022-12-31 13:56 | 只看該作者
感謝各位熱情回答修改好的代碼液晶上成功顯示電壓3866mv 電腦串口也可以同時顯示AD轉換值


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


#include "reg51.h"
#include "intrins.h"
#include "oled.h"
#include "bmp.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);
unsigned int num;//AD轉換數據緩存
unsigned int mV;//AD電壓顯示數字毫伏
ch=7;

void main()
{
    P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x80;
    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
        Init_ssd1327();                 //初始化OLED液晶驅動
    while (1)
    {
        ShowResult(7);              //顯示通道7
                OLED_ShowChinese(0,48,0,16);
                OLED_ShowChinese(16,48,1,16);
                OLED_ShowNum(40,36,num,4,32);
                OLED_ShowString(112,48,"mV",16);
                num=5*(long)ADC_RES*1000/256*2;
    }
}

/*----------------------------
發送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 = 0x80;                   //設置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--);
    }
}

回復

使用道具 舉報

9#
ID:227484 發表于 2023-10-28 20:05 | 只看該作者
學習了抽空試一下
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲一区国产 | 天天天天操 | 污免费网站 | 日韩成人免费av | 国产成人综合在线 | 久久r免费视频 | 久久久高清 | 伊人艹| 久久久久久蜜桃一区二区 | 成人天堂噜噜噜 | 日韩三区在线 | 国产色网 | 国产粉嫩尤物极品99综合精品 | 七七婷婷婷婷精品国产 | 好姑娘高清在线观看电影 | 黄a大片| 一区二区三区国产精品 | 国产午夜视频 | 国产精品99 | 日韩国产精品一区二区三区 | 国产成人精品一区二区三区在线 | 日本黄色影片在线观看 | 荷兰欧美一级毛片 | 在线观看国产91 | 81精品国产乱码久久久久久 | 精品久久一区二区 | 国产一区二区三区久久久久久久久 | 国产欧美一区二区三区另类精品 | 91资源在线 | 免费看国产精品视频 | 午夜一区 | 91精品国产色综合久久 | 欧美视频成人 | 99精品久久久久 | 日本电影韩国电影免费观看 | 欧美精品二区 | 欧美成人性生活 | 欧美成人激情视频 | 欧美aaa一级片 | 综合久久av | 日韩在线 |