專(zhuān)注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

使用STC12C5204AD單片機(jī)的數(shù)字電壓表

作者:黃云   來(lái)源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2013年11月13日   【字體:

        這是一塊使用STC12C5204AD數(shù)字電壓表的制作程序,P0.0-P0.3 共陰數(shù)碼管位驅(qū)動(dòng)端,P2口為共陰數(shù)碼管段a-g及dp的段驅(qū)動(dòng)端口,P0、P2口設(shè)置為推挽輸出方式,段輸出加470歐限流電阻,AD為8位,轉(zhuǎn)換電壓分度5/256=0.0195312V,分流電阻為實(shí)測(cè)阻值,AD值*0.0195312v/對(duì)地分流電阻,算出分流電流,然后用分流電流*分流電阻與限流電阻之和即為要顯示的輸入電壓值。業(yè)余使用,精度已經(jīng)夠用了,比那個(gè)小的指針的要準(zhǔn)確多了。其中涉及到端口設(shè)置的地方大家對(duì)照芯片手冊(cè)更正。
#include <STC12C52.H>  //STC12C5204AD頭文件 (6 K) 下載次數(shù):15
#include <intrins.h>   //_nop_();
#define uchar unsigned char
#define uint  unsigned int
//sfr ADC_CONTR=0XBC;//adc使能位.ADC電源控制位
sfr ADC_RES=0XBD;// adc數(shù)據(jù)高八位,即ADC值
sfr P1ASF=0X9D;//P1各端口ADC使能端
uchar led_bcd[]={0x3F,/*0*/  //共陰數(shù)碼管
          0x06,/*1*/
          0x5B,/*2*/
          0x4F,/*3*/
          0x66,/*4*/
          0x6D,/*5*/
          0x7D,/*6*/
          0x07,/*7*/
          0x7F,/*8*/
          0x6F,/*9*/
    0x00,/* */
    0x7c /*b*/
    }
    ,ad_data
    ;
uint data dis[5]={0x00,0x00,0x00,0x00,0x00},ZZ; //定義四個(gè)顯示數(shù)據(jù)單元和一個(gè)數(shù)據(jù)存儲(chǔ)單元
//dis[4,3,2,1,5]  顯示:12.34   5為存儲(chǔ)單元

/*******************************************************************/
/*  延時(shí)子程序                                                                                                                                 */
/*                                                                                                                  */
/*                                                                                                                                  */
/*******************************************************************/
void delay(uint z)    //延時(shí)子函數(shù)

   uchar de1,de2;
  for(de1=z;de1>0;de1--)
  for(de2=100;de2>0;de2--); 
}
/*******************************************************/
//顯示子函數(shù) display(h1,h2,h3,h4)
//h1,h2,h3,h4 為四位LED數(shù)碼管顯示變量
//
//
//
/*******************************************************/
void display(uchar h1,uchar h2,uchar s1,uchar s2)   ////LED顯示函數(shù)(參數(shù):LED1,LED2,LED3,LED4)
{

// 第一個(gè)數(shù)碼管顯示數(shù)據(jù)
if(h1==0x3f) h1=0x00;   //0消隱語(yǔ)句
P2=h1;
  //delay(2);
P00=0;
  delay(2);   //參數(shù)2-10   數(shù)值大LED亮度高但閃爍感強(qiáng),數(shù)值小LED亮度低,但閃爍感小.
P2=0X00;
P00=1;
/*******************************************************/
// 第二個(gè)數(shù)碼管顯示數(shù)據(jù)
P2=h2|0x80;
  //delay(2);
P01=0;
  delay(2);  //參數(shù)2-10   數(shù)值大LED亮度高但閃爍感強(qiáng),數(shù)值小LED亮度低,但閃爍感小.
P2=0X00;
P01=1;
//delay(5);
/*******************************************************/
// 第三個(gè)數(shù)碼管顯示數(shù)據(jù)

P2=s1;
  //delay(2);
P02=0;
  delay(2); //參數(shù)2-10   數(shù)值大LED亮度高但閃爍感強(qiáng),數(shù)值小LED亮度低,但閃爍感小.
  P2=0X00;
    P02=1;
// delay(5);
/*******************************************************/
// 第四個(gè)數(shù)碼管顯示數(shù)據(jù)
P2=s2;
  //delay(2);
P03=0;
  delay(2); //參數(shù)2-10   數(shù)值大LED亮度高但閃爍感強(qiáng),數(shù)值小LED亮度低,但閃爍感小.
  P2=0X00;
P03=1;

//delay(5);

}
void init()//系統(tǒng)初始化函數(shù)
{
P2M1=0Xff; //強(qiáng)推挽   推動(dòng)a-g dp
P2M0=0X00; //強(qiáng)推挽   推動(dòng)a-g dp
P0M1=0X0f; //強(qiáng)推挽   推動(dòng)位
P0M0=0X00; //強(qiáng)推挽   推動(dòng)位
P0=0XFF;   //初始化
P2=0;    //初始化
/***定時(shí)器0初始化設(shè)置*****/ 
TMOD = 0x01;
    TH0 = 0xFC;  //初值1ms
    TL0 = 0x18;  //初值1ms
    EA = 1;   //開(kāi)總中斷
    ET0 = 1;  //定時(shí)器0中斷打開(kāi)
    TR0 = 1;  //打開(kāi)定時(shí)器 開(kāi)始計(jì)時(shí)
/*************************/
ZZ=0;
}
void initADC()  //AD初始化
{
P1ASF=0x01;//只使用P1.0端口做為ADC輸入端.
ADC_RES=0;//ADC數(shù)據(jù)寄存器清零
ADC_CONTR=ADC_POWER|ADC_SPEEDLL;  //打開(kāi)ADC開(kāi)關(guān)并設(shè)置 轉(zhuǎn)換速率詳見(jiàn)STC12C52.H
delay(2);  //打開(kāi)ADC并延時(shí).
}
uchar readADC()   //讀AD
{
ADC_CONTR=ADC_POWER|ADC_SPEEDLL|0|ADC_START;
_nop_();
_nop_();
_nop_();
_nop_();
while(!(ADC_CONTR&ADC_FLAG));//等待轉(zhuǎn)換完成標(biāo)志
ADC_CONTR&=~ADC_FLAG;//close ADC
return ADC_RES;//返回ADC值.
}
void main()
{
init();
initADC();//初始化ADC
ad_data=readADC();//開(kāi)機(jī)轉(zhuǎn)換
while(1)
{
  float j;
  uchar ad_data;
  while(ZZ>=500) //500毫秒讀一次ADC
  {
   ad_data=readADC();//讀入ADC數(shù)據(jù)
   ZZ=0;
  }
  j=ad_data*19.5312;//由AD數(shù)據(jù)*19.5312(放大1000倍)=分流后的電壓
  j=j/9890; //j(電壓)/接地電阻(實(shí)測(cè))9890歐
  j=j*60190;//j(電流)*(輸入限流電阻(實(shí)測(cè))60190歐+接地電阻(實(shí)測(cè))9890歐) 計(jì)算出實(shí)際輸入電壓 如果使用高精度電阻,則直接輸入電阻值
  dis[4]=j/1000;
  dis[3]=dis[4]/10;
  dis[2]=dis[4]%10;
  //h=(h-(dis[3]*10+dis[2]))*100;
  dis[4]=j/10-dis[4]*100;
  //dis[4]=j%100;//小數(shù)位第一位
  dis[1]=dis[4]/10;
  dis[0]=dis[4]%10;//小數(shù)位第二位
  //delay(10000);
}
}
void Timer0Interrupt(void) interrupt 1
{
    ZZ++;   //AD讀取間隔時(shí)間控制
TH0 = 0xFC;
    TL0 = 0x18;
display(led_bcd[dis[3]],led_bcd[dis[2]],led_bcd[dis[1]],led_bcd[dis[0]]);
   }

關(guān)閉窗口

相關(guān)文章