"luodaye00001"也是小白,仅供学习参考
//本文章适合刚入门玩单片机开发板的小伙伴
零件清单:亚博51单片机开发板、1602液晶屏、风扇、灯、人感、DS18B20温感;//未占用IO口可以模块化添加功能
思路:人感完成51单片机点灯、DS18B20完成风扇控温以及在1602上显示温度、未占用IO口可以完成未涉及场景控制例如:窗帘、饮水机等等。
小模型的话单片机就能搞定,大模型还是选择PLC、zigbee等等来制作吧。例如国内某大厂的PLC全屋智慧家居是吧。
演示模型
#include<reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P1^2;//温度传感器 DQ 端接单片机 P2.0 口
sbit lcdrs=P1^0;//液晶的 RS 端接 P1.0 口
sbit lcdrw=P1^1;//液晶的 RW 端接 P1.1 口
sbit lcden=P2^5;// 液晶的 EN 使能端接 P2.5 口
sbit fs=P1^4;//风扇IOP.4口
sbit led=P1^5;//灯 P1.5 IO口
sbit HCR501=P2^0;//红外人感 P2.0 IO口
uint wendu=0; //温度初始数值 0
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=112;y>0;y--);
}
void write_cmd(char cmd) //写指令函数
{
lcdrs=0;//低电位送指令
P0=cmd;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
void write_data(uchar dat) //写数据函数
{
lcdrs=1;//高电位送数据
P0=dat ;
delay(1);
lcden=1;
delay(1);
lcden=0;
}
void write_str(uchar *str)//写字符串函数
{
while(*str!='\0')
{
write_data(*str++);
delay(60);
}
}
void init()
{
lcdrw=0;//先将 RW 拉低
lcden=0;//再把 EN 拉低
write_cmd(0x38);//显示模式设置
write_cmd(0x0c);//开启显示屏,关光标,光标不闪烁
write_cmd(0x06);//显示地址递增,即写一个数据后,显示位置右移一位
write_cmd(0x01);//清除屏幕
write_cmd(0x80);//数据指针 把光标移到第一行第一个位置
write_str(" I LIKE MCU"); //初始化显示
write_cmd(0xc0);//数据指针 把光标移到第二行第一个位置
write_str(" Temp:"); //初始化显示
}
bit init_DS18B20()
{
uchar num;
bit flag;
DQ=1;
for(num=0;num<2;num++); //先拉高
DQ=0;
for(num=0;num<200;num++); // 480-960us powerup
DQ=1;
for(num=0;num<20;num++); // >60us wait
flag=DQ; // 响应
for(num=0;num<150;num++); // 60-240us ds18b20 存在信号
DQ=1;
return flag;
}
void DS18B20_WR_CHAR(uchar byte)//写 18b20 数据
{
uchar num;
uchar num1;
for(num1=0;num1<8;num1++)
{
DQ=0; //拉低
_nop_(); //下拉 1us
_nop_();
DQ=byte&0x01; //写数据,从地位开始
for(num=0;num<20;num++); // >60us wait
byte>>=1;
DQ=1; //拉高
_nop_();
_nop_();
} //8 位数据,一位一位的写入 ds18b20
}
uchar DS18B20_RD_CHAR() //读 18b20 数据
{
uchar num;
uchar num1;
uchar byte=0;
for(num1=0;num1<8;num1++)
{
DQ=0; //拉低
_nop_();
DQ=1;
for(num=0;num<1;num++); // <10us
byte>>=1;
if(DQ==1)
byte|=0x80;
else
byte|=0x00;
DQ=1; //拉高
_nop_();
_nop_();
for(num=0;num<20;num++); // >60us
}
return byte;
}
void DS18B20_WENDU()
{
uchar temperaturel=0;
uchar temperatureh=0;
if(init_DS18B20()==0)
{
DS18B20_WR_CHAR(0xcc); //发命令:Skip ROM,跳过读序列号
DS18B20_WR_CHAR(0x44); //启动温度转换
delay(1000);
if(init_DS18B20()==0)
{
DS18B20_WR_CHAR(0xcc); //发命令:Skip ROM,跳过读序列号
DS18B20_WR_CHAR(0xBE); //读取温度
_nop_();
temperaturel=DS18B20_RD_CHAR(); //温度值低 8 为存入 temperaturel
temperatureh=DS18B20_RD_CHAR(); //温度值高 8 为存入 temperatureh
wendu=(temperatureh*256+temperaturel)*0.625;
init_DS18B20();
}
}
}
void main()
{uint m;
m=27;
init();//1602 液晶初始化函数
while(1)
{
if( init_DS18B20()==0)
{
DS18B20_WENDU();
write_cmd(0xc8);//把光标移到第二行第 8 个位置
write_data((wendu/100)%10+48);
write_data((wendu/10)%10+48);
write_data('.');
write_data(wendu%10+48);
write_data(0xdf);
if (wendu>m)
{
fs=0;
}
else
{
fs=1;
}
if(HCR501==1)
{
led=0;
}
else
{
led=1;
}
write_data('C');
}
}
}