第十五届蓝桥杯嵌入式模拟题二

一、基本要求


使用大赛组委会提供的嵌入式竞赛实训平台(基于STM32G431RBT6微控制器设计),完成本试题的程序设计与调试。程序编写、调试完成后,选手需通过考试系统提交以准考证号命名的hex文件。

hex文件是唯一成绩评测依据,不符合以上文件提交要求的作品将被评为零分或者被酌情扣分。

二、硬件框图


图1 系统硬件框图

三、功能描述   


3.1 基本功能

1)通过微控制器的ADC功能,检测电位器R37上输出的模拟电压信号。

2)通过PA1引脚输出频率、占空比可调节的脉冲信号。

3)通过串口实现远程控制功能。

4)根据试题要求,通过LED和LCD完成数据显示和报警功能。

5)根据试题要求,通过按键实现切换界面和控制等功能。

3.2 显示功能

1)数据界面

数据界面如图2所示,显示要素包括界面名称(DATA)、温度值(TEMP)、当前控制模式(MODE)和档位(GEAR)。

图2 数据界面

2)睡眠界面

睡眠界面如图3所示,显示要素包括界面名称(SLEEPING)和温度值(TEMP)。

图3 睡眠界面

5s内按键无动作,或串口未下发命令,自动进入“睡眠界面”。

备注:

温度值(TEMP)单位为℃,保留小数点后1位有效数字;

当前控制模式(MODE):Auto表示自动控制模式;Manu表示手动控制模式;

自动控制模式:

温度值 < 25℃时,档位为1档。

25℃ ≤ 温度值 ≤ 30℃,档位为2档。

温度值 > 30℃时,档位为3档。

显示说明

(1)显示背景颜色(BackColor):黑色。

(2)显示字体颜色(TextColor):白色。

(3)请严格按照图示要求设计各个信息项的名称(区分字母大小写)和相对行列位置。

3.3 模拟功能

通过检测电位器R37输出的模拟电压信号VR37模拟温度,VR37和与温度的关系如图4所示。

图4 VR37和温度关系图

3.3 按键功能

1)B1:定义为“模式”按键,在数据界面下,按下B1按键,切换自动控制模式和手动控制模式。切换顺序如图5所示。

图5 模式切换

2)B2:定义为“档位加”按键,在“手动控制”模式下,按下B2按键,调整当前档位。切换顺序如图6所示。

图5 档位加顺序

3)B3:定义为“档位减”按键,在“手动控制”模式下,按下B3按键,调整当前档位。切换顺序如图6所示。

图5 档位减顺序

注意:

(1)按键B2和B3仅在“手动控制”模式下有效。

(2)按键应进行有效的防抖处理,避免出现一次按键动作触发多次功能等情形。

(3)按键动作不应影响数据采集过程和屏幕显示效果。

(4)在“睡眠界面”下,按下按键B1、B2或B3切换到“数据界面”,且当前按键动作仅作唤醒“数据界面”使用,不触发按键功能。

3.5 串口功能

串口作远程遥控使用,串口功能如下:

串口发送‘B1’定义为按键B1,实现按键B1切换模式功能;

串口发送‘B2’,定义为按键B2,实现B2“档位加”功能;

串口发送‘B3’,定义为按键B3,实现B3“档位减”功能;

串口发送其他非法字符,返回“NULL”。

注意:

串口通信波特率9600;

除命令‘B1’、‘B2’和‘B3’外,其他字符均为非法字符。

在“睡眠界面”下,发送命令‘B1’、‘B2’和‘B3’界面切换到“数据界面”,且当前命令仅作唤醒“数据界面”使用,不触发功能。

3.6 PWM功能

通过PA1输出2kHz,占空比连续可调的频率信号,占空比和档位关系:

档位为1,占空比10%;

档位为2,占空比40%;

档位为3,占空比80%。

3.7 LED指示灯功能

1)在自动控制模式下,指示灯LD8点亮,否则熄灭;

2)档位为1时,指示灯LD1点亮,否则熄灭;

3)档位为2时,指示灯LD2点亮,否则熄灭;

4)档位为3时,指示灯LD3点亮,否则熄灭;

5)串口发送命令,同时指示灯LD4点亮,3秒后熄灭;

5)指示灯LD5~LD7始终处于熄灭状态。

3.8 初始状态说明

设备上电后,初始状态如下:

1)自动控制模式;

2)处于数据界面。

备注:请严格按照此初始状态设计功能。

具体代码如下:

/* 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 "stdio.h"
#include "string.h"
#include "led.h"
#include "myadc.h"
#include "lcd.h"
#include "interrupt.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
extern struct key_t key[4];
extern struct adc2_t adc2;
extern struct interface_t interface;
extern struct uart1_t uart1;
/* USER CODE END PTD */

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

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
void lcd_process(void)
{
		char buf[30];
	  if(interface.flg == 0)//DATA
		{
				if(interface.clean_flg)
				{
					  LCD_Clear(Black);
						interface.clean_flg = 0;
				}
				sprintf(buf,"        DATA");
			  LCD_DisplayStringLine(Line1,(uint8_t*)buf);
			  sprintf(buf,"     TEMP:%.1f",adc2.temp);
			  LCD_DisplayStringLine(Line3,(uint8_t*)buf);	  
			  if(interface.mode == 0)
				{ 
				    sprintf(buf,"     MODE:Auto");
				}
				else if(interface.mode == 1)
				{
						sprintf(buf,"     MODE:Manu");
				}
			  LCD_DisplayStringLine(Line4,(uint8_t*)buf);	 
			  sprintf(buf,"     GEAR:%d",interface.gears);
			  LCD_DisplayStringLine(Line5,(uint8_t*)buf);	 
		}
	  if(interface.flg == 1)//sleep
		{ 
        if(interface.sleep_clean)
				{
					 LCD_Clear(Black);
				 interface.sleep_clean = 0;
				}
			  sprintf(buf,"     SLEEPING");
			  LCD_DisplayStringLine(Line4,(uint8_t*)buf);	 
			  sprintf(buf,"     TEMP:%.1f",adc2.temp);
			  LCD_DisplayStringLine(Line5,(uint8_t*)buf);	 
		}
 
		
}

void key_process(void)
{
		//B1
	  if(key[0].short_flg == 1 && interface.flg == 0)
		{

			  interface.sleep_time = 500;
			  interface.mode++;
			  if(interface.mode > 1)
				{
						interface.mode = 0;
				}
				key[0].short_flg = 0;
		}
	  if(key[0].short_flg == 1 && interface.flg == 1)
		{
				interface.clean_flg = 1;
			  interface.sleep_time = 500;
				key[0].short_flg = 0;
		}
	  //B2
	  if(key[1].short_flg == 1 && interface.mode == 1 && interface.flg == 0)
		{
		
			 interface.sleep_time = 500;
			  interface.gears++;
			  if(interface.gears >= 3)
				{
						interface.gears = 3;
				}
				key[1].short_flg = 0;
		}
	  if(key[1].short_flg == 1&& interface.flg == 1)
		{
				interface.clean_flg = 1;
			  interface.sleep_time = 500;
				key[1].short_flg = 0;
		}
	  if(key[1].short_flg == 1&& interface.flg == 0)
		{
				
			  interface.sleep_time = 500;
				key[1].short_flg = 0;
		}
	  //B3
	  if(key[2].short_flg == 1 && interface.mode == 1&& interface.flg == 0)
		{
		
			 interface.sleep_time = 500;
			  interface.gears--;
			  if(interface.gears <= 1)
				{
						interface.gears = 1;
				}
				key[2].short_flg = 0;
		}
	  if(key[2].short_flg == 1 && interface.flg == 1)
		{
				interface.clean_flg = 1;
			  interface.sleep_time = 500;
				key[2].short_flg = 0;
		}
	  if(key[2].short_flg == 1 && interface.flg == 0)
		{
			
			  interface.sleep_time = 500;
				key[2].short_flg = 0;
		}

}

void adc_process(void)
{
		adc2.vol = get_adc();
	  if(adc2.vol <= 1.0f)
		{
		  adc2.temp = 20.0f;
		}
		else if(adc2.vol >= 3.0f)
		{
		  adc2.temp = 40.0f;
		}
		else
		{
				adc2.temp = 10.f*adc2.vol +10;
		}
		
		if(interface.mode == 0)
		{
				if(adc2.temp < 25)
				{
						interface.gears = 1;
				}
				else if(adc2.temp <= 30)
				{
						interface.gears = 2;
				}
				else
				{
						interface.gears = 3;
				}
		}
		
		
}

void pwm_process(void)
{
		if(interface.gears == 1)
		{
		   __HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,10);
		}
		else if(interface.gears == 2)
		{
		 __HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,40);
		}
		else if(interface.gears == 3)
		{
				 __HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,80);
		}
}

void myprintf(uint8_t *buf)
{
		while(*buf != 0)
		{
				HAL_UART_Transmit(&huart1,buf++,1,0xffff);
		}
}

void uart_process(void)
{
	  uint8_t str[10];
		if(uart1.place > 0)
		{
				uart1.lenght = uart1.place;
			  HAL_Delay(1);
			  if(uart1.lenght == uart1.place)
				{
					  uart1.led_flg = 1;
					  if(uart1.place == 4)
						{
						   sscanf((char*)uart1.buf,"%2s",str);
					
							 if(!strcmp((char*)str,"B1"))
							 {
										//B1
										if(interface.flg == 0)
										{
											interface.sleep_time = 500;
											interface.mode++;
											if(interface.mode > 1)
											{
													interface.mode = 0;
											}
										}
										else if(interface.flg == 1)
										{
												interface.clean_flg = 1;
												interface.sleep_time = 500;
										}
										else if(interface.flg == 0)
										{
												
												interface.sleep_time = 500;
										}								
							 }
							 else if (!strcmp((char*)str,"B2"))
							 {
										//B1
										if(interface.flg == 0 && interface.mode== 1)
										{
												 interface.sleep_time = 500;
													interface.gears++;
													if(interface.gears >= 3)
													{
															interface.gears = 3;
													}
										}
										else if(interface.flg == 1)
										{
												interface.clean_flg = 1;
												interface.sleep_time = 500;
										}
										else if(interface.flg == 0)
										{
											
												interface.sleep_time = 500;
										}
							 }
							 else if (!strcmp((char*)str,"B3"))
							 {
										//B1
										if(interface.flg == 0 && interface.mode== 1)
										{
											 interface.sleep_time = 500;
												interface.gears--;
												if(interface.gears <= 1)
												{
														interface.gears = 1;
												}
										}
										else if(interface.flg == 1)
										{
												interface.clean_flg = 1;
												interface.sleep_time = 500;
										}
										else if(interface.flg == 0)
										{
											
												interface.sleep_time = 500;
										}
							 }
							 else
							 {
									myprintf((uint8_t*)"NULL\r\n");
							 }
						}
						else
						{
									myprintf((uint8_t*)"NULL\r\n");
						}
					  uart1.place = 0;
						memset(uart1.buf,0,sizeof(uart1.buf));
					
				}
		}
}

void led_process(void)
{
		uint8_t mode = 0;
	  if(interface.mode == 0)
		{
					mode |= 0x80;
		}
		else
		{
					mode &= 0x7f;
		}
		
		if(interface.gears == 1)
		{
							mode |= 0x01;
		}
		else
		{
				mode &= 0xfe;
		}
		
		if(interface.gears == 2)
		{
				mode |= 0x02;
		}
		else
		{
				mode &= 0xfd;
		}
		
		if(interface.gears == 3)
		{
				mode |= 0x04;
		}
		else
		{
				mode &= 0xfb;
		}
		
		if(uart1.led_flg)
		{
				mode |= 0x08;
		}
		else
		{
				mode &= 0xf7;
		}
		
		LED_Disp(mode);
}
/* USER CODE END PM */

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

/* USER CODE BEGIN PV */

/* USER CODE END PV */

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

/* USER CODE END PFP */

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

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* 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_ADC2_Init();
  MX_TIM2_Init();
  MX_TIM4_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
	 interface.sleep_time = 500;
	 interface.mode = 0;
	LCD_Init();
	LCD_Clear(Black);
	LCD_SetBackColor(Black);
	LCD_SetTextColor(White);
  HAL_TIM_Base_Start_IT(&htim4);
	HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
	HAL_UART_Receive_IT(&huart1,&uart1.data,1);
  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */

		lcd_process();
		key_process();
		uart_process();
		adc_process();
		pwm_process();
		led_process();

  }
  /* 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 CPU, AHB and APB busses clocks 
  */
  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_DIV3;
  RCC_OscInitStruct.PLL.PLLN = 20;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the peripherals clocks 
  */
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_ADC12;
  PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
  PeriphClkInit.Adc12ClockSelection = RCC_ADC12CLKSOURCE_SYSCLK;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* 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 */

  /* 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,
     tex: 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****/

  • 9
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DENG YIRU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值