基于STM32设计的车库监控报警系统
一、前言
随着社会的发展,人们的生活水平不断提高对安防问题的关注度越来越高,因而各类防盗设备也层出不穷,本文采用红外测距传感器、摄像头、STM32单片机以及ESP8266无线通信模块设计一种车库防盗报警器,其可安装在车库的里,通过红外线测距检测是否有人入侵,产生报警信号,提醒相关人员采取应急防御措施。该防盗报警器成本低,功能优,防盗效果好,是家居防盗的优良选择。
二、具体需求
(一)主要模块:密码锁开门模块+检测模块+报警模块+拍摄模块+主控制模块+传输存取模块
检测模块:红外测距传感器
报警模块:灯+蜂鸣器
拍摄模块:摄像头
传输存取模块:WIFI模块实现传输,用SD卡存取
主控制模块:TFT显示屏+主控制器(STM32单片机)
最后整体呈现方式:矩形的微型车库构造
主要用途:主要解决电瓶车在车库内被盗和电瓶车长时间充电引起火灾等不良安全隐患。
二、具体流程想法
一开始门(由能运转90°的舵机和一个小木板构建成的)和限位开关一直触碰着
(二)、输入正确密码进入车库:
门打开(即舵机运转90°,门和限位开关脱离)时,灯常亮,其他模块装置不运转;关闭车库门时,门没关紧(即门没有触碰到限位开关)时,通过WIFI模块发送信息至手机端,提醒门没关紧;门关紧后灯灭,报警系统全部正常运转。
(三)、不能输入正确密码反而也能进入车库:
不正常进入车库内时,当红外测距系统检测到人时,灯亮起和蜂鸣器响起,同时触发摄像装置,触发后的摄像装置会连续拍摄两次(注:红外测距系统没有检测到人,摄像装置是不运行的,以达到一个低功耗的目的,连续拍摄两次也可改为一次,两次是为了保证抓拍效果),拍摄的图片保存至存储模块,手机端也会收到报警信息和图片,提醒有非本人进入车库。
(四)拟所用器件
类型 | 数量 | 预期达到的效果 | 备注 |
---|---|---|---|
STM32F103 | 1 | 主控制系统 | |
TFT液晶屏 | 1 | 实现输入四位密码开门及调整红外测距的测距距离和查看图片、显示车库内的温度等 | |
LED灯 | 10个或以上 | ||
ov7670摄像头 | 2 | 两个摄像头同时拍摄 | |
温度传感器 | 1 | ||
一种转运90°的舵机 | 1 | 用于开关门装置 | |
限位开关 | 1 | 门是否关紧感应装置 | |
蜂鸣器 | 1 | ||
存储装置 | 1 | 存储图片 | |
WIFI模块 | 1 | ESP8266 | |
红外测距装置 | 1 | 可实现自主调整测距感应 | 做设置10cm测距调试 |
(五)、想象的液晶屏效果图
二、功能拆解
(1) 通过红外线测距模块(超声波代替),检测是否有人经过,如果有人经过就调用摄像头拍摄一张照片存放到SD卡保存,并通过ESP8266通知手机APP,有人闯入,手机APP会产生警报声。手机上可以设置报警检测的距离。
(2) 照片拍摄时,保存的文件名称以当前时间为准,需要用到开发板上的RTC时钟,也需要手机APP上增加一个时间校准功能,方便校准开发板上的RTC实时时钟的时间。
(3) 实时检测环境温湿度,将温湿度信息传递给手机APP显示
技术点:
- 需要移植FATFS文件系统,构建BMP图片结果,才能将摄像头拍摄的照片保存在SD卡里。
- 需要启动RTC,实时记录当前时间,当做系统时钟使用,,手机APP需要增加一个时间校准功能。
- 摄像头采用OV7670,通过SCCB时序交互,需要将采集的RGB数据编码成BMP图片存放到SD卡。
三、上位机开发
上位机采用QT框架开发,分别开发了Android、windows版本。
3.1 QT 框架简介
Qt是一个1991年由QtCompany开发的跨平台C++图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(Meta Object Compiler, moc))以及一些宏,Qt很容易扩展,并且允许真正地组件编程。
在发布 Qt 4.6 的同时,作为 Qt 开发跨平台 IDE 的Qt Creator也发布了更新版本。Qt Creator 1.3 和 Qt 4.6共同构成的 Qt SDK,包含了开发跨平台应用程序所需的全部功能。
Qt Creator是一个用于Qt开发的轻量级跨平台集成开发环境。Qt Creator可带来两大关键益处:提供首个专为支持跨平台开发而设计的集成开发环境 (IDE),并确保首次接触Qt框架的开发人员能迅速上手和操作。即使不开发Qt应用程序,Qt Creator也是一个简单易用且功能强大的IDE。
QT官网: https://resources.qt.io/cn
3.2 QT环境搭建
QT5.12.6安装包下载地址: https://download.qt.io/archive/qt/5.12/5.12.6/
QT学习专栏: https://blog.csdn.net/xiaolong1126626497/category_11400392.html
QT环境搭建文章:https://xiaolong.blog.csdn.net/article/details/120654599
3.3 软件运行效果
软件功能介绍:
(1)STM32端通过DHT11实时检测环境温湿度,通过红外测距传感器测量距离,通过ESP8266传递到手机APP上实时显示。
数据传输的格式:
$update,16,23,23.5
温度、湿度、测量的距离
(2)手机APP上可以设置红外报警检测距离,在手机页面上点击设置之后,会传递给STM32。
数据传输的格式:
#5 5的单位是厘米,表示设置5cm的检测距离。
当实际测量的距离小于了设置的报警距离,就会产生报警信息,手机APPA上会自动响起报警铃声。
(3)在STM32上有一个RTC时钟,需要实时记录当前时间,手机APP有一个时间校准按钮,点击之后,会校准STM32开发板上的时间。
数据通信格式:
*20220309114156 传递过去的就是年月日时分秒时间
下面是在win10系统下运行软件的效果。
下面是在Android系统下运行软件的效果。
3.4 模拟测试
现在先不连接设置设备,采用网络调试助手来模拟ESP8266+STM32,测试通信效果,通信过程是否正常。
左边是TCP调试助手,右边是上位机软件,可以使用TCP调试助手模拟ESP8266,与上位机之间通信。
(1)搭建模拟化环境
(2)温度、湿度、检测距离上传
数据格式协议:
上位机时间校准–向ESP8266发送:*20220309114156
上位机设置报警距离-向ESP8266发送:#5
ESP8266向上位机发送:
$update,16,23,23.5
温度、湿度、测量的距离
(3)APP设置报警距离
(4)APP报警提示演示
四、设备端开发
如果需要完整工程,可以去这里下载:
https://download.csdn.net/download/xiaolong1126626497/85894457
4.1 硬件效果图
4.2 OV7725摄像头核心代码
#include "sys.h"
#include "ov7725.h"
#include "ov7725cfg.h"
#include "timer.h"
#include "delay.h"
#include "usart.h"
#include "sccb.h" //JTAG模式设置,用于设置JTAG的模式
//mode:jtag,swd模式设置;00,全使能;01,使能SWD;10,全关闭;
//#define JTAG_SWD_DISABLE 0X02
//#define SWD_ENABLE 0X01
//#define JTAG_SWD_ENABLE 0X00
void JTAG_Set(u8 mode)
{u32 temp;temp=mode;temp<<=25;RCC->APB2ENR|=1<<0; //开启辅助时钟 AFIO->MAPR&=0XF8FFFFFF; //清除MAPR的[26:24]AFIO->MAPR|=temp; //设置jtag模式
}//初始化OV7725
//返回0:成功
//返回其他值:错误代码
u8 OV7725_Init(void)
{u16 i=0;u16 reg=0; //设置IORCC->APB2ENR|=1<<2; //先使能外设PORTA时钟RCC->APB2ENR|=1<<3; //先使能外设PORTB时钟RCC->APB2ENR|=1<<4; //先使能外设PORTC时钟RCC->APB2ENR|=1<<5; //先使能外设PORTD时钟RCC->APB2ENR|=1<<8; //先使能外设PORTG时钟 GPIOA->CRH&=0XFFFFFFF0; GPIOA->CRH|=0X00000008; //PA8 输入 GPIOA->ODR|=1<<8; GPIOB->CRL&=0XFFF00FFF; GPIOB->CRL|=0X00033000; //PB3/4 输出GPIOB->ODR|=3<<3; GPIOC->CRL=0X88888888; //PC0~7 输入 GPIOC->ODR|=0x00ff; GPIOD->CRL&=0XF0FFFFFF; //PD6 输出 GPIOD->CRL|=0X03000000; GPIOD->ODR|=1<<6; GPIOG->CRH&=0X00FFFFFF; GPIOG->CRH|=0X33000000; GPIOG->ODR=7<<14; //PG14/15 输出高 JTAG_Set(1);SCCB_Init(); //初始化SCCB 的IO口 if(SCCB_WR_Reg(0x12,0x80))return 1; //复位SCCB DelayMs(50); reg=SCCB_RD_Reg(0X1c); //读取厂家ID 高八位reg<<=8;reg|=SCCB_RD_Reg(0X1d); //读取厂家ID 低八位if(reg!=OV7725_MID){printf("MID:%d\r\n",reg);return 1;}reg=SCCB_RD_Reg(0X0a); //读取厂家ID 高八位reg<<=8;reg|=SCCB_RD_Reg(0X0b); //读取厂家ID 低八位if(reg!=OV7725_PID){printf("HID:%d\r\n",reg);return 2;} //初始化 OV7725,采用QVGA分辨率(320*240) for(i=0;i<sizeof(ov7725_init_reg_tb1)/sizeof(ov7725_init_reg_tb1[0]);i++){ SCCB_WR_Reg(ov7725_init_reg_tb1[i][0],ov7725_init_reg_tb1[i][1]);} return 0x00; //ok
}
//OV7725功能设置
//白平衡设置
//0:自动模式
//1:晴天
//2,多云
//3,办公室
//4,家里
//5,夜晚
void OV7725_Light_Mode(u8 mode)
{switch(mode){case 0: //Auto,自动模式SCCB_WR_Reg(0x13, 0xff); //AWB on SCCB_WR_Reg(0x0e, 0x65);SCCB_WR_Reg(0x2d, 0x00);SCCB_WR_Reg(0x2e, 0x00);break;case 1://sunny,晴天SCCB_WR_Reg(0x13, 0xfd); //AWB offSCCB_WR_Reg(0x01, 0x5a);SCCB_WR_Reg(0x02, 0x5c);SCCB_WR_Reg(0x0e, 0x65);SCCB_WR_Reg(0x2d, 0x00);SCCB_WR_Reg(0x2e, 0x00);break; case 2://cloudy,多云SCCB_WR_Reg(0x13, 0xfd); //AWB offSCCB_WR_Reg(0x01, 0x58);SCCB_WR_Reg(0x02, 0x60);SCCB_WR_Reg(0x0e, 0x65);SCCB_WR_Reg(0x2d, 0x00);SCCB_WR_Reg(0x2e, 0x00);break; case 3://office,办公室SCCB_WR_Reg(0x13, 0xfd); //AWB offSCCB_WR_Reg(0x01, 0x84);SCCB_WR_Reg(0x02, 0x4c);SCCB_WR_Reg(0x0e, 0x65);SCCB_WR_Reg(0x2d, 0x00);SCCB_WR_Reg(0x2e, 0x00);break; case 4://home,家里SCCB_WR_Reg(0x13, 0xfd); //AWB offSCCB_WR_Reg(0x01, 0x96);SCCB_WR_Reg(0x02, 0x40);SCCB_WR_Reg(0x0e, 0x65);SCCB_WR_Reg(0x2d, 0x00);SCCB_WR_Reg(0x2e, 0x00);break; case 5://night,夜晚SCCB_WR_Reg(0x13, 0xff); //AWB onSCCB_WR_Reg(0x0e, 0xe5);break;}
}
//色度设置
//sat:-4~+4
void OV7725_Color_Saturation(s8 sat)
{if(sat>=-4 && sat<=4){ SCCB_WR_Reg(USAT,(sat+4)<<4); SCCB_WR_Reg(VSAT,(sat+4)<<4);}
}
//亮度设置
//bright:-4~+4
void OV7725_Brightness(s8 bright)
{u8 bright_value,sign;switch(bright){case 4:bright_value = 0x48;sign = 0x06;break;case 3:bright_value = 0x38;sign = 0x06; break; case 2:bright_value = 0x28;sign = 0x06; break; case 1:bright_value = 0x18;sign = 0x06; break;case 0:bright_value = 0x08;sign = 0x06; break; case -1:bright_value = 0x08;sign = 0x0e; break; case -2:bright_value = 0x18;sign = 0x0e; break; case -3:bright_value = 0x28;sign = 0x0e; break; case -4:bright_value = 0x38;sign = 0x0e; break; }SCCB_WR_Reg(BRIGHT, bright_value);SCCB_WR_Reg(SIGN, sign);
}
//对比度设置
//contrast:-4~+4
void OV7725_Contrast(s8 contrast)
{if(contrast >= -4 && contrast <=4){SCCB_WR_Reg(CNST,(0x30-(4-contrast)*4));}
}
//特效设置
//0:普通模式
//1,负片
//2,黑白
//3,偏红色
//4,偏绿色
//5,偏蓝色
//6,复古
void OV7725_Special_Effects(u8 eft)
{switch(eft){case 0://正常SCCB_WR_Reg(0xa6, 0x06);//TSLB设置SCCB_WR_Reg(0x60, 0x80);//MANV,手动V值SCCB_WR_Reg(0x61, 0x80);//MANU,手动U值break;case 1://负片SCCB_WR_Reg(0xa6, 0x46);break;case 2://黑白SCCB_WR_Reg(0xa6, 0x26);SCCB_WR_Reg(0x60, 0x80);SCCB_WR_Reg(0x61, 0x80);break; case 3://偏红SCCB_WR_Reg(0xa6, 0x1e);SCCB_WR_Reg(0x60, 0x80);SCCB_WR_Reg(0x61, 0xc0); break;case 4://偏绿SCCB_WR_Reg(0xa6, 0x1e);SCCB_WR_Reg(0x60, 0x60);SCCB_WR_Reg(0x61, 0x60); break;case 5://偏蓝SCCB_WR_Reg(0xa6, 0x1e);SCCB_WR_Reg(0x60, 0xa0);SCCB_WR_Reg(0x61, 0x40); break;case 6://复古SCCB_WR_Reg(0xa6, 0x1e);SCCB_WR_Reg(0x60, 0x40);SCCB_WR_Reg(0x61, 0xa0);break; }
}
//设置图像输出窗口
//width:输出图像宽度,<=320
//height:输出图像高度,<=240
//mode:0,QVGA输出模式;1,VGA输出模式
//QVGA模式可视范围广但近物不是很清晰,VGA模式可视范围小近物清晰
void OV7725_Window_Set(u16 width,u16 height,u8 mode)
{u8 raw,temp;u16 sx,sy; if(mode){sx=(640-width)/2;sy=(480-height)/2;SCCB_WR_Reg(COM7,0x06); //设置为VGA模式SCCB_WR_Reg(HSTART,0x23); //水平起始位置SCCB_WR_Reg(HSIZE,0xA0); //水平尺寸SCCB_WR_Reg(VSTRT,0x07); //垂直起始位置SCCB_WR_Reg(VSIZE,0xF0); //垂直尺寸SCCB_WR_Reg(HREF,0x00);SCCB_WR_Reg(HOutSize,0xA0); //输出尺寸SCCB_WR_Reg(VOutSize,0xF0); //输出尺寸}else{sx=(320-width)/2;sy=(240-height)/2;SCCB_WR_Reg(COM7,0x46); //设置为QVGA模式SCCB_WR_Reg(HSTART,0x3f); //水平起始位置SCCB_WR_Reg(HSIZE, 0x50); //水平尺寸SCCB_WR_Reg(VSTRT, 0x03); //垂直起始位置SCCB_WR_Reg(VSIZE, 0x78); //垂直尺寸SCCB_WR_Reg(HREF, 0x00);SCCB_WR_Reg(HOutSize,0x50); //输出尺寸SCCB_WR_Reg(VOutSize,0x78); //输出尺寸}raw=SCCB_RD_Reg(HSTART);temp=raw+(sx>>2);//sx高8位存在HSTART,低2位存在HREF[5:4]SCCB_WR_Reg(HSTART,temp);SCCB_WR_Reg(HSIZE,width>>2);//width高8位存在HSIZE,低2位存在HREF[1:0]raw=SCCB_RD_Reg(VSTRT);temp=raw+(sy>>1);//sy高8位存在VSTRT,低1位存在HREF[6]SCCB_WR_Reg(VSTRT,temp);SCCB_WR_Reg(VSIZE,height>>1);//height高8位存在VSIZE,低1位存在HREF[2]raw=SCCB_RD_Reg(HREF);temp=((sy&0x01)<<6)|((sx&0x03)<<4)|((height&0x01)<<2)|(width&0x03)|raw;SCCB_WR_Reg(HREF,temp);SCCB_WR_Reg(HOutSize,width>>2);SCCB_WR_Reg(VOutSize,height>>1);SCCB_RD_Reg(EXHCH); temp = (raw|(width&0x03)|((height&0x01)<<2)); SCCB_WR_Reg(EXHCH,temp);
}
4.3 ESP8266核心代码
#include "esp8266.h"
u8 ESP8266_IP_ADDR[16]; //255.255.255.255
u8 ESP8266_MAC_ADDR[18]; //硬件地址
/*
函数功能: ESP8266命令发送函数
函数返回值:0表示成功 1表示失败
*/
u8 ESP8266_SendCmd(char *cmd)
{u8 i,j;for(i=0;i<10;i++) //检测的次数--发送指令的次数{USARTx_StringSend(USART3,cmd);for(j=0;j<5;j++) //等待的时间{delay_ms(50);if(USART3_RX_FLAG){USART3_RX_BUFFER[USART3_RX_CNT]='\0';USART3_RX_FLAG=0;USART3_RX_CNT=0;if(strstr((char*)USART3_RX_BUFFER,"OK")){return 0;}}}}return 1;
}/*
函数功能: ESP8266硬件初始化检测函数
函数返回值:0表示成功 1表示失败
*/
u8 ESP8266_Init(void)
{USARTx_StringSend(USART3,"+++");delay_ms(50);return ESP8266_SendCmd("AT\r\n");
}/*
函数功能: 一键配置WIFI为AP+TCP服务器模式
函数参数:
char *ssid 创建的热点名称
char *pass 创建的热点密码 (最少8位)
u16 port 创建的服务器端口号
函数返回值: 0表示成功 其他值表示对应错误值
*/
u8 ESP8266_AP_TCP_Server_Mode(char *ssid,char *pass,u16 port)
{char *p;u8 i;char ESP8266_SendCMD[100]; //组合发送过程中的命令/*1. 测试硬件*/if(ESP8266_SendCmd("AT\r\n"))return 1;/*2. 关闭回显*/if(ESP8266_SendCmd("ATE0\r\n"))return 2;/*3. 设置WIFI模式*/if(ESP8266_SendCmd("AT+CWMODE=2\r\n"))return 3;/*4. 复位*/ESP8266_SendCmd("AT+RST\r\n");delay_ms(1000);delay_ms(1000);delay_ms(1000);/*5. 关闭回显*/if(ESP8266_SendCmd("ATE0\r\n"))return 5;/*6. 设置WIFI的AP模式参数*/sprintf(ESP8266_SendCMD,"AT+CWSAP=\"%s\",\"%s\",1,4\r\n",ssid,pass);if(ESP8266_SendCmd(ESP8266_SendCMD))return 6;/*7. 开启多连接*/if(ESP8266_SendCmd("AT+CIPMUX=1\r\n"))return 7;/*8. 设置服务器端口号*/sprintf(ESP8266_SendCMD,"AT+CIPSERVER=1,%d\r\n",port);if(ESP8266_SendCmd(ESP8266_SendCMD))return 8;/*9. 查询本地IP地址*/if(ESP8266_SendCmd("AT+CIFSR\r\n"))return 9;//提取IP地址p=strstr((char*)USART3_RX_BUFFER,"APIP");if(p){p+=6;for(i=0;*p!='"';i++){ESP8266_IP_ADDR[i]=*p++;}ESP8266_IP_ADDR[i]='\0';}//提取MAC地址p=strstr((char*)USART3_RX_BUFFER,"APMAC");if(p){p+=7;for(i=0;*p!='"';i++){ESP8266_MAC_ADDR[i]=*p++;}ESP8266_MAC_ADDR[i]='\0';}//打印总体信息printf("当前WIFI模式:AP+TCP服务器\r\n");printf("当前WIFI热点名称:%s\r\n",ssid);printf("当前WIFI热点密码:%s\r\n",pass);printf("当前TCP服务器端口号:%d\r\n",port);printf("当前TCP服务器IP地址:%s\r\n",ESP8266_IP_ADDR);printf("当前TCP服务器MAC地址:%s\r\n",ESP8266_MAC_ADDR);return 0;
}/*
函数功能: TCP服务器模式下的发送函数
发送指令:
*/
u8 ESP8266_ServerSendData(u8 id,u8 *data,u16 len)
{u8 i,j,n;char ESP8266_SendCMD[100]; //组合发送过程中的命令for(i=0;i<10;i++){sprintf(ESP8266_SendCMD,"AT+CIPSEND=%d,%d\r\n",id,len);USARTx_StringSend(USART3,ESP8266_SendCMD);for(j=0;j<10;j++){delay_ms(50);if(USART3_RX_FLAG){USART3_RX_BUFFER[USART3_RX_CNT]='\0';USART3_RX_FLAG=0;USART3_RX_CNT=0;if(strstr((char*)USART3_RX_BUFFER,">")){//继续发送数据USARTx_DataSend(USART3,data,len);//等待数据发送成功for(n=0;n<200;n++){delay_ms(50);if(USART3_RX_FLAG){USART3_RX_BUFFER[USART3_RX_CNT]='\0';USART3_RX_FLAG=0;USART3_RX_CNT=0;if(strstr((char*)USART3_RX_BUFFER,"SEND OK")){return 0;}} } }}}}return 1;
}
4.4 main函数逻辑代码
#include "stm32f10x.h"
#include "delay.h"
#include "usart.h"
#include "key.h"
#include "led.h"
#include "ff.h"
#include "timer.h"
#include "dht11.h"
#include "rtc.h"
#include "esp8266.h"
#include "ov7725.h"
#include "bmp.h"
#include "sdcard.h"
#include <string.h>
#include <stdlib.h>/*
硬件连接:(1) ESP8266 WIFI
PB10--->ESP8266-RX
PB11--->ESP8266-TX
3.3v--->VCC
GND---->GND(2) DHT11 温湿度传感器
PA5 ---->DHT11-OUT
3.3v---->VCC
GND----->GND(3) SD卡接线
PC11 片选 SDCardCS
PC12 时钟 SDCardSCLK
PD2 输出 SPI_MOSI--主机输出从机输入
PC8 输入 SPI_MISO--主机输入从机输出(4) OV7725摄像头接线OV7725_VSYNC----PA8 //同步信号检测IO
OV7725_WRST-----PD6 //写指针复位
OV7725_WREN-----PB3 //写入FIFO使能
OV7725_RCK------PB4 //读数据时钟
OV7725_RRST-----PG14 //读指针复位
OV7725_CS-------PG15 //片选信号(OE)
SCCB_SCL--------PD3 //SCL
SCCB_SDA--------PG13 //SDA
PC0~7 ----------输入 (5) 报警灯、车库灯接线(6) 红外测距模块接线(7) 板载LED灯
硬件连接: PB5 PE5
PF11--照明灯(8) 板载按键
K1: PA0
K2: PE3
K3: PE4*/FATFS FatFs;
u8 DHT11_temp; //温度
u8 DHT11_humi; //湿度
u32 length_cm; //距离长度
u32 warning_length_cm=20; //报警距离
u8 photograph_flag=0; //拍照标志 1需要拍照 0不需要拍照
u16 color_line_rgb[320]; //存放一行的数据//数据发送缓冲区
char esp8266_send_buff[200];//RTC时间更新
void rtc_time_update(char *buff)
{char *time;/*判断是否收到客户端发来的数据 */char *p=strstr((char*)buff,"+IPD");if(p!=NULL) //正常数据格式: +IPD,0,7:LED1_ON +IPD,0表示第0个客户端 7:LED1_ON表示数据长度与数据{/*解析上位机发来的数据*/p=strstr((char*)buff,":");if(p!=NULL){p+=1; //向后偏移1个字节if(*p=='*') //设置RTC时间{p+=1; //向后偏移,指向正确的时间time=p;calendar.w_year=(time[0]-48)*1000+(time[1]-48)*100+(time[2]-48)*10+(time[3]-48)*1;calendar.w_month=(time[4]-48)*10+(time[5]-48)*1;calendar.w_date=(time[6]-48)*10+(time[7]-48)*1;calendar.hour=(time[8]-48)*10+(time[9]-48)*1;calendar.min=(time[10]-48)*10+(time[11]-48)*1;calendar.sec=(time[12]-48)*10+(time[13]-48)*1;RTC_Set(calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);printf("时间设置成功:%s\r\n",buff);}}}
}extern u8 ov_sta;FIL file;//更新LCD显示(OV7725)
void OV7725_camera_refresh(void)
{u32 i,j;u16 color; if(ov_sta)//有帧中断更新{if(photograph_flag){//获取照片名称sprintf(esp8266_send_buff,"0:%d-%d-%d-%d-%d-%d.bmp",calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);printf("拍照的照片名称:%s\r\n",esp8266_send_buff);file=photograph_open((u8*)esp8266_send_buff,320,240);}OV7725_RRST=0; //开始复位读指针 OV7725_RCK_L;OV7725_RCK_H;OV7725_RCK_L;OV7725_RRST=1; //复位读指针结束 OV7725_RCK_H; for(i=0;i<240;i++){for(j=0;j<320;j++){OV7725_RCK_L;color=GPIOC->IDR&0XFF; //读数据OV7725_RCK_H; color<<=8; OV7725_RCK_L;color|=GPIOC->IDR&0XFF; //读数据OV7725_RCK_H; color_line_rgb[j]=color; //保存颜色数据}//如果需要拍照if(photograph_flag){photograph_write(file,color_line_rgb); }}//关闭文件if(photograph_flag){photograph_close(file); }ov_sta=0; //清零帧中断标记photograph_flag=0; //清除标志}
}/*
功 能:外部中断初始化配置
参 数:
u8 u8 GPIOx:那一个GPIO口
u8 IRQLine :中断线
u8 RF_TSR :边沿触发方式
*///以下定义外部中断触发方式
#define EXTI_RTSRFTSR 2 //双
#define EXTI_RTSR 1 //上升
#define EXTI_FTSR 0 //下降//定义外部中断的IO口编号
#define EXTI_GPIOA 0
#define EXTI_GPIOB 1
#define EXTI_GPIOC 2
#define EXTI_GPIOD 3
#define EXTI_GPIOE 4
#define EXTI_GPIOF 5
#define EXTI_GPIOG 6void ExtiInitConfig(u8 GPIOx,u8 IRQLine,u8 RF_TSR)
{u8 exticnt=IRQLine/4; //得到数组的下标u8 extiline=(IRQLine%4)*4; //得到向左移位的位置/*1. 开放来自IRQLine线上的中断请求;*/EXTI->IMR|=1<<IRQLine;/*2. 配置边沿触发方式*/if(RF_TSR==EXTI_RTSR)EXTI->RTSR|=1<<IRQLine; //上升if(RF_TSR==EXTI_FTSR)EXTI->FTSR|=1<<IRQLine; //下降if(RF_TSR==EXTI_RTSRFTSR){EXTI->RTSR|=1<<IRQLine; EXTI->FTSR|=1<<IRQLine;}/*3. 开启AFIO时钟*/RCC->APB2ENR|=1<<0;/*4. 配置外部中断寄存器*/AFIO->EXTICR[exticnt]&=~(0xf<<extiline); AFIO->EXTICR[exticnt]|=GPIOx<<extiline; if(IRQLine==0)STM32_SetPriority(EXTI0_IRQn,1,1); else if(IRQLine==1)STM32_SetPriority(EXTI0_IRQn,1,1); else if(IRQLine==2)STM32_SetPriority(EXTI0_IRQn,1,1); else if(IRQLine==3)STM32_SetPriority(EXTI0_IRQn,1,1); else if(IRQLine==4)STM32_SetPriority(EXTI0_IRQn,1,1); else if(IRQLine>4 && IRQLine<10)STM32_SetPriority(EXTI9_5_IRQn,1,1); else if(IRQLine>9 && IRQLine<16)STM32_SetPriority(EXTI15_10_IRQn,1,1);
}u8 ov_sta; //帧中断标记//外部中断5~9服务程序
void EXTI9_5_IRQHandler(void)
{ if(EXTI->PR&(1<<8)) //是8线的中断{ if(ov_sta==0){OV7725_WRST=0; //复位写指针 OV7725_RCK_L;OV7725_RCK_H; OV7725_WRST=1; OV7725_WREN=1; //允许写入FIFO ov_sta++; //帧中断加1 }else OV7725_WREN=0;//禁止写入FIFO }EXTI->PR=1<<8; //清除LINE8上的中断标志位
} extern u8 XKC_KL200_BUFF[20];
extern u8 XKC_KL200_CNT;
extern u8 XKC_KL200_RX_FLAG;
extern u8 XKC_KL200_RX_OK_FLAG;int main()
{u32 time_cnt=0;u8 key;u8 XKC_KL200_START_FLAG=0;LED_Init();KEY_Init();USART1_Init(115200);USART3_Init(115200); //串口-WIFIUSART2_Init(115200); //红外线测距TIMER3_Init(72,20000); //超时时间20msDHT11_Init(); //初始化DHT11if(SDCardDeviceInit())//检测不到SD卡{printf("SDCard_DeviceInit 错误.\r\n");}else{printf("SDCard_DeviceInit 成功.\r\n");}f_mount(&FatFs, "0:", 0); //注册工作区并初始化SD卡printf("正在初始化WIFI请稍等.\r\n");//初始化WIFI硬件if(ESP8266_Init()){printf("WIFI硬件错误.\n");}else{//配置WIFI的模式printf("WIFI配置状态:%d\n",ESP8266_AP_TCP_Server_Mode("esp8266_666","12345678",8089));}//摄像头初始if(OV7725_Init()!=0){printf("OV7725摄像头初始失败.\r\n");}else{printf("OV7725摄像头初始成功.\r\n");}OV7725_CS=0;ExtiInitConfig(EXTI_GPIOA,8,EXTI_RTSR);//外部中断8 上升沿触发RTC_Init();//RTC初始化,一定要初始化成功// while(1)
// {// //扫描按键
// key=KEY_Scan(0);
//
// //
// if(key)
// {// printf("按键%d按下.\r\n",key);
// //
// // XKC_KL200_START_FLAG=1;
// //LED3=1;
// //length_cm=666;
// }
//
// }
// while(1){ //ESP8266 WIFI 返回的数据if(USART3_RX_FLAG){USART3_RX_BUFFER[USART3_RX_CNT]='\0';printf("%s",USART3_RX_BUFFER);//解析WIFI返回的数据//如果是设置报警距离. length_cm if(strstr((char*)USART3_RX_BUFFER,":#")){char *p=strstr((char*)USART3_RX_BUFFER,":#");//设置报警距离warning_length_cm=atoi(p+2);printf("报警距离设置成功:%s,%d\r\n",p+2,warning_length_cm);}//如果是校准RTC时间 +IPD,0,15:*20220304220552else if(strstr((char*)USART3_RX_BUFFER,":*")){printf("校准时间.\r\n");rtc_time_update((char*)USART3_RX_BUFFER);}USART3_RX_CNT=0;USART3_RX_FLAG=0;}//扫描按键key=KEY_Scan(0);if(key==2){printf("按键%d按下.启动系统\r\n",key);//启动系统,关闭照明灯XKC_KL200_START_FLAG=1;LED3=1;length_cm=666;}else if(key==3){//关闭系统,开启照明灯printf("按键%d按下.关闭系统\r\n",key);//XKC_KL200_START_FLAG=0;LED3=0;}//得到红外测距的距离if(XKC_KL200_RX_OK_FLAG && XKC_KL200_START_FLAG){//开始计算距离length_cm=(XKC_KL200_BUFF[5]<<8|XKC_KL200_BUFF[6])/10.0; //清除接收标志XKC_KL200_RX_FLAG=0;XKC_KL200_CNT=0;XKC_KL200_RX_OK_FLAG=0;}//判断距离,检测是否有人闯入if(length_cm<warning_length_cm){//启动拍照photograph_flag=1;}//轮询时间time_cnt++;delay_ms(10);if(time_cnt>=50){//读取温湿度数据DHT11_Read_Data(&DHT11_temp,&DHT11_humi);printf("温度:%d,湿度:%d\r\n",DHT11_temp,DHT11_humi);//拼接数据格式sprintf(esp8266_send_buff,"$update,%d,%d,%d",DHT11_temp,DHT11_humi,length_cm);//发送给上位机ESP8266_ServerSendData(0,(u8*)esp8266_send_buff,strlen((char*)esp8266_send_buff));printf("发送:%s\r\n",esp8266_send_buff);time_cnt=0;LED1=!LED1;LED2=!LED2;}}
}
基于STM32设计的车库监控报警系统相关推荐
- 单片机课程设计:基于STM32的温湿度检监测报警系统的设计
基于STM32的温湿度检监测报警系统 文章目录 基于STM32的温湿度检监测报警系统 前言 一.设计任务 二.系统硬件设计 1.元器件选用 2.系统模型设计 3.硬件连接 二.系统程序设计 1.程序流 ...
- 基于STM32设计的健康检测设备(测温心率计步)
1. 项目介绍 本文介绍的项目是基于STM32设计的健康检测设备,支持体温测量,心率检测,支持运动计步(采用MPU6050陀螺仪实现),支持WIFI传输数据到手机APP打印显示. 硬件环境介绍: MC ...
- 基于STM32设计的指针式电子钟与万年历
1. 项目简介 这是基于STM32设计的一个指针式电子钟+万年历小项目,采用3.5寸的LCD屏显示时钟,日历.温度.天气,支持触摸屏调整设置时间,设置闹钟,查看日历等等.整体项目主要是技术点就是LCD ...
- 基于STM32设计的小说阅读器(翻页、字体切换、颜色切换、语音播报)
一.环境介绍 小车主控MCU: STM32F103ZET6 STM32程序开发IDE: keil5 STM32程序风格: 采用寄存器方式开发,注释齐全,执行效率高,方便移植 硬件包含: 一块STM ...
- 基于STM32设计的人体健康监护系统(华为云IOT)
一.设计需求 1.1 设计需求总结 根据需求,要求设计一款基于 STM32 的人体健康监护系统.采用系统模块化思路进行,将多个数模传感器收集到的数据和操作指令一并送至 STM32 中心处理器进行处理分 ...
- 基于STM32设计的老人监护系统
一.设计需求 1.1 项目背景 21世纪以来,随着科技的发展,在人们的生活水平不断的提升的同时中国老龄化人口问题日益严重,再加上社会经济的发展.许多子女外出打工,使得越来越多的空巢老人得不到及时有效的 ...
- 基于at89c52单片机温湿度c语言,基于AT89C52单片机的温度监控报警系统的设计
本系统由无线发射与接收模块.语音播报.温度采集.自动报警以及显示模块组成.实现功能:温度实时显示:可设定温度的上限和下限,当温度超过设定域值时发出声光报警信号:测量温度值可通过语音播报:通过射频模块完 ...
- 基于STM32设计的青少年学习监控系统(华为云IOT)
一.设计需求 1.1 项目背景 近几年,我国儿童青少年的近视发生率越来越高,生活中总会看到许多小小年纪就戴着眼镜的小朋友.家长对孩子的用眼时间没有约束,电子产品对孩子眼睛的影响,写字姿势,有的孩子写字 ...
- 基于STM32设计的城市绿化云端监控系统(华为云IOT)
一.设计需求 1.1 项目背景 随着科技的蓬勃发展改变了很多传统行业的作业方式,当我们用移动支付代替现金交易时,当我们足不出户就能满足饥饿的身体时,我们的生活方式因为科技而发生了改变:同样科技也在改变 ...
- 基于STM32设计的老人防摔倒报警设备(OneNet)
1. 前言 我国独生子女,以及人口老龄化等问题,正逐渐成为一个重大的社会问题,老年人机体能力的下降,摔倒引起的安全和危害愈来愈突出,国家和社会越来越关注老年人的健康和安全,开发一个能够实时检测出老年人 ...
最新文章
- 如何判断java对象是否为String数组
- php 词法分析,【PHP7源码学习】2019-03-20 PHP词法分析
- MATLAB 线型 颜色 和 标记点组合使用
- ThinkJs笔记琐碎
- html可以用坐标画svg图吗,HTML5如何使用SVG的方法示例
- 在VS工程中添加lib库的三种方法
- nginx nodejs环境配置_nginx的脚本特性-nginScript笔记
- 计算机考研地域重要还是学校,考研选学校,城市更重要还是专业更重要?
- 软件基本功:数组赋值,一定要对齐
- java myqq ui,MYQQ JAVA语言开发的QQ聊天系统,可以添加,删除,好友,支持在线,离线发送消 能 文 ICQ-IM-Chat 238万源代码下载- www.pudn.com...
- 电路matlab仿真,matlab电路仿真.doc
- 解决win10分辨率过高导致某些软件显示小的办法
- JavaScript 编程精解 中文第三版 五、高阶函数
- Pymol中如何显示stick+cartoon+surface
- 获取html元素的高,获取HTML元素的高度jQuery
- 北斗通讯协议4.0 java_北斗4.0协议讲解.doc
- 微信登录(微信公众号授权)的开发(详解)
- 湖人詹姆斯 戴维斯 拉塞尔三人合体就赢!
- 龙光集团布局广州,以龙光·天皓为业主拾起温度
- C++ list及数组中数字相连输出问题