基于51单片机简易秒表设计

    一、 想法:秒表在生活中的用途很常见,但凡有竞赛或者对时间有要求的场合都离不开它的身影,最近小孩子找出了她姐姐以前用过的一块儿童手表,对秒表特别感兴趣。吃饭,看电视、读书都要用时间来度量,难道那小子会珍惜时间了,如果真是那样,我就高兴了。看着时间飞快地从我们眼前溜走,我们有什么办法留住我们逝去的青春呢?哎,还是写个程序让这美丽的瞬间有了记忆。

二、软件:C51,keil4、立创EDA

三、硬件采用一个数字钟电路,等以后再做个时钟,话不多说直接上图

PCB图,遗憾的是PCB在设计的时候USB接口放反了,一个错版,不过也值得记住,以后在做事的时候一定要谨慎。万幸的是在立创EDA上打的样板可以免费领券,想想又是一件美事,PCB打样可以申请5块免费的哦,大家伙有需要的都可以去瞧一瞧。特别是对咱草根人群很是友善,谢谢你良心企业家,我真不是打广告哈,用着实在,多说一嘴。

实物焊的有点丑,还有那USB,真不忍直视,只是供电有点麻烦,本来USB就只设计了供电没有程序下载的部分,影响也不是太大,将就着用吧。

四、秒表功能及说明;

本设计用到了板载三个按键

A、加号键:清0和重新定时,在暂停键按下后,可以对秒表清。在正常计数的过程中如果按下该键,则重新启动秒表。

B、减号键:启动和暂停键,二次启动继续计时。

C、倒计时键:倒计时和正计时切换,在正计时按下该键切换到倒计时,反之亦然。

说明:1、上电时,显示00:00,按下启动键则正计时,最大设计为59:99;当让这个值可以更改。

           2、任意时刻按下暂停,则停止计时,此时按下清0键 ,数码管显示00:00

           3、上电时,直接按下倒计时按键,则进入倒计时模式,如果要正计时需要再次按下该键进行切换。

          4、在计时的过程中,如果按下清零按键,则会重新开启下一轮计时。  

          5、 本设计可以显示到百分秒,但由于人眼的视觉暂留效应,已经看不出该位的变化了,毕竟是做着玩的,后期可以改进一下。做一个能显示999.9的秒表。

         6、有点遗憾没有设计可以储存的功能,初学之路希望大佬们多多指点啊,在此谢过。

         7、程序使用了模块化编程,也是花姑娘上轿,头一回,不妥之处请指正。

五、程序:

1、主程序

#include<reg51.h>
#include"key.h"
#include"disp.h"
#include"time.h"
#define key=P3;
sbit ee=P3^2;
sbit fmq=P2^4;
extern u16 shijian;
void main()
{
   	init_t0();		  //T0初始化
	while(1)
	{

        keysan8(P3);   //按键检测
 	   	disp1(shijian/1000,shijian%1000/100,shijian%100/10,shijian%10);

	    
	}
}

2、延时程序

#include<intrins.h>
#include"delay.h"
 void delay(u16 xm)
{
      u16 i,j;
	  for(i=0;i<xm;i++)
	  {
	   	 for(j=0;j<124;j++);
	  }
}

void delay1ms()		//@11.0592MHz
{
	unsigned char i, j;

	_nop_();
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}
		  

3、按键检测程序

#include<reg51.h>
#include "delay.h"
extern signed char temp;
extern u16 shijian;
sbit fmq=P1^4;
extern bit djs_flag;

/*检测一位按键的状态*/
// void  onekeysan(bit ee )
//{					
//	   bit key,oldkey;
//	   key=ee;				 //必须将要检测的按键传给实参
	   oldkey=key;			 //放在这里就不行
//	   if(oldkey==0)		 //如果按键按下
//	   {
//	     if(key!=0)		     //等待key1松手
//		 {
//	   	  temp++;			 //加一
//		  }
//	   }
//	   oldkey=key;			 //该语句的位置很重要
//}	   
/*检测8位按键的状态*/	
void keysan8(u8 key) 
{
    u8 	oldkey,tt=0xff;
	bit downflag;			   //按键按下标志位
	if(!downflag)			  //没有按下
	{
	   oldkey=key;		     //读入引脚状态保存在 oldkey
		if(oldkey!=0xff)	  //判断是否按下
		{
		   	downflag=1;		  //标志为1		   
	    }  

	}
	if(downflag)
	{
	 if(key!=0xff)			  //松手检测,等待按键释放
	 {
	 	oldkey=key;
	 }
	  else 
	  {tt=oldkey;
	   downflag=0;				 //取按键值
	  }							 //清标志位,为下一次按键准备
	}
   	 switch(tt)					  //判断何键按下,对应处理处理
		       { 
			   case 0xfb:temp++;if(temp==100){temp=0;}break;  预留
			   case 0xf7:temp--;if(temp==-1){temp=99;}break;
			   case 0xef:shijian=0;break;	//秒表清零
			   case 0xdf:TR0=~TR0;break;	//秒表暂停
			   case 0xbf:TR0=0;shijian=5999;
			             djs_flag=~djs_flag;TR0=1;break;	//秒表倒计时
			   default:	 break;	
	   		   }
			 
	  
 } 
  
	   

4、显示程序

#include<reg51.h>
#include"disp.h"
#include"delay.h"
unsigned char code dispbuf[]={0x3f,0x06,0x5B,0x4F,0x66,
0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,
0x58,0x5E,0x79,0x71,0x00,0x40};
unsigned char code weima[]={0xfe,0xfd,0xfb,0xf7};	  
unsigned char code weima1[]={0x01,0x02,0x04,0x08};
void disp(unsigned q,unsigned b,unsigned s,unsigned g)
{
   P0=~dispbuf[q];				 	//仿真时程序
   P2=weima1[0];
   delay(3);
   P0=0xff;
   P0=~dispbuf[b];
   P2=weima1[1];
   delay(3);
   P0=0xff;
   P0=~dispbuf[s];
   P2=weima1[2];
   delay(3);
   P0=0xff;
   P0=~dispbuf[g];
   P2=weima1[3];
   delay(3);
   P0=0xff;
   

}
 //实验板程序
void disp1(unsigned q,unsigned b,unsigned s,unsigned g)
{
   P0=~dispbuf[q];
   P2=weima[0];
   delay1ms();
   P0=0xff;
   P0=~dispbuf[b];
   P2=weima[1];
   delay1ms();
   P0=0xff;
   P0=~dispbuf[s]&0x7f;
   P2=weima[2];
   delay1ms();
   P0=0xff;
   P0=~dispbuf[g]&0x7f;
   P2=weima[3];
   delay1ms();
   P0=0xff;
   

}

5、定时器中断程序

#include<reg51.h>
#include"time.h"
s16 shijian;
bit djs_flag;
void init_t0(void)			  //11.0592定时10ms
{
	 TMOD&=0xf0;	    //屏蔽高四位
	 TMOD|=0x01;	    //设置T0工作方式1,定时
	 TL0 = 0x00;		//设置定时初值
 	 TH0 = 0xdc;		//设置定时初值
	 EA=1;
	 ET0=1;
//	 TR0=1;

}
void init_t1(void)		  //定时50ms
{
	 TMOD&=0x0f;	//屏蔽高四位
	 TMOD|=0x10;	//设置T1工作方式1,定时
	 TL1 = 0x00;		//设置定时初值
	 TH1 = 0x4C;		//设置定时初值
	 EA=1;
	 ET1=1;
	 TR1=1;
}

void t0zd() interrupt 1 using 1
{
//	static i;
	TL0 = 0x00;		//设置定时初值
	TH0 = 0xDC;		//设置定时初值
//	i++;
//	if(i==2)
//	{ 
//	i=0;
    if(!djs_flag)			//	正计时	
	{
	    shijian++;
		if(shijian==6000)
		shijian=0;
	}
	else					 //	倒计时
	{
	   shijian--;
	   if(shijian==-1)
	   shijian=5999;
	}

}

void t1zd() interrupt 3 using 1
{

}

6、各种头文件

#ifndef __DELAY_H__
#define __DELAY_H__
#include "comm.h"
void delay(u16 xm);
void delay1ms(void);
#endif

//公共程序预定义头文件
#ifndef _comm_H_
#define _comm_H_
#define u8 unsigned char
#define u16 unsigned int
#define s8 signed char
#define s16 signed int
#endif

#ifndef _KEY_H_
#define _KEY_H_
#include "comm.h"
void onekeysan(bit);
void   keysan8( u8 );
#endif

#ifndef __DISP_H__
#define __DISP_H__
void disp(unsigned q,unsigned b,unsigned s,unsigned g);
void disp1(unsigned q,unsigned b,unsigned s,unsigned g);
#endif

#ifndef __TIME_H__
#define __TIME_H__
#include "comm.h"
void init_t0(void);
void init_t1(void);
void t0zd();
void t1zd();
#endif

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值