基于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

相关推荐
梁朝辉7 小时前
STM32H750VBT6中ADCINP与INN什么区别
stm32·单片机·嵌入式硬件
崇山峻岭之间9 小时前
单片机无感FOC驱动之ADC
单片机·嵌入式硬件
Ligocious9 小时前
1.点亮一颗小小的LED
单片机·嵌入式硬件
KaifuZeng13 小时前
通信与接口协议面试八、CAN通信
单片机·嵌入式硬件·面试·通信与接口协议
智源单片机设计14 小时前
基于单片机的直流电机双闭环调速系统设计
单片机·嵌入式硬件
kebidaixu15 小时前
两轮车换电 BMS 的模拟前端中颖 SH367306 AFE 芯片详解
stm32
kebidaixu15 小时前
两轮车换电 BMS 的模拟前端中颖 SH367306 AFE 芯片调试实录:四个关键问题与解决方案
stm32
wuyk5551 天前
24. C 语言模块化:不是拆几个.c 文件那么简单
c语言·开发语言·stm32·单片机
lzqrzpt1 天前
LED驱动电源选型标准与工程应用技术要点解析
python·单片机·嵌入式硬件·物联网