新台阶——蓝桥杯单片机省赛第十四届程序设计题目

        在做十四届题目之前,常常听学长说,十四届以前拿省一真的是右手就行,并不相信,在经历十四届痛苦的大量修bug和优化之后,或许学长的话真说对了几分。话不多说,我们开始一起完成单片机第十四届程序设计题目。

代码在这:

链接:https://pan.baidu.com/s/1E7S1zt6E9KrUoIRGVt-eqQ?pwd=1234 
提取码:1234 //这个注释比较多但是如果出现小瑕疵问题,可以用下面那个(因为懒得改全部hh

下面是第一次默写和优化后的代码,上面的注释比较多

链接:https://pan.baidu.com/s/1PakTSsUwwlIMly_FWpR9RQ?pwd=1234 
提取码:1234

一,变化

        因为之前都是使用的keil5来写,但是笔者这里比赛需要使用到keil4,所以也跟你们分享一下。

        芯片选择这里就只能点左下角这个区域,其他地方都是黑的,点击红框,找到STC89C52点击OK就行。

        按照笔者之前三大模板的文章写到这里,我们已经分好了文件夹、勾选了生成.hex文件、错误miss、和最重要的路径添加。

        在keil4中,添加.c文件不能右键就添加,而是键盘Ctrl+N创建一个新文件,再Ctrl+S保存修改成.c文件。

        出现的bug(下面第一张图)

        新bug,不过是笔者的低级错误,宏定义后面加了分号就会这样,数组定义会错误,就说指针类型错误了

唯一模板和底层改动的地方

        onewire底层的修改,为了方便显示小数

二、三大模板和底层驱动的完善

        除了定时器不能单独测试,其余文件的函数都是可以独立检测的,来验证你写的是否正确。这一步是所有代码的基础,所以一定要踏实地测试完防止后面还要倒回来修bug。

三、老规矩,从按键部分开始写

变量

        清除数据的函数先放着不写,到时候定义完全部变量再写也来的及。然后模板那里使用检测到一个就返回键码值的那一套模板,上一篇文章有讲。因为这个效果比较好。

勘误:应该是长按2s,那定时器那里改成>=2000和锁死在2001,把按键那里也改改就行了

计时 

 模式切换

void key_proc(void)
{if(key_dly)return;key_now=key_read();key_down=key_now&(key_now^key_old);key_up=(~key_now)&(key_now^key_old);key_old=key_now;if(key_down==4){Disp_mode=(++Disp_mode)%3;huixian_mode=0;}if((Disp_mode==1)&&(key_down==5)){huixian_mode=(++huixian_mode)%3;		}if(Disp_mode==2){if(key_down==8){para_temperature=(++para_temperature>99)?99:para_temperature;										 }if(key_down==9){para_temperature=(--para_temperature>254)?0:para_temperature;										 }}if((Disp_mode==1)&&(huixian_mode==2)){if(key_down==9)long_press_flag=1;if(key_up==9){if(tims_3s>=3000)Clear_data();long_press_flag=tims_3s=0;}	}
}

四、第二步写数码管(最难最多得分点的部分)

 1.框架

变量

        我们先不管最大值平均值这些怎么计算,我们就先根据模式变量将要显示的几个界面写好。

void seg_proc(void)
{
// 	ui temperature_10x,humi_10x;//也是十倍,就是用来计算平均值 if(uiseg_dly)return;if(Disp_mode==0){Rtc_read(ucRtc);sprintf(seg_char,"%02d-%02d-%02d",(ui)ucRtc[0],(ui)ucRtc[1],(ui)ucRtc[2]);}else if(Disp_mode==1){if(huixian_mode==0){sprintf(seg_char,"C %02d-%02d.%1d",(ui)max_temperature_10x/10,(ui)aver_temperature_10x/10,(ui)aver_temperature_10x%10);}if(huixian_mode==1){sprintf(seg_char,"H %02d-%02d.%1d",(ui)max_humi_10x/10,(ui)aver_humi_10x/10,(ui)aver_humi_10x%10);}if(huixian_mode==2){sprintf(seg_char,"F%02d%02d-%02d",(ui)tri_count,(ui)tri_time[0],(ui)tri_time[1]);	}	}else if(Disp_mode==2)sprintf(seg_char,"P     %02d",(ui)para_temperature);//	sprintf(seg_char,"E  %02d-%02d",(ui)temperature_10x/10,(ui)humi_10x/10);
//	sprintf(seg_char,"E  %02d-AA",(ui)temperature_10x/10);Seg_Tran(seg_char,seg_buf);
}

        这样写好之后,实验现象按键正常,模式切换正常,不同模式显示不同内容,只有时钟显示界面不是0和参数界面是默认30,其余都是显示0(很烦人的一个毛病,笔者在之前的代码,时间显示界面是稳定的,但是此次再写,尽管代码一样,但分钟十位还是一直在1和5之间闪烁,到0时0分0秒之后就没什么问题,换成不是59的分钟也没什么问题,不知道你们的板子会不会出现跟我一样的毛病)

2.开始做题

        直到现在,我们前面写那么多东西,都是可以靠熟练度写完的,所以大家对于基础模板一定要熟练掌握,我们现在看到题目中,这个采集部分是凌驾于我们所有逻辑之上的,也就说我们什么时候显示什么内容都会被它影响,那我们就可以先写这个触发检测代码,根据这个代码,创建标志位,来告诉单片机什么时候该显示什么内容。

       采集部分的判断和界面切换

        下面就是采集部分的判断和界面切换的判断(代码看着有点多,但是到这一步就写了一个光强的判断和计时,其余都是上一步的框架,然后提一嘴,定时器一定是12T不然检测到的光强极其不稳定。(因为笔者找这个bug找了好久))

void seg_proc(void)
{uc tri_count_old;uc light_val_old,light_val;ui temperature_10x=0,humi_10x;//也是十倍,就是用来计算平均值 if(uiseg_dly)return;light_val=pcf8591_Adc(1);if((light_val_old>50)&&(light_val<50)&&(tri_flag==0)){tri_flag=1;if(++tri_count==100)tri_count=99;tri_count_old=tri_count;		}if((tri_flag==1)&&(time_3s>=3000))tri_flag=0;light_val_old=light_val;//判断完之后再赋值	if(tri_flag==1){temperature_10x=(rd_temperature()*10);if(humi_10x==0)//无效数据{tri_count=tri_count_old-1;sprintf(seg_char,"        ");sprintf(seg_char,"E  %02d-AA",(ui)temperature_10x/10);	}else//有效数据{sprintf(seg_char,"E  %02d-%02d",(ui)temperature_10x/10,(ui)humi_10x/10);		}}else if(tri_flag==0){if(Disp_mode==0){Rtc_read(ucRtc);sprintf(seg_char,"%02d-%02d-%02d",(ui)ucRtc[0],(ui)ucRtc[1],(ui)ucRtc[2]);}else if(Disp_mode==1){if(huixian_mode==0){sprintf(seg_char,"C %02d-%02d.%1d",(ui)max_temperature_10x/10,(ui)aver_temperature_10x/10,(ui)aver_temperature_10x%10);}if(huixian_mode==1){sprintf(seg_char,"H %02d-%02d.%1d",(ui)max_humi_10x/10,(ui)aver_humi_10x/10,(ui)aver_humi_10x%10);}if(huixian_mode==2){sprintf(seg_char,"F%02d%02d-%02d",(ui)tri_count,(ui)tri_time[0],(ui)tri_time[1]);	}	}else if(Disp_mode==2)sprintf(seg_char,"P     %02d",(ui)para_temperature);}Seg_Tran(seg_char,seg_buf);
}

以上的内容是可以检测的,模式切换正常,采集触发也是可以正常使用。

最大值和平均值的计算

如果触发次数为0则显示标识符

        满足上面题目的要求就下面那些要加上的代码,不过还没写湿度计算部分,还没法检测。

Ne555测频率转湿度和之前没写的清除数据操作封装函数

变量和计算函数封装

清除数据函数和读取温度常规延时

定时器中的脉冲次数计算(定时器0的配置之前文章有讲) 

一个小小的优化 

        测试实验现象:完成了除led部分之外所有的题目要求,并且不会出现小瑕疵比如说数据严重错误的情况。(这就是你们写到这里之后要达到的效果)然后因为还要有一个处于温湿度界面就按键失效的要求嘛,就在if(key_down==4)上一行加上if(tri_flag==1)return;就行了

五、最简单的led部分

第一类

        同一类在点亮前要将不亮的全部熄灭。(所以笔者会将其分类)

void led_proc(void)
{if(led_dly)return;if(tri_flag==1){ucLed&=~0x03;ucLed|=0x04;}else if(tri_flag==0){ucLed&=~0x04;if(Disp_mode==0){ucLed&=~0x03;ucLed|=0x01;}elseucLed&=~0x01;if(Disp_mode==1){ucLed&=~0x03;ucLed|=0x02;}elseucLed&=~0x02;}}

第二类

        这一类都是由标志位点亮,标志位被置1就点亮,是独立的。

第一个 

变量

为闪烁服务

逻辑判断

Led部分 

        实验现象:触发采集,如果温度数据大于温度参数,则L4闪烁,间隔100ms,(这个是直到下一次温度数据低于温度参数时才会停止闪烁,如果想让其在采集的时候闪,那就可以在tri_flag=0时将warn_flag置0就行了)

然后那个数据错误的点灯就不拿出来讲了,应该都知道在哪进行置1和置

第二个

变量

逻辑判断

 

LED部分 

        实验现象:完成题目中所有的要求,并且没有小问题,小瑕疵。(有的话就再优化,笔者板子上没啥问题)

六、结言

至此,我们总算是完成了第十四届的省题,之所以说是新台阶,是因为难度较之前真的有天壤之别,体现在变量多(这个时候会出现大家陌生的内存空间不足bug要大家去合理节省内存空间),逻辑判断多,界面多,底层驱动使用多,模块多等等,这些对于要备战今年蓝桥杯省赛的读者来说,是向国一迈进的一个坎。最后祝愿大家能取得好成绩。

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

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

相关文章

Linux环境基础开发工具yum,vim使用

目录 1.Linux 软件包管理器 yum1.1什么是软件包1.2关于 rzsz1.3注意事项1.4查看软件包1.5如何安装软件1.6如何卸载软件 2.Linux开发工具2.1Linux编辑器-vim使用2.1.1vim的基本概念2.1.2vim的基本操作2.1.3vim正常模式命令集2.1.4vim末行模式命令集2.1.5vim操作总结 2.2简单vim配…

删除数组中的指定元素(了解如何删除数组中的指定元素,并返回一个新的数组,看这一篇就足够了!)

前言&#xff1a;有时候我们会遇到要在数组中删除指定元素&#xff0c;但是不能创建新的数组&#xff0c;那么这个时候应该如何操作呢&#xff1f; ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSDN博客 废话不多讲&#xff0c;让我们…

RuoYi-Vue-Plus(登录流程-验证码生成)

一、登录流程 1- 进入登录页面&#xff0c;调用 com.ruoyi.web.controller.common.CaptchaController 类中的 captchaImage 方法&#xff0c;生成base64的图片 以及 UUID 2- 提交 登录信息 验证码 uuid 比对 错误&#xff1a;返回错误信息&#xff0c;删除缓存的验证码 成功…

「MySQL」数据库约束

&#x1f387;个人主页&#xff1a;Ice_Sugar_7 &#x1f387;所属专栏&#xff1a;数据库 &#x1f387;欢迎点赞收藏加关注哦&#xff01; 数据库约束 &#x1f349;约束类型&#x1f34c;NOT NULL&#x1f34c;UNIQUE&#x1f34c;DEFAULT&#x1f34c;主键&#x1f34c;外键…

layui框架实战案例(25):laydate中mark的数据后端生成

mark&#xff0c;自定义日期标记。该属性是对 calendar 属性的进一步延伸&#xff0c;灵活度更高。属性可批量设置多个日期标记&#xff0c;如&#xff1a; mark: {0-10-14: 生日, //每年每月的某一天0-0-10: 工资, // 每月 10 号2008-8-8: 开幕, // 指定的日期 }其中日期的格式…

【微服务】Spring Boot 版本升级到 2.7.18

前言 目前项目上扫描出一些 Java 依赖的代码漏洞&#xff0c;需要对现有依赖版本升级&#xff0c;记录一下遇到的问题。 <spring-boot.version>2.3.2.RELEASE</spring-boot.version> <spring-cloud.version>Hoxton.SR9</spring-cloud.version> <s…

亚马逊服务器ssh以及scp

ssh awspass.pem为创建服务器时创建的密钥&#xff0c;ubuntu用户 ssh -i "awspass.pem" ubuntuipscp scp -i "awspass.pem" -r dist/* ubuntuip:/home/ubuntu/

菱形继承的问题以及解决方法

大家好&#xff1a; 衷心希望各位点赞。 您的问题请留在评论区&#xff0c;我会及时回答。 菱形继承概念 两个派生类继承同一个基类 又有一个类同时继承这两个派生类 这种继承被称为菱形继承&#xff0c;或者钻石继承。 基类A同时派生出类B和类C&#xff0c;派生类D又同时继…

基于ARM 的Linux系统的交叉编译

返回&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;在 MacOS 中安装 下一篇&#xff1a;MultiArch与Ubuntu/Debian 的交叉编译 警告 本教程可以包含过时的信息。 此步骤已在 Ubuntu Linux 12.04 上进行了测试&#xff0c;但应…

NOIP2011 数字反转 灰常经典的一道

[NOIP2011 普及组] 数字反转 - 洛谷https://www.luogu.com.cn/problem/P1307 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);int Nsc.nextInt();int fanzhuanNumfanZhuan(N);System.out.print(fa…

WSL使用

WSL使用 WSL安装和使用 Termianl和Ubuntu的安装 打开Hype-V虚拟化配置Microsoft Store中搜索Window Terminal并安装Microsoft Store中搜索Ubuntu, 选择安装Ubuntu 22.04.3 LTS版本打开Window Terminal选择Ubuntu标签栏, 进入命令行 中文输入法安装 查看是否安装了fcitx框架…

二分图

数据结构、算法总述&#xff1a;数据结构/算法 C/C-CSDN博客 二分图&#xff1a;节点由两个集合组成&#xff0c;且两个集合内部没有边的图。换言之&#xff0c;存在一种方案&#xff0c;将节点划分成满足以上性质的两个集合。 染色法 目的&#xff1a;验证给定的二分图是否可…

springboot3使用​自定义注解+Jackson优雅实现接口数据脱敏

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 &#x1f30a;山高路远&#xff0c;行路漫漫&#xff0c;终有归途 目录 写在前面 内容简介 实现思路 实现步骤 1.自定义脱敏注解 2.编写脱敏策略枚举类 3.编写JSON序列化实现 4.编写测…

日常刷题之77-组合

题目 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案 提示&#xff1a;假设 n5,k3 就是需要组合出来&#xff0c;长度3且内容数据是在[1,n]这个区间内的所有可能得组合 同时一个组合里面内个数字只能出现一次&#…

亮数据代理IP轻松解决爬虫数据采集痛点

文章目录 一、爬虫数据采集痛点二、为什么使用代理IP可以解决&#xff1f;2.1 爬虫和代理IP的关系2.2 使用代理IP的好处 三、亮数据代理IP的优势3.1 IP种类丰富3.1.1 动态住宅代理IP3.1.2 静态住宅代理IP3.1.3 机房代理IP3.1.4 移动代理IP 3.2 高质量IP全球覆盖3.3 超级代理服务…

Java标签提高for循环运行效率,减少资源开销

一&#xff0c;Java标签提高for循环运行效率,减少资源开销 少说先看代码再讲解 List<Long> lefts new ArrayList<>(); List<Long> rights new ArrayList<>(); lefts.add(0L); lefts.add(1L); lefts.add(2L); lefts.add(3L); lefts.add(4L); lefts.…

修改Linux系统时间与网络同步

文章目录 1、安装ntpdate2、修改时区3、设置系统时间与网络时间同步4、将系统时间写入硬件时间 1、安装ntpdate # Red Hat和Cent OS系统 sudo yum install ntpdate # 乌班图 sudo apt-get install ntpdate2、修改时区 1&#xff09;运行tzselect tzselect2&#xff09;选择A…

52、Qt/窗口、常用类、ui相关学习20240321

一、使用Qt 自由发挥登录窗口的应用场景&#xff0c;实现一个登录窗口界面。 要求&#xff1a; 1. 需要使用Ui界面文件进行界面设计 2. ui界面上的组件相关设置&#xff0c;通过代码实现 3. 需要添加适当的动图。 代码&#xff1a; #include "widget.h" #incl…

两台不同账号同一区域阿里云服务器如何实现内网互通?

登录阿里云平台 [开通peer对等] 点击右上角的控制台&#xff0c;然后进行搜索专有网络VPC。 点击进入专有网络VPC界面操作步骤如下&#xff1a; &#xff08;1&#xff09;点击VPC对等连接&#xff0c;然后开通VPC对等连接后创建对等连接。 &#xff08;2&#xff09;在另…

【计算机】——51单片机——持续更新

单片机是一种内部包含CPU、存储器和输入/输出接口等电路的集成电路&#xff08;IC芯片&#xff09; 单片机是单片微型计算机&#xff08;Single Chip Microcomputer&#xff09;的简称&#xff0c;用于控制领域&#xff0c;所以又称为微型控制器&#xff08;Microcontroller U…