当前位置: 首页 > ai >正文

【蓝桥杯嵌入式】【复盘】第15届省赛真题

 1. 前言

最近在准备16届的蓝桥杯嵌入式赛道的国赛,打算出一个系列的博客,记录STM32G431RBT6这块比赛用板上所有模块可能涉及到的所有考点,如果有错误或者遗漏欢迎各位大佬斧正。

本系列博客会分为以下两大类:

1.1. 单独模块的讲解

在这部分,我会分享自己总结的各个模块的相关配置、代码书写模板,涉及到的大致框架如下:

 这个框架后续可能会不断更新,欢迎各位给出建议。

这一大类相关的文章链接如下(持续补充中):

【蓝桥杯嵌入式】【模块】一、系统初始化-CSDN博客

【蓝桥杯嵌入式】【模块】二、LED相关配置及代码模板-CSDN博客

【蓝桥杯嵌入式】【模块】三、LCD相关配置及代码模板-CSDN博客

【蓝桥杯嵌入式】【模块】四、按键相关配置及代码模板-CSDN博客

【蓝桥杯嵌入式】【模块】五、ADC相关配置及代码模板-CSDN博客

【蓝桥杯嵌入式】【模块】六、PWM相关配置及代码模板-CSDN博客

【蓝桥杯嵌入式】【模块】七、IIC相关配置及代码模板-CSDN博客

【蓝桥杯嵌入式】【模块】八、UART相关配置及代码模板-CSDN博客

1.2. 蓝桥杯各届的真题、模拟题复盘及个人答案

在这一部分,我会分享个人练过的所有题的复盘思路及代码,每篇文章结构如下:

这一大类相关的文章链接如下(持续补充中):

【蓝桥杯嵌入式】【复盘】第13届国赛真题_蓝桥杯嵌入式13届国赛题-CSDN博客

【蓝桥杯嵌入式】【复盘】第14届国赛真题-CSDN博客

【蓝桥杯嵌入式】【复盘】第15届省赛真题-CSDN博客


以下是本篇博客正文内容:

2. 4t评测结果

4t平台网址:学单片机,上4T - 4T评测网

测试拿到了满分。


3. 个人解答代码

仓库地址:lanqiao/15_true_shengsai at main · Dukiyaaa/lanqiao

如果不嫌麻烦的话,可以点个star~


4. 重点和易错点

这一套题,根据我个人的做题经历,我认为应该关注的有以下几点:

1. pwm相关的超限报警、频率突变测量。

2. 按键长按。

4.1. pwm超限报警、频率突变测量

我的核心代码如下:

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance == TIM2){uint32_t tmp = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_1);if(tmp != 0){freA = 8000000.0f / (float)tmp;}if(freA > 20000){freA = 20000;}if(freA < 400){freA = 400;}freA += PX;__HAL_TIM_SET_COUNTER(&htim2, 0);HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);}if(htim->Instance == TIM3){uint32_t tmp = HAL_TIM_ReadCapturedValue(&htim3, TIM_CHANNEL_1);if(tmp != 0){freB = 8000000.0f / (float)tmp;}if(freB > 20000){freB = 20000;}if(freB < 400){freB = 400;}freB += PX;__HAL_TIM_SET_COUNTER(&htim3, 0);HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_1);}
}
float faMAX, fbMAX, faMIN, fbMIN;bool NHA_lock = 1, NHB_lock = 1;
void pwm_task(void)
{	// 超限if((NHA_lock == 0) && ((freA - (float)PH) > 10)){NHA++;NHA_lock = 1;}else if((NHA_lock == 1) && (((float)PH - freA) > 10)){NHA_lock = 0;}if((NHB_lock == 0) && ((freB - (float)PH) > 10)){NHB++;NHB_lock = 1;}else if((NHB_lock == 1) && (((float)PH - freB) > 10)){NHB_lock = 0;}// 突变,3s判断一次if(freA > faMAX){faMAX = freA;}if(freB > fbMAX){fbMAX = freB;}if((freA >= 0) && (freA < faMIN)){faMIN = freA;}if((freB >= 0) && (freB < fbMIN)){fbMIN = freB;}if(is_3s == 1){if(((faMAX - faMIN) - PD) >= 5){NDA++;}if(((fbMAX - fbMIN) - PD) >= 5){NDB++;}faMAX = -1;faMIN = 40000;fbMAX = -1;fbMIN = 40000;is_3s = 0;}}

 1. 关于超限预警,需要注意的是防抖的处理,蓝桥杯的要求默认情况下都是如果一直超限的话,超限次数不累加,所以建立一个flag用于控制超限次数的增加。

2. 关于频率突变,我的处理方法就是单纯每3s判断一次这3s内测到的最大最小值,根据要求做一下比较就行。之前想过很多种方法,比如滑动窗口,最后发现像现在这样处理就够了。

3. 可以发现,边界值部分我基本都采用的是做差比较,这种方法用于防止边界情况下的计数抖动。

4.2. 按键长按

我的核心代码如下:

void key_scan(void)
{key_buf[0].key_pin_state = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0);key_buf[1].key_pin_state = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1);key_buf[2].key_pin_state = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2);key_buf[3].key_pin_state = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);for(uint8_t i = 0;i < 4;i++){switch(key_buf[i].key_step){case 0:if(key_buf[i].key_pin_state == 0){key_buf[i].key_step = 1;}			else{key_buf[i].key_step = 0;key_buf[i].key_is_down = 0;key_buf[i].key_time = 0;key_buf[i].key_is_long = 0;}break;case 1:if(key_buf[i].key_pin_state == 0){key_buf[i].key_step = 2;key_buf[i].key_is_down = 1;}			else{key_buf[i].key_step = 0;key_buf[i].key_is_down = 0;key_buf[i].key_time = 0;key_buf[i].key_is_long = 0;}break;case 2:if(key_buf[i].key_pin_state == 0){key_buf[i].key_time++;if(key_buf[i].key_time >= 100){key_buf[i].key_is_long = 1;}					}			else{key_buf[i].key_step = 0;key_buf[i].key_is_down = 0;key_buf[i].key_time = 0;key_buf[i].key_is_long = 0;}break;}}
}
void key_task(void)
{for(uint8_t i = 0;i < 4;i++){if(key_buf[i].key_is_down == 1){switch(i){case 0:key_buf[i].key_is_down = 0;if(lcd_num == 1){switch(is_select){case 0:PD += 100;if(PD > 1000){PD = 1000;}break;case 1:PH += 100;if(PH > 10000){PH = 10000;}break;case 2:PX += 100;if(PX > 1000){PX = 1000;}break;}}break;case 1:key_buf[i].key_is_down = 0;if(lcd_num == 1){switch(is_select){case 0:PD -= 100;if(PD < 100){PD = 100;}break;case 1:PH -= 100;if(PH < 1000){PH = 1000;}break;case 2:PX -= 100;if(PX < -1000){PX = -1000;}break;}}break;case 2:// 短按if(lcd_num == 1){key_buf[i].key_is_down = 0;is_select++;if(is_select > 2){is_select = 0;}}else if(lcd_num == 0){key_buf[i].key_is_down = 0;is_fre ^= 1;	// 切换显示模式}else if(lcd_num == 2){if(key_buf[2].key_is_long == 1){key3_flag = 1;}}break;case 3:key_buf[i].key_is_down = 0;lcd_num++;if(lcd_num > 2){lcd_num = 0;}if(lcd_num == 0){is_fre = 1;}if(lcd_num == 1){is_select = 0;}break;}}if(key3_flag == 1){if(key_buf[2].key_is_long == 0){key3_flag = 0;if(lcd_num == 2){NHA = 0;NHB = 0;NDA = 0;NDB = 0;}}}}
}

其实比较常规,关于短按的逻辑直接处理就行,但是关于长按,则需要建立标志位,用于实现在松开之后再做处理的逻辑。


5. 总结

本文总结了个人在练习13届省赛过程中的复盘及易错点、重难点分析,主要内容在pwm超限与突变测量、按键长按。

http://www.xdnf.cn/news/9629.html

相关文章:

  • Python学习(3) ----- Python的函数定义及其使用
  • OpenLayers 加载网格信息
  • [CISCN 2021初赛]glass
  • 【第2章 绘制】2.15 剪辑区
  • 【摄影教程】
  • 使用jessibuca+wvp+zlm实现html无插件播放摄像头实时画面
  • promise详细总结
  • VTK|Z轴拉伸功能的实现
  • 【Redis】通用命令
  • 使用Milvus运行一个Milvus单机版实例
  • 什么是 SRM、ERP、SCM,如何科学选型采购系统
  • 【Python】 -- 趣味代码 - 皮卡丘
  • 打造卓越客户支持体验:知识共享驱动服务优化
  • 利用openwrt路由器和随身WIFI搭建CPE
  • 世界模型:AGI突破口?一文了解NVIDIA Cosmos 平台
  • PyTorch 入门学习笔记
  • 【Python】 -- 趣味代码 - 数字游戏
  • 从 0 开始学习大模型应用开发(加餐二)- 使用Spring AI开发MCP系统
  • Java 事务管理:在分布式系统中实现可靠的数据一致性
  • Micro-CT扫描成像的样本处理与样本要求技术指南
  • 浅谈国企数字化转型
  • 2025年5月通信科技领域周报(5.19-5.25):太赫兹通信规模商用启动 空天地一体化网络加速落地
  • “从复眼到智慧”:观测云2025发布会专访—— CEO 蒋烁淼
  • Python兴趣匹配算法:从理论到实战的进阶指南
  • Echarts实现3D地图(多层geo)同步缩放
  • LangChain + Redis:实现持久化的聊天历史记录管理
  • 华为认证是什么?网络工程师的华为认证考试详解
  • ActiveMQ 可观测性最佳实践
  • 日立HDS G350存储Dynamic Link Manager(HDLM)在linux系统多路径绑定
  • ChatGPT + 知网 + 知乎,如何高效整合信息写出一篇专业内容?