基于51单片机的分、秒、毫秒计时设计(数码管显示)

功能:当按下K1时,能实现分、秒、毫秒计时用数码管进行显示;按下K2时实现手动清零。

功能实现板子:51开发板

具体程序如下:

#include "reg52.h"

//#include "intrins.h"

typedef unsigned int u16;       //对系统默认数据类型进行重定义

typedef unsigned char u8;

#define SMG_A_DP_PORT     P0    //使用宏定义数码管段码口

//共阴极数码管显示0~F的段码数据

u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,

                                   0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

//定义独立按键控制脚

sbit KEY1=P3^1;

sbit KEY2=P3^0;

sbit KEY3=P3^2;

sbit KEY4=P3^3;

//使用宏定义独立按键按下的键值

#define KEY1_PRESS       1

#define KEY2_PRESS       2

#define KEY3_PRESS       3

#define KEY4_PRESS       4

#define KEY_UNPRESS   0

                                  

//定义数码管位选信号控制脚

sbit LSA=P2^2;

sbit LSB=P2^3;

sbit LSC=P2^4;

u8 gmsec=0;//ms级定义

u8 gsec=0;//秒定义

u8 gmin=0;//分定义                                

                                  

void delay_10us(u16 ten_us)

{

   while(ten_us--);

}

        

/*******************************************************************************

* 函 数 名       : key_scan

* 函数功能             : 检测独立按键是否按下,按下则返回对应键值

* 输    入       : mode=0:单次扫描按键

                                      mode=1:连续扫描按键

* 输    出         : KEY1_PRESS:K1按下

                                      KEY2_PRESS:K2按下

                                      KEY3_PRESS:K3按下

                                      KEY4_PRESS:K4按下

                                      KEY_UNPRESS:未有按键按下

*******************************************************************************/

u8 key_scan(u8 mode)

{

         static u8 key=1;

         if(mode)key=1;//连续扫描按键

         if(key==1&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0))//任意按键按下

         {

                  delay_10us(1000);//消抖

                  key=0;

                  if(KEY1==0)

                          return KEY1_PRESS;

                  else if(KEY2==0)

                          return KEY2_PRESS;

                  else if(KEY3==0)

                          return KEY3_PRESS;

                  else if(KEY4==0)

                          return KEY4_PRESS;       

         }

         else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1)  //无按键按下

         {

                  key=1;                      

         }

         return KEY_UNPRESS;            

}

void smg_display(u8 dat[],u8 pos)

{

         u8 i=0;

         u8 pos_temp=pos-1;

         for(i=pos_temp;i<8;i++)

         {

              switch(i)//位选

                  {

                          case 0: LSC=1;LSB=1;LSA=1;break;

                          case 1: LSC=1;LSB=1;LSA=0;break;

                          case 2: LSC=1;LSB=0;LSA=1;break;

                          case 3: LSC=1;LSB=0;LSA=0;break;

                          case 4: LSC=0;LSB=1;LSA=1;break;

                          case 5: LSC=0;LSB=1;LSA=0;break;

                          case 6: LSC=0;LSB=0;LSA=1;break;

                          case 7: LSC=0;LSB=0;LSA=0;break;

                  }

                  SMG_A_DP_PORT=dat[i-pos_temp];//传送段选数据

                  delay_10us(100);//延时一段时间,等待显示稳定

                  SMG_A_DP_PORT=0x00;//消音

         }

}

/*******************************************************************************

* 函 数 名       : time0_init

* 函数功能             : 定时器0中断配置函数,通过设置TH和TL即可确定定时时间

* 输    入       : 无

* 输    出         : 无

*******************************************************************************/

void time0_init(void)

{

         TMOD|=0X01;//选择为定时器0模式,工作方式1

         TH0=0XDC;      //给定时器赋初值,定时10ms

         TL0=0X00;      

         ET0=1;//打开定时器0中断允许

         EA=1;//打开总中断

         TR0=0;//关闭定时器             

}

/*******************************************************************************

* 函 数 名       : time0_start

* 函数功能             : 定时器0打开

* 输    入       : 无

* 输    出         : 无

*******************************************************************************/

void time0_start(void)

{

         TR0=1;//打开定时器    

}

/*******************************************************************************

* 函 数 名       : time0_stop

* 函数功能             : 定时器0关闭

* 输    入       : 无

* 输    出         : 无

*******************************************************************************/

void time0_stop(void)

{

         TR0=0;//关闭定时器

         TH0=0X00;

         TL0=0X00;      

}

void time0() interrupt 1 //定时器0中断函数

{

         TH0=0XDC;      //给定时器赋初值,定时10ms

         TL0=0X00;

         gmsec++;//10ms加1次

         if(gmsec==100)//定时1秒

         {

                  gmsec=0;

                  gsec++;//对秒计数

                  if(gsec==60)//到达60秒,即1分钟

                  {

                          gsec=0;

                          gmin++;//对分计数

                          if(gmin==60)gmin=0;

                  }      

         }                                         

}

void main()

{

        

         u8 key=0;

         u8 time_buf[8];

         u8 time_flag=0;

         time0_init();

        

         while(1)

         {key=key_scan(0);

                  if(key==KEY1_PRESS)//开始和停止计时

                  {

                          time_flag=!time_flag;

                          //beep_alarm(1000,10);//短暂提示音

                  }      

                  else if(key==KEY2_PRESS)//清除计时

                  {

                          time0_stop();

                          time_flag=0;

                          gmin=0;

                          gsec=0;

                          gmsec=0;

                          //beep_alarm(1000,10);//短暂提示音                 

                  }

                  if(time_flag)

                           time0_start();//开始计时

                  else

                          time0_stop();//停止计时

        

                  time_buf[0]=gsmg_code[gmin/10];

                  time_buf[1]=gsmg_code[gmin%10];//分

                  time_buf[2]=0x40;//-

                  time_buf[3]=gsmg_code[gsec/10];

                  time_buf[4]=gsmg_code[gsec%10];//秒

                  time_buf[5]=0x40;//-

                  time_buf[6]=gsmg_code[gmsec/10];

                  time_buf[7]=gsmg_code[gmsec%10];//毫秒

                  smg_display(time_buf,1);//显示  

         }

        

}

功能实现图:

  • 5
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
享一个用51单片机制作的6位数码管GPS授时时钟,使用Altium Designer 绘制电路图和PCB如下: 当显示GPS的时间时,时钟是精确的无须调整;但是当没有GPS信号或没有插入GPS模块时,时间是需要调整的,就加入了一个红外接收头,这样就可以用遥控器调整时间了。 单片机型号是STC89C52RC,手头没有IC座就将管脚折出来当贴片用。因为需要串口通信晶振频率选择了11.0592mhz。 硬件做好后开始了漫长的程序调试,用了几个晚上的时间,反复烧写多次后终于达到了自己的设计要求。 这是DIY时钟的当前时间 插入GPS后,自动与卫星同步,时间就想当的准确了 使用5V的电源,没有插入GPS模块时电流100ma左右,功耗大约是0.5W,插入GPS后,电流增加了一倍多,不过1W左右的功耗也不算太大。 数码管倒装,用左上角的小点指示GPS信号的有无。当没有GPS信号时,小点不亮,从DS1302里读出时间来显示;当有GPS信号时,自动与卫星同步并将准确的时间写入DS1302,这样即使GPS信号消失,在一段时间内还是相当的准确的(时间长短与DS1302的精度有关) 为了DIY“作品”的美观,特意从网上订购的半透明亚克力。个人认为还是非常简洁漂亮的。 本次DIY以实用为主,没有添加日期、星期、闹钟等功能,因为我需要的只是一个时间精准的钟,DIY爱好者可以根据需要自行添加。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

白茶丫

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

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

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

打赏作者

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

抵扣说明:

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

余额充值