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