第八届-电子时钟

一. 题目概述

  1. 目的
     通过按键控制时钟和闹钟的操作;

  2. 元器件
     由数码管显示、单片机最小系统、按键输入和电机控制保护电路组成。

  3. 具体操作
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

二. 对问题的解读

  1. 问题的难点仍在单列按键上,还是老难点,如何根据设计要求做出相应的的效果。这届题目难在逻辑思路的复杂,如何抽丝剥茧理出正确的思路。还要注意一些细节,注意数据的边界属性。两个状态来回转换,如何不导致混乱。
  2. 如何让数码管闪烁?用定时还是时钟。
  3. 如何让灯1闪烁在规定的时间,还只能闪5秒
  4. 其他部分由模板写成即可
    三. 问题的难点
    a) 最难的还是单列按键,如何在不同模式下进行切换,并做普通的计算;
    b) 数码管闪烁如何闪才是最好的。
    c) 在定时中,实现双重的时间定时
    d) 怎样定位数据的边界属性
    四. 问题的解决
  5. 单列按键的处理:需要用到很多的标志位,模式的切换其实很简单,在前几届题中出现过,可以直接套用。只是这里比较特殊,需要再多写一层,为的是不导致混乱。例如if(shi==0) {alarm=0;shi=5;} 在未被按下之前,需要将闹钟的部分关闭,然后打开时钟的区域。剩下的和这个是一样的操作。实现加减时,比较反复复杂,需要区分时钟和闹钟两种状态,在特定的状态下,进行加或减。还要注意,加上时间获得的函数。

子函数部分:
void keyscan()
{
if(P300)
{
delayms(5);
if(P30
0)
{
if(LED_shan0)
{
if(shi
0) {alarm=0;shi=5;}
else if(shi5) shi=1;
else if(shi
1) shi=2;
else if(shi2) shi=3;
else if(shi
3) shi=5;
}
else if(LED_shan==1)
{
LED_shan=0;
P2=0x80;P0=0xff;
}

	}
	while(!P30);
}
else if(P31==0)
{
	delayms(5);
	if(P31==0)
	{
		if(LED_shan==0)
		{
			if(alarm==0) {shi=0;alarm=5;}
		else if(alarm==5) alarm=1;
		else if(alarm==1) alarm=2;
		else if(alarm==2) alarm=3;
		else if(alarm==3) alarm=5;//不让显示了
		}
		else if(LED_shan==1)
		{
			LED_shan=0;
			P2=0x80;P0=0xff;
		}
		
		
	}
	while(!P31);
}
else	if(P32==0)
{
	delayms(5);
	if(P32==0)
	{
		if(LED_shan==0)
		{
			
				if(shi==1) {if(shijian[2]==23) shijian[2]=0;else shijian[2]++;DS_init();}
			else if(shi==2) {if(shijian[1]==59) shijian[1]=0;else shijian[1]++;jian=1;DS_init();}
			else if(shi==3) {if(shijian[1]==59) shijian[1]=0;else shijian[0]++;jian=1;DS_init();}
			else if(alarm==1) {if(shijian[1]==59) shijian[1]=0;else nao[2]++;}
			else if(alarm==2) {if(shijian[1]==59) shijian[1]=0;else nao[1]++;}
			else if(alarm==3) {if(shijian[1]==59) shijian[1]=0;else nao[0]++;}
		}
		else if(LED_shan==1)
		{
			LED_shan=0;
			P2=0x80;P0=0xff;
		}
	}
	while(!P32);
}
else	if(P33==0)
{
	delayms(5);
	if(P33==0)
	{
		if(LED_shan==0)
		{
			s4==1;//按键被按下了
			if(shi==5) {wendu=1;}
		}
		else if(LED_shan==1)
		{
			LED_shan=0;
			P2=0x80;P0=0xff;
		}		
	}
	if((s4==1)&&(P33==1))//P33=1是松手时的检测
	{
		s4=0;wendu=0;
		if(shi==1) {shijian[2]--;jian=1;DS_init();}
		else if(shi==2) {shijian[1]--;jian=1;DS_init();}
		else if(shi==3) {shijian[0]--;jian=1;DS_init();}
		else if(alarm==1) {nao[2]--;}
		else if(alarm==2) {nao[1]--;}
		else if(alarm==3) {nao[0]--;}
	}
}

}

主函数部分:
void main()
{
allinit();
DS_init();
Timer0Init();
yi=0;er=8;san=10;si=3;wu=0;liu=10;qi=0;ba=0;
while(1)
{

	DS_get();
	
	if(wendu==0)
	{
		
	
	if(shi==5)
	{
		yi=shijian[2]/10;er=shijian[2]%10;san=10;
		si=shijian[1]/10;wu=shijian[1]%10;liu=10;
		qi=shijian[0]/10;ba=shijian[0]%10;
	}
	else if(shi==1)
	{
				if(shijian[0]%2==1) 
				{
					yi=shijian[2]/10;er=shijian[2]%10;san=10;
					si=shijian[1]/10;wu=shijian[1]%10;liu=10;
					qi=shijian[0]/10;ba=shijian[0]%10;
				}
				else 
				{
					yi=11;er=11;san=10;
					si=shijian[1]/10;wu=shijian[1]%10;liu=10;
					qi=shijian[0]/10;ba=shijian[0]%10;
				}
	}
	else if(shi==2)
	{
				if(shijian[1]%2==1) 
				{
					yi=shijian[2]/10;er=shijian[2]%10;san=10;
					si=shijian[1]/10;wu=shijian[1]%10;liu=10;
					qi=shijian[0]/10;ba=shijian[0]%10;
				}
				else 
				{
					yi=shijian[2]/10;er=shijian[2]%10;san=10;
					si=11;wu=11;liu=10;
					qi=shijian[0]/10;ba=shijian[0]%10;
				}
	}
	else if(shi==3)
	{
				if(shijian[2]%2==1) 
				{
					yi=shijian[2]/10;er=shijian[2]%10;san=10;
					si=shijian[1]/10;wu=shijian[1]%10;liu=10;
					qi=shijian[0]/10;ba=shijian[0]%10;
				}
				else 
				{
					yi=shijian[2]/10;er=shijian[2]/10;san=10;
					si=shijian[1]/10;wu=shijian[1]%10;liu=10;
					qi=11;ba=11;
				}
	}
	
	
	
	
	if(alarm==5)
	{
		yi=nao[2]/10;er=nao[2]%10;san=10;
		si=nao[1]/10;wu=nao[1]%10;liu=10;
		qi=nao[0]/10;ba=nao[0]%10;
	}
	else if(alarm==1)
	{
				if(nao[0]%2==1) 
				{
					yi=nao[2]/10;er=nao[2]%10;san=10;
					si=nao[1]/10;wu=nao[1]%10;liu=10;
					qi=nao[0]/10;ba=nao[0]%10;
				}
				else 
				{
					yi=11;er=11;san=10;
					si=nao[1]/10;wu=nao[1]%10;liu=10;
					qi=nao[0]/10;ba=nao[0]%10;
				}
	}
	else if(alarm==2)
	{
				if(nao[1]%2==1) 
				{
					yi=nao[2]/10;er=nao[2]%10;san=10;
					si=nao[1]/10;wu=nao[1]%10;liu=10;
					qi=nao[0]/10;ba=nao[0]%10;
				}
				else 
				{
					yi=nao[2]/10;er=nao[2]%10;san=10;
					si=11;wu=11;liu=10;
					qi=nao[0]/10;ba=nao[0]%10;
				}
	}
	else if(alarm==3)
	{
				if(nao[2]%2==1) 
				{
					yi=nao[2]/10;er=nao[2]%10;san=10;
					si=nao[1]/10;wu=nao[1]%10;liu=10;
					qi=nao[0]/10;ba=nao[0]%10;
				}
				else 
				{
					yi=nao[2]/10;er=nao[2]/10;san=10;
					si=nao[1]/10;wu=nao[1]%10;liu=10;
					qi=11;ba=11;
				}
	}
	
	}
	
	else if(wendu==1)
	{
		yi=11;er=11;san=11;si=11;wu=11;liu=Tempget()/10;qi=Tempget()%10;ba=12;
		
	}
	if((shijian[0]==nao[0])&&(shijian[1]==nao[1])&&(shijian[2]==nao[2]))
	{
		LED_shan=1;tt=0;miao=0;
	}
  1. 数码管的闪烁,当时写题时,误以为要写定时器函数才能实现。其实并不是,直接在调用时间时,加上一个if的判断,也就是奇数秒亮,偶数秒的老套路,加以实现。
    if(shijian[2]%2==1)
    {
    yi=shijian[2]/10;er=shijian[2]%10;san=10;
    si=shijian[1]/10;wu=shijian[1]%10;liu=10;
    qi=shijian[0]/10;ba=shijian[0]%10;
    }
    else
    {
    yi=shijian[2]/10;er=shijian[2]/10;san=10;
    si=shijian[1]/10;wu=shijian[1]%10;liu=10;
    qi=11;ba=11;
    }

  2. 实现双重定时,还是用到标志位。只不过需要多个标志位加以区分。

    void time0() interrupt 1
    {
    tt++;miao++;

    	if((tt==40)&&(LED_shan==1))
    	{
    		tt=0;
    		if(fla==0) {fla=1;P2=0x80;P0=0xfe;}
    		else if(fla==1) {fla=0;P2=0x80;P0=0xff;}
    	}
    	if(miao==1000)
    	{
    		miao=0;
    		LED_shan=0;
    		P2=0x80;P0=0xff;
    	}
    

    }

  3. 定义数据的边界,仍然用到标志位。

    if(LED_shan0)
    {
    if(alarm
    0) {shi=0;alarm=5;}
    else if(alarm5) alarm=1;
    else if(alarm
    1) alarm=2;
    else if(alarm2) alarm=3;
    else if(alarm
    3) alarm=5;//不让显示了
    }
    else if(LED_shan==1)
    {
    LED_shan=0;
    P2=0x80;P0=0xff;
    }

五.经验总结
 这套题整体上比较难,难在实现比较繁杂,需要一点点的实现,不厌其烦的改程序,还要注意很多的细节问题。多个模式的切换必然会导致数据的跑串,这是就需要再以前的套路上进行变化。以此套题为例,3个数字不够,就多加一个加以区分。开这一模式时,就要将另一个关闭。并且还要多写一个数字,作为中间变量进行判断。
 需要注意的是,以前的一些小技巧可以直接移植过来,如果没有太多的变化的话。做这道题时,就有一种熟悉感,而且不是一处两处出现过。
 本届题目注重诸多的细节:在 “时钟显示”状态下,按下 S4 按键,显示温度数据,松开按键,返回“时钟显示”界面。这样的要求是对按键的深入考察,就要对按键的原理摸透。实现起来也不难,将松手检测部分进行替换,用if语句进行判别松手,实现灯的亮灭。
 自己的几点要求:驱动这三大部分已经基本定型,平时需反复进行理解并辅以记忆,便可容易将底层驱动写好。每日除了将模板反复练习外,更为重要的是:将历届做过的真题,亲自打一遍,同样需要反复练习。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值