简单的51程序控制风扇(或其他电气开关)
本程序实现的功能介绍:51单片机采集DHT继电器的开关通过不同的温度控制风扇。
材料:
DHT11温湿度传感器 51最小系统板(也可用于开发板) LCD1602显示屏 继电器 杜邦线 材料准备好后,就可以开始写程序了!
LCD.h
#ifndef __LCD_H_ #define __LCD_H_ #define LCD1602_DB P0 //data bus 数据总线 sbit LCD1602_RS = P2^6; sbit LCD1602_RW = P2^5; sbit LCD1602_EN = P2^7; void LCD_Delay10ms(unsigned int c); //void Read_Busy(); //判断bit七是0,允许执行;1禁止执行; void Lcd1602_Write_Cmd(unsigned char cmd); //写命令 void Lcd1602_Write_Data(unsigned char dat); //写数据 void LcdSetCursor(unsigned char x,unsigned char y); ///坐标显示 void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str); //显示字符串 void InitLcd1602(); //1602初始化 #endif
lcd.c
#include"lcd.h" void Lcd1602_Write_Cmd(unsigned char cmd) //写命令 {
//Read_Busy(); LCD1602_RS = 0; LCD1602_RW = 0; LCD1602_DB = cmd;
LCD_Delay10ms(1);
LCD1602_EN = 1;
LCD_Delay10ms(1);
LCD1602_EN = 0;
}
void Lcd1602_Write_Data(unsigned char dat) //写数据
{
//Read_Busy();
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_DB = dat;
LCD_Delay10ms(1);
LCD1602_EN = 1;
LCD_Delay10ms(1);
LCD1602_EN = 0;
}
//指定位置开始显示数据!
void LcdSetCursor(unsigned char x,unsigned char y) //坐标显示
{
unsigned char addr;
if(y == 0)
addr = 0x00 + x;//第一行开始,x表示一行的第x个
else
addr = 0x40 + x;//第二行开始,x表示一行的第x个
Lcd1602_Write_Cmd(addr|0x80);
}
void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str) //显示字符串
{
LcdSetCursor(x,y); //当前字符的坐标
while(*str != '\0')
{
Lcd1602_Write_Data(*str++);
}
}
void InitLcd1602() //1602初始化
{
Lcd1602_Write_Cmd(0x38); //打开,5*8,8位数据
Lcd1602_Write_Cmd(0x0c);
Lcd1602_Write_Cmd(0x06);
Lcd1602_Write_Cmd(0x01); //清屏
}
void LCD_Delay10ms(unsigned int c) //误差 0us
{
unsigned char a,b;
for(;c>0;c--)
for(b=38;b>0;b--)
for(a=130;a>0;a--);
}
main.c
#include<reg51.h> //根据官方给出关于DHT11的
芯片手册完成设计,调用1602的头文件 #include"lcd.h" //LCD屏幕的头文件 #include<intrins.h> //C语言头文件库 #include<stdio.h> //C语言头文件库 sbit Temp_data=P3^6; //DHT11温湿度传感器的信号读取引脚 sbit fan_jw=P1^1; //定义继电器的信号输入引脚 unsigned int rec_dat[4]; //unsigned char data_byte; //unsigned char rec_dat_lcd=[4]; unsigned char rec_dat_lcd0[6]; unsigned char rec_dat_lcd1[6]; unsigned char rec_dat_lcd2[6]; unsigned char rec_dat_lcd3[6]; //定义 void DHT11_delay_us(unsigned char n); void DHT11_delay_ms(unsigned int z); void DHT11_start(); unsigned char DHT11_rec_byte(); void DHT11_receive(); void InitUART(void); //主函数 void main() { InitUART(); P1=0xf0; InitLcd1602(); LcdShowStr(0,0,"WET:"); LcdShowStr(0,1,"Temp:"); EA = 1; //开总中断 while(1) { DHT11_delay_ms(150); DHT11_receive(); sprintf(rec_dat_lcd0,"%d",rec_dat[0]); sprintf(rec_dat_lcd1,"%d",rec_dat[1]); sprintf(rec_dat_lcd2,"%d",rec_dat[2]); sprintf(rec_dat_lcd3,"%d",rec_dat[3]); DHT11_delay_ms(100); //湿度 LcdShowStr(6,0,rec_dat_lcd0); LcdShowStr(8,0,"."); LcdShowStr(9,0,rec_dat_lcd1); LcdShowStr(10,0," %"); //温度 LcdShowStr(6,1,rec_dat_lcd2); LcdShowStr(8,1,"."); LcdShowStr(9,1,rec_dat_lcd3); LcdShowStr(10,1," C"); //下面通过串口助手打印温度 printf("WET:%d.%d \n",rec_dat[0],rec_dat[1]); printf("Temp:%d.%d °C\n",rec_dat[2],rec_dat[3]); } } //DHT11起始信号 void DHT11_start() { Temp_data=1; DHT11_delay_us(2); Temp_data=0; DHT11_delay_ms(20); Temp_data=1; DHT11_delay_us(13); } //接收一个字节 unsigned char DHT11_rec_byte() { unsigned char i,dat; for(i=0;i<8;i++) { while(!Temp_data); DHT11_delay_us(8); dat<<=1; if(Temp_data==1) { dat+=1; } while(Temp_data); } return dat; } //接收温湿度数据 void DHT11_receive() { unsigned int R_H,R_L,T_H,T_L; unsigned char RH,RL,TH,TL,revise; DHT11_start(); Temp_data=1; if(Temp_data==0) { while(Temp_data==0); //等待拉高 DHT11_delay_us(40); //拉高后延时80us R_H=DHT11_rec_byte(); //接收湿度高八位 R_L=DHT11_rec_byte(); //接收湿度低八位 T_H=DHT11_rec_byte(); //接收温度高八位 T_L=DHT11_rec_byte(); //接收温度低八位 revise=DHT11_rec_byte(); //接收校正位 DHT11_delay_us(25); //结束 if((R_H+R_L+T_H+T_L)==revise) //校正 { RH=R_H; RL=R_L; TH=T_H; TL=T_L; } /*数据处理,方便显示*/ rec_dat[0]=RH; rec_dat[1]=RL; rec_dat[2]=TH; rec_dat[3]=TL; if (rec_dat[2]<=0x19)//继电器读取高八位的数值,供给给继电器控制风扇的开关,这里设置高于25度时继电器控制开风扇,低于时关风扇 { fan_jw=0xff;//开风扇状态 }else fan_jw=0x00;//关风扇状态 } } //延时us --2*n+5us void DHT11_delay_us(unsigned char n) { while(--n); } //延时ms void DHT11_delay_ms(unsigned int z) { unsigned int i,j; for(i=z;i>0;i--) for(j=110;j>0;j--); } void InitUART(void)//使用定时器1作为串口波特率发生器 { SCON=0x40; //串口通信工作方式1 REN=1; //允许接收 TMOD=0x20; //定时器1的工作方式2 TH1=0xF3,TL1=0xF3; TI=1; //这里一定要注意 TR1=1; }
OK,代码写完,就可以烧录进去实现功能了
总结:
我这里设置的温度值是低于25摄氏度给继电器发送一个信号执行通断,使用的是一个5v的小风扇。接线就是小风扇的GND和电源的GND相接,VCC和继电器相接,输入的VCC接在继电器的常开端。