基于VB和单片机的智能家居监控系统设计

            以51单片机为主控板,外接煤气传感器模块、烟雾传感器模块、LCD12864/OLED屏幕、DS1302时钟芯片、DHT11温度传感器等,实时采集环境数据,并伴有报警提示,同时将数据显示到上位机界面(vb/vs),实现智能家居环境温度的实时监测。此外还将附带远程遥控的基本智能功能

展示视频:

2022-11-07_16-52-39

LCD12864xianshi.c的代码:

#include "reg52.h"
#include <intrins.h>
#include <DHT11.h>
#include<uart.h>
#include"DS1302.h"
//#include"adc0832.h"

#define uchar unsigned char
#define uint unsigned int
#define width	15						/* 显示宽度 */	
#define Graphic	1
#define TXT     0
#define LcmLengthDots	128
#define LcmWidthDots  64 
#define RUN_CNT_MAX			2
#define MENU_NUM_LIMIT			3

sbit REST = P2^0;			  			//复位信号,低电平有效
sbit C_D = P2^1;						//L:数据   H:指令
sbit C_E = P2^2;						//使能端,低电平有效
sbit R_D = P2^3;						//读
sbit W_R = P2^4;						//写

sbit CS = P1 ^ 0;
sbit CLK = P1 ^ 1;
sbit DO = P1 ^ 2;
sbit DI = P1 ^ 3;

sbit led = P1 ^ 5;
sbit led2 = P1 ^ 7;
sbit led3 = P2 ^ 5;

sbit HW = P1 ^ 4;

uchar sec;
uchar jishu;
uchar i;
uchar asd;
uchar add;
uchar shi, fen, miao,shi1,fen1,miao1,shi2,fen2,miao2;
char DHT[10];
uint DS[7];
uchar yu;
uchar shu = 0;
uchar hww = 0;
uchar yanwu,yanwu1,yanwu2,yanmwu3,yanwu4,yanwu5;
/****************************************液晶字库**************************************/

uchar num[] = "0123456789";
typedef struct typFNT_GB16
{
	char Mask[60];
};

code struct typFNT_GB16  GB_16[] = 					/* 汉字取模 */
{
//你要显示的文字用汉字取模软件
};

/***************************************液晶字库结束***************************************/


void delay_nms(uint i);										/* 延时函数 */
void write_commond(uchar com);								/*LCD12864写入8位命令子函数*/
void write_date(uchar dat)	;								/*LCD12864写入8位数据子函数*/									
void F12864_init();											/*LCD12864 并行初始化子程序*/		
void F12864_clear(void);									/* LCD12864初始化函数 */
void goto_xy(uchar x,uchar y,uchar mode);					/* 设定显示地址 */
void Putchar(uchar x,uchar y,uchar Charbyte);				/* 显示一个字符 */
void display_string(uchar x,uchar y,uchar *p);				/* 显示字符串 */
void display_num(uchar x,uchar y,uchar z);					/* 显示数字 */
void Get_Dat();
void USB_cccc(void);
uchar AD0834(uchar channel);
																							
void dprintf_hanzi_string_1(struct typFNT_GB16 code *GB_16,uint X_pos,uint Y_pos,uchar j,uchar k);	
/*	汉字显示 更改汉字取模 可以更改显示汉字(数组),坐标,坐标,j=k+n (n,显示字的个数,k,从那个字开始)   */
void delay2ms(void)   //晶振12M,误差 0us,含调用
{
	unsigned char a, b;
	for (b = 133; b > 0; b--)
		for (a = 6; a > 0; a--);
}
void main(void)
{
	UART_init();
	F12864_init();
	F12864_clear();
	DS1302_Init();
	while(1)
	{
		sec++;
		jishu++;
		DHT11_receive();
		switch (shu)
		{
		case 0:DS1302_ReadTime(); break;
		case 1:DS1302_SetTime(); break;
		}
		//DS1302_ReadTime();
		yanwu = AD0834(0);
		yanmwu3 = AD0834(1);
		yanwu1 = yanwu * 500 / 255 ;
		yanwu2 = yanwu1 / 10;
		yanwu4 = yanmwu3 * 500 / 255;
		yanwu5 = yanwu4 / 10;
		if (yanwu2 <10)
		{
			led = 1;
			display_string(12, 7, "N");
		}
		else
		{
			led = 0;
			display_string(12, 7, "Y");
		}
		if (yanwu5>10)
		{
			led2 = 1;
			display_string(12, 6, "N");
		}
		else
		{
			led2 = 0;
			display_string(12, 6, "Y");
		}
		if (HW == 0)
		{
			hww = !hww;
		}
		if (hww == 1)
		{
			led3 = 1;
		}
		else
		{
			led3 = 0;
		}
		if (sec >=5 )
		{
			shi1 = DS1302_Time[3] / 10 + 0x30;
			shi2 = DS1302_Time[3] % 10 + 0x30;
			fen1 = DS1302_Time[4] / 10 + 0x30;
			fen2 = DS1302_Time[4] % 10 + 0x30;
			miao1 = DS1302_Time[5] / 10 + 0x30;
			miao2 = DS1302_Time[5] % 10 + 0x30;
			DHT[0] = rec_dat[0];
			DHT[1] = rec_dat[1];							    
			DHT[2] = rec_dat[4];
			DHT[3] = rec_dat[5];
			DHT[4] = shi1;
			DHT[5] = shi2;
			DHT[6] = fen1;
			DHT[7] = fen2;
			DHT[8] = miao1;
			DHT[9] = miao2;
			DHT[10] = 0;
			UART_Send_Str(DHT);
			sec = 0;  
		}
		dprintf_hanzi_string_1(GB_16,1,16,5,0);			//左右移动8点阵,上下为1
		DHT11_receive();
		add = rec_dat[5] + (rec_dat[4] * 10) - 14 - 2;
		asd = ((DHT[0]-0x30) * 10) + (DHT[1]-0x30);
		shi = DS1302_Time[3];
		fen = DS1302_Time[4];
		miao = DS1302_Time[5];
		display_string(0, 6, "SiDu");						 //5表示横向8点阵倍数,7也是8点阵的倍数
		display_string(4, 6, ":");
		display_num(5, 6, asd);

		display_string(0, 7, "WeDu");
		display_string(4, 7, ":");
		display_num(5, 7, add);

		display_string(0, 5, "Time");
		display_string(5, 5, ":");
		display_num(6, 5, shi);
		display_string(8, 5, "-");
		display_num(9, 5, fen);
		display_string(11, 5, "-");
		display_num(12, 5, miao);

		display_string(9, 6, "CO");
		display_string(9, 7, "SM");
		display_string(11, 6, ":");
		display_string(11, 7, ":");

	}
}
void USB_cccc(void) interrupt 4
{
	if (RI)
	{
		RI = 0;
		if (SBUF == 0x01)//切换模式
		{
			shu = !shu;
		}
		if (SBUF == 0x02)//时++
		{
			DS1302_Time[3]++;
		}
		if (SBUF == 0x03)//分++
		{
			DS1302_Time[4]++;
		}
		if (SBUF == 0x04)//秒++
		{
			DS1302_Time[5]++;
		}
		if (DS1302_Time[3] > 23) { DS1302_Time[3] = 0; }//时越界判断
		if (DS1302_Time[4] > 59) { DS1302_Time[4] = 0; }//分越界判断
		if (DS1302_Time[5] > 59) { DS1302_Time[5] = 0; }//秒越界判断
		//if (SBUF == 0x01) 
		//{
		//	i = !i;
		//}
		//if (i == 1)
		//{
		//	if (SBUF == 0x02)
		//	{
		//		DS1302_Time[3]++;
		//	}
		//	if (SBUF == 0x03)
		//	{
		//		DS1302_Time[4]++;
		//	}
		//	if (SBUF == 0x04)
		//	{
		//		DS1302_Time[5]++;
		//	}
		//}
	}
}

void delay_nms(uint i)
{
	while(i)
	i--;
}


/* 并行
 * 写命令
 */
void write_commond(uchar com)
{
	C_E = 0;	
	C_D = 1;
	R_D = 1;
	P0 = com;
	W_R = 0;																// write	  
	_nop_();					
	W_R = 1;																// disable write
	C_E = 1;						   	   		
	C_D = 0;
}

/* 并行->写数据 */
void write_date(uchar dat)									
{
	C_E = 0;
	C_D = 0;
	R_D = 1;
	P0 = dat;
	W_R = 0;
	_nop_();
	W_R = 1;
	C_E = 1;
	C_D = 1;
}

/*
 * 写一个指令 一个数据
 */
 void write_dc(uchar com,uchar dat)											
{
	write_date(dat);
	write_commond(com);
}

/*
 * 写一个指令两个数据 
 */
void write_ddc(uchar com,uchar dat1,uchar dat2)
{
	write_date(dat1);
	write_date(dat2);
	write_commond(com);
}

/* 并行初始化 */
void F12864_init(void)
{	
	REST = 0;
	delay_nms(2000);					
	REST = 1;
	write_ddc(0x40,0x00,0x00);			     				 		/* 设置文本显示首地址 */
	write_ddc(0x41,128/8,0x00);  									/* 设置文本显示宽度 */
	write_ddc(0x42,0x00,0x08);			      						/* 设置文本显示首地址0x0800 */
	write_ddc(0x43,128/8,0x00);  									/* 设置图形显示宽度 */
	write_commond(0xA0);                     						/* 设置光标形状8*8 */
	write_commond(0x80);                     						/* 显示方式设置 文本and图形(异或) */
	write_commond(0x92);                     						/* 设置光标 */
	write_commond(0x9F);                     						/* 显示开关设置,文本开,图形开,光标闪烁关 */
}

/* 清除显示函数 */
void F12864_clear(void)
{
	unsigned int i;
	write_ddc(0x24,0x00,0x00); 													/* 设置地址指针从零开始 */									
   	write_commond(0xb0); 															/* 自动写 */
	for(i = 0;i < 128 * 64 ;i++)write_date(0x00); 			/* 清一屏 */
	write_commond(0xb2); 																/* 自动写结束 */
	write_ddc(0x24,0x00,0x00); 													/* 重置地址指针 */
}

/* 设定显示地址 
 * mode 1:图形
 *      0:汉字
 */
void goto_xy(uchar x,uchar y,uchar mode)
{
     uint  temp;
     temp = 128 / 8 * y + x;
     if(mode)                                 								//mode = 1为Graphic
     {                                        								//图形模式要加上图形区首地址0x0800
         temp = temp + 0x0100;
     }
     write_ddc(0x24,temp & 0xff,temp / 256);	  							//地址指针位置
}

/* 显示一个ASCII码 */
void Putchar(uchar x,uchar y,uchar Charbyte)
{
     goto_xy(x,y,TXT);
     write_dc(0xC4,Charbyte-32);		     								//数据一次写入 
}

void display_string(uchar x,uchar y,uchar *p)
{
	while(*p != 0)
	{
		if(x > 15 )                          								//超出一行,自动换行
		{										 	
			x = 0;
			y++;
		}
		Putchar(x,y,*p);
		++x;
		++p;
	}
}

void display_num(uchar x,uchar y,uchar z)
{
	uchar z1,z2;
	z1 = num[z / 10];
	z2 = num[z % 10];
	Putchar(x,y,z1);
	Putchar(x+1,y,z2);
}


/* 显示一串汉字,j=k+n (n,显示字的个数,k,从那个字开始)  */
void dprintf_hanzi_string_1(struct typFNT_GB16 code *GB_16,uint X_pos,uint Y_pos,uchar j,uchar k)
{  
	unsigned int address;
	unsigned char m,n;
	while(k < j)
	{
		m = 0;
		address = LcmLengthDots / 8 * Y_pos + X_pos + 0x0800;
		for(n = 0;n < 16;n++)                                  			  	//计数值16
    	{
		   write_ddc(0x24,(uchar)(address),(uchar)(address>>8)); //设置显示存储器地址
		   write_dc(0xc0,GB_16[k].Mask[m++]);                    //写入汉字字模左部
		   write_dc(0xc0,GB_16[k].Mask[m++]);                 	//写入汉字字模右部
		   address = address + 128/8;                           //修改显示存储器地址,显示下一列(共16列)
	    }
		X_pos += 2;
		k++;
	}
}
uchar AD0834(uchar channel)
{
	uchar V = 0, i = 0;

	CS = 0; //片选信号,低电平有效
	DO = 0;	//DO为高阻态,这里置低为后续读取做准备
	delay2ms();

	//前三个脉冲为配置设置
	CLK = 0;
	delay2ms();
	DI = 1;
	CLK = 1;//第一个脉冲,起始位
	delay2ms();

	CLK = 0;
	delay2ms();
	DI = 1;
	CLK = 1;//第二个脉冲,该位为“1”时是单端输入模式,为“0”时是差分输入模式
	delay2ms();

	CLK = 0;
	delay2ms();
	DI = channel; //第三个脉冲,DI=1表示选择通道1(CH2),DI=0表示选择通道0(CH1)
	CLK = 1;
	delay2ms();

	DI = 0; //DI转为高阻态,状态无关紧要,这里给低方便下一轮读取
	DO = 1; //DO口恢复默认上拉,准备接收信号
	CLK = 1;
	delay2ms();
	CLK = 0; //第一个下降沿,为去数做准备
	delay2ms();//等待芯片接收下降沿并切换输出模式

			//接收8位信号并转换
	for (i = 0; i < 8; i++)
	{
		CLK = 1;
		delay2ms();
		CLK = 0;
		if (DO)//如果DO为高电平,相应的位数是1
			V = V | 1 << (7 - i);
	}
	CS = 1;//关闭片选,结束一个转换周期
	return V;
}

DS1302.c代码

#include <REGX52.H>
#include"DS1302.h"

//引脚定义
sbit DS1302_SCLK = P3 ^ 6;
sbit DS1302_IO = P3 ^ 4;
sbit DS1302_CE = P3 ^ 5;

//寄存器写入地址/指令定义
#define DS1302_SECOND		0x80
#define DS1302_MINUTE		0x82
#define DS1302_HOUR			0x84
#define DS1302_DATE			0x86
#define DS1302_MONTH		0x88
#define DS1302_DAY			0x8A
#define DS1302_YEAR			0x8C
#define DS1302_WP			0x8E

//时间数组,索引0~6分别为年、月、日、时、分、秒、星期
unsigned char DS1302_Time[] = { 22,3,18,12,59,50,5 };
/**
  * @brief  DS1302初始化
  * @param  无
  * @retval 无
  */
void DS1302_Init(void)
{
	DS1302_CE = 0;
	DS1302_SCLK = 0;
}

/**
  * @brief  DS1302写一个字节
  * @param  Command 命令字/地址
  * @param  Data 要写入的数据
  * @retval 无
  */
void DS1302_WriteByte(unsigned char Command, Data)
{
	unsigned char i;
	DS1302_CE = 1;
	for (i = 0; i < 8; i++)
	{
		DS1302_IO = Command & (0x01 << i);
		DS1302_SCLK = 1;
		DS1302_SCLK = 0;
	}
	for (i = 0; i < 8; i++)
	{
		DS1302_IO = Data & (0x01 << i);
		DS1302_SCLK = 1;
		DS1302_SCLK = 0;
	}
	DS1302_CE = 0;
}

/**
  * @brief  DS1302读一个字节
  * @param  Command 命令字/地址
  * @retval 读出的数据
  */
unsigned char DS1302_ReadByte(unsigned char Command)
{
	unsigned char i, Data = 0x00;
	Command |= 0x01;	//将指令转换为读指令
	DS1302_CE = 1;
	for (i = 0; i < 8; i++)
	{
		DS1302_IO = Command & (0x01 << i);
		DS1302_SCLK = 0;
		DS1302_SCLK = 1;
	}
	for (i = 0; i < 8; i++)
	{
		DS1302_SCLK = 1;
		DS1302_SCLK = 0;
		if (DS1302_IO) { Data |= (0x01 << i); }
	}
	DS1302_CE = 0;
	DS1302_IO = 0;	//读取后将IO设置为0,否则读出的数据会出错
	return Data;
}

/**
  * @brief  DS1302设置时间,调用之后,DS1302_Time数组的数字会被设置到DS1302中
  * @param  无
  * @retval 无
  */
void DS1302_SetTime(void)
{
	DS1302_WriteByte(DS1302_WP, 0x00);
	DS1302_WriteByte(DS1302_YEAR, DS1302_Time[0] / 10 * 16 + DS1302_Time[0] % 10);//十进制转BCD码后写入
	DS1302_WriteByte(DS1302_MONTH, DS1302_Time[1] / 10 * 16 + DS1302_Time[1] % 10);
	DS1302_WriteByte(DS1302_DATE, DS1302_Time[2] / 10 * 16 + DS1302_Time[2] % 10);
	DS1302_WriteByte(DS1302_HOUR, DS1302_Time[3] / 10 * 16 + DS1302_Time[3] % 10);
	DS1302_WriteByte(DS1302_MINUTE, DS1302_Time[4] / 10 * 16 + DS1302_Time[4] % 10);
	DS1302_WriteByte(DS1302_SECOND, DS1302_Time[5] / 10 * 16 + DS1302_Time[5] % 10);
	DS1302_WriteByte(DS1302_DAY, DS1302_Time[6] / 10 * 16 + DS1302_Time[6] % 10);
	DS1302_WriteByte(DS1302_WP, 0x80);
}

/**
  * @brief  DS1302读取时间,调用之后,DS1302中的数据会被读取到DS1302_Time数组中
  * @param  无
  * @retval 无
  */
void DS1302_ReadTime(void)
{
	unsigned char Temp;
	Temp = DS1302_ReadByte(DS1302_YEAR);
	DS1302_Time[0] = Temp / 16 * 10 + Temp % 16;//BCD码转十进制后读取
	Temp = DS1302_ReadByte(DS1302_MONTH);
	DS1302_Time[1] = Temp / 16 * 10 + Temp % 16;
	Temp = DS1302_ReadByte(DS1302_DATE);
	DS1302_Time[2] = Temp / 16 * 10 + Temp % 16;
	Temp = DS1302_ReadByte(DS1302_HOUR);
	DS1302_Time[3] = Temp / 16 * 10 + Temp % 16;
	Temp = DS1302_ReadByte(DS1302_MINUTE);
	DS1302_Time[4] = Temp / 16 * 10 + Temp % 16;
	Temp = DS1302_ReadByte(DS1302_SECOND);
	DS1302_Time[5] = Temp / 16 * 10 + Temp % 16;
	Temp = DS1302_ReadByte(DS1302_DAY);
	DS1302_Time[6] = Temp / 16 * 10 + Temp % 16;
}

uart.c代码

#include<reg52.h>
#include<uart.h>
#include<intrins.h>
/*------------------------------------------------
 uS延时函数,含有输入参数 unsigned char t,无返回值
 unsigned char 是定义无符号字符变量,其值的范围是
 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
 长度如下 T=tx2+5 uS 
------------------------------------------------*/
/*-----------------------------
串口初始化程序;
-------------------------------*/
void UART_init(void)
{
	SCON = 0x50;
	TMOD = 0x21;
	TH1 = 0xfd;
	TL1 = 0xfd;
	TR1 = 1;
	EA = 1;
	ES = 1;
}
/*-----------------------------
串口发送程序;
-------------------------------*/
void UART_send_byte(char dat)	 //按发送字节
{
	SBUF = dat;					//发送
	while (TI == 0);			//等待发送完毕
	TI = 0;						//清发送完毕中断请求标志位 
}

void UART_Send_Str(unsigned char *buf) //按字符串发送
{
	while (*buf != '\0')
	{
		UART_send_byte(*buf++);
	}
} 

DHT11.h代码

#define uchar unsigned char
#define uint unsigned int

sbit Data = P1 ^ 6;
uchar rec_dat[9];
void DHT11_delay_us(uchar n)
{
    while (--n);
}
void DHT11_delay_ms(uint z)
{
    uint i, j;
    for (i = z; i > 0; i--)
        for (j = 110; j > 0; j--);
}
void DHT11_start()
{
    Data = 1;
    DHT11_delay_us(2);
    Data = 0;
    DHT11_delay_ms(30);
    Data = 1;
    DHT11_delay_us(30);
}
uchar DHT11_rec_byte()
{
    uchar i, dat = 0;
    for (i = 0; i < 8; i++)
    {
        while (!Data);
        DHT11_delay_us(8);
        dat <<= 1;
        if (Data == 1)
            dat += 1;
        while (Data);
    }
    return dat;
}
void DHT11_receive()
{
    uchar R_H, R_L, T_H, T_L, RH, RL, TH, TL, revise;
    DHT11_start();
    if (Data == 0)
    {
        while (Data == 0);
        DHT11_delay_us(40);
        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] = '0' + (RH / 10);
        rec_dat[1] = '0' + (RH % 10);
        rec_dat[2] = ' ';
        rec_dat[3] = ' ';

        //温度
        rec_dat[4] = '0' + (TH / 10);
        rec_dat[5] = '0' + (TH % 10);
        rec_dat[6] = ' ';
    }
}

DS1302.h代码

#ifndef __DS1302_H__
#define __DS1302_H__

//外部可调用时间数组,索引0~6分别为年、月、日、时、分、秒、星期
extern unsigned char DS1302_Time[];

void DS1302_Init(void);
void DS1302_WriteByte(unsigned char Command, Data);
unsigned char DS1302_ReadByte(unsigned char Command);
void DS1302_SetTime(void);
void DS1302_ReadTime(void);
#endif

uart.h代码

#ifndef __UART_H__
#define __UART_H__

void DelayUs2x( unsigned char t);
void DelayMs( int t);
void UART_init( void);
void UART_Send_Str( unsigned char *buf);

#endif


仿真示意图

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值