一、课题
1、用 DHT11 温湿度传感器获取温湿度信息,显示到OLED屏上
2、用 MQ-135 空气质量传感器获取空气质量信息,显示到OLED屏上
3、设计一个报警系统,可以设置温湿度与空气质量的上限,超过这个值蜂鸣器发出声响报警
二、准备材料
(一)、主控芯片stm32f103c8t6核心板
(二)DHT11温湿度传感器
(三)mq135空气质量传感器
(四)4针IIC OLED
三、原理图与PCB设计
(一)原理图设计
(二)PCB设计
四、程序设计
(一)DHT11驱动
DHT11.c
DHT11.h
- #ifndef __DHT11_H
- #define __DHT11_H
- #include "sys.h"
- #define DHT11_IO_IN() {GPIOA->CRL&=0XFF0FFFFF;GPIOA->CRL|=8<<20;}
- #define DHT11_IO_OUT() {GPIOA->CRL&=0XFF0FFFFF;GPIOA->CRL|=3<<20;}
-
- #define DHT11_DQ_OUT PAout(5)
- #define DHT11_DQ_IN PAin(5)
- #define DHT11_DQ_RCC RCC_APB2Periph_GPIOA
- #define DHT11_DQ_PIN GPIO_Pin_5
- #define DHT11_DQ_PORT GPIOA
- u8 DHT11_Init(void);
- u8 DHT11_Read_Data(u8 *temp,u8 *humi);
- u8 DHT11_Read_Byte(void);
- u8 DHT11_Read_Bit(void);
- void DHT11_Rst(void);
- u8 DHT11_Check(void);
- #endif
复制代码
(二)MQ-135驱动,由于用的是ADC,直接上ADC代码
- #include "adc.h"
- #include "delay.h"
-
- //初始化ADC
- //这里我们仅以规则通道为例
- //我们默认将开启通道0~3
- 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);
- ADC_DeInit(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规则组的转换结果
- }
- u16 Get_Adc_Average(u8 ch,u8 times)
- {
- u32 temp_val=0;
- u8 t;
- for(t=0;t<times;t++)
- {
- temp_val+=Get_Adc(ch);
- delay_ms(5);
- }
- return temp_val/times;
- }
复制代码
(三)主程序
main.c部分代码
- int main(void)
- {
- u16 key;
- int adc,cnt=0;
- float volt;
- delay_init();
- NVIC_Configuration();
- BEEP_Init();
- OLED_Init();
- OLED_Clear();
- uart_init(115200);
- printf("欢迎使用化作尘健康小工具\r\n");
- KEY_Init();
- LED_Init();
- TIM3_Int_Init(500-1,720-1);
-
- DEV_Init();
-
-
- OLED_Clear();
- OLED_Dis_Menu();
- while(1)
- {
- if(cnt++ ==1000)
- {
- cnt = 0;
- LED0=!LED0;
- adc = Get_Adc_Average(0,5);
- volt = adc*3.3/4096;
- air = pow((3.4880*10*volt)/(5-volt),(1.0/0.3203));
- printf("air :%d\r\n",air);
- //获取温湿度
- DHT11_Read_Data( &temp, &humi);
- if(last_temp!=temp || last_humi!=humi)
- {
- OLED_Dis_DHT(temp,humi,air);
- }
- }
- key = Key_GetValue(); //按键扫描
- if(key)
- DealKeyVal(key);
- if(!KEY1_IO())
- {
- printf("%d\r\n",GetTime());
- }
- if(temp>Max_temp || humi>Max_humi || air>Max_air)
- {
- if(cnt<500)BEEP=1;
- else if(cnt<1000)BEEP=0;
- }else BEEP=0;
-
-
- delay_ms(1);
- }
-
- }
复制代码
|