【C51】8-温湿度监测显示系统(LCD1602、温湿度传感器、IIC、OLED)
1.LCD1602概述
LCD1602(Liquid Crystal Display)是一种工业字符型液晶,能够同时显示 16×02 即 32 字符(16列两行)
//硬件接线
//电源
VSS -- GND
VDD -- 5V
//对比度
VO -- GND
//控制线
RS -- P1.0
RW -- P1.1
E -- P1.4
//背光灯
A -- 5V
K -- GND
//数据
D0到D7 -- P0.到P0.7
#include "reg52.h" #include "intrins.h" #define databuffer P0 sbit RS = P1^0; sbit RW = P1^1; sbit EN = P1^4;void check_busy() {char tmp = 0x80;databuffer = 0x80;while(tmp & 0x80){RS = 0;RW = 1;EN = 0;_nop_();EN = 1;_nop_();_nop_();tmp = databuffer;EN = 0;_nop_();} }void Write_Cmd(char cmd) {check_busy();RS = 0;RW = 0;EN = 0;_nop_();databuffer = cmd;_nop_();EN = 1;_nop_();_nop_();EN = 0;_nop_();}void Write_Data(char datashow) {check_busy();RS = 1;RW = 0;EN = 0;_nop_();databuffer = datashow;_nop_();EN = 1;_nop_();_nop_();EN = 0;_nop_(); }void Delay15ms() //@11.0592MHz {unsigned char i, j;i = 27;j = 226;do{while (--j);} while (--i); } void Delay5ms() //@11.0592MHz {unsigned char i, j;i = 9;j = 244;do{while (--j);} while (--i); }void LCD1602_init() {//(1)延时 15ms Delay15ms();//(2)写指令 38H(不检测忙信号) Write_Cmd(0x38);//(3)延时 5ms Delay5ms();//(4)以后每次写指令,读/写数据操作均需要检测忙信号 //(5)写指令 38H:显示模式设置 Write_Cmd(0x38);//(6)写指令 08H:显示关闭 Write_Cmd(0x08);//(7)写指令 01H:显示清屏Write_Cmd(0x01);//(8)写指令 06H:显示光标移动设置Write_Cmd(0x06);//(9)写指令 0CH:显示开及光标设置Write_Cmd(0x0c);}void LCD1602_showLine(char row,char col, char *string) {switch(row){case 1:Write_Cmd(0x80+col);while(*string){Write_Data(*string);string++;}break;case 2:Write_Cmd(0x80+0x40+col);while(*string){Write_Data(*string);string++;}break;} }void main() {char cmd = 0x80 + 0x05;char datashow = 'C';LCD1602_init();//Write_Cmd(cmd);//Write_Data(datashow);LCD1602_showLine(1,5,"NO 2");LCD1602_showLine(2,1,"CLC homesome"); }
2.DHT11温湿度传感器
DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,应用领域:暖通 空调;汽车;消费品;气象站;湿度调节器;除湿器;家电;医疗;自动控制
特点
相对湿度和温度测量 全部校准,数字输出 长期稳定性 超长的信号传输距离:20米 超低能耗:休眠 4 引脚安装:可以买封装好的 完全互换 : 直接出结果,不用转化
a : dht = 1 b :dht = 0
延时30ms c: dht = 1
在60us后读d点,如果d点是低电平(被模块拉低),说明模块存在!
代码实现
#include "reg52.h"
#include "intrins.h"sbit ledOne = P3^7;
sbit dht = P1^3;//模块的data插在p1.3void Delay30ms() //@11.0592MHz
{unsigned char i, j;i = 54;j = 199;do{while (--j);} while (--i);
}void Delay60us() //@11.0592MHz
{unsigned char i;i = 25;while (--i);
}void Delay1000ms() //@11.0592MHz
{unsigned char i, j, k;_nop_();i = 8;j = 1;k = 243;do{do{while (--k);} while (--j);} while (--i);
}void check_DHT()
{//a : dht = 1 dht = 1;//b :dht = 0dht = 0;//延时30msDelay30ms();//c: dht = 1dht = 1;//在60us后读d点,如果d点是低电平(被模块拉低),说明模块存在!Delay60us();if(dht == 0){ledOne = 0;//亮灯,说明模块存在}
}void main()
{ledOne = 1;Delay1000ms();Delay1000ms();check_DHT();while(1);
}
#include "reg52.h"
#include "intrins.h"sbit ledOne = P3^7;
sbit dht = P1^3;//模块的data插在p1.3
sfr AUXR = 0x8E;char datas[5];
void UartInit(void) //9600bps@11.0592MHz
{AUXR = 0x01;SCON = 0x40; //配置串口工作方式1,REN不使能接收TMOD &= 0xF0;TMOD |= 0x20;//定时器1工作方式位8位自动重装TH1 = 0xFD;TL1 = 0xFD;//9600波特率的初值TR1 = 1;//启动定时器
}
void sendByte(char data_msg)
{SBUF = data_msg;while(!TI);TI = 0;
}void sendString(char* str)
{while( *str != '\\0'){sendByte(*str);str++;}
}
void Delay30ms() //@11.0592MHz
{unsigned char i, j;i = 54;j = 199;do{while (--j);} while (--i);
}void Delay40us() //@11.0592MHz
{unsigned char i;_nop_();i = 15;while (--i);
}void Delay60us() //@11.0592MHz
{unsigned char i;i = 25;while (--i);
}void Delay1000ms() //@11.0592MHz
{unsigned char i, j, k;_nop_();i = 8;j = 1;k = 243;do{do{while (--k);} while (--j);} while (--i);
}void DHT11_stat()
{dht = 1;dht = 0;//延时30msDelay30ms();dht = 1;while(dht);while(!dht);while(dht);
}void Read_Data_From_DHT()
{int i;int j;char tmp;char flag;DHT11_stat();for(i=0;i<5;i++){for(j=0;j<8;j++){while(!dht);Delay40us();if(dht == 1){flag = 1;while(dht);}else{flag = 0;}tmp <<= 1;tmp |= flag;}datas[i] = tmp;}
}void main()
{ledOne = 1;UartInit();Delay1000ms();Delay1000ms();while(1){Delay1000ms();Read_Data_From_DHT();sendString("H:");sendByte(datas[0]/10 + 0x30);sendByte(datas[0]%10 + 0x30);sendByte('.');sendByte(datas[1]/10 + 0x30);sendByte(datas[1]%10 + 0x30);sendString("\\r\\n");sendString("T:");sendByte(datas[2]/10 + 0x30);sendByte(datas[2]%10 + 0x30);sendByte('.');sendByte(datas[3]/10 + 0x30);sendByte(datas[3]%10 + 0x30);sendString("\\r\\n");}
}
DHT11_04在LCD显示并通过蓝牙发送温湿度
#include "reg52.h"
#include "intrins.h"sbit ledOne = P3^7;
sbit dht = P1^3;//模块的data插在p1.3
sfr AUXR = 0x8E;
#define databuffer P0 //定义8位数据线,Po端口组
sbit RS = P1^0;
sbit RW = P1^1;
sbit EN = P1^4;char temp[8];
char huma[8];
void check_busy()
{char tmp = 0x80;databuffer = 0x80;while(tmp & 0x80){//1000 0000RS = 0;RW = 1;EN = 0;_nop_();EN = 1;_nop_();_nop_();tmp = databuffer;EN = 0;_nop_();}
}void Write_Cmd_Func(char cmd)
{check_busy();RS = 0;RW = 0;EN = 0;_nop_();databuffer = cmd;_nop_();EN = 1;_nop_();_nop_();EN = 0;_nop_();
}void Write_Data_Func(char dataShow)
{check_busy();RS = 1;RW = 0;EN = 0;_nop_();databuffer = dataShow;_nop_();EN = 1;_nop_();_nop_();EN = 0;_nop_();
}void Delay15ms() //@11.0592MHz
{unsigned char i, j;i = 27;j = 226;do{while (--j);} while (--i);
}
void Delay5ms() //@11.0592MHz
{unsigned char i, j;i = 9;j = 244;do{while (--j);} while (--i);
}
char datas[5];
void UartInit(void) //9600bps@11.0592MHz
{AUXR = 0x01;SCON = 0x40; //配置串口工作方式1,REN不使能接收TMOD &= 0xF0;TMOD |= 0x20;//定时器1工作方式位8位自动重装TH1 = 0xFD;TL1 = 0xFD;//9600波特率的初值TR1 = 1;//启动定时器
}
void sendByte(char data_msg)
{SBUF = data_msg;while(!TI);TI = 0;
}void sendString(char* str)
{while( *str != '\\0'){sendByte(*str);str++;}
}
void Delay30ms() //@11.0592MHz
{unsigned char i, j;i = 54;j = 199;do{while (--j);} while (--i);
}void Delay40us() //@11.0592MHz
{unsigned char i;_nop_();i = 15;while (--i);
}void Delay60us() //@11.0592MHz
{unsigned char i;i = 25;while (--i);
}void Delay1000ms() //@11.0592MHz
{unsigned char i, j, k;_nop_();i = 8;j = 1;k = 243;do{do{while (--k);} while (--j);} while (--i);
}void DHT11_stat()
{dht = 1;dht = 0;//延时30msDelay30ms();dht = 1;while(dht);while(!dht);while(dht);
}void Read_Data_From_DHT()
{int i;int j;char tmp;char flag;DHT11_stat();for(i=0;i<5;i++){for(j=0;j<8;j++){while(!dht);Delay40us();if(dht == 1){flag = 1;while(dht);}else{flag = 0;}tmp <<= 1;tmp |= flag;}datas[i] = tmp;}
}void LCD1602_INIT()
{//(1)延时 15msDelay15ms();
//(2)写指令 38H(不检测忙信号) Write_Cmd_Func(0x38);
//(3)延时 5msDelay5ms();
//(4)以后每次写指令,读/写数据操作均需要检测忙信号
//(5)写指令 38H:显示模式设置Write_Cmd_Func(0x38);
//(6)写指令 08H:显示关闭Write_Cmd_Func(0x08);
//(7)写指令 01H:显示清屏Write_Cmd_Func(0x01);
//(8)写指令 06H:显示光标移动设置Write_Cmd_Func(0x06);
//(9)写指令 0CH:显示开及光标设置}Write_Cmd_Func(0x0c);
}void LCD1602_showLine(char row, char col, char *string)
{switch(row){case 1:Write_Cmd_Func(0x80+col);while(*string){Write_Data_Func(*string);string++;}break;case 2:Write_Cmd_Func(0x80+0x40+col);while(*string){Write_Data_Func(*string);string++;}break;}
}void Build_Datas()
{huma[0] = 'H';huma[1] = datas[0]/10 + 0x30;huma[2] = datas[0]%10 + 0x30;huma[3] = '.';huma[4] = datas[1]/10 + 0x30;huma[5] = datas[1]%10 + 0x30;huma[6] = '%';huma[7] = '\\0';temp[0] = 'T';temp[1] = datas[2]/10 + 0x30;temp[2] = datas[2]%10 + 0x30;temp[3] = '.';temp[4] = datas[3]/10 + 0x30;temp[5] = datas[3]%10 + 0x30;temp[6] = 'C';temp[7] = '\\0';}void main()
{Delay1000ms();UartInit();LCD1602_INIT();Delay1000ms();Delay1000ms();ledOne = 0;while(1){Delay1000ms();Read_Data_From_DHT();Build_Datas();sendString(huma);sendString("\\r\\n");sendString(temp);sendString("\\r\\n");LCD1602_showLine(1,2,huma);LCD1602_showLine(2,2,temp);}
}