STM32实现除湿器

利用STM32G030实现除湿器

1、项目介绍

1.1 除湿器项目设计说明

功能概述:
在这里插入图片描述
功能要求:
设备自检功能:
设备上电自检(检查传感器采集是否正常, DHT11有存在响应, 可以自检使用, 有电池电压检测,可以判断电压是否正常)自检通过后,由串口打印设备状态信息。
自动控制功能:
进入自动控制模式, LCD显示温湿度信息以及电池电压 。与上位机通信( 串口助手), 每2s发送设备状态信息到上位机 。
阈值设置功能:
可以通过五向按键选择并调整温湿度的阈值大小。
可以通过上位机发送命令设定温湿度的阈值大小。

2、STM32cubeMX配置

配置的所有东西展示:
在这里插入图片描述

2.1 LCD显示屏

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
需要是GPIO_output模式
给引脚添加标签
输出速度为高电平
在这里插入图片描述

2.2 UART串口

在这里插入图片描述

2.3 RCC时钟

在这里插入图片描述
在这里插入图片描述

2.4 灯的引脚

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.5 ADC

在这里插入图片描述
PA0采集电源电压值,PA1采集五行按键不同按键按下时的电压
在这里插入图片描述

再把五行按键按下时,数据引脚设置为外部中断
在这里插入图片描述

2.6 温湿度传感器数据输入输出口

在这里插入图片描述

2.7 DMA

在这里插入图片描述

2.8 NVIC打开中断

在这里插入图片描述

3、代码

main函数中实现开机时,显示开机画面
在这里插入图片描述

在这里插入图片描述

Lcd_Init();
	//显示欢迎界面
	Lcd_Clear(0xffff);
	for(int wi=128;wi>-60;wi--)
	{
		Gui_DrawFont_1616(wi,60,BLACK,WHITE,openword,4);
	}
	//显示图片
	showimage(gImage_xiaokeai);
	HAL_Delay(2000);
	Lcd_Clear(0xF800);

2)main函数中,显示设置的初始阈值与电源电压与温湿度
FJ代表风机的状态。ZH代表制热板,ZL代表制冷。
F代表:关
T代表:开
在这里插入图片描述

//高温阈值显示
	//printf("tempHthres=%d\n",tempHthres);
	Gui_DrawFont_1616(10,58,BLUE,RED,tempHthresbuf,5);
	Gui_DrawFont_GBK16(90,58,BLUE,RED,tempHthresb);
	//低温阈值显示
	Gui_DrawFont_1616(10,74,BLUE,RED,tempLthresbuf,5);
	Gui_DrawFont_GBK16(90,74,BLUE,RED,tempLthresb);
	//湿度阈值显示
	Gui_DrawFont_1616(10,90,BLUE,RED,humiHthresbuf,5);
	Gui_DrawFont_GBK16(90,90,BLUE,RED,humiHthresb);
	//风机制冷制热片LCD显示
	uint8_t fc='F';
	sprintf(feijibuf,"FJ:%c ",fc);
	Gui_DrawFont_GBK16(10,106,BLUE,RED,feijibuf);
	
	uint8_t hc='F';
	sprintf(zhirebuf,"ZH:%c",hc);
	Gui_DrawFont_GBK16(50,106,BLUE,RED,zhirebuf);
	
	uint8_t lc='F';
	sprintf(zhilengbuf,"ZL:%c",fc);
	Gui_DrawFont_GBK16(90,106,BLUE,RED,zhilengbuf);

3)打开串口1空闲不定长接收中断

//打开串口1空闲中断
	HAL_UART_Receive_DMA(&huart1,interruptbuf,sizeof(interruptbuf));
	__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);

4)初始化时检测DHT11模块是否存在

FS_DHT11_Init();
	DHT11_Rst();
	if(FS_DHT11_Init()==0)
		printf("dht11正常");
	else
		printf("dht11不存在");

5)main函数while(1)循环中每间隔2s循环获取电压值

//获取按键与电压值
		HAL_ADC_Start_DMA(&hadc1,(uint32_t *)buf,2);

ADC转换完成后,回调的函数中
先停止DMA搬运,把采集到的电压值转化成对应格式传输到串口,在电脑端串口助手中打印。并同时在LCD上显示。想通过Printf()函数发送给串口,需要重写fputc函数。

int fputc(int ch,FILE *p)
{
	while(!(USART1->ISR&1<<7));
	USART1->TDR=ch;
	return ch;
	
}
HAL_ADC_Stop_DMA(&hadc1);
	//电压
	buf[0]=buf[0]*3000/4096/1000*2;
	float floatbuf=(float)buf[0];    //转化成浮点型
	char volt[12]={0};
	sprintf(volt,"%1.2fV",floatbuf);   //转换成字符串
	printf("电压=%1.1f\n",floatbuf);
	Gui_DrawFont_1616(10,10,BLUE,RED,volbuf,3);
	Gui_DrawFont_GBK16(48,10,BLUE,RED,(uint8_t *)volt);

6)五行按键按下时,触发按键中断PA8引脚的EXIT8

//按键中断
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin==GPIO_PIN_8)
	{
		HAL_ADC_Start_DMA(&hadc1,(uint32_t *)buf,2);
		flag=1;
	}
}


flag标志着是否发生按键中断,当按键中断时,标志位置1

//ADC转换完成,并DMA取完数据触发的中断函数
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
	HAL_ADC_Stop_DMA(&hadc1);
	//电压
	buf[0]=buf[0]*3000/4096/1000*2;
	float floatbuf=(float)buf[0];    //转化成浮点型
	char volt[12]={0};
	sprintf(volt,"%1.2fV",floatbuf);   //转换成字符串
	printf("电压=%1.1f\n",floatbuf);
	Gui_DrawFont_1616(10,10,BLUE,RED,volbuf,3);
	Gui_DrawFont_GBK16(48,10,BLUE,RED,(uint8_t *)volt);
	//printf("key=%d\n",buf[1]);
	//上方向键调高温阈值,下方向键调低温阈值,左方向键调湿度阈值
	
	if(flag)
	{
		printf("flag=%d\n",flag);
		if(buf[1]<2400&&buf[1]>2100)
		{	
			tempHthres--;
			if(tempHthres<26)
				tempHthres=46;
			sprintf(tempHthresb,"%d",tempHthres);
			Gui_DrawFont_GBK16(90,58,BLACK,RED,tempHthresb);
			
		}
		if(buf[1]<900&&buf[1]>500)
		{
			tempLthres--;
			if(tempLthres<18)
				tempLthres=32;
			sprintf(tempLthresb,"%d",tempLthres);
			Gui_DrawFont_GBK16(90,74,BLACK,RED,tempLthresb);
		}
		if(buf[1]<1800&&buf[1]>1500)
		{
			humiHthres--;
			if(humiHthres<53)
				humiHthres=68;
			sprintf(humiHthresb,"%d",humiHthres);
			Gui_DrawFont_GBK16(90,90,BLACK,RED,humiHthresb);
		}
		if(buf[1]<2900&&buf[1]>2500)
		{
			Gui_DrawFont_GBK16(90,58,BLUE,RED,tempHthresb);
			Gui_DrawFont_GBK16(90,74,BLUE,RED,tempLthresb);
			Gui_DrawFont_GBK16(90,90,BLUE,RED,humiHthresb);
		}
		
		flag=0;
	}
	
}

当flag=1是,说明有按键中断,需要通过按键调整阈值。
采集到按键电压范围在2100到2400之间时,说明上方向按键被按下,修改高温阈值
采集到按键电压范围在500到900之间时,说明下方向按键被按下,修改低温阈值
采集到按键电压范围在1500到1800之间时,说明左方向按键被按下,修改湿度阈值
采集到按键电压范围在2500到2900之间时,说明中间方向按键被按下,确认修改阈值
处理完成后重新把flag标志置零
7)温湿度
main函数while(1)循环中,每间隔2s采集一次温湿度数据

//获取温湿度
		DHT11_Read_Data(&humiH,&humiL,&tempH,&tempL);
		temp = tempH + tempL*0.1;
		
		printf("温度 = %.2fC  湿度 = %d%%",temp,humiH);
		
		//温度显示在LCD
		char tempb[10]={0};
		sprintf(tempb,"%.2f",temp);
	  Gui_DrawFont_1616(10,26,BLUE,RED,tempbuf,3);
	  Gui_DrawFont_GBK16(48,26,BLUE,RED,(uint8_t *)tempb);
		//湿度显示在LCD
		char hum[6]={0};
	  sprintf(hum,"%hu%%",humiH);
	  Gui_DrawFont_1616(10,42,BLUE,RED,humiditybuf,3);
	  Gui_DrawFont_GBK16(48,42,BLUE,RED,(uint8_t *)hum);
		HAL_Delay(2000);

dht11.c中的代码见下面详细的总代码
8)判断采集到的温湿度与设定的阈值之间的关系,执行相应的逻辑处理
main函数while(1)循环中,在采集完成后判断
高于高温阈值,绿灯亮,表示制冷片开启。并在LCD上显示ZL:T。表示制冷片开启
低于低温阈值,黄灯亮,表示加热片开启,并在LCD上显示ZH:T。表示制热片开启
当采集到的湿度大于设定的湿度阈值时,蓝灯亮,表示除湿器开启,并在LCD上显示FJ:T.表示除湿器开启

当加热片工作过程中,如果温度大于高温阈值+5,停止加热片
当制冷片工作过程中,如果温度小于低温阈值-5,停止制冷片
当除湿器工作过程中,湿度小于设定的湿度阈值时,停止除湿器

//高温绿灯亮,低温黄灯亮,湿度高蓝灯亮
		if(temp>tempHthres)
		{
			HAL_GPIO_WritePin(GREEN_GPIO_Port,GREEN_Pin,GPIO_PIN_RESET);
			HAL_GPIO_WritePin(GREEN_GPIO_Port,YELO_Pin,GPIO_PIN_SET);
			temp-=1;    //模拟降温过程
			
			//制冷LCD显示
			lc='T';
			sprintf(zhilengbuf,"ZL:%c",lc);
			Gui_DrawFont_GBK16(90,106,BLUE,RED,zhilengbuf);
		}
		if(temp<tempLthres)
		{
			HAL_GPIO_WritePin(GREEN_GPIO_Port,YELO_Pin,GPIO_PIN_RESET);
			//HAL_GPIO_WritePin(GREEN_GPIO_Port,GREEN_Pin,GPIO_PIN_SET);
			temp+=1;  //模拟升温过程
			
			//制热LCD显示
			 hc='T';
			sprintf(zhirebuf,"ZH:%c",hc);
			Gui_DrawFont_GBK16(50,106,BLUE,RED,zhirebuf);
		}
		if(humiH>humiHthres)
		{
			HAL_GPIO_WritePin(GREEN_GPIO_Port,BLUE_Pin,GPIO_PIN_RESET);
			
			humiH-=1;   //模拟除湿过程
			
			//风机状态LCD显示
			fc='T';
			sprintf(feijibuf,"FJ:%c ",fc);
			Gui_DrawFont_GBK16(10,106,BLUE,RED,feijibuf);
			
		}
		//如果在正常范围内关闭所有的灯
		if(temp<tempHthres&&temp>tempLthres)
		{
			HAL_GPIO_WritePin(GREEN_GPIO_Port,YELO_Pin|GREEN_Pin,GPIO_PIN_SET);
		}
		
		//温度大于高温阈值+5,关闭制热
		if(temp>tempHthres+5)
		{
			HAL_GPIO_WritePin(GREEN_GPIO_Port,YELO_Pin,GPIO_PIN_SET);
			hc='F';
			sprintf(zhirebuf,"ZH:%c",hc);
			Gui_DrawFont_GBK16(50,106,BLUE,RED,zhirebuf);
		}
		//温度低于低温阈值-5,关闭制冷
		if(temp<tempLthres-5)
		{
			HAL_GPIO_WritePin(GREEN_GPIO_Port,GREEN_Pin,GPIO_PIN_SET);
			lc='F';
			sprintf(zhilengbuf,"ZL:%c",fc);
			Gui_DrawFont_GBK16(90,106,BLUE,RED,zhilengbuf);	
		}
		//低于除湿阈值,关闭风机	
		if(humiH<humiHthres)
		{
			HAL_GPIO_WritePin(GREEN_GPIO_Port,BLUE_Pin,GPIO_PIN_SET);
			fc='F';
			sprintf(feijibuf,"FJ:%c ",fc);
			Gui_DrawFont_GBK16(10,106,BLUE,RED,feijibuf);
		}

9)通过串口修改设定的温湿度阈值
当发送数据过程中,发送完成后,会检测一个字节周期内没有数据发送,会触发串口空闲中断,调到串口空闲中断服务程序进行相应的逻辑处理

串口中断服务程序所在的.C文件中需要添加的头文件

#include <string.h>
#include <stdio.h>
#include "lcd.h"

需要引入main中定义的变量

extern uint8_t tempHthres;  //高温阈值
extern uint8_t tempLthres;  //低温阈值
extern uint8_t humiHthres;  //湿度阈值
extern uint8_t tempHthresb[6];
extern uint8_t tempLthresb[6];
extern uint8_t humiHthresb[6];

extern uint8_t interruptbuf[256];//串口接收到的数据
uint8_t cmdbuf[64];              //命令
uint8_t valuebuf[256];           //数值
extern uint8_t wifibuf[256];//串口2接收到的数据

进入中断服务程序后,先判断根据空闲中断标志位是不是空闲中断,如果是,
1)清除空闲标志位
2)停止DMA搬运
3)调用自定义的数据处理函数对接收到的数据进行处理
4)重新开启DMA接收

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
	if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE))
	{
		__HAL_UART_CLEAR_FLAG(&huart1,UART_FLAG_IDLE);
		HAL_UART_DMAStop(&huart1);
		recivemag();                //处理接受到的数据(命令和要设置的值)
			
	uint8_t len=sizeof(interruptbuf)-hdma_usart1_rx.Instance->CNDTR;
//		HAL_UART_Transmit_DMA(&huart1,interruptbuf,len);
		HAL_UART_Receive_DMA(&huart1,interruptbuf,sizeof(interruptbuf));
	}
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}

命令
修改高温阈值
th=要修改的数值
修改低温阈值
tl=要修改的数值
修改湿度阈值
hu=要修改的数值
void recivemag()函数
先根据间隔符;把“=”前面的命令取出,在把等号后面的数值取出。
uint16_t chartoint()函数
因为接受到的是字符串,所以我们需要把接受到的数值进行处理,转化成int型的变量
void setHthresb()函数
调用chartoint()函数,获取转化后的数值,根据命令判断是那个阈值需要修改,修改相应的数值,并对LCD上显示的阈值更新。

串口1
//温湿度数值字符串转整形
uint16_t chartoint()
{
	uint8_t *valuep=valuebuf;
	uint16_t sum=0;
	while(*valuep!='\0')
	{
		sum=sum*10+(*valuep-48);	
		valuep++;
	}
	
	return sum;
}
//送到LCD修改显示阈值
void setHthresb()
{
	uint16_t value=chartoint();
	if(strcmp(cmdbuf,"th")==0)
	{
		
		tempHthres=value;
		sprintf(tempHthresb,"%d",tempHthres);
		//高温阈值显示
		Gui_DrawFont_GBK16(90,58,BLUE,RED,tempHthresb);
		
		printf("高温阈值:%s",valuebuf);
	
	}
	else if(strcmp(cmdbuf,"tl")==0)
	{
		tempLthres=value;
		sprintf(tempLthresb,"%d",tempLthres);
		//低温阈值显示
		Gui_DrawFont_GBK16(90,74,BLUE,RED,tempLthresb);
		
		printf("低温阈值:%s",valuebuf);
		
	}
	else if(strcmp(cmdbuf,"hu")==0)
	{
		humiHthres=value;
		sprintf(humiHthresb,"%d",humiHthres);
		//湿度阈值显示
		Gui_DrawFont_GBK16(90,90,BLUE,RED,humiHthresb);
		printf("湿度阈值:%s",valuebuf);
		
	}
	
	
}
//处理接受到的数据
void recivemag()
{
	uint8_t *p=interruptbuf;
	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';
		
		
		setHthresb();      //调用设置LCD显示阈值的函数
	}
}

10) 需要图片取模软件和中文字符取模软件取出16进制的数组
软件见下方的项目代码链接。

//电压文字
const char volbuf[][32]=
{
{0x01,0x00,0x01,0x00,0x01,0x00,0x3F,0xF8,0x21,0x08,0x21,0x08,0x21,0x08,0x3F,0xF8,0x21,0x08,0x21,0x08,0x21,0x08,0x3F,0xF8,0x21,0x0A,0x01,0x02,0x01,0x02,0x00,0xFE},/*"电",0*/
{0x00,0x00,0x3F,0xFE,0x20,0x00,0x20,0x80,0x20,0x80,0x20,0x80,0x20,0x80,0x2F,0xFC,0x20,0x80,0x20,0x80,0x20,0x90,0x20,0x88,0x20,0x88,0x40,0x80,0x5F,0xFE,0x80,0x00},/*"压",1*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00},/*":",2*/
};
//温度
const char tempbuf[][32]=
{
{0x00,0x00,0x23,0xF8,0x12,0x08,0x12,0x08,0x83,0xF8,0x42,0x08,0x42,0x08,0x13,0xF8,0x10,0x00,0x27,0xFC,0xE4,0xA4,0x24,0xA4,0x24,0xA4,0x24,0xA4,0x2F,0xFE,0x00,0x00},/*"温",0*/
{0x01,0x00,0x00,0x80,0x3F,0xFE,0x22,0x20,0x22,0x20,0x3F,0xFC,0x22,0x20,0x22,0x20,0x23,0xE0,0x20,0x00,0x2F,0xF0,0x24,0x10,0x42,0x20,0x41,0xC0,0x86,0x30,0x38,0x0E},/*"度",1*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00},/*":",2*/
};
//湿度
const char humiditybuf[][32]=
{
{0x00,0x00,0x27,0xF8,0x14,0x08,0x14,0x08,0x87,0xF8,0x44,0x08,0x44,0x08,0x17,0xF8,0x11,0x20,0x21,0x20,0xE9,0x24,0x25,0x28,0x23,0x30,0x21,0x20,0x2F,0xFE,0x00,0x00},/*"湿",0*/
{0x01,0x00,0x00,0x80,0x3F,0xFE,0x22,0x20,0x22,0x20,0x3F,0xFC,0x22,0x20,0x22,0x20,0x23,0xE0,0x20,0x00,0x2F,0xF0,0x24,0x10,0x42,0x20,0x41,0xC0,0x86,0x30,0x38,0x0E},/*"度",1*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00},/*":",2*/
};
//低温阈值
const char tempLthresbuf[][32]=
{
{0x08,0x08,0x08,0x3C,0x0B,0xE0,0x12,0x20,0x12,0x20,0x32,0x20,0x32,0x20,0x53,0xFE,0x92,0x20,0x12,0x10,0x12,0x10,0x12,0x12,0x12,0x0A,0x12,0x8A,0x13,0x26,0x12,0x12},/*"低",0*/
{0x00,0x00,0x23,0xF8,0x12,0x08,0x12,0x08,0x83,0xF8,0x42,0x08,0x42,0x08,0x13,0xF8,0x10,0x00,0x27,0xFC,0xE4,0xA4,0x24,0xA4,0x24,0xA4,0x24,0xA4,0x2F,0xFE,0x00,0x00},/*"温",1*/
{0x20,0x00,0x17,0xFC,0x00,0x84,0x40,0xA4,0x40,0x94,0x5F,0xF4,0x40,0x84,0x4E,0xA4,0x4A,0xA4,0x4E,0xA4,0x40,0xC4,0x46,0x54,0x58,0xB4,0x41,0x14,0x42,0x04,0x40,0x0C},/*"阈",2*/
{0x08,0x40,0x08,0x40,0x0F,0xFC,0x10,0x40,0x10,0x40,0x33,0xF8,0x32,0x08,0x53,0xF8,0x92,0x08,0x13,0xF8,0x12,0x08,0x13,0xF8,0x12,0x08,0x12,0x08,0x1F,0xFE,0x10,0x00},/*"值",3*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00},/*":",4*/
};
//高温阈值
const char tempHthresbuf[][32]=
{
{0x02,0x00,0x01,0x00,0xFF,0xFE,0x00,0x00,0x0F,0xE0,0x08,0x20,0x08,0x20,0x0F,0xE0,0x00,0x00,0x7F,0xFC,0x40,0x04,0x4F,0xE4,0x48,0x24,0x48,0x24,0x4F,0xE4,0x40,0x0C},/*"高",0*/
{0x00,0x00,0x23,0xF8,0x12,0x08,0x12,0x08,0x83,0xF8,0x42,0x08,0x42,0x08,0x13,0xF8,0x10,0x00,0x27,0xFC,0xE4,0xA4,0x24,0xA4,0x24,0xA4,0x24,0xA4,0x2F,0xFE,0x00,0x00},/*"温",1*/
{0x20,0x00,0x17,0xFC,0x00,0x84,0x40,0xA4,0x40,0x94,0x5F,0xF4,0x40,0x84,0x4E,0xA4,0x4A,0xA4,0x4E,0xA4,0x40,0xC4,0x46,0x54,0x58,0xB4,0x41,0x14,0x42,0x04,0x40,0x0C},/*"阈",2*/
{0x08,0x40,0x08,0x40,0x0F,0xFC,0x10,0x40,0x10,0x40,0x33,0xF8,0x32,0x08,0x53,0xF8,0x92,0x08,0x13,0xF8,0x12,0x08,0x13,0xF8,0x12,0x08,0x12,0x08,0x1F,0xFE,0x10,0x00},/*"值",3*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00},/*":",4*/
};
//湿度阈值
const char humiHthresbuf[][32]=
{
	{0x00,0x00,0x27,0xF8,0x14,0x08,0x14,0x08,0x87,0xF8,0x44,0x08,0x44,0x08,0x17,0xF8,0x11,0x20,0x21,0x20,0xE9,0x24,0x25,0x28,0x23,0x30,0x21,0x20,0x2F,0xFE,0x00,0x00},/*"湿",0*/
{0x01,0x00,0x00,0x80,0x3F,0xFE,0x22,0x20,0x22,0x20,0x3F,0xFC,0x22,0x20,0x22,0x20,0x23,0xE0,0x20,0x00,0x2F,0xF0,0x24,0x10,0x42,0x20,0x41,0xC0,0x86,0x30,0x38,0x0E},/*"度",1*/
{0x20,0x00,0x17,0xFC,0x00,0x84,0x40,0xA4,0x40,0x94,0x5F,0xF4,0x40,0x84,0x4E,0xA4,0x4A,0xA4,0x4E,0xA4,0x40,0xC4,0x46,0x54,0x58,0xB4,0x41,0x14,0x42,0x04,0x40,0x0C},/*"阈",2*/
{0x08,0x40,0x08,0x40,0x0F,0xFC,0x10,0x40,0x10,0x40,0x33,0xF8,0x32,0x08,0x53,0xF8,0x92,0x08,0x13,0xF8,0x12,0x08,0x13,0xF8,0x12,0x08,0x12,0x08,0x1F,0xFE,0x10,0x00},/*"值",3*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00},/*":",4*/
};

全部代码

main.c

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include "lcd.h"
#include <string.h>
#include "dht11.h"
#include "xiaokeai.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  0
    if (tnow != told)
    {
      if (tnow < told)
        tcnt += told - tnow; //这里注意一下SYSTICK是一个递减的计数器就可以了.
      else
        tcnt += 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 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;

uint8_t tempHthres=30;  //高温阈值
uint8_t tempLthres=26;  //低温阈值
uint8_t humiHthres=60;  //湿度阈值
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint16_t buf[2];   //电压和按钮
//电压文字
const char volbuf[][32]=
{
{0x01,0x00,0x01,0x00,0x01,0x00,0x3F,0xF8,0x21,0x08,0x21,0x08,0x21,0x08,0x3F,0xF8,0x21,0x08,0x21,0x08,0x21,0x08,0x3F,0xF8,0x21,0x0A,0x01,0x02,0x01,0x02,0x00,0xFE},/*"电",0*/
{0x00,0x00,0x3F,0xFE,0x20,0x00,0x20,0x80,0x20,0x80,0x20,0x80,0x20,0x80,0x2F,0xFC,0x20,0x80,0x20,0x80,0x20,0x90,0x20,0x88,0x20,0x88,0x40,0x80,0x5F,0xFE,0x80,0x00},/*"压",1*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00},/*":",2*/
};
//温度
const char tempbuf[][32]=
{
{0x00,0x00,0x23,0xF8,0x12,0x08,0x12,0x08,0x83,0xF8,0x42,0x08,0x42,0x08,0x13,0xF8,0x10,0x00,0x27,0xFC,0xE4,0xA4,0x24,0xA4,0x24,0xA4,0x24,0xA4,0x2F,0xFE,0x00,0x00},/*"温",0*/
{0x01,0x00,0x00,0x80,0x3F,0xFE,0x22,0x20,0x22,0x20,0x3F,0xFC,0x22,0x20,0x22,0x20,0x23,0xE0,0x20,0x00,0x2F,0xF0,0x24,0x10,0x42,0x20,0x41,0xC0,0x86,0x30,0x38,0x0E},/*"度",1*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00},/*":",2*/
};
//湿度
const char humiditybuf[][32]=
{
{0x00,0x00,0x27,0xF8,0x14,0x08,0x14,0x08,0x87,0xF8,0x44,0x08,0x44,0x08,0x17,0xF8,0x11,0x20,0x21,0x20,0xE9,0x24,0x25,0x28,0x23,0x30,0x21,0x20,0x2F,0xFE,0x00,0x00},/*"湿",0*/
{0x01,0x00,0x00,0x80,0x3F,0xFE,0x22,0x20,0x22,0x20,0x3F,0xFC,0x22,0x20,0x22,0x20,0x23,0xE0,0x20,0x00,0x2F,0xF0,0x24,0x10,0x42,0x20,0x41,0xC0,0x86,0x30,0x38,0x0E},/*"度",1*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00},/*":",2*/
};
//低温阈值
const char tempLthresbuf[][32]=
{
{0x08,0x08,0x08,0x3C,0x0B,0xE0,0x12,0x20,0x12,0x20,0x32,0x20,0x32,0x20,0x53,0xFE,0x92,0x20,0x12,0x10,0x12,0x10,0x12,0x12,0x12,0x0A,0x12,0x8A,0x13,0x26,0x12,0x12},/*"低",0*/
{0x00,0x00,0x23,0xF8,0x12,0x08,0x12,0x08,0x83,0xF8,0x42,0x08,0x42,0x08,0x13,0xF8,0x10,0x00,0x27,0xFC,0xE4,0xA4,0x24,0xA4,0x24,0xA4,0x24,0xA4,0x2F,0xFE,0x00,0x00},/*"温",1*/
{0x20,0x00,0x17,0xFC,0x00,0x84,0x40,0xA4,0x40,0x94,0x5F,0xF4,0x40,0x84,0x4E,0xA4,0x4A,0xA4,0x4E,0xA4,0x40,0xC4,0x46,0x54,0x58,0xB4,0x41,0x14,0x42,0x04,0x40,0x0C},/*"阈",2*/
{0x08,0x40,0x08,0x40,0x0F,0xFC,0x10,0x40,0x10,0x40,0x33,0xF8,0x32,0x08,0x53,0xF8,0x92,0x08,0x13,0xF8,0x12,0x08,0x13,0xF8,0x12,0x08,0x12,0x08,0x1F,0xFE,0x10,0x00},/*"值",3*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00},/*":",4*/
};
//高温阈值
const char tempHthresbuf[][32]=
{
{0x02,0x00,0x01,0x00,0xFF,0xFE,0x00,0x00,0x0F,0xE0,0x08,0x20,0x08,0x20,0x0F,0xE0,0x00,0x00,0x7F,0xFC,0x40,0x04,0x4F,0xE4,0x48,0x24,0x48,0x24,0x4F,0xE4,0x40,0x0C},/*"高",0*/
{0x00,0x00,0x23,0xF8,0x12,0x08,0x12,0x08,0x83,0xF8,0x42,0x08,0x42,0x08,0x13,0xF8,0x10,0x00,0x27,0xFC,0xE4,0xA4,0x24,0xA4,0x24,0xA4,0x24,0xA4,0x2F,0xFE,0x00,0x00},/*"温",1*/
{0x20,0x00,0x17,0xFC,0x00,0x84,0x40,0xA4,0x40,0x94,0x5F,0xF4,0x40,0x84,0x4E,0xA4,0x4A,0xA4,0x4E,0xA4,0x40,0xC4,0x46,0x54,0x58,0xB4,0x41,0x14,0x42,0x04,0x40,0x0C},/*"阈",2*/
{0x08,0x40,0x08,0x40,0x0F,0xFC,0x10,0x40,0x10,0x40,0x33,0xF8,0x32,0x08,0x53,0xF8,0x92,0x08,0x13,0xF8,0x12,0x08,0x13,0xF8,0x12,0x08,0x12,0x08,0x1F,0xFE,0x10,0x00},/*"值",3*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00},/*":",4*/
};
//湿度阈值
const char humiHthresbuf[][32]=
{
	{0x00,0x00,0x27,0xF8,0x14,0x08,0x14,0x08,0x87,0xF8,0x44,0x08,0x44,0x08,0x17,0xF8,0x11,0x20,0x21,0x20,0xE9,0x24,0x25,0x28,0x23,0x30,0x21,0x20,0x2F,0xFE,0x00,0x00},/*"湿",0*/
{0x01,0x00,0x00,0x80,0x3F,0xFE,0x22,0x20,0x22,0x20,0x3F,0xFC,0x22,0x20,0x22,0x20,0x23,0xE0,0x20,0x00,0x2F,0xF0,0x24,0x10,0x42,0x20,0x41,0xC0,0x86,0x30,0x38,0x0E},/*"度",1*/
{0x20,0x00,0x17,0xFC,0x00,0x84,0x40,0xA4,0x40,0x94,0x5F,0xF4,0x40,0x84,0x4E,0xA4,0x4A,0xA4,0x4E,0xA4,0x40,0xC4,0x46,0x54,0x58,0xB4,0x41,0x14,0x42,0x04,0x40,0x0C},/*"阈",2*/
{0x08,0x40,0x08,0x40,0x0F,0xFC,0x10,0x40,0x10,0x40,0x33,0xF8,0x32,0x08,0x53,0xF8,0x92,0x08,0x13,0xF8,0x12,0x08,0x13,0xF8,0x12,0x08,0x12,0x08,0x1F,0xFE,0x10,0x00},/*"值",3*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00},/*":",4*/
};
uint8_t tempHthresb[6];
uint8_t tempLthresb[6];
uint8_t humiHthresb[6];

uint8_t feijibuf[6];
uint8_t zhilengbuf[6];
uint8_t zhirebuf[6];

uint8_t flag=0;  //按键中断触发标志

uint8_t interruptbuf[256];//串口1接收到的数据
uint8_t wifibuf[256];//串口2接收到的数据

/* 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_ADC1_Init();
  MX_USART1_UART_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
	Lcd_Init();
	//显示欢迎界面
	Lcd_Clear(0xffff);
	for(int wi=128;wi>-60;wi--)
	{
		Gui_DrawFont_1616(wi,60,BLACK,WHITE,openword,4);
	}
	//显示图片
	showimage(gImage_xiaokeai);
	HAL_Delay(2000);
	Lcd_Clear(0xF800);
	
	//打开串口1空闲中断
	HAL_UART_Receive_DMA(&huart1,interruptbuf,sizeof(interruptbuf));
	__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);
	
	//打开串口2空闲中断(wifi)
	HAL_UART_Receive_DMA(&huart2,wifibuf,sizeof(wifibuf));
	__HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE);
	delay_init(64);
	
	FS_DHT11_Init();
	DHT11_Rst();
	if(FS_DHT11_Init()==0)
		printf("dht11正常");
	else
		printf("dht11不存在");
  float temp;
	
	//将温湿度阈值转化为字符串
	sprintf(tempHthresb,"%d",tempHthres);
	sprintf(tempLthresb,"%d",tempLthres);
	sprintf(humiHthresb,"%d",humiHthres);
	
	//高温阈值显示
	//printf("tempHthres=%d\n",tempHthres);
	Gui_DrawFont_1616(10,58,BLUE,RED,tempHthresbuf,5);
	Gui_DrawFont_GBK16(90,58,BLUE,RED,tempHthresb);
	//低温阈值显示
	Gui_DrawFont_1616(10,74,BLUE,RED,tempLthresbuf,5);
	Gui_DrawFont_GBK16(90,74,BLUE,RED,tempLthresb);
	//湿度阈值显示
	Gui_DrawFont_1616(10,90,BLUE,RED,humiHthresbuf,5);
	Gui_DrawFont_GBK16(90,90,BLUE,RED,humiHthresb);
	//风机制冷制热片LCD显示
	uint8_t fc='F';
	sprintf(feijibuf,"FJ:%c ",fc);
	Gui_DrawFont_GBK16(10,106,BLUE,RED,feijibuf);
	
	uint8_t hc='F';
	sprintf(zhirebuf,"ZH:%c",hc);
	Gui_DrawFont_GBK16(50,106,BLUE,RED,zhirebuf);
	
	uint8_t lc='F';
	sprintf(zhilengbuf,"ZL:%c",fc);
	Gui_DrawFont_GBK16(90,106,BLUE,RED,zhilengbuf);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		//获取按键与电压值
		HAL_ADC_Start_DMA(&hadc1,(uint32_t *)buf,2);
		//获取温湿度
		DHT11_Read_Data(&humiH,&humiL,&tempH,&tempL);
		temp = tempH + tempL*0.1;
		
		printf("温度 = %.2fC  湿度 = %d%%",temp,humiH);
		
		//温度显示在LCD
		char tempb[10]={0};
		sprintf(tempb,"%.2f",temp);
	  Gui_DrawFont_1616(10,26,BLUE,RED,tempbuf,3);
	  Gui_DrawFont_GBK16(48,26,BLUE,RED,(uint8_t *)tempb);
		//湿度显示在LCD
		char hum[6]={0};
	  sprintf(hum,"%hu%%",humiH);
	  Gui_DrawFont_1616(10,42,BLUE,RED,humiditybuf,3);
	  Gui_DrawFont_GBK16(48,42,BLUE,RED,(uint8_t *)hum);
		HAL_Delay(2000);
		//高温绿灯亮,低温黄灯亮,湿度高蓝灯亮
		if(temp>tempHthres)
		{
			HAL_GPIO_WritePin(GREEN_GPIO_Port,GREEN_Pin,GPIO_PIN_RESET);
			HAL_GPIO_WritePin(GREEN_GPIO_Port,YELO_Pin,GPIO_PIN_SET);
			temp-=1;    //模拟降温过程
			
			//制冷LCD显示
			lc='T';
			sprintf(zhilengbuf,"ZL:%c",lc);
			Gui_DrawFont_GBK16(90,106,BLUE,RED,zhilengbuf);
		}
		if(temp<tempLthres)
		{
			HAL_GPIO_WritePin(GREEN_GPIO_Port,YELO_Pin,GPIO_PIN_RESET);
			//HAL_GPIO_WritePin(GREEN_GPIO_Port,GREEN_Pin,GPIO_PIN_SET);
			temp+=1;  //模拟升温过程
			
			//制热LCD显示
			 hc='T';
			sprintf(zhirebuf,"ZH:%c",hc);
			Gui_DrawFont_GBK16(50,106,BLUE,RED,zhirebuf);
		}
		if(humiH>humiHthres)
		{
			HAL_GPIO_WritePin(GREEN_GPIO_Port,BLUE_Pin,GPIO_PIN_RESET);
			
			humiH-=1;   //模拟除湿过程
			
			//风机状态LCD显示
			fc='T';
			sprintf(feijibuf,"FJ:%c ",fc);
			Gui_DrawFont_GBK16(10,106,BLUE,RED,feijibuf);
			
		}
		//如果在正常范围内关闭所有的灯
		if(temp<tempHthres&&temp>tempLthres)
		{
			HAL_GPIO_WritePin(GREEN_GPIO_Port,YELO_Pin|GREEN_Pin,GPIO_PIN_SET);
		}
		
		//温度大于高温阈值+5,关闭制热
		if(temp>tempHthres+5)
		{
			HAL_GPIO_WritePin(GREEN_GPIO_Port,YELO_Pin,GPIO_PIN_SET);
			hc='F';
			sprintf(zhirebuf,"ZH:%c",hc);
			Gui_DrawFont_GBK16(50,106,BLUE,RED,zhirebuf);
		}
		//温度低于低温阈值-5,关闭制冷
		if(temp<tempLthres-5)
		{
			HAL_GPIO_WritePin(GREEN_GPIO_Port,GREEN_Pin,GPIO_PIN_SET);
			lc='F';
			sprintf(zhilengbuf,"ZL:%c",fc);
			Gui_DrawFont_GBK16(90,106,BLUE,RED,zhilengbuf);	
		}
		//低于除湿阈值,关闭风机	
		if(humiH<humiHthres)
		{
			HAL_GPIO_WritePin(GREEN_GPIO_Port,BLUE_Pin,GPIO_PIN_SET);
			fc='F';
			sprintf(feijibuf,"FJ:%c ",fc);
			Gui_DrawFont_GBK16(10,106,BLUE,RED,feijibuf);
		}
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* 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_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;
  RCC_OscInitStruct.PLL.PLLN = 16;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  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)
{
	if(GPIO_Pin==GPIO_PIN_8)
	{
		HAL_ADC_Start_DMA(&hadc1,(uint32_t *)buf,2);
		flag=1;
	}
}
//ADC转换完成,并DMA取完数据触发的中断函数
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
	HAL_ADC_Stop_DMA(&hadc1);
	//电压
	buf[0]=buf[0]*3000/4096/1000*2;
	float floatbuf=(float)buf[0];    //转化成浮点型
	char volt[12]={0};
	sprintf(volt,"%1.2fV",floatbuf);   //转换成字符串
	printf("电压=%1.1f\n",floatbuf);
	Gui_DrawFont_1616(10,10,BLUE,RED,volbuf,3);
	Gui_DrawFont_GBK16(48,10,BLUE,RED,(uint8_t *)volt);
	//printf("key=%d\n",buf[1]);
	//上方向键调高温阈值,下方向键调低温阈值,左方向键调湿度阈值
	
	if(flag)
	{
		printf("flag=%d\n",flag);
		if(buf[1]<2400&&buf[1]>2100)
		{	
			tempHthres--;
			if(tempHthres<26)
				tempHthres=46;
			sprintf(tempHthresb,"%d",tempHthres);
			Gui_DrawFont_GBK16(90,58,BLACK,RED,tempHthresb);
			
		}
		if(buf[1]<900&&buf[1]>500)
		{
			tempLthres--;
			if(tempLthres<18)
				tempLthres=32;
			sprintf(tempLthresb,"%d",tempLthres);
			Gui_DrawFont_GBK16(90,74,BLACK,RED,tempLthresb);
		}
		if(buf[1]<1800&&buf[1]>1500)
		{
			humiHthres--;
			if(humiHthres<53)
				humiHthres=68;
			sprintf(humiHthresb,"%d",humiHthres);
			Gui_DrawFont_GBK16(90,90,BLACK,RED,humiHthresb);
		}
		if(buf[1]<2900&&buf[1]>2500)
		{
			Gui_DrawFont_GBK16(90,58,BLUE,RED,tempHthresb);
			Gui_DrawFont_GBK16(90,74,BLUE,RED,tempLthresb);
			Gui_DrawFont_GBK16(90,90,BLUE,RED,humiHthresb);
		}
		
		flag=0;
	}
	
}

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

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
#include <string.h>
#include <stdio.h>
#include "lcd.h"
/* 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 */
extern uint8_t tempHthres;  //高温阈值
extern uint8_t tempLthres;  //低温阈值
extern uint8_t humiHthres;  //湿度阈值
extern uint8_t tempHthresb[6];
extern uint8_t tempLthresb[6];
extern uint8_t humiHthresb[6];

extern uint8_t interruptbuf[256];//串口接收到的数据
uint8_t cmdbuf[64];              //命令
uint8_t valuebuf[256];           //数值
extern uint8_t wifibuf[256];//串口2接收到的数据

串口1
//温湿度数值字符串转整形
uint16_t chartoint()
{
	uint8_t *valuep=valuebuf;
	uint16_t sum=0;
	while(*valuep!='\0')
	{
		sum=sum*10+(*valuep-48);	
		valuep++;
	}
	
	return sum;
}
//送到LCD修改显示阈值
void setHthresb()
{
	uint16_t value=chartoint();
	if(strcmp(cmdbuf,"th")==0)
	{
		
		tempHthres=value;
		sprintf(tempHthresb,"%d",tempHthres);
		//高温阈值显示
		Gui_DrawFont_GBK16(90,58,BLUE,RED,tempHthresb);
		
		printf("高温阈值:%s",valuebuf);
	
	}
	else if(strcmp(cmdbuf,"tl")==0)
	{
		tempLthres=value;
		sprintf(tempLthresb,"%d",tempLthres);
		//低温阈值显示
		Gui_DrawFont_GBK16(90,74,BLUE,RED,tempLthresb);
		
		printf("低温阈值:%s",valuebuf);
		
	}
	else if(strcmp(cmdbuf,"hu")==0)
	{
		humiHthres=value;
		sprintf(humiHthresb,"%d",humiHthres);
		//湿度阈值显示
		Gui_DrawFont_GBK16(90,90,BLUE,RED,humiHthresb);
		printf("湿度阈值:%s",valuebuf);
		
	}
	
	
}
//处理接受到的数据
void recivemag()
{
	uint8_t *p=interruptbuf;
	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';
		
		
		setHthresb();      //调用设置LCD显示阈值的函数
	}
}




void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
	if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE))
	{
		__HAL_UART_CLEAR_FLAG(&huart1,UART_FLAG_IDLE);
		HAL_UART_DMAStop(&huart1);
		recivemag();                //处理接受到的数据(命令和要设置的值)
			
	uint8_t len=sizeof(interruptbuf)-hdma_usart1_rx.Instance->CNDTR;
//		HAL_UART_Transmit_DMA(&huart1,interruptbuf,len);
		HAL_UART_Receive_DMA(&huart1,interruptbuf,sizeof(interruptbuf));
	}
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}

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 mode
    HAL_Delay(5);
    Lcd_WriteData(0xC8);
    HAL_Delay(5);
    Lcd_WriteData(0xC8);
    HAL_Delay(5);
    Lcd_WriteIndex(0x3A);
    HAL_Delay(5);
    Lcd_WriteIndex(0x3A);//65k mode
    HAL_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_CLR
    SPI_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); 	//拉低DQ
    HAL_Delay(20);    	//拉低至少18ms
    HAL_GPIO_WritePin(DHT11_GPIO_PORT, DHT11_GPIO_PIN, GPIO_PIN_SET);		//DQ=1
    delay_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)   //说明,dht11还是大于80us的低电平信号,正常的话,应该是80us后,变成高电平,retry应该小于100接近80
			 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);
    }//延时100
    retry=0;
    while(!DHT11_DQ_IN&&retry<100)//等待变高电平
    {
        retry++;
        delay_us(1);
    }
    delay_us(40);//等待40us
    if(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];

        }
    } else
        return 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();  //复位DHT11
    return 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



  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值