【蓝桥杯嵌入式】【复盘】第14届省赛真题
1. 前言
最近在准备16届的蓝桥杯嵌入式赛道的国赛,打算出一个系列的博客,记录STM32G431RBT6这块比赛用板上所有模块可能涉及到的所有考点,如果有错误或者遗漏欢迎各位大佬斧正。
本系列博客会分为以下两大类:
1.1. 单独模块的讲解
在这部分,我会分享自己总结的各个模块的相关配置、代码书写模板,涉及到的大致框架如下:

这个框架后续可能会不断更新,欢迎各位给出建议。
这一大类相关的文章链接如下(持续补充中):
【蓝桥杯嵌入式】【模块】二、LED相关配置及代码模板-CSDN博客
【蓝桥杯嵌入式】【模块】三、LCD相关配置及代码模板-CSDN博客
【蓝桥杯嵌入式】【模块】四、按键相关配置及代码模板-CSDN博客
【蓝桥杯嵌入式】【模块】五、ADC相关配置及代码模板-CSDN博客
【蓝桥杯嵌入式】【模块】六、PWM相关配置及代码模板-CSDN博客
【蓝桥杯嵌入式】【模块】七、IIC相关配置及代码模板-CSDN博客
【蓝桥杯嵌入式】【模块】八、UART相关配置及代码模板-CSDN博客
1.2. 蓝桥杯各届的真题、模拟题复盘及个人答案
在这一部分,我会分享个人练过的所有题的复盘思路及代码,每篇文章结构如下:

这一大类相关的文章链接如下(持续补充中):
【蓝桥杯嵌入式】【复盘】第13届国赛真题_蓝桥杯嵌入式13届国赛题-CSDN博客
以下是本篇博客正文内容:
2. 4t评测结果
4t平台网址:学单片机,上4T - 4T评测网

尝试了接近20次,始终有一个评测点过不了,实在没辙了。。
3. 个人解答代码
仓库地址:lanqiao/14_true_shengsai at main · Dukiyaaa/lanqiao
如果不嫌麻烦的话,可以点个star~
4. 重点和易错点

这一套题,根据我个人的做题经历,我认为应该关注的有以下几点:
1. pwm输出的高频调整。
2. 最大速度保持不足2s的不纳入统计。
4.1. pwm输出的高频调整
我的核心代码如下:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM4)
{
// ...按键扫描逻辑
if(switch_lock == 1)
{
switch_lock_cnt++;
if((switch_lock_cnt % 10) == 0)
{
led_8bits = led_8bits ^ (1 << 1);
}
if((switch_lock_cnt % 25) == 0)
{
if(is_high == 1 && fre_out > 4000)
{
fre_out -= 200;
if(fre_out < 4000) fre_out = 4000;
}
else if(is_high == 0 && fre_out < 8000)
{
fre_out += 200;
if(fre_out > 8000) fre_out = 8000;
}
pwm_set_fre_duty(fre_out, duty);
}
if(switch_lock_cnt >= 500)
{
switch_lock_cnt = 0;
switch_lock = 0;
led_8bits &= ~(1 << 1);
if(is_high == 1)
{
fre_out = 4000.0f;
is_high = 0;
}
else if(is_high == 0)
{
fre_out = 8000.0f;
is_high = 1;
}
pwm_set_fre_duty(fre_out, duty);
}
}
else
{
switch_lock_cnt = 0;
}
// ...最高速度保持2s
}
}
void pwm_set_fre_duty(uint32_t fre, uint32_t duty)
{
uint32_t clk = 80000000;
uint32_t div = 1;
uint32_t period = clk / div / fre - 1;
uint32_t pulse = period * duty / 100;
if (pulse > period) pulse = period - 1; // 防止CCR超出ARR
// 设置周期与占空比
TIM2->ARR = period;
TIM2->CCR2 = pulse;
// 强制立即更新(如果启用了预装载)
TIM2->EGR |= TIM_EGR_UG;
// 启动定时器
TIM2->CR1 |= TIM_CR1_CEN;
}
void pwm_task(void)
{
// ...pwm捕获
// ...异步处理pwm输出
pwm_set_fre_duty(fre_out, duty);
}
这个考点与之前的内容不同的地方在于pwm的输出会经历短时间内高频率的切换(我的是250ms切换一次,共切换20次,每次让频率变化200),测试时发现这样操作pwm输出huui'dao
4.2. 最大速度保持不足2s的不纳入统计
我的核心代码如下:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM4)
{
// ...按键扫描逻辑
// ...pwm切换逻辑
if(mh_lock == 0)
{
max_vh_cnt++;
if(max_vh_cnt >= 200)
{
mh_lock = 1;
max_vh_cnt = 0;
MH = tmp_MH;
}
}
if(ml_lock == 0)
{
max_vl_cnt++;
if(max_vl_cnt >= 200)
{
ml_lock = 1;
max_vl_cnt = 0;
ML = tmp_ML;
}
}
}
}
void pwm_task(void)
{
V = fre * 2.0f * 3.14f * (float)R / (100.0f * (float)K);
// 要加进任务调度才行,否则下面的if作比较会出问题
if((V > MH) && (is_high == 1))
{
if(V != tmp_MH)
{
tmp_MH = V;
max_vh_cnt = 0;
mh_lock = 0;
}
}
if((V > ML) && (is_high == 0))
{
if(V != tmp_ML)
{
tmp_ML = V;
max_vl_cnt = 0;
ml_lock = 0;
}
}
// pwm输出逻辑
}
处理思路如下:
当测量得到当前的V大于记录的最大速度时,需要先进行判断,如果这次的V与当前的tmp_MH/tmp_ML相同,说明是同一个值重复在保持,跳过;反之说明上一次的最大值保持不足2s,所以要清零计数器重新开始计数2s;达到2s后,再做更新。
但是我这个点测评一直过不了,自己的板子上测试效果倒是没问题。如果有佬发现可能有什么问题,非常欢迎提出。
5. 总结
本文总结了个人在练习14届省赛过程中的复盘及易错点、重难点分析,主要内容在pwm输出高频调整、最大速度的捕捉。
更多推荐
所有评论(0)