|
最近大一在做一個電子設計,本人打算做一個智能加濕器,基于52單片機,DHT11與LCD1602顯示溫度、濕度,但是在安裝完最小系統后(雖然有些亂,但親測能燒錄程序,之前用來做光立方的最小系統被拆下來了。。),然后按照I/O口全部接好了之后上電LCD只能顯示一列方格,電位器已經VO與1.5K電阻串聯連接到GND代替了,上網查了一下,有人說是LCD初始化沒有正確,然后叫我檢查一下電路。。。我已經在程序加了點延時了,而且全部把I\0口連接都確認了一遍。以下是代碼,求大神指教#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit Data=P2^7;//定義數據線
sbit Open = P1^0;//定義一個噴霧開關
uchar rec_dat[21];//用于顯示的接收數據數組
sbit lcdrs = P3^5;//寄存器選擇輸入
sbit lcdrw = P3^6;//液晶讀/寫控制
sbit lcden = P3^4;//液晶使能控制
/*全局變量*/
uchar RH=0,TH=0;//濕度,溫度
uchar stand_RH=80,stand_TH=28;//設置濕度,溫度閥值
//sbit wela = P2^7;
//sbit dula = P2^6;
void DHT11_delay_us(uchar n)
{
while(--n);
}
void DHT11_delay_ms(uint z)
{
uint i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
void DHT11_start()
{
Data=1;
DHT11_delay_us(2);
Data=0;
DHT11_delay_ms(20);//延時18ms以上
Data=1;
DHT11_delay_us(30);
}
uchar DHT11_rec_byte()//接收一個字節
{
uchar i,dat=0;
for(i=0;i<8;i++)//從高到低依次接收8位數據
{
while(!Data);//等待50us低電平過去
DHT11_delay_us(8);//延時60us,如果還為高則數據為1,否則為0
dat<<=1;//移位使正確接收8位數據,數據為0時直接移位
if(Data==1)//數據為1時,使dat加1來接收數據1
dat+=1;
while(Data);//等待數據線拉低
}
return dat;
}
void DHT11_receive()//接收40位的數據
{
uchar R_H,R_L,T_H,T_L,RL,TL,revise;
DHT11_start();
if(Data==0)
{
while(Data==0); //等待拉高
DHT11_delay_us(40); //拉高后延時80us
R_H=DHT11_rec_byte(); //接收濕度高八位
R_L=DHT11_rec_byte(); //接收濕度低八位
T_H=DHT11_rec_byte(); //接收溫度高八位
T_L=DHT11_rec_byte(); //接收溫度低八位
revise=DHT11_rec_byte(); //接收校正位
DHT11_delay_us(25); //結束
if((R_H+R_L+T_H+T_L)==revise) //校正
{
RH=R_H-2;
RL=R_L;
TH=T_H-3;
TL=T_L;
}
/*數據處理,方便顯示*/
rec_dat[0]='H';
rec_dat[1]='u';
rec_dat[2]='m';
rec_dat[3]=':';
rec_dat[4]='0'+(RH/10);
rec_dat[5]='0'+(RH%10);
rec_dat[6]='%';
rec_dat[7]='R';
rec_dat[8]='H';
rec_dat[9]='T';
rec_dat[10]='e';
rec_dat[11]='m';
rec_dat[12]=':';
rec_dat[13]='0'+(TH/10);
rec_dat[14]='0'+(TH%10);
rec_dat[15]=0xdf;//輸出℃
rec_dat[16]=0x43;
rec_dat[17]='0'+(stand_RH/10);
rec_dat[18]='0'+(stand_RH%10);
rec_dat[19]='0'+(stand_TH/10);
rec_dat[20]='0'+(stand_TH%10);
}
}
void Read_Busy()
{
uchar busy;
P0 = 0xff; //輸入D0~D7狀態字,先全部拉高
lcdrs = 0;
lcdrw = 1;
do
{
lcden = 1;
busy = P0;
lcden = 0;
}while(busy & 0x80);//判斷STA7是否為1忙,若1則繼續循環直到為0;
}
void write_com(uchar com)
{
Read_Busy();
lcdrw= 0;
lcdrs= 0;
P0 = com;
DHT11_delay_ms(5);
lcden= 1;
DHT11_delay_ms(5);
lcden =0;
}
void write_date(uchar date)
{
Read_Busy();
lcdrw =0;
lcdrs=1;
P0 =date;
DHT11_delay_ms(5);
lcden =1;
DHT11_delay_ms(5);
lcden =0;
}
void init()
{
//dula =0;
//wela =0;
lcden=0;
lcdrw=0;
write_com(0x38);//設置16*2顯示
DHT11_delay_ms(5);
write_com(0x0c);//開顯示,不顯示光標,
DHT11_delay_ms(5);
write_com(0x01);//清屏
DHT11_delay_ms(5);
write_com(0x06);//地址指針位移命令
DHT11_delay_ms(5);
//如果指針不賦值,指針默認80h
write_com(0x80);//寫指針地址
DHT11_delay_ms(5);
}
void main()
{
uchar i;
init();//lcd1602初始化
while(1)
{
DHT11_delay_ms(1500);//DHT11上電后要等待1S以越過不穩定狀態在此期間不能發送任何指令
DHT11_receive();
write_com(0x80);//從lcd1602第一行第一個位置開始顯示
for(i=0;i<9;i++)
write_date(rec_dat[i]);//顯示第一行數據
write_com(0x80 | 0x40);
for(i=9;i<17;i++)
write_date(rec_dat[i]);//顯示第二行數據
write_com(0x80 | 0x0A);
write_date(0x7c); //'|'
write_com(0x80 | 0x0C);
write_date(rec_dat[17]);
write_date(rec_dat[18]);
write_com(0x80 | 0x4A);
write_date(0x7c); //'|'
write_com(0x80 | 0x4C);
write_date(rec_dat[19]);
write_date(rec_dat[20]);
if((RH<=stand_RH)||(TH>=stand_TH))//當濕度低于閥值時候打開噴霧
{
Open=0;
}
}
}
|
|