同时通过温度和蓝牙来控制风扇
实验器材:
51开发板、DHT11模块、蓝牙模块、LCD1602、马达、小风扇、杜邦线
源码仅供参考:
#include <REGX52.H>
#include “intrins.h”
#define databuffer P0 //定义8位数据线,Po端口组
sfr AUXR = 0x8E;
sbit LED1 = P3^7;
sbit DHT = P3^3;
sbit RS = P1^0;
sbit RW = P1^1;
sbit EN = P1^4;
sbit JDQ = P1^6; //继电器
char dates[5]; //8位为一个数据
char temp[8]; //字符有7个,但是\0占一个字符
char Hema[8];
void Delay30ms(void) //@11.0592MHz
{
unsigned char data i, j;
i = 54;
j = 199;
do
{
while (--j);
} while (--i);
}
void Delay40us(void) //@11.0592MHz
{
unsigned char data i;
_nop_();
i = 15;
while (--i);
}
void Delay60us(void) //@11.0592MHz
{
unsigned char data i;
i = 25;
while (--i);
}
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 Delay1000ms(void) //@11.0592MHz
{
unsigned char data i, j, k;
_nop_();
i = 8;
j = 1;
k = 243;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
串口初始化以及发送数据
``
`c
void Uart1_Init() //串口初始化
{ AUXR = 0x01; //让波特率更加稳定,防止掉帧
SCON = 0x50; //配置串口工作模式,REN为1则接收数据
TMOD &= 0x0F;
TMOD |= 0x20; //配置定时器为8位自动重装模式
TL1 = 0xFD;
TH1 = 0xFD; //8位自动重装模式TH1存放的值自动存入TL1
TR1 = 1; //启动定时器
}
``
void senddate(char date) //串口发出一个个数据函数
{
SBUF = date;
while(!TI); //直到等于1时发送成功,TI为0时变1发送成功;为1变0时不循环
TI = 0; //无时差
}
void sendstring(char* str) //传入字符串
{
while(*str != '\0')
{
senddate(*str); //将字符串打印出来
str++; //地址偏移
}
}
DHT11湿温度传感器时序信号和读数据
void check_DHT_start() //DHT信号
{
DHT = 1;
DHT = 0;
Delay30ms();
DHT = 1;
Delay60us();
while(DHT); //DHT拉低时才会往下走
while(!DHT);
while(DHT); //到f点了
}
void Read_date_form()
{
char flag; //标志位
char tmp; //数据 40bit 8位 需要5次
int i,j;
check_DHT_start(); //送出数据前发出信号
for(i=0;i<5;i++) //先传输数据在卡g点
{
for(j=0;j<8;j++)
{
while(!DHT);//等待卡g点
Delay40us();
if(DHT == 1)
{
flag = 1;
while(DHT); //如果是1先卡一会
}else{
flag = 0;
}tmp = tmp << 1; //8个bit为一个数据,每次左移更新数据
tmp |= flag; //有1则1
}dates[i] = tmp; //8+8+8+8+8
}
}
void check_busy() //忙信号
{
char tmp = 0x80;
databuffer = 0x80;
while(tmp & 0x80){ //1000 0000
RS = 0;
RW = 1;
EN = 0;
_nop_();
EN = 1;
_nop_();
_nop_();
tmp = databuffer; //tmp是1直接控死
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 LCD1602_INIT() //LED1602初始化
{
//(1)延时 15ms
Delay15ms();
//(2)写指令 38H(不检测忙信号)
Write_Cmd_Func(0x38);
//(3)延时 5ms
Delay5ms();
//(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) //LCD1602显示一行
{
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;
}
}
DHT11建立数据为8+8+8+8+8
void build_date()
{
Hema[0] = 'H'; //目的将来自DHT传感器dates显示在串口
Hema[1] = dates[0]/10 + 0x30; //字符与ASCll相差30
Hema[2] = dates[0]%10 + 0x30; //列如43
Hema[3] = '.';
Hema[4] = dates[1]/10 + 0x30;
Hema[5] = dates[1]%10 + 0x30;
Hema[6] = '%';
Hema[7] = '\0';
//sendstring("\r\n");
temp[0] = 'T';
temp[1] = dates[2]/10 + 0x30;
temp[2] = dates[2]%10 + 0x30;
temp[3] = '.';
temp[4] = dates[3]/10 + 0x30;
temp[5] = dates[3]%10 + 0x30; //手册湿度整数+小数,温度整数+小数,效验和
temp[6] = 'C';
temp[7] = '\0';
//sendstring("\r\n");
}
void main()
{
Uart1_Init(); //串口初始化
Delay1000ms();
LCD1602_INIT(); //LCD初始化
Delay1000ms();
Delay1000ms(); //上电先抖至少1s 参考DHT11手册
while(1)
{ Delay1000ms();
Read_date_form(); //一下40bit
if(dates[2]>24)
{
JDQ = 0;
}
build_date();
sendstring(Hema); //串口发送
sendstring("\r\n");
sendstring(temp);
sendstring("\r\n");
LCD1602_showLine(1,2,Hema); //LCD接收
LCD1602_showLine(2,2,temp);
}
}