第十五届蓝桥杯模拟考试III_物联网设计与开发官方代码分析

目录

  • 前言:
  • 显示界面部分:
  • 页面切换:
  • 数值的轮回调整:
  • 传递数据:

前言:

这次模拟的效果很不好。85分,4h的限时我花了两天完成,这个时间是远远超出要求的,而且最后还只拿到56分,抛开分数高低不提,就这个用时属实蜗牛一样的速度,不根治比赛就是凉凉,分析原因主要有以下两点:
第一点配置CubMx过慢,这证明我对那个板子和原理图很不熟悉,这大概和我前一年学的标准库有关吧,才接触CubMx,还有就是各功能只过了一遍,大致很多细节都忘了,所以后续考虑把板子各引角对应的功能直接背下来,考试花更少的时间在看原理图上,芯片的引脚不算太多,还有就是一些接口代码必须要背下来,官方的参考代码里没有这些东西,这个没有技巧理解之后多练多写。
第二点就是官方的代码用的很优雅,将我几十行的代码用两三行的代码解决,这个是今天重点讨论对象。

显示界面部分:

显示界面部分由于要显示double类型数据,所以我写了一个oled_shownumber函数,也是基于oled_showchar的基础上写出来的,但是首先要写一个pow函数,又要写一个求数字长度的函数过于复杂,甚至数据长度一会是3一会是2的情况下我又要写一个区域清屏函数,光是这一部分代码估计就有100+

看了官方给的代码后我才宛若如梦初醒,以下是官方代码解析:

官方代码将sprintf函数用到了极致!!!

sprintf 函数的作用是将一个或多个表达式按照指定的格式转换成字符串,并将结果存储在指定的字符数组中,定义在 stdio.h 头文件中。

真是一个神仙函数,之前我还看不上,今天我才发现是我高攀不起的函数,真的是方便到极致

例子1:

原始人代码:

void Function_NumbertoStr(unsigned char a[]){unsigned char up[30];unsigned char down[30];sprintf(up, "%.2f", num1);sprintf(down, "%.2f", num2);unsigned char i = 0, j = 0, k = 0;while(up[j] != '\0') a[i ++] = up[j ++];a[i ++] = '/';		while(down[k] != '\0') a[i ++] = down[k ++];a[i] = '/';//OLED_ShowString(0, 2, a, 8);
}

优雅代码:

void Function_NumbertoStr(unsigned char a[]){sprintf(a, "%.2f/%.2f/",num1, num2);
}

在这里插入图片描述

两者等效妙解,这就是一个或多个表达式的意思

例子2:

原始人代码:

unsigned char Function_NumberPoint(double number){while(number >= 1){number = number - 1;}return (unsigned char)(number * 10 + 0.5);
}unsigned char  Function_NumberLen(unsigned char number){unsigned char res = 0;while(number){res = res + 1;number = number / 10;}if(res == 0) res = 1;return res;
}uint32_t OLED_Pow(uint32_t X, uint32_t Y){uint32_t result = 1;while(Y){result = result * X;Y --;}return result;
}void OLED_ShowNumber(unsigned char x, unsigned char y, uint32_t chr, unsigned char len, unsigned char size){unsigned char i = 0, j = 0;while(j < len){OLED_ShowChar(x, y, chr / OLED_Pow(10, len - 1 - i) % 10 + '0' , size);i ++;j ++;x += 8;if(x > 120){x = 0;y += 2;}}
}
void Function_ShowMasg1(void){OLED_ShowString(24, 0, "TEMP:", 16);OLED_ShowNumber(64, 0, (uint32_t)(num1), Function_NumberLen((uint32_t)(num1)), 16);OLED_ShowString(64 + 8 * Function_NumberLen((uint32_t)(num1)), 0, "." , 16);OLED_ShowNumber(64 + 8 * Function_NumberLen((uint32_t)(num1)) + 8, 0,  Function_NumberPoint(num1), 1, 16);OLED_ShowString(24, 2, "HUMI:", 16);OLED_ShowNumber(64, 2, (uint32_t)(num2), Function_NumberLen((uint32_t)(num2)), 16);OLED_ShowString(64 + 8 * Function_NumberLen((uint32_t)(num2)), 2, "." , 16);OLED_ShowNumber(64 + 8 * Function_NumberLen((uint32_t)(num2)) + 8, 2,  Function_NumberPoint(num2), 1, 16);}
void Function_ShowMasg2(void){OLED_ShowString(0, 0, "TEMP",16);OLED_ShowString(48, 0, "UP:", 16);OLED_ShowNumber(72, 0, upt[flag1], 2, 16);OLED_ShowString(32, 2, "DOWN:", 16);OLED_ShowNumber(72, 2, dnt[flag2], 2,16);
}void Function_ShowMasg3(void){OLED_ShowString(0, 0, "HUMI", 16);OLED_ShowString(48, 0, "UP:", 16);OLED_ShowNumber(72, 0, ups[flag3], 2, 16);OLED_ShowString(32, 2, "DOWN:", 16);OLED_ShowNumber(72, 2, dns[flag4], 2, 16);
}

优雅代码:

	if(ui == 0){sprintf((char*)ucBuf, "   TEMP:%.1f   ", TEMP_rx*0.1);OLED_ShowString(0, 0, ucBuf);sprintf((char*)ucBuf, "   HUMI:%.1f   ", HUMI_rx*0.1);OLED_ShowString(0, 2, ucBuf);}else if(ui == 1){ sprintf((char*)ucBuf, "TEMP  UP:%d  ", TEMP_UP);OLED_ShowString(0, 0, ucBuf);sprintf((char*)ucBuf, "    DOWN:%d  ", TEMP_DOWN);OLED_ShowString(0, 2, ucBuf);}else if(ui == 2){sprintf((char*)ucBuf, "HUMI  UP:%d  ", HUMI_UP);OLED_ShowString(0, 0, ucBuf);sprintf((char*)ucBuf, "    DOWN:%d  ", HUMI_DOWN);OLED_ShowString(0, 2, ucBuf);}

在这里插入图片描述
特别是这个格式,我弄了很久很久,又是写新的显示函数,又是写查看数字长度函数,又是调试区域,还好这次数字显示长度没有过多的变化,不用写区域清屏函数,否者真是越写越🤡

人家代码绝妙在于直接将格式连同数据打印到数组里了,直接用show_string显示即可,真是优雅

———— 2024 / 3 / 15

页面切换:

页面切换部分我感觉我的还是不错的,毕竟我的代码不可能什么优点也没有,页面切换基于算法%符号
选取一个标记位,keynumber每次按键按下对这个标记位%3即可,毕竟只有三个页面分别标记为0、1、2即可,这个比官方的if else 语句要优雅😏

优雅代码:

unsigned char Function_KeyCheck(unsigned char keynumber){if(HAL_GPIO_ReadPin(User_key_GPIO_Port, User_key_Pin) == GPIO_PIN_RESET){while(HAL_GPIO_ReadPin(User_key_GPIO_Port, User_key_Pin) == GPIO_PIN_RESET);keynumber = keynumber + 1;OLED_Clear();}	 return keynumber % 3;
}

数值的轮回调整:

里面有一个功能是

在这里插入图片描述

我用的方式仍然是%算法即建立四个数组,按键每次都会更新键值,键值%数组长度,即可保证轮回,官方用的依旧是if else 语句

我的代码:

unsigned char upt[] = {25, 30, 35, 40, 45, 50};
unsigned char ups[] = {50, 55, 60, 65, 70, 75, 80, 85, 90, 95};
unsigned char dnt[] = {20,15,10, 5};
unsigned char dns[] = {45, 40, 35, 30, 25, 20, 15, 10};
static unsigned char flag1 = 3;
static unsigned char flag2 = 0;
static unsigned char flag3 = 4;
static unsigned char flag4 = 3;
void Function_MsgUpdata(unsigned char type, unsigned char keynumber){if(type == 1){if(keynumber == 1){flag1 = (flag1 + 1) % 6;}else if(keynumber == 2){flag2 = (flag2 + 1) % 4;}}else if(type == 2){if(keynumber == 1){flag3 = (flag3 + 1) % 10;}else if(keynumber == 2){flag4 = (flag4 + 1) % 8;}}		 
}

官方代码:

if(keyvalue != 0xff){if(keyvalue == 1){if(ui == 1){TEMP_UP += 5;if(TEMP_UP == 55){TEMP_UP = 25;}}else if(ui == 2){HUMI_UP += 5;if(HUMI_UP == 100){HUMI_UP = 50;}}keyvalue = 0xff;}else if(keyvalue == 2){if(ui == 1){TEMP_DOWN = TEMP_DOWN - 5;if(TEMP_DOWN == 0){TEMP_DOWN = 20;}}else if(ui == 2){HUMI_DOWN = HUMI_DOWN - 5;if(HUMI_DOWN == 5){HUMI_DOWN = 45;}}keyvalue = 0xff;}}

各有千秋吧

传递数据:

传递数据我和官方的思路是一样的即,将两个adc数据整合到一起发送,只不过我用的纯手写代码合并数据,原始人。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/278888.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用 Boot Camp 助理查明您的 Mac 需不需要 Windows 安装介质

使用 Boot Camp 助理查明您的 Mac 需不需要 Windows 安装介质 当前的 Mac 机型无需介质即可安装 Windows&#xff0c;也就是说&#xff0c;您不需要用到外置驱动器。较早的 Mac 机型需要用到 USB 驱动器或光盘驱动器。使用 Boot Camp 助理可查明您需要用到什么。 Boot Camp 助…

了解常用开发模型 -- 瀑布模型、螺旋模型、增量与迭代、敏捷开发

目录 瀑布模型 开发流程 开发特征 优缺点 适用场景 螺旋模型 开发流程 开发特征 优缺点 适用场景 增量与迭代开发 什么是增量开发&#xff1f;什么是迭代开发&#xff1f; 敏捷开发 什么是敏捷开发四原则&#xff08;敏捷宣言&#xff09;&#xff1f; 什么是 s…

nodejs 使用express插件multer文件上传,接收不到文件的bug

把路径改成绝对路径即可 改成 temp是你想上传到文件夹的路径&#xff0c;一般是在项目根目录下

Java-JVM 虚拟机原理调优实战

一、基础 栈帧&#xff08;Stack Frame&#xff09;栈空间的 基本元素&#xff0c;用于 方法的调用和方法的执行的数据结构 堆内存用来存放由new创建的对象和数组。在堆中分配的内存&#xff0c;由Java虚拟机的自动垃圾回收器来管理。在堆中产生了一个数组或对象后&#xff0c…

多线程:线程安全、线程同步、线程通信

线程安全 什么是线程安全问题? 多个线程&#xff0c;同时操作同一个共享资源的时候&#xff0c;可能会出现业务安全问题。 1.线程安全问题出现的原因? 存在多个线程在同时执行同时访问一个共享资源存在修改该共享资源 用程序模拟线程安全问题 取钱案例 需求: 小明和小红…

2025张宇考研数学基础36讲,视频百度网盘+PDF

一、张宇老师全年高数体系&#xff08;听课用书指南&#xff09; 25张宇全程&#xff1a; docs.qq.com/doc/DTmtOa0Fzc0V3WElI 复制粘贴在浏览器上打开&#xff0c;就可以看到2025张宇的全部的啦&#xff01; 一般来说我们把考研数学划分为3-4个阶段&#xff0c;分别是基础阶…

2. IS-IS 基础实验

2.1 IS-IS 配置实验 2.1.1 实验介绍 2.1.1.1 学习目标 1. 实现 IS-IS 协议基本配置 2. 实现 IS-IS 协议 DIS 优先级修改 3. 实现 IS-IS 协议网络类型修改 4. 实现 IS-IS 协议外部路由引入 5. 实现 IS-IS 接口 cost 修改 6. 实现 IS-IS 路由渗透配置 2.1.1.2 实验组网介…

Git——标签详解

目录 Git标签1、概述1.1、标签是什么1.2、什么时候使用标签1.3、标签的分类 2、轻量标签&#xff08;lightweight tag&#xff09;3、有附注的标签&#xff08;annotated tag&#xff09;4、两种标签的区别5、删除标签 Git标签 1、概述 1.1、标签是什么 在Git中&#xff0c;…

Java基于springboot的篮球NBA球队管理系统ssm

本次将以NBA球队管理方面为切入点&#xff0c;论述了NBA球队管理的意义和内容&#xff0c;以此展开对NBA球队管理系统的开发与建设的详细分析。从数据挖掘的角度出发&#xff0c;了解信息管理系统的作用&#xff0c;对NBA球队管理系统的过程以及用处进行更深一步的研究&#xf…

Java 世界破破烂烂,电音小猫缝缝补补

Java 世界破破烂烂&#xff0c;电音小猫缝缝补补 Java 通用代码生成器光 2.4.0 电音之王尝鲜版六正在研发&#xff0c;昨天发布了介绍视频&#xff0c;请见&#xff1a; https://www.bilibili.com/video/BV1yD421j7UP/ 电音之王尝鲜版六支持哑数据模式&#xff0c;支持枚举。…

win10笔记本在显示设置中不慎将主显示器禁用掉导致开机黑屏的解决方案

因为笔记本电脑的显示扩展接口有问题&#xff0c;所以在电脑开机之后&#xff0c;会误识别出几个不存在的扩展屏幕&#xff0c;所以我就想从显示设置中将这几个误识别出来的扩展屏幕禁用掉&#xff08;不然鼠标总是移动到主屏幕边界之外的地方&#xff09;&#xff0c;在显示设…

RabbitMQ介绍及搭建

架构 RabbitMQ是实现了高级消息队列协议&#xff08;AMQP&#xff09;的开源消息代理软件&#xff0c;使用erlang语言编写&#xff0c;依赖Erlang环境运行。 Broker&#xff1a;运行消息队列服务进程的节点&#xff0c;包含Exchange、Queue&#xff1b; Producer&#xff1a;消…

蓝桥杯刷题总结(Python组)

1、蛇形矩阵 解题思路&#xff1a;每次赋值后都对方向进行改变&#xff0c;一般上下左右就是&#xff08;-1&#xff0c;0&#xff09;&#xff0c;&#xff08;0&#xff0c;1&#xff09;&#xff0c;&#xff08;1&#xff0c;0&#xff09;&#xff0c;&#xff08;0&…

TSINGSEE青犀AI智能分析网关V4酿酒厂安全挂网AI检测算法

在酿酒行业中&#xff0c;安全生产一直是企业经营中至关重要的一环。为了确保酒厂生产过程中的安全&#xff0c;TSINGSEE青犀AI智能分析网关V4的安全挂网AI检测算法发挥了重要作用。 TSINGSEE青犀AI智能分析网关V4的安全挂网检测算法是针对酒厂里酒窖挂网行为进行智能检测与识…

爬虫 Day2

resp.close()#关掉resp 一requests入门 &#xff08;一&#xff09; 用到的网页&#xff1a;豆瓣电影分类排行榜 - 喜剧片 import requestsurl "https://movie.douban.com/j/chart/top_list" #参数太长&#xff0c;重新封装参数 param {"type": "…

【Qt问题】使用QSlider创建滑块小部件无法显示

问题描述&#xff1a; 使用QSlider创建滑块小部件用于音量按钮的时候&#xff0c;无法显示&#xff0c;很奇怪&#xff0c;怎么都不显示 一直是这个效果&#xff0c;运行都没问题&#xff0c;但是就是不出现。 一直解决不了&#xff0c;最后我在无意中&#xff0c;在主程序中…

LLM 面试知识点——模型基础知识

1、主流架构 目前LLM(Large Language Model)主流结构包括三种范式,分别为Encoder-Decoder、Causal Decoder、Prefix Decode。对应的网络整体结构和Attention掩码如下图。 、 各自特点、优缺点如下: 1)Encoder-Decoder 结构特点:输入双向注意力,输出单向注意力。 代表…

MySQL中数据库表的监控

MySQL中数据库表的监控 &#xff08;1&#xff09;查看数据库中当前打开了哪些表&#xff1a;show OPEN TABLES &#xff0c;如图6-1-5所示。另外&#xff0c;还可以通过show OPEN TABLES where In_use > 0过滤出当前已经被锁定的表。 查看数据库中表的状态&#xff1a;SHO…

css3 实现html样式蛇形布局

文章目录 1. 实现效果2. 实现代码 1. 实现效果 2. 实现代码 <template><div class"body"><div class"title">CSS3实现蛇形布局</div><div class"list"><div class"item" v-for"(item, index) …

聚类分析 | Matlab实现基于NNMF+DBO+K-Medoids的数据聚类可视化

聚类分析 | Matlab实现基于NNMFDBOK-Medoids的数据聚类可视化 目录 聚类分析 | Matlab实现基于NNMFDBOK-Medoids的数据聚类可视化效果一览基本介绍程序设计参考资料 效果一览 基本介绍 NNMFDBOK-Medoids聚类&#xff0c;蜣螂优化算法DBO优化K-Medoids 非负矩阵分解&#xff08…