基于stm32的DHT11温湿度采集LCD显示Proteus仿真

*本设计:*

基于stm32温湿度采集Proteus仿真(仿真+程序)

仿真图protues 8.9

程序编译器:keil 5

编程语言:C语言

*设计编号:C0041*

*功能描述:*

通过STM32驱动DHT11温度传感器采集温湿度数据,将温湿度信息显示在LCD1602显示屏上及虚拟串口上。

资料下载链接(可点击)

*源程序(提供源文件)**:*

img

int main(void)
{

    DHT11_Data_TypeDef DHT11_Data;
    RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);
  
    
    /* 配置SysTick 为1us中断一次 */
    SysTick_Init();
    LED_GPIO_Config();
    //LED1_ON;
    LED2_ON;
    LED3_ON;
    //NVIC_Configuration();
    LcdGpioInit();
    LCD1602Init();

    USART_Config();//初始化串口1
    NVIC_Configuration();
    printf("\r\n***dht11 温湿度传感器实验***\r\n");

    /*初始化DTT11的引脚*/
    DHT11_Init();
    //printf("22\n");

    dht11_delay_ms(10);
    
    while(1)
    {
        //调用DHT11_Read_TempAndHumidity读取温湿度,若成功则输出该信息
        if( DHT11_Read_TempAndHumidity ( & DHT11_Data ) == SUCCESS)
        {
            uint8_t index = 0;
            char str[20];
            printf("\r\n读取DHT11成功!\r\n\r\n湿度为%d.%d %RH ,温度为 %d.%d℃ \r\n", DHT11_Data.humi_int, DHT11_Data.humi_deci, DHT11_Data.temp_int, DHT11_Data.temp_deci);
            sprintf(str, "H:%d.%d T:%d.%d", DHT11_Data.humi_int, DHT11_Data.humi_deci, DHT11_Data.temp_int, DHT11_Data.temp_deci);
            LcdWriteCom(0x80);//设置第一行 数据地址指针
            for(index = 0; index < 20; index++)
            LcdWriteDate(str[index]);  //写入数据
        }
        else
        {
            printf("Read DHT11 ERROR!\r\n");
        }
        Delay_ms(10);


    }



}

LCD显示函数




#include "./LCD/bsp_lcd.h"  
#include "./systick/bsp_SysTick.h"
uint8_t const table1[]="hello";
/*初始化用到的引脚*/
void LcdGpioInit(void)   
{
	GPIO_InitTypeDef GPIO_InitStruct;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
	 
	GPIO_WriteBit(GPIOC,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12,Bit_RESET);	
	 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init ( GPIOC, &GPIO_InitStruct);
}
/*******************************************************************************
* 函 数 名 :write_com
* 函数功能 :LCD1602 写指令
* 输    入 :无
* 输    出 :无
*******************************************************************************/
void LcdWriteCom(uint8_t com)
{
	Delay_us(20);
	GPIOC->BSRR = 0x00ff0000;
	GPIOC->BSRR = (com);
	GPIO_WriteBit(GPIOC,GPIO_Pin_10,Bit_RESET);	//LCDRS
	GPIO_WriteBit(GPIOC,GPIO_Pin_11,Bit_RESET);	//LCDRW
	GPIO_WriteBit(GPIOC,GPIO_Pin_12,Bit_RESET);	//LCDEN
	Delay_us(10);
	GPIO_WriteBit(GPIOC,GPIO_Pin_12,Bit_SET);	//LCDEN
	Delay_us(10);
	GPIO_WriteBit(GPIOC,GPIO_Pin_12,Bit_RESET);	//LCDEN
	Delay_us(10);
}
/*******************************************************************************
* 函 数 名 :write_Date
* 函数功能 :LCD1602 写数据
* 输    入 :无
* 输    出 :无
*******************************************************************************/
void LcdWriteDate(uint8_t date)
{
	Delay_us(20);
	GPIOC->BSRR = 0x00ff0000;
	GPIOC->BSRR = (date);
	GPIO_WriteBit(GPIOC,GPIO_Pin_10,Bit_SET);	//LCDRS
	GPIO_WriteBit(GPIOC,GPIO_Pin_11,Bit_RESET);	//LCDRW
	GPIO_WriteBit(GPIOC,GPIO_Pin_12,Bit_RESET);	//LCDEN
	Delay_us(10);
	GPIO_WriteBit(GPIOC,GPIO_Pin_12,Bit_SET);	//LCDEN
	Delay_us(10);
	GPIO_WriteBit(GPIOC,GPIO_Pin_12,Bit_RESET);	//LCDEN
	Delay_us(10);
}
/*******************************************************************************
* 函 数 名 :LCD1602Init
* 函数功能 :LCD1602初始化
* 输    入 :无
* 输    出 :无
*******************************************************************************/
void LCD1602Init(void)
{
	uint8_t index=0;
	Delay_ms(10);
	LcdWriteCom(0x38);  //设置16*2显示,8位数据接口
	LcdWriteCom(0x0c); //开显示,显示光标且闪烁
	LcdWriteCom(0x06);//写一个指针自动加一
	LcdWriteCom(0x01);//清屏  
	Delay_ms(10);//延时一段时间时间,等待LCD1602稳定	
	
	LcdWriteCom(0x80);//设置第一行 数据地址指针
	for(index=0;index<13;index++)
		LcdWriteDate(table1[index]);  //写入数据
	
//	LcdWriteCom(0xc0);//设置第二行 数据地址指针
//	for(index=0;index<7;index++)
//		LcdWriteDate(table2[index]);  //写入数据
}
/*******************************************************************************
* 函 数 名 :LCD1602WriteCommand
* 函数功能 :显示指令到屏幕 U D L R S 
* 输    入 :comm 字符格式
* 输    出 :无
*******************************************************************************/
void LCD1602WriteCommand(uint8_t comm)
{
	LcdWriteCom(0xc0 + 14);
	LcdWriteDate(comm);  //写入数据   
}

SHT11底层驱动代码


#include "./dht11/bsp_dht11.h"
#include "./systick/bsp_SysTick.h"



static void                           DHT11_GPIO_Config                       ( void );
static void                           DHT11_Mode_IPU                          ( void );
static void                           DHT11_Mode_Out_PP                       ( void );
static uint8_t                        DHT11_ReadByte                          ( void );



 /**
  * @brief  DHT11 初始化函数
  * @param  无
  * @retval 无
  */
void DHT11_Init ( void )
{
	DHT11_GPIO_Config ();
	
	DHT11_Dout_1;               // 拉高GPIOC15
}
//使用水滴计时器不准,于是 采用粗略计时
void dht11_delay_us(int32_t time){
   while(time--){   
   }
}

void dht11_delay_ms(int32_t time){   
 
   uint32_t i = 0;
	 i = time*1400;
   while(i--){
	 }
}

/*
 * 函数名:DHT11_GPIO_Config
 * 描述  :配置DHT11用到的I/O口
 * 输入  :无
 * 输出  :无
 */
static void DHT11_GPIO_Config ( void )
{		
	/*定义一个GPIO_InitTypeDef类型的结构体*/
	GPIO_InitTypeDef GPIO_InitStructure; 

	
	/*开启DHT11_Dout_GPIO_PORT的外设时钟*/
  DHT11_Dout_SCK_APBxClock_FUN ( DHT11_Dout_GPIO_CLK, ENABLE );	
 
	/*选择要控制的DHT11_Dout_GPIO_PORT引脚*/															   
  	GPIO_InitStructure.GPIO_Pin = DHT11_Dout_GPIO_PIN;	

	/*设置引脚模式为通用推挽输出*/
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   

	/*设置引脚速率为50MHz */   
  	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 

	/*调用库函数,初始化DHT11_Dout_GPIO_PORT*/
  	GPIO_Init ( DHT11_Dout_GPIO_PORT, &GPIO_InitStructure );		  
	
}


/*
 * 函数名:DHT11_Mode_IPU
 * 描述  :使DHT11-DATA引脚变为上拉输入模式
 * 输入  :无
 * 输出  :无
 */
static void DHT11_Mode_IPU(void)
{
 	  GPIO_InitTypeDef GPIO_InitStructure;

	  	/*选择要控制的DHT11_Dout_GPIO_PORT引脚*/	
	  GPIO_InitStructure.GPIO_Pin = DHT11_Dout_GPIO_PIN;

	   /*设置引脚模式为浮空输入模式*/ 
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ; 
		/*设置引脚速率为50MHz */   
  	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

	  /*调用库函数,初始化DHT11_Dout_GPIO_PORT*/
	  GPIO_Init(DHT11_Dout_GPIO_PORT, &GPIO_InitStructure);	 
	
}


/*
 * 函数名:DHT11_Mode_Out_PP
 * 描述  :使DHT11-DATA引脚变为推挽输出模式
 * 输入  :无
 * 输出  :无
 */
static void DHT11_Mode_Out_PP(void)
{
 	GPIO_InitTypeDef GPIO_InitStructure;

	 	/*选择要控制的DHT11_Dout_GPIO_PORT引脚*/															   
  	GPIO_InitStructure.GPIO_Pin = DHT11_Dout_GPIO_PIN;	

	/*设置引脚模式为通用推挽输出*/
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   

	/*设置引脚速率为50MHz */   
  	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

	/*调用库函数,初始化DHT11_Dout_GPIO_PORT*/
  	GPIO_Init(DHT11_Dout_GPIO_PORT, &GPIO_InitStructure);	 	 
	
}


/* 
 * 从DHT11读取一个字节
 */
static uint8_t DHT11_ReadByte ( void )
{
	uint8_t i, temp=0;
	uint8_t try_num = 0;

	for(i=0;i<8;i++)    
	{	 
		temp <<= 1;
		//等待从机拉低,表示1Bit数据开始传输
	while((DHT11_Dout_IN()==Bit_SET)&& try_num<100 ){
		try_num++;
		dht11_delay_us(1);
	}
	
	//等待从机拉高,开始1Bit数据值
	try_num = 0;
	while((DHT11_Dout_IN()==Bit_RESET)&& try_num<100){
		try_num++;
		dht11_delay_us(1);
	}

	dht11_delay_us(30); //高电平超过28us表示1
	if((DHT11_Dout_IN()==Bit_SET))
		{
			temp |= 1;
	} else {
		temp |= 0;
	}
	
	}
	
	return temp;
	
}


/*
 * 一次完整的数据传输为40bit,高位先出
 * 8bit 湿度整数 + 8bit 湿度小数 + 8bit 温度整数 + 8bit 温度小数 + 8bit 校验和 
 */
uint8_t DHT11_Read_TempAndHumidity(DHT11_Data_TypeDef *DHT11_Data)
{  
	/*输出模式*/
	DHT11_Mode_Out_PP();
	/*主机拉低*/
	//printf("\r\n computer high \r\n");
	DHT11_Dout_0;
	/*延时20ms*/
//	Delay_ms(18);
	dht11_delay_ms(18);
	//printf("\r\n computer low \r\n");
	/*总线拉高 主机延时18us*/
	DHT11_Dout_1; 

	//Delay_us(30);   //延时20us
	dht11_delay_us(35);
//printf("\r\n accept \r\n");
	/*主机设为输入 判断从机响应信号*/ 
	DHT11_Mode_IPU();

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

		/*轮询直到从机发出的 80us 高电平 标置信号结束*/
		while(DHT11_Dout_IN()==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();
		//printf("\r\nreceive\n");

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

		/*检查读取的数据是否正确*/
		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;
	
}

	  


/*************************************END OF FILE******************************/

*仿真图(提供源文件):*

img

### STM32DHT11传感器仿真的实现方法 在Proteus中实现STM32DHT11传感器仿真,通常涉及硬件配置、软件开发以及两者之间的协同工作。以下是详细的说明: #### 硬件配置 在Proteus中搭建电路时,需将STM32微控制器(如STM32F103C8T6)与DHT11温湿度传感器连接。具体接线方式如下: - DHT11的数据引脚连接到STM32的一个GPIO口。 - DHT11的VCC引脚连接至电源(通常是3.3V或5V),GND引脚接地。 此过程可以通过拖拽元件并设置其属性完成[^1]。 #### 软件开发环境 使用Keil uVision5作为开发工具,编写用于读取DHT11数据的嵌入式程序。该程序应包括初始化GPIO端口、发送请求信号给DHT11、接收响应数据等功能[^2]。 以下是一个简单的代码框架示例,展示如何通过HAL库操作GPIO以驱动DHT11传感器: ```c #include "stm32f1xx_hal.h" #define DHT11_PIN GPIO_PIN_0 #define DHT11_PORT GPIOA void DHT11_Init(void){ __HAL_RCC_GPIOA_CLK_ENABLE(); 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_LOW; HAL_GPIO_Init(DHT11_PORT, &GPIO_InitStruct); } uint8_t DHT11_ReadData(void){ uint8_t data=0; // 将引脚切换成输入状态 GPIO_InitStruct.Mode = GPIO_MODE_INPUT; HAL_GPIO_Init(DHT11_PORT,&GPIO_InitStruct); while(HAL_GPIO_ReadPin(DHT11_PORT,DHT11_PIN)==GPIO_PIN_SET); //等待低电平到来 for(int i=0;i<8;i++){ while(HAL_GPIO_ReadPin(DHT11_PORT,DHT11_PIN)==GPIO_PIN_RESET); //等待高电平到来 delay_us(40); //延时一段时间判断高低电平 if(HAL_GPIO_ReadPin(DHT11_PORT,DHT11_PIN)==GPIO_PIN_SET){ //如果此时还是高电平,则表示是‘1’ data |= (1<<(7-i)); } while(HAL_GPIO_ReadPin(DHT11_PORT,DHT11_PIN)==GPIO_PIN_SET); //再等待低电平的到来 } return data; } ``` 上述代码片段展示了基本的DHT11通信逻辑。 #### Proteus中的仿真测试 加载编译后的HEX文件到Proteus项目中的STM32模型上运行即可观察效果。确保使用Proteus版本支持所选型号的MCU及其外设模拟功能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BT-BOX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值