蓝桥杯嵌入式STM32G431——第九届省赛真题电子定时器

第九届省赛真题

在这里插入图片描述
在这里插入图片描述

主函数代码(不包含各模块初始化代码)

#include "main.h"
#include "rcc.h"
#include "led_key.h"
#include "lcd.h"
#include "tim.h"
#include "i2c.h"

//***通过滴答定时器实现执行速度控制变量
__IO uint32_t uwTick_LED_Speed_Ctrl;
__IO uint32_t uwTick_KEY_Speed_Ctrl;
__IO uint32_t uwTick_LCD_Speed_Ctrl;
__IO uint32_t uwTick_KEY_Time_Count;
__IO uint32_t uwTick_Time_Count_down_Crtl;
__IO uint32_t uwTick_LED_BuLingBuLing_Crtl;

//***全局变量区
uint8_t ucLED; //控制LED的变量
//*按键三行代码变量
uint8_t key_value,key_up,key_down;
static uint8_t key_old;

uint8_t LCD_String_Disp[21];

uint8_t Status_Selection = 0; //状态选择变量 默认为0
uint8_t Storage_Location = 1; //存储位置 1-2-3-4-5-1 默认为1

uint8_t Time_Set[3]; //时间设置

__IO uint32_t Time_Count_down_temp; //开始计时时用于存储总秒数的变量

//*子函数声明区
void SystemClock_Config(void);
void LED_Proc(void);
void KEY_Proc(void);
void LCD_Proc(void);
void KEY_B3_Proc(void);



//***主函数区
int main(void)
{
  HAL_Init();

  SystemClock_Config();

	//*初始化函数区
	LED_KEY_Init();
	
	LCD_Init();
	LCD_Clear(Black);
	LCD_SetBackColor(Black);
	LCD_SetTextColor(Magenta);
	
	TIM3_Init();
	//HAL_TIM_PWM_Start(&htim3 , TIM_CHANNEL_1);
	I2CInit();
	
	//*掉电重启后 显示存储位置1的定时时间
	I2C_24c02_read(Time_Set , 0 , 3);	//将默认为存储位置1的数据读入Time_Set
	
  while (1)
  {
    LED_Proc();
		KEY_Proc();
		LCD_Proc();
  }

}

//***子函数区

//*LED处理子函数
void LED_Proc(void)
{
	if((uwTick - uwTick_LED_Speed_Ctrl)<100) return;
		uwTick_LED_Speed_Ctrl = uwTick;	//控制子函数执行速度为100ms
	
	
	LED_Disp(ucLED);
	
}

//*按键B3处理
void KEY_B3_Proc(void)
{
	if(Status_Selection == 1) //高亮小时状态
	{
		Time_Set[0]+=1;  //小时+1
		if(Time_Set[0] == 24)
			Time_Set[0] = 0;
	}
	
	else if(Status_Selection == 2) //高亮分钟状态
	{
		Time_Set[1]+=1;  //分钟+1
		if(Time_Set[1] == 60)
			Time_Set[1] = 0;
	}
	
	else if(Status_Selection == 3) //高亮秒状态
	{
		Time_Set[2]+=1;  //秒+1
		if(Time_Set[2] == 60)
			Time_Set[2] = 0;
	}
	
	
}

//*KEY处理子函数
void KEY_Proc(void)
{
	if((uwTick - uwTick_KEY_Speed_Ctrl)<50) return;
		uwTick_KEY_Speed_Ctrl = uwTick;	//控制子函数执行速度为50ms	
	
	key_value = KEY_Scan();
	key_down = key_value & (key_value ^ key_old);
	
	key_up = ~key_value & (key_value ^ key_old);
	key_old = key_value;
	
	if(key_down)
	{
		uwTick_KEY_Time_Count = uwTick;
	}
	
	if((uwTick - uwTick_KEY_Time_Count) < 800) //短按
	{
		switch(key_up)
		{
			case 1:	//B1按下 切换存储位置 
				if(Status_Selection == 0)
				{
					if( ++Storage_Location == 6)
						Storage_Location = 1;
					I2C_24c02_read(Time_Set, 3*(Storage_Location-1) ,3); //将对应存储位置的值从EEPROM中读出
				}
				
				break;
			
			case 2:	//B2短按 来回切换时分秒的高亮位置
					if( ++Status_Selection == 4)
						Status_Selection = 1;
				
				break;
				
			case 3:	//B3短按 对应选中的高亮时间+1
					KEY_B3_Proc();
				break;
				
			case 4:	//B4短按 在除Running状态下的任何状态下按下着切换到Running状态 在Running状态下按下则切换至Pause状态
				if(Status_Selection != 4)
				{
					Status_Selection = 4;
					HAL_TIM_PWM_Start(&htim3 , TIM_CHANNEL_1); //定时器开启 PA6口输出PWM信号
				}
				else 
				{
					Status_Selection = 5;
					HAL_TIM_PWM_Stop(&htim3 , TIM_CHANNEL_1); //定时器暂停 停止输出PWM信号
					ucLED = 0x00; //关闭LED
				}
				uwTick_Time_Count_down_Crtl = uwTick; //在B4按下后便开始计时 
				Time_Count_down_temp = Time_Set[0]*3600 + Time_Set[1]*60 + Time_Set[2]; //计时时间的总秒数

				break;
		}
		
		
	}
	else //长按
	{
		switch(key_value)
		{
			
			case 2:	//长按B2 状态选择从时间Seeting界面进入Standby界面 并存储设置的时间
				if(Status_Selection == 1||Status_Selection == 2||Status_Selection == 3)
				{
					Status_Selection = 0; //切换到状态0-Standby界面
					
					//将设置状态的时间写入EEPROM对应的存储位置中 显示在Standby状态的相应存储位置
					I2C_24c02_write(Time_Set, 3*(Storage_Location-1) ,3);						
				}

			
				break;
			
			
			case 3: //B3长按 对应选中的高亮时间持续+1
				KEY_B3_Proc();		
				break;
			
			case 4:	//短按B4 退出Running界面 进入Standby界面
				Status_Selection = 0;
			
				//将EEPROM存储在对应位置的定时时间读入Time_Set
				I2C_24c02_read(Time_Set, 3*(Storage_Location-1) ,3); 
			
				HAL_TIM_PWM_Stop(&htim3 , TIM_CHANNEL_1); //定时器关闭 停止输出PWM信号
				ucLED = 0x00; //关闭LED
				break;
			
		}

	}
}


void LCD_Proc(void)
{
	if((uwTick - uwTick_LCD_Speed_Ctrl)<100) return;
		uwTick_LCD_Speed_Ctrl = uwTick;	//控制子函数执行速度为100ms	
	
	memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
	sprintf((char*)LCD_String_Disp , "   No %1d       ",Storage_Location);
	LCD_DisplayStringLine(Line0 , LCD_String_Disp);

	//***只在状态4-Running界面和状态5-Pause界面有效
	if(Status_Selection == 4 || Status_Selection==5)	
	{
		if((uwTick - uwTick_Time_Count_down_Crtl)>=1000)
		{
			uwTick_Time_Count_down_Crtl = uwTick;	//每秒执行一次
			if(Status_Selection == 4) //在状态4-定时器Running状态下 开始倒计时
				Time_Count_down_temp -= 1; //时间减少1s
		}
		//*开启倒计时后以秒为单位变化的时间
		Time_Set[0] = Time_Count_down_temp/3600;			//小时
		Time_Set[1] = Time_Count_down_temp%3600/60;		//分钟
		Time_Set[2] = Time_Count_down_temp%3600%60;		//秒
	}
	
	//***只在状态4定时器开启 Running界面有效
	if(Status_Selection ==4)
	{
		if((uwTick - uwTick_LED_BuLingBuLing_Crtl)>=500)	//定时器开启 LED以0.5s频率闪烁
		{
			uwTick_LED_BuLingBuLing_Crtl = uwTick;		
			ucLED ^=0x01;
		}
	}
	
	
	//void LCD_DisplayChar(u8 Line, u16 Column, u8 Ascii);	//LCD字符显示函数
	//第一个参数代表行 
	//第二个参数代表列第i列的公式为320-(16*i),则代表是i列 
	//第三个参数为需要显示的Ascii码值 数字需要+0x30 字符' '
	
	//***时间显示处理(包含高亮处理)
	if(Status_Selection == 1) LCD_SetBackColor(Blue); //状态1-Seeting状态 高亮显示小时
	LCD_DisplayChar(Line4 , (320 - (16 * 6)) , Time_Set[0]/10 + 0x30);
	LCD_DisplayChar(Line4 , (320 - (16 * 7)) , Time_Set[0]%10 + 0x30);
	LCD_SetBackColor(Black);
	LCD_DisplayChar(Line4 , (320 - (16 * 8)) , ':');
	
	if(Status_Selection == 2) LCD_SetBackColor(Blue); //状态2-Seeting状态 高亮显示分钟
	LCD_DisplayChar(Line4 , (320 - (16 * 9)) , Time_Set[1]/10 + 0x30);
	LCD_DisplayChar(Line4 , (320 - (16 * 10)) , Time_Set[1]%10 + 0x30);
	LCD_SetBackColor(Black);
	LCD_DisplayChar(Line4 , (320 - (16 * 11)) , ':');

	if(Status_Selection == 3) LCD_SetBackColor(Blue); 状态3-Seeting状态 高亮显示秒
	LCD_DisplayChar(Line4 , (320 - (16 * 12)) , Time_Set[2]/10 + 0x30);
	LCD_DisplayChar(Line4 , (320 - (16 * 13)) , Time_Set[2]%10 + 0x30);
	LCD_SetBackColor(Black);
	
	
	//***不同状态对应的界面
	if(Status_Selection == 0) //状态0
	{
		memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
		sprintf((char*)LCD_String_Disp , "       Standby       ");
		LCD_DisplayStringLine(Line7 , LCD_String_Disp);
	}
	else if(Status_Selection == 4)	//状态4
	{
		memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
		sprintf((char*)LCD_String_Disp , "       Running      ");
		LCD_DisplayStringLine(Line7 , LCD_String_Disp);		
	}
	else if(Status_Selection == 5)	//状态4
	{
		
		memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
		sprintf((char*)LCD_String_Disp , "       Pause      ");
		LCD_DisplayStringLine(Line7 , LCD_String_Disp);		
	}
	
	else //状态1-2-3
	{
		memset(LCD_String_Disp , 0 ,sizeof(LCD_String_Disp));
		sprintf((char*)LCD_String_Disp , "       Setting      ");
		LCD_DisplayStringLine(Line7 , LCD_String_Disp);
	}
	
}

按键模块与LCD模块的逻辑图(仅供参考)

在这里插入图片描述

  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
### 回答1: 蓝桥杯是全国性的计算机大赛,旨在提高大学生的计算机技术水平和创新能力。嵌入式STM32G431是一款嵌入式芯片,具有高性能和低功耗的特点。第十二届第一场省赛停车计费系统是蓝桥杯的一道工程题目,要求参赛选手设计一个停车场计费系统。 停车计费系统是指通过嵌入式技术实现对车辆进入和离开停车场的自动检测、计时和计费的系统。对于这个题目,参赛选手可以根据题目要求,使用STM32G431芯片设计一个具有以下功能的系统: 1. 车辆进入检测:使用车辆传感器检测车辆的进入,触发计时。 2. 车辆离开检测:使用车辆传感器检测车辆的离开,停止计时。 3. 计时功能:使用内部时钟模块获取进入和离开的时间,并计算停车时间。 4. 计费功能:根据停车时间,按照一定的计费规则进行计费。 5. 显示功能:使用液晶显示屏显示当前的停车信息,如车牌号、停车时间、费用等。 6. 数据存储功能:使用闪存等储存介质将停车数据进行存储,以便后续的数据分析和查询。 设计一个停车计费系统涉及到硬件设计和软件编程两个方面。硬件方面,参赛选手需要选择合适的传感器、显示屏、存储介质等,以及设计电路和接口进行连接。软件方面,需要使用C语言或者汇编语言编写程序,对芯片进行编程,实现各项功能。 通过此次比赛,选手们可以锻炼嵌入式系统的设计能力和编程能力,了解实际应用中嵌入式系统的工作原理和应用场景。同时,也能提升对STM32G431芯片的理解和运用能力。这对于培养嵌入式技术人才,推动物联网技术的发展都具有积极意义。 ### 回答2: 蓝桥杯是面向计算机爱好者的智力竞赛,而嵌入式STM32G431是一款嵌入式系统开发板。第十二届第一场省赛的停车计费系统真题工程,则是要求参赛选手设计并实现一个能够进行停车计费的系统。 停车计费系统是一种用于自动计费和管理停车场的系统。这个系统可以通过识别车辆的进出以及停车的时间,自动计算并收费。在这个工程中,选手需要使用嵌入式STM32G431开发板以及相关的硬件和软件,来设计一个能够实现停车计费功能的系统。 首先,选手需要使用传感器或摄像头来实现车辆进出的检测。当车辆进入或离开停车场时,传感器会发出信号并通过STM32G431进行检测。接着,选手需要编程实现识别车辆的算法,以便能够识别不同的车辆。当车辆停放时,系统会通过计时器记录停车的时间。 然后,选手需要编写计费算法,根据停车的时间来计算费用。这个算法可以根据停车场的规则来确定费用的计算方式,例如按小时计费或按照不同的时间段采用不同的费率。 最后,选手还需要设计一个界面,使得系统能够与用户进行交互。用户可以通过该界面查询停车费用,并进行付款。同时,选手还需要保证系统的稳定性和安全性,确保数据的准确性和保密性。 总而言之,蓝桥杯嵌入式STM32G431第十二届第一场省赛停车计费系统真题工程要求选手使用硬件和软件开发能力,设计并实现一个完整的停车计费系统。这需要选手具备嵌入式系统开发、传感器技术、算法设计和界面设计等多方面的知识和技能。 ### 回答3: 蓝桥杯嵌入式stm32g431——第十二届第一场省赛停车计费系统真题工程是一个基于STM32G431开发板的停车计费系统设计题目。该系统的主要功能是实现停车场的车辆进入、出场的计费管理。 首先,该系统需要实现一个车辆进入检测的功能。当车辆进入停车场时,系统会通过传感器检测到车辆的到达,并记录下进入的时间。 然后,系统需要实现一个车辆出场的功能。当车辆准备离开停车场时,系统会通过传感器检测到车辆的离开,并记录下离开的时间。 接下来,系统需要计算车辆停留的时间。通过进入时间和离开时间的差值计算得出车辆停留的时长。 最后,系统需要计算停车费用。根据停车场的计费规则,根据车辆停留的时长计算出停车费用,并将费用显示在屏幕上。 在实现上述功能的过程中,需要运用STM32G431开发板的各种功能和模块,包括GPIO口、定时器、中断、串口通信等。通过编写相应的代码,实现按钮的控制、传感器检测、时间的计算以及屏幕的显示等功能。 该项目的设计需要考虑多种情况,比如车辆重复进入出场、车辆进入出场顺序错乱等,要充分考虑这些异常情况并进行相应的处理。在代码编写过程中,还需注意代码的优化和资源的合理利用,以提高系统的性能和效率。 通过完成这个项目的设计与实现,可以加深对STM32G431嵌入式系统的了解和应用,并提升嵌入式系统开发的能力。同时,也能锻炼自己的逻辑思维、问题解决能力和团队合作精神。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

lzya.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值