马上就要比赛了,我也是把自己写完调试好的题目分享出来给大家,同时也祝大家取得自己理想的成绩。 好了废话不多说,我们先看客观题再看程序设计题。
目录
客观题:
程序设计题:
题目解析:
CubeMX配置
代码演示:
客观题:
收集的一些历年的比赛客观题和解析,以及程序设计题的PDF,在这里分享给大家。
链接:https://pan.baidu.com/s/1hTw0inSbLjX57hOtankgKw
提取码:np1p
第十三届的客观题考察的是比较基础的知识的了,其中第一题和最后一题都可以在参考手册(比赛时允许查阅)中找到不需要死记。本次客观题的解析来自4梯,里面还有客观题的视频讲解哦。
程序设计题:
题目解析:
十三届的程序设计题用到了LCD,LED,按键,串口和PWM,都是老朋友了。
其中PWM主要用到了两个函数,一个用来改变PWM的频率,一个用来改变PWM的占空比。
//通过修改PWM的自动重装载值(ARR)来修改PWM的频率
__HAL_TIM_SET_AUTORELOAD(&htim2,499);
//修改PWM的占空比(CCRX)
__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,50);
注意:PWM的占空比 = CCRX / (ARR+1),例如以上代码就是设置定时器2的第二通道的ARR为499,CCRX为50,所以占空比为50/(499+1) = 10%
而串口主要是处理接收的字符串,就可以使用sscanf()函数来切割字符串。
函数原型:int sscanf(const char *str, const char *format, ...)
详细用法感兴趣的可以百度一下,简单说一下这个函数的用法是从字符串读取格式化输入,其实和scanf()用法差不多,举个例子吧 sscanf(rxarr, "%d-%d",&Old_PWD,&New_PWD);
以上用法是,从串口接收的字符串rxarr假如是"123-789",那么就把“123”转化成整数型赋值给Old_PWD,把“789”转化成整数型赋值给New_PWD
说完了就从 CubeMX配置开始吧。
CubeMX配置
时钟配置完了,需要按下回车(Enter)来保存。
根据原理图配置GPIO引脚,其中lcd和led的引脚都设置为output,按键设置为input,串口使用USART1也就是PA10和PA9,PWM是PA1设置为定时器2的第二通道,需要把PD2也设置为output用来作为led的锁存器。
在GPIO中选中按键的引脚,设置为上拉输入模式。
在GPIO中,选中led的引脚,设置为初始状态为高电平,推挽输出模式,既不上拉也不下拉。其他引脚使用默认设置就是行。
需要把定时器2的通道2设置为PWM通道2,然后设置预分频器值和自动重装值以及占空比。
设置定时器3每10ms中断一次。
设置串口1的波特率为9600,开启中断,其他默认即可。
设置项目名字和保存路径(建议不要有中文),以及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 "tim.h" #include "usart.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "led.h" #include "timer.h" #include "display.h" #include "lcd.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 rxdata; //串口接收的单个字符 extern uchar btn; //按键值 extern uchar STA_Flag; //密码正确的标志 char text[21]; //输出到LCD的字符串 uint PWD = 123; //密码值 char B1 = '@',B2 = '@',B3 = '@'; bool jm = 0; //0表示密码输入界面,1表示输出状态界面 uchar CNT = 0; //密码输入错误的计数值 bool L1 = 0,L2 = 0,L2_Flag = 0; //L1是LED1标志位,L2是LED2的标志位,L2_flag是LED2 5秒计时的标志位 /* 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_TIM2_Init(); MX_TIM3_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ LED_Show(0xFF,GPIO_PIN_SET); //初始化LED,使其全灭 LCD_Init(); //初始化LCD LCD_Clear(Black); //清屏为黑色 LCD_SetBackColor(Black); LCD_SetTextColor(White); HAL_TIM_Base_Start_IT(&htim3); //初始化定时器3 HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2); //初始化PWM HAL_UART_Receive_IT(&huart1, &rxdata, 1); //初始化串口接收 /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ switch(btn) { case 1: //按键1使密码的第一位从@-0-9-0 { if(jm == 0) { if(B1 == '@') B1 = 48; //字符'0'的ASCII值 else if(++B1>=58) B1 = 48; } btn = 0; } break; case 2: //按键2使密码的第二位从@-0-9-0 { if(jm == 0) { if(B2 == '@') B2 = 48; else if(++B2>=58) B2 = 48; } btn = 0; } break; case 3: //按键3使密码的第三位从@-0-9-0 { if(jm == 0) { if(B3 == '@') B3 = 48; else if(++B3>=58) B3 = 48; } btn = 0; } break; case 4: //按键4,处理密码是否正确 { if(jm == 0) { if(PWD == (B1-48)*100+(B2-48)*10+(B3-48)) { jm = 1; LCD_Clear(Black); __HAL_TIM_SET_AUTORELOAD(&htim2,499); __HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,50); L1 = 1; STA_Flag = 1; } else { if(++CNT>=3) { L2_Flag = 1; CNT = 0; } B1 = '@',B2 = '@',B3 = '@'; } } btn = 0; } break; } if(STA_Flag == 2) //密码正确进入输出状态界面 { STA_Flag = 0; jm = 0; LCD_Clear(Black); __HAL_TIM_SET_AUTORELOAD(&htim2,999); __HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,500); B1 = '@',B2 = '@',B3 = '@'; } if(jm == 0) PSD(); else STA(); LED_Hint(); //LED的处理 UART_RX(); //串口接收处理函数 } /* 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 #include #include /* 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 -----------------------------------------------------------*/ /* USER CODE BEGIN Private defines */ #define uchar unsigned char #define uint unsigned int /* USER CODE END Private defines */ #ifdef __cplusplus } #endif #endif /* __MAIN_H */
main.h中添加了几个头文件和define。
led.c
#include "led.h" extern bool L1; extern bool L2; void LED_Show(uint16_t value,GPIO_PinState PinState) { HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOC,value=500) { L1_CNT = 0; L1 = 0; } } if(L2_Flag == 1) //LED2闪烁计时5秒 { if(++L2_CNT>=10) { L2 ^= 1; L2_CNT = 0; } if(++L2_Flag_CNT>=500) { L2_Flag = 0; L2_Flag_CNT = 0; L2 = 0; } } } } void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) //串口接收中断回调函数 { if(huart->Instance == USART1) { rxarr[arrow++] = rxdata; HAL_UART_Receive_IT(&huart1, &rxdata, 1); } } void UART_RX(void) //判断串口有没有接收完字符 { uchar temp; if(arrow != 0) { temp = arrow; HAL_Delay(1); if(temp == arrow) CH_Handle(); } }
timer.h
#ifndef __TIMER_H #define __TIMER_H #include "main.h" #include "usart.h" #include "display.h" typedef struct { bool press; uchar state; }Btn; void KEY_Scan(void); void UART_RX(void); #endif
display.c
#include "display.h" extern char text[21]; extern uchar arrow; extern char rxarr[8]; extern uint PWD; extern char B1,B2,B3; void LCD_Print(uchar line, char *text) //重新封装一下LCD显示函数,可以不写 { LCD_DisplayStringLine((u8)line*24, (u8 *)text); } void CH_Handle(void) //串口接收到字符串的处理函数 { if(arrow>0) { if(arrow == 7) { uint Old_PWD = 0,New_PWD = 0; sscanf(rxarr, "%d-%d",&Old_PWD,&New_PWD); if(Old_PWD == PWD) PWD = New_PWD; } } arrow = 0; memset(rxarr,0,8); } void PSD(void) //密码显示界面 { sprintf(text," PSD "); LCD_Print(0,text); sprintf(text," B1:%c ",B1); LCD_Print(3,text); sprintf(text," B2:%c ",B2); LCD_Print(4,text); sprintf(text," B3:%c ",B3); LCD_Print(5,text); } void STA(void) //状态输出界面 { sprintf(text," STA "); LCD_Print(0,text); sprintf(text," F:2000Hz "); LCD_Print(3,text); sprintf(text," D:10%% "); LCD_Print(4,text); }
display.h
#ifndef __DISPLAY_H #define __DISPLAY_H #include "main.h" #include "LCD.h" #include "usart.h" void LCD_Print(uchar line, char *text); void CH_Handle(void); void PSD(void); void STA(void); #endif
以上就是我修改过的文件和新添加的文件。还有lcd模块,不过不需要我们自己写,官方有提供,直接复制过来就行,注意有三个文件,别只复制lcd.c和lcd.h。
好了,以上就是蓝桥杯嵌入式第十三届省赛的题目解析了,如果有什么问题和建议都欢迎在评论区提出来喔。
还没有评论,来说两句吧...