13届蓝桥杯省赛程序设计试题

发布于:2025-07-09 ⋅ 阅读:(13) ⋅ 点赞:(0)

目录

一、题目

二、题目分析

2.1 按键功能分析

2.2 脉冲输出功能分析

2.3 串口通信功能分析

2.4 LED 指示功能分析

三、CubeMX 配置

3.1 系统时钟配置

3.2 GPIO配置

3.3 定时器(TIM2)配置

3.4 串口(USART)配置

四、相关代码实现

4.1 按键扫描功能

4.2 LCD显示

4.3 PWM输出控制

4.4 串口通信

4.5 LED指示灯控制

五、测试结果

一、题目

二、题目分析

2.1 按键功能分析

(1) 密码调整功能,按键刚上电显示界面的密码值为 @,按下 B1 B2 B3 三位密码值分别加 1
(2)  密码确认功能 B4 ,密码正确就跳转到输出状态页面,不正确就停留在输入界面,同时三位密码值重置为@

2.2 脉冲输出功能分析

(1) 无正确密码提交时,PA1 输出 1KHz 的方波信号
(2) 输入正确密码时,PA1 输出 2KHz 10% 占空比的脉冲信号持续 5 秒,之后切换回原始密码输入界面

2.3 串口通信功能分析

发送指定格式:当前密码 - 新密码,可修改密码,如果当前密码不正确就无法修改

2.4 LED 指示功能分析

(1) 密码验证成功,LD1 5 秒之后熄灭
(2) 连续三次及以上的密码输入错误,LD2 0.1 秒闪烁 5 秒熄灭

三、CubeMX 配置

3.1 系统时钟配置

主频设置为80MHz,确保TIM、USART等外设时钟正确。

3.2 GPIO配置

按键(B1-B4):配置为输入模式,并写出相应名称。

LED(LD1-LD8):配置为输出模式,且初始电平设置为Low。

PA1(PWM输出):配置为TIM2_CH2的PWM模式。

3.3 定时器(TIM2)配置

3.4 串口(USART)配置

USART1:波特率9600,8位数据位,无校验位,1位停止位。

四、相关代码实现

4.1 按键扫描功能

(1)按键读取函数-->uint8_t KEY_Read(void)

uint8_t KEY_Read(void)
{
	ucVal = 0;
	if (HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin) == 0)
	{
		HAL_Delay(10);
		if (HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin) == 0)
		{
			ucVal = 1;
		}
	}
	if (HAL_GPIO_ReadPin(B2_GPIO_Port, B2_Pin) == 0)
	{
		HAL_Delay(10);
		if (HAL_GPIO_ReadPin(B2_GPIO_Port, B2_Pin) == 0)
		{
			ucVal = 2;
		}
	}
	if (HAL_GPIO_ReadPin(B3_GPIO_Port, B3_Pin) == 0)
	{
		HAL_Delay(10);
		if (HAL_GPIO_ReadPin(B3_GPIO_Port, B3_Pin) == 0)
		{
			ucVal = 3;
		}
	}
	if (HAL_GPIO_ReadPin(B4_GPIO_Port, B4_Pin) == 0)
	{
		HAL_Delay(10);
		if (HAL_GPIO_ReadPin(B4_GPIO_Port, B4_Pin) == 0)
		{
			ucVal = 4;
		}
	}
	return ucVal;
}

(2)B1/B2/B3:每次按下对应密码位+1(0-9循环)。

         B4:验证密码,正确则切换PWM输出并跳转界面,错误则重置密码显示并计数。

void Key_Proc(void)
{
	static uint8_t Key_old = 0,couter_error = 0;
	uint8_t key;
	if(ui == 0)
	{
		key = KEY_Read();
		if(key != Key_old)
		{
			Key_old = key;
			switch(key)
			{
				case 3:
					if((psd[2]=='@')||(psd[2]=='9'))
					{
						psd[2]='0';
					}
					else
					{
						++psd[2];
					}
					break;
				case 4:
					if(psd[2]==psd_defualt[0])
					{
						ui = 1;
						couter_error = 0;
						led_5s = 5000;
					}
					else
					{
						psd[0] = '@';
						psd[1] = '@';
						psd[2] = '@';
						++couter_error;
						if(couter_error >= 3)
						{
							led_5s = 5000;
						}
					}
					break;
				default:
					break;
			}
		}
	}
}

4.2 LCD显示

(1)密码输入界面(PSD):

void Lcd_Proc(void)
{
	uint8_t uclcd[21];//lcd display ram
	if(lcd_100ms<100) return;
	lcd_100ms = 0;    //reset
	
	if(ui == 0)
	{
		sprintf((char *)uclcd, "       PSD");
		LCD_DisplayStringLine(Line2, uclcd);
		sprintf((char *)uclcd, "    B1:%c    ",psd[0]);
		LCD_DisplayStringLine(Line4, uclcd);
		sprintf((char *)uclcd, "    B2:%c    ",psd[1]);
		LCD_DisplayStringLine(Line5, uclcd);
		sprintf((char *)uclcd, "    B3:%c    ",psd[2]);
		LCD_DisplayStringLine(Line6, uclcd);
		
	}
	else
	{
		//...
	}
}

(2)输出状态界面(STA):

void Lcd_Proc(void)
{
	uint8_t uclcd[21];
	if(lcd_100ms<100) return;
	lcd_100ms = 0;
	
	if(ui == 0)
	{
		//...
	}
	else
	{
		sprintf((char *)uclcd, "       STA");
		LCD_DisplayStringLine(Line2, uclcd);
		sprintf((char *)uclcd, "    F:2000Hz    ");
		LCD_DisplayStringLine(Line4, uclcd);
		sprintf((char *)uclcd, "    D:10%%    ");
		LCD_DisplayStringLine(Line5, uclcd);
		sprintf((char *)uclcd, "          ");
		LCD_DisplayStringLine(Line6, uclcd);
	}
}

!!!由于代码较长,故不一一展示,有需要可联系我获取完整代码

4.3 PWM输出控制

默认状态:1KHz方波(ARR=999, Pulse=500)。

密码正确时:2KHz 10%占空比(ARR=499, Pulse=50),持续5秒后恢复默认。

4.4 串口通信

接收格式:当前密码-新密码(如123-789)。校验当前密码是否正确。若正确,更新密码并返回Success;否则返回Fail。

4.5 LED指示灯控制

密码正确时LD1点亮5秒,连续3次错误后LD2闪烁。

五、测试结果

(1)上电默认显示PSD界面,密码位显示@。

      

(2)输入正确密码(默认123)后:切换界面,显示F:2000Hz, D:10%。PA1输出2KHz 10%占空比脉冲,持续5秒后恢复1KHz方波。LD1点亮5秒。

  

(3)连续3次输入错误密码:LD2以0.1秒间隔闪烁5秒。

(4)串口通信:发送123-789修改密码---->密码正确时更新,错误时提示。