原创 C51 温湿度传感器DHT11驱动 LCD1602显示程序 硬件通过 含电路图和实际测试效果图
- 格式:doc
- 大小:840.50 KB
- 文档页数:9
DHT11.c文件#include<reg52.h>#include<Time_Delay.h>//the main only needs to call getDHT11(),then the temperature and huminity was geted in F16T,F16RH as floatsbit bit11=P2^0;unsigned char U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;float F16T,F16RH; //用于最终读取的温湿度数据// read 8 bits onicechar COM(void){char i,U8temp,U8comdata;for(i=0;i<8;i++){while(!bit11); //表示读取的高电位延时大于20多us 则读取的是1 否则读取的是0Delay_us(35); //通过U8FLAG 可判断bit11 显示数据的脉长U8temp=0;if(bit11)U8temp=1;while(bit11);U8comdata<<=1;U8comdata|=U8temp; //0}//rofreturn U8comdata;}//--------------------------------//-----温湿度读取子程序------------//--------------------------------//----以下变量均为全局变量--------//----温度高8位== U8T_data_H------//----温度低8位== U8T_data_L------//----湿度高8位== U8RH_data_H-----//----湿度低8位== U8RH_data_L-----//----校验8位== U8checkdata-----//----调用相关子程序如下----------//---- Delay();, Delay_10us();,COM();//--------------------------------void getDHT11(void){//主机拉低18msGO1: bit11=0;Delay_ms(20);bit11=1;//总线由上拉电阻拉高主机延时20usDelay_us(60);//主机设为输入判断从机响应信号// bit11=1;//判断从机是否有低电平响应信号如不响应则跳出,响应则向下运行if(!bit11) //T !{while(!bit11); //wait DHT goto highwhile(bit11);//数据接收状态U8RH_data_H=COM();U8RH_data_L=COM();U8T_data_H=COM();U8T_data_L=COM();U8checkdata=COM();bit11=1;//数据校验if((U8T_data_H+U8T_data_L+U8RH_data_H+U8RH_data_L)!=U8checkdata) //if check wrong,read againgoto GO1;}//fiF16T=U8T_data_H+(float)U8T_data_L/256; //change integer to floatF16RH=U8RH_data_H+(float)U8RH_data_L/256;}LCD1602文件#include<reg52.h>#include <stdio.h>#include <INTRINS.H>#include <Lcd_1602.h>#include <Time_Delay.h>#define LCD_DATA P0 //LCD1602 data transfer define#define uint unsigned int#define uchar unsigned char/*只由主函数调用的有Init_Lcd()LCD_write_str(uchar X,uchar Y,uchar *s)LCD_value(unsigned char x,unsigned char y,float f)*/sbit LCD_RS = P2^5; //1602 control definesbit RW = P2^6;sbit LCD_E = P2^7;/*************************************************************************** #define LCD_SCREEN_ON 0x0C //显示开#define LCD_SCREEN_OFF 0x08 //显示关#define LCD_CURSOR_ON 0x0A //显示光标#define LCD_CURSOR_OFF 0x0c //无光标#define LCD_C_FLASH_ON 0x0f //有光标,光标闪动#define LCD_C_FLASH_OFF 0x0e //有光标,光标不闪动//进入模式设置指令#define LCD_AC_UP 0x06 //新数据后光标右移#define LCD_AC_DOWN 0x04 //新数据后光标左移#define LCD_S_MOVE_ON 0x05 // 画面可平移#define LCD_S_MOVE_OFF 0x04 //画面不可平移//设定显示屏或光标移动方向指令#define LCD_C_LEFT 0x10 //光标左移1格,且AC值减1#define LCD_C_RIGHT 0x11 //光标右移1格,且AC值加1#define LCD_CHAR_LEFT 0x18 //显示器上字符全部左移一格,但光标不动#define LCD_CHAR_RIGHT 0x1C //显示器上字符全部右移一格,但光标不动***************************************************************************/ //注有主函数调用的函数都已作说明其他函数一般不由主函数调用/**************************************************************************** * 名称:Init_Lcd() 主函数调用* 功能:Lcd初始化* 入口参数:无* 出口参数:无* 范例: 在主函数中直接调用****************************************************************************/void Init_Lcd() //LCD初始化{LCD_write_char(0x38,0);Delay_ms(1);LCD_write_char(0x38,0);Delay_ms(1);LCD_write_char(0x38,0);Delay_ms(1);LCD_write_char(0x0c,0);Delay_ms(1);LCD_write_char(0x06,0);Delay_ms(1);LCD_write_char(0x0c,0);Delay_ms(1);//}/**************************************************************************** * 名称:LCD_write_str(uchar X,uchar Y,uchar *s)主函数调用* 功能:在指定地址写一个字符串eg:Y=0,1,2,3,4,5,6,7,8,9,10...15。
X=0,1。
* 入口参数:X:横坐标Y:纵坐标*s:字符串首地址* 出口参数:无* 范例: LCD_write_str(1,1,uchar *s)****************************************************************************/ void LCD_write_str(unsigned char X,unsigned char Y,unsigned char *s){LCD_write_char(0,' ');LCD_set_xy( X, Y ); //写地址while (*s) // 写显示字符{LCD_write_char( 0, *s );s ++;}}/**************************************************************************** * 名称:LCD_set_xy( uchar x, uchar y ) the optic sign flash?* 功能:指定一个地址* 入口参数:X:横坐标Y:纵坐标* 出口参数:无* 范例: LCD_set_xy(5,1)*************CD_set_xy********************************************************* ******/void LCD_set_xy( uchar x, uchar y ) //写地址函数{unsigned char address;if (y == 0) address = 0x80 + x;elseaddress = 0xc0 + x;LCD_write_char( address, 0 );}/**************************************************************************** * 名称:LCD_en_write(void)* 功能:液晶使能* 入口参数:无* 出口参数:无* 范例: 直接调用*************CD_set_xy********************************************************* ******/void LCD_en_write(void) //液晶使能{_nop_();LCD_E=1;//EN=1_nop_();LCD_E=0;//EN=0}//------------------------------------------------/**************************************************************************** * 名称:LCD_write_char(uchar cd,uchar ab)* 功能:写指令或数据当写ab时应使cd=0 当cd不为0 则写cd 且ab的赋值无效* 入口参数:cd:指令内容ab:数据内容指令常量已在上面定义但一般不用* 出口参数:无* 范例: LCD_write_char( 0, ‘f’)*************CD_set_xy********************************************************* ******/void LCD_write_char(uchar cd,uchar ab) // 写数据{Delay_us(20);if(cd==0){LCD_RS=1; //RS=1,写显示内容LCD_byte(ab);}else{LCD_RS=0; //RS=0,写命令LCD_byte(cd);}}/**************************************************************************** * 名称:LCD_byte(abc);* 功能:写一个字符到or called one byte to LCD中* 入口参数:* 出口参数:无*************CD_set_xy********************************************************* ******/void LCD_byte(unsigned char abc){RW = 0;LCD_E = 0;LCD_DATA = abc;LCD_en_write();}//在液晶中显示浮点数函数LCD_value(unsigned char x,unsigned char y,float f)unsigned char str[15]; //不能定义为char* str,数组长度一定要大于浮点数的总位数sprintf(str,"%.1f",f); //1表示小数位数小数太多自动四舍五入LCD_write_str( x, y, str);return 0;}主函数文件#include <reg52.h>#include <intrins.h>#include <Lcd_1602.h>#include <Time_Delay.h>#include"DHT11.h"extern float F16T,F16RH; //全局变量声明void main (){Init_Lcd();LCD_write_str(0,1,"abc"); //液晶预显示测试LCD_value(0,0,34.345);Delay_ms(2000);Init_Lcd();while(1){getDHT11();LCD_write_str(0,0,"T=");LCD_value(3,0,F16T); LCD_write_str(8,0,"\"C"); //字符" 应用转义格式LCD_write_str(0,1,"RH=");LCD_value(4,1,F16RH); LCD_write_str(9,1,"%");Delay_ms(500);}}延时函数文件//以下为延时函数this is fit to old C51 12MHz, 12 devide freqencyvoid Delay_ms(unsigned int n)//n毫秒延时unsigned char j;while(n--){for(j=0;j<125;j++);}}void Delay_us(unsigned char n) //N us延时函数精度±4us {n=n/2;while(--n);}电路图实际效果。