基于STM32温湿度采集Proteus仿真设计

基于STM32温湿度采集Proteus仿真设计

本设计包含Proteus仿真+程序代码

📚开发环境

仿真图:protues 8.9

程序编译器:keil 5

编程语言:C语言

设计编号:C0041

📚功能描述

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

📚仿真图

📚程序代码

c 复制代码
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显示函数

c 复制代码
#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);  //写入数据   
}

DHT11底层驱动代码

c 复制代码
#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******************************/

📚资料清单&下载链接

资料下载链接(可点击):
https://docs.qq.com/doc/DS0dGTnp2bG9xSkJI

相关推荐
d111111111d8 小时前
江协科技-PID基本原理-(学习笔记)-主页有所有STM32外设的笔记基本都是万字起步。
笔记·科技·stm32·单片机·嵌入式硬件·学习
wotaifuzao8 小时前
Nordic-nRF54L 系列架构全景:从蓝牙 6.0 到超低功耗设计详解
单片机·物联网·硬件架构·蓝牙·nordic
xiaohai@Linux8 小时前
STM32上使用HAL库驱动9针FC手柄实现游戏自由!
stm32·fc游戏手柄
1+2单片机电子设计10 小时前
基于 STM32 的太阳能 MPPT 充电控制器设计
stm32·单片机·嵌入式硬件
CFZPL10 小时前
espidf用CMake文件构建项目
单片机·esp32
猪八戒1.011 小时前
9.5 【定时器】输入捕获
单片机·嵌入式硬件
xiaohai@Linux11 小时前
STM32之移植原生的infoNES nes游戏模拟器源码实现游戏自由!!!(原生纯C版,非汇编版)
stm32·游戏·模拟器·infones·nes游戏机
无垠的广袤11 小时前
【启明云端 WT9932S3-Nano 开发板】介绍、环境搭建、工程测试
python·单片机·嵌入式硬件
小李做物联网12 小时前
【单片机毕业设计】143.1基于单片机stm32塔吊控制反馈物联网嵌入式项目程序开发系统
stm32·单片机·嵌入式硬件·物联网