打印
[51单片机]

湿度传感器DHT11,1602显示

[复制链接]
3818|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
20122778|  楼主 | 2014-11-25 22:36 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
求大神指导一下,这个是湿度传感器DHT11的程序,用1602显示


#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit lcden=P2^7;
sbit lcdrs=P2^6;
sbit lcdrw=P2^5;
sbit TRH=P1^0;
uchar TH_data,TL_data,RH_data,RL_data,CK_data;
uchar TH_temp,TL_temp,RH_temp,RL_temp,CK_temp;
uchar com_data,untemp,temp,respond;
uchar str1[]="";
uchar str2[]="";

//10us延时程序
void delay_nop()
{
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
}

//1ms延时程序
void delay(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=114;y>0;y--);
}

// 测试LCD忙碌状态
//lcd_busy()为1时,忙,等待。lcd_busy()为0时,闲,可写指令与数据。
bit lcd_busy()
{      
        bit result;
        lcdrs=0;
        lcdrw=1;
        lcden=1;
        delay_nop();
        result=(bit)(P0&0x80);
        lcden=0;
        return result;
}

//写指令
void write_cmd(uchar cmd)
{
        while(lcd_busy());
        lcdrs=0;
        lcdrw=0;
        lcden=0;
        delay_nop();
        P0=cmd;
        delay_nop();
        lcden=1;
        delay_nop();
        lcden=0;
}

//写数据
void write_data(uchar dat)
{
        while(lcd_busy());
        lcdrs=1;
        lcdrw=0;
        lcden=0;
        P0=dat;
        delay(5);
        lcden=1;
        delay(5);
        lcden=0;
}


//初始化
void init()
{
        delay(15);                  
        write_cmd(0x38);      //16*2显示,5*7点阵,8位数据
        delay(5);
        write_cmd(0x08);      
        delay(5);
        write_cmd(0x0c);      //显示开,关光标
        delay(5);
        write_cmd(0x06);      //写入数据后光标右移
        delay(5);
}

//设定LCD显示位置
void lcd_dis_pos(uchar pos)
{      
        write_cmd(pos|0x80);        //数据指针=80+地址变量
}

//接收数据
char receive()
{   
        uchar i;
        com_data=0;
        for(i=0;i<=7;i++)
        {
                respond=2;
                while((!TRH)&&respond++);
                delay_nop();
                delay_nop();
                delay_nop();
                //delay_nop();
                //delay_nop();
                //delay_nop();
                //delay_nop();
                //delay_nop();
                if(TRH)
                {
                        temp=1;
                        respond=2;
                        while((TRH)&&respond++);
                }
                else
                {
                        temp=0;
                        com_data=com_data<<1;
                        com_data|=temp;
                }
        }       
        return(com_data);
}

//湿度读取子程序
//温度高8位== TH_data
//温度低8位== TL_data
//湿度高8位== RH_data
//湿度低8位== RL_data
//校验 8位 == CK_data
//调用的程序有 delay();, Delay_5us();,RECEIVE();
/***************************************************************************/
void read_TRH()
{
        //主机拉低18ms
        TRH=0;
        delay(20);
        TRH=1;
        //DATA总线由上拉电阻拉高 主机延时20us
        delay_nop();
        delay_nop();
        //delay_us();
        //delay_us();
        //delay_us();
        //delay_us();
        //主机设为输入 判断从机响应信号
        TRH=1;
        //判断DHT11是否有低电平响应信号 如不响应则跳出,响应则向下运行   
        if(!TRH)   
        {
                respond=2;                         //判断DHT11发出 80us 的低电平响应信号是否结束
                while((!TRH)&&respond++);
                respond=2;                         //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
                while(TRH && respond++);           //数据接收状态   
                RH_temp=receive();
                RL_temp=receive();
                TH_temp=receive();
                TL_temp=receive();
                CK_temp=receive();
                TRH=1;                             //数据校验
                untemp=(RH_temp+RL_temp+TH_temp+TL_temp);
                if(untemp==CK_temp)
                {
                        RH_data=RH_temp;
                        RL_data=RL_temp;
                        TH_data=TH_temp;
                        TL_data=TL_temp;
                        CK_data=CK_temp;
                }
        }
                                                                               
        str1[0]=0x52;   //"R"
        str1[1]=0x48;   //"H"       
        str1[2]=0x3A;   //:
        str1[3]=(char)(0x30+RH_data/10);    //湿度整数部分
        str1[4]=(char)(0x30+RH_data%10);
        str1[5]=0x2e;   //小数点                                                                               
        str1[6]=(char)(0x30+RL_data/10);         //湿度小数部分
        str1[7]=0x25;   //"%"
                                                                               
        str2[0]=0x54;   //T
        str2[1]=0x3A;   //:
        //str2[2]=0x20; //空格
        str2[2]=(char)(0x30+TH_data/10);    //温度整数部分
        str2[3]=(char)(0x30+TH_data%10);
        str2[4]=0x2e;  //小数点
        str2[5]=(char)(0x30+TL_data/10);    //温度小数部分
        str2[6]=0x27;  //"'"
        str2[7]=0x43;  //"C"
}


void main()
{
        uchar i,m;
        init();
        delay_nop();
        while(1)
        {
                read_TRH();            

                m=0x00;                                //写湿度数据
                for(i=0;i<=7;i++)
                {
                        lcd_dis_pos(m);
                        write_data(str1[i]);
                        delay(10);
                        m++;
                }
                //delay(10);

                m=0x40;                                //写温度数据
                for(i=0;i<=7;i++)
                {
                        lcd_dis_pos(m);
                        write_data(str2[i]);
                        delay(10) ;
                        m++;
                }
                delay(100) ;//延时
        }
}




为什么显示出来的结果中第二个字符串是正常的,而第一个字符串从第二个字符开始显示的就是第二个字符串的内容。

相关帖子

沙发
20122778|  楼主 | 2014-11-25 22:40 | 只看该作者
就像这样

IMG_20141125_223748.jpg (348.62 KB )

IMG_20141125_223748.jpg

使用特权

评论回复
板凳
songchenping| | 2014-11-26 11:06 | 只看该作者
对软件比较头疼,我原先就是老老实实参照DATASHEET写就可以了。我用的是SHT11.

使用特权

评论回复
地板
wangch_sh| | 2014-11-26 11:47 | 只看该作者
行和列弄错了吧?

使用特权

评论回复
5
ningling_21| | 2014-11-26 12:04 | 只看该作者
20122778 发表于 2014-11-25 22:40
就像这样

只有行地址,没有列地址?

使用特权

评论回复
6
20122778|  楼主 | 2014-11-26 21:30 | 只看该作者
//设定LCD显示位置
void lcd_dis_pos(uchar pos)
{      
        write_cmd(pos|0x80);        //数据指针=80+地址变量
}

是用这个确定的列啊,怎么错了

使用特权

评论回复
7
wangch_sh| | 2014-11-26 21:48 | 只看该作者
显示函数呢?你把行和列对调一下试试。
我记得遇到过这种情况。
你要先把LCD程序搞好,位置显示对,再搞DHT11.

使用特权

评论回复
8
20122778|  楼主 | 2014-11-26 22:59 | 只看该作者
就是要解决显示的问题,没有专门的lcd程序,通过P0口给1602直接写的数据啊,两个字符串str1[]和str2[]

使用特权

评论回复
9
mazhao141| | 2014-11-30 18:51 | 只看该作者
程序我没有细看,但是你T和:都写到第二行了,那显然你数组值出错的概率比较大。我啊,建议你给第二行的数组写一个常量。如果显示出来了,那就确定是传感器传递的值就不对。

使用特权

评论回复
10
20122778|  楼主 | 2014-11-30 22:29 | 只看该作者
mazhao141 发表于 2014-11-30 18:51
程序我没有细看,但是你T和:都写到第二行了,那显然你数组值出错的概率比较大。我啊,建议你给第二行的数组 ...

这个我试过了,改第一个字符串的第一个字符的时候可以改,但其他的不行,第二个字符串改动后第一个会跟着变的。

使用特权

评论回复
11
mazhao141| | 2014-12-1 09:26 | 只看该作者
本帖最后由 mazhao141 于 2014-12-1 09:34 编辑

看到了,不好意思,看到了。要不你一行一行调试吧~先不写第二行看看第一行能不能显示正确。其实你设置了光标右移没必要每次都重写光标。我电脑上没装这个环境所以不能跑。初始化加个清屏命令,我用这个初始化的时候连续写俩数组进去是没有问题的。
       write_com(0x80);
        for(i=0;i<8;i++)
                {
                        write_date(str1【i】);
                        delay(5);
                }
        write_com(0x80+0x40);
        for(i=0;i<8;i++)
                {
                        write_date(str2【i】);
                        delay(5);
                }

这个论坛回复中括号貌似显示不出来,领会精神吧。。。

使用特权

评论回复
12
揍用力| | 2015-12-1 21:11 | 只看该作者
楼主,这个问题感觉没解决啊

使用特权

评论回复
13
揍用力| | 2015-12-2 10:18 | 只看该作者
字符串定义str1[],str2[]改成str1[8],str2[8]。我改过后可以正常显示了,但我不知道为什么这样改

使用特权

评论回复
14
越努力,越幸运| | 2016-7-25 13:54 | 只看该作者
揍用力 发表于 2015-12-2 10:18
字符串定义str1[],str2[]改成str1[8],str2[8]。我改过后可以正常显示了,但我不知道为什么这样改 ...

可是显示出来的温度和湿度读书都是00,0

使用特权

评论回复
15
yaosongjin| | 2016-7-26 09:17 | 只看该作者
本帖最后由 yaosongjin 于 2016-7-26 09:19 编辑

从楼主最后的回帖看应该是读数据函数里面处理有问题,1602显示部分是正常的了

使用特权

评论回复
16
YANG5815| | 2016-8-19 12:21 | 只看该作者
yaosongjin 发表于 2016-7-26 09:17
从楼主最后的回帖看应该是读数据函数里面处理有问题,1602显示部分是正常的了 ...

请问你能解决吗?我也在弄这个、有点小问题

使用特权

评论回复
17
yaosongjin| | 2016-8-31 08:07 | 只看该作者
YANG5815 发表于 2016-8-19 12:21
请问你能解决吗?我也在弄这个、有点小问题

这个传感器我手上没有,没法试验,你可以先在数组里面写几个初始化的数据,看是否能显示出来,以判断显示部分的正确性,如果不能正确显示说明显示有问题,否则就是接收数据部分,调试程序应该一步一步缩小问题点的范围,要不然很难调通的

使用特权

评论回复
18
heishe1989| | 2016-8-31 17:13 | 只看该作者
期待高人出现喽

使用特权

评论回复
19
416356084| | 2016-8-31 18:03 | 只看该作者
这个应该没什么的吧,给个邮箱,发给你们

使用特权

评论回复
20
Obligation| | 2018-3-23 22:39 | 只看该作者
416356084 发表于 2016-8-31 18:03
这个应该没什么的吧,给个邮箱,发给你们

228303760@qq.com

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

18

帖子

0

粉丝