求基于单片机的数字电压表C51程序

核心提示//晶振:11.0592MHz,定时器T0每50ms中断一次,每隔0.1秒读ADC一次#include "reg51.

//晶振:11.0592MHz,定时器T0每50ms中断一次,每隔0.1秒读ADC一次

#include "reg51.h"

#include "intrins.h"

#include "math.h"

sbit ad_clk=P1^0;

sbit ad_dout=P1^1;

sbit ad_cs=P1^2;

unsigned char data re_data;

unsigned int data T_cnt;

double volt,xishu;

char code led_seg_code[10]={0x3f,0x06,0x05b,0x04f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

//led_seg_code[0-9]代表0-9的7段码

//---------------

void delay(unsigned int i)//延时

{ while(--i); }

//---------------

void led_show(double f)

{ unsigned char i,s;

unsigned int k,*j;

if (f<2)

{ k=f;//取整数 部分

i=k;

P0=led_seg_code[i] | 0x80;

P2=0xfb;

delay(50);

i=f*10;

i=i%10;

P0=led_seg_code[i];

P2=0xfd;

delay(50);

i=f*100; //取小数后1位

i=i%10;

P0=led_seg_code[i];

P2=0xfe;

delay(50);

else //超限报警,显示“---”

{ P0=0x40;

P2=0xfb;

delay(50);

//---------

P2=0xfd;

delay(50);

//-----------

P2=0xfe;

delay(50);

}

}

//----读取ADC转换器TLC549的数据----

unsigned char receive_data()

{unsigned char i,d;

d=0;

ad_cs=1; // /CS置高,片选无效

ad_clk=0;

ad_cs=0;

_nop_();

for(i<0;i<8;i++)

{ ad_clk=1;

d=d<<1;

if (ad_dout)

{ d++;}

ad_clk=0;

}

ad_cs=1;

for(i=0;i<10;i++) // 适当延时超过17us

_nop_();

return d;

}

//-------------

main()

{T_cnt=0;

TMOD=0x01; //定时器设置T0

TH0=0x4c; //50000us=(65536-0x4c00)*12/11.0592

TL0=00;

EA=0;

TR0=1;

re_data=0x00;

volt=0;

xishu=2.5/255.0;

//-----------------------------

while(1)

{ if(TF0==1)

{ TF0=0;

TH0=0x4c; //50000us=(65536-0x4c00)*12/11.0592

TL0=0x0;

if (T_cnt<2) //T0为50毫秒溢出一次,每100ms读取一次AD转换器数据

{T_cnt++;}

else

{ T_cnt=0;//计时到100ms了

re_data=receive_data();

//转换为电压值

volt=re_data;

volt=volt*xishu;

}

}

led_show(volt);

}

}

AT89C51单片机内部没有AD转换模块,可以通过IO口扩展AD转换芯片现在市面上很多这种芯片比如TLC2543、ads1204就是,如果电压表精度要求不高,用后出来的单片机内部就集成了AD转换芯片比如avr、PIC等。

 
友情链接
鄂ICP备19019357号-22