搜索
bottom↓
回复: 6

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

[复制链接]

出0入0汤圆

发表于 2013-5-5 14:34:55 | 显示全部楼层 |阅读模式
本帖最后由 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 int  uint;

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[1]++;
                        if(t[1]>9)
                        {
                          t[1]=0;
                          t[0]++;
                        }
                        if(t[0]==2 && t[1]>3)
                        {
                          t[0]=0;
                          t[1]=0;
                        }
                  }
                  break;
                  
                  case 2:                                        //分+1
                  {
                        t[4]++;
                        if(t[4]>9)
                        {
                          t[4]=0;
                          t[3]++;
                          if(t[3]>5)
                          {
                            t[3]=0;
                                t[4]=0;
                          }
                        }
                  }
                  break;
                  
                  case 3:                                          //秒+1
                  {
                    t[7]++;
                        if(t[7]>9)
                        {
                          t[7]=0;
                          t[6]++;
                          if(t[6]>5)
                          {
                            t[6]=0;
                                t[7]=0;
                          }
                        }
                  }
                  break;
                  
                  default: break;
                }
          key_state=KEY_PROCESS;
        }
        break;

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

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

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

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

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

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

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

                  case 3:
                  {
                    t[7]--;
                        if(t[7]>9)
                        {
                          t[7]=9;
                          t[6]--;
                          if(t[6]>5)
                          {
                            t[6]=5;
                                t[7]=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 uint  j=0;
  static uint  k=0;
  if(TIME2MS_2)
  {
    TIME2MS_2=0;
        if(adjust==0)                                                //没有调整时间时的显示
    {
            j++;
          if(j>=500)                                                //1秒钟时间到,秒+1,调整时间
          {
            j=0;
                t[7]++;
                if(t[7]>=10)
                {
                  t[7]=0;
                  t[6]++;
                  if(t[6]>=6)
                  {
                    t[6]=0;
                        t[4]++;
                        if(t[4]>=10)
                        {
                          t[4]=0;
                          t[3]++;
                          if(t[3]>=6)
                          {
                            t[3]=0;
                                t[1]++;
                                if(t[1]>=10)
                                {
                                  t[1]=0;
                                  t[0]++;
                                }
                                  if(t[0]==2 && t[1]>=4)
                                  {
                                    t[0]=0;
                                        t[1]=0;
                                  }

                          }
                        }
                  }
                }
          }
      
          P0=s[t];                                 //显示时间
          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[t];
                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[t];
                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[t];
                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[t];
                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[t];
                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[t];
                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执行一次
  }
}








阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2013-5-5 20:43:31 来自手机 | 显示全部楼层
自己调应该能搞定的

出0入0汤圆

发表于 2013-5-5 21:34:32 来自手机 | 显示全部楼层
不错我也学习一下

出0入0汤圆

 楼主| 发表于 2013-5-6 13:03:08 | 显示全部楼层
求指点,求批评,求板砖,感谢各位朋友指出问题互相交流帮忙进步。

出0入0汤圆

发表于 2013-5-8 10:57:41 | 显示全部楼层
我也学习一下

出0入55汤圆

发表于 2013-5-8 15:02:11 | 显示全部楼层
感觉和我以前写的差不多。。。问下楼主,多少级的菜单?

出0入0汤圆

 楼主| 发表于 2013-5-20 16:58:02 | 显示全部楼层
jssd 发表于 2013-5-8 15:02
感觉和我以前写的差不多。。。问下楼主,多少级的菜单?

“多少级的菜单?”是什么意思啊,不好意思,我是新手
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 16:12

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表