首页 > 其他分享 >温湿度传感器的学习及基于串口和逻辑分析仪的验证

温湿度传感器的学习及基于串口和逻辑分析仪的验证

时间:2024-07-13 16:19:54浏览次数:8  
标签:USART 温湿度 分析仪 InitStructure 串口 GPIO USART1 DHT11

目录

温湿度传感器

温湿度传感器的基本概述

image

测量精度

image

硬件接线

image

时序分析

image

接收数据分析

image

代码

全局变量

GPIO_InitTypeDef  GPIO_InitStructure;   //定义GPIO外设的结构体变量

配置DHT11为输出模式

void DHT11_OutputConfig(void)
{
    //1.打开GPIOG端口的时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);
	
	//2.配置PG9引脚为输出模式
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
	
	//3.对GPIOG端口进行初始化
	GPIO_Init(GPIOG, &GPIO_InitStructure);

}

配置DHT11为输入模式

//配置DHT11为输入模式
void DHT11_InputConfig(void)
{
    //1.打开GPIOG端口的时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);
	
	//2.配置PG9引脚为输入模式
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	
	//3.对GPIOG端口进行初始化
	GPIO_Init(GPIOG, &GPIO_InitStructure);
}

配置初始化DHT11

void DHT11_Config(void)
{	
	DHT11_OutputConfig();
}

发送开始信号

void Sent_StartSignal(void)
{
    //将主机设置为输出模式并输出高电平并延时5ms  ——>空闲模式
    DHT11_OutputConfig();
    GPIO_SetBits(GPIOG, GPIO_Pin_9);
    delay_ms(5);
    
    //输出低电平并延时20ms
    GPIO_ResetBits(GPIOG, GPIO_Pin_9);
    delay_ms(20);
    
    //输出高电平并延时30us
    GPIO_SetBits(GPIOG, GPIO_Pin_9);
    delay_us(30);         
}

判断DHT11温湿度传感器是否应答

bool Is_DHT11ACK(void)
{
    //定义一个计数器用来记数
    u32 cont = 0;
    
    //配置PG9为输入模式
    DHT11_InputConfig();
    
    //此时总线为高电平,需要等待总线拉低为低电平,并做超时处理
    while( (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_9)) && cont < 50)
    {
        delay_us(1);
        cont++;
    }
    
    //判断延时了多少us
    if(cont >= 50) 
    {
        return false; //说明超时了
    }
    
    //计数器清零
    cont = 0;
    
    //这里为DHT11的应答
    //此时总线为低电平,需要等待总线拉高为高电平,并计数
    while((! GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_9)) && cont < 100)
    {
        delay_us(1);
        cont++;
    }
    
    //判断延时了多少us
    if(cont >= 100) 
    {
        return false; //说明超时了
    }
    
    return true;
}

接收一位数据

u8 Recv_DHT11Bit(void)
{
    //定义计时器
    u32 cont = 0;
    
    //此时为高电平,需要等待低电平出现
    while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_9) );
    
    //此时为低电平,需要等待总线电平变为高电平
    while( ! GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_9) );
    
    //此时为高电平,需要等待总线电平变为低电平,并通过判断高电平的持续时间,从而判断数据是0还是1
    while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_9) )
    {
        delay_us(1);
        cont++;
    }
    
    
    if( cont <= 50)
        return 0;
    else
        return 1;
}

接收一个字节的数据

u8 Recv_DHT11Byte(void)
{
    //定义用来接收数据的变量
    u8 data = 0;
    
    //循环接收数据
    for(u32 i = 0; i<8; i++)
    {
        data <<= 1 ;
        data |=Recv_DHT11Bit();
    }
    
    return data;
}

接收DHT11传输的数据

义计时器
    //u32 cont = 0;
    
    //1.配置PG9为输出模式
    DHT11_OutputConfig();
        
    //2.发送开始信号
    Sent_StartSignal();
    
    //3.等待DHT11应答
    if(Is_DHT11ACK())
    {
        
        //6.开始接收数据
        for( u32 i = 0; i<5; i++)
        {
            DHT11Data[i] = Recv_DHT11Byte();
        }
        
        //7.检验校验和
        if(DHT11Data[4] == DHT11Data[0] + DHT11Data[1] + DHT11Data[2] + DHT11Data[3])
            return true;
        else
            return false;
        
    }
    else
        return false;
}

串口USART1的初始化

void USART1_Config(u32 baud)
{
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	
	//打开了GPIO端口时钟  PA9和PA10
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	
	//打开USART1的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	
	//选择GPIO引脚的复用功能
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource9 , GPIO_AF_USART1);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
	
	//配置GPIO引脚 注意:复用模式
	GPIO_InitStructure.GPIO_Mode 	= GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd 	= GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Pin 	= GPIO_Pin_9|GPIO_Pin_10;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	//配置串口参数+对串口初始化
	USART_InitStructure.USART_BaudRate = baud;																			//波特率
	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(USART1, &USART_InitStructure);

	//配置NVIC参数 + 对NVIC初始化
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
	
	//选择USART1的中断源,接收到数据则触发中断
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
	
	//打开串口
	USART_Cmd(USART1, ENABLE);
}

利用串口发送一个字符串

//利用串口发送一个字符串
void  USART1_SendString(const char *str)
{
	while(*str)
	{
		 USART_SendData(USART1,*str++);
		 while( USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET );		
	}
}

主函数

/**
   ******************************************************************************
   * @file      main.c 
   * @author  	Dazz
   * @version 	v1.0
   * @date      2024/07/12
   * @brief     利用温湿度传感器DHT11获取温度和湿度,并重定向到串口输出
   * @None      DQ -> PG9                                        
   ******************************************************************************
**/

#include "stm32f4xx.h"  //必须包含
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "DHT11.h"
#include "delay.h"

#define  BUFSIZE        128

uint8_t  recvbuf[BUFSIZE] ={0};  //用于存储串口收到的数
uint32_t recvcnt = 0;						 //用于作为数组的计数器
u8 DHT11Data[5] = "0";          //用于接收DHT11的数据

//前台程序就是中断服务程序,该程序是不需要手动调用的,当中断触发之后CPU会自动跳转过来执行该函数
void USART1_IRQHandler(void)
{
	uint8_t data;
  //判断中断是否发生
  if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
  {   
		//从USART1中接收一个字节
		data = USART_ReceiveData(USART1);  //一次只能接收一个字节   
		
		//把接收到的数据转发出去
		USART_SendData(USART1,data);
  }
}



int main()
{
	
	//1.硬件的初始化
	USART1_Config(9600);  //串口
    DHT11_Config();       //DHT11温湿度传感器
    
    u8 data[128] = "0";
	
	
	while(1)
	{
        Recv_DHT11Data(DHT11Data);
        sprintf((char*)data, "湿度 = %d%%RH, 温度 = %d℃\r\n", DHT11Data[0], DHT11Data[2]);
        USART1_SendString((char*)data);
        delay_ms(500);
	}
}

串口验证

image

逻辑分析仪的验证

空闲高电平/主机发送开始信号

image

从机应答

image

接收数据

数据'0'

image

数据'1'

image

标签:USART,温湿度,分析仪,InitStructure,串口,GPIO,USART1,DHT11
From: https://www.cnblogs.com/Dazz24/p/18300261

相关文章

  • STM32驱动-DHT11(温湿度模块)
    STM32驱动-DHT11(温湿度模块)一、DHT11模块简介DHT11是一款含有已校准数字信号输出的温湿度复合传感器,它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接......
  • vofa与单片机的串口通信笔记
    1.HAL_UART_Receive(UART_HandleTypeDef*huart,uint8_t*pData,uint16_tSize,uint32_tTimeout)/*      huart:使用哪个串口进行通信      pData:一个地址,用于保存接受到的数据      Size:接收的数据个数Timeout:超时时间         ......
  • gd32F470串口重定义
    c代码:/**@Author:Bleaach008*@Date:2024-07-1017:31:01*@LastEditTime:2024-07-1109:42:06*@FilePath:\MDK-ARMd:\Code\GD32\GD01_UART\MyApplication\Public.c*@Description:**Copyright(c)2024by008,AllRightsReserved.*//*Incl......
  • 树莓派4B-用串口读取JY901S陀螺仪数据
    相关知识介绍陀螺仪是一种用来感测与维持方向的装置,基于角动量的理论设计出来的。陀螺仪主要是由一个位于轴心可以旋转的轮子构成,陀螺仪一旦开始旋转,由于轮子的「角动量」,陀螺仪有抗拒方向改变的趋向。陀螺仪多用于导航、定位等系统JY901S是9轴姿态角度传感器,支持串口和IIC......
  • 串口通信&控制LED
    目录1.串口介绍2.硬件电路3.电平标准4.接口及引脚定义5.常见通信接口比较6.51单片机的UART7.串口参数及时序图8.串口模式图9.串口和中断系统10.串口相关寄存器11.串口向电脑发送数据12.电脑通过串口控制LED1.串口介绍串口是一种应用十分广泛的......
  • stm32串口接受定长和不定长数据的两种中断方式
    stm32串口有两种中断方式1.字节中断(定长数据接受)接收指定字节数的数据后产生中断:HAL_UART_Receive_IT(&huart3,rxBuffer,21);注意这里仍然是接受一个字节进入一次IRQ中断函数,这里指定的字节数指的是接受指定字节数量后进入一次回调函数,由于IRQ函数会关闭中断,如需重复接受定......
  • 通信方式中常用的串口,你真的了解么?
    串口介绍一、引言串行接口(SerialPort),简称串口,是计算机与外部设备或其他计算机之间进行数据交换的一种通信接口。与并行通信相比,串行通信通过一条或几条信号线按顺序传输数据,具有接口简单、传输距离长等优点。串口在计算机历史中占据了重要位置,即便在今天,许多工业控制系统、......
  • 串口电平多种,TLL、232、485、422到底应该如何选择?
    串口通信是电子设备之间进行数据交换的重要方式,其中常见的电平标准包括TTL电平、RS-232电平、RS-485电平和RS-422电平。本文将详细介绍这些电平的由来、原理、特点、优缺点、应用、实现方式及接线方式,帮助各位同学或工程师更好地理解这些通讯基础。TTL电平TTL(Transistor......
  • stm32串口 环形缓冲区 代码
    voidHAL_UART_RxCpltCallback(UART_HandleTypeDef*huart){ //printf("ITIN\r\n");// printf("%d\r\n",HAL_GetTick()); //置零设定电流值PID时间if(huart->Instance==USART3){ //将数据放入缓冲区 circular_buffer.buffe......
  • stm32学习笔记---USART串口数据包(代码部分)串口收发HEX数据包/文本数据包
    目录第一个代码:串口收发HEX数据包Serial.cSerial.hMain.c第二个程序:串口收发文本数据包Serial.cSerial.hMain.c声明:本专栏是本人跟着B站江科大的视频的学习过程中记录下来的笔记,我之所以记录下来是为了方便自己日后复习。如果你也是跟着江科大的视频学习的,可以配套......