weixin_51396523 2020-10-29 23:27
浏览 71

想问一下大佬们,为什么这段程序的液晶屏上无法显示湿度的检测值?

#include
#include"intrins.h"
#define uchar unsigned char
#define uint unsigned int
void UART_Send_Byte(unsigned char mydata);
sbit lcdrs=P0^7; //1602液晶的RS脚接在P0.7口上
sbit lcdrw=P0^6; //1602液晶的RW脚接在P0.6口上
sbit lcden=P0^5; //1602液晶的E脚接在P0.5口上
sbit SCL=P1^7; //PCF8591T的 SCL 引脚接于单片机的P1^7引脚上
sbit SDA=P1^6; //PCF8591T的 SDA 引脚接于单片机的P1^6引脚上

sbit beep=P1^0;
sbit ds=P0^1; //温度传感器信号线
sbit dat=P1^5; //湿度

uchar DHT11[5],RTflag=0;
uchar FLAG; //超时标志位

uint temp,num=0;
float f_temp;
uchar code table[]={'0','1','2','3','4','5','6','7','8','9',':','-','B',' ','M','F','S','R','Y','N','\'','C'};
uchar code table1[]={'1','5','7','0','1','7','5','1','1','9','0'};
uchar code table2[]="T:";
uchar code table3[]="H:";
uchar code table4[]="YW:";

unsigned char UART_data; //定义串口接收数据变量
uint count=0; /////////////定时器计数
uchar wendu1,wendu2,yanwu1,yanwu2,yanwu3; ///串口发送温度,光照值暂存
unsigned char ADbuf;//设置8位的寄存器用来暂存A/D转换结果
///////////////////////////////////延时函数//////////////////////////////////////
void delay(uint z)
{
uint i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}

void Delay_t(uint j)
{
uchar i;
for(;j>0;j--)
{
for(i=0;i<27;i++);
}

}

///////////////////////////////////10us延时函数///////////////////////////////////
void Delay_10us(void) //10us延时函数
{
uchar i;
i--;
i--;
i--;
i--;
i--;
i--;
}

////////////////////////////////写命令函数///////////////////////////////////
void write_com(uchar com)
{
lcdrs=0;
P2=com; //读命令
delay(1);
lcden=1; //启动脉冲
delay(1);
lcden=0;
}
///////////////////////////////写数据函数////////////////////////////////////
void write_data(uchar date)
{
lcdrs=1;
P2=date; //写命令
delay(1);
lcden=1; //启动脉冲
delay(1);
lcden=0;
}
///////////////////////////////LCD初始化////////////////////////////////////
void init_1602()
{
lcden=0;
write_com(0x38); //设置16*2显示;5*7点阵;8位数据接口
write_com(0x0c); //设置开显示,不显示光标
write_com(0x06); //写一个字符后地址指针自动加1
write_com(0x01); //设置清0,数据指针清零
}

///////////////////////////////////1602数据显示数字函数///////////////////////////////////
void write_shu(uchar x,uchar y,uchar num)
{
uchar s,g;

if(y==0)

write_com(0x80+x);

else

write_com(0xc0+x);

s=num/10;// 数据分离显示

write_data(0x30+s);
g=num%10;//数据分离显示

write_data(0x30+g);
}

///////////////////////////////初始显示////////////////////////////////////
void name()
{
uchar a,b,c;
write_com(0x80+0x00);

for(a=0;a {
write_data(table2[a]);
delay(1);
}
write_com(0x80+0x08);
for(b=0;b {
write_data(table3[b]);
delay(1);
}
write_com(0x80+0x40);
for(c=0;c {
write_data(table4[c]);
delay(1);
}
}
/////////////////////////////////18B20复位,初始化函数////////////////////////////////////
void dsreset(void)
{
uint i;
ds=0;
i=103;
while(i>0)i--;
ds=1;
i=4;
while(i>0)i--;
}
/////////////////////////////////18B20读1位函数////////////////////////////////////
bit tempreadbit(void)

{
uint i;
bit dat;
ds=0;i++; //i++ 起延时作用
ds=1;i++;i++;
dat=ds;
i=8;while(i>0)i--;
return (dat);
}
/////////////////////////////////18B20读1个字节////////////////////////////////////
uchar tempread(void)

{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tempreadbit();
dat=(j<>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里
}
return(dat);
}
/////////////////////////////////向18B20写一个字节数据////////////////////////////////////
void tempwritebyte(uchar dat)

{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //写 1
{
ds=0;
i++;i++;
ds=1;
i=8;while(i>0)i--;
}
else
{
ds=0; //写 0
i=8;while(i>0)i--;
ds=1;
i++;i++;
}

}
}
//////////////////////////////DS18B20 开始获取温度并转换////////////////////////////////////
void tempchange(void)
{
dsreset();
delay(1);
tempwritebyte(0xcc); // 写跳过读ROM指令
tempwritebyte(0x44); // 写温度转换指令
}
////////////////////////////////读取寄存器中存储的温度数据////////////////////////////////////
uint get_temp()

{
uchar f,g;

dsreset();
delay(1);
tempwritebyte(0xcc);
tempwritebyte(0xbe);
f=tempread(); //读低8位
g=tempread(); //读高8位
temp=g;
temp<<=8; //两个字节组合为1个字
temp=temp|f;
f_temp=temp*0.0625; //温度在寄存器中为12位 分辨率位0.0625°
temp=f_temp*10+0.5; //乘以10表示小数点后面只取1位,加0.5是四舍五入
f_temp=f_temp+0.05;
return temp; //temp是整型
}
////////////////////////////////1602显示温度数据h和温度报警程序////////////////////////////////////
void dis_temp(uint t)
{
uchar i;
i=t/100;
write_com(0x80+0x02); //显示温度十位
write_data(table[i]);

wendu1=table[i];
i=t%100/10;

write_com(0x80+0x03);      //显示温度个位
write_data(table[i]);

write_com(0x80+0x04);      //显示'C
write_data(table[20]);
write_com(0x80+0x05);      //显示'C
write_data(table[21]);
wendu2=table[i];

}
////////////////////////////////1602显示烟雾和烟雾报警////////////////////////////////////
void dis_yanwu(uint t)
{
uchar i;
t=t*100/255;
i=t/100;
write_com(0x80+0x43); //显示烟雾百位
write_data(table[i]);

yanwu1=table[i];
i=t%100/10;

write_com(0x80+0x44);      //显示烟雾十位
write_data(table[i]);
yanwu2=table[i];
i=t%100%10;
write_com(0x80+0x45);      //显示烟雾个位
write_data(table[i]);

yanwu3=table[i];
if(t>52)
    beep=0;
else
    beep=1;

}

void IICstart(void)
{
SDA=1; //先将SDA=1,以准备在SCL=1时,将SDA=0
SCL=1; //时钟总线拉高
nop(); //略做延时
nop(); //略做延时
SDA=0; //SCL=1时,将SDA拉低即产生启动信号
nop(); //略做延时
nop(); //略做延时
SCL=0; //将SCL=0,完成启动信号操作

}

void IICstop(void)
{
SDA=0; //先将SDA=0,以准备在SCL=1时,将SDA=1
SCL=1; //时钟总线拉高
nop(); //略做延时
nop(); //略做延时
SDA=1; //SCL=1时,将SDA拉高即产生停止信号
nop(); //略做延时
nop(); //略做延时
SCL=0; //将SCL=0,完成启动信号操作

}

void Write1Byte(unsigned char Buf1)
{
unsigned char k; //1个字节要分8次写入,需要定义一个寄存器用来计数
for(k=0;k<8;k++) //做一个8次的循环,每次写入1位,需要写8次
{
if(Buf1&0x80) //从最高位开始写
{
SDA=1; //如果欲写入数据为1,就将数据线置1
}
else
{
SDA=0; //如果欲写入数据为0,就将数据线写0
}
nop(); //略做延时
nop(); //略做延时
SCL=1; //时钟线做一个上升沿,将一位数据写入
Buf1=Buf1<<1; //数据左移一位,将下次要写入的位数据移到最高位
nop(); //略做延时
SCL=0; //将SCL=0,以准备通过上升沿将数据写入
nop(); //略做延时
}
SDA=1; //将SDA=1,准备读应答信号
nop(); //略做延时
SCL=1; //将SCL=1,做个上升沿准备读应答信号
nop(); //略做延时
nop(); //略做延时
SCL=0; //将SCL=0,结束应答信号读操作
}

unsigned char Read1Byte(void)
{
unsigned char k; //1个字节要分8次读出,需要定义一个寄存器用来计数
unsigned char t=0; //定义一个寄存器用保存读出数据
for(k=0;k<8;k++) //做一个8次的循环,每次读入1位,需要读8次
{
t=t<<1; //数据左移一位,空出最低位以准备保存读入的一位数据
SDA=1; //将SDA写1准备读
SCL=1; //将SCL=1,做个上升沿准备读一位数据
nop(); //略做延时
nop(); //略做延时
if(SDA==1) //读一位数据,并判断
{
t=t|0x01; //如果读入数据为1,就将接收缓冲区最低一位置1
}
else
{
t=t&0xfe; //如果读入数据为0,就将接收缓冲区最低一位写0
}
SCL=0; //SCL恢复为0,结束一位数据读操作
nop(); //略做延时
nop(); //略做延时
}
return t; //将读入的一个字节返回
}

void WritePCF8591(unsigned char Databuf)
{ //直接调用本函数即可启动PCF8591的D/A转换
IICstart(); //IIC启动信号

Write1Byte(0x90);      //发送PCF8591的器件地址和写信号

Write1Byte(0x40);      //发送器件子地址

Write1Byte(Databuf);   //发送数据

IICstop();             //产生IIC停止信号

}

unsigned ReadPCF8591(unsigned char Ch)
{ //直接调用本函数即可从PCF8591的Ch通道读出数据返回
unsigned char buf; //定义一个寄存器用来暂存读出的数据
IICstart(); //IIC启动信号

Write1Byte(0x90);      //发送PCF8591的器件地址和写信号

Write1Byte(0x40|Ch);   //发送器件通道参数Ch=0-3

IICstart();            //IIC启动信号

Write1Byte(0x91);      //发送PCF8591的器件地址和读信号

buf=Read1Byte();//读一个字节数据

IICstop();             //产生IIC停止信号

return(buf);           //将读出数据返回

}

/************************************DHT11读一个字节********************************/
uchar write_byte1() //读一个字节
{
uchar i,comdata,temp1;

for(i=0;i<8;i++)

{

FLAG=2;

while((!dat)&&FLAG++);//判断数据位是0还是1

Delay_10us();

Delay_10us();

Delay_10us();

temp1=0;

if(dat)temp1=1; // 如果高电平高过预定0高电平值则数据位为 1

FLAG=2;

while((dat)&&FLAG++);//flag先与后加1 如果dat一直为1 uchar型变量 flag 溢出变为0 再自加1

if(FLAG==1)break; //超时则跳出for循环

comdata<<=1;//左移一位 高位在前 低位在后

comdata|=temp1;
}

return (comdata);
}

///////////////////////////////////DHT11读5个字节数据///////////////////////////////////
void DHT11_5() //两个字节为温度数据 两个字节为湿度数据 最后一个字节为校验
{
uchar i,temp;

//主机拉低18ms

dat=0;

Delay_t(180);

dat=1;

//总线由上拉电阻拉高 主机延时20us

Delay_10us();

Delay_10us();

Delay_10us();

Delay_10us();

//主机设为输入 判断从机响应信号

dat=1;

//判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行

if(!dat) //T !

{

FLAG=2; //超时标志位

while((!dat)&&FLAG++);//判断从机是否发出 80us 的低电平响应信号是否结束
FLAG=2;
while(

(dat)&&FLAG++); //判断从机拉高80us是否结束

for(i=0;i<5;i++)//数据接收状态

{

DHT11[i]=write_byte1();
}

dat=1; //释放数据总线 为下一次读取做好准备
temp=(DHT11[0]+DHT11[1]+DHT11[2]+DHT11[3]);
if(temp==DHT11[4]) //数据校验

{

RTflag=1;

}

}
}

///////////////////////////////////湿度显示函数///////////////////////////////////
void display_RH()
{
DHT11_5(); //读数据
if(RTflag==1) //如果RTflag=1 说明读取到得数据正确

{

RTflag=0;

write_shu(10,0,DHT11[0]);

}
}

//////////////////////////////串口初始化////////////////////////////////
void UARTinit()
{
TMOD=0X21;
SCON=0X40;
TH1=0XFD;
TL1=0XFD;
TH0=(65536-45872)/256;
TL0=(65536-45872)%256;
TR1=1;
TR0=1;
EA=1;
ES=1;
ET0=1;
}

///////////////////////////////主函数////////////////////////////////////
void main()
{

uint wendu;
beep=1;
UARTinit();
lcdrw=0; //确定读操作
init_1602(); //初始化LCD1602
delay(5);
name();
delay(500);
while(1)
{
write_byte1();//读一个字节
display_RH();
tempchange();
wendu=get_temp();
dis_temp(wendu);
ADbuf=ReadPCF8591(0); //将AIN0通道A/D转换结果暂存在ADbuf
dis_yanwu(ADbuf);
}
}

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 求差集那个函数有问题,有无佬可以解决
    • ¥15 【提问】基于Invest的水源涵养
    • ¥20 微信网友居然可以通过vx号找到我绑的手机号
    • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
    • ¥15 解riccati方程组
    • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
    • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
    • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
    • ¥50 树莓派安卓APK系统签名
    • ¥65 汇编语言除法溢出问题