|
300黑币
#include<reg51.h>
#include <intrins.h>
//#define dates P0 //P0 LCD1602专用IO口
#define uint unsigned int
#define uchar unsigned char
sbit lcdcos=P2^6;
sbit lcdrw=P2^5;
sbit lcden=P2^7;
sbit adcs=P3^3; //芯片选通信号,低有效
sbit adclk=P3^2; //芯片时钟信号
sbit addo=P3^7; //通道0
sbit addi=P3^6; //通道1
sbit A=P3^4; //模拟通道选择IO口AB
sbit C=P3^5; //模拟通道选择IO口AB
sbit LNH=P3^1; //AB选择使能口
uchar date;
int a,b,c;
uchar i,j,z,dat1,dat2; // dat1,dat2分别为adc转化后的8位数,即LCD先转化后显示的数
void delay(uint z) //延时程序z ms
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void delay1() //延时两个空指令
{
_nop_();
_nop_();
}
int ADconvertin() //AD转换输入电压
{
uchar i=0;
uchar j;
uint dat1=0;
uchar ndat1=0;
addi=1;
delay1();
adcs=0; //芯片选通
delay1();
adclk=1; //
delay1();
adclk=0; //下降沿1
delay1();
adclk=1; //
addi=0;
delay1();
adclk=0; //下降沿2
delay1();
adclk=1; //
addi=1; //选择通道
delay1();
adclk=0; //下降沿3
addi=1;
delay1();
dat1=0;
for(i=0;i<8;i++) //串行接收数据 高位在前
{
dat1|=addo; //将addo数据给dat
adclk=1; //拉高
delay1();
adclk=0; //拉低,循环时钟
delay1();
dat1<<=1; //将数据向左移动1位,方便低位接收下一位数据
if(i==7)
dat1|=addo; //最后一位数据直接赋给dat
}
for(i=0;i<8;i++) //串行接收数据 低位在前
{
j=0; //每次接收前复位为0
j|=addo; //j用来接收1位数据
adclk=1; //拉高
delay1();
adclk=0; //拉低,循环时钟
delay1();
j<<=7; //将接收到的数据移动到最高位
ndat1=ndat1|j; //将接收到的数据传给ndat
if(i<7)
ndat1>>=1; //每接收到1为数据,ndat向右移动1位
}
adcs=1;
adclk=0;
addo=1; //回到初始状态
dat1<<=8; //int型数据为16位,将接收到的8位数据移到高8位,
dat1|=ndat1;
return(dat1);
}
int ADconvertout() //AD转换输出电压
{
uchar i=0;
uchar j;
uint dat2=0;
uchar ndat2=0;
addi=1;
delay1();
adcs=0; //芯片选通
delay1();
adclk=1; //
delay1();
adclk=0; //下降沿1
delay1();
adclk=1; //
addi=0;
delay1();
adclk=0; //下降沿2
delay1();
adclk=1; //
addi=1; //选择通道
delay1();
adclk=0; //下降沿3
addi=1;
delay1();
dat2=0;
for(i=0;i<8;i++) //串行接收数据 高位在前
{
dat2|=addo; //将addo数据给dat
adclk=1; //拉高
delay1();
adclk=0; //拉低,循环时钟
delay1();
dat2<<=1; //将数据向左移动1位,方便低位接收下一位数据
if(i==7)
dat2|=addo; //最后一位数据直接赋给dat
}
for(i=0;i<8;i++) //串行接收数据 低位在前
{
j=0; //每次接收前复位为0
j|=addo; //j用来接收1位数据
adclk=1; //拉高
delay1();
adclk=0; //拉低,循环时钟
delay1();
j<<=7; //将接收到的数据移动到最高位
ndat2=ndat2|j; //将接收到的数据传给ndat
if(i<7)
ndat2>>=1; //每接收到1为数据,ndat向右移动1位
}
adcs=1;
adclk=0;
addo=1; //回到初始状态
dat2<<=8; //int型数据为16位,将接收到的8位数据移到高8位,
dat2|=ndat2;
return(dat2);
}
void chosecom0(uint com) //读数据操作
{
lcdcos=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void choseshu1(uint shu) //读数据操作
{
lcdcos=1;
P0=shu;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init() //初始化lcd,规定运行方式,
{
lcden=0;
chosecom0(0x38);
chosecom0(0x0c);
chosecom0(0x06);
chosecom0(0x01);
}
/*--这个函数的作用是:将读到的8591中的数据换算为电压值的个位值,
----并转换为对应的ASCII码,用以在液晶中显示*/
unsigned char data1_convert(unsigned char dat_temp)
{
unsigned char data1;
data1=(unsigned char)(((float)dat_temp/255)*5); //换算为电压值的个位值
data1=data1+48; //转换为对应的ASCII码 ,因为0对应ASCII码的48,以此类推
return data1;
}
/*--这个函数的作用是:将读到的8591中的数据换算为电压值的小数点后第一位的值,
----并转换为对应的ASCII码,用以以在液晶中显示*/
unsigned char data0_convert(unsigned char dat_temp)
{
unsigned char data0,data1;
data1=(unsigned char)(((float)dat_temp/255)*5); //换算为电压值的个位值
data0=(unsigned char)((((float)dat_temp/255)*5-data1)*10);//换算为为电压值的小--
//--数点后第一位的那个值
data0=data0+48;
return data0; //转换为对应的ASCII码
}
/*--这个函数的作用是:将读到的8591中的数据换算为电压值的小数点后第二位的值,
----并转换为对应的ASCII码,用以以在液晶中显示*/
unsigned char data2_convert(unsigned char dat_temp)
{
unsigned char data0,data1,data2;
data1=(unsigned char)(((float)dat_temp/255)*5); //换算为电压值的个位值
data0=(unsigned char)((((float)dat_temp/255)*5-data1)*10);//换算为为电压值的小--
data2=(unsigned char)((((float)dat_temp/255)*5-data1-data0*(0.1))*100); //--数点后第一位的那个值
data2=data2+48;
return data2;
}
void chuxian() //定义LCD初显程序
{
lcdrw=0;
init();
chosecom0(0x80);
choseshu1('V');
choseshu1('i');
choseshu1(':');
chosecom0(0x84);
choseshu1('.');
chosecom0(0x87);
choseshu1('v');
chosecom0(0x89);
choseshu1('A');
chosecom0(0x80+0x0a);
choseshu1('u');
chosecom0(0x80+0x0b);
choseshu1(':');
chosecom0(0x80+0x0d);
choseshu1('.');
chosecom0(0x80+0x40);
choseshu1('V');
choseshu1('o');
choseshu1(':');
chosecom0(0x80+0x44);
choseshu1('.');
chosecom0(0x80+0x47);
choseshu1('v');
}
void moxian() //定义LCD末显程序
{ chosecom0(0x83); //将要显示的字符显示在此地址处
choseshu1(data1_convert(dat1)); //显示电压的整数部分
chosecom0(0x85); //将要显示的字符显示在此地址处
choseshu1(data0_convert(dat1));
chosecom0(0x86); //将要显示的字符显示在此地址处
choseshu1(data2_convert(dat1));
chosecom0(0x80+0x43); //将要显示的字符显示在此地址处
choseshu1(data1_convert(dat2)); //显示电压的整数部分
chosecom0(0x80+0x45); //将要显示的字符显示在此地址处
choseshu1(data0_convert(dat2));
chosecom0(0x80+0x46); //将要显示的字符显示在此地址处
choseshu1(data2_convert(dat2));
}
void main()
{ float lin; //储存adc转化输入电压的实际量
while(1) //循环实时显示
{
chuxian(); //运行lcd初显函数
dat1=ADconvertin(); //运行adc程序得到输入电压数字量
lin=dat1*(5.0)/256; //将数字量转化为实际量
LNH=1; //初始4052模拟开关
if((0.16<=lin)&&(lin<0.24)) //通过实际量与参考量的比较选择运放的通道,达到不同的增益
{LNH=0; //启动4052模拟开关
A=0; //x0--x接通
C=0;
chosecom0(0x80+0x0c); //显示增益值5
choseshu1('5');
}
if((0.24<=lin)&&(lin<0.6))
{LNH=0; //x1--x接通
A=1;
C=0;
chosecom0(0x80+0x0c); //显示增益值2处
choseshu1('2');
}
if((0.6<=lin)&&(lin<2.4))
{LNH=0; //x2--x接通
A=0;
C=1;
chosecom0(0x80+0x0c); ///显示增益值0.5
choseshu1('0');
choseshu1('.');
choseshu1('5');
}
if((2.4<=lin)&&(lin<=5))
{LNH=0; //x3--x接通
A=1;
C=1;
chosecom0(0x80+0x0c); //显示增益值0.2
choseshu1('0');
choseshu1('.');
choseshu1('2');
}
if((5<lin)||(lin<0.16))
{
chosecom0(0x80+0x0c); //显示超出范围
choseshu1('w');
choseshu1('a');
choseshu1('r');
choseshu1('n');
}
dat2=ADconvertout(); //运行adc程序得到输出电压数字量
moxian(); // 运行lcd初显函数
}
}
|
评分
-
查看全部评分
|