跪求51单片机控制DHT11温湿度传感器在1602LCD上显示的C程序

2019-07-15 18:08发布

课程设计了,,,但是由于没有学好单片机,不会写程序,,,求大神帮助
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
6条回答
chenyongan
2019-07-15 21:03
#include <reg52.h>
#include <intrins.h>
typedef unsigned char uchar;
typedef unsigned int unint;
unsigned char str1[]={""};
unsigned char str2[]={""};
unsigned char code dis1[] = {"TRH RH: "};
unsigned char code dis2[] = {"TRH  T: "};
sbit TRH = P2^7;//温湿度传感器DHT11数据接入
sbit LCD_RS = P3^5;            
sbit LCD_RW = P3^6;
sbit LCD_EN = P3^4;
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;
uchar respond;
/*********************************************************************************/
void delayNOP()
{
        _nop_();
        _nop_();
        _nop_();
        _nop_();
}
/*********************************************************************************/

/*********************************************************************************/
// 毫秒级延时子程序
/*********************************************************************************/
void delay_ms(unsigned char ms)
{      
        unsigned char i;
        while(ms--)
        {
                for(i = 0; i< 150; i++)
                {
                        _nop_();
                        _nop_();
                        _nop_();
                        _nop_();
                }
        }
}
/*********************************************************************************/

/*********************************************************************************/
//5us级延时程序
/*********************************************************************************/
void delay_us()
{
        uchar i;
        i--;
        i--;
        i--;
        i--;
        i--;
        i--;
}
/********************************************************************************/


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

/*******************************************************************************/
// 写入指令数据到LCD
/*******************************************************************************/
void lcd_wcmd(unsigned char cmd)
{      
        while(lcd_busy());
        LCD_RS = 0;
        LCD_RW = 0;
        LCD_EN = 0;
        _nop_();
        _nop_();
        P0 = cmd;
        delayNOP();
        LCD_EN = 1;
        delayNOP();
        LCD_EN = 0;
}
/*****************************************************************************/

/*****************************************************************************/
//写显示数据到LCD                                                
//RS=高电平,RW=低电平,E=高脉冲,D0-D7=数据。                             
/*****************************************************************************/
void lcd_wdata(unsigned char dat)
{                          
        while(lcd_busy());
        LCD_RS = 1;
        LCD_RW = 0;
        LCD_EN = 0;
        P0 = dat;
        delayNOP();
        LCD_EN = 1;
        delayNOP();
        LCD_EN = 0;
}
/****************************************************************************/

/****************************************************************************/
//LCD初始化设定
/****************************************************************************/
void lcd_init()
{
        delay_ms(15);                  
        lcd_wcmd(0x38);      //16*2显示,5*7点阵,8位数据
        delay_ms(5);
        lcd_wcmd(0x38);         
        delay_ms(5);
        lcd_wcmd(0x38);         
        delay_ms(5);
        lcd_wcmd(0x0c);      //显示开,关光标
        delay_ms(5);
        lcd_wcmd(0x06);      //移动光标
        delay_ms(5);
        //lcd_wcmd(0x01);      //清除LCD的显示内容,如果屏幕过暗,可将这俩句删除
        //delay_ms(5);
}
/****************************************************************************/

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

/****************************************************************************/
//收发信号检测,数据读取
/****************************************************************************/
char receive()
{   
uchar i;
com_data=0;
for(i=0;i<=7;i++)   
{
        respond=2;
        while((!TRH)&&respond++);
        delay_us();
        delay_us();
        delay_us();
        if(TRH)
        {
                temp=1;
                respond=2;
                while((TRH)&&respond++);
        }
        else
                temp=0;
        com_data<<=1;
        com_data|=temp;   
}
return(com_data);  
}
/****************************************************************************/

/****************************************************************************/
//湿度读取子程序
//温度高8位== TL_data
//温度低8位== TH_data
//湿度高8位== RH_data
//湿度低8位== RH_data
//校验 8位 == CK_data
//调用的程序有 delay();, Delay_5us();,RECEIVE();
/***************************************************************************/
void read_TRH()
{
//主机拉低18ms
TRH=0;
delay_ms(18);
TRH=1;
//DATA总线由上拉电阻拉高 主机延时20us
delay_us();
delay_us();
delay_us();
delay_us();
//delay_us();
//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] = (char)(0X30+RH_data/10);
str1[1] = (char)(0X30+RH_data%10);
str1[2] =  0x2e; //小数点
                                                                                //湿度小数部分
str1[3] = (char)(0X30+RL_data/10);
str1[5] = 0X25; //"%"
str1[6] = 0X52; //"R"
str1[7] = 0X48; //"H"
                                                                                //温度整数部分
str2[0] = (char)(0X30+TH_data/10);
str2[1] = (char)(0X30+TH_data%10);
str2[2] =  0x2e; //小数点
                                                                                //温度小数部分
str2[3] = (char)(0X30+TL_data/10);
str2[5] = 0X27;  //"'"
str2[6] = 0X43;  //"C"
}
/****************************************************************************/
//主函数
//TH,TL,RH,RL分别代表温湿度的整数和小数部分
/****************************************************************************/
void main()
{
        unsigned char i,n=0x40,m;
        lcd_init();
        delay_us();
        while(1)
        {
                read_TRH();            //写字符
                for(i=0;i<=7;i++)
                {
                        lcd_dis_pos(i);               //显示字符
                        lcd_wdata(dis1[i]);
                        lcd_dis_pos(n+i);            //显示字符
                        lcd_wdata(dis2[i]);
                }                                   //写湿度数据
                m=0x08;
                for(i=0;i<=7;i++)      
                {
                        lcd_dis_pos(m);
                        lcd_wdata(str1[i]);
                        m++;
                }
                                                                        //写温度数据
                m=0x48;
                for(i=0;i<=7;i++)      
                {
                        lcd_dis_pos(m);
                        lcd_wdata(str2[i]);
                        m++;
                }
               
                delay_ms(100) ;//延时
        }      
}

一周热门 更多>