欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

#物联网#一个小型的物联网系统——智能窗帘控制系统

程序员文章站 2022-03-13 17:32:36
...

介绍

涉及模块:

1.LCD1602液晶屏

2.DS18B20温度传感器

3.ADC0832数模转换芯片

4.TORCH_LDR光照度控件

5.步进电机

实现功能:

1.在LCD上显示实时温度与窗帘状态。

2.温度在15~25℃范围内开窗帘,范围外关窗帘。

3.光线强时关窗帘,光线弱时开窗帘。

4.可通过按钮手动开关窗帘。

仿真图

窗帘系统Proteus仿真图:

#物联网#一个小型的物联网系统——智能窗帘控制系统

代码

项目由以下6个文件组成 :

main.c
#include <reg52.h>
#include <intrins.h>
#include "define.h"
#include "delay.h"
#include "LCD1602.h"
#include "DS18B20.h"
#include "ADC0832.h"

void main()
{
	//开启T0中断
	EA = 1;
	ET0 = 1;
	ET1 = 1;
	//设置T0
	TMOD = 0X01;
	TH0 = 0XFFED;
	TL0 = 0XFFFF;		
	TR0 = 1;

	LCD_init();
	while(1)
	{
		DS_read_temperature();
		display_temperature();		
		LightIntensity(ADC0832());
	//	LCD_write_data(Temp_AD);//在LCD上显示光照强度的数值		
		
		if(flag)
		{
			//关窗
			if(status==0||Temp_AD<=Standard) 
			{
				for(;i<sizeof(Run);i++)
				{
					P2 = Run[i];
					delayms(RunSpeed);	
				}
			}
			//开窗
			else
			{
				for(;i>0;i--)
				{
					P2 = Run[i];
					delayms(RunSpeed);
				}
			}
		}	
	}  
}

//定时器0中断服务
void InterruptTimer() interrupt 1
{
	TH0 = 0XFFED;
	TL0 = 0XFFFF;

	if (key1==0)
	{    //顺时钟
		flag=0;
		for(;i<sizeof(Run);i++)
		{
			P2 = Run[i];
			delayms(RunSpeed);	
		}
	} 
	if (key2==0)
	{   //逆时钟
		flag=0;
		for(;i>0;i--)
		{
			P2 = Run[i];
			delayms(RunSpeed);
		}
	}	
}

define.h
#ifndef _DEFINE_H_
#define _DEFINE_H_

#define uchar unsigned char
#define uint unsigned int

sbit RS=P2^6;
sbit RW=P2^5;
sbit EN=P2^7;
sbit DQ=P3^3;
sbit CLK=P3^1;
sbit CS=P3^0;
sbit DO=P3^2;
bit DS_OK=1;
sbit key1 = P1^0;	 //开关开窗帘	
sbit key2 = P1^1;	 //开关关窗帘						   
uchar code Run[]={
0x00,0x01,0x03,0x02,0x06,0x04,0x0C,0x08,0x09,0xff};	
uchar RunSpeed = 60;
uchar status=0;
uchar i=0;
uchar Temp_AD=0;//现在的光照强度
uchar Standard='F';//光照强弱临界值
bit flag=1;	//手动模式/自动模式的标志
uchar CurtainStatu[]={"  STATE :                  "};
uchar buffer_line2[]={"  Temp:       C            "};
uchar code df_tab[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};
uchar current=0;
uchar display_digit[]={0,0,0,0};
uchar temp_value[]={0x00,0x00};
uchar back_temp_value[]={0x00,0x00};
char alarm_HL[]={70,-10};
char sign_temp;
bit LO_alarm=0;
bit HI_alarm=0;		

#endif
delay.h
#ifndef _DELAY_H_
#define _DELAY_H_

void delay(uint z)
{
	uint x;
	while(z--)
		for(x=50;x>0;x--);
}

void delay0(uint z)
{
	uint x,y;
	for(x=z;x>0;x--)
		for(y=0;y<10;y++);
}

void delay1(uint y)
{
	uint x;
	while(y--)
		for(x=4500;x>0;x--);
}

void delayms(uchar x)
{
	int i,j;
	for(i=x;i>0;i--)
		for(j=0;j<120;j++);
}
void delay_us()
{_nop_();_nop_();
_nop_();_nop_();}
void delay_1us(uint x)	//延时
{
	 while(--x);
}


#endif
DS18B20.h
#ifndef _DS18B20_H_
#define _DS18B20_H_
#include "define.h"
#include "DELAY.H"
#include "LCD1602.h"
#include <string.h>
/*****************************************************/
/************全局都要精确延时************************/
uchar DS_init()
{
	uchar state;	   
	DQ=1;
	delay_1us(8);
	DQ=0;
	delay_1us(80); //精确延时大于4800US
	DQ=1;
	delay_1us(8);
	state=DQ;
	delay(100);	//延时
	return state;	//返回值为1时,初始化失败
}

void DS_write_byte(uchar dat)
{
	uchar i;
	for(i=0;i<8;i++)
	{
		if((dat&0x01)==0)  //写一
		{
			DQ=0;
			delay_1us(5);
		  	DQ=1;	  //精确延时,形成脉冲
		}
		else	   //写0
		{
			DQ=0;
			delay_1us(1);
			DQ=1;
			delay_1us(4);
		}
		dat>>=1;
	}
}

uchar DS_read_byte()
{
	uchar i,dat=0;
	for(i=0;i<8;i++)
	{
		DQ=0;
		dat>>=1;
		DQ=1;
		if(DQ==1)
			dat|=0x80;
		else
			dat|=0x00;
		delay_1us(30);
		DQ=1;
	}
	return dat;
}

void DS_read_temperature()
{
	if(DS_init()==1)	   //返回值为1时
		DS_OK=0;		   //DS_ok=0代表失败
	else
	{
		DS_init();
		DS_write_byte(0xcc);//跳过***
	 	DS_write_byte(0x44);  //启动温度转换
		DS_init();
		DS_write_byte(0xcc);
		DS_write_byte(0xbe);//启动读取温度
		temp_value[1]=DS_read_byte(); //先写低位在写高位
		temp_value[0]=DS_read_byte();
		DS_OK=1;
	}
}

void display_temperature()
{
	uchar flag=0;
	if((temp_value[0]&0xf8)==0xf8)
	{
		flag=1;
		temp_value[0]=~temp_value[0];
		temp_value[1]=~temp_value[1]+1;
		if(temp_value[1]==0x00)
			temp_value[0]++;
	}
	display_digit[3]=df_tab[temp_value[1]&0x0f];//取小数
	//取整数
	current=((temp_value[0]&0x07)<<4)|((temp_value[1]&0xf0)>>4);
	if(current<=25&&current>=15)
	status=1;//15~25°C开窗帘 
	else
	status=0;//范围之外关窗帘

	//判断正负
	sign_temp=flag?-current:current;
	
	LO_alarm=sign_temp<=alarm_HL[1]?1:0;	
	HI_alarm=sign_temp>=alarm_HL[0]?1:0;

/*********分解整数*************************************/
	display_digit[0]=current/100;
	display_digit[1]=current%100/10;
	display_digit[2]=current%10;
/****装入缓冲*********************************************/
	buffer_line2[8]=display_digit[0]+'0';
	buffer_line2[9]=display_digit[1]+'0';
	buffer_line2[10]=display_digit[2]+'0';
	buffer_line2[11]='.';
	buffer_line2[12]=display_digit[3]+'0';
 /*********屏蔽高位不显示*******************************/
	if(display_digit[0]==0)
		buffer_line2[8]=' ';
	if(display_digit[0]==0&&display_digit[1]==0)
		buffer_line2[9]=' ';
	if(flag==1)
	{
		if(buffer_line2[9]==' ')
			buffer_line2[9]='-';
		else
		{
			if(buffer_line2[8]==' ')
				buffer_line2[8]='-';
	 		else
				buffer_line2[7]='-';
		}
	}	
	if (i==0)
	strcpy(CurtainStatu,"  STATE : OPEN             ");
	else if(i==sizeof(Run))
	strcpy(CurtainStatu,"  STATE : CLOSE            ");
	LCD_write_cmd(0x00);
	LCD_display(0x00,CurtainStatu);
	LCD_display(0x40,buffer_line2);
	LCD_write_cmd(0x80+0x4d);
	LCD_write_data(0x00);
	LCD_write_cmd(0x80+0x4e);
	LCD_write_data('C');	 
}

#endif

LCD1602.h
#ifndef _LCD1602_H_
#define _LCD1602_H_

uchar LCD_check_busy()
{
	uchar state;
	RS=0;
	RW=1;
	delay(2);
	EN=1;
	state=P0;
	delay(2);
	EN=0;
	delay(2);
	return state;
}
void LCD_write_cmd(uchar cmd)
{
	while((LCD_check_busy()&0x80)==0x80);
	RS=0;
	RW=0;
	delay(2);
	EN=1;
	P0=cmd;
	delay(2);
	EN=0;
	delay(2);	
}
void LCD_write_data(uchar dat)
{
	while((LCD_check_busy()&0x80)==0x80);
	RS=1;
	RW=0;
	delay(2);
	EN=1;
	P0=dat;
	delay(2);
	EN=0;
	delay(2);
}
void LCD_display(uchar position,uchar *s)
{
	uchar i;
	LCD_write_cmd(0x80+position);
	for(i=0;i<16;i++)
	{
		LCD_write_data(s[i]);
	}
}

void LCD_init()
{
	LCD_write_cmd(0x38);
	LCD_write_cmd(0x0c);
	LCD_write_cmd(0x06);
	LCD_write_cmd(0x01);
}



#endif
ADC0832.h
#ifndef _ADC0832_H_
#define _ADC0832_H_

uchar ADC0832()
{
	uchar i,temp;
	CLK=0;
	CS=0;//选中AD芯片
	delay0(1);
	DO=1;//发送bit1 说明开始转换
	CLK=1;//一个上升沿 将开始位输出ADC0832
	
	delay0(1);
	CLK=0;
	DO=1;
	delay0(1);
	CLK=1;
	
	delay0(1);
	CLK=0;
	DO=0;
	delay0(1);
	CLK=1;
	
	delay0(1);
	CLK=0;
	DO=1;
	for(i=8;i>0;i--)
	{
		CLK = 1;
		delay(1);
		CLK=0;
		delay(1);
		temp|=DO;
		if(DO)
			temp++;
		temp<<1;
	}
	CS=1;//释放芯片
	return temp;//返回读回来的数值
}

void  LightIntensity(unsigned char num1)
{
	//ad在光度强的时候采集回来的电压是小的数值
	//为了方便显示用255将其取反,为光度越强的时候数值越大
	
	//保留实际ad的数值 比如ad50的时候对应80
	//转换为更100有关的高度
	num1=num1/2.55;
	Temp_AD=100-num1;
}

末尾献上可运行资源,需要自取:

上传ing

相关标签: 物联网