//**10-Bit-ADC:每次给定一个转化电压,需要用开关键进行刷新显示**//
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit RS=P2^0; // 数据/命令选择位,低电平为命令,高电平为数据
sbit RW=P2^1; // 读/写选择位,低电平为写,高电平为读
sbit EN=P2^2; //使能端,提供脉冲
sbit en=P1^0;
uchar code table1[]="------ADC-------";
uchar code table2[]="voltage :0.00000";
uchar flag;
void delay(uint x) //毫秒延时函数
{ uint k,l;
for(k=x;k>=1;k--)
for(l=110;l>=1;l--);
}
void write_com(uchar com)//写命令函数,每次只在一个相应的字符位写一个字符
{
RW=0; //置低为写
RS=0; //置低为写命令
delay(5);
P0=com;//给IO口写一个命令字符
EN=1; //一个高脉冲使之能成功写入
delay(5);
EN=0;
}
void write_date(uchar date) //每次写一个字符
{
RW=0; //置低为写
RS=1; //置低为写数据
delay(5);
P0=date;//给IO口写一个数据字符
EN=1; //一个高脉冲使之能成功写入
delay(5);
EN=0;
}
void init()
{
write_com(0x38);//设置1602显示器显示模式:16*2显示,5*7点阵,8位数据接口
write_com(0x0c);//开显示,不显示光标,光标不闪烁.(0x0e为显示光标但光标不闪烁,0x0f为显示光标且光标闪烁)
write_com(0x06);//每写入一个字符后,地址自动加一
TMOD=0x01; //T0用作定时器,且工作在方式1
TH0=0X00;
TL0=0X00;
TCON=0x05; //两个外部中断为负跳沿触发
EA=1;
EX0=1;
EX1=1;
TR0=0;
}
/************函数声明****************/
void write_chushishuju();
void write_voltagez(uchar add,uint count1,uint count2);
void write_voltagex(uchar add,uint count1,uint count2);
/************主程序***********/
void main()
{ uint A,B;
init();
write_chushishuju(); //显示初始数据
en=0; //先让积分电路放电
flag=0;
while(1)
{
if(flag==1)
{
flag=0;
A=TH0; //读出定时器计数数值
B=TL0;
TH0=0X00;
TL0=0X00;
write_voltagez(9,A,B);//显示读数数值整数部分
write_voltagex(11,A,B);//显示读数数值小数部分
}
}
}
/************中断子函数*************/
void INT_0() interrupt 0 //开始按键的外部中断函数
{
TR0=1;//按下开始键,开启定时器
en=1; //并让电容开始充电
}
void INT_1() interrupt 2 //积分到Ux后负跳沿触发中断
{
TR0=0; //关闭定时器
delay(2); //延时2ms
en=0; //让电容放电
flag=1; //计数数值显示标志
}
/*********初始显示函数*********/
void write_chushishuju() //给液晶显示器赋初值,使之初始时显示相应数据
{
uchar i,j;
write_com(0x80+0x00);//规定字符地址指针,使数据从第一行的第0个地址写起
for(i=0;i<sizeof(table1)-1;i++)//sizeof包含一个停止位
{
write_date(table1[i]);
delay(2);
}
write_com(0x80+0x40);//从第二行的第0个地址写起
for(j=0;j<sizeof(table2)-1;j++)
{
write_date(table2[j]);
delay(2);
}
}
/*********显示函数*********/
void write_voltagez(uchar add,uint count1,uint count2) //写电压整数函数
{
double N;
long int M;
uint g;
N=count1*(256)+count2;//定时器计数大小
N=N*0.00488;//转化为实际电压大小
M=N*100000; //方便下面依次取出各位的值
g=M/100000; //取出个位
write_com(0x80+0x40+add);//从相应的字符地址处开始写个位;
write_date(0x30+g); //注意此处要加0x30,因为要显示g的数值,据1602显示ASICC码要求可得
delay(2);
}
void write_voltagex(uchar add,uint count1,uint count2) //写电压小数函数
{
double N;
long int M;
uint sf,bf,qf,wf,swf;
N=count1*(256)+count2;
N=N*0.00488;
M=N*100000;
M=M%100000;
sf=M/10000;//取出十分位
M=M%10000;
bf=M/1000;//取出百分位
M=M%1000;
qf=M/100; //取出千分位
M=M%100;
wf=M/10; //取出万分位
M=M%10;
swf=M; //取出十万分位
write_com(0x80+0x40+add);//从相应的字符地址处开始各位;
write_date(0x30+sf); //注意此处要加0x30,因为要显示数字,据1602显示ASICC码要求可得
write_date(0x30+bf);
write_date(0x30+qf);
write_date(0x30+wf);
write_date(0x30+swf);
delay(2);
}