蓝桥杯嵌入式12届省赛,轻松解决——附满分工程链接

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

近年来,蓝桥杯竞赛的题目设计逐渐向思维深度和创新性倾斜,传统“刷题式”备考的效果正在减弱。面对这一趋势,借鉴他人的解题思路和分析方法,往往能帮助参赛者更快抓住问题核心,实现事半功倍。

本次分享聚焦第12届蓝桥杯的这道典型题目,这些题目有一定难度。通过拆解题目背景、关键思路和优化技巧,希望能为读者提供一种可参考的思考范式。需说明的是,所有观点仅为个人经验总结,未必完全适用所有场景,欢迎交流指正。

(注:若需具体题目解析或进一步讨论,可随时补充细节。)


题目

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

配置Cubemx:

主要的配置如下:
在这里插入图片描述
串口配置:

在这里插入图片描述
打开串口中断:
在这里插入图片描述

题目难点

我认为本届题目的难点有2个
1、对于时间的处理,时间的是否合理,怎么计算时间
2、出库入库的存储及处理

代码实现

对于第一点

恰当地用c语言的库函数有时候可以很高效的解决问题和减少出问题的概论,在比赛短短的5小时来说,还是很关键的。
我首先介绍一个库函数

#include"time.h"

这个库函数里面有很多处理时间的封装好的函数。
本次工程用到了“time_t mktime(struct tm *timeptr);”
在这里插入图片描述
简单说就是计算当前时间距离1970-01-01的秒数;

 times.tm_year = T.year + 2000-1900; // 2000+年偏移
        times.tm_mon = T.mon - 1;      // 月份从0开始
        times.tm_mday = T.day;
        times.tm_hour = T.hour;
        times.tm_min = T.min;
        times.tm_sec = T.sec;
        now_car.sec_all = mktime(&times); // 生成时间戳```

然后我写了很简单的一个判断年月日是否合理的代码

void mon_pd() {
    // 月份校验(1-12)
    if (T.mon < 1 || T.mon > 12) error = 1;
    
    // 计算当月最大天数(考虑闰年)
    int day_max = 31;
    if (T.mon == 2) {
        int is_leap = ((T.year % 4 == 0) && (T.year % 100 != 0)) || (T.year % 400 == 0);
        day_max = is_leap ? 29 : 28;
    } else if (T.mon == 4 || T.mon == 6 || T.mon == 9 || T.mon == 11) {
        day_max = 30;
    }
    
    // 校验时间合法性
    if (T.day > day_max || T.hour > 23 || T.min > 59 || T.sec > 59) error = 1;
}

用了两次三目运算符:
简单说就是前面为1的话,就选前面那个的值,否在就选后面的值
1、首先判断月份是否在1~12月
2、当是2月时,判断是否闰年,来确定2月的天数
3、计算其他月份的时间的天数
4、得到的此月份的最大天数

对于第二点

写两个函数,一个入库函数,一个出库函数
入库函数

void park_in() {
    uint8_t id_yn = 0;//判断车牌有无,id yes or no
    if (now_car.cv_yn != 0) {
        // 检查车牌是否已存在
        for (uint8_t i = 0; i < 8; i++) {
            if (strcmp(all_car[i].id, now_car.id) == 0) {
                id_yn = 1;
                break;
            }
        }
        // 分配空闲车位
        if (!id_yn) {
            for (uint8_t i = 0; i < 8; i++) {
                if (all_car[i].cv_yn == 0) {
                    all_car[i] = now_car; // 复制车辆信息
                    if (now_car.cv_yn == 1) ct.cn_num++;
                    else if (now_car.cv_yn == 2) ct.vn_num++;
                    in_out_flag = 1; // 标记进场成功
                    break;
                }
            }
        }
    }
}

出库函数及时间和费用的计算

void park_out()
{
    uint8_t id_yn=0;         // 车辆存在标志:0=未找到,1=已找到
    uint8_t place=0;         // 存储找到车辆的位置索引(0-7)
    uint32_t cha;            // 存储停车时长差值(秒)
    // 检查当前车辆状态是否有效(cv_yn=1 普通车,2=VIP车)
    if (now_car.cv_yn != 0) 
    {
        // 遍历停车场所有车位(共8个)
        for (uint8_t i = 0; i < 8; i++)
        {
            // 比较当前车辆ID与车位中的车辆ID
            if (strcmp(all_car[i].id, now_car.id) == 0)
            {
                id_yn=1;     // 标记车辆已找到
                place=i;     // 记录车辆所在位置
                break;       // 找到后立即跳出循环
            }
        }
        // 如果找到车辆
        if(id_yn==1)
        {
            // 计算停车时长(当前时间戳 - 入场时间戳)[1](@ref)
            cha = now_car.sec_all - all_car[place].sec_all; // 计算完整小时数(秒转小时)
            all_car[place].hour_all = cha / 3600; // 处理不足1小时的部分(向上取整)
            if(cha % 3600 != 0 && cha > 0)  all_car[place].hour_all++;  // 不足1小时按1小时计费
            if(now_car.cv_yn == 1)
            {
                money = ct.cn_vlaue * all_car[place].hour_all;  // 计算费用
                ct.cn_num--;  // 减少普通车计数
                // 格式化账单信息:类型+车牌+时长+金额
                sprintf(tx, "CNBR:%4s:%d:%0.2f\r\n", 
                        all_car[place].id, 
                        all_car[place].hour_all, 
                        money);
                // 通过串口发送账单(超时50ms)[6,7](@ref)
                HAL_UART_Transmit(&huart1, (uint8_t*)tx, strlen(tx), 50);
            }
            
            else if(now_car.cv_yn == 2)
            {
                money = ct.vn_vlaue * all_car[place].hour_all;  // 计算费用
                ct.vn_num--;  // 减少VIP车计数
                // 格式化账单信息
                sprintf(tx, "VNBR:%4s:%d:%0.2f\r\n", 
                        all_car[place].id, 
                        all_car[place].hour_all, 
                        money);
                // 通过串口发送账单
                HAL_UART_Transmit(&huart1, (uint8_t*)tx, strlen(tx), 50);
            }
            // 释放车位
            all_car[place].cv_yn = 0;  // 清除车辆类型标记
            all_car[place].hour_all = all_car[place].sec_all = 0;   // 重置时长计数器
            memset(&all_car[place].id, '\0', 5); // 清空车牌号(安全擦除)[2]
        }
    }
}

总结

把这两个难点解决了,其他的就很好解决啦。
此文仅代表个人愚见。
蓝桥杯12届完整工程链接

其他届的工程及解析

第8届省赛工程及解析

第15届国赛解题思路及完整工程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

杰杰桀桀桀

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

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

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

打赏作者

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

抵扣说明:

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

余额充值