第九届蓝桥杯嵌入式省赛程序设计题(HAL库版)

蓝桥杯嵌入式(HAL库版)省赛系列文章

第六届蓝桥杯嵌入式省赛程序设计题(HAL库版)
第十届蓝桥杯嵌入式省赛程序设计题(HAL库版)
第十一届蓝桥杯嵌入式省赛程序设计题(HAL库版)
第十三届蓝桥杯嵌入式省赛程序设计题(HAL库版)


前言

报名参加蓝桥杯嵌入式组别,通过做往年省赛例题的方式进行能力整体提升,需要的小伙伴可以简单看一下哈,写的不好,还请大家多多包涵,欢迎大佬指出问题!
需要其他届文章的朋友可以从顶部的链接直达喔!
闲话少说,进入正题!

一、赛题要求

1. 硬件框图

通过按键设置定时时间,启动定时器后,开始倒计时;计时过程中,可以暂停、取消定时器。在定时时间内,按要求输出PWM 信号和控制LED 指示灯。系统框图如图1所示:

2. 功能描述

2.1 LCD显示

LCD 显示存储位置、定时时间和当前状态。系统预留5个存储位置用于存储常用的定时时间。当定时器停止时,当前状态为Standby;当系统正在设置时间时,当前状态为Setting;当定时器运行时,当前状态为Running,定时器暂停时,当前状态为Pause。

2.2 按键功能

系统使用4个按键,B1、B2、B3 和B4。

按键B1为存储位置切换键。每按一次,存储位置依次以1、2、3、4、5循环切换,切换后定时时间设定为当前位置存储的时间。

按键B2为时间位置(时、分、秒)切换键和存储键。短按B2键进入时间设置状态。每次短按B2键,设置位置以时、分、秒循环切换,并突出显示(高亮)当前位置;设置完后,长按B2 键(超过0.8 秒)把设置的时间存储到当前的存储位置,并退出设置状态。如果是临时设置定时时间,则不需存储,直接按定时器启动按键。

按键B3为时、分、秒(按键B2确定当前位置)数字增加键。每短按B3一次,数字递增一次;按住B3超过0.8 秒,则数字快速递增,直到松开B3按键。数字递增时,超出范围则从头循环。

按键B4为定时器启动键。短按B4,定时器启动,开始运行;运行期间短按B4,暂停定时器,再短按B4,恢复定时器运行;长按B4(超过0.8 秒),则取消定时器运行,回到Standby状态。

2.3 PWM 输出和LED 显示

定时器运行时,PA6口输出PWM信号,同时LED灯(LD1)以0.5秒的频率闪烁。PWM 信号频率为1KHz,占空比为80%。
定时器停止或暂停时,停止输入PWM 信号,LED 灯灭。

2.4 定时时间存储

设定好的定时时间存储在EEPROM中。
掉电重启后,显示存储位置1的定时时间。

根据上述任务要求,使用STM32CubeMX生成Keil文件进行程序编写。

二、配置工程

1. 配置流程

使用STM32CubeMX的流程可以概括为四个步骤,分别为:选择芯片、配置引脚、配置时钟、建立工程

1.1 选择芯片

选择蓝桥杯赛事指定使用的STM32G431RBTx型号芯片

1.2 配置引脚

1.2.1 LED灯

PC8-PC15控制,低电平点亮,由PD2引脚控制锁存,低电平变为高电平开锁,高电平变为低电平上锁,设置引脚模式为输出模式。

1.2.2 按键

开发板上共配备了4个按键,分别连接在PB0,PB1,PB2,PA0引脚上,设置引脚模式为输入模式。

1.2.3 PWM输出

根据项目要求,选择PA6端口输出PWM信号,PA6对应TIM3_CH1

1.2.4 IIC读写EEPROM

在过去的蓝桥杯比赛中,IIC总线使用的是引脚PB6和PB7,总线上挂接了两个设备,分别是存储芯片24C02和可编程电阻MCP4017。
在STM32CubeMX按照下图方式配置I2C1。

1.3 配置时钟

时钟配置选择将HCLK一栏设置为最大值80MHz,同时选择HSE外部时钟,自动进行参数配置

1.4 创建工程

注意事项:
1.将Toolchain/IDE更改为MDK-ARM
2.选择将必要的库文件粘贴过来,可以减小工程建立的大小

三、软件实现

直接放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 "lcd.h"
#include "i2c - hal.h"
#include "stdio.h"
#include "string.h"

/* Private includes ----------------------------------------------------------*/

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/
#define Pressed			1
#define UnPressed		0
#define Long_Pressed	8

#define Key_Long_OK		2
#define KEY_Short_OK	3
#define KEY_Error		4
/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1;

TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim3;
TIM_HandleTypeDef htim4;

char LCD_TEXT[30];

uint8_t data;
uint8_t Position = 1;
uint8_t KEY_FLAG = 0;
uint8_t LED_TIME = 0;
uint8_t State = 0;
uint8_t Hours = 0;
uint8_t Minutes = 0;
uint8_t Seconds = 0;
uint8_t KEYB2_FLAG = 0;
uint8_t KEYB4_FLAG = 0;
uint8_t KEYB4_FLAGS = 0;
uint8_t temp = 0;

uint16_t KEY_TIME = 0;
uint16_t TIMES = 0;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MX_TIM3_Init(void);
static void MX_TIM2_Init(void);
static void MX_TIM4_Init(void);

void EXTI0_IRQHandler(void);
void LED_Flash(void);
void LED_OFF(void);
void I2C_Write_AT24C02(uint8_t add, uint8_t data);
void State_Selection(void);
void Time_Saved(void);
void Time_Read(void);
void KEYB2(void);
void KEYB4(void);

uint8_t I2C_Read_AT24C02(uint8_t add);
uint8_t Key_Scan(GPIO_TypeDef *GPIOx, uint16_t GPIO_PIN);
/* Private user code ---------------------------------------------------------*/

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* Configure the system clock */
  SystemClock_Config();
  /* Initialize all configured peripherals */
  MX_GPIO_Init();

  MX_I2C1_Init();
  MX_TIM3_Init();
  MX_TIM2_Init();
  MX_TIM4_Init();
	
	LCD_Init();
	LCD_Clear(White);
	LCD_SetBackColor(Black);
	
	HAL_TIM_Base_Start_IT(&htim2);
	
	I2CInit();
	Time_Read();
	LED_OFF();

  /* Infinite loop */
  while (1)
  {
		LCD_SetTextColor(Green);
		
		sprintf(LCD_TEXT,"		NO%2d	",Position);
		LCD_DisplayStringLine(Line1,(uint8_t*)LCD_TEXT);
		
		KEYB2();
		
		Hours = TIMES /3600;
		Minutes = TIMES %3600 / 60;
		Seconds = TIMES %3600 % 60;
		
		if(State != 1)
		{
			KEYB4();
			
			LCD_SetTextColor(Green);
			LCD_DisplayChar(Line5,210,Hours/10 + 0x30);
			LCD_DisplayChar(Line5,195,Hours%10 + 0x30);
			LCD_DisplayChar(Line5,180,':');
			LCD_DisplayChar(Line5,165,Minutes/10 + 0x30);
			LCD_DisplayChar(Line5,150,Minutes%10 + 0x30);
			LCD_DisplayChar(Line5,135,':');
			LCD_DisplayChar(Line5,120,Seconds/10 + 0x30);
			LCD_DisplayChar(Line5,105,Seconds%10 + 0x30);
		}
		
		State_Selection();
		LED_Flash();
  }
}

/**
  * @brief  Key B2 function
  * @retval None
  */
void KEYB2(void)
{
		if(Key_Scan(KEYB2_GPIO_Port,KEYB2_Pin) == KEY_Short_OK)
		{
			KEYB2_FLAG ++;
			if(KEYB2_FLAG > 4)
				KEYB2_FLAG = 0;
		}
		
		//Enter setting state
		if(KEYB2_FLAG == 1)
			State = 1;
		
		//Hours Selected
		if(KEYB2_FLAG == 2)
		{
			LCD_SetTextColor(Red);
			if(Key_Scan(KEYB3_GPIO_Port,KEYB3_Pin) == KEY_Short_OK)
				Hours ++;
			if(Key_Scan(KEYB3_GPIO_Port,KEYB3_Pin) == Key_Long_OK)
				Hours += 5;
		}
		else
			LCD_SetTextColor(Green);
		LCD_DisplayChar(Line5,210, Hours/10 +0x30);
		LCD_DisplayChar(Line5,195, Hours%10 +0x30);
		
		//Minutes Selected
		if(KEYB2_FLAG == 3)
		{
			LCD_SetTextColor(Red);
			if(Key_Scan(KEYB3_GPIO_Port,KEYB3_Pin) == KEY_Short_OK)
				Minutes ++;
			if(Key_Scan(KEYB3_GPIO_Port,KEYB3_Pin) == Key_Long_OK)
				Minutes += 5;
		}
		else
			LCD_SetTextColor(Green);
		LCD_DisplayChar(Line5,165, Minutes/10 + 0x30);
		LCD_DisplayChar(Line5,150, Minutes%10 + 0x30);
		
		//Seconds Selected
		if(KEYB2_FLAG == 4)
		{
			if(Key_Scan(KEYB3_GPIO_Port,KEYB3_Pin) == KEY_Short_OK)
				Seconds ++;
			if(Key_Scan(KEYB3_GPIO_Port,KEYB3_Pin) == Key_Long_OK)
				Seconds += 5;
		}
		else
			LCD_SetTextColor(Green);
		LCD_DisplayChar(Line5,120, Seconds/10 + 0x30);
		LCD_DisplayChar(Line5,105, Seconds%10 + 0x30);
		LCD_SetTextColor(Green);
		
		//Long Pressed -> data saved
		if(Key_Scan(KEYB2_GPIO_Port,KEYB2_Pin) == Key_Long_OK)
		{
			Time_Saved();
			State = 0;
		}
		
		if(Seconds > 60)
			Seconds = 0;
		if(Minutes > 60)
			Minutes = 0;
		if(Hours > 4)
		{
			TIMES = 0;
			Seconds = 0;
			Minutes = 0;
		}
		if(State == 1)
			TIMES = 3600*Hours + 60*Minutes + Seconds;
}

/**
  * @brief  Key B4 function
  * @retval None
  */
void KEYB4(void)
{
	if(Key_Scan(KEYB4_GPIO_Port,KEYB4_Pin) == KEY_Short_OK)
		KEYB4_FLAG = !KEYB4_FLAG;
	
	if(Key_Scan(KEYB4_GPIO_Port,KEYB4_Pin) == Key_Long_OK)
	{
		HAL_TIM_Base_Stop_IT(&htim4);
		HAL_TIM_PWM_Stop_IT(&htim3,TIM_CHANNEL_1);
		LED_OFF();
		
		KEYB4_FLAGS = 1;
		State = 0;
	}
	if(KEYB4_FLAG != temp)
	{
		if(KEYB4_FLAG == 1)
		{
			HAL_TIM_Base_Start_IT(&htim4);
			HAL_TIM_PWM_Start_IT(&htim3,TIM_CHANNEL_1);
			
			State = 2;
			KEYB4_FLAGS = 0;
		}
		if(KEYB4_FLAG == 0 && KEYB4_FLAGS == 0)
		{
			HAL_TIM_Base_Stop_IT(&htim4);
			HAL_TIM_PWM_Stop_IT(&htim3,TIM_CHANNEL_1);
			LED_OFF();
			
			State = 3;
		}
	}
	temp = KEYB4_FLAG;
}
	
/**
  * @brief  LED OFF
  * @retval None
  */
void LED_OFF(void)
{
	HAL_GPIO_WritePin(LED1_GPIO_Port,GPIO_PIN_All,GPIO_PIN_SET);
	HAL_GPIO_WritePin(LEDControl_GPIO_Port,LEDControl_Pin,GPIO_PIN_SET);
	HAL_GPIO_WritePin(LEDControl_GPIO_Port,LEDControl_Pin,GPIO_PIN_RESET);
}

/**
  * @brief  LED1 Flash
  * @retval None
  */
void LED_Flash(void)
{
	if(State == 2)
	{
		if(LED_TIME <= 5)
		{
			HAL_GPIO_WritePin(LED1_GPIO_Port,GPIO_PIN_All,GPIO_PIN_SET);
			HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET);
			HAL_GPIO_WritePin(LEDControl_GPIO_Port,LEDControl_Pin,GPIO_PIN_SET);
			HAL_GPIO_WritePin(LEDControl_GPIO_Port,LEDControl_Pin,GPIO_PIN_RESET);
		}
		if(LED_TIME >=5)
		{
			HAL_GPIO_WritePin(LED1_GPIO_Port,GPIO_PIN_All,GPIO_PIN_SET);
			HAL_GPIO_WritePin(LEDControl_GPIO_Port,LEDControl_Pin,GPIO_PIN_SET);
			HAL_GPIO_WritePin(LEDControl_GPIO_Port,LEDControl_Pin,GPIO_PIN_RESET);
		}
		if(LED_TIME >= 10)
			LED_TIME = 0;
	}
}

/**
  * @brief	State selection
  * @retval None
  */
void State_Selection(void)
{
	if(State == 0)
		LCD_DisplayStringLine(Line8,(uint8_t *)"       Standby      ");
	if(State == 1)
		LCD_DisplayStringLine(Line8,(uint8_t *)"       Setting      ");
	if(State == 2)
		LCD_DisplayStringLine(Line8,(uint8_t *)"       Running      ");
	if(State == 3)
		LCD_DisplayStringLine(Line8,(uint8_t *)"        Pause       ");
	
}

/**
  * @brief  Key scanning.
	*					Pressed means 1.
	*					UnPressed means 0.
  * @retval uint8_t
	*					Key_Long_OK means	2.
	*					KEY_Short_OK means 3.
	*					KEY_Error means 4.
  */
uint8_t Key_Scan(GPIO_TypeDef *GPIOx,uint16_t GPIO_PIN)
{
	if(HAL_GPIO_ReadPin(GPIOx,GPIO_PIN) == RESET)
	{
		KEY_TIME = 0;
		while(HAL_GPIO_ReadPin(GPIOx,GPIO_PIN) == RESET);
		KEY_FLAG = Pressed;
	}
	
	if(KEY_FLAG == Pressed && KEY_TIME <= Long_Pressed)
	{
		KEY_FLAG = UnPressed;
		return KEY_Short_OK;
	}
	if(KEY_FLAG == Pressed && KEY_TIME > Long_Pressed)
	{
		KEY_FLAG = UnPressed;
		return Key_Long_OK;
	}
	
	return KEY_Error;
}

/**
  * @brief  Read time from EEPROM.
  * @retval None
  */
void Time_Read(void)
{
	Hours = I2C_Read_AT24C02(10 + 0x01);
	HAL_Delay(5);
	Minutes = I2C_Read_AT24C02(10 + 0x02);
	HAL_Delay(5);
	Seconds = I2C_Read_AT24C02(10 + 0x03);
	HAL_Delay(5);
	
	TIMES = 3600*Hours + 60*Minutes + Seconds;
}

/**
  * @brief  Save time to EEPROM.
  * @retval None
  */
void Time_Saved(void)
{
	I2C_Write_AT24C02(Position*10 + 0x01, Hours);
	HAL_Delay(5);
	I2C_Write_AT24C02(Position*10 + 0x02, Minutes);
	HAL_Delay(5);
	I2C_Write_AT24C02(Position*10 + 0x03, Seconds);
	HAL_Delay(5);
}

/**
  * @brief  I2C Read Data to EEPROM
  * @retval unsigned char data
  */
uint8_t I2C_Read_AT24C02(uint8_t add)
{
	I2CStart();
	I2CSendByte(0xA0);
	I2CWaitAck();
	
	I2CSendByte(add);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0xA1);
	I2CWaitAck();
	
	data = I2CReceiveByte();
	I2CWaitAck();
	I2CStop();
	
	return data;	
}
/**
  * @brief  I2C Write Data to EEPROM
  * @retval none
  */
void I2C_Write_AT24C02(uint8_t add, uint8_t data)
{
	I2CStart();
	I2CSendByte(0xA0);
	I2CWaitAck();
	
	I2CSendByte(add);
	I2CWaitAck();
	
	I2CSendByte(data);
	I2CWaitAck();
	
	I2CStop();
}

/**
  * @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_DIV1;
  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();
  }
}

/**
  * @brief I2C1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_I2C1_Init(void)
{

  /* USER CODE BEGIN I2C1_Init 0 */

  /* USER CODE END I2C1_Init 0 */

  /* USER CODE BEGIN I2C1_Init 1 */

  /* USER CODE END I2C1_Init 1 */
  hi2c1.Instance = I2C1;
  hi2c1.Init.Timing = 0x10909CEC;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Analogue filter
  */
  if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Digital filter
  */
  if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I2C1_Init 2 */

  /* USER CODE END I2C1_Init 2 */

}

/**
  * @brief TIM2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM2_Init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 80-1;										//80MHz /80 = 1MHz
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 999;												//1MHz / 1000 = 1kHz
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
    Error_Handler();
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
    Error_Handler();
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
    Error_Handler();
}

/**
  * @brief TIM3 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM3_Init(void)
{
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};

  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 80-1;										//80MHz /80 = 1MHz
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 999;												//1MHz / 1000 = 1kHz
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
    Error_Handler();
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
    Error_Handler();
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 800;													// Duty = 80%
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
    Error_Handler();
  HAL_TIM_MspPostInit(&htim3);

}

/**
  * @brief TIM4 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM4_Init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  htim4.Instance = TIM4;
  htim4.Init.Prescaler = 80-1;										//80MHz / 80 = 1MHz
  htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim4.Init.Period = 999;												//1MHz / 1000 = 1kHz
  htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
    Error_Handler();
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
    Error_Handler();
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
    Error_Handler();
}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, LED6_Pin|LED7_Pin|LED8_Pin|LED1_Pin
                          |LED2_Pin|LED3_Pin|LED4_Pin|LED5_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LEDControl_GPIO_Port, LEDControl_Pin, GPIO_PIN_SET);

  /*Configure GPIO pins : LED6_Pin LED7_Pin LED8_Pin LED1_Pin
                           LED2_Pin LED3_Pin LED4_Pin LED5_Pin */
  GPIO_InitStruct.Pin = LED6_Pin|LED7_Pin|LED8_Pin|LED1_Pin
                          |LED2_Pin|LED3_Pin|LED4_Pin|LED5_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pin : KEYB4_Pin */
  GPIO_InitStruct.Pin = KEYB4_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(KEYB4_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pins : KEYB2_Pin KEYB3_Pin */
  GPIO_InitStruct.Pin = KEYB2_Pin|KEYB3_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
	
	/*Configure GPIO pins : KEYB2_Pin KEYB3_Pin */
	GPIO_InitStruct.Pin = KEYB1_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /*Configure GPIO pin : LEDControl_Pin */
  GPIO_InitStruct.Pin = LEDControl_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LEDControl_GPIO_Port, &GPIO_InitStruct);
	
	/* EXTI interrupt init */
	HAL_NVIC_SetPriority(EXTI0_IRQn,8,0);
	HAL_NVIC_EnableIRQ(EXTI0_IRQn);

}

/**
  * @brief  EXTI0 Handler.
  * @retval None
  */
void EXTI0_IRQHandler(void)
{
	if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_0) != RESET)
	{
		Position ++;
		if(Position > 5)
		{
			Position = 1;
		}
		HAL_Delay(5);
		
		__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0);
	}
}


void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	static uint16_t TIM2_Cnt = 0;
	static uint16_t TIM4_Cnt = 0;
	
	if(htim ->Instance == TIM2)
			TIM2_Cnt++;
	
	if(TIM2_Cnt >= 100)
	{
		TIM2_Cnt = 0;
		
		KEY_TIME ++;
		LED_TIME ++;
	}
	
	if(htim ->Instance == TIM4)
		TIM4_Cnt++;
	if(TIM4_Cnt >= 1000)
	{
		TIM4_Cnt =0;
		
		TIMES ++;
	}
	
}
/**
  * @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 */


总结

本次省赛使用到了IIC对EEPROM进行读写操作,且用到较多定时器进行时间校准,中断配置较为复杂,笔者能力有限,仅能完成以上部分,如果有哪里写的不好欢迎各路大佬指点一下!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DayDayUp..

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值