当前位置:   article > 正文

蓝桥杯嵌入式第十三届省赛题目解析_第13届蓝桥杯嵌入式省赛

第13届蓝桥杯嵌入式省赛

马上就要比赛了,我也是把自己写完调试好的题目分享出来给大家,同时也祝大家取得自己理想的成绩。 好了废话不多说,我们先看客观题再看程序设计题。

目录

客观题: 

程序设计题:

题目解析:

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

  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * @file : main.c
  5. * @brief : Main program body
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * Copyright (c) 2023 STMicroelectronics.
  10. * All rights reserved.
  11. *
  12. * This software is licensed under terms that can be found in the LICENSE file
  13. * in the root directory of this software component.
  14. * If no LICENSE file comes with this software, it is provided AS-IS.
  15. *
  16. ******************************************************************************
  17. */
  18. /* USER CODE END Header */
  19. /* Includes ------------------------------------------------------------------*/
  20. #include "main.h"
  21. #include "tim.h"
  22. #include "usart.h"
  23. #include "gpio.h"
  24. /* Private includes ----------------------------------------------------------*/
  25. /* USER CODE BEGIN Includes */
  26. #include "led.h"
  27. #include "timer.h"
  28. #include "display.h"
  29. #include "lcd.h"
  30. /* USER CODE END Includes */
  31. /* Private typedef -----------------------------------------------------------*/
  32. /* USER CODE BEGIN PTD */
  33. /* USER CODE END PTD */
  34. /* Private define ------------------------------------------------------------*/
  35. /* USER CODE BEGIN PD */
  36. /* USER CODE END PD */
  37. /* Private macro -------------------------------------------------------------*/
  38. /* USER CODE BEGIN PM */
  39. /* USER CODE END PM */
  40. /* Private variables ---------------------------------------------------------*/
  41. /* USER CODE BEGIN PV */
  42. extern uint8_t rxdata; //串口接收的单个字符
  43. extern uchar btn; //按键值
  44. extern uchar STA_Flag; //密码正确的标志
  45. char text[21]; //输出到LCD的字符串
  46. uint PWD = 123; //密码值
  47. char B1 = '@',B2 = '@',B3 = '@';
  48. bool jm = 0; //0表示密码输入界面,1表示输出状态界面
  49. uchar CNT = 0; //密码输入错误的计数值
  50. bool L1 = 0,L2 = 0,L2_Flag = 0; //L1是LED1标志位,L2是LED2的标志位,L2_flag是LED2 5秒计时的标志位
  51. /* USER CODE END PV */
  52. /* Private function prototypes -----------------------------------------------*/
  53. void SystemClock_Config(void);
  54. /* USER CODE BEGIN PFP */
  55. /* USER CODE END PFP */
  56. /* Private user code ---------------------------------------------------------*/
  57. /* USER CODE BEGIN 0 */
  58. /* USER CODE END 0 */
  59. /**
  60. * @brief The application entry point.
  61. * @retval int
  62. */
  63. int main(void)
  64. {
  65. /* USER CODE BEGIN 1 */
  66. /* USER CODE END 1 */
  67. /* MCU Configuration--------------------------------------------------------*/
  68. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  69. HAL_Init();
  70. /* USER CODE BEGIN Init */
  71. /* USER CODE END Init */
  72. /* Configure the system clock */
  73. SystemClock_Config();
  74. /* USER CODE BEGIN SysInit */
  75. /* USER CODE END SysInit */
  76. /* Initialize all configured peripherals */
  77. MX_GPIO_Init();
  78. MX_TIM2_Init();
  79. MX_TIM3_Init();
  80. MX_USART1_UART_Init();
  81. /* USER CODE BEGIN 2 */
  82. LED_Show(0xFF,GPIO_PIN_SET); //初始化LED,使其全灭
  83. LCD_Init(); //初始化LCD
  84. LCD_Clear(Black); //清屏为黑色
  85. LCD_SetBackColor(Black);
  86. LCD_SetTextColor(White);
  87. HAL_TIM_Base_Start_IT(&htim3); //初始化定时器3
  88. HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2); //初始化PWM
  89. HAL_UART_Receive_IT(&huart1, &rxdata, 1); //初始化串口接收
  90. /* USER CODE END 2 */
  91. /* Infinite loop */
  92. /* USER CODE BEGIN WHILE */
  93. while (1)
  94. {
  95. /* USER CODE END WHILE */
  96. /* USER CODE BEGIN 3 */
  97. switch(btn)
  98. {
  99. case 1: //按键1使密码的第一位从@-0-9-0
  100. {
  101. if(jm == 0)
  102. {
  103. if(B1 == '@')
  104. B1 = 48; //字符'0'的ASCII值
  105. else
  106. if(++B1>=58)
  107. B1 = 48;
  108. }
  109. btn = 0;
  110. }
  111. break;
  112. case 2: //按键2使密码的第二位从@-0-9-0
  113. {
  114. if(jm == 0)
  115. {
  116. if(B2 == '@')
  117. B2 = 48;
  118. else
  119. if(++B2>=58)
  120. B2 = 48;
  121. }
  122. btn = 0;
  123. }
  124. break;
  125. case 3: //按键3使密码的第三位从@-0-9-0
  126. {
  127. if(jm == 0)
  128. {
  129. if(B3 == '@')
  130. B3 = 48;
  131. else
  132. if(++B3>=58)
  133. B3 = 48;
  134. }
  135. btn = 0;
  136. }
  137. break;
  138. case 4: //按键4,处理密码是否正确
  139. {
  140. if(jm == 0)
  141. {
  142. if(PWD == (B1-48)*100+(B2-48)*10+(B3-48))
  143. {
  144. jm = 1;
  145. LCD_Clear(Black);
  146. __HAL_TIM_SET_AUTORELOAD(&htim2,499);
  147. __HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,50);
  148. L1 = 1;
  149. STA_Flag = 1;
  150. }
  151. else
  152. {
  153. if(++CNT>=3)
  154. {
  155. L2_Flag = 1;
  156. CNT = 0;
  157. }
  158. B1 = '@',B2 = '@',B3 = '@';
  159. }
  160. }
  161. btn = 0;
  162. }
  163. break;
  164. }
  165. if(STA_Flag == 2) //密码正确进入输出状态界面
  166. {
  167. STA_Flag = 0;
  168. jm = 0;
  169. LCD_Clear(Black);
  170. __HAL_TIM_SET_AUTORELOAD(&htim2,999);
  171. __HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,500);
  172. B1 = '@',B2 = '@',B3 = '@';
  173. }
  174. if(jm == 0)
  175. PSD();
  176. else
  177. STA();
  178. LED_Hint(); //LED的处理
  179. UART_RX(); //串口接收处理函数
  180. }
  181. /* USER CODE END 3 */
  182. }
  183. /**
  184. * @brief System Clock Configuration
  185. * @retval None
  186. */
  187. void SystemClock_Config(void)
  188. {
  189. RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  190. RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  191. /** Configure the main internal regulator output voltage
  192. */
  193. HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
  194. /** Initializes the RCC Oscillators according to the specified parameters
  195. * in the RCC_OscInitTypeDef structure.
  196. */
  197. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  198. RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  199. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  200. RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  201. RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV3;
  202. RCC_OscInitStruct.PLL.PLLN = 20;
  203. RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  204. RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  205. RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  206. if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  207. {
  208. Error_Handler();
  209. }
  210. /** Initializes the CPU, AHB and APB buses clocks
  211. */
  212. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  213. |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  214. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  215. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  216. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  217. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  218. if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  219. {
  220. Error_Handler();
  221. }
  222. }
  223. /* USER CODE BEGIN 4 */
  224. /* USER CODE END 4 */
  225. /**
  226. * @brief This function is executed in case of error occurrence.
  227. * @retval None
  228. */
  229. void Error_Handler(void)
  230. {
  231. /* USER CODE BEGIN Error_Handler_Debug */
  232. /* User can add his own implementation to report the HAL error return state */
  233. __disable_irq();
  234. while (1)
  235. {
  236. }
  237. /* USER CODE END Error_Handler_Debug */
  238. }
  239. #ifdef USE_FULL_ASSERT
  240. /**
  241. * @brief Reports the name of the source file and the source line number
  242. * where the assert_param error has occurred.
  243. * @param file: pointer to the source file name
  244. * @param line: assert_param error line source number
  245. * @retval None
  246. */
  247. void assert_failed(uint8_t *file, uint32_t line)
  248. {
  249. /* USER CODE BEGIN 6 */
  250. /* User can add his own implementation to report the file name and line number,
  251. ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  252. /* USER CODE END 6 */
  253. }
  254. #endif /* USE_FULL_ASSERT */

main.h

  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * @file : main.h
  5. * @brief : Header for main.c file.
  6. * This file contains the common defines of the application.
  7. ******************************************************************************
  8. * @attention
  9. *
  10. * Copyright (c) 2023 STMicroelectronics.
  11. * All rights reserved.
  12. *
  13. * This software is licensed under terms that can be found in the LICENSE file
  14. * in the root directory of this software component.
  15. * If no LICENSE file comes with this software, it is provided AS-IS.
  16. *
  17. ******************************************************************************
  18. */
  19. /* USER CODE END Header */
  20. /* Define to prevent recursive inclusion -------------------------------------*/
  21. #ifndef __MAIN_H
  22. #define __MAIN_H
  23. #ifdef __cplusplus
  24. extern "C" {
  25. #endif
  26. /* Includes ------------------------------------------------------------------*/
  27. #include "stm32g4xx_hal.h"
  28. /* Private includes ----------------------------------------------------------*/
  29. /* USER CODE BEGIN Includes */
  30. #include <stdio.h>
  31. #include <stdbool.h>
  32. #include <string.h>
  33. /* USER CODE END Includes */
  34. /* Exported types ------------------------------------------------------------*/
  35. /* USER CODE BEGIN ET */
  36. /* USER CODE END ET */
  37. /* Exported constants --------------------------------------------------------*/
  38. /* USER CODE BEGIN EC */
  39. /* USER CODE END EC */
  40. /* Exported macro ------------------------------------------------------------*/
  41. /* USER CODE BEGIN EM */
  42. /* USER CODE END EM */
  43. /* Exported functions prototypes ---------------------------------------------*/
  44. void Error_Handler(void);
  45. /* USER CODE BEGIN EFP */
  46. /* USER CODE END EFP */
  47. /* Private defines -----------------------------------------------------------*/
  48. /* USER CODE BEGIN Private defines */
  49. #define uchar unsigned char
  50. #define uint unsigned int
  51. /* USER CODE END Private defines */
  52. #ifdef __cplusplus
  53. }
  54. #endif
  55. #endif /* __MAIN_H */

main.h中添加了几个头文件和define。

led.c

  1. #include "led.h"
  2. extern bool L1;
  3. extern bool L2;
  4. void LED_Show(uint16_t value,GPIO_PinState PinState)
  5. {
  6. HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
  7. HAL_GPIO_WritePin(GPIOC,value<<8,PinState);
  8. HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
  9. HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
  10. }
  11. void LED_Hint(void)
  12. {
  13. if(L1 == 1)
  14. LED_Show(0x01, GPIO_PIN_RESET);
  15. else
  16. LED_Show(0xFD, GPIO_PIN_SET);
  17. if(L2 == 1)
  18. LED_Show(0x02, GPIO_PIN_RESET);
  19. else
  20. LED_Show(0xFE, GPIO_PIN_SET);
  21. }

led.h

  1. #ifndef __LED_H
  2. #define __LED_H
  3. #include "main.h"
  4. void LED_Show(uint16_t value,GPIO_PinState PinState);
  5. void LED_Hint(void);
  6. #endif

timer.c

  1. #include "timer.h"
  2. Btn key[4]; //按键的数组,保存每个按键的状态
  3. uchar btn = 0; //返回给主函数是哪个按键按下
  4. char rxarr[8];
  5. uchar arrow = 0;
  6. uint8_t rxdata;
  7. uint STA_CNT = 0;
  8. uint L1_CNT = 0,L2_Flag_CNT = 0;
  9. uchar L2_CNT = 0;
  10. volatile uchar STA_Flag = 0;
  11. extern bool L1,L2,L2_Flag;
  12. void KEY_Scan(void) //按键扫描
  13. {
  14. uchar i=0;
  15. key[0].press = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
  16. key[1].press = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
  17. key[2].press = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
  18. key[3].press = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
  19. for(i=0;i<4;i++)
  20. {
  21. switch(key[i].state)
  22. {
  23. case 0:
  24. if(key[i].press == 0)
  25. key[i].state = 1;
  26. break;
  27. case 1:
  28. if(key[i].press == 0)
  29. {
  30. key[i].state = 2;
  31. btn = i+1;
  32. }
  33. else
  34. key[i].state = 0;
  35. break;
  36. case 2:
  37. if(key[i].press == 1)
  38. key[i].state = 0;
  39. break;
  40. }
  41. }
  42. }
  43. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) //定时器3的中断回调函数
  44. {
  45. if(htim->Instance == TIM3)
  46. {
  47. KEY_Scan();
  48. if(STA_Flag == 1) //状态输出界面计时5秒
  49. {
  50. if(++STA_CNT>=500)
  51. {
  52. STA_Flag = 2;
  53. STA_CNT = 0;
  54. }
  55. }
  56. if(L1 == 1) //LED1计时5秒
  57. {
  58. if(++L1_CNT>=500)
  59. {
  60. L1_CNT = 0;
  61. L1 = 0;
  62. }
  63. }
  64. if(L2_Flag == 1) //LED2闪烁计时5秒
  65. {
  66. if(++L2_CNT>=10)
  67. {
  68. L2 ^= 1;
  69. L2_CNT = 0;
  70. }
  71. if(++L2_Flag_CNT>=500)
  72. {
  73. L2_Flag = 0;
  74. L2_Flag_CNT = 0;
  75. L2 = 0;
  76. }
  77. }
  78. }
  79. }
  80. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) //串口接收中断回调函数
  81. {
  82. if(huart->Instance == USART1)
  83. {
  84. rxarr[arrow++] = rxdata;
  85. HAL_UART_Receive_IT(&huart1, &rxdata, 1);
  86. }
  87. }
  88. void UART_RX(void) //判断串口有没有接收完字符
  89. {
  90. uchar temp;
  91. if(arrow != 0)
  92. {
  93. temp = arrow;
  94. HAL_Delay(1);
  95. if(temp == arrow)
  96. CH_Handle();
  97. }
  98. }

timer.h

  1. #ifndef __TIMER_H
  2. #define __TIMER_H
  3. #include "main.h"
  4. #include "usart.h"
  5. #include "display.h"
  6. typedef struct
  7. {
  8. bool press;
  9. uchar state;
  10. }Btn;
  11. void KEY_Scan(void);
  12. void UART_RX(void);
  13. #endif

display.c

  1. #include "display.h"
  2. extern char text[21];
  3. extern uchar arrow;
  4. extern char rxarr[8];
  5. extern uint PWD;
  6. extern char B1,B2,B3;
  7. void LCD_Print(uchar line, char *text) //重新封装一下LCD显示函数,可以不写
  8. {
  9. LCD_DisplayStringLine((u8)line*24, (u8 *)text);
  10. }
  11. void CH_Handle(void) //串口接收到字符串的处理函数
  12. {
  13. if(arrow>0)
  14. {
  15. if(arrow == 7)
  16. {
  17. uint Old_PWD = 0,New_PWD = 0;
  18. sscanf(rxarr, "%d-%d",&Old_PWD,&New_PWD);
  19. if(Old_PWD == PWD)
  20. PWD = New_PWD;
  21. }
  22. }
  23. arrow = 0;
  24. memset(rxarr,0,8);
  25. }
  26. void PSD(void) //密码显示界面
  27. {
  28. sprintf(text," PSD ");
  29. LCD_Print(0,text);
  30. sprintf(text," B1:%c ",B1);
  31. LCD_Print(3,text);
  32. sprintf(text," B2:%c ",B2);
  33. LCD_Print(4,text);
  34. sprintf(text," B3:%c ",B3);
  35. LCD_Print(5,text);
  36. }
  37. void STA(void) //状态输出界面
  38. {
  39. sprintf(text," STA ");
  40. LCD_Print(0,text);
  41. sprintf(text," F:2000Hz ");
  42. LCD_Print(3,text);
  43. sprintf(text," D:10%% ");
  44. LCD_Print(4,text);
  45. }

display.h

  1. #ifndef __DISPLAY_H
  2. #define __DISPLAY_H
  3. #include "main.h"
  4. #include "LCD.h"
  5. #include "usart.h"
  6. void LCD_Print(uchar line, char *text);
  7. void CH_Handle(void);
  8. void PSD(void);
  9. void STA(void);
  10. #endif

以上就是我修改过的文件和新添加的文件。还有lcd模块,不过不需要我们自己写,官方有提供,直接复制过来就行,注意有三个文件,别只复制lcd.c和lcd.h。

 好了,以上就是蓝桥杯嵌入式第十三届省赛的题目解析了,如果有什么问题和建议都欢迎在评论区提出来喔。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/489325
推荐阅读
相关标签
  

闽ICP备14008679号