C语言——基于stm32G030的温湿度传感器项目实验

news2024/10/5 13:02:30

一、功能要求:

设备自检功能:

设备上电自检(检查传感器采集是否正常, DHT11有存在响应, 可以自检使用, )自检通过后,由串口打印设备状态信息。

自动控制功能:

进入自动控制模式, LCD显示温湿度信息 加热片制冷片风机状态。与上位机通信( 串口助手), 每2s发送设备状态信(温湿度值,风机状态,制冷片状态,加热片状态)到上位机 。

阈值设置功能:

可以通过五向按键选择并调整温湿度的阈值大小。

可以通过上位机发送命令设定温湿度的阈值大小。

二、功能概述

模块

功能

LCD显示屏

显示温湿度, 风机开关情况 ,制冷片开关情况, 加热片开关情况, 温湿

度上下阈值

LED

三个灯分别模拟风机 、制冷片, 加热片 。( 灯亮表示开, 灯灭表示关)

PA0

电池电压采集(选做)

串口

数据接收及下发数据控制

低温加热

当环境温度低于设置的阈值时, 加热片启动 。加热到温度阈值5度以上停止工作

高温降温

当环境温度高于设置的阈值时,制冷片启动 。降温到温度阈值5度以下停止工作

除湿

当环境湿度高于设置的阈值时, 风机和制冷片,加热片启动 。湿度低于设置的阈值停止。

三、除湿器项目设计说明

  湿度高于阈值,加热片、制冷片、风机同时工作

  温度也高于某一阈值,制冷片工作

四、项目实验

1.打开stm32cube max,创建新的工程,以STM32G030C8Tx芯片建立工程,配置相关引脚。

2.完成相关配置,生成hal库函数的标准代码

3.分别将Lcd和DHT11的驱动.c文件和头文件放到生成文件中的code的Src和Inc文件中

4.完成相关代码的编写,然后完成相关实验

五、代码解析

1.延时函数

        滴答计时器是向下计数的,told是获取的计数器的初值,tnow是在每次循环的开始重新获取计数器的数值;如果told大于tnow代表计数器正常运行,tcnt就加一,如果全程没有错误,等到tcnt大于计数器初值的时候退出,计数结束;

         如果中途出现told小于tnow时,就代表着循环了一圈了,用重载值减去tnow现在的值,再加上tnow,还是相当于tcnt就加一,等到tcnt大于计数器初值的时候退出,计数结束,实现延时功能。

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);
}

2.定义全局变量和主函数

初始化LCD和DHT11,开始时检验DHT11是否正常,无论是否正常都反馈;如果DHT11正常的话,读取温湿度数据。

/* USER CODE BEGIN PFP */
uint8_t humiH;
uint8_t humiL;
uint8_t tempH;
uint8_t tempL;
int tempmax=30;
int tempmin=26;
int humimax=65;
float temp;
char lcdtem[16]="";
char lcdhum[16]="";
char humiset[16]="";
char tmaxset[16]="";
char tminset[16]="";
char devh[32]="devhot: off";
char devc[32]="devcold:off";
char fun[32]="fun:    off";
char set[32]="";
char md[3]="CS";
int setmode=0;
int high=0;
int low=0;
int mode=0;
int color0=BLUE;
int color1=BLUE;
int color2=BLUE; 
/* USER CODE END PFP */
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_USART1_UART_Init();
  MX_TIM16_Init();
  MX_ADC1_Init();
  /* USER CODE BEGIN 2 */
	Lcd_Init();
	Lcd_Clear(BLUE);
	delay_init(16);//根据频率确定参数 此时16MHZ
	FS_DHT11_Init();//自检初始化函数 检测能否正常通信 只关心起始信号的正确性 不关心后面的数据
	HAL_Delay(500);
	if(!FS_DHT11_Init()) //根据0或1的返回值 由子函数可知 0自检成功 1表示失败
	{
		printf("check ok\n");
		Gui_DrawFont_GBK16(15,40,YELLOW,BLUE,"check ok   ");
	}
	Lcd_Clear(BLUE);
	HAL_TIM_Base_Start_IT(&htim16);
  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */
		DHT11_Read_Data(&humiH,&humiL,&tempH,&tempL);
		temp = tempH + tempL*0.1;
		HAL_UART_Receive_IT(&huart1,set,10);
		dev_control();
		send_lcd();
		HAL_ADC_Start(&hadc1);//启动ADC转化
		HAL_ADC_PollForConversion(&hadc1,1000);//等待转换完成,多通道不可用
		uint32_t key = HAL_ADC_GetValue(&hadc1);//获取ADC转化值
		HAL_ADC_Stop(&hadc1);//停止ADC转化
		HAL_Delay(300);
		
  }
  /* USER CODE END 3 */
}

3.控制函数

将控制模式分为两种,模式1控制除湿,如果湿度大于阈值,进行除湿;模式2控制升温和降温,如果大于高温阈值,就进行降温;如果小于低温阈值,就进行升温。

void dev_control()
{
	if(mode==1)
	{
		strcpy(md,"CS");
		if(humiH>humimax)//除湿
		{
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2,0);
			strcpy(devh,"devhot:  on");
			strcpy(devc,"devcold: on");
			strcpy(fun,"fun:     on");
		}else
		{
			strcpy(devh,"devhot: off");
			strcpy(devc,"devcold:off");
			strcpy(fun,"fun:    off");
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2,1);
		}
	}
	if(mode==0)
	{
		strcpy(md,"KW");
		if(temp>tempmax)//高温 降温
		{
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0 | GPIO_PIN_2,1);
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,0);
			strcpy(devh,"devhot: off");
			strcpy(devc,"devcold: on");
			strcpy(fun,"fun:    off");
		}else if(temp<(tempmax-5))
		{
			strcpy(devc,"devcold:off");
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,1);
		}
		if(temp<tempmin)//低温 加热
		{
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1 | GPIO_PIN_2,1);
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,0);
			strcpy(devh,"devhot:  on");
			strcpy(devc,"devcold:off");
			strcpy(fun,"fun:    off");
		}else if(temp>(tempmin+5))
		{
			strcpy(devh,"devhot: off");
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,1);
		}
	}
}

4.LCD数据显示

将temp等数值在屏幕中显示出来。

void send_lcd()
{

	sprintf(lcdtem,"Temp:%.2fC",temp);
	sprintf(lcdhum,"Humi:%d%%",humiH);
	sprintf(humiset,"HumiMax:%d%%",humimax);
	sprintf(tmaxset,"TempMax:%dC",tempmax);
	sprintf(tminset,"TempMin:%dC",tempmin);
	Gui_DrawFont_GBK16(5,5,YELLOW,BLUE,lcdtem);
	Gui_DrawFont_GBK16(100,5,WHITE,BLACK,md);
	Gui_DrawFont_GBK16(5,20,YELLOW,BLUE,lcdhum);
	Gui_DrawFont_GBK16(5,35,YELLOW,BLUE,devh);
	Gui_DrawFont_GBK16(5,50,YELLOW,BLUE,devc);
	Gui_DrawFont_GBK16(5,65,YELLOW,BLUE,fun);
	Gui_DrawFont_GBK16(5,80,YELLOW,color0,humiset);
	Gui_DrawFont_GBK16(5,95,YELLOW,color1,tmaxset);
	Gui_DrawFont_GBK16(5,110,YELLOW,color2,tminset);
}

5.按键控制

根据五向按键每个方向都可以产生不同参数,然后根据相应参数,进行控制阈值的改变

//上 2100-2000
//下 500-600
//左1500-1600
//右2900-3000
//中2500-2600
void change_data(int key)
{
	if((key>1900)&&(key<2200))//增加温度
	{
		if(low==1)
		{
			tempmin++;
		}else if(high==1)
		{
			tempmax++;
		}
	}else if((key>400)&&(key<700))//减小温度
	{
		if(low==1)
		{
			tempmin--;
		}else if(high==1)
		{
			tempmax--;
		}
	}else if((key>1400)&&(key<1700))//减小湿度
	{
		color0=BLACK;
		color1=BLUE;
		color2=BLUE;
		humimax--;
	}else if((key>2800)&&(key<3100))//增大湿度
	{
		color0=BLACK;
		color1=BLUE;
		color2=BLUE;
		humimax++;
	}else if((key>2400)&&(key<2700))//进入或退出调节模式
	{
		if(setmode == 0)
		{
			setmode=1;
			high=1;
			low=0;
			color0=BLUE;
			color1=BLACK;
			color2=BLUE;
		}else if(setmode == 1)
		{
			low=1;
			high=0;
			setmode=2;
			color0=BLUE;
			color1=BLUE;
			color2=BLACK;
		}else
		{
			setmode=0;
			color0=BLUE;
			color1=BLUE;
			color2=BLUE;
		}
	}
}
/* USER CODE END 4 */

6.输出重定向

int fputc(int ch,FILE *p)
{
		while(!(USART1->ISR &(1<<7)));
	  USART1->TDR = ch;
	  return ch;
}

7.ADC中断

void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
	HAL_ADC_Start(&hadc1);//启动ADC转化
	HAL_ADC_PollForConversion(&hadc1,1000);//等待转换完成,多通道不可用
	uint32_t key = HAL_ADC_GetValue(&hadc1);//获取ADC转化值
	HAL_ADC_Stop(&hadc1);//停止ADC转化
	change_data(key);
}

8.串口响应中断

 查找到相关数据,并将收到的数据转化成字符串,然后向串口发送

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim==&htim16)
	{
		printf("temp = %.2fC  humi = %d%%\n %s %s %s ",temp,humiH,devh,devc,fun);
	}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(strstr(set,"tempmax:"))
	{
		sscanf(set,"tempmax:%d",&tempmax);
		printf("recvdata=%s",set);
	}else if(strstr(set,"tempmin:"))
	{
		sscanf(set,"tempmin:%d",&tempmin);
		printf("recvdata=%s",set);
	}else if(strstr(set,"humimax:"))
	{
		sscanf(set,"humimax:%d",&humimax);
		printf("recvdata=%s",set);
	}else if(strstr(set,"modeset=="))
	{
		sscanf(set,"modeset==%d",&mode);
		printf("recvdata=%s",set);
	}
}

六、主函数完整代码

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2024 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 "tim.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  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;
int tempmax=30;
int tempmin=26;
int humimax=65;
float temp;
char lcdtem[16]="";
char lcdhum[16]="";
char humiset[16]="";
char tmaxset[16]="";
char tminset[16]="";
char devh[32]="devhot: off";
char devc[32]="devcold:off";
char fun[32]="fun:    off";
char set[32]="";
char md[3]="CS";
int setmode=0;
int high=0;
int low=0;
int mode=0;
int color0=BLUE;
int color1=BLUE;
int color2=BLUE; 
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void dev_control();
void send_lcd();
void change_data(int key);
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim==&htim16)
	{
		printf("temp = %.2fC  humi = %d%%\n %s %s %s ",temp,humiH,devh,devc,fun);
	}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(strstr(set,"tempmax:"))
	{
		sscanf(set,"tempmax:%d",&tempmax);
		printf("recvdata=%s",set);
	}else if(strstr(set,"tempmin:"))
	{
		sscanf(set,"tempmin:%d",&tempmin);
		printf("recvdata=%s",set);
	}else if(strstr(set,"humimax:"))
	{
		sscanf(set,"humimax:%d",&humimax);
		printf("recvdata=%s",set);
	}else if(strstr(set,"modeset=="))
	{
		sscanf(set,"modeset==%d",&mode);
		printf("recvdata=%s",set);
	}
}
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
	HAL_ADC_Start(&hadc1);//启动ADC转化
	HAL_ADC_PollForConversion(&hadc1,1000);//等待转换完成,多通道不可用
	uint32_t key = HAL_ADC_GetValue(&hadc1);//获取ADC转化值
	HAL_ADC_Stop(&hadc1);//停止ADC转化
	change_data(key);
}
/* 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_USART1_UART_Init();
  MX_TIM16_Init();
  MX_ADC1_Init();
  /* USER CODE BEGIN 2 */
	Lcd_Init();
	Lcd_Clear(BLUE);
	delay_init(16);//根据频率确定参数 此时16MHZ
	FS_DHT11_Init();//自检初始化函数 检测能否正常通信 只关心起始信号的正确性 不关心后面的数据
	HAL_Delay(500);
	if(!FS_DHT11_Init()) //根据0或1的返回值 由子函数可知 0自检成功 1表示失败
	{
		printf("check ok\n");
		Gui_DrawFont_GBK16(15,40,YELLOW,BLUE,"check ok   ");
	}
	Lcd_Clear(BLUE);
	HAL_TIM_Base_Start_IT(&htim16);
  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */
		DHT11_Read_Data(&humiH,&humiL,&tempH,&tempL);
		temp = tempH + tempL*0.1;
		HAL_UART_Receive_IT(&huart1,set,10);
		dev_control();
		send_lcd();
		HAL_ADC_Start(&hadc1);//启动ADC转化
		HAL_ADC_PollForConversion(&hadc1,1000);//等待转换完成,多通道不可用
		uint32_t key = HAL_ADC_GetValue(&hadc1);//获取ADC转化值
		HAL_ADC_Stop(&hadc1);//停止ADC转化
		HAL_Delay(300);
		
  }
  /* 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_NONE;
  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_HSI;
  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;
}

//PB0 蒸发器
//PB1 制冷片
//PB2 风机
void dev_control()
{
	if(mode==1)
	{
		strcpy(md,"CS");
		if(humiH>humimax)//除湿
		{
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2,0);
			strcpy(devh,"devhot:  on");
			strcpy(devc,"devcold: on");
			strcpy(fun,"fun:     on");
		}else
		{
			strcpy(devh,"devhot: off");
			strcpy(devc,"devcold:off");
			strcpy(fun,"fun:    off");
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2,1);
		}
	}
	if(mode==0)
	{
		strcpy(md,"KW");
		if(temp>tempmax)//高温 降温
		{
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0 | GPIO_PIN_2,1);
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,0);
			strcpy(devh,"devhot: off");
			strcpy(devc,"devcold: on");
			strcpy(fun,"fun:    off");
		}else if(temp<(tempmax-5))
		{
			strcpy(devc,"devcold:off");
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,1);
		}
		if(temp<tempmin)//低温 加热
		{
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1 | GPIO_PIN_2,1);
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,0);
			strcpy(devh,"devhot:  on");
			strcpy(devc,"devcold:off");
			strcpy(fun,"fun:    off");
		}else if(temp>(tempmin+5))
		{
			strcpy(devh,"devhot: off");
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,1);
		}
	}
}
void send_lcd()
{

	sprintf(lcdtem,"Temp:%.2fC",temp);
	sprintf(lcdhum,"Humi:%d%%",humiH);
	sprintf(humiset,"HumiMax:%d%%",humimax);
	sprintf(tmaxset,"TempMax:%dC",tempmax);
	sprintf(tminset,"TempMin:%dC",tempmin);
	Gui_DrawFont_GBK16(5,5,YELLOW,BLUE,lcdtem);
	Gui_DrawFont_GBK16(100,5,WHITE,BLACK,md);
	Gui_DrawFont_GBK16(5,20,YELLOW,BLUE,lcdhum);
	Gui_DrawFont_GBK16(5,35,YELLOW,BLUE,devh);
	Gui_DrawFont_GBK16(5,50,YELLOW,BLUE,devc);
	Gui_DrawFont_GBK16(5,65,YELLOW,BLUE,fun);
	Gui_DrawFont_GBK16(5,80,YELLOW,color0,humiset);
	Gui_DrawFont_GBK16(5,95,YELLOW,color1,tmaxset);
	Gui_DrawFont_GBK16(5,110,YELLOW,color2,tminset);
}
//上 2100-2000
//下 500-600
//左1500-1600
//右2900-3000
//中2500-2600
void change_data(int key)
{
	if((key>1900)&&(key<2200))//增加温度
	{
		if(low==1)
		{
			tempmin++;
		}else if(high==1)
		{
			tempmax++;
		}
	}else if((key>400)&&(key<700))//减小温度
	{
		if(low==1)
		{
			tempmin--;
		}else if(high==1)
		{
			tempmax--;
		}
	}else if((key>1400)&&(key<1700))//减小湿度
	{
		color0=BLACK;
		color1=BLUE;
		color2=BLUE;
		humimax--;
	}else if((key>2800)&&(key<3100))//增大湿度
	{
		color0=BLACK;
		color1=BLUE;
		color2=BLUE;
		humimax++;
	}else if((key>2400)&&(key<2700))//进入或退出调节模式
	{
		if(setmode == 0)
		{
			setmode=1;
			high=1;
			low=0;
			color0=BLUE;
			color1=BLACK;
			color2=BLUE;
		}else if(setmode == 1)
		{
			low=1;
			high=0;
			setmode=2;
			color0=BLUE;
			color1=BLUE;
			color2=BLACK;
		}else
		{
			setmode=0;
			color0=BLUE;
			color1=BLUE;
			color2=BLUE;
		}
	}
}
/* 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****/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1705227.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

汇编原理(二)寄存器——内存访问

一个字 两个字节 双字 字节为8位 字为16位&#xff08;看两格&#xff09; 双子dword32位&#xff08;看四格&#xff09; 内存中字的存储&#xff1a; 0地址单元中存放的字节型数据是多少&#xff1f; 0地址字单元中存放的字型数据是多少&#xff1f; 2地址字单元中存放…

网络之再谈体系结构

大家都知道的是网络的体系结构&#xff0c;现代软件常用的体系结构无非是TCP/IP协议栈&#xff0c;OSI因为实现复杂并且效率没有TCP/IP协议栈好&#xff0c;所以不用OSI&#xff0c;但是&#xff0c;最近在复习网络知识的时候&#xff0c;发现了一些奇怪的地方&#xff0c;那就…

深度学习-序列模型

深度学习-序列模型 1. 定义2. 应用领域3. 典型模型4. 技术细节5. 总结 序列模型是一种处理序列数据的机器学习模型&#xff0c;其输入和/或输出通常为序列形式的数据。以下是关于序列模型的详细解释&#xff1a; 1. 定义 序列模型是输入输出均为序列数据的模型&#xff0c;它…

【Python】 Python中__slots__的妙用与深入解析

基本原理 在Python中&#xff0c;__slots__是一个特殊的类属性&#xff0c;它可以用来限制一个类可以拥有的属性数量。这个特性在Python中非常有用&#xff0c;尤其是在创建大量实例时&#xff0c;可以显著减少内存的使用。 通常&#xff0c;Python的类会为每个实例自动创建一…

linux下docker 的使用(2)

上期我们讲了网络&#xff0c;现在来进行最后的 docker的基础内容 java项目的部署 假如说 我们java 项目已经写好了&#xff0c;现在在maven中打包一下我们的项目&#xff0c;然后会得到一个jar包&#xff0c;把jar包 上传到虚拟机上 点击package 命令&#xff0c;会得到一个…

【ARM+Codesys案例】RK3568 +Codesys 软PLC方案在电镀生产线的应用

1 电镀生产简介 电镀是一种比较重要的工艺&#xff0c;产品经过电镀工艺处理后&#xff0c;不仅产品质量获得提高&#xff0c;产品性能也会大幅度提高&#xff0c;同时延长了产品的使用时间。电镀生产线是指按一定的电镀生产工艺要求,将有关的各种电镀处理槽、电镀行车运动装置…

ip地址更改方法有哪些类型

在互联网世界中&#xff0c;IP地址作为每个网络设备的唯一标识符&#xff0c;其重要性不言而喻。无论是为了提升网络安全、实现远程办公&#xff0c;还是解决地域限制等问题&#xff0c;我们都有可能需要更改IP地址。本文将详细介绍IP地址更改方法有哪些类型&#xff0c;以便在…

Android面试题之Jetpack的三大核心组件

本文首发于公众号“AntDream”&#xff0c;欢迎微信搜索“AntDream”或扫描文章底部二维码关注&#xff0c;和我一起每天进步一点点 ViewModel 和 LiveData 是 Android Jetpack 组件库中的两个核心组件&#xff0c;它们能帮助开发者更有效地管理 UI 相关的数据&#xff0c;并且…

009、字符串_应用场景

缓存功能 Redis作为缓存层&#xff0c;MySQL作 为存储层&#xff0c;绝大部分请求的数据都是从Redis中获取。由于Redis具有支撑高 并发的特性&#xff0c;所以缓存通常能起到加速读写和降低后端压力的作用。 计数 许多应用都会使用Redis作为计数的基础工具&#xff0c;它可…

Pycharm常见问题1

问题&#xff1a; ValueError at /user/users/ The view user.views.get_users didnt return an HttpResponse object. It returned None instead. 问题分析&#xff1a; 视图user.views.get_users未返回HttpResponse对象&#xff0c;它返回值为None。也就是说在视图文件没有…

[JDK工具-10] jvisualvm 多合一故障处理工具

文章目录 1. 介绍2. 查看堆的变化3. 查看堆快照4. 导出堆快照文件5. 查看class对象加载信息6. CPU分析&#xff1a;发现cpu使用率最高的方法7. 查看线程快照&#xff1a;发现死锁问题 1. 介绍 VisualVM 是一款免费的&#xff0c;集成了多个 JDK 命令行工具的可视化工具&#xf…

荣耀200系列正式发布,以深度创新引领中高端市场

5月27日&#xff0c;荣耀召开数字系列新品发布会&#xff0c;正式发布荣耀200系列。 据「TMT星球」了解&#xff0c;在荣耀AI技术的加持下&#xff0c;全新荣耀200系列在影像、护眼等方面有了更进一步的创新升级&#xff0c;为行业带来众多开创性的技术解决方案。同时&#xf…

社交媒体数据恢复:云叙

在使用云盘的过程中&#xff0c;由于误操作或其他原因&#xff0c;我们可能会遇到数据丢失的问题。了解云盘数据恢复的原理和技巧对于确保云盘数据安全非常重要。接下来&#xff0c;我将为您提供一份关于云盘数据恢复的教程。 一、文件恢复 当您发现文件丢失或损坏后&#xff0…

逆向基础:软件手动脱壳技术入门

这里整合了一下之前自己学习软件手工脱壳的一些笔记和脱文&#xff0c;希望能给新学软件逆向和脱壳的童鞋们一点帮助。 1 一些概念 1.1 加壳 加壳的全称应该是可执行程序资源压缩&#xff0c;是保护文件的常用手段。加壳过的程序可以直接运行&#xff0c;但是不能查看源代码…

【Flowable 7】学习笔记 01 - 初始化数据库表创建流程(源码)

文章目录 前言版本说明配置1、引擎配置初始化2、SQL 执行创建表2.0、创建表概览&#xff08;创建表数目&#xff1a;38&#xff09;2.1、基础组件表创建&#xff08;以 common 组件为例&#xff09;2.2、changelog 组件表创建&#xff08;基于 liquibase&#xff09;2.3、Engin…

Ora-32004错误处理

问题现象 处理方法 观察alert会发现报错的参数在加载spfile的阶段 按照mos的方法对其reset 重新启动无报错 观察日志无报错

人工智能在肺癌领域的最新进展|【医学AI·顶刊速递·05-28】

小罗碎碎念 2024-05-28&#xff5c;文献速递 今天推荐的6篇文章&#xff0c;质量都非常的高&#xff0c;都是与肺癌相关的最新进展。 看我推文的&#xff0c;很多来自不同的专业&#xff0c;研究不同的癌种。小罗友情提醒&#xff0c;不要只盯着自己领域的癌种&#xff0c;要兼…

Creating parameterized straight waveguide in INTERCONNECT 创建参数化的器件

Creating parameterized straight waveguide in INTERCONNECT 创建参数化的器件 引言正文引言 之前,我们在 INTERCONNECT 中使用库中器件制作一个损耗为 3 dB /m 的直波导 一文中介绍了如何使用 Library 中的直波导来进行仿真,这里我们简单介绍如何在 INTERCONNECT 中创建属…

两年前的微信聊天记录能恢复吗?正确答案在这里(全)

微信已经成为我们日常沟通中不可或缺的一部分&#xff0c;承载着无数重要的对话和回忆。然而&#xff0c;面对手机更换、系统升级或意外删除等情况&#xff0c;许多人不禁要问&#xff1a;两年前的微信聊天记录能恢复吗&#xff1f;这个问题的答案并不简单&#xff0c;因为能否…

【荐闻】空中目标检测综述

https://t.zsxq.com/tgUjbhttps://t.zsxq.com/tgUjb 这篇综述论文全面回顾了空中目标检测的最新进展&#xff0c;包括五个不平衡问题、相关方法、实际应用和性能评估。以下是对论文内容的详细描述&#xff1a; 1&#xff09;引言&#xff1a;介绍了空中目标检测的概念&#x…