目录
前言
首次参加的蓝桥杯比赛,发挥一般以为寄了,没想到活了,于是有了今天的这篇文章。
贴个图证实一下
然后给大家看一下工程的完成情况↓↓
蓝桥杯第14届省赛本科组
赛程难度:
相比于往届的比赛难度真的上升了,逻辑难度大概提升了两个档次,但是整个工程组成的繁琐度提高了三个档次的样子,这个看个人感受吧,取决于往届的比赛你做了多少,也看个人吧。
代码框架:
说下这份主观题,有哪些我觉得需要注意的点。
1.注意很多不同的.C文件和main.c文件之间的变量传递。
2.整个过程我一开始使用的是3个定时器,但是我发现这样定时器的中断优先级很难把握,整个工程也很臃肿,所以在NE555频率检测中用到的两个定时器,选定时器1作为整个过程的标志位检测及LED状态更新。
3.在主函数中进行按键扫描,数码管显示,光敏采集,
细节归纳:
这份题目我觉的难度还是很高的,湿度数据的采集、数码管显示的时候很多的变量、显示的精度、不同类型的变量之间的运算精度、LED的控制、中断函数的逻辑编写、非常推荐准备下一届的去自己写一写,肯定有很多的收获。
主观题题目:
代码部分:
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
欢迎大家指出的我的代码问题,在评论区讨论。