蓝桥杯单片机第14届省赛本科组客观题(赛后完美实现版)

目录

前言

赛程难度:

代码框架:

细节归纳:

主观题题目:

代码部分:

代码资源:


前言

首次参加的蓝桥杯比赛,发挥一般以为寄了,没想到活了,于是有了今天的这篇文章。

贴个图证实一下

8fc18f882e054a68bd445338da2271bb.jpeg


然后给大家看一下工程的完成情况↓↓

蓝桥杯第14届省赛本科组

赛程难度:

相比于往届的比赛难度真的上升了,逻辑难度大概提升了两个档次,但是整个工程组成的繁琐度提高了三个档次的样子,这个看个人感受吧,取决于往届的比赛你做了多少,也看个人吧。

代码框架:

说下这份主观题,有哪些我觉得需要注意的点。

1.注意很多不同的.C文件和main.c文件之间的变量传递。

2.整个过程我一开始使用的是3个定时器,但是我发现这样定时器的中断优先级很难把握,整个工程也很臃肿,所以在NE555频率检测中用到的两个定时器,选定时器1作为整个过程的标志位检测及LED状态更新。

3.在主函数中进行按键扫描,数码管显示,光敏采集,

细节归纳:

这份题目我觉的难度还是很高的,湿度数据的采集、数码管显示的时候很多的变量、显示的精度、不同类型的变量之间的运算精度、LED的控制、中断函数的逻辑编写、非常推荐准备下一届的去自己写一写,肯定有很多的收获。

主观题题目:

1e552a4c3a464261a8079d8d02e7daca.png


fe00cee31bbf4178833d0ec397b22125.png


3040ed1fbcbb4a43b38d19ad908e4810.png


f3920fd90fb440d7b1e981e64755a590.png


d467d9ab77c442f980b8b899306fdf21.png

代码部分:

main.c

#include <STC15F2K60S2.H>
#include <ds1302.H>
#include <seg.H>
#include <base.H>
#include <onewire.H>
#include <ne555.H>
#include <iic.H>

bit i=0,j=0,L4=0;
extern unsigned char Time[7];
extern unsigned int count,count_s,dat;
unsigned char S4_Flag=0,Set_Temp=30,S5_Flag=0,Led_Run=0;
unsigned long Temp_Value,Sum_Temp,Last_Temp,Last_Temp_1;
unsigned int Humidity_Value,Sum_Humidity,Last_Humidity,Last_Humidity_1;
unsigned char Count_chufa=0,add_1=0,Led_L5=0;
unsigned char Flag_2=0,Count_Last=0,Last_Com=0;
unsigned char Light=0,Flag_Light=0,Flag_L6=0;
unsigned char Time_1,Time_2,Dis_Temp_Humidity,Flag_Temp_Humidity;



void Delay5ms()		//@12.000MHz
{
	unsigned char i, j;

	i = 59;
	j = 90;
	do
	{
		while (--j);
	} while (--i);
}
void Display_Time(void)  //显示时间
{
	Seg(1,Time[2]/10);
	Delay2ms();
	Seg(2,Time[2]%10);
	Delay2ms();
	Seg(3,21);
	Delay2ms();
	Seg(4,Time[1]/10);
	Delay2ms();
	Seg(5,Time[1]%10);
	Delay2ms();
	Seg(6,21);
	Delay2ms();
	Seg(7,Time[0]/10);
	Delay2ms();
	Seg(8,Time[0]%10);
	Delay2ms();
}
void Display_Back_Temp(void)  //c 显示温度
{
	if(Count_chufa==0)
	{
	Seg(1,22);
	Delay2ms();
	Seg(2,20);
	Delay2ms();
	Seg(3,20);
	Delay2ms();
	Seg(4,20);
	Delay2ms();
	Seg(5,20);
	Delay2ms();
	Seg(6,20);
	Delay2ms();
	Seg(7,20);
	Delay2ms();
	Seg(8,20);
	Delay2ms();
	}else
	{
	Seg(1,22);
	Delay2ms();
	Seg(2,20);
	Delay2ms();
	Seg(3,Set_Temp/10);
	Delay2ms();
	Seg(4,Set_Temp%10);
	Delay2ms();
	Seg(5,21);
	Delay2ms();
	Seg(6,(Sum_Temp/Count_chufa)/100000);
	Delay2ms();
	Seg(7,(Sum_Temp/Count_chufa)%100000/10000+10);
	Delay2ms();
	Seg(8,(Sum_Temp/Count_chufa)%10000/1000);
	Delay2ms();
	}
}
void Display_Set_Value(void)//p 设定温度
{
	Seg(1,24);
	Delay2ms();
	Seg(2,20);
	Delay2ms();
	Seg(3,20);
	Delay2ms();
	Seg(4,20);
	Delay2ms();
	Seg(5,20);
	Delay2ms();
	Seg(6,20);
	Delay2ms();
	Seg(7,Set_Temp/10);
	Delay2ms();
	Seg(8,Set_Temp%10);
	Delay2ms();
}
void Display_Back_Humidity(void)  //h 湿度
{
	if(Count_chufa==0)
	{
	Seg(1,26);
	Delay2ms();
	Seg(2,20);
	Delay2ms();
	Seg(3,20);
	Delay2ms();
	Seg(4,20);
	Delay2ms();
	Seg(5,20);
	Delay2ms();
	Seg(6,20);
	Delay2ms();
	Seg(7,20);
	Delay2ms();
	Seg(8,20);
	Delay2ms();
	}else
	{
		if(Humidity_Value==0)
			{
			Seg(1,26);
			Delay2ms();
			Seg(2,20);
			Delay2ms();
			Seg(3,6);
			Delay2ms();
			Seg(4,8);
			Delay2ms();
			Seg(5,21);
			Delay2ms();
			Seg(6,23);
			Delay2ms();
			Seg(7,23); //a
			Delay2ms();
			Seg(8,23);
			Delay2ms();
			}
			else{
	Seg(1,26);
	Delay2ms();
	Seg(2,20);
	Delay2ms();
	Seg(3,6);
	Delay2ms();
	Seg(4,8);
	Delay2ms();
	Seg(5,21);
	Delay2ms();
	Seg(6,(Sum_Humidity/Count_chufa)/100);
	Delay2ms();
	Seg(7,(Sum_Humidity/Count_chufa)%100/10+10);
	Delay2ms();
	Seg(8,(Sum_Humidity/Count_chufa)%10);
	Delay2ms();
			}
	}
}
void Display_Back_Time(void)  //f 记录采集时间
{
	if(Count_chufa==0)
	{
	Seg(1,27);
	Delay2ms();
	Seg(2,Count_chufa/10);
	Delay2ms();
	Seg(3,Count_chufa%10);
	Delay2ms();
	Seg(4,20);
	Delay2ms();
	Seg(5,20);
	Delay2ms();
	Seg(6,20);
	Delay2ms();
	Seg(7,20);
	Delay2ms();
	Seg(8,20);
	Delay2ms();
	}
	else{
	Seg(1,27);
	Delay2ms();
	Seg(2,Count_chufa/10);
	Delay2ms();
	Seg(3,Count_chufa%10);
	Delay2ms();
	Seg(4,Time_1 / 10);
	Delay2ms();
	Seg(5,Time_1 % 10);
	Delay2ms();
	Seg(6,21);
	Delay2ms();
	Seg(7,Time_2 / 10);
	Delay2ms();
	Seg(8,Time_2 % 10);
	Delay2ms();
	}
}

void Temp_Humidity(void)//e 温湿度数据
{
	if(Humidity_Value==0)
	{
	Seg(1,25);
	Delay2ms();
	Seg(2,20);
	Delay2ms();
	Seg(3,20);
	Delay2ms();
	Seg(4,Temp_Value/100000);
	Delay2ms();
	Seg(5,Temp_Value%100000/10000);
	Delay2ms();
	Seg(6,21);
	Delay2ms();
	Seg(7,23);
	Delay2ms();
	Seg(8,23);
	Delay2ms();
	}
	else{
	Seg(1,25);
	Delay2ms();
	Seg(2,20);
	Delay2ms();
	Seg(3,20);
	Delay2ms();
	Seg(4,Temp_Value/100000);
	Delay2ms();
	Seg(5,Temp_Value%100000/10000);
	Delay2ms();
	Seg(6,21);
	Delay2ms();
	Seg(7,Humidity_Value/100);
	Delay2ms();
	Seg(8,Humidity_Value%100/10);
	Delay2ms();
	}
}


void All_Display(void)//显示模式切换
{
	if(Dis_Temp_Humidity==1)
	{
		Temp_Humidity();
	}
	else
	{
		if(S4_Flag == 0)
		{
			Display_Time();
		}
		if(S4_Flag == 1)
		{
			if(S5_Flag==0)
			{
				Display_Back_Temp();
			}
			if(S5_Flag==1)
			{
				Display_Back_Humidity();
			}
			if(S5_Flag==2)
			{
				Display_Back_Time();
			}
		}
		if(S4_Flag == 2)
		{
			Display_Set_Value();
		}
	}
}


void Scan_Key(void)//按键扫描
{
	P32=0;P33=1;
	if(P44==0)
	{
		Delay5ms();
		while(P44==0)
		{
			All_Display();
		}
		if(S4_Flag==1)
		{
			S5_Flag++;
			S5_Flag %= 3;
		}
	}  //S5定义为“回显”按键,在记录回显界面下,按下 S5 按键,切换
	   //温度回显、湿度回显和时间回显三个子界面。S5 按键在时间界面无效。
	if(P42==0)
	{
		Delay5ms();
		while(P42==0)
		{
			All_Display();
			Flag_2=0;
		}
		Flag_2=1;
		if(S4_Flag==2)
		{
			Set_Temp--;
			if(Set_Temp==0)
			{
				Set_Temp=99;
			}
		}
	}  //S9定义为“减”按键,参数界面下,按下温度参数值减 1;
//时间回显子界面下,长按 S9 超过 2 秒后松开,清除所有已记录的数据,触
//发次数重置为 0。
	P32=1;P33=0;
	if(P44==0)
	{
		Delay5ms();
		while(P44==0)
		{
			All_Display();
		}
		S4_Flag++;
		S4_Flag %= 3;
		S5_Flag=0;
	}  //S4切换时间回显参数界面
	if(P42==0)
	{
		Delay5ms();
		while(P42==0)
		{
			All_Display();
		}
		if(S4_Flag==2)
		{
			Set_Temp++;
			if(Set_Temp==100)
			{
				Set_Temp=0;
			}
		}
	}  //S8定义为“加”按键,参数界面下,按下温度参数值加 1
	
	
}


void Recode_Last(void)//L6_完成数据的记录
{
	if(i==0)
	{
		Last_Temp=Temp_Value;
		Last_Humidity=Humidity_Value;
		i = 1;
	}
	else
	{
		Last_Temp_1=Temp_Value;
		Last_Humidity_1=Humidity_Value;
		i = 0;
	}
}
void Compare_Last(void)//L6_比对数据的结果
{
	if(j==0)
	{
		if(Temp_Value>Last_Temp && Humidity_Value>Last_Humidity)
		{
			Flag_L6=1;
		}
		else
		{
			Flag_L6=0;
		}
		j = 1;
	}
	else
	{
		if(Humidity_Value>Last_Humidity_1 && Temp_Value>Last_Temp_1)
		{
			Flag_L6=1;
		}
		else
		{
			Flag_L6=0;
		}
		j = 0;
	}
	
}
void Led(void)//LED控制
{
	P0=0xff;//先将P0口的灯都熄灭掉,再根据情况点亮灯,刷新速度够快的话,相当于都亮
	if(S4_Flag==0)
	{
		P0 &= 0xfe;//点亮L1
		Select_138(4);
	}
	
	if(S4_Flag==1)
	{
		P0=0xff;
		P0 &= 0xfd;//点亮L2
		Select_138(4);
	}
	
	if(S4_Flag==2)
	{
		P0 &= 0xfb;//点亮L3
		Select_138(4);
	}
	
	if(L4==1)
	{
		if(Led_Run==1)
		{
			P0 &= 0xf7;
			Select_138(4);
		}
		else
		{
			P0 |= 0x08;
			Select_138(4);
		}
	}
	
	if(Led_L5==1)
	{
		P0 &= 0xef;//点亮L5
		Select_138(4);
	}
	else
	{
		P0 |= 0x10;//关闭L5
		Select_138(4);
	}

	if(Flag_L6==1)
	{
		P0 &= 0xdf;//点亮L6
		Select_138(4);
	}
	else
	{
		P0 |= 0x20;//关闭L6
		Select_138(4);
	}
}

void Timer0_Service() interrupt 1
{
	count++;
}

void Timer1_Service() interrupt 3
{
	TH1 = (65535-50000)/256;         //50MS
	TL1 = (65535-50000)%256;
	count_s++;
	if(count_s == 20)
	{
		dat = count;
		count = 0;
		count_s = 0;
	}//NE555
	
	Get_Time();//获取时间
	
	if(P42==0)//长按两秒清除数据 50MS*40=2S
	{
		add_1++;
		if(add_1>=40)
		{
			Count_chufa=0;
			Flag_2=1;
			add_1=0;
		}
	}
	
	if(Flag_Light==0 && Light<120)//先采集数据,然后置标志位,
	{
		Flag_Light=1;
		if((Temp_Value*0.0001) > Set_Temp){L4=1;}else{L4=0;}
		if(Humidity_Value==0){Led_L5=1;}else{Led_L5=0;}//L5控制位
		Time_1 = Time[2];//小时
		Time_2 = Time[1];//分钟
		Count_chufa++;
		Recode_Last();
		if(Count_chufa>=2){Compare_Last();}//控制L6
		Dis_Temp_Humidity=1;//显示界面切换
	}
	
	if(Dis_Temp_Humidity==1)
	{
		Flag_Temp_Humidity++;//开始计时,
		if(Flag_Temp_Humidity>=60)//60*20ms=3S
		{
			Sum_Humidity += Humidity_Value;//记录湿度的总和
			Sum_Temp += Temp_Value;//记录温度的总和
			Flag_Temp_Humidity=0;//计时清零
			Dis_Temp_Humidity=0;//取消计时
			S4_Flag=0;//回显界面的数字清零
			S5_Flag=0;//显示完全后回到主界面
			Flag_Light=0;//等待下一次变化
		}
	}
	
	Led_Run++;//LED闪烁控制
	Led_Run%=2;
	Led();//led控制
}

void main()
{
	Init_Sys();//系统初始化
	Init_Time();//DS1302初始化
	Timer_Init();//定时器0、1初始化
	while(1)
	{
		Scan_Key();//按键扫描
		All_Display();//数码管显示
		Humidity_Value=Get_Shidu()*10;//湿度数据获取  ex:64.8
		Temp_Value = Get_Temp()*625;//温度数据获取 ex:123456
		Light = AD_Read(0x01);//光敏电阻数据获取
	}
}

其他工程文件由于时间问题就不都上传了,有时间我做成云盘文件,需要的请自取,

代码资源:

完整的工程代码如下,需要的自取。

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

欢迎大家指出的我的代码问题,在评论区讨论。

猜你喜欢

转载自blog.csdn.net/weixin_52091264/article/details/130350876