8★☆基于STM32的小区环境检测系统√★☆
Posted 行走的皮卡丘
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了8★☆基于STM32的小区环境检测系统√★☆相关的知识,希望对你有一定的参考价值。
8、★☆基于STM32的小区环境检测系统√★☆
文章目录
Introduction
The current era is an era in which new technologies emerge in an endless stream. In the field of electronics, especially in the field of automated intelligent control, control systems composed of traditional discrete components or digital logic circuits are being replaced by single-chip intelligent control systems at an unprecedented speed. Embedded has the advantages of small size, strong functions, low cost, and wide application range. It can be said that the core of intelligent control and automatic control is the single-chip microcomputer. At present, a climax of learning and application of embedded is emerging on a large scale in factories, schools, and enterprises. The most effective way to learn embedded is to pay equal attention to theory and practice. This article uses the residential environment detection system designed by STM32.
The system is equipped with input and output parts through the STM32 development board, and displays the data on the TFT-LCD liquid crystal display by collecting data such as temperature, humidity, PM2.5, and light intensity. An external 5v power supply supplies power to the entire system.
引言
当今时代是一个新技术层出不穷的时代,在电子领域尤其是自动化智能控制领域,传统的分立元件或数字逻辑电路构成的控制系统,正以前所未有的速度被单片机智能控制系统所取代。嵌入式具有体积小、功能强、成本低、应用面广等优点,可以说,智能控制与自动控制的核心就是单片机。目前,一个学习与应用嵌入式的高潮正在工厂、学校及企事业单位大规模地兴起。学习嵌入式的最有效的方法就是理论与实践并重,本文用STM32设计的小区环境检测系统。
本系统通过STM32开发板配以输入输出部分,通过采集温度、湿度、PM2.5、光照强度等数据在TFT-LCD液晶显示器上显示,外接5v电源对整个系统供电。
1、系统概述
1.1、设计任务
用STM32设计一个小区环境检测系统。
1.2、设计要求
要求达到轻便,实时准确监测如温度、湿度、PM2.5、光照强度等多项环境参数,并把相应的结果在液晶显示器实时显示出来。
2、 方案设计与论证
2.1、芯片选择方案
stm32是一个低功耗,高性能32位单片机,片内含4k Bytes ISP(In-system programmable)的可反复擦写1000次的Flash只读程序存储器。主要性能有:与MCS-51单片机产品兼容、全静态操作:0Hz~33Hz、 三级加密程序存储器、32个可编程I/O口线、三个16位定时器/计数器、八个中断源、全双工UART串行通道、掉电后中断可唤醒、看门狗定时器、双数据指针、掉电标识符、易编程。
2.2 、系统概述
小区环境检测系统能实现对小区环境中的温度、湿度,空气中的粉尘等环境参数的实时监测,本系统通过STM32开发板及外部连接的的传感器对室外环境参数的实时采集处理,并通过液晶显示器显示环境数据的智能小区环境检测系统,该系统测量数据准确且精度高,能让用户随时了解当前环境的具体情况,从而大大地节省了现场采集数据的时间并有效避免了有毒气体对人体造成伤害,大大地提高了小区的环境安全,并且具有较好的实时性、经济性和安全性。
2.3、设计要求
①利用stm32及相关模块组成小区环境检测系统。
②通过DHT11温湿度传感器模块、PM2.5传感器、GY-30数字光照传感器等模块进行数据收集。
③通过液晶显示器可以正常显示各数据
2.4、系统总体设计
(1)设计能正常工作的一个嵌入式系统;
(2)进行软件设计,利用单片机的系统时钟先设计一个高精度的内部时钟系统;
(3)实时显示当前的温度、湿度、PM2.5、光照强度等参数,和在设置动作时间过程中的相应变化显示。
2.5、各功能模块程序实现原理分析
该系统由DHT11温湿度传感器模块、PM2.5传感器、GY-30数字光照传感器和TFT-LCD液晶显示器组成。
2.5.1、 DHT11温湿度传感器模块
DHT11温湿度传感器是一款集温湿度测量于一体的数字传感器。该传感器多用于需要采集温度或者湿度的数字化监控系统中,具有较高的准确性和稳定性。传感器包括一个电阻式测湿元件和一个大NTC测温元件。DHT11与单片机之间能采用简单的单总线进行通信,只需要一个I/O口。传感器内部温度和湿度数据40bit的数据一次性传给单片机,数据采用校验的方式进行校验,有效地保证数据传输的准确性。DHT11功耗很低,5v电源电压下,工作平均最大电流0.5Ma。
2.5.2、 PM2.5传感器
PM2.5传感器选用的是夏普光学灰尘传感器,相较于其他PM2.5传感器,它的封装体积较小,而且可以检测非常细小的颗粒,并且检测时间较短,只要一个脉冲的时间就可以检测到空气中的尘埃,且还能区分烟和灰尘。该传感器的设计中有空气流动的通孔,空气的流动会使空气中的灰尘、烟雾等微小粒子也被带动起来,而PM2.5传感器内部含有发光的二极管,通过发光二极管发出的光,由于空气中含有粉尘或者烟雾等微小颗粒,光照射后会产生折射现象,根据PM2.5传感器内部接收管所接受到的光量来判断空气中粉尘、烟雾等的浓度,然后再将浓度值转换成电压信号传入单片机检测。
2.5.3、 GY-30数字光照传感器
光照传感器是一种专用于检测光照强度的仪器,它能够将光照强度值转化为电压值,光照强度传感器由发送器、接收器和检测电路组成,发送器对准目标发射光束,光束不间断地发射或改变脉冲宽度;三角反射板是结构牢固的发射装置,能够使光束准确地从反射板中返回;接收器由光电二极管、光电三极管、光电池组成;在接收器的前面,装有光学元件如透镜和光圈等,在其后面是检测电路,它能滤出有效信号和发送该信号。
2.5.4、 TFT-LCD液晶显示器
TFE-LCD显示器的显像原理采用“背透式”照射方式,当光源照射时,先通过下偏光板向上透出,借助液晶分子来传导光纤。由于上下夹层的电极改成FET电极和共通电极,在FET电极导通时,液晶分子的排列状态同样会发生改变,也通过遮光和透光来达到显示的目的。但不同的是,由于FET晶体管具有电容效率,能够保持电位状态,先前透光的液晶分子会一直保持这种状态,直到FET电极下一次再加电改变其排列方式为止。
3、 STM32性能介绍及硬件
3.1、 STM32单片机性能介绍
STM32它拥有的资源包括:48KB SRAM、256KB FLASH、2 个基本定时器、4 个通用定时器、2个高级定时器、2个DMA 控制器(共 12 个通道)、3 个SPI、2个IIC、5个串口、1个USB、1个CAN、3个12位ADC、1个12位DAC、1个SDIO接口及51 个通用IO口,该芯片性价比极高。
各个引脚说明如下:
-
PA0 作用1,按键 KEY_UP 2,可以做待机唤醒脚(WKUP) 3,可以接 DS18B20 传感器接口(P2 设置)
-
PA1作用1,NRF24L01 接口 IRQ 信号 2,接 HS0038 红外接收头(P2 设置)
-
PA2 作用 作为W25Q64 的片选信号
-
PA3 作用 作为SD 卡接口的片选脚
-
PA4 作用 作为NRF24L01 接口的 CE 信号
-
PA5 作用 作为W25Q64、SD 卡和 NRF24L01 接口的 SCK 信号
-
PA6 作用 作为 W25Q64、SD 卡和 NRF24L01 接口的 MISO 信号
-
PA7 作用 作为 W25Q64、SD 卡和 NRF24L01 接口的 MOSI 信号
-
PA8 作用 作为 接 DS0 LED 灯(红色)
-
PA9 作用 作为串口 1 TX 脚,默认连接 CH340 的 RX(P4 设置)
-
PA10 作用 作为串口 1 RX 脚,默认连接 CH340 的 TX(P4 设置)
-
PA11 作用 作为接 USB D-引脚
-
PA12 作用 作为接 USB D+引脚
-
PA13作用 作为JTAG/SWD 仿真接口,没接任何外设
-
PA14 作用 作为JTAG/SWD 仿真接口,没接任何外设
-
PA15 作用 作为1,JTAG 仿真口(JTDI) 2,PS/2 接口的 CLK 信号 3,接按键 KEY1
3.2小区环境检测系统硬件设计
3.2.1、硬件结构框图
3.2.2、系统接线图
4 、系统程序
4.1主程序设计如下
主程序中有各个模块的子程序调用,通过调用就能够访问该程度所在位置,使主程序简洁明了,程序设计过程中的大体流程图如下图所示。
4.2、主程序内容
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "lcd.h"
#include "adc.h"
#include "gy30.h"
#include "myiic.h"
#include "dht11.h"
extern uint8_t dat[5];
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
delay_init(); //延时函数初始化
uart_init(9600); //串口初始化为9600
LED_Init(); //初始化与LED连接的硬件接口
LCD_Init();
Adc_Init(); //ADC初始化
IIC_Init();
Init_BH1750();
POINT_COLOR=RED;//设置字体为红色
LCD_ShowString(26,70,200,16,16,"Environmental Monitoring!");
POINT_COLOR=BLUE;//设置字体为蓝色
LCD_ShowString(0,130,200,16,16,"PM2.5:");
LCD_ShowString(0,150,200,16,16,"Temperature:");
LCD_ShowString(0,170,200,16,16,"humidity:");
LCD_ShowString(0,190,200,16,16,"illumination:");
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, 1);
while(1)
{
u16 i,pm;
pm=Get_GP2Y_Average(30)*10; //获取PM2.5数值
LCD_ShowxNum(200,130,pm,4,16,0);
if(DHT_Read())
{
LCD_ShowxNum(215,150,dat[2],2,16,0); //获取温度数值
LCD_ShowxNum(215,170,dat[0],2,16,0); //获取湿度数值
}
i = GetBH1750Data();//获取光照强度数值
LCD_ShowxNum(105,190,i,16,16,0);
LED0=!LED0;
delay_ms(250);
}
}
4.3、各子程序
4.3.1、温湿度采集程序程序如下:
#include "stm32f10x.h"
#include "dht11.h"
#include "delay.h"
uint8_t dat[5]={0x00,0x00,0x00,0x00,0x00}; //存储读取的温湿度信息
uint32_t sum=0; //存放校验时的求和
void DHT11_PortOutput(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;//推挽输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//输出50MHz
GPIO_Init(GPIOC,&GPIO_InitStructure);
}
void DHT11_PortInput(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//推挽输出
GPIO_Init(GPIOC,&GPIO_InitStructure);
}
uint8_t DHT_Read_Byte(void)
{
uint8_t temp; //存放读取到的位数据
uint8_t ReadDat = 0;
uint8_t i;
uint8_t retry = 0;
for(i=0;i<8;i++)
{
while(DHT11 ==0 && retry < 100) //等待DHT11输出高电平
{
delay_us(1);
retry++;
}
retry = 0;
delay_us(30); //延时30us,由于‘0’代码高电平时间26~28us,'1'代码高电平时间70us,延时30us可判断出是1,还是0
temp = 0; //先将寄存器清零
if(DHT11 ==1) //延时30us之后如果还是高电平,证明为1代码
temp = 1; //将1存储
while(DHT11 ==1 && retry < 100) //等待信号被拉低,跳出
{
delay_us(1);
retry++;
}
retry = 0;
ReadDat<<=1; //数据左移1位,存放新得到的数据
ReadDat|= temp; //新得到的数据放到最后1位
}
return ReadDat;
}
uint8_t DHT_Read(void)
{
uint8_t i;
uint8_t retry = 0;
DHT11_PortOutput(); //端口方向设置为输出
DHT11_LOW; //端口数据拉低
delay_ms(18); //延时18ms,时序要求
DHT11_HIGH; //端口数据拉高
delay_us(40); //延时40us,
DHT11_PortInput(); //方向设置为输入
delay_us(20); //延时20us
if(DHT11 ==0) //如果读取到低电平,证明DHT11响应
{
while(DHT11 ==0 && retry < 100) //等待变高电平
{
delay_us(1);
retry++;
}
retry = 0;
while(DHT11 ==1 && retry < 100) //等待变低电平
{
delay_us(1);
retry++;
}
retry = 0;
for(i=0;i<5;i++) //循环5次将40位读出
{
dat[i] = DHT_Read_Byte(); //读出1个字节
}
delay_us(50); //最后延时等待50us
}
sum=dat[0]+dat[1]+dat[2]+dat[3]; //前4个字节数据的和
if(dat[4]==(u8)(sum)) //前4个数据和的末8位要和第5个数据相等,才算读取正确
{
return 1; //校验正确,返回1
}
else
return 0; //校验错误,返回0
}
4.3.2、PM2.5采集程序程序如下:
#include "adc.h"
#include "delay.h"
void Adc_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 , ENABLE ); //使能ADC1通道时钟
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
//PA1 作为模拟通道输入引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
GPIO_Init(GPIOA, &GPIO_InitStructure);
//PB1 作为脉冲输出引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GP2Y_High;
ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //模数转换工作在单通道模式
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //模数转换工作在单次转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目
ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1
ADC_ResetCalibration(ADC1); //使能复位校准
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
ADC_StartCalibration(ADC1); //开启AD校准
while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
// ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
}
//获得ADC值
//ch:通道值 0~3
u16 Get_Adc(u8 ch)
{
//设置指定ADC的规则组通道,一个序列,采样时间
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果
}
float GetGP2Y(void)
{
u32 AD_PM;
double pm;
GP2Y_Low;
delay_us(280);
AD_PM = Get_Adc(ADC_Channel_1); //PA0
delay_us(40);
GP2Y_High;
delay_us(9680);
pm = 0.17*AD_PM-0.1; //转换公式
printf("%f\\n",pm);
return pm;
}
u16 Get_GP2Y_Average(u8 times)
{
u32 pm_val=0;
u8 t;
for(t=0;t<times;t++)
{
pm_val+=GetGP2Y();
delay_ms(5);
}
return pm_val/times;
}
4.3.3、数字光照采集程序程序
#include "gy30.h"
#include "myiic.h"
#include "delay.h"
#include "usart.h"
#include "lcd.h"
u8 BUFFER[8] = {0};
void Single_Write_BH1750(u8 REG_Address)
{
u8 ack=0;
IIC_Start(); //起始信号
IIC_Send_Byte(SlaveAddress); //发送设备地址+写信号
ack = IIC_Wait_Ack();
if(ack){
printf("GY30 ack ADDR failure\\n");
return ;
}
IIC_Send_Byte(REG_Address); //内部寄存器地址
ack = IIC_Wait_Ack();
if(ack){
printf("2402 ack CMD failure\\n");
return ;
}
IIC_Stop(); //发送停止信号
}
//连续读出BH1750内部数据
void Multiple_read_BH1750(u8 *BUF)
{
u8 i;
u8 ack=0;
IIC_Start(); //起始信号
IIC_Send_Byte(SlaveAddress+1); //发送设备地址+读信号
ack = IIC_Wait_Ack();
if(ack){
printf("GY30 ack ADDR failure\\n");
return ;
}
for (i=0; i<6; i++) //连续读取6个地址数据,存储中BUF
{
BUF[i] = IIC_Read_Byte(); //BUF[0]存储0x32地址中的数据
if (i == 6)
{
IIC_NAck(); //最后一个数据需要回NOACK
}
else
{
IIC_Ack(); //回应ACK
}
}
IIC_Stop(); //停止信号
delay_ms(5);
}
//获取数字光照传感器数据
float GetBH1750Data(void)
{
int dis_data = 0;
float temp = 0;
Single_Write_BH1750(0x01); // power on
Single_Write_BH1750(0x11); // H- resolution mode
delay_ms(180); //延时180ms
Multiple_read_BH1750(BUFFER); //连续读出数据,存储在BUF中
dis_data=BUFFER[0];
dis_data=(dis_data<<8)+BUFFER[1]以上是关于8★☆基于STM32的小区环境检测系统√★☆的主要内容,如果未能解决你的问题,请参考以下文章