蓝桥杯单片机第八届省赛程序简化

这里只提供简化的主程序和简化说明,原程序见链接

/*头文件*/
#include <STC15F2K60S2.H>
#include <Init.h>
#include <Seg.h>
#include <Key.h>
#include <Led.h>
#include <onewire.h>
#include <intrins.h>
#include <ds1302.h>

/*变量定义区*/
unsigned char Key_Slow_Down;
unsigned int Seg_Slow_Down;
unsigned char Key_Val,Key_Old,Key_Up,Key_Down;
unsigned char Seg_Buf[8] = {10,10,10,10,10,10,10,10};
unsigned char Seg_Pos;
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 char ucRct[3] = {0x23,0x59,0x50};
unsigned char ucRtc_Set[3];
unsigned char ucRtc_Set_Index;//设置调节指针
unsigned char Alerm_Disp[3];
unsigned char Alerm_Set[3];
bit Change_Mode;//0-时间显示 1-温度显示
unsigned char Timer_Mode;//0-时钟显示  1-时钟设置 2-闹钟设置
unsigned char temperature;//实时温度数据
bit Seg_Star_Flag;//0-灭 1-亮
unsigned char Timer_200Ms;//0.2秒为间隔
bit Alerm_Flag;//0-闹钟不提醒 1-闹钟开始提醒
bit Led_Star_Flag;
unsigned char* ucRtc_Buf[3] = {ucRct,ucRtc_Set,Alerm_Disp};
	
/*处理函数*/
void Key_Proc()
{
	unsigned char i;
	if(Key_Slow_Down) return;
	Key_Slow_Down = 1;
	
	Key_Val = Key_Read();
	Key_Down = Key_Val & (Key_Old ^ Key_Val);
	Key_Up = ~ Key_Val & (Key_Old ^ Key_Val);
	Key_Old = Key_Val;
	
	
	if(Alerm_Flag == 1)
	{
		if(Key_Down != 0)
			Alerm_Flag = 0;
		return;
	}
	
	if(Timer_Mode == 0)
	{
		if(Key_Old == 4)
			Change_Mode = 1;
		else
      Change_Mode = 0; 					
	}
	
 switch(Key_Down)
 {
	 case 7:
		 if(Change_Mode == 0)
		 {
			 
			 if(Timer_Mode == 0)
			 {
				 for(i=0;i<3;i++)
				   ucRtc_Set[i] = ucRct[i];
				 Timer_Mode = 1;	 
			 }
			 else if(Timer_Mode == 1)
			 {
				 if(++ucRtc_Set_Index == 3)
				 {
					 ucRtc_Set_Index = Timer_Mode = 0;
					 Ds1302_Set(ucRtc_Set);
				 }
			 }
	  }
	 break;
	 case 6:
		 if(Change_Mode == 0)
		 {
			 if(Timer_Mode == 0)
				 Timer_Mode = 2;
			 else if(Timer_Mode == 2)
			 {
				 if(++ucRtc_Set_Index == 3)
				 {
					 ucRtc_Set_Index = Timer_Mode = 0;
					 for(i=0;i<3;i++)
					  Alerm_Set[i] = Alerm_Disp[i];
					  for(i=0;i<3;i++)
					    Alerm_Disp[i] = 0;
				 }
			 }
		 }
	 break;
	 case 5:
		 if(Change_Mode == 0)
		 {
			 if(Timer_Mode>0)
			 {
				 if((++ucRtc_Buf[Timer_Mode][ucRtc_Set_Index]) %16 == 0x0a)
					 ucRtc_Buf[Timer_Mode][ucRtc_Set_Index] += 6;//为了方便转化为10  0x0a + 6 = 0x10
				 if(ucRtc_Buf[Timer_Mode][ucRtc_Set_Index] == (ucRtc_Set_Index?0x60:0x24))
					    ucRtc_Buf[Timer_Mode][ucRtc_Set_Index] = ucRtc_Set_Index?0x59:0x23;	
			 }
		 }
	 break;
	 case 4:
		 if(Change_Mode == 0)
		 {
			 if(Timer_Mode>0)
			 {
				 if((--ucRtc_Buf[Timer_Mode][ucRtc_Set_Index]) %16 == 0x0f)
					 ucRtc_Buf[Timer_Mode][ucRtc_Set_Index] -= 6;//为了方便转化为10  0xa0 + 6 = 0x10
				 if(ucRtc_Buf[Timer_Mode][ucRtc_Set_Index] == 0xf9)  // 0-7 = f9
					    ucRtc_Buf[Timer_Mode][ucRtc_Set_Index] = 0x00;
			 }
		 }
	 break;
		 
 }
}


void Seg_Proc()
{
	unsigned char i;
	if(Seg_Slow_Down) return;
	Seg_Slow_Down = 1;
	Ds1302_Read(ucRct);
	temperature = rd_temperature();
	Seg_Star_Flag = ucRct[2] %16%2;
	if(Change_Mode)//处于温度显示格式
	{
		for(i=0;i<5;i++)
		  Seg_Buf[i] = 0;
		Seg_Buf[5] = temperature/10%10;
		Seg_Buf[6] = temperature%10;
		Seg_Buf[7] = 12;
	}
	else//处于时间显示界面
	{
				for(i=0;i<3;i++)
				{
					Seg_Buf[3*i] = ucRtc_Buf[Timer_Mode][i] /16%16;
					Seg_Buf[3*i+1] = ucRtc_Buf[Timer_Mode][i] %16;
				}
			  Seg_Buf[2] = Seg_Buf[5] = 11;
				if(Timer_Mode >0)
				{
					Seg_Buf[3*ucRtc_Set_Index] = Seg_Star_Flag?ucRtc_Buf[Timer_Mode][ucRtc_Set_Index] /16%16:10;
					Seg_Buf[3*ucRtc_Set_Index+1] = Seg_Star_Flag?ucRtc_Buf[Timer_Mode][ucRtc_Set_Index] %16:10;					
				}
	}
 
}



/*显示函数*/
void Led_Proc()
{
	if(ucRct[0]==Alerm_Set[0] && ucRct[1]==Alerm_Set[1] && ucRct[2]==Alerm_Set[2])
		Alerm_Flag =1;
	if((ucRct[2]%16) == ((Alerm_Set[2]%16)+5)%10)
		Timer_200Ms = Alerm_Flag =0;
	ucLed[0] = Led_Star_Flag;

}


/*定时器0初始化函数*/
void Timer0Init(void)		//1ms@12.000MHz
{
	AUXR &= 0x7F;		
	TMOD &= 0xF0;		
	TL0 = 0x18;		
	TH0 = 0xFC;		
	TF0 = 0;		
	TR0 = 1;		
	ET0 = 1;
	EA = 1;
}

/*中断服务函数*/
void Timer0Sever() interrupt 1
{
	if(++Key_Slow_Down == 10) Key_Slow_Down = 0;
	if(++Seg_Slow_Down == 500) Seg_Slow_Down = 0;
	if(++Seg_Pos == 8) Seg_Pos = 0;
	Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);
	Led_Disp(Seg_Pos,ucLed[Seg_Pos]);
	if(Alerm_Flag == 1)
	{
		if(++Timer_200Ms == 200)
		{
			Timer_200Ms = 0;
			Led_Star_Flag ^= 1;
		}
	}
	else
		Led_Star_Flag = 0;

}




/*主函数*/
void main()
{
	System_Init();
	Timer0Init();
	Ds1302_Set(ucRct);
	while(1)
	{
		Key_Proc();
		Seg_Proc();
		Led_Proc();
	}
}



简化说明:
我们可以看到很多操作是重复的比如说,三个数组的显示其实很简单,都是一样的,还有时钟和闹钟的设置其实也是一样的,所以我们就创建一个指针数组,把时间显示的三个数组装进去,然后通过Timer_Mode进行调用即可,这样可以节省很大的代码量
unsigned char* ucRtc_Buf[3] = {ucRct,ucRtc_Set,Alerm_Disp};

原程序链接:

https://mp.csdn.net/mp_blog/creation/editor/137477930

  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

学知识的小白

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

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

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

打赏作者

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

抵扣说明:

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

余额充值