本人目前在做一個設計,要求是利用土壤濕度傳感器檢測土壤中的濕度,并傳輸模擬信號到LCD1602進行百分比的顯示。我想實現的功能是:將傳感器檢測到的信號送到LCD1602進行顯示,LCD1602顯示的百分比能夠代表濕度的變化,即濕度上升,百分比上升,但是目前問題是:當土壤濕度變大時,LCD1602顯示的百分比下降,請問怎樣可以解決呢?使用PCF895 AD模塊進行數模轉換
設計代碼附上:
#include <reg52.h>
#include <intrins.h>
typedef unsigned char u8;
typedef unsigned int u16;
#define LCD1602_DATA_PORT P0
#define PCF8591 0x90
#define NOP() _nop_()
#define _Nop() _nop_()
sbit gLcd1602_E = P3^4;
sbit gLcd1602_RW = P3^6;
sbit gLcd1602_RS = P3^5;
sbit SCL = P2^0;
sbit SDA = P2^1;
sbit Dj = P3^1;
sbit Dj1 = P3^2;
sbit Dj2 = P3^3 ;
sbit gIO = P2^2;
bit ack;
u16 tDisp = 0;
void delay15us(void)
{
unsigned char a;
for(a=6;a>0;a--);
}
void delay45us(void)
{
unsigned char a;
for(a=21;a>0;a--);
}
void delay70us(void)
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=32;a>0;a--);
}
void delay750us(void)
{
unsigned char a,b;
for(b=83;b>0;b--)
for(a=3;a>0;a--);
}
void delay1ms(void)
{
unsigned char a,b,c;
for(c=1;c>0;c--)
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
void delay5ms(void)
{
unsigned char a,b;
for(b=19;b>0;b--)
for(a=130;a>0;a--);
}
void delay250ms(void)
{
unsigned char a,b,c;
for(c=11;c>0;c--)
for(b=92;b>0;b--)
for(a=122;a>0;a--);
}
void Start_I2c()
{
SDA=1;
_Nop();
SCL=1;
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SDA=0;
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SCL=0;
_Nop();
_Nop();
}
void Stop_I2c()
{
SDA=0;
_Nop();
SCL=1;
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SDA=1;
_Nop();
_Nop();
_Nop();
_Nop();
}
void SendByte(unsigned char c)
{
unsigned char BitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++)
{
if((c<<BitCnt)&0x80)SDA=1;
else SDA=0;
_Nop();
SCL=1;
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SCL=0;
}
_Nop();
_Nop();
SDA=1;
_Nop();
_Nop();
SCL=1;
_Nop();
_Nop();
_Nop();
if(SDA==1)ack=0;
else ack=1;
SCL=0;
_Nop();
_Nop();
}
unsigned char RcvByte()
{
unsigned char retc;
unsigned char BitCnt;
retc=0;
SDA=1;
for(BitCnt=0;BitCnt<8;BitCnt++)
{
_Nop();
SCL=0;
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SCL=1;
_Nop();
_Nop();
retc=retc<<1;
if(SDA==1)retc=retc+1;
_Nop();
_Nop();
}
SCL=0;
_Nop();
_Nop();
return(retc);
}
void Ack_I2c(bit a)
{
if(a==0)SDA=0;
else SDA=1;
_Nop();
_Nop();
_Nop();
SCL=1;
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SCL=0;
_Nop();
_Nop();
}
void Lcd1602WaitNoBusy(void)
{
u8 sta = 0;
LCD1602_DATA_PORT = 0xff;
gLcd1602_RS = 0;
gLcd1602_RW = 1;
do
{
gLcd1602_E = 1;
sta = LCD1602_DATA_PORT;
gLcd1602_E = 0;
}while(sta & 0x80);
}
void Lcd1602WriteCmd(u8 cmd)
{
Lcd1602WaitNoBusy();
gLcd1602_E = 0;
gLcd1602_RS = 0;
gLcd1602_RW = 0;
LCD1602_DATA_PORT = cmd;
gLcd1602_E = 1;
gLcd1602_E = 0;
}
void Lcd1602WriteData(u8 dat)
{
Lcd1602WaitNoBusy();
gLcd1602_E = 0;
gLcd1602_RS = 1;
gLcd1602_RW = 0;
LCD1602_DATA_PORT = dat;
gLcd1602_E = 1;
gLcd1602_E = 0;
}
void Lcd1602SetCursor(u8 x, u8 y)
{
u8 addr = 0;
switch (y)
{
case 0:
addr = 0x00 + x; break;
case 1:
addr = 0x40 + x; break;
default:
break;
}
Lcd1602WriteCmd(addr | 0x80);
}
void write_sfm2(u8 hang,u8 add,u16 date)
{
if(hang==1)
Lcd1602WriteCmd(0x80+add);
else
Lcd1602WriteCmd(0x80+0x40+add);
Lcd1602WriteData(0x30+date/10%10);
Lcd1602WriteData(0x30+date%10);
}
void Lcd1602ShowStr(u8 x, u8 y, u8 *pStr)
{
Lcd1602SetCursor(x, y);
while (*pStr != '\0')
{
Lcd1602WriteData(*pStr++);
}
}
void Lcd1602Init(void)
{
Lcd1602WriteCmd(0x38);
delay5ms();
Lcd1602WriteCmd(0x38);
delay5ms();
Lcd1602WriteCmd(0x38);
delay5ms();
Lcd1602WriteCmd(0x38);
Lcd1602WriteCmd(0x08);
Lcd1602WriteCmd(0x01);
Lcd1602WriteCmd(0x06);
Lcd1602WriteCmd(0x0c);
}
void write_sfm(u8 hang,u8 add,u16 date)
{
if(hang==1)
Lcd1602WriteCmd(0x80+add);
else
Lcd1602WriteCmd(0x80+0x40+add);
Lcd1602WriteData('s');
Lcd1602WriteData('h');
Lcd1602WriteData('i');
Lcd1602WriteData('d');
Lcd1602WriteData('u');
Lcd1602WriteData(':');
Lcd1602WriteData(0x30+date/100);
Lcd1602WriteData(0x30+date%100/10);
Lcd1602WriteData(0x30+date%10);
Lcd1602WriteData('%');
if(date<100)
{
Dj1=1;
}
else
{
Dj1=0;
}
}
void write_sfm3(u8 hang,u8 add,u16 date)
{
if(hang==1)
Lcd1602WriteCmd(0x80+add);
else
Lcd1602WriteCmd(0x80+0x40+add);
Lcd1602WriteData(' ');
Lcd1602WriteData('G');
Lcd1602WriteData(':');
Lcd1602WriteData(0x30+date/100);
Lcd1602WriteData(0x30+date%100/10);
Lcd1602WriteData(0x30+date%10);
Lcd1602WriteData('%');
if(date<100)
{
Dj2=0;
}
else
{
Dj2=1;
}
}
void write_wendu(u8 hang,u8 add,u16 date)
{
if(hang==1)
Lcd1602WriteCmd(0x80+add);
else
Lcd1602WriteCmd(0x80+0x40+add);
Lcd1602WriteData('W');
Lcd1602WriteData('e');
Lcd1602WriteData('n');
Lcd1602WriteData('d');
Lcd1602WriteData('u');
Lcd1602WriteData(':');
Lcd1602WriteData(0x30+date%1000/100);
Lcd1602WriteData(0x30+date%100/10);
Lcd1602WriteData('.');
Lcd1602WriteData(0x30+date%10);
Lcd1602WriteData(0xdf);
Lcd1602WriteData('C');
if(date>250)
{
Dj=1;
}
else
{
Dj=0;
}
}
bit ISendByte(unsigned char sla,unsigned char c)
{
Start_I2c();
SendByte(sla);
if(ack==0)return(0);
SendByte(c);
if(ack==0)return(0);
Stop_I2c();
return(1);
}
unsigned char IRcvByte(unsigned char sla)
{ unsigned char c;
Start_I2c();
SendByte(sla+1);
if(ack==0)return(0);
c=RcvByte();
Ack_I2c(1);
Stop_I2c();
return(c);
}
u8 Ds18b20Init(void)
{
u8 i = 0;
gIO = 0;
delay750us();
gIO = 1;
i = 0;
while (gIO)
{
i++;
if(i>5)
{
return 1;
}
delay15us();
}
return 0;
}
static void Ds18b20WriteByte(u8 dat)
{
u16 i = 0, j = 0;
for (j=0; j<8; j++)
{
gIO = 0;
i++;
gIO = dat & 0x01;
delay70us();
gIO = 1;
dat >>= 1;
}
}
u8 Ds18b20ReadByte(void)
{
u8 byte = 0, bi = 0;
u16 i = 0, j = 0;
for (j=8; j>0; j--)
{
gIO = 0;
i++;
gIO = 1;
i++;
i++;
bi = gIO;
byte = (byte >> 1) | (bi << 7);
delay45us();
}
return byte;
}
void Ds18b20TempConvertCmd(void)
{
Ds18b20Init();
delay1ms();
Ds18b20WriteByte(0xcc);
Ds18b20WriteByte(0x44);
delay250ms();
}
void Ds18b20TempReadCmd(void)
{
Ds18b20Init();
delay1ms();
Ds18b20WriteByte(0xcc);
Ds18b20WriteByte(0xbe);
}
u16 Adc_value = 0;
u16 Adc_value1 = 0;
void main(void)
{
u8 water_level = 0;
u8 water_level1 = 0;
u16 temp = 0;
u8 tmh = 0, tml = 0;
double wendu = 0;
Lcd1602Init();
Dj = 0;
while (1)
{
ISendByte(PCF8591,0x41);
IRcvByte(PCF8591);
ISendByte(PCF8591,0x42);
Adc_value=IRcvByte(PCF8591);
water_level = Adc_value/2;
if(water_level>120)water_level=120;
write_sfm(1,0,water_level);
ISendByte(PCF8591,0x40);
IRcvByte(PCF8591);
ISendByte(PCF8591,0x42);
Adc_value1=IRcvByte(PCF8591);
water_level1 = Adc_value1/2;
if(water_level1>120)water_level1=120;
write_sfm3(1,9,water_level1);
Ds18b20TempConvertCmd();
Ds18b20TempReadCmd();
tml = Ds18b20ReadByte();
tmh = Ds18b20ReadByte();
temp = tml | (tmh << 8);
wendu = temp * 0.0625;
tDisp = (u16)(wendu * 10);
write_wendu(2,0,tDisp);
}
}
|