zcs独裁者 发表于 2012-12-27 19:47:36

可调时钟8位共阳极数码管显示

/***************************************************************************************************************************************
自学一段时间了,这个可调时钟也看了好久,总算自己写出来了一个,只是按自己的想法写的,算法还不简洁,各位提出宝贵意见



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



                   /*********************************************************************
                  *                   8位共阳极数码管可调时钟显示                      *
          *            KEY_1键选择数码管,选中数码管开始闪烁                       *
          *            KEY_2键对选中数码管做加1处理                                       *
          *            KEY_3键对选中数码管做减1处理                                       *
          *            KEY_4键取消闪烁,正常显示                                       *
          *********************************************************************/                                                                                       


#include<reg52.h>
#include"keyscan.h"
#include"display.h"
int temp;
unsigned char num1,LASTkey,KeyValue;
unsigned long int num2;

void timerinit()                          //中断函数初始化
{
   TMOD=0x01;
   EA=1;
   ET0=1;
   TR0=1;
   TH0=(65536-10000)/256;
   TL0=(65536-10000)%256;
}

main()
{

   timerinit();

   while(1)
   {                                        //把秒数换算成小时,分钟数
                temp=num2/3600;             //时
                  shi1=temp/10;
                  shi2=temp%10;

                  temp=num2%3600;        //分
                  temp=temp/60;
                  fen1=temp/10;
                  fen2=temp%10;
               
                  temp=num2%3600%60;        //秒
                  miao1=temp/10;               
                  miao2=temp%10;
        lastkey(&KeyValue);
                if(KeyValue==((KEY_VALUE_1)&(KEY_UP))) //按键1控制数码管闪烁位
                  {                                              
                  num++;                                           //num=0正常显示,num=1、2、3、4、5、6
                  if(num==7)                                     //分别是第1、2、4、5、7、8数码管闪烁
                  num=1;
                  }
                                                                           
                  if(KeyValue==((KEY_VALUE_2)&(KEY_UP)))                   //按键2控制数码加数
                  {
                     
                           if(num==1)
                             {
                                num2=num2+36000;
                                   if(num2>86400)
                           num2=num2-72000;
                                }
                             if(num==2)
                             num2=num2+3600;
                             if(num==3)
                             num2=num2+600;
                             if(num==4)
                             num2=num2+60;
                             if(num==5)
                             num2=num2+10;
                             if(num==6)
                             num2=num2+1;
                             if(num2>86400)
                     num2=num2-86400;
                       
                  }
                  if(KeyValue==((KEY_VALUE_3)&(KEY_UP)))                         //按键3控制数码管减数
                  {
                     
                           if(num==1)
                             {if(num2>36000)
                                num2=num2-36000;                  
                                }
                             if(num==2)
                             {
                             if(num2>3600)
                             num2=num2-3600;
                             }
                             if(num==3)
                             {
                             if(num2>600)
                             num2=num2-600;
                             }
                             if(num==4)
                             {
                             if(num2>60)
                             num2=num2-60;
                             }
                             if(num==5)
                             {
                             if(num2>10)
                             num2=num2-10;
                             }
                             if(num==6)
                             {
                             if(num2>1)
                             num2=num2-1;
                             }
                          
                       
                  }
                  if(KeyValue==((KEY_VALUE_4)&(KEY_UP)))                          //置num=0,使数码管正常显示
                  {
                  num=0;
                  }
    display();

}
}
void timer_0() interrupt 1
{
   TH0=(65536-50000)/256;
   TL0=(65536-50000)%256;
   num1++;
   if(num1%5==0)                //STATE控制数码管闪烁
   STATE=on;
   if(num1%10==0)
    {
    STATE=off;
    }
   if(num1==20)
   {
      num1=0;

   num2++;
       if(num2==86400)
       num2=0;
   }

}




/****************************************************************************************************************************
****************************************************************************************************************************/
/*键盘扫描函数*/
                //独立键盘接P3口的2、3、4、5端口
#include<reg52.h>
#define KEY_VALUE_1 0xfb    //定义键值
#define KEY_VALUE_2 0xf7
#define KEY_VALUE_3 0xef
#define KEY_VALUE_4 0xdf
#define KEY_NULL 0xff

#define KEY_DOWN 0xfe             //定义按键状态
#define KEY_LONG 0xfd
#define KEY_CONTINUE 0xbf
#define KEY_UP 0x7f

#define KEY_STATE_INIT 0        //定义按键过程
#define KEY_STATE_WOBBLE 1
#define KEY_STATE_PRESS 2
#define KEY_STATE_LONG 3
#define KEY_STATE_CONTINUE 4
#define KEY_STATE_RELEASE 5

#define KEY_TICK_LONG 100          //定义LONG、CONTINUE两种状态的tick数(时间)
#define KEY_TICK_CONTINUE 20

sbit KEY_1=P3^2;                          //定义端口
sbit KEY_2=P3^3;
sbit KEY_3=P3^4;
sbit KEY_4=P3^5;

static unsigned char keyscan()          //键盘扫描
{
   if(KEY_1==0)
   return KEY_VALUE_1;

   if(KEY_2==0)
   return KEY_VALUE_2;

   if(KEY_3==0)
   return KEY_VALUE_3;

   if(KEY_4==0)
   return KEY_VALUE_4;

   return KEY_NULL;

}

void lastkey(unsigned char *LASTkey)
{
static unsigned char KEY_STATE=KEY_STATE_INIT;   //定义键盘状态变量,并赋值为初始状态
static unsigned char keytemp=KEY_NULL;                   //定义中间变量存取键值
static unsigned char lastkey=KEY_NULL;
static unsigned int num=0,num2;

    keytemp=keyscan();                                       //获取键值
    switch(KEY_STATE)
    {
            case KEY_STATE_INIT:
                                  if(keytemp!=KEY_NULL)
                                  KEY_STATE=KEY_STATE_WOBBLE;
                                  break;

        case KEY_STATE_WOBBLE:
                             if(keytemp!=KEY_NULL)
                             KEY_STATE=KEY_STATE_PRESS;
                                   break;
        case KEY_STATE_PRESS:
                                   {
                                   if(keytemp!=KEY_NULL)
                                      {
                               
                                          lastkey=keytemp;
                                          keytemp&=KEY_DOWN;
                                          KEY_STATE=KEY_STATE_LONG;
                                          
                                       }
                                  else
                                  KEY_STATE=KEY_STATE_INIT;
                                  }
                                  break;
        case KEY_STATE_LONG:
                                  {
                                   if(keytemp!=KEY_NULL)
                                     {
                                  
                                     num++;
                                               if(num==KEY_TICK_LONG)
                                           {
                                          
                                             num=0;
                                             keytemp&=KEY_LONG;
                                             KEY_STATE=KEY_STATE_CONTINUE;
                                           }
                                     }
                                  else
                                  KEY_STATE=KEY_STATE_RELEASE;
                                  }
                                  break;
        case KEY_STATE_CONTINUE:
                                {
                                       if(keytemp!=KEY_NULL)
                                           {
                                           num2++;
                                                if(num2==KEY_TICK_CONTINUE)
                                                  {
                                                  num2=0;
                                                  
                                                  keytemp&=KEY_CONTINUE;
                                                  }
                                           }
                                           else
                                           KEY_STATE=KEY_STATE_RELEASE;
                                        }
                                        break;
   case KEY_STATE_RELEASE:
                            {
                                  lastkey&=KEY_UP;
                                  keytemp=lastkey;
                                  KEY_STATE=KEY_STATE_INIT;
                                  num2=0;
                                  num=0;
                                  }
                                  break;
    default:break;
    }
    *LASTkey=keytemp;
}

/********************************************************************************************
********************************************************************************************/
/*显示函数*/
#include<reg52.h>
#define on 1
#define off 0
unsigned char num=0,STATE,shi1,shi2,fen1,fen2,miao1,miao2;
unsigned char weima[]={0x01,0x02,0x04,0x08,0x010,0x20,0x40,0x80};
unsigned char duanma[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

sbit duan=P2^6;
sbit wei=P2^7;
void delayms(unsigned char z)
{
   unsigned char i,j;
   for(i=z;i>0;i--)
   for(j=145;j>0;j--);
   
}

void display()
{
   wei=1;
   if((num==1)&&(STATE==off))
   {
   
   P0=0x00;
   }
   else
   P0=weima;
   wei=0;
   P0=0xff;
   duan=1;
   P0=duanma;
   duan=0;
   delayms(2);

   wei=1;
   if((num==2)&&(STATE==off))
   {
   P0=0x00;
   }
   else
   P0=weima;
   wei=0;
    P0=0xff;
   duan=1;
   P0=duanma;
   duan=0;
   delayms(2);

   wei=1;
   P0=weima;
   wei=0;
    P0=0xff;
   duan=1;
   P0=0xbf;
   duan=0;
   delayms(2);

   wei=1;
   if((num==3)&&(STATE==off))
   {
   P0=0x00;
   }
   else
   P0=weima;
   wei=0;
    P0=0xff;
   duan=1;
   P0=duanma;
   duan=0;
   delayms(2);

   wei=1;
   if((num==4)&&(STATE==off))
   {
   
   P0=0x00;
   }
   else
   P0=weima;
   wei=0;
    P0=0xff;
   duan=1;
   P0=duanma;
   duan=0;
   delayms(2);

   wei=1;
   P0=weima;
   wei=0;
    P0=0xff;
   duan=1;
   P0=0xbf;
   duan=0;
   delayms(2);

   wei=1;
   if((num==5)&&(STATE==off))
   {
   P0=0x00;
   }
   else
   P0=weima;
   wei=0;
   duan=1;
   P0=duanma;
   duan=0;
   delayms(2);

   wei=1;
   if((num==6)&&(STATE==off))
   {
   P0=0x00;
   }
   else
   P0=weima;
   wei=0;
    P0=0xff;
   duan=1;
   P0=duanma;
   duan=0;
   delayms(2);
}


/************************************************************************
*************************************************************************/
/*头文件keyscan.h*/


#ifndef _KEYSCAN_H
#define _KEYSCAN_H
#define KEY_VALUE_1 0xfb
#define KEY_VALUE_2 0xf7
#define KEY_VALUE_3 0xef
#define KEY_VALUE_4 0xdf
#define KEY_NULL 0xff

#define KEY_DOWN 0xfe
#define KEY_LONG 0xfd
#define KEY_CONTINUE 0xbf
#define KEY_UP 0x7f
sbit KEY_1=P3^2;
sbit KEY_2=P3^3;
sbit KEY_3=P3^4;
sbit KEY_4=P3^5;
extern void lastkey(unsigned char *LASTkey);

#endif
/*头文件display.h*/
#ifndef _DISPLAY_H
#define _DISPLAY_H
#define on 1
#define off 0
extern void display();
extern unsigned char num,STATE,shi1,shi2,fen1,fen2,miao1,miao2;
#endif

lmt50211 发表于 2012-12-28 09:53:40

楼主,能单独讲讲你的按键程序吗?

lcw_swust 发表于 2012-12-28 10:32:26

这个误差恐怕不小,建议楼主的定时器用自动重装的模式

zcs独裁者 发表于 2012-12-29 11:24:53

lmt50211 发表于 2012-12-28 09:53 static/image/common/back.gif
楼主,能单独讲讲你的按键程序吗?

这个我是在这个帖子里面看到的。。。。。。你可以先看看吧,有什么问题再交流

zcs独裁者 发表于 2012-12-29 11:25:08

zcs独裁者 发表于 2012-12-29 11:24 static/image/common/back.gif
这个我是在这个帖子里面看到的。。。。。。你可以先看看吧,有什么问题再交流 ...

http://www.amobbs.com/thread-3985870-1-1.html

zcs独裁者 发表于 2012-12-29 11:25:31

lmt50211 发表于 2012-12-28 09:53 static/image/common/back.gif
楼主,能单独讲讲你的按键程序吗?

http://www.amobbs.com/thread-3985870-1-1.html

zcs独裁者 发表于 2012-12-29 11:26:38

lcw_swust 发表于 2012-12-28 10:32 static/image/common/back.gif
这个误差恐怕不小,建议楼主的定时器用自动重装的模式

哦   谢谢指教   再去学习学习。。。
页: [1]
查看完整版本: 可调时钟8位共阳极数码管显示