基于STM32和DHT11的温湿度测试仪

2024-03-19 19:20

本文主要是介绍基于STM32和DHT11的温湿度测试仪,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

设计要求

知识点

功能概述

基本要求

通信要求

STM32配置

LCD屏设置

 UARR串口设置

 RCC时钟设置

 LED引脚设置

 ADC设置

 温湿度传感器数据输入输出引脚设置

 DMA设置

 NVIC中断设置

 代码示例

lcd.h和lcd.c的导入

main.c

stm32g0xx_it.c(串口中断服务程序所在的.c文件)

lcd.c

lcd.h

dht11.c

dht11.h


设计要求

知识点

需要⽤到GPIO输⼊输出,定时器,串⼝通信,ADC(DMA⽅式实现),LCD屏幕,DHT11

功能概述

模块功能
LCD显示温湿度,风机开关情况,制冷片开关情况,加热片开关情况,温湿度上下阈值,设备ID
LED三个灯分别模拟风机、制冷片、加热片,灯亮表示开,灯灭表示关
DHT11温湿度传感器
PA0电池电压采集
串口数据接收及下发数据控制
低温加热当环境温度低于设置的阈值时,加热片开启,加热到最低温阈值加5摄氏度停止加热
高温降温当环境温度高于设置的阈值时,制冷片开启,降温到最高温阈值减5摄氏度停止降温
高湿干燥当环境湿度高于设置的阈值时,风机开启,干燥到低于最高湿度阈值停止

基本要求

加湿器上电设备⾃检(检查传感器采集是否正常,这个DHT11有存在响应,可以⾃检使⽤,有电池电压检 测,这⾥可以判断电压是否正常),⾃检通过后进⼊⾃动模式,LCD显示温湿度信息以及电池电压。当 湿度达到启动阀值⾃动启动,低于(启动阀值)则停⽌⼯作。 通过五向按键选择并调整温湿度的阙值⼤⼩,以及设备ID号。 与上位机通信(串⼝助⼿),每2s发送设备状态信息到上位机。上位机可发送命令设置除湿器(这⾥需 要识别设备ID),上位机可发送指令获取设备状态信息。

通信要求

• 通讯协议
• 通讯⽅式(暂时使⽤串⼝):9600-N-8-1,MODBUS 协议,参数及内容如下表所示
地址数据信息备注
0包头0x55
1设备ID可读
2环境温度可读
3环境湿度可读
4湿度启动值可读可写
5加热启动值可读可写
6设备ID设置只写
7包尾0xFF
• 除湿原理(作为了解简单看看就⾏)
当潮湿空⽓经⻛扇吸⼊后,通过特殊设计的⻛道流动,先经半导体制冷器降温结露,制冷器的结露在重 ⼒作⽤下滴⼊引⽔槽,再由导⽔管流出柜外。在设定启动值内经过充分循环除湿,使柜内空⽓湿度降⾄ 结露点以下,完成整个防潮引凝加热过程。同时,除湿装置信号采集传感器外置,能实时准确的采集到 柜内的真实湿度,保证除湿装置在柜内将要达到凝露条件时提前启动除湿。
根据⾃身情况分级做:
1、根据阙值控制LED,并且上传串⼝助⼿,串⼝助⼿可下发配置
2、根据阙值控制LED,并且上传串⼝助⼿,串⼝助⼿可下发配置,LCD显示
3、除了modbus外所有功 能
4、全部功能

STM32配置

LCD屏设置

 UARR串口设置

 RCC时钟设置

 LED引脚设置

 ADC设置

 PA0采集电源电压值,PA1采集五向键五个不同方向按键按下的电压

 再将五向键设置为外部中断,PA8的值判断是否按下按键,当按下的时候调用外部中断函数

 温湿度传感器数据输入输出引脚设置

 DMA设置

 NVIC中断设置

 代码示例

lcd.h和lcd.c的导入

main.c

/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.* All rights reserved.</center></h2>** This software component is licensed by ST under BSD 3-Clause license,* the "License"; You may not use this file except in compliance with the* License. You may obtain a copy of the License at:*                        opensource.org/licenses/BSD-3-Clause********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "dma.h"
#include "usart.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "dht11.h"
#include <stdio.h>
#include "lcd.h"
#include <string.h>
static uint32_t fac_us = 0; //us延时倍乘数void delay_init(uint8_t SYSCLK)
{fac_us = SYSCLK;
}void delay_us(uint32_t nus)//100  6800
{uint32_t ticks;uint32_t told, tnow, tcnt = 0;uint32_t reload = SysTick->LOAD; //LOAD的值ticks = nus * fac_us;            //需要的节拍数told = SysTick->VAL;             // 24  刚进入时的计数器值while (1){tnow = SysTick->VAL;//22  20  0if (tnow != told){if (tnow < told)tcnt += told - tnow; //这里注意一下SYSTICK是一个递减的计数器就可以了.elsetcnt += reload - tnow + told;told = tnow;if (tcnt >= ticks)break; //时间超过/等于要延迟的时间,则退出.}};
}
void delay_ms(uint16_t nms)
{uint32_t i;for (i = 0; i < nms; i++)delay_us(1000);
}
/* USER CODE END 4 */
/* 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 *//* 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 */
uint8_t humiH;
uint8_t humiL;
uint8_t tempH;
uint8_t tempL;
/* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t tempHthres=30;  //高温阈值
uint8_t tempLthres=26;  //低温阈值
uint8_t humiHthres=60;  //湿度阈值
uint16_t buf[2];//获取到的电压和按键值
int val,key;//获取按键值
int flag=0;//标志位
char Buf[128];
uint8_t cmdbuf[128];
uint8_t valuebuf[128];
float temp;//温度
uint8_t fj;//风机制冷制热
uint8_t zl;
uint8_t zr;uint8_t FJ[12];
uint8_t JR[12];
uint8_t ZL[12];extern int flag1;void recivemag();
void show();
void setstatus();
uint16_t chartoint();
/* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* 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_DMA_Init();MX_USART1_UART_Init();MX_ADC1_Init();MX_USART2_UART_Init();/* USER CODE BEGIN 2 */delay_init(64);FS_DHT11_Init();Lcd_Init();//初始化LCD屏Lcd_Clear(BLACK);Gui_DrawFont_GBK16(40,60,WHITE,BLACK,"Weclome");//显示welcomeHAL_Delay(500);Lcd_Clear(BLACK);Gui_DrawFont_GBK16(0,15,WHITE,BLACK,"Volt:");//显示电压Gui_DrawFont_GBK16(0,15,WHITE,BLACK,"Elect:");//显示电量Gui_DrawFont_GBK16(0,30,WHITE,BLACK,"Tempe:");//显示温度Gui_DrawFont_GBK16(0,45,WHITE,BLACK,"humi:");//显示湿度Gui_DrawFont_GBK16(0,60,WHITE,BLACK,"HThres:");//高温阈值float H=tempHthres;char ht[32];sprintf(ht,"%.2fC",H);Gui_DrawFont_GBK16(55,60,WHITE,BLACK,(uint8_t *)ht);Gui_DrawFont_GBK16(0,75,WHITE,BLACK,"LThres:");//低温阈值float L=tempLthres;char lt[32];sprintf(lt,"%.2lfC",L);Gui_DrawFont_GBK16(55,75,WHITE,BLACK,lt);Gui_DrawFont_GBK16(0,90,WHITE,BLACK,"HumThres:");//湿度阈值int Hu=humiHthres;char hum[32];sprintf(hum,"%d%%%",Hu);Gui_DrawFont_GBK16(75,90,WHITE,BLACK,(uint8_t *)hum);fj='F';zl='F';zr='F';sprintf(FJ,"FJ:%c",fj);sprintf(ZL,"ZL:%c",zl);sprintf(JR,"ZR:%c",zr);Gui_DrawFont_GBK16(0,105,WHITE,BLACK,FJ);//风机开关Gui_DrawFont_GBK16(45,105,WHITE,BLACK,ZL);//制冷片开关Gui_DrawFont_GBK16(90,105,WHITE,BLACK,JR);//加热片开关char t[128],h[128];//温度、湿度实时监测//	Gui_DrawFont_GBK16(25,105,WHITE,BLACK,&fj);//风机开关状态
//	Gui_DrawFont_GBK16(70,105,WHITE,BLACK,&zl);//制冷片开关状态
//	Gui_DrawFont_GBK16(115,105,WHITE,BLACK,&zr);//加热片开关状态HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2,GPIO_PIN_SET);HAL_UART_Receive_DMA(&huart1,(uint8_t *)Buf,128);__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */HAL_ADC_Start_DMA(&hadc1,(uint32_t *)buf,2);DHT11_Read_Data(&humiH,&humiL,&tempH,&tempL);temp = tempH + tempL*0.1;HAL_Delay(500);//printf("temp = %.2fC  humi = %d%%",temp,humiH);sprintf(t,"%.2fC",temp);sprintf(h,"%d%%",humiH);Gui_DrawFont_GBK16(50,30,WHITE,BLACK,(uint8_t *)t);Gui_DrawFont_GBK16(50,45,WHITE,BLACK,(uint8_t *)h);if(temp>tempHthres)//超过高温阈值,制冷打开,直到温度低于高温阈值-5{zl='T';sprintf(ZL,"ZL:%c",zl);Gui_DrawFont_GBK16(45,105,WHITE,BLACK,ZL);//制冷片开关HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET);}else if(temp<tempHthres-5){zl='F';sprintf(ZL,"ZL:%c",zl);Gui_DrawFont_GBK16(45,105,WHITE,BLACK,ZL);//制冷片开关HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET);}if(temp<tempLthres)//低于低温阈值{zr='T';sprintf(JR,"ZR:%c",zr);Gui_DrawFont_GBK16(90,105,WHITE,BLACK,JR);//加热片开关HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET);}else if(temp>tempLthres+5){zr='F';sprintf(JR,"ZR:%c",zr);Gui_DrawFont_GBK16(90,105,WHITE,BLACK,JR);//加热片开关HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET);}if(humiH>humiHthres)//大于湿度阈值{fj='T';sprintf(FJ,"FJ:%c",fj);Gui_DrawFont_GBK16(0,105,WHITE,BLACK,FJ);//风机开关HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_RESET);}else if(humiH<humiHthres){fj='F';sprintf(FJ,"FJ:%c",fj);Gui_DrawFont_GBK16(0,105,WHITE,BLACK,FJ);//风机开关HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_SET);}show();if(flag1==1){flag1=0;recivemag();}}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};/** Configure the main internal regulator output voltage*/HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;RCC_OscInitStruct.PLL.PLLN = 12;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV3;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}/** Initializes the peripherals clocks*/PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_ADC;PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1;PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_SYSCLK;if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 */
int fputc(int ch,FILE *p)
{while(!(USART1->ISR &(1<<7)));USART1->TDR = ch;return ch;
}//按键中断
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{int val,key;if(GPIO_Pin==GPIO_PIN_8){HAL_ADC_Start_DMA(&hadc1,(uint32_t *)buf,2);//按键操作HAL_ADC_Start(&hadc1);while(!(ADC1->ISR&(1<<2)));val=HAL_ADC_GetValue(&hadc1);while(!(ADC1->ISR&(1<<3)));key=HAL_ADC_GetValue(&hadc1);HAL_ADC_Stop(&hadc1);printf("%d",key);if(key>800&&key<1000)//向下选择{if(flag==0||flag==3){flag=1;Gui_DrawFont_GBK16(0,60,RED,BLACK,"HThres:");//高温阈值Gui_DrawFont_GBK16(0,75,WHITE,BLACK,"LThres:");//低温阈值Gui_DrawFont_GBK16(0,90,WHITE,BLACK,"HumThres:");//湿度阈值}else if(flag==1){flag=2;Gui_DrawFont_GBK16(0,60,WHITE,BLACK,"HThres:");//高温阈值Gui_DrawFont_GBK16(0,75,RED,BLACK,"LThres:");//低温阈值Gui_DrawFont_GBK16(0,90,WHITE,BLACK,"HumThres:");//湿度阈值}else if(flag==2){flag=3;Gui_DrawFont_GBK16(0,60,WHITE,BLACK,"HThres:");//高温阈值Gui_DrawFont_GBK16(0,75,WHITE,BLACK,"LThres:");//低温阈值Gui_DrawFont_GBK16(0,90,RED,BLACK,"HumThres:");//湿度阈值}}if(key>2000&&key<2500)//向上选择{if(flag==0||flag==3){flag=1;Gui_DrawFont_GBK16(0,60,WHITE,BLACK,"HThres:");//高温阈值Gui_DrawFont_GBK16(0,75,WHITE,BLACK,"LThres:");//低温阈值Gui_DrawFont_GBK16(0,90,RED,BLACK,"HumThres:");//湿度阈值}else if(flag==1){flag=2;Gui_DrawFont_GBK16(0,60,WHITE,BLACK,"HThres:");//高温阈值Gui_DrawFont_GBK16(0,75,RED,BLACK,"LThres:");//低温阈值Gui_DrawFont_GBK16(0,90,WHITE,BLACK,"HumThres:");//湿度阈值}else if(flag==2){flag=3;Gui_DrawFont_GBK16(0,60,RED,BLACK,"HThres:");//高温阈值Gui_DrawFont_GBK16(0,75,WHITE,BLACK,"LThres:");//低温阈值Gui_DrawFont_GBK16(0,90,WHITE,BLACK,"HumThres:");//湿度阈值}}if(key>1500&&key<1800)//向左选择{if(flag==1)//高温阈值降低{tempHthres--;float H=tempHthres;char ht[32];sprintf(ht,"%.2fC",H);Gui_DrawFont_GBK16(55,60,WHITE,BLACK,(uint8_t *)ht);}if(flag==2)//低温阈值降低{tempLthres--;float L=tempLthres;char lt[32];sprintf(lt,"%.2lfC",L);Gui_DrawFont_GBK16(55,75,WHITE,BLACK,lt);}if(flag==3)//湿度阈值降低{printf("11111");humiHthres--;int Hu=humiHthres;char hum[32];sprintf(hum,"%d%%%",Hu);Gui_DrawFont_GBK16(75,90,WHITE,BLACK,(uint8_t *)hum);}}if(key>2900&&key<3100)//向右选择{if(flag==1)//高温阈值增加{tempHthres++;float H=tempHthres;char ht[32];sprintf(ht,"%.2fC",H);Gui_DrawFont_GBK16(55,60,WHITE,BLACK,(uint8_t *)ht);}if(flag==2)//低温阈值增加{tempLthres++;float L=tempLthres;char lt[32];sprintf(lt,"%.2lfC",L);Gui_DrawFont_GBK16(55,75,WHITE,BLACK,lt);}if(flag==3)//湿度阈值增加{printf("22222");humiHthres++;int Hu=humiHthres;char hum[32];sprintf(hum,"%d%%%",Hu);Gui_DrawFont_GBK16(75,90,WHITE,BLACK,(uint8_t *)hum);}}}	if(key>2500&&key<2700)//选择中间{Gui_DrawFont_GBK16(0,60,WHITE,BLACK,"HThres:");//高温阈值Gui_DrawFont_GBK16(0,75,WHITE,BLACK,"LThres:");//低温阈值Gui_DrawFont_GBK16(0,90,WHITE,BLACK,"HumThres:");//湿度阈值}}//获取电压
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{HAL_ADC_Stop_DMA(&hadc1);buf[0]=buf[0]*3000/4096/1000*2;float Volt=buf[0];char volt[2];sprintf(volt,"%1.2fV",Volt);Gui_DrawFont_GBK16(50,15,WHITE,BLACK,(uint8_t *)volt);//	buf[1]=buf[1]/4096*100;
//	float Elect=buf[1];
//	char elect[2];
//	sprintf(elect,"%.2f%%",Elect);
//	Gui_DrawFont_GBK16(50,15,WHITE,BLACK,(uint8_t *)elect);//printf("电压=%1.2f",Volt);
}void show()
{printf("temp = %.2fC  humi = %d%% FJ:%c ZL:%c JR:%c", temp, humiH,fj,zl,zr);HAL_Delay(2000);
}void recivemag()
{printf("rrrr");uint8_t *p =Buf;uint8_t i=0;while(*p!='\0'){while(*p!='='){cmdbuf[i++]=*p;p++;}cmdbuf[i]='\0';i=0;p++;while(*p!='\0'){valuebuf[i++]=*p;p++;}valuebuf[i]='\0';}setstatus();
}
uint16_t chartoint()
{uint8_t *valuep=valuebuf;uint16_t sum=0;while(*valuep!='\0'){sum=sum*10+(*valuep-48);	valuep++;}return sum;
}
void setstatus()
{printf("0000");if(strncmp("th=",Buf,3)==0){//printf("1111");tempHthres=chartoint();//tempHthres=Buf[4];float H=tempHthres;char ht[32];sprintf(ht,"%.2fC",H);Gui_DrawFont_GBK16(55,60,WHITE,BLACK,(uint8_t *)ht);}if(strncmp("lh=",Buf,3)==0){ tempLthres=chartoint();//tempLthres=Buf[4];float L=tempLthres;char lt[32];sprintf(lt,"%.2lfC",L);Gui_DrawFont_GBK16(55,75,WHITE,BLACK,(uint8_t*)lt);}if(strncmp("hh=",Buf,3)==0){humiHthres=chartoint();//humiHthres=Buf[4];int Hu=humiHthres;char hum[32];sprintf(hum,"%d%%%",Hu);Gui_DrawFont_GBK16(75,90,WHITE,BLACK,(uint8_t *)hum);}if (strncmp("zl=T",Buf,4)==0){zl = 'T';sprintf(ZL,"ZL:%c",zl);Gui_DrawFont_GBK16(45,105,WHITE,BLACK,ZL);//制冷片开关HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET);}else if (strncmp("zl=F",Buf,4)==0){zl = 'F';sprintf(ZL,"ZL:%c",zl);Gui_DrawFont_GBK16(45,105,WHITE,BLACK,ZL);//制冷片开关HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET);}if (strncmp("zr=T",Buf,4)==0){zr = 'T';sprintf(JR,"ZR:%c",zr);Gui_DrawFont_GBK16(90,105,WHITE,BLACK,JR);//加热片开关HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET);}else if (strncmp("zr=F",Buf,4)==0){zr = 'F';sprintf(JR,"ZR:%c",zr);Gui_DrawFont_GBK16(90,105,WHITE,BLACK,JR);//加热片开关HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET);}if (strncmp("fj=T",Buf,4)==0){fj = 'T';sprintf(FJ,"FJ:%c",fj);Gui_DrawFont_GBK16(0,105,WHITE,BLACK,FJ);//风机开关HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_RESET);}else if (strncmp("fj=F",Buf,4)==0){fj = 'F';sprintf(FJ,"FJ:%c",fj);Gui_DrawFont_GBK16(0,105,WHITE,BLACK,FJ);//风机开关HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_RESET);}
}
/* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT *//************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

stm32g0xx_it.c(串口中断服务程序所在的.c文件)

/* USER CODE BEGIN Header */
/********************************************************************************* @file    stm32g0xx_it.c* @brief   Interrupt Service Routines.******************************************************************************* @attention** <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.* All rights reserved.</center></h2>** This software component is licensed by ST under BSD 3-Clause license,* the "License"; You may not use this file except in compliance with the* License. You may obtain a copy of the License at:*                        opensource.org/licenses/BSD-3-Clause********************************************************************************/
/* USER CODE END Header *//* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32g0xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD *//* USER CODE END TD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//* External variables --------------------------------------------------------*/
extern DMA_HandleTypeDef hdma_adc1;
extern ADC_HandleTypeDef hadc1;
extern DMA_HandleTypeDef hdma_usart1_rx;
extern DMA_HandleTypeDef hdma_usart1_tx;
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart2;
/* USER CODE BEGIN EV *//* USER CODE END EV *//******************************************************************************/
/*           Cortex-M0+ Processor Interruption and Exception Handlers          */
/******************************************************************************/
/*** @brief This function handles Non maskable interrupt.*/
void NMI_Handler(void)
{/* USER CODE BEGIN NonMaskableInt_IRQn 0 *//* USER CODE END NonMaskableInt_IRQn 0 *//* USER CODE BEGIN NonMaskableInt_IRQn 1 */while (1){}/* USER CODE END NonMaskableInt_IRQn 1 */
}/*** @brief This function handles Hard fault interrupt.*/
void HardFault_Handler(void)
{/* USER CODE BEGIN HardFault_IRQn 0 *//* USER CODE END HardFault_IRQn 0 */while (1){/* USER CODE BEGIN W1_HardFault_IRQn 0 *//* USER CODE END W1_HardFault_IRQn 0 */}
}/*** @brief This function handles System service call via SWI instruction.*/
void SVC_Handler(void)
{/* USER CODE BEGIN SVC_IRQn 0 *//* USER CODE END SVC_IRQn 0 *//* USER CODE BEGIN SVC_IRQn 1 *//* USER CODE END SVC_IRQn 1 */
}/*** @brief This function handles Pendable request for system service.*/
void PendSV_Handler(void)
{/* USER CODE BEGIN PendSV_IRQn 0 *//* USER CODE END PendSV_IRQn 0 *//* USER CODE BEGIN PendSV_IRQn 1 *//* USER CODE END PendSV_IRQn 1 */
}/*** @brief This function handles System tick timer.*/
void SysTick_Handler(void)
{/* USER CODE BEGIN SysTick_IRQn 0 *//* USER CODE END SysTick_IRQn 0 */HAL_IncTick();/* USER CODE BEGIN SysTick_IRQn 1 *//* USER CODE END SysTick_IRQn 1 */
}/******************************************************************************/
/* STM32G0xx Peripheral Interrupt Handlers                                    */
/* Add here the Interrupt Handlers for the used peripherals.                  */
/* For the available peripheral interrupt handler names,                      */
/* please refer to the startup file (startup_stm32g0xx.s).                    */
/******************************************************************************//*** @brief This function handles EXTI line 4 to 15 interrupts.*/
void EXTI4_15_IRQHandler(void)
{/* USER CODE BEGIN EXTI4_15_IRQn 0 *//* USER CODE END EXTI4_15_IRQn 0 */HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8);/* USER CODE BEGIN EXTI4_15_IRQn 1 *//* USER CODE END EXTI4_15_IRQn 1 */
}/*** @brief This function handles DMA1 channel 1 interrupt.*/
void DMA1_Channel1_IRQHandler(void)
{/* USER CODE BEGIN DMA1_Channel1_IRQn 0 *//* USER CODE END DMA1_Channel1_IRQn 0 */HAL_DMA_IRQHandler(&hdma_adc1);/* USER CODE BEGIN DMA1_Channel1_IRQn 1 *//* USER CODE END DMA1_Channel1_IRQn 1 */
}/*** @brief This function handles DMA1 channel 2 and channel 3 interrupts.*/
void DMA1_Channel2_3_IRQHandler(void)
{/* USER CODE BEGIN DMA1_Channel2_3_IRQn 0 *//* USER CODE END DMA1_Channel2_3_IRQn 0 */HAL_DMA_IRQHandler(&hdma_usart1_rx);HAL_DMA_IRQHandler(&hdma_usart1_tx);/* USER CODE BEGIN DMA1_Channel2_3_IRQn 1 *//* USER CODE END DMA1_Channel2_3_IRQn 1 */
}/*** @brief This function handles ADC1 interrupt.*/
void ADC1_IRQHandler(void)
{/* USER CODE BEGIN ADC1_IRQn 0 *//* USER CODE END ADC1_IRQn 0 */HAL_ADC_IRQHandler(&hadc1);/* USER CODE BEGIN ADC1_IRQn 1 *//* USER CODE END ADC1_IRQn 1 */
}/*** @brief This function handles USART1 global interrupt / USART1 wake-up interrupt through EXTI line 25.*/
extern char Buf[128];
uint8_t len=0;
int flag1=0;
void USART1_IRQHandler(void)
{/* USER CODE BEGIN USART1_IRQn 0 *//* USER CODE END USART1_IRQn 0 */HAL_UART_IRQHandler(&huart1);/* USER CODE BEGIN USART1_IRQn 1 */if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE))	  // 1. 获得串口空闲中断标志	{__HAL_UART_CLEAR_FLAG(&huart1,UART_CLEAR_IDLEF);		 // 2. 清除空闲中断标志HAL_UART_DMAStop(&huart1);						// 3. 清除->空闲->停止DMAlen = 128 - hdma_usart1_rx.Instance->CNDTR;					 // 4. 设定的传输长度-剩余传输数量(DMA_CNDTRx)=实际长度HAL_UART_Transmit(&huart1,Buf,len,100);			 // 5. 数据处理——发送HAL_UART_Receive_DMA(&huart1 ,Buf,128);				// 6. 重新开启DMAflag1=1;}/* USER CODE END USART1_IRQn 1 */
}/*** @brief This function handles USART2 global interrupt / USART2 wake-up interrupt through EXTI line 26.*/
void USART2_IRQHandler(void)
{/* USER CODE BEGIN USART2_IRQn 0 *//* USER CODE END USART2_IRQn 0 */HAL_UART_IRQHandler(&huart2);/* USER CODE BEGIN USART2_IRQn 1 *//* USER CODE END USART2_IRQn 1 */
}/* USER CODE BEGIN 1 *//* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

lcd.c

#include "gpio.h"
#include "stdint.h"
#include "lcd.h"
#include "lcd_font.h"
#include <string.h>//static uint8_t lcd_send_data = 0;//extern  void HalLcd_HW_WaitUs(uint16 i);/** Initialize LCD Service*/
void HalLcdInit(void);//LCD Init For 1.44Inch LCD Panel with ST7735R.
void Lcd_Init(void)
{HAL_Delay(10);//开LCD背光HAL_GPIO_WritePin(LCD_GPIO_Port, LCD_Pin, GPIO_PIN_SET);Lcd_WriteIndex(0x11);HAL_Delay(3);//Sleep exit HAL_Delay(10);Lcd_WriteIndex(0x11);
//        HAL_Delay(1000);
//        HAL_Delay(1000);
//        HAL_Delay(1000);HAL_Delay(5);Lcd_WriteIndex(0x36);HAL_Delay(5);Lcd_WriteIndex(0x36);//MX, MY, RGB modeHAL_Delay(5);Lcd_WriteData(0xC8);HAL_Delay(5);Lcd_WriteData(0xC8);HAL_Delay(5);Lcd_WriteIndex(0x3A);HAL_Delay(5);Lcd_WriteIndex(0x3A);//65k modeHAL_Delay(5);Lcd_WriteData(0x05);HAL_Delay(5);Lcd_WriteData(0x05);HAL_Delay(20);Lcd_WriteIndex(0x29);HAL_Delay(5);Lcd_WriteIndex(0x29);//Display on//有问题
}//
///*
// * Write a string to the LCD
// */
//
//void HalLcdWriteString ( char *str, uint8 option);
//
///*
// * Write a value to the LCD
// */
//extern void HalLcdWriteValue ( uint32 value, const uint8 radix, uint8 option);
//
///*
// * Write a value to the LCD
// */
//extern void HalLcdWriteScreen( char *line1, char *line2 );
//
///*
// * Write a string followed by a value to the LCD
// */
//extern void HalLcdWriteStringValue( char *title, uint16 value, uint8 format, uint8 line );
//
///*
// * Write a string followed by 2 values to the LCD
// */
//extern void HalLcdWriteStringValueValue( char *title, uint16 value1, uint8 format1, uint16 value2, uint8 format2, uint8 line );
//
///*
// * Write a percentage bar to the LCD
// */
//extern void HalLcdDisplayPercentBar( char *title, uint8 value );
//
//extern void Gui_DrawFont_GBK16(uint16 x, uint16 y, uint16 fc, uint16 bc, uint8 *s);
//void Line_Dsp_single_colour(unsigned int x_start,unsigned int y_start,unsigned int x_end,unsigned int y_end,unsigned int color);
//void dsp_single_colour(int color);void Delay_ms(int time)
{int i,j;for(i=0; i<time*10; i++){for(j=0; j<100; j++){}}
}void SPI_WriteData(uint8_t Data)
{unsigned char i;for(i=8; i>0; i--){if(Data & 0x80){LCD_SDA_SET;              //数据输出高电平}else{LCD_SDA_CLR;               //数据输出低电平}LCD_SCL_SET;              //时钟高LCD_SCL_CLR;              //时钟低Data  <<=  1;}
}void LCD_WriteData_16Bit(uint16_t Data)
{LCD_CS_CLR;LCD_RS_SET;SPI_WriteData(Data>>8); 	//写入高8位数据SPI_WriteData(Data); 			//写入低8位数据LCD_CS_SET;
}//向液晶屏写一个8位指令
void Lcd_WriteIndex(uint8_t Index)
{//SPI 写命令时序开始LCD_CS_CLR;LCD_RS_CLR;           //LCD_RS_CLRSPI_WriteData(Index);LCD_CS_SET;
}
//向液晶屏写一个8位数据
void Lcd_WriteData(uint8_t Data)
{LCD_CS_CLR;LCD_RS_SET;SPI_WriteData(Data);LCD_CS_SET;
}void Lcd_WriteReg(uint8_t Index,uint8_t Data)
{LCD_CS_CLR;Lcd_WriteIndex(Index);Lcd_WriteData(Data);LCD_CS_SET;
}LCD Init For 1.44Inch LCD Panel with ST7735R.
//void Lcd_Init(void)
//{
//	Lcd_WriteIndex(0x11);//Sleep exit
//	HAL_Delay(120);
//
//	Lcd_WriteIndex(0x36); //MX, MY, RGB mode
//	Lcd_WriteData(0xC8);
//
//	Lcd_WriteIndex(0x3A); //65k mode
//	Lcd_WriteData(0x05);
//
//	Lcd_WriteIndex(0x29);//Display on
//}/*************************************************
函数名:LCD_Set_Region
功能:设置lcd显示区域,在此区域写点数据自动换行
入口参数:xy起点和终点
返回值:无
*************************************************/
void Lcd_SetRegion(uint16_t x_start,uint16_t y_start,uint16_t x_end,uint16_t y_end)
{Lcd_WriteIndex(0x2a);Lcd_WriteData(0x00);Lcd_WriteData(x_start+2);Lcd_WriteData(0x00);Lcd_WriteData(x_end+2);Lcd_WriteIndex(0x2b);Lcd_WriteData(0x00);Lcd_WriteData(y_start+3);Lcd_WriteData(0x00);Lcd_WriteData(y_end+3);Lcd_WriteIndex(0x2c);}
/*************************************************
函数名:LCD_Set_XY
功能:设置lcd显示起始点
入口参数:xy坐标
返回值:无
*************************************************/
void Lcd_SetXY(uint16_t x,uint16_t y)
{Lcd_SetRegion(x,y,x,y);
}/*************************************************
函数名:LCD_DrawPoint
功能:画一个点
入口参数:无
返回值:无
*************************************************/
void Gui_DrawPoint(uint16_t x,uint16_t y,uint16_t Data)
{Lcd_SetRegion(x,y,x+1,y+1);LCD_WriteData_16Bit(Data);}/*****************************************函数功能:读TFT某一点的颜色出口参数:color  点颜色值
******************************************/
//unsigned int Lcd_ReadPoint(uint16_t x,uint16_t y)
//{
//  unsigned int Data;
//  Lcd_SetXY(x,y);
//
//  //Lcd_ReadData();//丢掉无用字节
//  //Data=Lcd_ReadData();
//  Lcd_WriteData(Data);
//  return Data;
//}
/*************************************************
函数名:Lcd_Clear
功能:全屏清屏函数
入口参数:填充颜色COLOR
返回值:无
*************************************************/
void Lcd_Clear(uint16_t Color)
{unsigned int i,m;Lcd_SetRegion(0,0,X_MAX_PIXEL-1,Y_MAX_PIXEL-1);Lcd_WriteIndex(0x2C);for(i=0; i<X_MAX_PIXEL; i++)for(m=0; m<Y_MAX_PIXEL; m++){LCD_WriteData_16Bit(Color);}
}
//取模方式 水平扫描 从左到右 低位在前
void showimage_farsight(const unsigned char *p) //显示128*35 QQ图片
{int i;unsigned char picH,picL;//Lcd_Clear(WHITE); //清屏Lcd_SetRegion(0,0,127,34);		//坐标设置for(i=0; i<128*35; i++){picL=*(p+i*2);	//数据低位在前picH=*(p+i*2+1);LCD_WriteData_16Bit(picH<<8|picL);}
}void showimage(const unsigned char *p) //显示128*35 QQ图片
{int i;unsigned char picH,picL;//Lcd_Clear(WHITE); //清屏Lcd_SetRegion(0,0,127,127);		//坐标设置for(i=0; i<128*128; i++){picL=*(p+i*2);	//数据低位在前picH=*(p+i*2+1);LCD_WriteData_16Bit(picH<<8|picL);}
}//void Gui_DrawFont_GBK16(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint8_t *s)
//{
//	unsigned char i,j;
//	unsigned short k,x0;
//	x0=x;
//
//	while(*s)
//	{
//		if((*s) < 128)
//		{
//			k=*s;
//			if (k == 13)
//			{
//				x=x0;
//				y+=16;
//			}
//			else
//			{
//				if (k>32) k-=32; else k=0;
//
//			    for(i=0;i<16;i++)
//				for(j=0;j<8;j++)
//					{
//				    	if(asc16[k*16+i]&(0x80>>j))	Gui_DrawPoint(x+j,y+i,fc);
//						else
//						{
//							if (fc!=bc) Gui_DrawPoint(x+j,y+i,bc);
//						}
//					}
//				x+=8;
//			}
//			s++;
//		}
//
//		else
//		{
//
//
//			for (k=0;k<hz16_num;k++)
//			{
//			  if ((hz16[k].Index[0]==*(s))&&(hz16[k].Index[1]==*(s+1)))
//			  {
//				    for(i=0;i<16;i++)
//				    {
//						for(j=0;j<8;j++)
//							{
//						    	if(hz16[k].Msk[i*2]&(0x80>>j))	Gui_DrawPoint(x+j,y+i,fc);
//								else {
//									if (fc!=bc) Gui_DrawPoint(x+j,y+i,bc);
//								}
//							}
//						for(j=0;j<8;j++)
//							{
//						    	if(hz16[k].Msk[i*2+1]&(0x80>>j))	Gui_DrawPoint(x+j+8,y+i,fc);
//								else
//								{
//									if (fc!=bc) Gui_DrawPoint(x+j+8,y+i,bc);
//								}
//							}
//				    }
//				}
//			  }
//			s+=2;x+=16;
//		}
//
//	}
//}
void Gui_DrawFont_GBK16(uint16_t x0, uint16_t y0, uint16_t fc, uint16_t bc, uint8_t *s)
{int i,j,k,x,y,xx;unsigned char qm;long int ulOffset;char  ywbuf[32];
// char   temp[2];for(i = 0; i<strlen((char*)s); i++){if(((unsigned char)(*(s+i))) >= 161){
//      temp[0] = *(s+i);
//      temp[1] = '\0';return;}else{qm = *(s+i);ulOffset = (long int)(qm) * 16;for (j = 0; j < 16; j ++){ywbuf[j]=Zk_ASCII8X16[ulOffset+j];}for(y = 0; y < 16; y++){for(x=0; x<8; x++){k=x % 8;if(ywbuf[y]&(0x80 >> k)){xx=x0+x+i*8;Gui_DrawPoint(xx,y+y0,fc);}else{xx=x0+x+i*8;Gui_DrawPoint(xx,y+y0,bc);}}}}}
}
void Gui_DrawFont_1616(uint16_t x0, uint16_t y0, uint16_t fc, uint16_t bc,const char tfont16[][32],int num)
{uint16_t i,j;uint8_t Hznum;for(Hznum = 0;Hznum < num;Hznum++){// 设置汉子显示的区域Lcd_SetRegion(x0+Hznum*16,y0,x0+16-1+Hznum*16,y0+16-1);for(i = 0;i < 32;i++) //一个汉字的字模由32个元素组成{	for(j = 0;j < 8;j++) //每个元素有8位,每一位代表一个亮点{if(tfont16[Hznum][i] & (0x80 >> j)){LCD_WriteData_16Bit(fc);}else	{LCD_WriteData_16Bit(bc);}}}}
}

lcd.h

#ifndef __LCD_H
#define __LCD_H
#include "stdint.h"#include "main.h"#define RED  	0xf800
#define GREEN	0x07e0
#define BLUE 	0x001f
#define WHITE	0xffff
#define BLACK	0x0000
#define YELLOW  0xFFE0#define CYAN    0x07ff
#define BRIGHT_RED 0xf810   #define GRAY0   0xEF7D   	//灰色0 3165 00110 001011 00101
#define GRAY1   0x8410      	//灰色1      00000 000000 00000
#define GRAY2   0x4208      	//灰色2  1111111111011111#define X_MAX_PIXEL	        128
#define Y_MAX_PIXEL	        128//LCD的SPI引脚的定义
#define LCD_CTRL_PORT           GPIOB		//定义TFT数据端口
#define LCD_LED        	      LCD_Pin  //LCD背光--->>TFT --BL
#define LCD_RS         	      MISO_Pin	//MISO--->>TFT --RS/DC
#define LCD_SDA        	      MOSI_Pin	//MOSI--->>TFT --SDA/DIN
#define LCD_SCL        	      SCLK_Pin	//SCK--->>TFT --SCL/SCK#define LCD_CS_PORT     CSS_GPIO_Port
#define LCD_CS        	CSS_Pin  //MCU_PB11--->>TFT --CS/CE//液晶控制口置1操作语句宏定义
#define	LCD_CS_SET  	LCD_CS_PORT->BSRR=LCD_CS #define	LCD_RS_SET  	LCD_CTRL_PORT->BSRR=LCD_RS    
#define	LCD_SDA_SET  	LCD_CTRL_PORT->BSRR=LCD_SDA    
#define	LCD_SCL_SET  	LCD_CTRL_PORT->BSRR=LCD_SCL     
#define	LCD_LED_SET  	LCD_CTRL_PORT->BSRR=LCD_LED   //液晶控制口置0操作语句宏定义
#define	LCD_CS_CLR  	LCD_CS_PORT->BRR=LCD_CS #define	LCD_RS_CLR  	LCD_CTRL_PORT->BRR=LCD_RS    
#define	LCD_SDA_CLR  	LCD_CTRL_PORT->BRR=LCD_SDA    
#define	LCD_SCL_CLR  	LCD_CTRL_PORT->BRR=LCD_SCL       
#define	LCD_LED_CLR  	LCD_CTRL_PORT->BRR=LCD_LED void LCD_GPIO_Init(void);
void Lcd_WriteIndex(uint8_t Index);
void Lcd_WriteData(uint8_t Data);
void Lcd_WriteReg(uint8_t Index,uint8_t Data);
uint16_t Lcd_ReadReg(uint8_t LCD_Reg);
void Lcd_Reset(void);
void Lcd_Init(void);
void Lcd_Clear(uint16_t Color);
void Lcd_SetXY(uint16_t x,uint16_t y);
void Gui_DrawPoint(uint16_t x,uint16_t y,uint16_t Data);
unsigned int Lcd_ReadPoint(uint16_t x,uint16_t y);
void Lcd_SetRegion(uint16_t x_start,uint16_t y_start,uint16_t x_end,uint16_t y_end);
void LCD_WriteData_16Bit(uint16_t Data);
void showimage(const unsigned char *p);
void Lcd_ReadID(void);
void showimage_farsight(const unsigned char *p);
void Gui_DrawFont_GBK16(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint8_t *s);
void Gui_DrawFont_1616(uint16_t x0, uint16_t y0, uint16_t fc, uint16_t bc,const char tfont16[][32],int num);
#endif

dht11.c

#include "dht11.h"#define DHT11_GPIO_PORT 		GPIOB
#define DHT11_GPIO_PIN 			GPIO_PIN_8
#define	DHT11_DQ_IN  		    HAL_GPIO_ReadPin(DHT11_GPIO_PORT, DHT11_GPIO_PIN)static void DHT11_IO_IN(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};GPIO_InitStruct.Pin = DHT11_GPIO_PIN;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init(DHT11_GPIO_PORT, &GPIO_InitStruct);
}static void DHT11_IO_OUT(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};GPIO_InitStruct.Pin = DHT11_GPIO_PIN;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(DHT11_GPIO_PORT, &GPIO_InitStruct);
}//复位DHT11  \\起始
void DHT11_Rst(void)
{DHT11_IO_OUT(); 	//SET OUTPUT  转换成输出模式HAL_GPIO_WritePin(DHT11_GPIO_PORT, DHT11_GPIO_PIN, GPIO_PIN_RESET); 	//拉低DQHAL_Delay(20);    	//拉低至少18msHAL_GPIO_WritePin(DHT11_GPIO_PORT, DHT11_GPIO_PIN, GPIO_PIN_SET);		//DQ=1delay_us(30);     	//主机拉高20~40us
}//等待DHT11的回应
//返回1:未检测到DHT11的存在
//返回0:存在
uint8_t DHT11_Check(void)
{uint8_t retry=0;DHT11_IO_IN();//SET INPUT 转换成输入模式while (!DHT11_DQ_IN&&retry<100)//DHT11会拉低40~80us{retry++;delay_us(1);}if(retry>=100)return 1;else retry=0;while (DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~80us{retry++;delay_us(1);}if(retry>=100)return 1;return 0;
}//从DHT11读取一个位
//返回值:1/0
uint8_t DHT11_Read_Bit(void)
{uint8_t retry=0;while(DHT11_DQ_IN&&retry<100)//等待变为低电平{retry++;delay_us(1);}//延时100retry=0;while(!DHT11_DQ_IN&&retry<100)//等待变高电平{retry++;delay_us(1);}delay_us(40);//等待40usif(DHT11_DQ_IN)return 1;else return 0;
}//从DHT11读取一个字节
//返回值:读到的数据
uint8_t DHT11_Read_Byte(void)
{uint8_t 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%)
//返回值:HAL_OK,正常;1,读取失败
uint8_t DHT11_Read_Data(uint8_t *humiH,uint8_t *humiL,uint8_t *tempH,uint8_t *tempL)
{uint8_t buf[5];uint8_t i;DHT11_Rst();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]){*humiH=buf[0];*humiL=buf[1];*tempH=buf[2];*tempL=buf[3];}} elsereturn HAL_ERROR;return HAL_OK;
}//初始化DHT11的IO口 DQ 同时检测DHT11的存在
//返回1:不存在
//返回0:存在
uint8_t FS_DHT11_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};GPIO_InitStruct.Pin = DHT11_GPIO_PIN;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(DHT11_GPIO_PORT, &GPIO_InitStruct);HAL_GPIO_WritePin(DHT11_GPIO_PORT, DHT11_GPIO_PIN, GPIO_PIN_SET);	// 输出高DHT11_Rst();  //复位DHT11return DHT11_Check();//等待DHT11的回应
}

dht11.h

#ifndef __DHT11_H__
#define __DHT11_H__#include "main.h"uint8_t DHT11_Read_Data(uint8_t *humiH,uint8_t *humiL,uint8_t *tempH,uint8_t *tempL);
uint8_t FS_DHT11_Init(void);#endif

这篇关于基于STM32和DHT11的温湿度测试仪的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/826998

相关文章

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

STM32(十一):ADC数模转换器实验

AD单通道: 1.RCC开启GPIO和ADC时钟。配置ADCCLK分频器。 2.配置GPIO,把GPIO配置成模拟输入的模式。 3.配置多路开关,把左面通道接入到右面规则组列表里。 4.配置ADC转换器, 包括AD转换器和AD数据寄存器。单次转换,连续转换;扫描、非扫描;有几个通道,触发源是什么,数据对齐是左对齐还是右对齐。 5.ADC_CMD 开启ADC。 void RCC_AD

STM32内部闪存FLASH(内部ROM)、IAP

1 FLASH简介  1 利用程序存储器的剩余空间来保存掉电不丢失的用户数据 2 通过在程序中编程(IAP)实现程序的自我更新 (OTA) 3在线编程(ICP把整个程序都更新掉) 1 系统的Bootloader写死了,只能用串口下载到指定的位置,启动方式也不方便需要配置BOOT引脚触发启动  4 IAP(自己写的Bootloader,实现程序升级) 1 比如蓝牙转串口,

FreeRTOS-基本介绍和移植STM32

FreeRTOS-基本介绍和STM32移植 一、裸机开发和操作系统开发介绍二、任务调度和任务状态介绍2.1 任务调度2.1.1 抢占式调度2.1.2 时间片调度 2.2 任务状态 三、FreeRTOS源码和移植STM323.1 FreeRTOS源码3.2 FreeRTOS移植STM323.2.1 代码移植3.2.2 时钟中断配置 一、裸机开发和操作系统开发介绍 裸机:前后台系

寻迹模块TCRT5000的应用原理和功能实现(基于STM32)

目录 概述 1 认识TCRT5000 1.1 模块介绍 1.2 电气特性 2 系统应用 2.1 系统架构 2.2 STM32Cube创建工程 3 功能实现 3.1 代码实现 3.2 源代码文件 4 功能测试 4.1 检测黑线状态 4.2 未检测黑线状态 概述 本文主要介绍TCRT5000模块的使用原理,包括该模块的硬件实现方式,电路实现原理,还使用STM32类

STM32 ADC+DMA导致写FLASH失败

最近用STM32G070系列的ADC+DMA采样时,遇到了一些小坑记录一下; 一、ADC+DMA采样时进入死循环; 解决方法:ADC-dma死循环问题_stm32 adc dma死机-CSDN博客 将ADC的DMA中断调整为最高,且增大ADCHAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, ADC_Buffer_Size); 的ADC_Bu

基于stm32的河流检测系统-单片机毕业设计

文章目录 前言资料获取设计介绍功能介绍具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机设计精品

STM32的使用方法一

注:我采用的是STM32F103RC芯片、相应的电路图和STM32CubeIDE软件这是在STM32CubeIDE软件定义芯片后,所给的必要的代码逻辑,加上了注释 #include "main.h"/* Private variables ---------------------------------------------------------*//* Private function

STM32 HAL CAN通讯 实操

1、简介 相比于串口通讯,对于刚接触CAN通讯的小白来说,CAN通讯相对复杂,看各种视频、帖子理论,总是一知半解。本次通过傻瓜式操作,先实现CAN通讯的交互,以提高小白的信心,也便于自己复习观看。本次以STM32CubeMX进行初始化配置,通过Keil 5软件进行软件设计,通过CAN盒实现进行数据的交互。该流程实际以STM32F0、F1、F3、F4、F7实测好用(理论上都适用),这三种型号单片机

我在高职教STM32——准备HAL库工程模板(1)

新学期开学在即,又要给学生上 STM32 嵌入式课程了。这课上了多年了,一直用的都是标准库来开发,已经驾轻就熟了。人就是这样,有了自己熟悉的舒适圈,就很难做出改变,老师上课也是如此,排斥新课和不熟悉的内容。显然,STM32 的开发,HAL 库已是主流,自己其实也在使用,只不过更换库就意味着教学内容有很大变化,自己也就迟迟没有迈出调整这一步。现在,是时候做出变化了,笔者计划保持教学项