蓝桥杯嵌入式第十届初赛题目解析
最近写完了嵌入式第十届初赛的题目,拿出来和大家分享,希望帮助解决一些问题。
目录
客观题
程序设计题
题目解析
CubeMX配置
代码演示
客观题
收集的一些历年的比赛客观题和解析,以及程序设计题的PDF,在这里分享给大家。
链接:https://pan.baidu.com/s/1hTw0inSbLjX57hOtankgKw
提取码:np1p
不理解的地方可以在评论区提问嗷,或者分享的百度云里解析。
程序设计题
题目解析
这次题目用到的模块是LCD,LED,按键和ADC,没什么好说的都是常用模块,但是还是又不一样的东西,那就是LCD显示时有‘高亮’提醒 。
‘高亮’显示也比较容易实现。
LCD_SetBackColor(Green),这个函数是LCD库提供的设置背景颜色。只要使用了一次,那后面的背景色就默认都是选中的颜色,所以我们就在需要高亮显示的那一行前使用这个函数修改背景色,显示完后再把背景改回原来的颜色。
例如,题目中原来的背景色是白色,高亮显示是绿色。
if(0 == choice)LCD_SetBackColor(Green); sprintf(text," Max Volt: %.1fV ",Max); LCD_SHOW(2,text); LCD_SetBackColor(White);
说完了,那还是从CubeMX的配置开始吧。说明一下使用的新版开发板G431。
CubeMX配置
时钟配置完了,需要按下回车(Enter)来保存。
根据原理图配置GPIO引脚,其中lcd和led的引脚都设置为output,按键设置为input,PB15设置为ADC2的15通道,需要把PD2也设置为output用来作为led的锁存器。
在GPIO中选中按键的引脚,设置为上拉输入模式。
在GPIO中,选中led的引脚,设置为初始状态为高电平,推挽输出模式,既不上拉也不下拉。其他引脚使用默认设置就是行。
设置定时器3每10ms中断一次。
勾选ADC2的第15通道,其他设置默认就行。
设置项目名字和保存路径(建议不要有中文),以及IDE的版本。
勾选这个主要是让.c和.h文件单独分开,之后就可以生成代码了,CubeMX配置就完成了,如果之后想要添加新的模块或者修改配置好了模块的值,可以直接在文件中打开CubeMX的工程进行修改,改完后再点击GENERATE CODE就行了。
代码演示
main.c
/* USER CODE BEGIN Header */
/* @file : main.c* @brief : Main program body* @attention Copyright (c) 2023 STMicroelectronics.* All rights reserved. This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS./
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "tim.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "lcd.h"
#include "sys.h"
#include "show.h"
#include "timer.h"
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV */
extern uint8_t btn; //按键值float Volt = 0.0f,Max = 2.4f,Min = 1.2f;
uint8_t Up = 1,Low = 2; //Up是电压超过最大值的LED灯,Low是电压低于最小值的LED灯,不能相等
char Status[3][7] = {"Upper","Lower","Normal"};
uint8_t arrow = 0; //指向当前状态,0是Upper,1是Lower,2是Normal
bool jm = 0; //界面:0是数据显示界面,1是参数配置界面
uint8_t choice = 0; //高亮显示,选择参数项
/* 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_TIM3_Init();/* USER CODE BEGIN 2 */LCD_Init();LCD_Clear(White);LCD_SetBackColor(White);LCD_SetTextColor(Blue);HAL_TIM_Base_Start_IT(&htim3);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */Volt = GetADC(&hadc2);switch(btn){case 1:{jm ^= 1;LCD_Clear(White);btn = 0;}break;case 2:{if(1 == jm){choice ++;if(4 == choice)choice = 0;}btn = 0;}break;case 3:{if(1 == jm) ADD(choice);if(Up == Low) //如果Up的LED灯和Low的LED灯相等,被选择参数项就加一ADD(choice);btn = 0;}break;case 4:{if(1 == jm)SUB(choice); if(Up == Low) //如果Up的LED灯和Low的LED灯相等,被选择参数项就减一SUB(choice);btn = 0;}break;}Infer();LED_SHOW();if(0 == jm)Data();elseSetting();}/* USER CODE END 3 */
}/* @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {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_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 buses 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_2) != 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 */__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 */
main.h
/* USER CODE BEGIN Header */
/* @file : main.h* @brief : Header for main.c file.* This file contains the common defines of the application.* @attention Copyright (c) 2023 STMicroelectronics.* All rights reserved. This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS./
/* USER CODE END Header *//* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H#ifdef __cplusplus
extern "C" {
#endif/* Includes ------------------------------------------------------------------*/
#include "stm32g4xx_hal.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
/* USER CODE END Includes *//* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET *//* USER CODE END ET *//* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC *//* USER CODE END EC *//* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM *//* USER CODE END EM *//* Exported functions prototypes ---------------------------------------------*/
void Error_Handler(void);/* USER CODE BEGIN EFP *//* USER CODE END EFP *//* Private defines -----------------------------------------------------------*/
#define key_Pin GPIO_PIN_0
#define key_GPIO_Port GPIOA
#define keyB0_Pin GPIO_PIN_0
#define keyB0_GPIO_Port GPIOB
#define keyB1_Pin GPIO_PIN_1
#define keyB1_GPIO_Port GPIOB
#define keyB2_Pin GPIO_PIN_2
#define keyB2_GPIO_Port GPIOB
/* USER CODE BEGIN Private defines *//* USER CODE END Private defines */#ifdef __cplusplus
}
#endif#endif /* __MAIN_H */
main.h中添加了几个头文件和define。
sys.c
#include "sys.h"Btn key[4] = {0};
uint8_t btn = 0;extern float Max,Min;
extern uint8_t Up,Low,arrow;
extern bool Up_flag,Low_flag; //Up的LED灯标志,Low的LED灯标志void LED_SET(uint16_t Pin, GPIO_PinState PinState)
{HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOC,Pin,PinState);HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}void LED_SHOW(void)
{if(1 == Up_flag)LED_SET(GPIO_PIN_8<<(Up-1),GPIO_PIN_RESET);else if(1 == Low_flag)LED_SET(GPIO_PIN_8<<(Low-1),GPIO_PIN_RESET);elseLED_SET(GPIO_PIN_All,GPIO_PIN_SET);
}void KEY_Scan(void)
{uint8_t i = 0;key[0].press = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);key[1].press = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);key[2].press = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);key[3].press = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);for(i=0;i<4;i++){switch(key[i].state){case 0:if(0 == key[i].press)key[i].state = 1;break;case 1:{if(0 == key[i].press){key[i].state = 2;btn = i+1;}else{key[i].state = 0;}}break;case 2:if(1 == key[i].press)key[i].state = 0;break;}}
}void ADD(uint8_t choice)
{switch(choice){case 0:{Max += 0.3f;if(Max>3.3f)Max = 0.0f;}break;case 1:{Min += 0.3f;if(Min>3.3f)Min = 0.0f;}break;case 2:{Up++;if(9 == Up)Up = 1;}break;case 3:{Low++;if(9 == Low)Low = 1;}break;}
}void SUB(uint8_t choice)
{switch(choice){case 0:{Max -= 0.3f;if(Max<0.0f)Max = 3.3f;}break;case 1:{Min -= 0.3f;if(Min<0.0f)Min = 3.3f;}break;case 2:{Up--;if(0 == Up)Up = 8;}break;case 3:{Low--;if(0 == Low)Low = 8;}break;}
}
sys.h
#ifndef __SYS_H
#define __SYS_H#include "main.h"typedef struct{bool press;uint8_t state;
}Btn;void LED_SET(uint16_t Pin, GPIO_PinState PinState);
void LED_SHOW(void);
void KEY_Scan(void);
void ADD(uint8_t choice);
void SUB(uint8_t choice);#endif
show.c
#include "show.h"
char text[21] = {0};extern float Volt,Max,Min;
extern uint8_t Up,Low;
extern char Status[][7];
extern uint8_t arrow;
extern uint8_t choice;void LCD_SHOW(u8 line,char *text)
{LCD_DisplayStringLine(line*24,(u8 *)text);
}void Data(void)
{sprintf(text," Main ");LCD_SHOW(1,text);sprintf(text," Volt: %.2fV ",Volt);LCD_SHOW(4,text);sprintf(text," Status: %s ",Status[arrow]);LCD_SHOW(5,text);
}void Setting(void)
{sprintf(text," Setting ");LCD_SHOW(1,text);if(0 == choice)LCD_SetBackColor(Green);else LCD_SetBackColor(White);sprintf(text," Max Volt: %.1fV ",Max);LCD_SHOW(2,text);if(1 == choice)LCD_SetBackColor(Green);else LCD_SetBackColor(White);sprintf(text," Min Volt: %.1fV ",Min);LCD_SHOW(3,text);if(2 == choice)LCD_SetBackColor(Green);else LCD_SetBackColor(White);sprintf(text," Upper: LD%d ",Up);LCD_SHOW(4,text);if(3 == choice)LCD_SetBackColor(Green);else LCD_SetBackColor(White);sprintf(text," Lower: LD%d ",Low);LCD_SHOW(5,text);LCD_SetBackColor(White);
}float GetADC(ADC_HandleTypeDef *pin) //获取电压值
{uint16_t adc;HAL_ADC_Start(pin);adc = HAL_ADC_GetValue(pin);return adc*3.3/4096;
}void Infer(void) //判断电压的状态
{if(Volt>Max)arrow = 0;else if(Volt<Min)arrow = 1;elsearrow = 2;
}
show.h
#ifndef __SHOW_H
#define __SHOW_H#include "main.h"
#include "lcd.h"
#include "adc.h"
#include "sys.h"void LCD_SHOW(u8 line,char *text);
void Data(void);
void Setting(void);
float GetADC(ADC_HandleTypeDef *pin);
void Infer(void);#endif
timer.c
#include "timer.h"uint8_t Up_Cnt = 0;
uint8_t Low_Cnt = 0;
bool Up_flag = 0,Low_flag = 0; //LED闪烁的标志位extern uint8_t Up,Low,arrow;void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(TIM3 == htim->Instance){KEY_Scan();if(0 == arrow){if(20 == ++Up_Cnt){Up_Cnt = 0;Up_flag ^= 1;}}else {Up_Cnt = 0;Up_flag = 0;}if(1 == arrow){if(20 == ++Low_Cnt){Low_Cnt = 0;Low_flag ^= 1;}}else{Low_Cnt = 0;Low_flag = 0;}if(2 == arrow)LED_SET(GPIO_PIN_All,GPIO_PIN_SET);}
}
timer.h
#ifndef __TIMER_H
#define __TIMER_H#include "main.h"
#include "sys.h"#endif
以上就是我修改过的文件和新添加的文件。还有lcd模块,不过不需要我们自己写,官方有提供,直接复制过来就行,注意有三个文件,别只复制lcd.c和lcd.h。
第十届的程序设计题是不难,只要逻辑正确就比较容易。 好了,以上就是蓝桥杯嵌入式第十届省赛的题目解析了,如果有什么问题和建议都欢迎在评论区提出来喔。