基于stm32的温湿度检测案例(一)

这篇具有很好参考价值的文章主要介绍了基于stm32的温湿度检测案例(一)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

系列文章目录

一、基于stm32的温度检测案例(一)

文章目录

目录

系列文章目录

一、基于stm32的温度检测案例(一)

文章目录

前言

一、实验器材简介

1.1、基于STM32F042F6P6的最小单片机系统

1.2、串口通信工具CH340G(USB转TTL)​编辑

1.3、仿真器(ST-LINK V2)

二、检测STM32F042F6P6功能是否正常

2.1、程序验证

 2.2、上电验证

三、代码演示

3.1、时钟树

3.2、Systick配置(Cortex--M0)

3.3、GPIO配置

3.2.1、方法功能测试

3.3、串口调试

3.3.1、串口配置

四、DHT11温湿度检测模块

4.1、引脚与接口

4.2、内部结构

4.3、根据时序写代码

4.2.1、时钟、端口、引脚、高低电平的配置

4.2.2、通讯过程

前言

使用基于stm32f042F6P6的最小单片机系统通过单总线与DHT11温湿度检测传感器通信,实现对当前环境下的温湿度检测。使用串口通信将DHT11模块检测到的数据在PC上显示。

一、实验器材简介

1.1、基于STM32F042F6P6的最小单片机系统

基于stm32的温湿度检测案例(一),单片机项目,开发语言

1.2、串口通信工具CH340G(USB转TTL)

1.3、仿真器(ST-LINK V2)

基于stm32的温湿度检测案例(一),单片机项目,开发语言

二、检测STM32F042F6P6功能是否正常

2.1、程序验证

通过观看原理图发现板子上有两个灯,一个电源指示灯与一个接在PB1引脚上的led。编写代码驱动接在PB1上的 LED,检查LED是否正常工作从而推论硬件是否有问题(量产的板子一般"冒得问题”)。

基于stm32的温湿度检测案例(一),单片机项目,开发语言

1、二极管工作原理:从标有三角那一端(P),流向标一横那一端(N)。实物:从标有“+”号那一端流向标有“-”号那一端。正向导通(P->N),反向截止(N->p)。

2、拉电流”,是指驱动LED负载的电流方向为  从电路输出端流向LED负载.  单片机给管脚高电平(推),LED熄灭
3、灌电流”是指驱动LED负载的电流方向为    从LED负载流向电路输出端。   单片机给管脚低电平 (挽),LED点亮

4、推挽输出(英语:Push–pull output)是一种使用一对选择性地从相连负载灌电流或者拉电流的器件的电路。它常常使用一对参数相同的功率三极管或MOSFET管,以推挽方式存在于电路中。

5、补充:推挽电路使用两个参数相同的三极管或MOSFET,以推挽方式存在于电路中。电路工作时,两只对称的开关管每次只有一个导通,所以导通损耗小、效率高。输出既可以向负载灌电流,也可以从负载抽取电流。推拉式输出级既提高电路的负载能力,又提高开关速度。

6、I/o口默认输出为高电平状态。

 2.2、上电验证

用ST_LINK V2连接板子与电脑,通过电脑的USB口给板子供电,查看板子上的电源指示灯是否正常点亮。(电脑的usb口输出5v左右的电压,不可作为驱动高于5v的板子的电源,会烧电脑usb口甚至电脑主板)。

三、代码演示

3.1、时钟树

基于stm32的温湿度检测案例(一),单片机项目,开发语言

3.2、Systick配置(Cortex--M0)

#include "public.h"
	//    us延时倍乘数			
static st_u8  fac_us=0;	

	//    ms延时倍乘数
static st_u16 fac_ms=0;						
/*********************************************************************************
                                 初始化延迟函数
SYSCLK:系统时钟频率
*********************************************************************************/
void SysTick_Init(st_u8 SYSCLK)
{
	//   SYSTICK的时钟固定为AHB时钟的1/8     6M
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); 
	fac_us=SYSCLK/8;					
	fac_ms=(st_u16)fac_us*1000;		// 6000us  		   
}								    


		
/*********************************************************************************
                              延时nus
                              nus为要延时的us数.
*********************************************************************************/
void delay_us(st_u32 nus)
{		
	st_u32 temp;	    	 
	SysTick->LOAD=nus*fac_us; 					      //    时间加载	  		 
	SysTick->VAL=0x00;        					      //    清空计数器
	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;	//    开始倒数	  
	do
	{
		temp=SysTick->CTRL;
	}while((temp&0x01)&&!(temp&(1<<16)));		  //  等待时间到达   
	SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;	//  关闭计数器
	SysTick->VAL =0X00;      					        //  清空计数器	 
}


/*********************************************************************************
                   延时nms
                 鈔ms的范围SysTick->LOAD为24位寄存器,所以,最大延时为:nms<=0xffffff*8*1000/SYSCLK
                 SYSCLK单位为Hz,nms单位为ms
                     对72M条件下,nms<=1864 
                      对24M条件下,nms<=5592
*********************************************************************************/
void delay_ms(st_u16 nms)
{	 		  	  
	st_u32 temp;		   
	SysTick->LOAD=(st_u32)nms*fac_ms;				   //  时间加载(SysTick->LOAD为24bit)
	SysTick->VAL =0x00;							           //  清空计数器
	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;	 //  开始倒数  
	do
	{
		temp=SysTick->CTRL;
	}while((temp&0x01)&&!(temp&(1<<16)));		  //  等待时间到达   
	SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;	//  关闭计数器
	SysTick->VAL =0X00;       				      	//  清空计数器	  	    
} 


3.3、GPIO配置

/*********************************************GPIO配置部分*********************************************/
/*********************************************
                  GPIO输出封装
1、时钟 RCC_AHBPeriph_x
2、端口 GPIOx
3、引脚 GPIO_PIN
4、输出模式  GPIOMode
5、输出类型  GPIOOType
5、指定所选引脚的操作上拉/下拉  GPIOPuPd
*********************************************/
void GPIOInit_Dout(st_u32 RCC_AHBPeriph_x,GPIO_TypeDef* GPIOx,st_u32 GPIO_PIN,GPIOMode_TypeDef GPIOMode,
	GPIOOType_TypeDef GPIOOType,GPIOPuPd_TypeDef GPIOPuPd)
{
	 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_x, ENABLE);      //  使能端口时钟
	
	GPIO_InitTypeDef GPIO_InitStructure;
 
  /* Configure PC10 and PC11 in output pushpull mode */
  GPIO_InitStructure.GPIO_Pin = GPIO_PIN;              //  引脚
  GPIO_InitStructure.GPIO_Mode = GPIOMode;             //  输入/输出模式
  GPIO_InitStructure.GPIO_OType = GPIOOType;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIOPuPd;            	//  上拉 or 下拉
  GPIO_Init(GPIOx, &GPIO_InitStructure);
}

/*********************************************
                  GPIO输入封装
1、时钟  RCC_AHBPeriph_x
2、端口  GPIOx
3、引脚  GPIO_PIN
4、输入模式  GPIOMode
5、指定所选引脚的操作上拉/下拉  GPIOPuPd
*********************************************/
void GPIOInit_Din(st_u32 RCC_AHBPeriph_x,GPIO_TypeDef* GPIOx,st_u32 GPIO_PIN,GPIOMode_TypeDef GPIOMode,GPIOPuPd_TypeDef GPIOPuPd)
{
	GPIO_InitTypeDef GPIO_InitStructure;
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_x, ENABLE);     //  使能时钟
  /* Configure PC10 and PC11 in output pushpull mode */
  GPIO_InitStructure.GPIO_Pin = GPIO_PIN;              //  引脚
  GPIO_InitStructure.GPIO_Mode = GPIOMode;             //  输入/输出模式
  //GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIOPuPd;            	//  上拉 or 下拉
  GPIO_Init(GPIOx, &GPIO_InitStructure);
}

3.2.1、方法功能测试

通过一个LED的来验证,函数功能是否正常

//  LED初始化
void LED_Init(void)
{
	// 时钟  端口  引脚  输出模式   推挽输出类型  上拉/下拉
  GPIOInit_Dout(LED_RCC,LED_PORT,LED_PIN,GPIO_Mode_OUT,GPIO_OType_PP,GPIO_PuPd_NOPULL);
	GPIO_SetBits(LED_PORT,LED_PIN);    //  初始化后默认PB1输出高电平
}
//  测试LED  高低电频每隔500ms交替一次  低电平期间LED点亮  高电平期间LED熄灭
void LED_Test(void)
{
       delay_ms(500);
		LED_L;
		delay_ms(500);
		LED_H;
}

.h文件中定义

#ifndef _LED_H
#define _LED_H
/*********************************************
     时钟  端口  引脚宏定义
*********************************************/
#define LED_RCC   RCC_AHBPeriph_GPIOB
#define LED_PORT  GPIOB 
#define LED_PIN   GPIO_Pin_1

#define LED_H    GPIO_SetBits(LED_PORT,LED_PIN)    //  高电平
#define LED_L    GPIO_ResetBits(LED_PORT,LED_PIN)  //  低电平

extern void LED_Init(void);
extern void  LED_Test(void);
#endif 
 

主函数

#define ROOT
#include "public.h"

int main(void)
{
//  初始化systick
	SysTick_Init(48);
	LED_Init();
	//Uart2_Init1();
	while(1)
	{
    LED_Test();
		//Uart2_Test();
	}
}

void SystemInit(void)
{

}

3.3、串口调试

外接5电源到板子,串口调试工具与板子供地共GND,串口调试工具的RX、TX与板子的RX、TX交叉相接能正常收发数据。 

3.3.1、串口配置

库函数配置串口


/*********************************************  
中断优先级配置
cortex-m0 智能配置 0~3
********************************************/
void NVIC_Config(st_u8 IRQn,st_u8 IRQChannelPriority)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  NVIC_InitStructure.NVIC_IRQChannel = IRQn;
	
	NVIC_InitStructure.NVIC_IRQChannelPriority = IRQChannelPriority;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

/*********************************************串口配置*********************************************/
/**********
STM32共有两种串口通信接口,分别是:UART通用异步收发器,USART:通用同步异步收发器
单工:数据传输只支持数据在一个方向上传输   一个通道
半双工:允许数据在两个方向上传输,但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信;  两个通道
全双工:允许数据同时在两个方向上传输,因此,全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力。  两个通道

同步通信与异步通信
同步通信指的是带有时钟同步信号,比如:SPI通信、IIC通信;
异步通信指的是不带时钟同步信号比如:UART(通用异步收发器),单总线
**********/
void USART_Config(USART_TypeDef* USARTx,st_u32 Baudrate)
{
	if(USARTx==USART1)
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	else
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
	
	USART_InitTypeDef USART_InitStructure;
  USART_InitStructure.USART_BaudRate = 9600;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  USART_Init(USARTx, &USART_InitStructure);
	
  USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE);
  USART_Cmd(USARTx, ENABLE);
  }

/*********************************************
	          串口2通信初始化1
	*********************************************/
void Uart2_Init1(void)
{
  NVIC_Config(USART2_IRQn,0x00);
	//  TX        时钟                端口   引脚      复用模式     推挽输出       上拉/下拉
	//  推(拉电流) 驱动负载的电流方向为  从电路输出端流向负载
	//  挽(灌电流) 驱动负载的电流方向为  从负载流向电路输出端 
	GPIOInit_Dout(RCC_AHBPeriph_GPIOA,GPIOA,GPIO_Pin_2|GPIO_Pin_3,GPIO_Mode_AF,GPIO_OType_PP ,GPIO_PuPd_NOPULL);
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_1);     // USART2_Tx
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_1);     // USART2_Rx
	USART_Config(USART2,9600);
}

中断服务函数

#include "public.h"

//  加入以下代码,支持printf函数,而不需要选择use MicroLIB	
#if 1
//#pragma import(__use_no_semihosting) 
#pragma import(__use_no_semihosting_swi)

struct  __FILE {st_32 handle;};   //  标准库需要的支持函数

FILE  _stdout;

void sys_exit(st_32 x){             // 定义_sys_exit()以避免使用半主机模式 
   x=x;
}
//  发送数据
//  重定向 c 库函数 printf 到串口,重定向后可使用 printf 函数
int fputc(int ch,FILE*p)
{
	//#if 1
  USART_SendData(USART2,(st_u8)ch);
	// USART_FLAG_TXE  数据寄存器为空的标记
	while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
	return ch;
	//#else
	//while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
 // USART1->TDR = (st_u8) ch;      
	//return ch;
	//#endif

}

//  接收数据
//  重定向 c 库函数 scanf 到串口,重写向后可使用 scanf、getchar 等函数
 int fgetc(FILE *f)
 {
 // 等待串口输入数据 
 while (USART_GetFlagStatus(USART2, USART_IT_RXNE) == RESET);
 return (st_32)USART_ReceiveData(USART2);
 }
 
 //  发送字符
void Usart_SendByte( USART_TypeDef * pUSARTx,st_u8 ch)
{
 
USART_SendData(pUSARTx,ch);
 while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}

//  发送字符串
void Usart_SendString( USART_TypeDef * pUSARTx, char *str)
{
  st_u32 k=0;
  do {
   Usart_SendByte( pUSARTx, *(str + k));
   k++;
} while (*(str + k)!='\0');
 while (USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET) { /* 等待发送完成 */
   }
 }
#endif
 
 /*********************************************第一种方式*********************************************/
 #if USART2_RX_EN
  //USART2_RX_BUF[USART2_REC_LEN];
 // USART2_RX_STA=0;

 
 void USART2_IRQHandler(void)
 {
	INTX_DISABLE();  //  中断屏蔽
  st_u8 r;
	if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  //接收中断
	{
		r =USART_ReceiveData(USART2);//(USART1->DR);	//读取接收到的数据
		if((USART2_RX_STA&0x8000)==0)//接收未完成
		{
			if(USART2_RX_STA&0x4000)//接收到了0x0d
			{
				if(r!=0x0a)USART2_RX_STA=0;//接收错误,重新开始
				else USART2_RX_STA|=0x8000;	//接收完成了 
			}
			else //还没收到0X0D
			{	
				if(r==0x0d)USART2_RX_STA|=0x4000;
				else
				{
					USART2_RX_BUF[USART2_RX_STA&0X3FFF]=r;
					USART2_RX_STA++;
					if(USART2_RX_STA>(USART2_REC_LEN-1))USART2_RX_STA=0;//接收数据错误,重新开始接收	  
				}		 
			}
		}   		 
	} 
	INTX_ENABLE();  //  放开中断屏蔽
 }
 #endif

 

四、DHT11温湿度检测模块

4.1、引脚与接口

  • VCC:DTH11的供电电压为 3-5.5V。传感器上电后,要等待 1s 以越过不稳定状态在此期间无需发送任何指令。
  • DATA:mcu与DHT11单总线通信引脚。一次通讯时间4ms左右,数据分小数部分和整数部分.
  • GND:接地。

DTH11工作流程:

  • MCU发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待主机开始信号结束后,
  • DHT11发送响应信号,送出40bit的数据,并触发一次信号采集, 用户可选择读取部分数据.
  • 从模式下,DHT11接收到开始信号触发一次温湿度采集, 如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集.采集数据后转换到低速模式。

基于stm32的温湿度检测案例(一),单片机项目,开发语言

4.2、内部结构

传感器包括一个电阻式感湿元件和一个NTC测 温元件,并与一个高性能8位单片机相连接。

4.3、根据时序写代码

4.2.1、时钟、端口、引脚、高低电平的配置

#ifndef  _DHT_11
#define  _DHT_11 
//  时钟  端口  引脚   
#define DHT11_RCC RCC_AHBPeriph_GPIOA
#define DHT11_PORT GPIOA
#define DHT11_PIN GPIO_Pin_7


#define DHT11_H    GPIO_SetBits(DHT11_PORT,DHT11_PIN)    //  高电平
#define DHT11_L    GPIO_ResetBits(DHT11_PORT,DHT11_PIN)  //  低电平



#endif
int8_t GPIOSet(GPIO_TypeDef* GPIOx, uint16_t GPIOPin, uint16_t GPIOMode)
{
	if(GPIOMode == 0)
	{
		GPIO_ResetBits(GPIOx,GPIOPin);
	}
	else
	{
		GPIO_SetBits(GPIOx,GPIOPin);
	}
	return GPIOMode;
}

//  uint8_t GPIOGet(GPIO_TypeDef* GPIOx, uint16_t GPIOPin)
uint8_t GPIOGet(GPIO_TypeDef* GPIOx, uint16_t GPIOPin)
{
	return (GPIO_ReadInputDataBit(GPIOx, GPIOPin));
}
//  输出配置
void DHT11_GPIO_Out(void)
{
	//  时钟   端口  引脚  输出模式  推挽输出   不上拉/不下拉
  GPIOInit_Dout(DHT11_RCC,DHT11_PORT,DHT11_PIN,GPIO_Mode_OUT,GPIO_OType_PP,GPIO_PuPd_NOPULL);
}

//  输入配置
void DHT11_GPIO_In(void)
{
	
	//   时钟  端口  引脚  输入模式   上拉输入
  GPIOInit_Din(DHT11_RCC,DHT11_PORT,DHT11_PIN,GPIO_Mode_IN,GPIO_PuPd_UP);
}

4.2.2、通讯过程

基于stm32的温湿度检测案例(一),单片机项目,开发语言

三种写时序的方式文章来源地址https://www.toymoban.com/news/detail-793489.html


//  输出配置
void DHT11_GPIO_Out(void)
{
	//  时钟   端口  引脚  输出模式  推挽输出   不上拉/不下拉
  GPIOInit_Dout(DHT11_RCC,DHT11_PORT,DHT11_PIN,GPIO_Mode_OUT,GPIO_OType_PP,GPIO_PuPd_NOPULL);
}

//  输入配置
void DHT11_GPIO_In(void)
{
	 //  
	 // GPIOInit_Din(DHT11_RCC,DHT11_PORT,DHT11_PIN,GPIO_Mode_IN,GPIO_PuPd_DOWN);
	
	  //GPIOInit_Din(DHT11_RCC,DHT11_PORT,DHT11_PIN,GPIO_Mode_IN,GPIO_PuPd_NOPULL);
	
	 //   时钟  端口  引脚  输入模式   上拉输入    经过测试此处必须设置为上拉才能上数据
    GPIOInit_Din(DHT11_RCC,DHT11_PORT,DHT11_PIN,GPIO_Mode_IN,GPIO_PuPd_UP);
	
}

void DHT11_Init(void)
{
  DHT11_GPIO_Out();
	DHT11_H;
	
}

#if 1
/* 
 * 从DHT11读取一个字节,MSB先行
 */
static st_u8 DHT11_ReadByte ( void )
{
	st_u8 i, temp=0;
	

	for(i=0;i<8;i++)    
	{	 
		/*每bit以50us低电平标置开始,轮询直到从机发出 的50us 低电平 结束*/  
		while(DHT11_Input==Bit_RESET);

		/*DHT11 以26~28us的高电平表示“0”,以70us高电平表示“1”,
		 *通过检测 x us后的电平即可区别这两个状 ,x 即下面的延时 
		 */
		delay_us(40); //延时x us 这个延时需要大于数据0持续的时间即可	   	  

		if(DHT11_Input==Bit_SET)/* x us后仍为高电平表示数据“1” */
		{
			/* 等待数据1的高电平结束 */
			while(DHT11_Input==Bit_SET);

			temp|=(st_u8)(0x01<<(7-i));  //把第7-i位置1,MSB先行 
		}
		else	 // x us后为低电平表示数据“0”
		{			    
			temp&=(st_u8)~(0x01<<(7-i)); //把第7-i位置0,MSB先行  高位先出。  高位 1111 1111  地位  左边高位,右边地位  
		}
	}
	
	return temp;
	
}

/*
 * 一次完整的数据传输为40bit,高位先出
 * 8bit 湿度整数 + 8bit 湿度小数 + 8bit 温度整数 + 8bit 温度小数 + 8bit 校验和 
 */
st_u8 DHT11_Read_TempAndHumidity(DHT11_Data_TypeDef *DHT11_Data)
{  
	/*输出模式*/
	DHT11_GPIO_Out();
	/*主机拉低*/
	DHT11_L;
	/*延时18ms*/
	delay_us(18);

	/*总线拉高 主机延时30us*/
	DHT11_H; 

	delay_ms(30);   //延时30us

	/*主机设为输入 判断从机响应信号*/ 
	DHT11_GPIO_In();

	/*判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行*/   
	if(DHT11_Input==Bit_RESET)     
	{
		/*轮询直到从机发出 的80us 低电平 响应信号结束*/  
		while(DHT11_Input==Bit_RESET);

		/*轮询直到从机发出的 80us 高电平 标置信号结束*/
		while(DHT11_Input==Bit_SET);

		/*开始接收数据*/   
		DHT11_Data->humi_int= DHT11_ReadByte();

		DHT11_Data->humi_deci= DHT11_ReadByte();

		DHT11_Data->temp_int= DHT11_ReadByte();

		DHT11_Data->temp_deci= DHT11_ReadByte();

		DHT11_Data->check_sum= DHT11_ReadByte();


		/*读取结束,引脚改为输出模式*/
		DHT11_GPIO_Out();
		/*主机拉高*/
		DHT11_H;

		/*检查读取的数据是否正确*/
		// 一次完整的数据传输为40bit,高位先出。数据格式:8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据+8bit校验和
		if(DHT11_Data->check_sum == DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int+ DHT11_Data->temp_deci)
			return SUCCESS;
		else 
			return ERROR;
	}
	
	else
		return ERROR;
	
}
#elif select1
//从DHT11读取一个位
//返回值:1/0
st_u8 DHT11_Read_Bit(void) 			 
{
 	st_u8 retry=0;
	while(DHT11_Input==0 &&retry<100)//等待变为低电平 12-14us 开始
	{
		retry++;
		delay_us(1);
	}
	retry=0;
	while(!DHT11_Input&&retry<100)//等待变高电平	 26-28us表示0,116-118us表示1
	{
		retry++;
		delay_us(1);
	}
	delay_us(40);//等待40us
	if(DHT11_Input)return 1;
	else return 0;		   
}

//从DHT11读取一个字节
//返回值:读到的数据
st_u8 DHT11_Read_Byte(void)    
{        
    st_u8 i,dat;
    dat=0;
	for (i=0;i<8;i++) 
	{
   		dat<<=1; 
	    dat|=DHT11_Read_Bit();
    }						    
    return dat;
}

//从DHT11读取一次数据
//temp:温度值(范围:0~50°)
//humi:湿度值(范围:20%~90%)
//返回值:0,正常;1,读取失败
st_u8 DHT11_Read_Data(st_u8 *temp,st_u8 *humi)    
{        
 	st_u8 buf[5];
	st_u8 i;
	DHT11_Rst();
	if(DHT11_Check()==0)
	{
		for(i=0;i<5;i++)//读取40位数据
		{
			buf[i]=DHT11_Read_Byte();
		}
		if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
		{
			*humi=buf[0];
			*temp=buf[2];
		}
		
	}else return 1;
	return 0;	    
}
#else
// 转译采集DHT11发送给IO口的电平信号(8位)
// 从DHT11读取一位(8字节)信号
st_u8 DHT11_Read_Byte(void)
{
   st_u8 ReadData = 0; // 存放8bit数据,即8个单次读取的1bit数据的组合
	 st_u8 temp;         // 临时存放信号电平(0或1)
	 st_u8 retry =0;     //  retry用于防止卡死
	 st_u8 i;
	for(i=0;i<8;i++)      // 一次温湿度信号读取八位
	{
	    while(DHT11_Input==0&&retry<100)
			{
			  // 等待直到DHT11输出高电平:
				// 当PA7=1,上升沿,表示开始接受数据,可以判断0 or 1,跳出循环,执行后续判断(若PA7=0,将一直循环等待)
			   delay_us(1);
				 retry++;
			};
			 retry=0;
			delay_us(40);
			//  根据时序图,DHT传回高电平信号维持26us~28us表示0,	维持70us表示1
		  //  延时30us后,如果IO读取到仍是高电平,说明采集到1;如果IO读取到低电平,说明采集到0
			//  读取电平信号暂存temp内,随后会压入ReadData中
     while(DHT11_Input==1&&retry<100)
		 {
			  delay_us(1);
				 retry++;
		 };
		 retry=0;
		 ReadData <<=1;  //  ReadData内信号先全部左移一位,空出末尾位置
		 ReadData|=temp;
	}
	return ReadData;
}

st_u8 DHT_Read(void)
{
	 st_u8 retry=0;
	 st_u8 i;
		
	 DHT11_GPIO_Out();    //IO设置为输出模式。在传输的最开始,MCU要向DHT11发送信号
	 DHT11_L;   //IO->DHT11:先拉低电平18ms(应时序要求)
	 delay_us(18);
	DHT11_H;   //IO->DHT11:随后拉高电平20us
	 delay_us(20);
	
	//MCU通过IO向DHT11发送请求完毕。接下来DHT11向IO发送响应,IO转为输入模式。在这之后就开始信号的转译读取。
	DHT11_GPIO_In();
	delay_us(20);
	if(DHT11_Input==0) //DHT11发回低电平响应(读取到低电平,说明DHT11有响应)
	{
		//接下来,DHT11拉低电平一段时间后拉高电平一段时间
		while(DHT11_Input==0 && retry<100)  
		{
		   delay_us(1);
			 retry++;
		}
		 retry=0;
		while(DHT11_Input==1 && retry<100) 
		{
		   delay_us(1);
			 retry++;
		}
		retry=0;
		
		//一共传输40位,一次DHT_Read_Byte返回8位,共读取5次。存储在Data[]中。(Data[]定义为全局)
		for(i=0; i<5; i++)
		{
			 Data[i] = DHT11_Read_Byte();  //每次读取一字节(8位)
		}
		delay_us(50);
		//说明:Data[0]湿度, Data[2]温度。Data[1]和Data[3]分别为0和2的小数位。Data[4]用于校验。
	}
	 st_u32 sum=Data[0]+Data[1]+Data[2]+Data[3];  //校验
	 if((sum)==Data[4])    return 1;  
	   else   return 0;
}
#endif

到了这里,关于基于stm32的温湿度检测案例(一)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于STM32的温湿度检测(程序+Proteus仿真+论文)

    1、主要功能 使用STM32和DHT11温湿度传感器对室内温湿度进行检测,并通过LCD显示。 2、仿真 3、程序源码 4、资源获取 其它毕设/课设资源 基于51单片机的智能温控风扇 基于51单片机的智能水箱控制系统 基于51单片机的智能家居安防系统 基于51单片机的计算器设计 基于单片机的

    2024年02月06日
    浏览(69)
  • 【物联网毕业设计】 单片机WIFI智能家居温湿度与烟雾检测系统 - Stm32 嵌入式

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2023年04月21日
    浏览(135)
  • 单片机项目分享 Stm32 WIFI智能家居温湿度和烟雾检测系统 - 单片机 物联网 嵌入式

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月19日
    浏览(62)
  • 嵌入式项目分享 Stm32 WIFI智能家居温湿度和烟雾检测系统 - 单片机 物联网 嵌入式

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年01月16日
    浏览(140)
  • 通信工程毕设 Stm32 WIFI智能家居温湿度和烟雾检测系统 - 单片机 物联网 嵌入式

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月02日
    浏览(58)
  • 68、基于STM32单片机DHT11温湿度蓝牙控制报警器app系统设计

    毕设帮助、开题指导、技术解答(有偿)见文末。 目录 摘要 一、硬件方案 二、设计功能 三、实物图 四、原理图 五、PCB图 六、程序源码 七、资料包括 温度、湿度和人类的生产、生活有着密切的关系,同时也是工业生产中最常见最基本的工艺参数,例如机械、电子、石油、

    2024年02月08日
    浏览(55)
  • 基于STM32物联网环境采集系统设计 --------AHT10温湿度检测(5)

    目录 一、电路连接图 二、AHT10模块简介 三、AHT10模块工作原理 四、AHT10的通信方式 五、AHT10的时序图 5-1、AHT10测量指令时序图解析 5-2、AHT10读数据时序图解析 5-3、AHT10的温湿度转换公式 六、IIC的GPIO配置   6-1、AHT10.C文件 6-2、AHT10.H文件 七、实现的功能 图(1)AHT10电路连接图

    2024年02月22日
    浏览(51)
  • 74-基于stm32单片机农业蔬菜大棚温湿度光照采集控制系统(程序+原理图+元件清单全套资料)...

    资料编号:074 功能介绍:采用stm32单片机作为主控CPU,采用DHT11传感器采集温湿度,采用光敏传感器采集光照强度,通过按键设置温湿度、光照的阈值,当温度高于设置值,继电器开启散热,当湿度低于设置值,继电器开启加湿,当光敏值大于设置值,蜂鸣器进行报警提醒,

    2024年02月12日
    浏览(45)
  • 86、基于STM32单片机的温湿度DHT11 MQ-2烟雾火灾报警器蓝牙物联网设计

    毕设帮助、开题指导、技术解答(有偿)见文末。 目录 摘要 一、硬件方案                     二、设计功能 三、实物图 四、原理图 五、硬件框图 六、流程图 七、程序源码   八、资料包括 随着社会和经济的发展,防火工作越来越重要,但是目前国内的许多研发都侧重

    2024年02月06日
    浏览(44)
  • 105-基于stm32单片机智能家居温湿度烟雾监测人体红外防盗报警系统Proteus仿真+程序源码

    一:功能介绍 1、采用stm32单片机+LCD1602+DHT11温湿度传感器+烟雾传感器+按键开关+蜂鸣器+LED灯,制作一个智能家居温湿度烟雾监测人体红外防盗报警系统; 2、通过按键开关来模拟人体红外检测触发,并且可以通过按键开关来设置正在布防和停止布防状态,布防状态下,当检测

    2024年02月03日
    浏览(63)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包