husange 发表于 2013-5-5 14:34:55

新手用AT89S52、按键、数码管做的可调时钟,请朋友们多指点

本帖最后由 husange 于 2013-5-5 23:58 编辑

功能:系统有四个按键k5,k6,k7,k8,功能分别是 调整,加,减,确定。在按下k5时候,显示 时 的两位数码管以一定频率闪烁。如果再次按下k5,则 分 开始闪烁,时恢复正常显示,依次循环,直到按下确定键k8,恢复正常的显示。在数码管闪烁的时候,按下k6或者k7可以调整相应的显示内容。按键支持短按,和长按,即短按时,修改的内容每次增加一或者减小一,长按时候以一定速率连续增加或者减少。8位数码管显示格式如下:时-分-秒(XX-XX-XX)。P2控制位选,P0是段码。12MHZ晶振。

我是新手,写的代码功能虽然实现了,但是冗长混乱,请大家帮忙指点。


timer.c

#include<reg52.h>

bit TIME2MS_1=0;   //2ms时标,用于按键扫描
bit TIME2MS_2=0;   //2ms时标,用于数码管扫描

void timer0_init()
{
TMOD=0x01;
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
TR0=1;
ET0=1;
}

void timer0_interrupt() interrupt 1
{
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
TIME2MS_1=1;
TIME2MS_2=1;
}

anjian.c

#include<reg52.h>
#include"timer.h"

typedef unsigned char uchar;
typedef unsigned intuint;

sbit k5=P1^4;
sbit k6=P1^5;
sbit k7=P1^6;
sbit k8=P1^7;

#define KEY_INIT   0
#define KEY_PRESS       1               //k5摁下
#define KEY_RELEASE       2               //k5释放
#define KEY_PROCESS       3
#define KEY_CERTAIN       4               //k8摁下
#define KEY6_LONG    5               // k6长摁
#define KEY6_SHORT   6
#define KEY7_LONG    7               // k7长摁
#define KEY7_SHORT   8

uchar t[]={2,3,10,5,9,10,4,1};                          //数码管显示缓存
uchar adjust=0;                               //调整标志位

void key_init()
{
k5=1;
k6=1;
k7=1;
k8=1;
}

void key_process()                                        //状态转移处理
{
static uchar key_state=KEY_INIT;
static uchar j=0,n=0;                                        //定义变量,用于判断长、短摁

switch(key_state)
{
    case KEY_INIT:
        {
          if(k5==0)
          {
          key_state=KEY_PRESS;
          }
        }
        break;
       
        case KEY_PRESS:
        {
          if(k5==0)
          {
          adjust=1;                                       //k5摁下,把调整标志位置1
                key_state=KEY_RELEASE;
          }
          else
          {
          key_state=KEY_INIT;
          }
        }
        break;
       
        case KEY_RELEASE:                               //k5释放
        {
          if(k5==1)
          {
          key_state=KEY_PROCESS;
          }
        }
        break;
       
        case KEY_PROCESS:
        {
          if(k5==0)
          {
          adjust++;                                        //k5摁下,即调整标志位
                if(adjust>3)
                {
                  adjust=1;
                }
                key_state=KEY_RELEASE;
          }

          if(k6==0)
          {
          j++;
                if(j>=3)                                          //长按
                {
                  j=0;
                  key_state=KEY6_LONG;
                }
                if(j==1)                                           //短按
                {
                  key_state=KEY6_SHORT;
                }
          }
          else
          {
          j=0;
          }
          
          if(k7==0)
          {
          n++;
                if(n>=3)                                        //长按
                {
                  n=0;
                  key_state=KEY7_LONG;
                }
                if(n==1)                                       //短按
                {
                  key_state=KEY7_SHORT;
                }
          }
          else
          {
          n=0;
          }
          
          if(k8==0)
          {
          key_state=KEY_CERTAIN;
          }
        }
        break;

        case KEY6_SHORT:                                          //短摁,加1
        {
          switch(adjust)
                {
                  case 1:                                        //时+1
                  {
                        t++;
                        if(t>9)
                        {
                          t=0;
                          t++;
                        }
                        if(t==2 && t>3)
                        {
                          t=0;
                          t=0;
                        }
                  }
                  break;
                  
                  case 2:                                        //分+1
                  {
                        t++;
                        if(t>9)
                        {
                          t=0;
                          t++;
                          if(t>5)
                          {
                          t=0;
                                t=0;
                          }
                        }
                  }
                  break;
                  
                  case 3:                                          //秒+1
                  {
                  t++;
                        if(t>9)
                        {
                          t=0;
                          t++;
                          if(t>5)
                          {
                          t=0;
                                t=0;
                          }
                        }
                  }
                  break;
                  
                  default: break;
                }
          key_state=KEY_PROCESS;
        }
        break;

        case KEY6_LONG:                                       //长摁,每100ms加1
        {
          if(k6==0)
          {
          switch(adjust)
                {
                  case 1:
                  {
                        t++;
                        if(t>9)
                        {
                          t=0;
                          t++;
                        }
                        if(t==2 && t>3)
                        {
                          t=0;
                          t=0;
                        }
                  }
                  break;
                  
                  case 2:
                  {
                        t++;
                        if(t>9)
                        {
                          t=0;
                          t++;
                          if(t>5)
                          {
                          t=0;
                                t=0;
                          }
                        }
                  }
                  break;
                  
                  case 3:
                  {
                  t++;
                        if(t>9)
                        {
                          t=0;
                          t++;
                          if(t>5)
                          {
                          t=0;
                                t=0;
                          }
                        }
                  }
                  break;
                  
                  default: break;
                }
        }
        else
        {
          key_state=KEY_PROCESS;
        }
        }
        break;

        case KEY7_SHORT:
        {
          switch(adjust)
                {
                  case 1:
                  {
                  t--;
                        if(t>9)
                        {
                          t=9;
                          t--;
                          if(t>2)
                          {
                          t=2;
                                t=3;
                          }
                        }
                  }
                  break;

                  case 2:
                  {
                        t--;
                        if(t>9)
                        {
                          t=9;
                          t--;
                          if(t>5)
                          {
                          t=5;
                                t=9;
                          }
                        }
                  }
                  break;

                  case 3:
                  {
                  t--;
                        if(t>9)
                        {
                          t=9;
                          t--;
                          if(t>5)
                          {
                          t=5;
                                t=9;
                          }
                        }
                  }
                  break;

                  default: break;
                }
          key_state=KEY_PROCESS;
        }
        break;

        case KEY7_LONG:
        {
          if(k7==0)
          {
          switch(adjust)
                {
                  case 1:
                  {
                  t--;
                        if(t>9)
                        {
                          t=9;
                          t--;
                          if(t>2)
                          {
                          t=2;
                                t=3;
                          }
                        }
                  }
                  break;

                  case 2:
                  {
                        t--;
                        if(t>9)
                        {
                          t=9;
                          t--;
                          if(t>5)
                          {
                          t=5;
                                t=9;
                          }
                        }
                  }
                  break;

                  case 3:
                  {
                  t--;
                        if(t>9)
                        {
                          t=9;
                          t--;
                          if(t>5)
                          {
                          t=5;
                                t=9;
                          }
                        }
                  }
                  break;

                  default: break;
                }
          }
          else
          {
          key_state=KEY_PROCESS;
          }
        }
        break;
       
        case KEY_CERTAIN:                               //k8摁下,将调整标志位清0,结束调整
        {
          adjust=0;
          key_state=KEY_INIT;
        }
        break;

        default :break;
}
}

void key_loop()                              //键盘扫描周期为100ms
{
static uchar i=0;
if(TIME2MS_1)                                       
{
    TIME2MS_1=0;
        i++;
        if(i>=50)                                        //每100ms扫描一次
        {
          i=0;
          key_process();
        }
}
}

shumaguan.c

#include<reg52.h>
#include<intrins.h>
#include"timer.h"
#include"anjian.h"

uchar code s[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};           //段码表
uchar wei=0xfe;                                                        //数码管位选

void desplay()                                                        //每2ms扫描一位数码管,每16ms全部扫描一次,频率为60HZ多,不会闪烁的
{
static uchar i=0;
static uintj=0;
static uintk=0;
if(TIME2MS_2)
{
    TIME2MS_2=0;
        if(adjust==0)                                                //没有调整时间时的显示
    {
          j++;
          if(j>=500)                                                //1秒钟时间到,秒+1,调整时间
          {
          j=0;
                t++;
                if(t>=10)
                {
                  t=0;
                  t++;
                  if(t>=6)
                  {
                  t=0;
                        t++;
                        if(t>=10)
                        {
                          t=0;
                          t++;
                          if(t>=6)
                          {
                          t=0;
                                t++;
                                if(t>=10)
                                {
                                  t=0;
                                  t++;
                                }
                                  if(t==2 && t>=4)
                                  {
                                  t=0;
                                        t=0;
                                  }

                          }
                        }
                  }
                }
          }
      
          P0=s];                               //显示时间
          P2=wei;
          i++;
          if(i>7)
          i=0;
          wei=_crol_(wei,1);
    }
       
        else                                       //调整时间时的显示
        {
          j=0;                                       //调整时间时,把j=0,保证调整结束后j从0开始加
          k++;
          switch(adjust)                                       
          {
          case 1:
          {
                  if(k<=50)                                                //调整 时,显示 时 的数码管闪烁,频率为5HZ
                  {                                                                //亮100ms
                  P0=s];
                P2=wei;
                i++;
                if(i>7)
                i=0;
                wei=_crol_(wei,1);
                  }
                  if(k>50)                                               //灭100ms
                  {
                  if(i==0)
                        {
                          i=2;                                               //跳过 时 的扫描
                        }
                        if(wei==0xfe)
                        {
                          wei=0xfb;                                        //跳过 时 的扫描
                        }
                        P0=s];
                P2=wei;
                i++;
                if(i>7)
                i=0;
                wei=_crol_(wei,1);
                  }
                  if(k>100)
                  {
                  k=0;
                  }
          }
          break;

          case 2:                                                               //调整 分,显示 分 的数码管闪烁,频率为5HZ
          {
                  if(k<=50)
                  {
                  P0=s];
                P2=wei;
                i++;
                if(i>7)
                i=0;
                wei=_crol_(wei,1);
                  }
                  if(k>50)
                  {
                  if(i==3)
                        {
                          i=5;
                        }
                        if(wei==0xf7)
                        {
                          wei=0xdf;
                        }
                        P0=s];
                P2=wei;
                i++;
                if(i>7)
                i=0;
                wei=_crol_(wei,1);
                  }
                  if(k>100)
                  {
                  k=0;
                  }
                  
          }
          break;

          case 3:                                                                  //调整 秒,显示 秒 的数码管闪烁,频率为5HZ
          {
                  if(k<=50)
                  {
                  P0=s];
                P2=wei;
                i++;
                if(i>7)
                i=0;
                wei=_crol_(wei,1);
                  }
                  if(k>50)
                  {
                  if(i==6)
                        {
                          i=0;
                        }
                        if(wei==0xbf)
                        {
                          wei=0xfe;
                        }
                        P0=s];
                P2=wei;
                i++;
                if(i>7)
                i=0;
                wei=_crol_(wei,1);
                  }
                  if(k>100)
                  {
                  k=0;
                  }
                  
          }
          break;

          default : break;
          }
                    
        }
   
}

}


main.c

#include<reg52.h>
#include"timer.h"
#include"anjian.h"
#include"shumaguan.h"

void main()
{
timer0_init();                  //每2ms中断一次
EA=1;
key_init();
while(1)
{
    key_loop();               //每100ms执行一次
        desplay();               //每2ms执行一次
}
}








qq511153186 发表于 2013-5-5 20:43:31

自己调应该能搞定的

benqme 发表于 2013-5-5 21:34:32

不错我也学习一下

husange 发表于 2013-5-6 13:03:08

求指点,求批评,求板砖,感谢各位朋友指出问题互相交流帮忙进步。

qlasamour 发表于 2013-5-8 10:57:41

我也学习一下

jssd 发表于 2013-5-8 15:02:11

感觉和我以前写的差不多。。。问下楼主,多少级的菜单?

husange 发表于 2013-5-20 16:58:02

jssd 发表于 2013-5-8 15:02 static/image/common/back.gif
感觉和我以前写的差不多。。。问下楼主,多少级的菜单?

“多少级的菜单?”是什么意思啊,不好意思,我是新手
页: [1]
查看完整版本: 新手用AT89S52、按键、数码管做的可调时钟,请朋友们多指点