蓝桥杯嵌入式第十三届省赛题目及详细编程解答

这是第一次发关于嵌入式的题目解答,后续会将其他届的题目和解答一并发出,详见我的博客,总体来说嵌入式的题目不会特别难,现在官方提供了CUBEMX,用这个软件生成一些底层代码,相当好用,但是目前一个明显缺点是用一次软件生成代码后重新编译会比较慢,可能会用两分钟左右,所以为了编译速度快一点,我们可以将代码合理排列在main.c里面,这样不用怕编译后自己的.c和.h文件丢失(当然也可以不用这样,让代码更直观)。废话不多说直接给代码。

蓝桥杯嵌入式第十三届省赛题目及详细编程解答_第1张图片

蓝桥杯嵌入式第十三届省赛题目及详细编程解答_第2张图片
蓝桥杯嵌入式第十三届省赛题目及详细编程解答_第3张图片
蓝桥杯嵌入式第十三届省赛题目及详细编程解答_第4张图片
蓝桥杯嵌入式第十三届省赛题目及详细编程解答_第5张图片
蓝桥杯嵌入式第十三届省赛题目及详细编程解答_第6张图片
蓝桥杯嵌入式第十三届省赛题目及详细编程解答_第7张图片

CUBEMX配置:

蓝桥杯嵌入式第十三届省赛题目及详细编程解答_第8张图片
蓝桥杯嵌入式第十三届省赛题目及详细编程解答_第9张图片
蓝桥杯嵌入式第十三届省赛题目及详细编程解答_第10张图片

串口基本配置:

蓝桥杯嵌入式第十三届省赛题目及详细编程解答_第11张图片

Main.c

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 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 "BSP.H"
#include "lcd.h"
#include "stdio.h"
#include "string.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

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

    void led_display(uchar led);
    void mima_sezhi(void);
    void PWM_PA1(void);
    void lcd_disp(void);
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
    void recive_contr(void);
    
    extern struct keys key[4];
    
    struct key_num
    {
        uchar num;
    
    };
    struct key_num unmber[3]= {'@','@','@'};
    struct key_num chu_shi_unmber[3]= {1,2,3};//初始密码
    bool jie_mian = 0;//默认在密码输入界面,1表示是密码对的界面
    
    uchar string_b1[10],string_b2[10],string_b3[10];
    uchar string_F[12],string_D[12];
    uint puse=50,pre=500;
    extern bool date;
    bool ERR = 0;//报警
    uchar send_string[15];
  uchar string_chushi[4],string_xiugai[4];
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
void led_display(uchar led)
{
    
    HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOC,led<<8,GPIO_PIN_RESET);
    
    HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}


void mima_she_zhi(void)
{
    if(jie_mian ==0)
    {
        for(uchar j= 0;j<3;j++)
        {
            if(key[j].single_flag == 1)
            {
                switch(unmber[j].num)
                {
                    case '@': unmber[j].num = 0;key[j].single_flag =0;break;
                    case 0: unmber[j].num = 1;key[j].single_flag =0;break;
                    case 1: unmber[j].num = 2;key[j].single_flag =0;break;
                    case 2: unmber[j].num = 3;key[j].single_flag =0;break;
                    case 3: unmber[j].num = 4;key[j].single_flag =0;break;
                    case 4: unmber[j].num = 5;key[j].single_flag =0;break;
                    case 5: unmber[j].num = 6;key[j].single_flag =0;break;
                    case 6: unmber[j].num = 7;key[j].single_flag =0;break;
                    case 7: unmber[j].num = 8;key[j].single_flag =0;break;
                    case 8: unmber[j].num = 9;key[j].single_flag =0;break;
                    case 9: unmber[j].num = '@';key[j].single_flag =0;break;
                }
            }
        }
  }
    
    if(key[3].single_flag)
    {
        if(unmber[0].num ==chu_shi_unmber[0].num &&unmber[1].num ==chu_shi_unmber[1].num &&unmber[2].num ==chu_shi_unmber[2].num )
        {
            jie_mian = 1;
            
        }
        else//密码不对
        {
            unmber[0].num = '@';
            unmber[1].num = '@';
            unmber[2].num = '@';
            
            
        ERR = 1;
            
        }
        key[3].single_flag = 0;
    }
    
}


void PWM_PA1(void)
{
    if(jie_mian == 1)
    {
        
        TIM2->ARR = pre-1;
        TIM2->CCR2 = puse;
    }
    
}



void bian_hui(void)
    {
        if(date==1)
        {
            unmber[0].num = '@';
            unmber[1].num = '@';
            unmber[2].num = '@';
            
             date= 0;
        }
    }
    








void lcd_disp(void)
{
    if(jie_mian == 0)
    {
        LCD_DisplayStringLine(Line2,"      P S D         ");
        
        if(unmber[0].num!='@')
        {
            sprintf((char *)string_b1,"    B1:%u     ",unmber[0].num);
            LCD_DisplayStringLine(Line4,string_b1);
        }
        else if(unmber[0].num=='@')
            LCD_DisplayStringLine(Line4,"    B1:@     ");
        
        if(unmber[1].num!='@')
        {
        sprintf((char *)string_b2,"    B2:%u     ",unmber[1].num);
        LCD_DisplayStringLine(Line5,string_b2);
        }
        else if(unmber[1].num=='@')
          LCD_DisplayStringLine(Line5,"    B2:@     ");
        
        
        if(unmber[2].num!='@')
        {
        sprintf((char *)string_b3,"    B3:%u     ",unmber[2].num);
        LCD_DisplayStringLine(Line6,string_b3);
        }
        else if(unmber[2].num=='@')
            LCD_DisplayStringLine(Line6,"    B3:@     ");
    }
    else if(jie_mian == 1)
    {
        
        LCD_ClearLine(Line6);
        LCD_DisplayStringLine(Line2,"        S T A        ");
        
        sprintf((char *)string_F," F :%uHZ     ",(80000000/(TIM2->PSC+1))/(TIM2->ARR+1));
        LCD_DisplayStringLine(Line4,string_F);
        
        sprintf((char *)string_D," D :%u%%        ",((TIM2->CCR2+1)*100)/(TIM2->ARR+1));
        LCD_DisplayStringLine(Line5,string_D);
        
        
    }
}


uchar recive_char;
uchar recive_string[20];
uint recive_num=0;

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    
    recive_string[recive_num++] = recive_char;
    HAL_UART_Receive_IT(&huart1,& recive_char,1);
    HAL_UART_Transmit(&huart1,& recive_char,1,50);
}


uchar jfal[3];
void recive_contr(void)
{
    
    if(recive_num>0)
    {
        if(recive_num == 7)
        {
            
            sscanf((char *)recive_string,"%3s:%3s",string_chushi,string_xiugai);
            
            if((string_chushi[0]-48==chu_shi_unmber[0].num) && (string_chushi[1]-48==chu_shi_unmber[1].num) && (string_chushi[2]-48==chu_shi_unmber[2].num))
            {
                chu_shi_unmber[0].num = string_xiugai[0]-48;
                chu_shi_unmber[1].num = string_xiugai[1]-48;
                chu_shi_unmber[2].num = string_xiugai[2]-48;
            }
            else
            {
                sprintf((char *)send_string,"mimaerron\n\r");
                HAL_UART_Transmit(&huart1,send_string,strlen(send_string),50);
            }
        }
        else
        {
            sprintf((char *)send_string,"erron\n\r");
            HAL_UART_Transmit(&huart1,send_string,strlen(send_string),50);
        }
          recive_num = 0;
          memset(recive_string,0,20);
  }
    
    
    //sprintf((char *)jfal,"%u",string_chushi[0]-48);
    //LCD_DisplayStringLine(Line7,jfal);
}

/* 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_TIM2_Init();
  MX_TIM3_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
    LCD_Init();
    LCD_Clear(Black);
    LCD_SetBackColor(Black);
    LCD_SetTextColor(White);
    
        HAL_TIM_Base_Start_IT(&htim3);
        HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
      HAL_UART_Receive_IT(&huart1,&recive_char,1);//开启接收中断
        
      led_display(0X00);
        
        sprintf((char *)send_string,"adsha\n\r");
        HAL_UART_Transmit(&huart1,send_string,strlen(send_string),50);
        
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
        
        
        
        
        mima_she_zhi();
         PWM_PA1();
        lcd_disp();
         bian_hui();
        
         recive_contr();
    /* 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};

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

BSP.H

#ifndef _BSP_H_
#define _BSP_H_

#include "main.h"
#include "stdbool.h"



struct keys
{
    uchar judge_sta;  //用于状态切换,和消抖
    bool key_sta;  //用于检测是否按下
    bool single_flag;//按下标志位
    bool long_flag;//长按下标志位
    uint key_time;
};



void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
    
#endif


BSP.C

#include "BSP.H"
#include "lcd.h"
#include "usart.h"


extern void led_display(uchar led);
extern uchar jie_mian;
uint time = 0;
struct keys key[4] = {0,0,0,0,0};
bool date = 0;
uint shan =0;
extern bool ERR;
//extern  struct key_num unmber[3];


void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM3)
    {
        key[0].key_sta = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0); //读取端口值
        key[1].key_sta = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
        key[2].key_sta = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
        key[3].key_sta = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
        
        
        for(int i= 0;i<4;i++)
        {
            switch(key[i].judge_sta)
            {
                case 0:
                
                                if(key[i].key_sta == 0)
                                {
                                    key[i].judge_sta = 1;
                                    
                                }
                            break;
                case 1:
                
                                if(key[i].key_sta == 0)
                                {
                                    key[i].judge_sta = 2;
                                    
                                }
                            break;
                case 2:
                
                                if(key[i].key_sta == 1)
                                {
                                    key[i].judge_sta = 0;
                                    if(key[i].key_time>80)
                                    {
                                        key[i].long_flag = 1;
                                    }
                                    else 
                                    {
                                        key[i].single_flag = 1;
                                    }
                                    key[i].key_time = 0;
                                
                                }
                                else
                                {
                                    key[i].key_time++;
                                }
                                
                            break;
            }
        }
    }
    
    
    
    if(jie_mian == 1)
    {
      time++;
        led_display(0X01);
        if(time>=500)
        {
            jie_mian = 0;
            time = 0;
            TIM2->ARR = 1000-1;
            TIM2->CCR2 = 500;
            
            date = 1;
            
            led_display(0X00);
        }
    }

    
    
        if(ERR ==1)
        {
            shan++;
            if(shan%10)
            {
                led_display(0X02);
            }
            else 
                led_display(0X00);
            
            if(shan == 500)
            {
                shan = 0;
                ERR = 0;
            }
        }
    
}

你可能感兴趣的:(蓝桥杯,stm32,mcu)