前言:
本次毕业设计智能衣柜使用异味传感器检测衣柜内的异味浓度值,一个温湿度检测衣柜的温度值和湿度值。
一,异味传感器
1.1异味传感器购买渠道
1.2异味传感器---STM32CUBEMAX配置部分
第一步:ADC采集传感器传过来的数据,要打印在串口处,所以先使能串口1。串口的触发方式为异步触发,剩下的按照默认配置就好了,波特率:115200。
第二步:使能ADC通道,这里我选择的串口通道为通道0。其余信息按照默认配置就好了,
第四步:配置时钟树。相关配置如下所示:
第五步:生成keilv5工程,注意,生成KEIL文件时,IDE选择:MDK-ARM,选择的文件目录不要用中文名字命名。
这里选上就会生成你所需要的.c和.h文件。
1.3异味传感器---Keil_V5部分
第一步:在usart.c文件中添加代码,串口输出printf打印。
#include "stdio.h"
int fputc(int c,FILE *stream)
{
HAL_UART_Transmit(&huart1,(unsigned char *)&c,1,1000);
return 1;
}
第二步:打开魔术棒功能,在LIB方框中打上√
第三步,在main.c函数中printf打印输出日志信息,sscom打印串口输出:
第四步:这里建议自己在工程目录下新建文件夹保存后面功能的.c和.h文件,创建自己的adc.c文件。
第五步:在自己的user_adc.h文件中加入以下代码:
#ifndef H_USER_ADC_H
#define H_USER_ADC_H
#include "main.h"
extern ADC_HandleTypeDef hadc1 ;
uint16_t SMOG_IN_(void);
#endif
第六步:在自己创建的user_adc.c中加入以下代码:
#include "user_adc.h"
uint16_t SMOG_IN_(void) //ADCÊý¾Ý²É¼¯Çý¶¯º¯Êý
{
HAL_ADC_Start(&hadc1);//开启ADC采集
HAL_ADC_PollForConversion(&hadc1, 1000);//ADC数据采集时间
if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))//读取ADC采集完成标志位
{
return HAL_ADC_GetValue(&hadc1);//返回ADC采集数值
}
return 0;
}
第七步:在main.c函数中调用user_adc.c中读取异味浓度函数。
注意:在main函数添加user_adc.h,就可以调用user_adc.c中函数
第六步:sscom串口查看打印异味浓度值。
Attention:注意在测试异味传感器时,使用打火机放气测试,看到异味值在增大。
其实ADC转换器,主要就是采集使能ADC引脚电平的变化,然后转换成数值,存在一定的误差,可以通过异味传感器上的变阻器调节异味传感器的误差值。当然,这款异味传感器还可以通过高地电平触发。有兴趣自己尝试一下哦。
二,温湿度传感器
2.1温湿度传感器
温湿度传感器,既可以采集温度又可以采集湿度,主要就是通过单总线协议去实现的,有兴趣自己去百度一下单总线协议介绍哦。这里就不展开说了。
2.2温湿度传感器---CUBEMAX部分
第一步:设置IO输出引脚为PC5,输出方式为开漏输出,无上下拉电阻,高速输出。
注意:User Labal 那里加了DHT11的名称,建议也改成这个,后面GPIO口配置时,就可以不用改了。
第二步:配置us秒级延时函数,网上有许多的例程,这里是使用单片机定时器配置的,首先配置定时器1,时钟来源选择内部时钟,在参数配置选项哪里,Prescaler:72-1,(看上面时钟树的配置,给定时器的时钟频率为72Mhz),所以,这里选择72-1,计数值:为65535。
点击生成keil-v5软件。
2.2温湿度传感器---KEIL-V5部分
第一步:在tim.c中加上微妙级的函数:
void delay_us(uint32_t time)
{
__HAL_TIM_SetCounter(&htim1,0);
__HAL_TIM_ENABLE(&htim1);
while(__HAL_TIM_GetCounter(&htim1)<time);
__HAL_TIM_DISABLE(&htim1);
}
第二步:新建检测温湿度的.c和.h文件,放到USER这个目录下:
第三步:在user_temple.h中加入以下函数:
#ifndef H_USER_TEMPLE_H
#define H_USER_TEMPLE_H
#include "stm32f1xx_hal.h"
#include "main.h"
void DHT11_OUT(void);
void DHT11_IN(void);
void DHT11_RST(void);
uint8_t Dht11_Check(void);
uint8_t Dht11_ReadBit(void);
uint8_t Dht11_ReadByte(void);
uint8_t DHT11_Init(void);
uint8_t DHT11_ReadData(uint8_t *h);
#endif
第四步:在user_temple.c中加入以下函数:
#include "user_temple.h"
#include "delay_us.h"
void DHT11_OUT(void) //ÉèÖÃÊä³öģʽ²ÎÊý
{
GPIO_InitTypeDef GPIO_InitStruct ={0};
GPIO_InitStruct.Pin=DHT11_Pin; //ÉèÖÃÊä³öÒý½Å
GPIO_InitStruct.Mode=GPIO_MODE_OUTPUT_PP;//ÉèÖÃÊä³öµÄģʽ
GPIO_InitStruct.Pull=GPIO_NOPULL; //ÉèÖõÄÉÏÀ·½Ê½--²»ÉÏÀ
GPIO_InitStruct.Speed=GPIO_SPEED_FREQ_HIGH;//ÉèÖÃÊä³öµÄƵÂÊ£¬¸ßµçƽ
HAL_GPIO_Init(GPIOC,&GPIO_InitStruct);
}
void DHT11_IN(void) //ÉèÖÃÊäÈëģʽ
{
GPIO_InitTypeDef GPIO_InitStruct ={0};
GPIO_InitStruct.Pin=DHT11_Pin; //ÉèÖÃÊäÈëµÄÒý½Å
GPIO_InitStruct.Mode=GPIO_MODE_INPUT;//ÉèÖÃÊäÈëµÄģʽ
GPIO_InitStruct.Pull =GPIO_PULLUP;//ÉèÖÃÊäÈëÉÏÀģʽ¡ª¡ª¡ª¡ªÉÏÀÊäÈë
HAL_GPIO_Init(GPIOC,&GPIO_InitStruct);
}
void DHT11_RST(void) //¸´Î»º¯Êý£¬·¢³öÆðʼÐźÅ
{
DHT11_OUT();
HAL_GPIO_WritePin(GPIOC,DHT11_Pin,GPIO_PIN_RESET); //Ä£Äâµ¥×ÜÏ߸øµ½µÍµçƽ
HAL_Delay(20);
HAL_GPIO_WritePin(GPIOC,DHT11_Pin,GPIO_PIN_SET); //Ä£Äâµ¥×ÜÏßÐÒé¸øµ½¸ßµçƽ
delay_us(30);
}
uint8_t DHT11_Init(void) //Ä£¿é³õʼ»¯
{
DHT11_RST(); //¸´Î»£¬Ö÷»ú·¢³öÆðÖ¹ÐźÅ
return Dht11_Check(); //µÈ´ý»ØÓ¦
}
uint8_t DHT11_ReadData(uint8_t *h) //¶ÁÈ¡Ò»´ÎÊý¾Ý£¬ÎÂʪ
{
uint8_t buf[5];
DHT11_RST(); //µ÷Óø´Î»º¯Êý uint8_t i;
uint8_t i;
if(Dht11_Check()==0)
{
for(i=0;i<5;i++)
{
buf[i]=Dht11_ReadByte(); //¶ÁÈ¡ÎåλÊý×Ö´æ·ÅÔÚÊý×éÖÐ
}
if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]) //Êý¾ÝУÑé
{
*h=buf[0]; //½«Êª¶ÈÖµ´æ·ÅÔÚÖ¸Õë1
h++;
*h=buf[2]; //½«Î¶ȴæ·ÅÔÚÖ¸Õë2ÖÐs
}
}
else
return 1;
return 0;
}
uint8_t Dht11_ReadBit(void) //¶Á³öÒ»¸öÊý¾Ýλ £¬·µ»ØֵΪ0»òÕß1
{
uint8_t retry=0;
while(HAL_GPIO_ReadPin(GPIOC,DHT11_Pin)&&retry<100) //µÈ´ý±ä³ÉµÍµçƽ
{
retry++;
delay_us(1);
}
retry=0;
while(!HAL_GPIO_ReadPin(GPIOC, DHT11_Pin )&&retry<100)//µÈ´ý±ä³É¸ßµçƽ
{
retry++;
delay_us(1);
}
delay_us(40);//µÈ´ý40us //ÓÃÓÚÅжϸߵÍÍÍƽ£¬ ¼´Êý¾Ý1»ò0
if(HAL_GPIO_ReadPin(GPIOC,DHT11_Pin))
return 1;
else return 0;
}
uint8_t Dht11_ReadByte(void) //¶ÁÈ¡Ò»¸ö×Ö½Ú£¬ ͨ¹ý·µ»ØÖµµÃµ½Êý¾ÝÖµ
{
uint8_t i,dat;
dat=0;
for(i=0;i<8;i++)
{
dat<<=1;
dat|=Dht11_ReadBit();//Ñ»·¶ÁÈ¡8´Î¶ÁÈ¡Ò»×éÊý¾Ý
}
return dat;
}
uint8_t Dht11_Check(void)
{
uint8_t retry=0;
DHT11_IN(); //½«Ä£Ê½ÉèÖÃΪÊäÈëģʽ
while((HAL_GPIO_ReadPin(GPIOC,DHT11_Pin))&&retry<100) //ÀµÍµçƽ
{
retry++;
delay_us(1);
}
if(retry>=100)
{
return 1;
} //0±íʾÉèÖóɹ¦£¬1±íʾÉèÖÃʧ°Ü
else
retry=0;
while(!HAL_GPIO_ReadPin(GPIOC, DHT11_Pin)&&retry<100) //À¸ßµçƽ
{
retry++;
delay_us(1);
}
if(retry>=100)
{
return 1;
}
else
return 0;
}
第五步,在main函数中初始化函数,并打印输出温湿度值,注意:DHT11_ReadData(DHT11_BUF);这个函数的形参需要自己定义,是一个uint8_t 类型长度为2的一维数组。
第六步:在sscom串口打印观察是否有数据:
三,总结
温湿度传感器对时序要求很严格,复制代码不成功,试一下改变一下IO口,在stm32cubemax中我用的是PA口,自己测试时,定义其他IO口,在DHT11初始化那儿记得改一下io口,多检查一下IO口是否对得上。本文到此结束,如有什么错误,欢迎评论区指正。