找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索

開源基于STC單片機內(nèi)部基準mini電壓表—極簡設(shè)計創(chuàng)新制作

查看數(shù): 87653 | 評論數(shù): 235 | 收藏 137
關(guān)燈 | 提示:支持鍵盤翻頁<-左 右->
    組圖打開中,請稍候......
發(fā)布時間: 2016-10-20 15:32

正文摘要:

開源基于STC單片機內(nèi)部基準(Bandgap voltage reference)mini電壓表—極簡設(shè)計創(chuàng)新制作 1.hello-壇友們大家好!今天開源制作一款9.99v量程的電壓表(改變一下電阻和程序可以改為更大量程),只需要單片機數(shù)碼管電 ...

回復(fù)

ID:66416 發(fā)表于 2021-7-13 01:21
@樓主,過來幫忙看一下,為什么我用的共陽極的,改了程序還是沒有顯示:
一、原理圖:
二、STC15ADC.c
/********************************************/
//2016.10.20日 1:01編寫完成
//作者:劉海龍 (讀單片機內(nèi)部BandGap基準電壓值參考的STC官網(wǎng)程序)
//硬件:STC15W408AS+3位共陰數(shù)碼管+2個10K的電阻(1/4w)
//晶振無說明的情況選12M
//測量口P1.3
#include <STC15W.h>
#include <intrins.h>
#include<4LED_YIN.H>//數(shù)碼管驅(qū)動顯示程序
#include <BandGap.H>//包含讀單片機內(nèi)部BandGap基準電壓值       
/********************************/
void main (void)
{        Delay20ms();//待系統(tǒng)穩(wěn)定
    InitADC();//初始化ADC
    P1M1=0X08;//P1.3高阻輸入
          init();//IO口設(shè)置初始化
    while (1)
    {
        ShowResult(3);//顯示通道P1.3的測量值、單位為毫伏
                    disp();        //數(shù)碼管顯示電壓值
    }
}


三、4LED_YIN.H
/***********四位共陰數(shù)碼管驅(qū)動程序************/
//stc15w單片機
//1在主程序前加上初始化init();程序
//2硬件連接變動時需修改下面的參數(shù)
sbit H1        = P1^0;//設(shè)置第1位數(shù)碼管陽極連接的I/O口
sbit H2        = P1^1;//設(shè)置第2位數(shù)碼管陽極連接的I/O口
sbit H3        = P1^2;//設(shè)置第3位數(shù)碼管陽極連接的I/O口
//sbit H4        = P1^7;//設(shè)置第4位數(shù)碼管陽極連接的I/O口
sbit a        = P3^7;
sbit b        = P3^6;
sbit c        = P3^5;
sbit d        = P3^4;
sbit e        = P3^3;
sbit f        = P3^2;
sbit g        = P3^1;
sbit dp        = P3^0;
unsigned char PWM;//顯示亮度
unsigned int v;//定義測量電壓變量
#define P1M0SET                0x00 //設(shè)置I/O口工作方式//00000000(左到右,高到低位)
#define P1M1SET                0x00 //設(shè)置I/O口工作方式//00000000
#define P3M0SET                0xFF //設(shè)置I/O口工作方式//11111111
#define P3M1SET                0x00 //設(shè)置I/O口工作方式//00000000
/*****以上定義需要根據(jù)實際硬件情況更改******/
#define light                        9         //設(shè)置LED顯示的亮度(值域:1~9)
#define DELAY_L                12         //設(shè)置每一個點顯示的時間長度(1~20)
/********* 延時函數(shù)    ***************/
void delay (unsigned int a){ // 用于點掃描的延時
        unsigned int i;
        while( a-- != 0){
                for(i = 0; i < DELAY_L; i++);
        }                                     
}
/*********************************************************************************************/
unsigned char code disdata[]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09}; //顯示0~9的段碼

//數(shù)碼管:負向位置;共陽極;負向連接

void dis_off (void){
        P3 = P3M0SET; //關(guān)所有顯示
        P1 = ~P1M0SET;
        delay(10-PWM);
}
/*********************************************************************************************/
void displayHH1 (unsigned char q){ //第1位數(shù)碼管顯示程序
        unsigned char i;
        i = q & 0x7F;
        if(i == 0x7F){
                H1 = 0;a = 0;}delay(PWM);dis_off();
        i = q & 0xBF;
        if(i == 0xBF){
                H1 = 0;b = 0;}delay(PWM);dis_off();
        i = q & 0xDF;
        if(i == 0xDF){
                H1 = 0;c = 0;}delay(PWM);dis_off();
        i = q & 0xEF;
        if(i == 0xEF){
                H1 = 0;d = 0;}delay(PWM);dis_off();
        i = q & 0xF7;
        if(i == 0xF7){
                H1 = 0;e = 0;}delay(PWM);dis_off();
        i = q & 0xFB;
        if(i == 0xFB){
                H1 = 0;f = 0;}delay(PWM);dis_off();
        i = q & 0xFD;
        if(i == 0xFD){
                H1 = 0;g = 0;}delay(PWM);dis_off();
        i = q & 0xFE;
        if(i == 0xFE){
                H1 = 0;dp = 0;}delay(PWM);dis_off();
}
/*********************************************************************************************/
void displayHH2 (unsigned char q){ //第2位數(shù)碼管顯示程序
        unsigned char i;
        i = q & 0x7F;
        if(i == 0x7F){
                H2 = 0;a = 0;}delay(PWM);dis_off();
        i = q & 0xBF;
        if(i == 0xBF){
                H2 = 0;b = 0;}delay(PWM);dis_off();
        i = q & 0xDF;
        if(i == 0xDF){
                H2 = 0;c = 0;}delay(PWM);dis_off();
        i = q & 0xEF;
        if(i == 0xEF){
                H2 = 0;d = 0;}delay(PWM);dis_off();
        i = q & 0xF7;
        if(i == 0xF7){
                H2 = 0;e = 0;}delay(PWM);dis_off();
        i = q & 0xFB;
        if(i == 0xFB){
                H2 = 0;f = 0;}delay(PWM);dis_off();
        i = q & 0xFD;
        if(i == 0xFD){
                H2 = 0;g = 0;}delay(PWM);dis_off();
        i = q & 0xFE;
        if(i == 0xFE){
                H2 = 0;dp = 0;}delay(PWM);dis_off();
}
/*********************************************************************************************/
void displayHH3 (unsigned char q){ //第3位數(shù)碼管顯示程序
        unsigned char i;
        i = q & 0x7F;
        if(i == 0x7F){
                H3 = 0;a = 0;}delay(PWM);dis_off();
        i = q & 0xBF;
        if(i == 0xBF){
                H3 = 0;b = 0;}delay(PWM);dis_off();
        i = q & 0xDF;
        if(i == 0xDF){
                H3 = 0;c = 0;}delay(PWM);dis_off();
        i = q & 0xEF;
        if(i == 0xEF){
                H3 = 0;d = 0;}delay(PWM);dis_off();
        i = q & 0xF7;
        if(i == 0xF7){
                H3 = 0;e = 0;}delay(PWM);dis_off();
        i = q & 0xFB;
        if(i == 0xFB){
                H3 = 0;f = 0;}delay(PWM);dis_off();
        i = q & 0xFD;
        if(i == 0xFD){
                H3 = 0;g = 0;}delay(PWM);dis_off();
        i = q & 0xFE;
        if(i == 0xFE){
                H3 = 0;dp = 0;}delay(PWM);dis_off();
}
void diplay_data (unsigned char l,unsigned char q){
                switch (l){//顯示的數(shù)碼管位置               
                                case 1://                       
                                        displayHH1(q); //將顯示數(shù)據(jù)送入               
                                        break;//               
                                case 2://                       
                                        displayHH2(q); //將顯示數(shù)據(jù)送入               
                                        break;//               
                                case 3://                       
                                        displayHH3(q); //將顯示數(shù)據(jù)送入               
                                        break;//
//                                case 4://                       
//                                        displayHH4(q); //將顯示數(shù)據(jù)送入               
//                                        break;//                       
                               
                }
}

/*****************IO口初始化**************************/
void init (void){       
                P3M1=P3M1SET;
                P3M0=P3M0SET;
                P1M0=P1M0SET;
                P1M1=P1M1SET;
                dis_off();
                PWM = light;}
/*******************************************/
/******************顯示程序*************************/
void disp(){
unsigned int i;
        for(i=0;i<50;i++){
                diplay_data (1,disdata[v/1000]+0x80);
                diplay_data (2,disdata[v%1000/100]);
                diplay_data (3,disdata[v%100/10]);
        }
}


四、BandGap.H
//內(nèi)部BandGap為基準測電壓
//-----------------------------------------
#define  uchar unsigned char  
#define uint  unsigned int
unsigned int v;       
//ADC相關(guān)設(shè)定參數(shù)
#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個時鐘
//-----------------------------------------
//BandGap相關(guān)參數(shù)
//注意:需要在下載代碼時選擇"在ID號前添加重要測試參數(shù)"選項,才可在程序中獲取此參數(shù)
//#define ID_ADDR_ROM 0x03f7      //1K程序空間的MCU
//#define ID_ADDR_ROM 0x07f7      //2K程序空間的MCU
//#define ID_ADDR_ROM 0x0bf7      //3K程序空間的MCU
//#define ID_ADDR_ROM 0x0ff7      //4K程序空間的MCU
//#define ID_ADDR_ROM 0x13f7      //5K程序空間的MCU
#define ID_ADDR_ROM 0x1ff7      //8K程序空間的MCU
//#define ID_ADDR_ROM 0x27f7      //10K程序空間的MCU
//#define ID_ADDR_ROM 0x2ff7      //12K程序空間的MCU
//#define ID_ADDR_ROM 0x3ff7      //16K程序空間的MCU
//#define ID_ADDR_ROM 0x4ff7      //20K程序空間的MCU
//#define ID_ADDR_ROM 0x5ff7      //24K程序空間的MCU
//#define ID_ADDR_ROM 0x6ff7      //28K程序空間的MCU
//#define ID_ADDR_ROM 0x7ff7      //32K程序空間的MCU
//#define ID_ADDR_ROM 0x9ff7      //40K程序空間的MCU
//#define ID_ADDR_ROM 0xbff7      //48K程序空間的MCU
//#define ID_ADDR_ROM 0xcff7      //52K程序空間的MCU
//#define ID_ADDR_ROM 0xdff7      //56K程序空間的MCU
//#define ID_ADDR_ROM 0xeff7      //60K程序空間的MCU


//-----------------------------------------
//聲明

void Delay20ms()                //@12.000MHz
{
        unsigned char i, j, k;

        _nop_();
        _nop_();
        i = 1;
        j = 234;
        k = 113;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}


/*----------------------------
初始化ADC
----------------------------*/
void InitADC()
{
           P1ASF = 0x00;                   //不設(shè)置P1口為AD口
    ADC_RES = 0;                    //清除結(jié)果寄存器
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
        Delay20ms();
}
/*----------------------------
讀取ADC結(jié)果
----------------------------*/
uint GetADCResult(uchar ch)
{
    uint ADC_10BIT_RES;
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
    _nop_();                        //等待4個NOP
    _nop_();
    _nop_();
    _nop_();
    while (!(ADC_CONTR & ADC_FLAG));//等待ADC轉(zhuǎn)換完成
    ADC_CONTR &= ~ADC_FLAG;         //關(guān)閉 ADC
    ADC_10BIT_RES=ADC_RES;      //得到高8位
    ADC_10BIT_RES<<=2;
    ADC_10BIT_RES+=ADC_RESL;     //得到低2位
    return ADC_10BIT_RES;                 //返回ADC結(jié)果

}

/*----------------------------
發(fā)送ADC結(jié)果
----------------------------*/
void ShowResult(uchar ch)
{
    uint adc_res10,//測量設(shè)定通道adc值
    bandgap,       //bandgap預(yù)儲存校準值,單位毫伏
    adc_9gallery_res; //測量第九通道(bandgap)值
    float power_voltage,        //系統(tǒng)供電電壓,單位毫伏
    ADC_voltage;     //設(shè)定通道電壓值,單位毫伏

    uchar  code *cptr; //定義ROM(代碼)區(qū)指針
    //uchar  idata *iptr;//定義RAM(內(nèi)存)區(qū)指針

    cptr = ID_ADDR_ROM;         //從程序區(qū)讀取BandGap電壓值(單位:毫伏mV)
    bandgap=*cptr++;
    bandgap<<=8;
    bandgap+=*cptr;
    /*iptr = ID_ADDR_RAM;         //從內(nèi)存區(qū)讀取BandGap電壓值(單位:毫伏mV)
    bandgap=*iptr++;              //兩種方法結(jié)果一樣,上面的方法需要在下載式勾選"在ID號前添加重要測試參數(shù)"選項,才可在程序中獲取此參數(shù)
    bandgap<<=8;                  //下面的方法不需要
    bandgap+=*iptr;    */
    //測量設(shè)定通道adc值
    ADC_RES = 0;                    //清除結(jié)果寄存器
    P1ASF = 0x08;                   //設(shè)置P1.3口為AD口
    GetADCResult(ch);
    GetADCResult(ch);                 //讀三次獲得穩(wěn)定
    adc_res10= GetADCResult(ch);
    //測量第九通道(bandgap)值
    ADC_RES = 0;                    //清除結(jié)果寄存器
    P1ASF = 0x00;                   //設(shè)置讀第九通道
    GetADCResult(0);                 //測bandgap時,調(diào)用此函數(shù)時通道數(shù)只能填0
    GetADCResult(0);                 //讀三次獲得穩(wěn)定
    adc_9gallery_res=GetADCResult(0);
    //計算系統(tǒng)供電電壓
    power_voltage=(float)bandgap*1024/adc_9gallery_res;
    //計算ADC通道測得電壓值
    ADC_voltage=(float)bandgap*adc_res10/adc_9gallery_res;
        v=ADC_voltage;
        v=v*2;
}


原理圖.jpg (185.98 KB, 下載次數(shù): 998)

原理圖

原理圖
ID:1148909 發(fā)表于 2025-4-24 20:56
你發(fā)帖子,我點贊,鼓勵繼續(xù)做貢獻
ID:759144 發(fā)表于 2025-3-25 23:54
新手入門,學習中,感謝分享!
ID:299780 發(fā)表于 2025-3-23 11:22
好文章,我現(xiàn)在才看到
ID:343102 發(fā)表于 2025-3-22 22:51
謝謝分享!
ID:759144 發(fā)表于 2025-3-22 21:11
單片機學習中,向無私分享的大神們致敬!
ID:356964 發(fā)表于 2025-1-3 11:07
好文章,學習了,收益很大!
ID:1075398 發(fā)表于 2024-12-27 08:29
越快樂越墮落 發(fā)表于 2017-5-4 11:11
這樣就可以了?數(shù)碼管的百位會不會亂碼?是繼續(xù)用三位數(shù)碼管嗎?如果是,那么小數(shù)點的位移怎么解決?比如 ...

雖然我來的晚,但是我看見樓主說了,這個表量程9.9V,你要測量30.5V那肯定出問題,
ID:235691 發(fā)表于 2024-12-7 09:26
a185980800 發(fā)表于 2024-2-23 22:34
把R1換成多圈可調(diào)電阻,就可以校準了

探討程序校準,硬件校準沒有意義
ID:857072 發(fā)表于 2024-2-23 22:34
gpdt3209 發(fā)表于 2022-11-15 13:48
增加標定校準功能就準了,哪位大師可以改改

把R1換成多圈可調(diào)電阻,就可以校準了
ID:890642 發(fā)表于 2023-12-18 22:59
taoran 發(fā)表于 2016-10-20 19:52
電路還是很簡潔的,stc的內(nèi)部基準不知道精度怎么樣。先收藏備用了,對了樓主你那個原理圖還漂亮 請教下是用 ...

應(yīng)該是AD
ID:890642 發(fā)表于 2023-12-18 22:48
樓主分享的很有用,辛苦樓主了,這個改4位也好改吧
ID:43600 發(fā)表于 2023-11-15 01:09
手頭剛好友幾個stc15w408as,有空拿來做電壓電流表似乎有不錯,謝樓主。
ID:237471 發(fā)表于 2023-11-1 18:47
支持努力實踐并分享成果的人
ID:65066 發(fā)表于 2023-10-29 09:50
很好的資料,收藏學習!謝謝分享
ID:608872 發(fā)表于 2023-10-26 11:17
數(shù)碼管不亮,測了位選高電平4.6V,段選也是高電平4.48V
ID:1092028 發(fā)表于 2023-8-27 19:59
都是牛人啊,下去用protues仿真測試一下下
ID:1066267 發(fā)表于 2023-4-10 00:30
很好的東西,值得學習,準備試試。
ID:1595 發(fā)表于 2023-3-30 09:37
完全照著樓主的做了一個,效果還可以。

3V.jpg (500.39 KB, 下載次數(shù): 580)

3V.jpg

4V.jpg (609.73 KB, 下載次數(shù): 593)

4V.jpg

5V.jpg (544.27 KB, 下載次數(shù): 589)

5V.jpg

實物圖.jpg (819.77 KB, 下載次數(shù): 633)

實物圖.jpg
ID:283207 發(fā)表于 2023-3-27 10:48
很好,值得分享,建議單片機多IO口都沒用,可以做成雙路現(xiàn)實的,實現(xiàn)電壓、電流同時測試、顯示。
ID:824664 發(fā)表于 2023-3-13 00:01
簡單實用,新意構(gòu)思,值得學習。
ID:1037819 發(fā)表于 2022-12-27 06:49
fmdpj 發(fā)表于 2022-6-24 14:13
樓主還會來看嗎?我下載了附件,源代碼就怎么就這么一點點

****************************************** ...

我沒分,下不了。應(yīng)該還有H文件
ID:85508 發(fā)表于 2022-12-8 19:45
樓主的設(shè)計簡單、實用,適合初學仿制。
ID:235691 發(fā)表于 2022-11-15 13:48
增加標定校準功能就準了,哪位大師可以改改
ID:495990 發(fā)表于 2022-11-2 19:42
很好,值得點贊和學習
ID:96653 發(fā)表于 2022-8-22 11:59
就喜歡這簡潔的設(shè)計,內(nèi)部基準精度應(yīng)該夠用,現(xiàn)在影響精度的是外部電阻,
ID:456690 發(fā)表于 2022-7-1 19:21
第九通道是讀取第0通道的值P1.0口,你的電路圖里是P1.7口。是不是畫錯了?


第九通道.jpg (160.55 KB, 下載次數(shù): 582)

第九通道

第九通道
ID:796531 發(fā)表于 2022-6-25 11:06
程序中     //計算系統(tǒng)供電電壓
    power_voltage=(float)bandgap*1024/adc_9gallery_res;
多余了,沒用到,浪費算力
ID:598951 發(fā)表于 2022-6-24 14:13
樓主還會來看嗎?我下載了附件,源代碼就怎么就這么一點點

********************************************/
//2016.10.20日 1:01編寫完成
//作者:劉海龍 (讀單片機內(nèi)部BandGap基準電壓值參考的STC官網(wǎng)程序)
//硬件:STC15W408AS+3位共陰數(shù)碼管+2個10K的電阻(1/4w)
//晶振無說明的情況選12M
//測量口P1.7
#include <STC15W.h>
#include <intrins.h>
#include<4LED_YIN.H>//數(shù)碼管驅(qū)動顯示程序
#include <BandGap.H>//包含讀單片機內(nèi)部BandGap基準電壓值       
/********************************/
void main (void)
{        Delay20ms();//待系統(tǒng)穩(wěn)定
    InitADC();//初始化ADC
    P1M1=0X80;//P1.7高阻輸入
        init();//IO口設(shè)置初始化
    while (1)
    {
        ShowResult(7);//顯示通道P1.7的測量值、單位為毫伏
                disp();        //數(shù)碼管顯示電壓值
    }
}
ID:598951 發(fā)表于 2022-6-24 14:04
wjqzywmm 發(fā)表于 2021-7-19 18:43
我驅(qū)動4為共陽的方法,電路圖相同,供參考:
unsigned char code disdata[]={
0x01,0x4F,0x12,0x06,0x ...

你好!能否把完整的源代碼分享給我,先謝謝了
ID:598951 發(fā)表于 2022-6-24 13:58
要是能移植到儲能點焊機控制板里面,用于監(jiān)視儲能電容電壓,這樣就不用另外配個電壓表,不會玩單片機只能看看
ID:170800 發(fā)表于 2022-6-22 09:36
大神:LED沒有限流電阻,這個方案是如何控制電流,避免LED和MCU過流損壞的呢?
ID:170800 發(fā)表于 2022-6-22 09:35
原理很好,但有不理解的地方:一般而言,用限流電阻控制各LED的電流,目前的方案是以什么方式控制LED電流,以減少LED及MCU的過電流損壞??
ID:936913 發(fā)表于 2021-7-19 18:43
hewe_001 發(fā)表于 2021-7-13 01:21
@樓主,過來幫忙看一下,為什么我用的共陽極的,改了程序還是沒有顯示:
一、原理圖:
二、STC15ADC.c

我驅(qū)動4為共陽的方法,電路圖相同,供參考:
unsigned char code disdata[]={
0x01,0x4F,0x12,0x06,0x4C,
0x24,0x20,0x0D,0x00,0x04};//0-9


void dis_off (){
        P3 = 0xFF; //P3對應(yīng)筆畫,關(guān)所有顯示
        H2=1;H4=1;
        H1=1;H3=1;
        delay(10-light);
}

void dispNum (unsigned char q,unsigned char dot){        //dot=1為顯示小數(shù)點;
                unsigned char x;
                x=disdata[q];
                dp=1-dot;                       
                a=x>>6 & 0x01;
                b=x>>5 & 0x01;
                c=x>>4 & 0x01;
                d=x>>3 & 0x01;
                e=x>>2 & 0x01;
                f=x>>1 & 0x01;
                g=x & 0x01;
}


/******************顯示程序*************************/
void disp(){
        unsigned int ii;
        unsigned int vv;
        unsigned char i;
        for(ii=0;ii<50;ii++){
                i=v%10;   //我用的是四位led,所以這里的v=原始v/10
                vv=v-i;
                H1=0;dispNum(i,0);delay(light);dis_off();
                i=(vv/10)%10;
                vv=vv-10*i;
                H2=0;dispNum(i,0);delay(light);dis_off();
                i=(vv/100)%10;
                vv=vv-100*i;
                H3=0;dispNum(i,1);delay(light);dis_off();        //第三位顯示小數(shù)點
                i=(vv/1000)%10;
                if(i>0){
                        H4=0;dispNum(i,0);delay(light);dis_off();  //第四位是0,不顯示
                }
        }
}


ID:936913 發(fā)表于 2021-7-14 22:11
真夠簡單的,正好想做一個,感謝樓主分享。!
ID:899156 發(fā)表于 2021-7-14 07:53
你發(fā)帖子,我點贊,鼓勵繼續(xù)做貢獻!
ID:66416 發(fā)表于 2021-7-13 16:26
劉海龍 發(fā)表于 2016-10-20 16:39
下載時要勾選圖片中紅色圈內(nèi)的選項

下載時已經(jīng)勾選了!
ID:53978 發(fā)表于 2021-7-13 08:33
留個記號 有時間了來學習一下,謝謝大神們。
ID:951574 發(fā)表于 2021-7-12 11:24
電路簡潔,先收藏一下
ID:66416 發(fā)表于 2021-7-11 22:20
樓主能不能改個共陽的程序?
或者在4LED_YIN.h中指明一下,怎樣修改?

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表