|
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初顯函數
}
}
|
評分
-
查看全部評分
|