51项目分享:基于51单片机仓库环境检测系统
“我们不做一锤子买卖,只做技术成长的长期伙伴!”
目录
一、视频展示
二、项目简介
三、原理图设计
四、PCB硬件设计
五、程序设计
六、资料分享
一、视频展示
基于51单片机仓库环境检测系统 -视频分享
二、项目简介
题目:基于51单片机仓库环境检测系统
主控芯片 STC89C52RC
烟雾浓度传感器
温度传感器
光照传感器
蓝牙通信模块
蜂鸣器声光报警
继电器*4
按键*6
功能:自动模式和手动模式,自动模式下烟雾浓度过高自动打开继电器一模拟风扇,
温度过低打开继电器二模拟升温,过高则打开继电器三模拟降温。
当光照强度过低时则打开继电器四模拟补光灯 。
手动模式则可以手动打开以上继电器。通过蓝牙模块可以跟手机进行通信。
三、原理图设计

四、PCB硬件设计


五、程序设计
#include <reg52.h> //调用单片机头文件
#include <intrins.h>
#include "lcd1602.h"
#include "ds1302.h"
#include "uart.h"
#include "ds18b20.h"#define uchar unsigned char //无符号字符型 宏定义 变量范围0~255
#define uint unsigned int //无符号整型 宏定义 变量范围0~65535
extern unsigned char TIME[7];//按键引脚定义sbit ADCS = P2^1;
sbit ADCLK = P2^2;
sbit ADDI = P2^3;
sbit ADDO = P2^3;sbit BEEP = P2^4;sbit DEC = P1^4;
sbit MOD = P1^2;
sbit key5 = P1^1;
sbit SET = P1^5;
sbit ADD = P1^3;sbit key6 = P1^0;sbit jd1 = P3^3;
sbit jd2 = P3^4;
sbit jd3 = P3^5;
sbit jd4 = P3^6;uchar set_flag,add_flag,dec_flag,show_flag,MOD_flag,show1_flag,key5_flag,key6_flag;
uchar tu=40,gu=50,w=30,wd=5,i,jd11,t,g,p;
uchar last_temp;
extern uchar receive_data[8];
extern uint bytes;
extern uint bytes_old;//uchar mp3[] = {0xaa,0x00};
uchar len;//长度
uchar str[8];
int temperature = 0;//温度值
int temp_int,temp_dec;//温度的整数和小数
char temp_max = 40;
uchar IntToString(uchar *str,int changeDat){uchar len_str = 0,i = 0;//记录字符串的长度uchar temp_buf[6]; if(changeDat < 0){changeDat = -changeDat;//赋值为负数*str++ = '-';len_str++;}do{temp_buf[i++] = changeDat % 10;changeDat /= 10;}while(changeDat > 0);len_str = len_str + i;//得到最新的长度while(i--){*str++ = temp_buf[i] + '0';//对于转换成字符串}*str = '\0';//字符串接收标志位的添加return len_str;
}void show_temp(void)//温度显示
{bit ACK;ACK = getTempForDs18b20(&temperature); if(~ACK){temp_int = temperature >> 4;//取整数部分temp_dec = temperature & 0xf;//取小数部分len = IntToString(str,temp_int);str[len++] = '.';//添加一个小数点//处理小数部分temp_dec = (temp_dec * 10)/16;//二进制小数部分转换为十六进制str[len++] = temp_dec + '0';while(len < 3){str[len++] = ' ';}str[len] = '\0';
// lcd_write_str( 5,1,str);}startDs18b20();
// lcd_write_str(8,0,"temp:");
}uchar ADC0832(bit mode,bit channel) //AD转换,返回结果
{uchar i,dat,ndat;ADCS = 0;//拉低CS端_nop_();_nop_();ADDI = 1; //第1个下降沿为高电平ADCLK = 1;//拉高CLK端_nop_();_nop_();ADCLK = 0;//拉低CLK端,形成下降沿1_nop_();_nop_();ADDI = mode; //低电平为差分模式,高电平为单通道模式。 ADCLK = 1;//拉高CLK端_nop_();_nop_();ADCLK = 0;//拉低CLK端,形成下降沿2_nop_();_nop_();ADDI = channel; //低电平为CH0,高电平为CH1 ADCLK = 1;//拉高CLK端_nop_();_nop_();ADCLK = 0;//拉低CLK端,形成下降沿3ADDI = 1;//控制命令结束(经试验必需)dat = 0;//下面开始读取转换后的数据,从最高位开始依次输出(D7~D0)for(i = 0;i < 8;i++){dat <<= 1;ADCLK=1;//拉高时钟端_nop_();_nop_();ADCLK=0;//拉低时钟端形成一次时钟脉冲_nop_();_nop_();dat |= ADDO;}ndat = 0; //记录D0if(ADDO == 1)ndat |= 0x80;//下面开始继续读取反序的数据(从D1到D7) for(i = 0;i < 7;i++){ndat >>= 1;ADCLK = 1;//拉高时钟端_nop_();_nop_();ADCLK=0;//拉低时钟端形成一次时钟脉冲_nop_();_nop_();if(ADDO==1)ndat |= 0x80;} ADCS=1;//拉高CS端,结束转换ADCLK=0;//拉低CLK端ADDI=1;//拉高数据端,回到初始状态if(dat==ndat)return(dat);elsereturn 0;
}void key_scan(void)
{if(SET== 0)//设置键按下{ delay_ms(20);if(SET== 0){while(!SET);set_flag=1;lcd_clear();}}if(ADD == 0)//加键按下{delay_ms(20);if(ADD == 0){while(!ADD);add_flag = 1;}}if(DEC == 0)//减键按下{delay_ms(20);if(DEC == 0){while(!DEC);dec_flag = 1;}}if(MOD == 0)//减键按下{delay_ms(20);if(MOD == 0){while(!MOD);MOD_flag = 1;lcd_clear();}}if(key5 == 0)//减键按下{delay_ms(20);if(key5 == 0){while(!key5);key5_flag = 1;}}if(key6 == 0)//减键按下{delay_ms(20);if(key6 == 0){while(!key6);key6_flag = 1;}}
}void main()
{TMOD = 0x01; //定时器0工作方式1TH0 = 0xfc; //设置定时初值TL0 = 0x67;ET0 = 1; //允许定时器0中断EA = 1; //允许总中断TR0 = 1; //启动定时器0InitDS18B20ACK();lcd_init();//1602初始化uart_init();lcd_write_str(0,0,"smok:"); while(1){ t=(ADC0832(1,0)*100/256);if(0>=t){t=0;}g=100-(ADC0832(1,1)*100/256);show_temp();p=temp_int;if(p>100)p=last_temp;last_temp=p;key_scan();if (set_flag == 1){show_flag++;set_flag = 0;jd1=1;jd2=1;jd3=1;jd4=1;BEEP=1;if(show_flag==2){jd1=1;jd2=1;jd3=1;jd4=1;}if(show_flag==2){show_flag=0;}}if (show_flag == 0){if (MOD_flag == 1){MOD_flag = 0;show1_flag++;if(show1_flag==5){show1_flag=0;}}SendString("当前温度:");SendChar(p/100+'0');SendChar(p/10+'0');SendChar(p%10+'0');SendString("\r\n"); SendString("当前烟雾浓度:");SendChar(t/100+'0');SendChar((t%100)/10+'0');SendChar((t%100)%10+'0');SendString("\r\n");SendString("当前光照:");SendChar(g/100+'0');SendChar((g%100)/10+'0');SendChar((g%100)%10+'0');SendString("\r\n");SendString("\r\n");SendString("\r\n");SendString("\r\n");if(key6_flag==1){key6_flag=0;}if(key5_flag==1){key5_flag=0;}if(show1_flag==0){lcd_write_str(0,0,"smok:");lcd_write_char(5,0,t/100+'0');lcd_write_char(6,0,(t%100)/10+'0');lcd_write_char(7,0,(t%100)%10+'0');lcd_write_str(0,1,"Illu:");lcd_write_char(5,1,g/100+'0');lcd_write_char(6,1,(g%100)/10+'0');lcd_write_char(7,1,(g%100)%10+'0');lcd_write_str(8,0,"temp:");lcd_write_char(13,0,p/100+'0');lcd_write_char(14,0,p/10+'0');lcd_write_char(15,0,p%10+'0');lcd_write_str(12,1,"AUTO");}if(show1_flag==1){lcd_write_str(6,0,"smok");lcd_write_str(0,1,"XG:");lcd_write_char(3,1,tu/100+'0');lcd_write_char(4,1,(tu%100)/10+'0');lcd_write_char(5,1,(tu%100)%10+'0');if(dec_flag == 1){tu--;dec_flag=0;}if(add_flag == 1){tu++;add_flag = 0;}}if(show1_flag==2){lcd_write_str(2,0,"Illumination");lcd_write_str(0,1,"XG:");lcd_write_char(3,1,gu/100+'0');lcd_write_char(4,1,(gu%100)/10+'0');lcd_write_char(5,1,(gu%100)%10+'0');if(dec_flag == 1){gu--;dec_flag=0;}if(add_flag == 1){gu++;add_flag = 0;}}if(show1_flag==3){lcd_write_str(2,0,"TemperatureH");lcd_write_str(0,1,"XG:");lcd_write_char(3,1,w/100+'0');lcd_write_char(4,1,(w%100)/10+'0');lcd_write_char(5,1,(w%100)%10+'0');if(dec_flag == 1){w--;dec_flag=0;}if(add_flag == 1){w++;add_flag = 0;}}if(show1_flag==4){lcd_write_str(2,0,"TemperatureL");lcd_write_str(0,1,"XG:");lcd_write_char(3,1,wd/100+'0');lcd_write_char(4,1,(wd%100)/10+'0');lcd_write_char(5,1,(wd%100)%10+'0');if(dec_flag == 1){wd--;dec_flag=0;}if(add_flag == 1){wd++;add_flag = 0;}}
// tgp tu gu w wd// if(tu>=t || gu>=g || p>=w || wd>=p)
// BEEP=0;
// else
// BEEP=1;if(tu<=t)jd4=0;elsejd4=1;if(gu>=g)jd1=0;elsejd1=1;if(p>=w)jd3=0;elsejd3=1;if(wd>=p)jd2=0;elsejd2=1;if(tu<=t || gu>=g || p>=w || wd>=p){BEEP=0;SendString("环境异常!!!");}elseBEEP=1;}if (show_flag == 1){lcd_write_str(0,0,"Soil:");lcd_write_char(5,0,t/100+'0');lcd_write_char(6,0,(t%100)/10+'0');lcd_write_char(7,0,(t%100)%10+'0');lcd_write_str(0,1,"Illu:");lcd_write_char(5,1,g/100+'0');lcd_write_char(6,1,(g%100)/10+'0');lcd_write_char(7,1,(g%100)%10+'0');lcd_write_str(8,0,"temp:");lcd_write_char(13,0,p/100+'0');lcd_write_char(14,0,p/10+'0');lcd_write_char(15,0,p%10+'0');lcd_write_str(12,1,"MANU");if(MOD_flag==1) {jd1=~jd1;MOD_flag=0; }if(key5_flag==1){jd2=~jd2;key5_flag=0; }if(key6_flag==1){jd3=~jd3;key6_flag=0; }if(add_flag==1){jd4=~jd4;add_flag=0; }}}}
void timer0_int(void) interrupt 1
{uint i,j;TH0 = 0xfc; //重新设置定时初值TL0 = 0x67;i++;if(i == 800){i = 0;}if(j == 100){j = 0;}
}
void Com_Int(void) interrupt 4
{EA = 0;if(RI==1) //此句判断不能省略,否则发送数据时也会执行此语句,造成字符串错误!!!(RI为接收数据标志,当接收到数据自动置为1){RI=0;receive_data[bytes] = SBUF;//接收到的数据bytes++;} EA = 1;}
六、资料分享
点击即可查看当前资料分享。
