第15届蓝桥杯单片机省赛代码(仅供参考)

15届省赛已结束,这次结果也算自己的预期,考试的时候有失误,好在有惊无险,赛后已经更正

代码因为考试时间紧,就没有过多优化,有点长,但是更易懂

main

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

unsigned char Key_Val,Key_Down,Key_Up,Key_Old;
unsigned char Key_Slow_Down;
unsigned char Seg_Pos;
unsigned int Seg_Slow_Down;
unsigned char Seg_Buf[8]={10,10,10,10,10,10,10,10};
unsigned char Seg_Point[8]={0,0,0,0,0,0,0,0};
unsigned char ucLed[8]={0,0,0,0,0,0,0,0};

unsigned int Freq;
unsigned int Timer_1000ms;
unsigned char ucRtc[3]={0x13,0x03,0x05};

unsigned char Seg_Disp_Mode;//0-频率 1-参数 2-时间 3-回显
bit Para_Disp_Mode;//0-超限参数 1-校准值
unsigned int Freq_Para=2000;//超限参数 超限参数可调整范围: 1000Hz ~ 9000Hz
unsigned int jiaozhun_Value;//校准值参数可调整范围: -900Hz ~ 900Hz
bit Single_Flag;//符号标志位判断 1-表示有符号
bit Freq_Time;//0-频率回显 1-时间回显
unsigned int Freq_Max;
unsigned char Timer_Rtc[3];//最大频率发生的时间
bit error_Flag;//获得错误频率值标志位
float DA_Data;
unsigned char Timer_200ms;
bit Led_Flag;
bit L2_Flag;
unsigned char TimerL2_200ms;
unsigned int Freq_Data[2];//1位置放最大值 0位置实时更新
bit Freq_Flag;//判断是否是第一次获取Freq_Max标志位
void Key_Pro()
{
	if(Key_Slow_Down) return;
	Key_Slow_Down=1;
	
	Key_Val=Key_Read();
	Key_Down=Key_Val&(Key_Val^Key_Old);
	Key_Up=~Key_Val&(Key_Val^Key_Old);
	Key_Old=Key_Val;
	
	switch(Key_Down)
	{
		case 4:
			if(++Seg_Disp_Mode==4)
				Seg_Disp_Mode=0;
			if(Seg_Disp_Mode==0)//每次从频率界面切换到参数界面时, 处于超限参数子界面
				Para_Disp_Mode=0;
			else if(Seg_Disp_Mode==2)//每次从时间界面切换到回显界面时,处于频率回显子界面
			{
				Freq_Time=0;
			}
		break;
		case 5:
			if(Seg_Disp_Mode==1)//参数界面前提下
				Para_Disp_Mode^=1;
			else if(Seg_Disp_Mode==3)//回显界面前提下
				Freq_Time^=1;
		break;
		case 8://加
			if(Seg_Disp_Mode==1)//参数界面前提下
			{
				if(Para_Disp_Mode==0)//超限参数设置
				{
					Freq_Para+=1000;
					if(Freq_Para>9000)
						Freq_Para=9000;
				}
					else//校准值设置
				{
					if(jiaozhun_Value==0)//已到正数阶段
						Single_Flag=0;
					if(Single_Flag==1)//处于负数 需要进行减值 以完成加值操作
					{
						jiaozhun_Value-=100;
						
					}
					else//正常减值
					{
						jiaozhun_Value+=100;
						if(jiaozhun_Value>900)
							jiaozhun_Value=900;
					}
				}
		}
		break;
		case 9://减
			if(Seg_Disp_Mode==1)//参数界面前提下
			{
				if(Para_Disp_Mode==0)//超限参数设置
				{
					Freq_Para-=1000;
					if(Freq_Para<1000)
						Freq_Para=1000;
				}
				else//校准值设置
				{
					if(jiaozhun_Value==0)//进入负数阶段
						Single_Flag=1;//符号标志位置1
					
					if(Single_Flag==1)
					{
						jiaozhun_Value+=100;//进行1加值操作 以完成减成负数的结果
						if(jiaozhun_Value>900)//负数边界限制
							jiaozhun_Value=900;
					}
					else//值为100~900之间 正常减
					{
						jiaozhun_Value-=100;
					}
				}
			}
		break;
	}
}
void Seg_Pro()
{
	unsigned char i;
	if(Seg_Slow_Down) return;
	Seg_Slow_Down=1;
	/*数据获取区域*/
	Read_Rtc(ucRtc);
	DA_Write(DA_Data*51);
	if(error_Flag==0)//获得正确的频率条件下
	{
		Freq_Data[0]=Freq;
		if(Freq_Flag==0)//第一次存放
		{
			Freq_Max=Freq_Data[0];
			Freq_Data[1]=Freq_Data[0];
			
		for(i=0;i<3;i++)
		Timer_Rtc[i]=ucRtc[i];
		}
		else//第二次以上存放
		{
			if(Freq_Data[0]<=Freq_Data[1])
			{
				Freq_Max=Freq_Data[1];//1 位置存放大值 0位置实时更新值
			}
			else if(Freq_Data[0]>=Freq_Data[1])
			{
				Freq_Data[1]=Freq_Data[0];
				Freq_Max=Freq_Data[1];
		for(i=0;i<3;i++)
		Timer_Rtc[i]=ucRtc[i];
			}
		}
		Freq_Flag=1;//标志置1 表示非第一次存放
	}
	/*数据显示区域*/
	switch(Seg_Disp_Mode)
	{
		case 0://频率
			Seg_Buf[1]=Seg_Buf[2]=10;
			Seg_Buf[0]=11;//F
			if(error_Flag==1)//获得错误频率
			{
				for(i=1;i<=5;i++)
				Seg_Buf[i]=10;//清零
				Seg_Buf[6]=Seg_Buf[7]=16;
			}
			else
			{
				Seg_Buf[3]=(unsigned int)Freq/10000%10;
				Seg_Buf[4]=(unsigned int)Freq/1000%10;
				Seg_Buf[5]=(unsigned int)Freq/100%10;
				Seg_Buf[6]=(unsigned int)Freq/10%10;
				Seg_Buf[7]=(unsigned int)Freq%10;
				if(Seg_Buf[3]==0)//高位熄灭
				{
					Seg_Buf[3]=10;
					if(Seg_Buf[4]==0)
					{
						Seg_Buf[4]=10;
						if(Seg_Buf[5]==0)
						{
							Seg_Buf[5]=10;
							if(Seg_Buf[6]==0)
								Seg_Buf[6]=10;
						}
					}
				}
			}
		break;
		case 1://参数
			Seg_Buf[0]=12;//P
			if(Para_Disp_Mode==0)//超限参数界面
			{
				Seg_Buf[2]=Seg_Buf[3]=10;
				Seg_Buf[1]=1;
				Seg_Buf[4]=Freq_Para/1000%10;
				Seg_Buf[5]=Freq_Para/100%10;
				Seg_Buf[6]=Freq_Para/10%10;
				Seg_Buf[7]=Freq_Para%10;
				if(Seg_Buf[4]==0)//高位熄灭
				{
					Seg_Buf[4]=10;
					if(Seg_Buf[5]==0)
					{
						Seg_Buf[5]=10;
						if(Seg_Buf[6]==0)
							Seg_Buf[6]=10;
					}
				}
		}
			else//校准值界面
			{
				Seg_Buf[2]=Seg_Buf[3]=Seg_Buf[4]=10;
				Seg_Buf[1]=2;
				if(Single_Flag==0)//无符号
				{
					Seg_Buf[5]=(unsigned int)jiaozhun_Value/100%10;
					Seg_Buf[6]=(unsigned int)jiaozhun_Value/10%10;
					Seg_Buf[7]=(unsigned int)jiaozhun_Value%10;
					if(Seg_Buf[5]==0)//高位熄灭
					{
						Seg_Buf[5]=10;
						if(Seg_Buf[6]==0)
							Seg_Buf[6]=10;
					}
				}
				else//有符号
				{
					Seg_Buf[4]=15;//-
					Seg_Buf[5]=(unsigned int)jiaozhun_Value/100%10;
					Seg_Buf[6]=(unsigned int)jiaozhun_Value/10%10;
					Seg_Buf[7]=(unsigned int)jiaozhun_Value%10;
					if(Seg_Buf[5]==0)//高位熄灭
					{
						Seg_Buf[4]=10;//符号位也要熄灭
						Seg_Buf[5]=10;
						if(Seg_Buf[6]==0)
							Seg_Buf[6]=10;
					}
				}
			}
		break;
		case 2://时间
			Seg_Buf[2]=Seg_Buf[5]=15;
			for(i=0;i<3;i++)
			{
				Seg_Buf[3*i]=ucRtc[i]/16;
				Seg_Buf[3*i+1]=ucRtc[i]%16;
			}
		break;
		case 3://回显
			Seg_Buf[0]=13;//H
			if(Freq_Time==0)//频率回显
			{
				Seg_Buf[2]=10;
				Seg_Buf[1]=11;//F
			Seg_Buf[3]=Freq_Max/10000%10;
			Seg_Buf[4]=Freq_Max/1000%10;
			Seg_Buf[5]=Freq_Max/100%10;
			Seg_Buf[6]=Freq_Max/10%10;
			Seg_Buf[7]=Freq_Max%10;
			if(Seg_Buf[3]==0)//高位熄灭
			{
				Seg_Buf[3]=10;
				if(Seg_Buf[4]==0)
				{
					Seg_Buf[4]=10;
					if(Seg_Buf[5]==0)
						Seg_Buf[5]=10;
				}
			}
			}
			else//时间回显
			{
				Seg_Buf[1]=14;//A
				Seg_Buf[2]=Timer_Rtc[0]/16;
				Seg_Buf[3]=Timer_Rtc[0]%16;
				Seg_Buf[4]=Timer_Rtc[1]/16;
				Seg_Buf[5]=Timer_Rtc[1]%16;
				Seg_Buf[6]=Timer_Rtc[2]/16;
				Seg_Buf[7]=Timer_Rtc[2]%16;
			}
		break;
	}
}
void Led_Pro()
{
	/*DAC相关*/
	if(Freq<500)
		DA_Data=1;
	else if(Freq>Freq_Para)
		DA_Data=5;
	else
		DA_Data=1+4*(Freq-500)/(Freq_Para-500);
	/*Led相关*/
	ucLed[0]=Led_Flag&(0==Seg_Disp_Mode);
	if(error_Flag==0)//正确的状态下
	{
		if(Freq>Freq_Para)
			ucLed[1]=L2_Flag;
		else
			ucLed[1]=0;
	}
	else//频率错误情况下 点亮error_Flag=1
	{
		ucLed[1]=error_Flag;
	}
}
/*定时器1初始化函数*/
void Timer1_Init(void)		//1毫秒@12.000MHz
{
	AUXR &= 0xBF;			//定时器时钟12T模式
	TMOD &= 0x0F;			//设置定时器模式
	TL1 = 0x18;				//设置定时初始值
	TH1 = 0xFC;				//设置定时初始值
	TF1 = 0;				//清除TF1标志
	TR1 = 1;				//定时器1开始计时
	ET1=1;
	EA=1;
}
/*定时器0初始化函数*/
void Timer0Init(void)		//0毫秒@12.000MHz
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x05;	
	TL0 = 0x00;		//设置定时初值
	TH0 = 0x00;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
}

/*定时器1服务函数*/
void Timer1Server() interrupt 3
{
	if(++Key_Slow_Down==10) Key_Slow_Down=0;
	if(++Seg_Pos==8) Seg_Pos=0;
	if(++Seg_Slow_Down==100) Seg_Slow_Down=0;
	Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);
	Led_Disp(Seg_Pos,ucLed[Seg_Pos]);
	
	if(Seg_Disp_Mode==0)//处于频率界面
	{
		if(++Timer_200ms==200)
		{
			Timer_200ms=0;
			Led_Flag^=1;
		}
	}
	if(error_Flag==0)
	{
		if(++TimerL2_200ms==200)
		{
			TimerL2_200ms=0;
			L2_Flag^=1;
		}
	}
		
//	Freq=(Single_Flag==1?Freq-jiaozhun_Value:Freq+jiaozhun_Value);
	if(++Timer_1000ms==1000)
	{
		TR0 = 0;
		Timer_1000ms=0;
			if(Single_Flag==0)//无符号
			{
				Freq=TH0<<8|TL0;
				Freq+=jiaozhun_Value;
			}
			else
			{
				Freq=TH0<<8|TL0;
				Freq-=jiaozhun_Value;
			}
			if(Freq<=65535&&Freq>50000)
				error_Flag=1;//获得错误频率值
			else
				error_Flag=0;
		TH0=TL0=0;
		TR0 = 1;
	}
}
void main()
{
	System_Init();
	Timer0Init();
	Timer1_Init();
	Set_Rtc(ucRtc);
	while(1)
	{
		Key_Pro();
		Seg_Pro();
		Led_Pro();
	}
}

总的来说,善于用标志位能解决很多问题

这里这是提供思路,可能不是很好,仅供大家参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

顺顺心心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值