15届蓝桥杯单片机赛后心得

 前言

        首先,本人是一名大二学生,第一次参加蓝桥杯比赛。在比赛前的一个月,我几乎将大量精力花在备战蓝桥杯上,周末或是没课的时侯都专注于刷往届赛题。在网上有很多什么速通的课程,但本人比较推荐小蜜蜂老师和西风的。对于想要完全搞懂这款单片机基本原理的可以看小蜜蜂老师的,但如果你是那种想混个奖项的,那就首选西风的视频吧,不要犹豫!一个偏于原理,一个更加偏于速成。

        在讲下我个人情况,毕竟是个人赛后心得。赛前我在网上看了很多种写法,最后我是结合了西风和小蜜蜂的代码,综合了一个自己的代码风格。省赛题目主要考的是DS1302、DS18B20和IIC总线三个,往年也是主要集中于这三个。赛前一个月,我几乎将10届到14届的所有省赛题都刷了一遍,个人感觉光看视频教学没有意义,一定要动手亲自刷题。

获奖情况

       “功夫不负有心人”。省一!!!

试题分析

        首先要说,今年难度确实要比去年14届的题目要简单,大部分功能也比较常规,按键也没有往年复杂(长、短按、双击等),但是考的更多的是细节处理。就比如NE555的频率处理,调试值为负数时的越界问题等。所以,严格来说今年试题也不轻松!!!

演示

主函数

#include <STC15F2K60S2.H>
#include "Key.h"
#include "Seg.h"
#include "Led.h"
#include "ds1302.h"
#include "iic.h"

unsigned char Key_time;
unsigned int Seg_time;

unsigned char Key_value, Key_dowm, Key_up, Key_old;
unsigned char Seg_buf[]={10,10,10,10,10,10,10,10};
unsigned char Seg_pos;
unsigned char Seg_point[]={0,0,0,0,0,0,0,0};
unsigned char Led_buf[]={0,0,0,0,0,0,0,0};

unsigned int NE555;
unsigned int Time_1000ms;
unsigned char Mode;
unsigned int Big_can=2000;  //超限参数
unsigned char Time[]={0x13,0x03,0x05};   //时间
unsigned char Mode_can;  //S5参数切换
unsigned char Mode_hui;  //S5回显切换
unsigned int Change_hz;  //校准值
unsigned int Fu;  //负数表示
unsigned int Ne555_true;
unsigned int MAX_HZ;  //最大频率
unsigned char Time_mx[3];  //发生时间
unsigned char Da_V; //电压
unsigned char Time_200ms;
unsigned char State;

void Key_get()
{
	if(Key_time)return;
	Key_time=1;
	
	Key_value=Key_read();
	Key_dowm=Key_value&(Key_value^Key_old);
	Key_up=~Key_value&(Key_value^Key_old);
	Key_old=Key_value;
	
	switch(Key_dowm)
	{
		case 4:
			if(++Mode==4)Mode=0;
			if(Mode==1)
			{
				Mode_can=0; 
			
			}
			if(Mode==3)Mode_hui=0; 
		
		break;
		
		case 5:
			if(Mode==1)
				Mode_can=1-Mode_can;
			if(Mode==3)
				Mode_hui=1-Mode_hui;
		break;
			
		case 8:
			if(Mode==1)    //参数界面
			{
				if(Mode_can==0)      //超限界面
				{
					Big_can+=1000;
					if(Big_can==10000)Big_can=9000;
				}
				if(Mode_can==1)      //校准界面
				{
					if(Change_hz>=0 && Fu==0)
					{
						Change_hz+=100;
						if(Change_hz==1000)Change_hz=900;
					}
					if(Fu<=900 && Fu>0)
					{
						Fu-=100;
					}
				}
			}
		break;
		
		case 9:
			if(Mode==1)    //参数界面
			{
				if(Mode_can==0)      //超限界面
				{
					Big_can-=1000;
					if(Big_can==0)Big_can=1000;
				}
				if(Mode_can==1)      //校准界面
				{
					if(Change_hz==0 && Fu>=0)
					{
						Fu+=100;
						if(Fu==1000)Fu=900;
					}
					if(Change_hz<=900 && Change_hz>0)
					{
						Change_hz-=100;
					}
				}
			}
		break;
	}
	
}

void Seg_get()
{
	if(Seg_time)return;
	Seg_time=1;
	
	DS1302_read(Time);
	if(Ne555_true<=500)Da_V=1;
	if(Ne555_true>=Big_can)Da_V=5;
	if(Ne555_true>500 && Ne555_true<Big_can)
		Da_V=(12*Ne555_true-500)/(3*Big_can-1500)-(Big_can/(3*Big_can-1500));
	if(Ne555_true>50000)Da_V=0;
	Da_read(Da_V*51);
	switch(Mode)
	{
		case 0:
			Seg_buf[0]=11;
			Seg_buf[1]=10;
			Seg_buf[2]=10;
			if(Ne555_true>0 && Ne555_true<50000)
			{
				Seg_buf[3]=(Ne555_true>=10000)?(Ne555_true/10000):10;
				Seg_buf[4]=(Ne555_true>=1000)?(Ne555_true/1000%10):10;
				Seg_buf[5]=(Ne555_true>=100)?(Ne555_true/100%10):10;
				Seg_buf[6]=(Ne555_true>=10)?(Ne555_true/10%10):10;
				Seg_buf[7]=(Ne555_true>0)?(Ne555_true%10):10;
			}
			else if(Ne555_true>50000)
			{
				Seg_buf[3]=10;
				Seg_buf[4]=10;
				Seg_buf[5]=10;
				Seg_buf[6]=16;
				Seg_buf[7]=16;
			}
		break;
		
		case 1:
			if(Mode_can==0)
			{
				Seg_buf[0]=12;
				Seg_buf[1]=1;
				Seg_buf[3]=10;
				Seg_buf[4]=Big_can/1000;
				Seg_buf[5]=Big_can/100%10;
				Seg_buf[6]=Big_can/10%10;
				Seg_buf[7]=Big_can%10;
			}
			if(Mode_can==1)
			{
				Seg_buf[0]=12;
				Seg_buf[1]=2;
				Seg_buf[3]=10;
				Seg_buf[4]=(Fu>0)?13:10;
				if(Change_hz>=100 && Fu==0)Seg_buf[5]=Change_hz/100%10;
				else if(Fu>=100 && Change_hz==0)Seg_buf[5]=Fu/100%10;
				else Seg_buf[5]=10;
				
				if(Change_hz>=10)Seg_buf[6]=Change_hz/10%10;
				else if(Fu>=10)Seg_buf[6]=Fu/10%10;
				else Seg_buf[6]=10;
				Seg_buf[7]=Change_hz%10;
			}
			
		break;
		
		case 2:
			Seg_buf[0]=Time[0]/16;
			Seg_buf[1]=Time[0]%16;
			Seg_buf[2]=13;
			Seg_buf[3]=Time[1]/16;
			Seg_buf[4]=Time[1]%16;
			Seg_buf[5]=13;
			Seg_buf[6]=Time[2]/16;
			Seg_buf[7]=Time[2]%16;
		break;
				
		case 3:
			if(Mode_hui==0)
			{
				Seg_buf[0]=14;
				Seg_buf[1]=11;
				Seg_buf[2]=10;
				Seg_buf[3]=(MAX_HZ>=10000)?(MAX_HZ/10000):10;
				Seg_buf[4]=(MAX_HZ>=1000)?(MAX_HZ/1000%10):10;
				Seg_buf[5]=(MAX_HZ>=100)?(MAX_HZ/100%10):10;
				Seg_buf[6]=(MAX_HZ>=10)?(MAX_HZ/10%10):10;
				Seg_buf[7]=(MAX_HZ>0)?(MAX_HZ%10):10;
			}
			if(Mode_hui==1)
			{
				Seg_buf[0]=14;
				Seg_buf[1]=15;
				Seg_buf[2]=Time_mx[0]/16;
				Seg_buf[3]=Time_mx[0]%16;
				Seg_buf[4]=Time_mx[1]/16;
				Seg_buf[5]=Time_mx[1]%16;
				Seg_buf[6]=Time_mx[2]/16;
				Seg_buf[7]=Time_mx[2]%16;
			}
		break;
	}
	
	
	
}

void Led_get()
{
	unsigned char i;
	if(Change_hz>=0 && Fu==0)    //校准为正数时
	{
		Ne555_true=NE555+Change_hz;
	}
	if(Fu>=0 && Change_hz==0)    //校准为负数时
	{
		Ne555_true=NE555-Fu;
	}
	if(MAX_HZ<Ne555_true  && Ne555_true<50000)
	{
		MAX_HZ=Ne555_true;
		for(i=0;i<3;i++)
			Time_mx[i]=Time[i];
	}
	if(Mode==0)
		Led_buf[0]=(State);
	else Led_buf[0]=0;
	
	if(Ne555_true>Big_can)
		Led_buf[1]=(State);
	else Led_buf[1]=0;
}

void Timer0_Init()		    //定时器0
{
	AUXR &= 0x7F;			
	TMOD &= 0xF0;	
	TMOD |= 0x05;
	TL0 = 0;				
	TH0 = 0;				
	TF0 = 0;				
	TR0 = 1;				
}

void Timer1_Init()		    //定时器1
{
	AUXR &= 0xBF;			
	TMOD &= 0x0F;			
	TL1 = 0x18;				
	TH1 = 0xFC;				
	TF1 = 0;				
	TR1 = 1;				
	EA=1;
	ET1=1;
}

void main()
{
	InitHC138(4,0xff);
	InitHC138(5,0x00);
	Timer0_Init();
	Timer1_Init();
	DS1302_write(Time);
	while(1)
	{
		Key_get();
		Seg_get();
		Led_get();
	}
}

void Init_T1() interrupt 3
{
	if(++Key_time==10)Key_time=0;
	if(++Seg_time==500)Seg_time=0;
	if(++Seg_pos==8)Seg_pos=0;
	SMG(Seg_pos,Seg_buf[Seg_pos],Seg_point[Seg_pos]);
	Led_read(Seg_pos,Led_buf[Seg_pos]);
	
	if(++Time_1000ms==1000)
	{
		Time_1000ms=0;
		NE555=(TH0<<8)|TL0;
		TH0=TL0=0;
	}
	if(++Time_200ms==200)
	{
		Time_200ms=0;
		State^=1;
	}
}

15届蓝桥杯试题演示

该文章由本人原创作品,创作不易。点赞+关注 后面创作详细教程。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值