蓝桥杯嵌入式第8届真题(完成) STM32G431

2024-03-19 1099阅读

温馨提示:这篇文章已超过375天没有更新,请注意相关的内容是否还可用!

蓝桥杯嵌入式第8届真题(完成) STM32G431

题目

蓝桥杯嵌入式第8届真题(完成) STM32G431

蓝桥杯嵌入式第8届真题(完成) STM32G431

蓝桥杯嵌入式第8届真题(完成) STM32G431

蓝桥杯嵌入式第8届真题(完成) STM32G431

分析和代码

对比第六届和第七届,这届的题目在逻辑思维上确实要麻烦不少,可以从题目看出,这届题目对时间顺序的要求很严格,所以就可以使用状态机的思想来编程,拿到类似题目不要急着写代码,一定要先分析好步骤,想出状态转换的逻辑后,在根据逻辑写代码写起来就很快了。

main.c
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * 

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * 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 "rtc.h" #include "tim.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "key.h" #include "led.h" #include "string.h" #include "stdio.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ extern struct Key key[4];//4个按键 uint8_t lcdtext[30]; //lcd显示的内容 uint8_t status[30]; //lcd显示的内容 uint8_t led;//LED状态 uint8_t setfloor[5]={0,0,0,0,0};//四层楼,为了方便1-4所以数组大小为5 uint32_t key_time_1s; //按键按下后等待的1s uint32_t open_or_close_door_time_4s; //开门或者关门所需时间 uint32_t up_or_down_dir_time_6s; //电梯往上一楼或者往下一楼所需的时间 uint32_t wait_time_2s; //电梯在每层楼等待时间 uint8_t current_floor = 1;//当前所在层 RTC_DateTypeDef D; //用于显示日期 RTC_TimeTypeDef T; //用于显示时间 uint8_t process_status = 0;//执行的状态 uint8_t dir = 2;//是上还是下,默认停止 //下面用于流水灯的部分 uint32_t lastUpdateTime = 0; // 上次更新LED状态的时间 const uint32_t updateInterval = 200; // 更新间隔,以毫秒为单位 uint8_t flow_led_enable = 0; //是否打开流水灯 /* 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 */ void led_process(void); void key_process(void); void lcd_process(void); void status_process(void); /* 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_RTC_Init(); MX_TIM16_Init(); MX_TIM17_Init(); /* USER CODE BEGIN 2 */ HAL_TIM_Base_Start_IT(&htim2); LCD_Init(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ LCD_Clear(Black); LCD_SetBackColor(Black); LCD_SetTextColor(White); LED_display(0x00); sprintf((char *)lcdtext," %d",current_floor); //默认为1楼 LCD_DisplayStringLine(Line3,lcdtext); while (1) { led_process(); lcd_process(); key_process(); status_process(); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* 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_OSCILLATORTYPE_LSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.LSIState = RCC_LSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV2; 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(); } /** Initializes the peripherals clocks */ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC; PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); } } /* USER CODE BEGIN 4 */ void key_process(void) { if((process_status==0||process_status==1))//没有按键按下时,和按键按下1s内还可以继续按 { sprintf((char *)status," wait key "); if(key[0].key_flag&&current_floor!=0+1) //不能是当前楼层 { key[0].key_flag = 0; setfloor[1] = 1;//设置目标楼层 led|=0x01; //设置对应led打开 LED_display(led);//打开对应led process_status = 1;//按键按下后进入1s等待状态 key_time_1s = uwTick; //更新按键按下时时间 } if(key[1].key_flag&&current_floor!=1+1) { key[1].key_flag = 0; setfloor[2] = 1; led|=0x02; LED_display(led); process_status = 1; key_time_1s = uwTick; } if(key[2].key_flag&&current_floor!=2+1) { key[2].key_flag = 0; setfloor[3] = 1; led|=0x04; LED_display(led); process_status = 1; key_time_1s = uwTick; } if(key[3].key_flag&&current_floor!=3+1) { key[3].key_flag = 0; setfloor[4] = 1; led|=0x08; LED_display(led); process_status = 1; key_time_1s = uwTick; } } } void lcd_process(void) { HAL_RTC_GetDate(&hrtc,&D,RTC_FORMAT_BIN); HAL_RTC_GetTime(&hrtc,&T,RTC_FORMAT_BIN); sprintf((char *)lcdtext," FLOOR"); LCD_DisplayStringLine(Line1,lcdtext); // sprintf((char *)lcdtext," %d",current_floor); // LCD_DisplayStringLine(Line3,lcdtext); sprintf((char *)lcdtext," %02d:%02d:%02d",T.Hours,T.Minutes,T.Seconds); LCD_DisplayStringLine(Line4,lcdtext); //LCD_ClearLine(Line7); sprintf((char *)lcdtext,"%s",status); LCD_DisplayStringLine(Line7,lcdtext); sprintf((char *)lcdtext," floors:%d-%d-%d-%d",setfloor[1],setfloor[2],setfloor[3],setfloor[4]); LCD_DisplayStringLine(Line8,lcdtext); } void status_process(void) { if(process_status) { switch(process_status) { case 1: //状态1:等待1s内是否有按键按下 { sprintf((char *)status," wait key 1s "); if((uwTick-key_time_1s)>=1000) //如果1s到了,进入下一个关门状态 { sprintf((char *)status," key_1s_yes "); process_status = 2; } }break; case 2: //状态2:开始关门 { sprintf((char *)status," close door "); HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);//关门 __HAL_TIM_SET_COMPARE(&htim17,TIM_CHANNEL_1,250); //占空比50% HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1); process_status = 3; //进入等待关门状态 open_or_close_door_time_4s = uwTick;//更新关门时间 }break; case 3://状态3:4s关门时间等待,关完门开始判断电梯是上行还是下行 { sprintf((char *)status,"wait close door 4s "); if(uwTick-open_or_close_door_time_4s>=4000) //关门后,开始判断上下行 { sprintf((char *)status,"close door yes "); int up = 0, down = 0; HAL_TIM_PWM_Stop(&htim17,TIM_CHANNEL_1); // 检查上行 for(int i = current_floor + 1; i = 1; i--) { //如果电梯数组中存在比当前楼层低的楼层被设置 if(setfloor[i] == 1) { down = 1; break; } } // 判断方向 if(up && !down) { //只有往上 dir = 1; } else if(down && !up) { //只有往下 dir = 0; } else if(up && down) { //上下都有,先向上 dir = 1; } else { dir = 2; //都没有 } sprintf((char *)status," move "); sprintf((char *)lcdtext," dir:%d--%d",up,down); LCD_DisplayStringLine(Line9,lcdtext); if(dir==1)//上行 { flow_led_enable = 1; HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET); __HAL_TIM_SET_COMPARE(&htim16,TIM_CHANNEL_1,800); //占空比80% HAL_TIM_PWM_Start(&htim16,TIM_CHANNEL_1); up_or_down_dir_time_6s = uwTick;//更新上行时间 process_status = 4; }else if(dir==0)//下行 { flow_led_enable = 1; HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET); __HAL_TIM_SET_COMPARE(&htim16,TIM_CHANNEL_1,600); //占空比80% HAL_TIM_PWM_Start(&htim16,TIM_CHANNEL_1); up_or_down_dir_time_6s = uwTick;//更新上行时间 process_status = 4; }else if(dir==2)//既不需要上行也不需要下行,回到电梯状态 { process_status = 0; } } }break; case 4://状态4:等待6s上下行时间 { sprintf((char *)status," wait move 6s "); if(uwTick-up_or_down_dir_time_6s>=6000) //上下行时间到了 { sprintf((char *)status," move yes "); if(dir==1) //如果是上行 { current_floor+=1; } else{ current_floor-=1; } HAL_TIM_PWM_Stop(&htim16,TIM_CHANNEL_1);// setfloor[current_floor] = 0;//已到达该层 // 显示楼层号并闪烁两次 for(int i = 0; i =4000)//打开门 { sprintf((char *)status," open door yes "); wait_time_2s = uwTick;//更新等待时间 process_status = 6; } }break; case 6 ://状态5:等待开门4s时间到 { sprintf((char *)status," wait 2s "); if(uwTick-wait_time_2s>=2000)//每层停留时间 { sprintf((char *)status," wait 2s yes "); wait_time_2s = uwTick;//更新等待时间 process_status = 2; } }break; } } } void led_process(void) { static uint8_t flow_led_state = 0; // 初始状态为0,表示流水灯未激活 if((uwTick - lastUpdateTime) >= updateInterval && flow_led_enable) { lastUpdateTime = uwTick; // 更新最后一次更新时间 if(flow_led_state == 0) // 如果流水灯未激活,根据方向初始化流水灯状态 { flow_led_state = (dir == 1) ? 0x08 : 0x01; // 从左侧或右侧开始 } else { if(dir == 1) // 上行:从右到左流水 { flow_led_state flow_led_state = 0x01; } } else if(dir == 0) // 下行:从左到右流水 { flow_led_state >= 1; // 向右移动 if(flow_led_state
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]