最近用手机做了51单片机驱动8266APP控制火灾报警功能的板。下面给大家介绍一下,有需要的朋友可以私信。
由于时间有限,我会慢慢更新这部分。
先上整体图

手机app截图
1.功能描述。
a、使用DS18B读取温度,并在app上显示。超过26度报警,报警灯亮,蜂鸣器响,app报警灯变红。
b、使用MQ-2.阅读烟雾浓度,并在app超过40ppm报警,报警灯亮,蜂鸣器响,app报警灯变红。
c、用120度火焰传感器感受火焰app报警。检测到火焰后,报警灯亮,蜂鸣器响,app报警灯变红。
d、上电后,手动模式指示灯在板上和app同时点亮绿灯。这时,可以手动操作app上按上 下 左 右按钮,控制光源跟踪板旋转;可按水泵按钮,控制水泵继电器吸合,然后控制水泵动作。
e、在app按下手动按钮,切换到自动模式,自动模式指示灯在板上app同时点亮,为绿灯。此时,光源跟踪板自动跟踪光源旋转,可用手电筒模拟;对准光源后,打开水泵;水泵工作10s之后,自动关闭。之后,流程循环进行。
硬件设计。
直接上图。
没什么好说的,看图就行了。
3.软件设计。
#include #include #include "math.H" #include #include "PCF8591.H" #define uchar unsigned char // 以后unsigned char就可以用uchar代替 #define uint unsigned int // 以后unsigned int 就可以用uint 代替 #define del 20//调速 #define ydl 20 //移动调节 #define PCF8591 0x90 //PCF8591 地址 sbit temp_led=P0^0; sbit smoke_led=P0^1; sbit fire_led=P0^2; sbit auto_led=P0^3; sbit manual_led=P0^4; sbit pump=P1^0; sbit fire1=P3^3; sbit fire2=P3^4; sbit fire3=P3^5; sbit fire4=P3^6; sbit fire5=P3^7; sbit DQ = P1^1; // 温度传感器的引脚 sbit ADC_CS = P1^2; // ADC0832的CS引脚 sbit ADC_CLK = P1^3; // ADC0832的CLK引脚 sbit ADC_DAT = P1^4; // ADC0832的DI/DO引脚 sbit Buzzer_P = P0^5; // 蜂鸣器 bit up_flag; bit down_flag; bit left_flag; bit right_flag; bit pump_flag; bit AM_flag=0; bit Auto_start; uchar Motor_Up[4]={0x08,0x04,0x02,0x01}; uchar Motor_Down[4]={0x01,0x02,0x04,0x08}; uchar Motor_Left[4]={0x10,0x20,0x40,0x80}; uchar Motor_Right[4]={0x80,0x40,0x20,0x10}; uchar AD_CHANNEL; uchar AD_Up,AD_Down,AD_Left,AD_Right; uint i; uchar dat[20]; uchar temp_flag; // 温度报警标志位 uchar smoke_flag; // 烟雾报警标志位 uchar fire_flag; // 火焰报警标志位 int temp; // 保存温度值 uchar smoke; // 保存烟雾值 uchar Smoke_Alarm=30; // 烟雾报警值 int Temp_Alarm=26; // 温度报警值 uint time_20ms=0;//定时器计数 bit disFlag ; //显示标志 unsigned char Recive_table[15]; /*********************************************************/ // 毫秒延迟函数,time毫秒数要延迟 /*********************************************************/ void DelayMs(uint time) { uint a,b; for(a=0;a
对于程序,我不做全部解释,有疑问的朋友可以私信或者评论。
我这里只把我遇到的问题说一下:
a、DS18B20读取温度程序。
如下
/*********************************************************/
// 读取温度值
/*********************************************************/
int DS18B20_ReadTemp(void)
{
uchar j;
int b,temp=0;
EA=0;
DS18B20_ReSet(); // 产生复位脉
DS18B20_WriteByte(0xcc); // 忽略ROM指令
DS18B20_WriteByte(0x44); // 启动温度转换指令
DS18B20_ReSet(); // 产生复位脉
DS18B20_WriteByte(0xcc); // 忽略ROM指令
DS18B20_WriteByte(0xbe); // 读取温度指令
for(j=0;j<16;j++) // 读取温度数量
{
DQ=0;
_nop_();
_nop_();
DQ=1;
Delay15us();
b=DQ;
Delay15us();
Delay15us();
Delay15us();
b=b<
在程序的开始和末尾最好加上EA=0和EA=1。就是禁用总中断和开启总中断。因为DS18B20对于时序很敏感,如果不加这两个命令,读取温度会出现乱码!
b、ATK-ESP8266发送数据时,组成字符串程序。
如下为组成字符串程序
void SendDat(int temp,uchar smoke)
{
dat[0]=(char)(temp%100/10)+48;//发送温度值的十位
dat[1]=(char)(temp%10)+48;//发送温度值的个位
dat[2]=(char)temp_flag+48;//发送温度值报警标志位
dat[3]=(char)fire_flag+48;//发送火焰报警标志位
dat[4]=(char)smoke_flag+48;//发送烟雾浓度报警标志位
dat[5]=(char)(smoke%100/10)+48;//发送烟雾浓度值的十位
dat[6]=(char)(smoke%10)+48;//发送烟雾浓度值的个位
}
如下为发送程序
SendDat(temp,smoke);
if(disFlag==1)
{
disFlag=0;
Uart_SendStrData("AT+CIPSEND=0,7\r\n");
DelayMs(5);
Uart_SendStrData(dat);
DelayMs(5);
}
组成字符串程序时,也可以用sprintf函数,比如:sprintf(dat,"%d%d%d%d%d%d",temp,(int)temp_flag,(int)fire_flag,(int)smoke_flag,(int)smoke);
如果这样写,不仅会增加代码总量大小,而且sprintf用不好的话会造成错误。所以建议使用如上的字符串组成程序。
c、初始化ATK-ESP8266时,在函数开头应该延时一段时间,让板子上电时,8266自己可以有个初始化过程,否则8266会出现错误,导致连接不上8266。
/*********************************************************/
// ATK-ESP8266初始化
/*********************************************************/
void Init_ESP01S(){
DelayMs(50);
Uart_SendStrData("AT+CIPMUX=1\r\n"); // ?????
DelayMs(5);
Uart_SendStrData("AT+CIPSERVER=1,8080\r\n"); // ?????,??8080??
DelayMs(5);
}
以上就是我的描述,想进一步了解的朋友私信我。谢谢!