利用Proteus仿真STM32实现DHT11温湿度检测

发布时间:2024-06-11  

1. 前言

Proteus是英国著名的EDA工具(仿真软件),从原理图布图、代码调试到单片机与外围电路协同仿真,一 键切换到PCB设计,真正实现了从概念到产品的完整设计。是世界上唯一将电路仿真软件、PCB设计软 件和虚拟模型仿真软件三合一的设计平台,其处理器模型支持8051、HC11、 PIC10/12/16/18/24/30/DSPIC33、AVR、ARM、8086和MSP430等,2010年又增加了Cortex和DSP系 列处理器,并持续增加其他系列处理器模型。在编译方面,它也支持IAR、Keil和MATLAB等多种编译 器。 前面文章介绍了Proteus的下载,安装,建立工程,完成LED灯仿真运行。这篇文章在这基础上增加串口打印,DHT11温湿度检测。

2. 设计程序

先使用keil软件就将程序设计设计好,然后生成HEX文件,等待设计好原理图后进行仿真测试。


注意: 当前使用的芯片是STM32F103。Proteus的版本是8.9

image-20220524143658130

#include "stm32f10x.h"

#include "led.h"

#include "delay.h"

#include "key.h"

#include "dht11.h"


/*

(3)温湿度传感器: DHT11

VCC--VCC

GND---GND

DAT---PA5 

*/


#include "stm32f10x.h"

#include 

#include 

#include "sys.h"

#include 


#define USART1_RX_LENGTH 1024

extern u8 USART1_RX_BUFFER[USART1_RX_LENGTH]; //保存接收数据的缓冲区

extern u32 USART1_RX_CNT; //当前接收到的数据长度

extern u8 USART1_RX_FLAG; //1表示数据接收完毕 0表示没有接收完毕


#define USART2_RX_LENGTH 1024

extern u8 USART2_RX_BUFFER[USART2_RX_LENGTH]; //保存接收数据的缓冲区

extern u32 USART2_RX_CNT; //当前接收到的数据长度

extern u8 USART2_RX_FLAG; //1表示数据接收完毕 0表示没有接收完毕


#define USART3_RX_LENGTH 1024

extern u8 USART3_RX_BUFFER[USART3_RX_LENGTH]; //保存接收数据的缓冲区

extern u32 USART3_RX_CNT; //当前接收到的数据长度

extern u8 USART3_RX_FLAG; //1表示数据接收完毕 0表示没有接收完毕


void USART1_Init(u32 baud);

void USART2_Init(u32 baud);

void USART3_Init(u32 baud);

void USARTx_StringSend(USART_TypeDef *USARTx,char *str);

void USARTx_DataSend(USART_TypeDef *USARTx,u8 *data,u32 len);


//定义按键IO口

#define KEY_S3 PAin(1) 


//函数声明

void KEY_Init(void);

u8 KEY_Scan(u8 mode);



//LED定义

#define LED1 PBout(6)

#define LED2 PBout(7)

#define LED3 PBout(8)

#define LED4 PBout(9)


//蜂鸣器IO口定义

#define BEEP PAout(6)


//函数声明

void LED_Init(void);

void BEEP_Init(void);




//IO方向设置

#define DHT11_IO_IN()  {GPIOA->CRL&=0XFF0FFFFF;GPIOA->CRL|=0x00800000;}

#define DHT11_IO_OUT() {GPIOA->CRL&=0XFF0FFFFF;GPIOA->CRL|=0x00300000;}

////IO操作函数                                            

#define DHT11_DQ_OUT PAout(5) //数据端口    PA5 

#define DHT11_DQ_IN  PAin(5) //数据端口    PA5



u8 DHT11_Init(void);        //初始化DHT11

u8 DHT11_Read_Data(u8 *temp,u8 *humi);//读取温湿度

u8 DHT11_Read_Byte(void);   //读出一个字节

u8 DHT11_Read_Bit(void);    //读出一个位

u8 DHT11_Check(void);       //检测是否存在DHT11

void DHT11_Rst(void);       //复位DHT11  


//复位DHT11

void DHT11_Rst(void)      

{         

     DHT11_IO_OUT();   //SET OUTPUT

  DHT11_DQ_OUT=0;     //拉低DQ

  DelayMs(20);       //拉低至少18ms

  DHT11_DQ_OUT=1;     //DQ=1 

     DelayUs(30);    //主机拉高20~40us

}

//等待DHT11的回应

//返回1:未检测到DHT11的存在

//返回0:存在

u8 DHT11_Check(void)      

{  

    u8 retry=0;

    DHT11_IO_IN();//SET INPUT    

 while (DHT11_DQ_IN&&retry<100)//DHT11会拉低40~80us

     {

         retry++;

         DelayUs(1);

     };   

     if(retry>=100)return 1;

    else retry=0;

  while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~80us

     {

         retry++;

         DelayUs(1);

     };

     if(retry>=100)return 1;   

    return 0;

}

//从DHT11读取一个位

//返回值:1/0

u8 DHT11_Read_Bit(void)              

{

    u8 retry=0;

    while(DHT11_DQ_IN&&retry<100)//等待变为低电平

     {

         retry++;

         DelayUs(1);

     }

     retry=0;

     while(!DHT11_DQ_IN&&retry<100)//等待变高电平

     {

         retry++;

         DelayUs(1);

     }

     DelayUs(40);//等待40us

     if(DHT11_DQ_IN)return 1;

     else return 0;         

 }

 

 //从DHT11读取一个字节

 //返回值:读到的数据

 u8 DHT11_Read_Byte(void)    

 {        

     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,读取失败

 u8 DHT11_Read_Data(u8 *temp,u8 *humi)    

 {        

     u8 buf[5];

     u8 i;

     DHT11_Rst();

     //printf("------------------------rn");

     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;       

 }

 

 

 //初始化DHT11的IO口 DQ 同时检测DHT11的存在

 //返回1:不存在

 //返回0:存在         

 u8 DHT11_Init(void)

 {

     RCC->APB2ENR|=1<<2;    //使能PORTA口时钟 

     GPIOA->CRL&=0XFF0FFFFF;//PORTA.5 推挽输出

    GPIOA->CRL|=0X00300000;

    GPIOA->ODR|=1<<5;      //输出1                    

     DHT11_Rst();

     return DHT11_Check();

 }

 

 

 /*

 函数功能:按键初始化

 硬件连接:PA1

 特性: 按下为低电平---没按下高电平

 */

 void KEY_Init(void)

 {

     //开时钟

     RCC->APB2ENR|=1<<2;

     //配置模式

     GPIOA->CRL&=0xFFFFFF0F;

  GPIOA->CRL|=0x00000080;

  //上拉

  GPIOA->ODR|=1<<1;

 }

 

 

 /*

 函数功能:函数扫描函数

 函数参数: mode=1表示使用连续模式  mode=0使用单击模式

 返回值:  2 3 4 5 表示具体的按钮   0表示没有按下

 */

 u8 KEY_Scan(u8 mode)

 {

    static u8 flag=1; //记录上一次按下的状态 

    if(mode)flag=1;

    if(flag&&(KEY_S3==0))

    {

        flag=0;

        delay_ms(20);

        if(KEY_S3==0)return 3;

    }

    else if(KEY_S3)

    {

        flag=1; 

    }

    return 0;

 }

 

 

 /*

 函数功能: LED初始化

 硬件连接: PB6 PB7 PB8 PB9

 特性: 低电平点亮

 */

 void LED_Init(void)

 {

     //开时钟

     RCC->APB2ENR|=1<<3;

     //配置GPIO口

     GPIOB->CRL&=0x00FFFFFF;

  GPIOB->CRL|=0x22000000;

  GPIOB->CRH&=0xFFFFFF00;

  GPIOB->CRH|=0x00000022;

  //上拉

  GPIOB->ODR|=1<<6;

     GPIOB->ODR|=1<<7;

     GPIOB->ODR|=1<<8;

     GPIOB->ODR|=1<<9;

 }

 

 /*

 函数功能: 蜂鸣器初始化

 硬件连接: PA6

 特性: 高电平响

 */

 void BEEP_Init(void)

 {

    RCC->APB2ENR|=1<<2;

    GPIOA->CRL&=0xF0FFFFFF;

  GPIOA->CRL|=0x02000000;

}



/*

函数功能: 串口1的初始化

硬件连接: PA9(TX)  和 PA10(RX)

*/

void USART1_Init(u32 baud)

{

  /*1. 开时钟*/

  RCC->APB2ENR|=1<<14; //USART1时钟

     RCC->APB2ENR|=1<<2;  //PA

     RCC->APB2RSTR|=1<<14; //开启复位时钟

     RCC->APB2RSTR&=~(1<<14);//停止复位

     /*2. 配置GPIO口的模式*/

     GPIOA->CRH&=0xFFFFF00F;

  GPIOA->CRH|=0x000008B0;

  /*3. 配置波特率*/

  USART1->BRR=72000000/baud;

  /*4. 配置核心寄存器*/

  USART1->CR1|=1<<5; //开启接收中断

     STM32_SetPriority(USART1_IRQn,1,1); //设置中断优先级

     USART1->CR1|=1<<2; //开启接收

     USART1->CR1|=1<<3; //开启发送

     USART1->CR1|=1<<13;//开启串口功能

 }

 

 /*

 函数功能: 串口2的初始化

 硬件连接: PA2(TX)  和 PA3(RX)

 */

 void USART2_Init(u32 baud)

 {

     /*1. 开时钟*/

     RCC->APB1ENR|=1<<17; //USART2时钟

     RCC->APB2ENR|=1<<2;  //PA

     RCC->APB1RSTR|=1<<17; //开启复位时钟

     RCC->APB1RSTR&=~(1<<17);//停止复位

     

     /*2. 配置GPIO口的模式*/

     GPIOA->CRL&=0xFFFF00FF;

  GPIOA->CRL|=0x00008B00;

  /*3. 配置波特率*/

  USART2->BRR=36000000/baud;

  /*4. 配置核心寄存器*/

  USART2->CR1|=1<<5; //开启接收中断

     STM32_SetPriority(USART2_IRQn,1,1); //设置中断优先级

     USART2->CR1|=1<<2; //开启接收

     USART2->CR1|=1<<3; //开启发送

     USART2->CR1|=1<<13;//开启串口功能

 }

 

 /*

 函数功能: 串口3的初始化

 硬件连接: PB10(TX)  和 PB11(RX)

 */

 void USART3_Init(u32 baud)

 {

     /*1. 开时钟*/

     RCC->APB1ENR|=1<<18; //USART3时钟

     RCC->APB2ENR|=1<<3;  //PB

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>