基于STM32_HAL库的温湿度检测系统

基于STM32_HAL库的温湿度检测系统

一、项目需求

使用DHT11温湿度传感器检测当前温湿度,当温度达到设定值时打开风扇,并通过LCD1602屏幕显示当前实时温湿度和风扇状态,并把当前的温湿度值和风扇状态上传手机到BLE助手。

加粗样式

二、硬件连接

在这里插入图片描述

项目用到的模块:STM32F103C8T6最小系统板、LCD1602屏幕、DHT11温湿度传感器、HC-08蓝牙模块、继电器模块

LCD1602 to MCU:【D0-D7👉PA0-PA7】【RS👉PB1】【RW👉PB2】【EN👉PB10】

DHT11 to MCU:【data👉PB7】

HC-08 to MCU:【RXD👉PA9】【TXD👉PA10】

继电器 to MCU:【IN👉PB6】


三、项目实现

3.1 CubeMX配置:

  1. 配置Debug

    在这里插入图片描述

  2. 打开RCC配置时钟,将高速时钟配置成Crystal/Ceramic Resonator

    在这里插入图片描述

  3. 点击配置时钟选项,把时钟配置成高速外部时钟HSE,并且通过PLLCLK倍频到72MHZ按下回车之后就为芯片内部的功能分配好了对应的时钟频率。

    在这里插入图片描述

  4. 打开左侧的USART1,首先将串口配置成异步通信模式,对波特率、数据位、奇偶校验位、停止位等进行配置。

    在这里插入图片描述

  5. 我们对LCD1602的GPIO和继电器的GPIO进行配置,把它们全部配置成GPIO_Output模式,因为DHT11我们需要既有输入又有输出,所以在这里先不配置,等到代码中实现。

    在这里插入图片描述

  6. 接着对我们的工程进行配置,配置完成之后点击右上角的 GENERATE CODE 生成工程

    在这里插入图片描述


3.2 代码实现:

dht11.c

#include "dht11.h"

uint8_t datas[5];

/* DHT11 GPIO初始化 */
void DHT_GPIO_Init(uint32_t mode)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	__HAL_RCC_GPIOB_CLK_ENABLE();
	
	GPIO_InitStruct.Pin = GPIO_PIN_7;
	GPIO_InitStruct.Mode = mode;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

void delay_us(uint16_t cnt)
{
	uint8_t i;
	while(cnt)
	{
		for (i = 0; i < 10; i++){	
		}
		cnt--;
	}
}

void DHT11_Start()
{
	DHT_GPIO_Init(GPIO_MODE_OUTPUT_PP);
	DHT_HIGH;
	DHT_LOW;
	HAL_Delay(30);
	DHT_HIGH;
	

	DHT_GPIO_Init(GPIO_MODE_INPUT);
	while(DHT_VALUE);
	while(!DHT_VALUE);
	while(DHT_VALUE);
}

/* 读取DHT温湿度 */
void Read_Data_From_DHT(void)
{
	int i;
	int j;
	char tmp;
	char flag;
	
	DHT11_Start();
	DHT_GPIO_Init(GPIO_MODE_INPUT);
	for(i=0; i<5; i++){
		for(j=0; j<8; j++){
			while(!DHT_VALUE);
			delay_us(40);
			if(DHT_VALUE == 1){
				flag = 1;
				while(DHT_VALUE);
			}else{
				flag = 0;
			}
			tmp = tmp << 1;
			tmp |= flag;
		}
		datas[i] = tmp;
	}
}

dht11.h

#ifndef __DHT11_H__
#define __DHT11_H__

#include "gpio.h"

#define DHT_HIGH  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET)
#define DHT_LOW   HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET)
#define DHT_VALUE HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7)

void Read_Data_From_DHT(void);

#endif

lcd1602.c

#include "lcd1602.h"

/* LCD1602写命令 */
void Write_Cmd_Func(uint8_t cmd)
{
	RS_LOW;
	RW_LOW;
	EN_LOW;
	GPIOA->ODR = cmd;
	HAL_Delay(5);
	EN_HIGH;
	HAL_Delay(5);
	EN_LOW;
}

/* LCD1602写数据 */
void Write_Data_Func(uint8_t dataShow)
{
	RS_HIGH;
	RW_LOW;
	EN_LOW;
	GPIOA->ODR = dataShow;
	HAL_Delay(5);
	EN_HIGH;
	HAL_Delay(5);
	EN_LOW;
}

/* LCD1602初始化 */
void LCD1602_Init(void)
{
	HAL_Delay(15);			// 延时 15ms
	Write_Cmd_Func(0x38);	// 写指令 38H(不检测忙信号)
	HAL_Delay(5);			// 延时 5ms
	Write_Cmd_Func(0x38);	// 写指令 38H:显示模式设置
	Write_Cmd_Func(0x08);	// 写指令 08H:显示关闭
	Write_Cmd_Func(0x01);	// 写指令 01H:显示清屏
	Write_Cmd_Func(0x06);	// 写指令 06H:显示光标移动设置
	Write_Cmd_Func(0x0c);	// 写指令 0CH:显示开及光标设置
}

/* LCD1602显示 */
void LCD1602_showLine(char row, char col, char *string)
{
	switch(row){
		case 1:	
			Write_Cmd_Func(0x80+col);
			while(*string != '\0'){
				Write_Data_Func(*string);
				string++;
			}
			break;
		case 2:
			Write_Cmd_Func(0x80+0x40+col);
			while(*string != '\0'){
				Write_Data_Func(*string);
				string++;
			}
			break;
	}
}

lcd1602.h

#ifndef __LCD1602_H__
#define __LCD1602_H__

#include "gpio.h"

#define RS_GPIO_Port GPIOB
#define RW_GPIO_Port GPIOB
#define EN_GPIO_Port GPIOB
#define RS_PIN 		 GPIO_PIN_1
#define RW_PIN 		 GPIO_PIN_2
#define EN_PIN 		 GPIO_PIN_10

#define RS_HIGH HAL_GPIO_WritePin(RS_GPIO_Port, RS_PIN, GPIO_PIN_SET)
#define RS_LOW  HAL_GPIO_WritePin(RS_GPIO_Port, RS_PIN, GPIO_PIN_RESET)
#define RW_HIGH HAL_GPIO_WritePin(RW_GPIO_Port, RW_PIN, GPIO_PIN_SET)
#define RW_LOW  HAL_GPIO_WritePin(RW_GPIO_Port, RW_PIN, GPIO_PIN_RESET)
#define EN_HIGH HAL_GPIO_WritePin(EN_GPIO_Port, EN_PIN, GPIO_PIN_SET)
#define EN_LOW  HAL_GPIO_WritePin(EN_GPIO_Port, EN_PIN, GPIO_PIN_RESET)

void LCD1602_Init(void);
void LCD1602_showLine(char row, char col, char *string);

#endif

gpio.c

#include "gpio.h"

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/*----------------------------------------------------------------------------*/
/* Configure GPIO                                                             */
/*----------------------------------------------------------------------------*/
/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

/** Configure pins as
        * Analog
        * Input
        * Output
        * EVENT_OUT
        * EXTI
*/
void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, 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_SET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10, GPIO_PIN_SET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);

  /*Configure GPIO pins : PA0 PA1 PA2 PA3
                           PA4 PA5 PA6 PA7 */
  GPIO_InitStruct.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_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pins : PB1 PB2 PB10 PB6 */
  GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10|GPIO_PIN_6;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

/* USER CODE BEGIN 2 */

/* USER CODE END 2 */

usart.c

/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usart.h"

/* USER CODE BEGIN 0 */
#include <stdio.h>

int fputc(int ch, FILE *f)
{
	unsigned char temp[1]={ch};
	HAL_UART_Transmit(&huart1,temp,1,0xffff);
	return ch;
}
/* USER CODE END 0 */

UART_HandleTypeDef huart1;

/* USART1 init function */

void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 9600;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */

  /* USER CODE END USART1_Init 2 */

}

main.c

#include "main.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include <string.h>
#include "lcd1602.h"
#include "dht11.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
extern uint8_t datas[5];
/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
	/* USER CODE BEGIN 1 */
	char message[16];
	/* USER CODE END 1 */

	/* MCU Configuration--------------------------------------------------------*/

	/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
	HAL_Init();

	/* USER CODE BEGIN Init */

	/* USER CODE END Init */

	/* Configure the system clock */
	SystemClock_Config();

	/* USER CODE BEGIN SysInit */

	/* USER CODE END SysInit */

	/* Initialize all configured peripherals */
	MX_GPIO_Init();
	MX_USART1_UART_Init();
	/* USER CODE BEGIN 2 */
	LCD1602_Init();													// LCD初始化
	LCD1602_showLine(1, 13, "FS:");
	/* USER CODE END 2 */

	/* Infinite loop */
	/* USER CODE BEGIN WHILE */
	while (1)
	{
	/* USER CODE END WHILE */

		/* USER CODE BEGIN 3 */
		Read_Data_From_DHT();										// 读取DHT温湿度
		if(datas[2] >= 27){											// 如果温度达到27℃打开风扇
			HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
			printf("风扇已打开\r\n");								// 风扇状态上传到BLE-APP
			LCD1602_showLine(2,13, "ON ");							// LCD显示风扇状态
		}else{
			HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
			LCD1602_showLine(2,13, "OFF");
		}
		memset(message, 0, sizeof(message));
		sprintf(message,"Temp = %d.%d",datas[2], datas[3]);	
		LCD1602_showLine(1, 0, message);							// LCD显示当前温度
		memset(message, 0, sizeof(message));
		sprintf(message,"Humi = %d.%d",datas[0], datas[1]);			
		LCD1602_showLine(2, 0, message);							// LCD显示当前湿度

		printf("Temp = %d.%d℃ ",datas[2], datas[3]);				// 上传当前温度到BLE-APP
		printf("Humi = %d.%d\r\n",datas[0], datas[1]);				// 上传当前湿度到BLE-APP
		HAL_Delay(1000);											// 1s读取一次
	}
		/* USER CODE END 3 */
}

代码写完之后我们编译并且烧录进我们的单片机,就实现了我们的效果:

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值