|
最近大一在做一个电子设计,本人打算做一个智能加湿器,基于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;
}
}
}
|
|