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

news2024/11/17 1:39:27

        在做十四届题目之前,常常听学长说,十四届以前拿省一真的是右手就行,并不相信,在经历十四届痛苦的大量修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;
		}
		else
			ucLed&=~0x01;
	
		if(Disp_mode==1)
		{
			ucLed&=~0x03;
			ucLed|=0x02;
		}
		else
			ucLed&=~0x02;
	}


}

第二类

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

第一个 

变量

为闪烁服务

逻辑判断

Led部分 

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

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

第二个

变量

逻辑判断

 

LED部分 

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

六、结言

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

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

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

相关文章

【】(综合练习)博客系统

在之前的学些中&#xff0c;我们掌握了Spring框架和MyBatis的基本使用&#xff0c;接下来 我们就要结合之前我们所学的知识&#xff0c;做出一个项目出来 1.前期准备 当我们接触到一个项目时&#xff0c;我们需要对其作出准备&#xff0c;那么正规的准备是怎么样的呢 1.了解需求…

基于傅里叶描述子的手势动作识别,Matlab实现

博主简介&#xff1a; 专注、专一于Matlab图像处理学习、交流&#xff0c;matlab图像代码代做/项目合作可以联系&#xff08;QQ:3249726188&#xff09; 个人主页&#xff1a;Matlab_ImagePro-CSDN博客 原则&#xff1a;代码均由本人编写完成&#xff0c;非中介&#xff0c;提供…

ubuntu22.04物理机双系统手动分区

ubuntu22.04物理机双系统手动分区 文章目录 ubuntu22.04物理机双系统手动分区1. EFI系统分区2. 交换分区3. /根分区4. /home分区分区后的信息 手动分区顺序&#xff1a;EFI系统分区(/boot/efi)、交换分区(/swap)、/根分区、/home分区。 具体参数设置&#xff1a; 1. EFI系统分…

02. 【Android教程】开发环境搭建

在学习 Android 应用开发之前&#xff0c;我们先要完成环境的搭建&#xff0c;它将帮助我们将 Java 代码编译打包生成最终的 Android 安装包。本教程在 Mac 下完成安装&#xff0c;Windows 和 Linux 步骤类似&#xff0c;不同之处会着重区分。 1. 文件清单 Java SE Developmen…

JVM的知识

什么是JVM 1.JVM&#xff1a; JVM其实就是运行在 操作系统之上的一个特殊的软件。 2.JVM的内部结构&#xff1a; &#xff08;1&#xff09;因为栈会将执行的程序弹出栈。 &#xff08;2&#xff09;垃圾99%的都是在堆和方法区中产生的。 类加载器&#xff1a;加载class文件。…

芯片中小公司ERP系统的业务流程:揭秘数字化管理的新篇章

随着信息技术的飞速发展&#xff0c;ERP(企业资源规划)系统已成为众多企业实现数字化管理的重要工具。对于芯片中小公司而言&#xff0c;ERP系统更是提升运营效率、优化资源配置的关键所在。那么&#xff0c;芯片中小公司的ERP系统究竟是如何运作的呢?让我们一同揭开其业务流程…

Spatialite坐标投影并计算面积

将坐标转为WGS_1984_UTM_Zone_48N&#xff08;32648&#xff09;后再计算其面积&#xff1a; -- 转换坐标系并计算面积&#xff08;平方米&#xff09; SELECT ST_Area(ST_Transform(GeomFromText(POLYGON((106.763 26.653, 106.763 26.626, 106.815 26.625, 106.809 26.666, …

我们使用 Postgres 构建多租户 SaaS 服务时踩的坑

原文 Our Multi-tenancy Journey with Postgres Schemas and Apartment。这篇和之前发出的「如何使用 Postgres 对一个多租户应用分片」相呼应。 多租户 (Multip-tenancy) 是当下的热门话题。我对多租户应用程序的定义是一个能够服务于多个客户的软件系统&#xff0c;每个客户都…

有名的爬虫框架 colly 的特性及2个详细采集案例

一. Colly概述 前言&#xff1a;colly 是 Go 实现的比较有名的一款爬虫框架&#xff0c;而且 Go 在高并发和分布式场景的优势也正是爬虫技术所需要的。它的主要特点是轻量、快速&#xff0c;设计非常优雅&#xff0c;并且分布式的支持也非常简单&#xff0c;易于扩展。 框架简…

javaSSM游泳馆日常管理系统IDEA开发mysql数据库web结构计算机java编程maven项目

一、源码特点 IDEA开发SSM游泳馆日常管理系统是一套完善的完整企业内部系统&#xff0c;结合SSM框架和bootstrap完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;MAVEN方式加载&#xff0c;系统具有完整的源代码和…

疫情居家办公OA系统设计与实现| Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)

本项目包含可运行源码数据库LW&#xff0c;文末可获取本项目的所有资料。 推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含java&#xff0c;…

day04套餐管理模块所有业务功能代码开发

目录 1. 新增套餐1.1 需求分析和设计1.2 代码实现1.2.1 DishController1.2.2 DishService1.2.3 DishServiceImpl1.2.4 DishMapper1.2.5 DishMapper.xml1.2.6 SetmealController1.2.7 SetmealService1.2.8 SetmealServiceImpl1.2.9 SetmealMapper1.2.10 SetmealMapper.xml1.2.11…

shell脚本入门练习(非常详细)零基础入门到精通,收藏这一篇就够了

【脚本1】打印形状 打印等腰三角形、直角三角形、倒直角三角形、菱形 #!/bin/bash \# 等腰三角形 read \-p "Please input the length: " n for i in \seq 1 $n\ do for ((j\$n;j>i;j--)) do echo \-n " " done for m in \seq 1 $i\ do…

希尔伯特-黄变换(Hilbert-Huang Transform, HHT)详解

目录 经验模态分解&#xff08;EMD&#xff09; 希尔伯特谱分析&#xff08;HSA&#xff09; 定义 连续时信号的Hilbert变换定义 离散时信号的Hilbert变换定义 解析信号定义&#xff1a; 解析信号的傅里叶变换 解析信号的重要意义 解析信号的属性 希尔伯特--黄变换&#xff08;…

LabVIEW电动汽车直流充电桩监控系统

LabVIEW电动汽车直流充电桩监控系统 随着电动汽车的普及&#xff0c;充电桩的安全运行成为重要议题。通过集成传感器监测、单片机技术与LabVIEW开发平台&#xff0c;设计了一套电动汽车直流充电桩监控系统&#xff0c;能实时监测充电桩的温度、电压和电流&#xff0c;并进行数…

Geohash编码

1. 简介 地理位置&#xff08;经纬度坐标对&#xff09;编码为字母数字串&#xff0c;将空间分为网格形状每个网格使用一个编码&#xff0c;是Z阶曲线的众多应用之一。 2. 编码原理 &#xff08;1&#xff09; 首先根据区域划分的精度大小选择Geohash的字符串的长度&#xf…

[DDD] ValueObject的一种设计落地及应用

目录 前言一、ValueObject二、设计2.1 接口2.2 单一值ValueObject2.3 单一字符串ValueObject 三、实现3.1 示例3.1.1 PhoneNumber3.1.2 SocialCreditCode 四、使用4.1 异常处理4.2 Json 反/序列化4.2.1 请求体4.2.2 HTTP接口4.2.3 用例 4.3 JPA/MyBatis4.3.1 Converter或TypeHa…

HarmonyOS实战开发-如何使用首选项能力实现一个简单示例。

介绍 本篇Codelab是基于HarmonyOS的首选项能力实现的一个简单示例。实现如下功能&#xff1a; 创建首选项数据文件。将用户输入的水果名称和数量&#xff0c;写入到首选项数据库。读取首选项数据库中的数据。删除首选项数据文件。 最终效果图如下&#xff1a; 相关概念 首选…

第二证券|基本面向好预期强化 全球资本加紧布局A股

开年以来&#xff0c;在我国经济上升向好的态势持续稳固增强的大布景下&#xff0c;结合各方努力&#xff0c;A股商场企稳上升痕迹明显。受一系列稳定商场预期政策出台的加持&#xff0c;全球本钱正在加速布局A股商场。 业界人士指出&#xff0c;当时我国本钱商场依然具有明显…

QT(6.5) cmake构建C++编程,调用python (已更新:2024.3.23晚)

一、注意事项 explicit c中&#xff0c;一个参数的构造函数(或者除了第一个参数外其余参数都有默认值的多参构造函数)&#xff0c;承担了两个角色&#xff0c;构造器、类型转换操作符&#xff0c; c提供关键字explicit&#xff0c;阻止转换构造函数进行的隐式转换的发生&#…