基于STM32单片机的车内红外震动有人监控拍照系统设计
1、项目简介
- 系统构成:本设计由STM32单片机电路+TFT屏幕+ov7670摄像头电路+SD卡存储电路+重量检测+红外检测+震动检测+蜂鸣器报警电路+短信报警电路+电源电路组成。
1.1 系统功能
- 功能介绍:
- 1、系统具有相机的基本功能
- 2、系统检测到车门未关闭时进行震动和座椅是否有人检测
- 3、当检测到有震动或座椅上有人时,系统触发拍照功能。
- 4、STM32单片机通过将摄像头拍摄的照片存储在SD卡中。
- 5、拍照完成后,向车主发送报警短信,同时使用蜂鸣器报警。
1.2 演示视频
2、部分电路设计
2.1 STM32单片机核心板电路设计
- 基于 ARM Cortex-M3内核的STM32F1系列单片机属于主流STM32单片机,其中增强型STM32F103子系列单片机的CPU 主频高达72MHz,片内Flash容量高达1MB,芯片引脚数量多达144个,有 QFN、LQFP、CSP、BGA 等多种芯片封装形式,并具有多种片内外设、USB接口和CAN 接口。根据STM32F103单片机片内Flash容量的不同,ST 公司将其分为小容量(16-32KB)、中等容量(64-128KB)、大容量(256KB-1MB)3种。
- 电源电路:为单片机提供稳定的工作电压,通常采用3.3V电源供电。电源电路的设计要保证单片机在不同工作条件下都能获得稳定的电压输出,以确保单片机的正常工作。
- 晶振电路:提供单片机工作所需的时钟信号。晶振电路通过晶振和电容组成,为单片机提供稳定的工作脉冲,确保单片机的定时和同步需求。
- 复位电路:实现单片机的复位功能,类似于电脑的重启。复位电路通过电容和电阻的配合,实现单片机在上电启动时的自动复位,以及通过手动按键实现复位功能,保证单片机在程序跑飞或异常情况下能够重新开始执行程序。
STM32单片机是一种功能强大、易于使用、灵活且可靠的32位微控制器,基于ARM Cortex™-M内核。其主要功能特点包括:
- 高性能和低功耗:STM32系列单片机提供多种内核选择,如Cortex-M0、Cortex-M3、Cortex-M4等,满足不同应用场景对性能的需求,同时保持低功耗特性。
- 多种通信和外设接口:STM32单片机具备广泛的通信和外设接口,如I2C、SPI、USART、USB等,便于开发者实现各种复杂功能。
- 易于开发和调试:STM32单片机提供了丰富的软件和硬件工具,如HAL库、CubeMX等,帮助开发者快速创建和调试嵌入式系统。
- 高集成度和设计灵活性:STM32系列单片机全系列产品共用大部分引脚、软件和外设,优异的兼容性为开发人员带来最大的设计灵活性
单片机最小系统原理图如下图所示:
2.2 ov7670摄像头电路设计
- OV7670/OV7171 CAMERACHIPTM图像传感器,体积小、工作电压低,提供单片VGA摄像头和影像处理器的所有功能。通过SCCB 总线控制,可以输出整帧、子采样、取窗口等方式的各种分辨率8位影响数据。该产品VGA图像最高达到30帧/秒。用户可以完全控制图像质量、数据格式和传输方式。所有图像处理功能过程包括伽玛曲线、白平衡、饱和度、色度等都可以通过SCCB接口编程。
- OmmiVision 图像传感器应用独有的传感器技术,通过减少或消除光学或电子缺陷如固定图案噪声、托尾、浮散等,提高图像质量,得到清晰的稳定的彩色图像。
其具体电路原理图如下图所示:
实物图如下:
2.3 HX711压力重力检测电路设计
- HX711是一款专为高精度电子秤而设计的24 位A/D 转换器芯片。与同类型其它芯片相比,该芯片集成了包括稳压电源、片内时钟振荡器等其它同类型芯片所需要的外围电路,具有集成度高、响应速度快、抗干扰性强等优点。降低了电子秤的整机成本,提高了整机的性能和可靠性。
将采集到的AD电压值准换为重力值
- 假设重力为 A Kg,(x<5Kg),测量出来的 AD 值为 y 传感器输出,发送给 AD 模块儿的电压为 A Kg * 4.3mV / 5Kg = 0.86A mV 经过 128 倍增益后为 128 * 0.86A = 110.08AmV 转换为 24bit 数字信号为 110.08A mV * 224 / 4.3V = 429496.7296A 所以 y = 429496.7296A 因此得出 A = y / 429496.7296 。
- 所以得出程序中计算公式 Weight_Shiwu = (unsigned long)((float)Weight_Shiwu/429.5);
- 特别注意: 因为不同的传感器斜率特性曲线不是完全一样,因此,每一个传感器需要矫正这里的 429.5 这个除数,才能达到精度很高。
- #define GapValue 430
- 当发现测试出来的重量偏大时,增加该数值。 如果测试出来的重量偏小时,减小改数值。该值可以为小数,例如 429.5 等。
具体电路原理图如下图所示:
实物图:
2.4 sim900A GSM短信报警电路
- SIM900A模块是一款由SIMCom公司生产的GSM/GPRS无线通信模块,支持语音、短信和数据传输等多种功能。 该模块采用高性价比的设计,支持双频GSM/GPRS网络(900/1800MHz),具备低功耗、高性能的特点。SIM900A模块支持RS232和LVTTL串口,工作电压范围广泛(5V~24V),便于与各种设备连接。其硬件结构包括嵌入式ARM处理器、GSM/GPRS调制解调器、SIM卡插槽、天线接口、串口和GPIO等,通过AT指令集进行控制,可以实现发送短信、接听电话、建立GPRS连接等功能。SIM900A模块的应用非常广泛,包括但不限于物联网、远程监控、物流管理、车辆定位和安防系统等领域,因其体积小、功耗低、稳定性高的特点,非常适合嵌入式系统的应用。
优点:
- 稳定可靠:SIM900A模块采用高质量的GSM/GPRS芯片和先进的射频技术,能够稳定地连接到移动网络,具有良好的信号质量和通信稳定性。
- 灵活易用:SIM900A模块支持标准的AT指令集,可以通过串口控制模块的各种功能,使用方便,上手快。
- 低功耗高性能:SIM900A模块采用低功耗设计,能够在省电模式下工作,同时具有高性能的数据处理和通信速度。
- 成本低廉:相对于其他移动通信模块,SIM900A模块的成本相对较低,适合各种中小型应用场景。
其具体电路原理图如下图所示:
实物图:
2.5 SDIO TF卡座电路设计
- SDIO接口是在SD内存卡接口的基础上发展起来的接口,SDIO接口兼容以前的SD内存卡,并且可以连接SDIO接口的设备
- SDIO总线和USB总线类似,SDIO总线也有两端,其中一端是主机(HOST)端,另一端是设备端(DEVICE),采用HOST- DEVICE这样的设计是为了简化DEVICE的设计,所有的通信都是由HOST端发出命令开始的。在DEVICE端只要能解析HOST的命令,就可以同HOST进行通信了,SDIO的HOST可以连接多个DEVICE。
- SDIO的信号传输模式有SPI、1-bit、4-bit三种。在SPI模式中,第8脚位被当成中断信号。其它脚位的功能和通信协定与SD记忆卡的标准规范一样。在SDIO总线定义中,DAT1信号线复用为中断线。在SDIO的1BIT模式下DAT0用来传输数据,DAT1用作中断线。在SDIO的4BIT模式下DAT0-DAT3用来传输数据,其中DAT1复用作中断线。
电路原理图:
实物图:
3、单片机代码展示
3.1 系统初始化
void HardWare_Init(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
delay_init(168); //延时函数初始化
LED_Init(); //初始化与LED连接的硬件接口
uart_init(9600);
HX711Init(); //称重模块初始化
KEY_Init(); //初始化红外探头
SPI1_Init(); //初始化SPI1总线
SPI1_SetSpeed(SPI_BaudRatePrescaler_2);//设置为18M时钟,高速模式
Lcd_Init(); //LCD 初始化
SPI_Flash_Init(); //FLASH 片选io CS 初始化
XPT2046_Init(); //触摸芯片XPT2046 io配置
OV_Gpio_Init();
GUI_Clear(White); //清屏
pf_mount(&fatfs); //初始化petit FATFS文件系统 并提取tf卡相应数据
check_system();
Ov_Photograph(); //进入ov照相机
}
3.2 TFT屏幕初始化
void Lcd_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO结构体
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOE, ENABLE);//使能PC,PB,PE时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; //端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_2|GPIO_Pin_4;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_2|GPIO_Pin_4|GPIO_Pin_6;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_ResetBits(GPIOE,GPIO_Pin_6);
}
3.3 OV7670摄像头初始化
void OV_Gpio_Init(void) // OV相应IO初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOD, ENABLE); //使能相关端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; // 输入 上拉
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_1|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7; // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = 0xff00; // 输入 上拉
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输入模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOD, &GPIO_InitStructure);
SCCB_Init();
}
u8 OV_Init(void)
{
u8 temp;
u16 i=0;
//初始化SCCB 的IO口
if(SCCB_WR_Reg(0x12,0x80)==0) return 1; //复位SCCB
delay_ms(50);
//读取产品型号
temp=SCCB_RD_Reg(0x0b);
if(temp!=0x73) return 2;
temp=SCCB_RD_Reg(0x0a);
if(temp!=0x76) return 2;
//初始化序列
for(i=0;i<CHANGE_REG_NUM;i++) //写寄存器循环
{
SCCB_WR_Reg(ov7670_init_reg_tbl[i][0],ov7670_init_reg_tbl[i][1]);
delay_us(20);
}
return 0;//ok
}
3.4 HX711初始化
void HX711Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //使能PF端口时钟
//HX711_SCK
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//;//上拉
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOB
//HX711_DOUT
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输入模式
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//;//上拉
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_1); //初始化设置为0
}