找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2269|回复: 3
打印 上一主题 下一主题
收起左侧

按下k2 数码管开始跑表,但是数码管上显示不出跑表过程

[复制链接]
跳转到指定楼层
楼主
ID:115593 发表于 2016-5-1 10:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
第二次按下K2暂停跑表,正常显示xx秒xx毫秒。
#include "reg52.h"
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define N_key    0     //按键没被按下         
#define S_key    1   //  单击        
#define D_key    2    //双击         
#define L_key    3     //长安        

#define key_state_0 0
#define key_state_1 1
#define key_state_2 2
#define key_state_3 3
sbit key1 = P3^0;
sbit key2 = P3^2;   
unsigned char time_10ms_ok = 0;
unsigned char key = 0;
//引脚定义:               
sbit LED8_0 = P1^0;        //定义数码管阳级控制脚(千位)
sbit LED8_1 = P1^1;        //定义数码管阳级控制脚(百位)
sbit LED8_2 = P1^2;        //定义数码管阳级控制脚(十位)
sbit LED8_3 = P1^3;        //定义数码管阳级控制脚(个位)
sbit LED=P1^7;
sbit led=P1^6;
uchar  Flag_Fresh = 0; // 刷新标志
bit flag=1;
bit sflag,dflag,lflag;
bit T1keyflag,INT0flag;
unsigned char disp_BUF[4];        //显示缓冲区(4个字节,对应4个数码管)
                                //disp_BUF[0]   disp_BUF[1]   disp_BUF[2]   disp_BUF[3]
                                //    千位         百位         十位           个位
uchar shi,fen,counter;       
uint count=0;
uint miao=0;                       
const unsigned char leddata[]={

                0x03,  //"0"         显示码/段码/字形码
                0x9F,  //"1"
                0x25,  //"2"
                0x0D,  //"3"
                0x99,  //"4"
                0x49,  //"5"                                                                                          
                0x41,  //"6"
                0x1F,  //"7"
                0x01,  //"8"
                0x09,  //"9"
                0x11,  //"A"
                0xC1,  //"B"
                0x63,  //"C"
                0x85,  //"D"
                0x61,  //"E"
                0x71,  //"F"
                0x91,  //"H"
                0xE3,  //"L"
                0x13,  //"n"
                0x83,  //"u"
                0x31,  //"P"
                0xC5,  //"o"
                0xFD,  //"-"
                0xFF,  //熄灭
                                0xFE,
                0x11  //自定义
                                 };
enum KeyState{StateInit,StateAffirm,StateSingle,StateRepeat};
//======================================函数声明=======================
  void delay20ms(void);
  void HEXtoBCD_miao(uchar count);
  void display_LED(void);
    void HEXtoBCD_shi(uchar miao);
     void delay();
//=================延时函数================================================//
void delay()
{
        unsigned int j;
        //for(i=0; i<100; i++)
                for(j=0; j<200; j++);        //软件延时
}
//=========================T0初始化========================================//
void T0_init(void)
{
        TMOD = 0x01;                                    // 设置定时器0工作在模式1下
        TH0 = 0xDC;                                             // 定时10ms
        TL0 = 0x00;                                             // 赋初始值
        PT0=0;                                         
        EA=1;
        ET0=1;
   // TR0 = 1;//启动定时器0;
       
}
//======================================外部中断0初始化================
void INT0init()
{
        EA=1;
        EX0=1;
        IT0=1;          
}
//===================================================T1初始化=============
void T1_Init(void)                //10毫秒@12.000MHz
{
        TMOD &= 0x0F;                //设置定时器模式
        TMOD |= 0x10;                //设置定时器模式
         PT1=1;
        TL1 = 0xF0;                //设置定时初值
        TH1 = 0xD8;                //设置定时初值
        TF1 = 0;                //清除TF1标志
        TR1 = 1;                //定时器1开始计时
        EA=1;
        ET1=1;
}
//=============================================开机初始化=================
void start_init()
{
            delay20ms();
            disp_BUF[0] = leddata[22];
            disp_BUF[1] = leddata[22];
            disp_BUF[2] = leddata[22];
            disp_BUF[3] = leddata[22];
            P0=0xff;
}
//===================延时环数==============================================//
void Delay5ms()                //@12.000MHz
{
        unsigned char i, j;

        i = 10;
        j = 183;
        do
        {
                while (--j);
        } while (--i);
}

void delay20ms(void)
{
        unsigned int i;
        for(i=0; i<3850; i++);
}
//============================//数码管显示=====================================//
void display_LED(void)                        
{
        unsigned char temp,i;
       
        temp = 0xfe;                //1111 1110          1111 1100                 1111 1010
                               //                1111 1101               1111 1011
        for(i=0; i<4; i++)       
        {
                P1 = temp;                        //temp中是“位选”
                temp = (temp<<1)|0x01;
                P0 = disp_BUF[i];        //送“段码”(要显示的内容)
                delay();                //扫描刷新时间(频率)
                                //时间长——会闪烁、时间短——会模糊(有其他的笔画)
        }
}
//========函数名称:HEXtoBCD===============================================
//函数功能:转换一个小于9999的十六进制数为BCD码(非压缩)并放入显示缓冲区disp_BUF[0]--disp_BUF[3]中================================//
void HEXtoBCD_shi(uchar miao)
{
   if(shi> 59)shi =0;
   disp_BUF[0] = leddata[miao/10];//得到时的高位,并送到相应的显示缓冲区       
           P0=0xff;
    if(flag)
       {
        disp_BUF[1] = leddata[miao%10]&0xfe;      //小数点闪烁
       }
       else
   {
   disp_BUF[1] = leddata[miao%10];  //得到时的低位,并送到相应的显示缓冲区
         P0=0xff;
}
}
void HEXtoBCD_miao(uchar count)
{
  if(miao>99) miao=0;

   disp_BUF[2] = leddata[count/10];        //得到秒的高位,并送到相应的显示缓冲区
        P0=0xff;  //消除鬼影

   disp_BUF[3] = leddata[count%10];        //得到秒的位,并送到相应的显示缓冲区
   P0=0xff;
}
// ============================================外部中断counter处理函数========================
void counterhandle()
{
  if(counter==1)
  {
  EA=1;
  TR0=1;
  }
else if(counter==2)
  {
    EA=1;
    TR0=0;
  }
else if(counter==3)
{
  TR0=0;
   EA=1;
   count=0;
   miao=0;
   counter=0;
}
}

//============================================标志处理函数==============================
  void flaghandle()
  {

if(dflag==1)            
{                        
                            disp_BUF[0] = leddata[1];
                             P0=0xff;
                            disp_BUF[1] = leddata[2];
                               P0=0xff;
                            disp_BUF[2] = leddata[3];
                              P0=0xff;
                            disp_BUF[3] = leddata[4];
                               P0=0xff;
                            dflag=0;
  }
if(sflag==1)
{

                            disp_BUF[0] = leddata[16];
                              P0=0xff;
                            disp_BUF[1] = leddata[14];
                              P0=0xff;
                            disp_BUF[2] = leddata[17];
                              P0=0xff;
                            disp_BUF[3] = leddata[21];
                               P0=0xff;
                            sflag=0;
}
if(lflag==1)
{

      if(flag)
      {               
                           disp_BUF[0] = leddata[23];
                           disp_BUF[1] = leddata[23];
                           disp_BUF[2] = leddata[23];
                           disp_BUF[3] = leddata[23];
                           }
         else              {  
                            disp_BUF[0] = leddata[22];
                           disp_BUF[1] = leddata[22];
                           disp_BUF[2] = leddata[22];
                           disp_BUF[3] = leddata[22];
                           }
                          lflag=0;

       }                 
  }


//===========================================按键扫描======================
unsigned char key_driver(void)
{
    static unsigned char key_state = key_state_0;   // 变量初始化
    static unsigned  int  keytime = 0;
    unsigned char  key_return = N_key;
   bit key_press;        //定义一个位                                                                                         

    key_press = key1;                                                            //P3^0的按下状态,按下0,不按为1

    switch (key_state)                                                                                        
    {                                                                                                                             
      case key_state_0:                                                             
        if (!key_press) key_state = key_state_1;                                       //如果按键被按下,置状态1
        break;                                                                                                          
                                                            
      case key_state_1:                                                                      
       if (!key_press)                                                                                            //判断状态1
        {                                                                                                                                  //如果按键还是被按下的 “去抖”
             keytime = 0;                                                            //按下时间初始值为0
             key_state = key_state_2;                                                           //按键还是被按下的,置状态2
        }                                                                                                                          
        else                                                                                                                        
             key_state = key_state_0;                                                    //否则置状态0,再次进行按键判断
        break;                                                                                                           
                                                                                                                                      
      case key_state_2:                                                                                           
        if(key_press)                                                 //如果按键是没被按下的,key_press为1 即条件为真。按下为0,条件为假                                               
        {                                                                           
             key_return = S_key;        // 状态2中按键是被松开的,即判断为单击
             key_state = key_state_0;           //返回状态0,进行下次的按键操作
        }                                                                                        
        else if (++keytime >= 1000)            // if条件为假按键还是被按下的,进行key_time自增运算,再进行key_time>=1000的判断
        {                                                                                                  
             key_return = L_key;        //如果条件成立、则定义为长按的操作
             key_state = key_state_3;   // 进入状态3
        }                                                                
        break;                                                                         //跳出循环
                                                                                               
      case key_state_3:                                  // 执行状态3的操作
        if (key_press) key_state = key_state_0;    //如果按键被松开了,返回状态0
        break;                                                                                  
    }                                                                                                
    return key_return;                                                 //返回值key_return
}                                                                                        
unsigned char key_read(void)                                 // 键值处理函数
{                                                                                                                           
    static unsigned char key_m = key_state_0 ; //静态变量 key_m,key_time_1。
     static unsigned int key_time_1 = 0;
    unsigned char key_return = N_key,key_temp;                         //

    key_temp = key_driver();                                         //key_temp=        key_return。(S_key或者L_key)
                                                                                    
    switch(key_m)                                                
    {                                                                                   
        case key_state_0:                                            //状态0的操作
            if (key_temp == S_key )                   // 如果判断为单击
            {                                                                   
                 key_time_1 = 0;             // key_time_1初始值为0
                 key_m = key_state_1;                 // 进入状态2
            }                                                          
            else                                                
                 key_return = key_temp;   // 状态0里,将 key_temp的值给key_return  
            break;                                                  
                                                                               
        case key_state_1:                                 //状态1
            if (key_temp == S_key)       //单击之后还有一次按键     
            {
                 key_return = D_key;    // 定为双击      
                 key_m = key_state_0;  // 返回状态0
            }
            else                                
            {                                 
                 if(++key_time_1 >= 500)//key_time_1        自增,如果大于等于500 (两次按键时间间隔大于50)
                 {
                      key_return = S_key;// 定义为单击      
                      key_m = key_state_0;// 返回状态0   
                 }
             }
             break; //跳出循环
    }
    return key_return;                                   // 返回值key_return
}
//===========================================主函数=======================
void main(void)  
{
         T1_Init() ;
         T0_init();
         INT0init();
     start_init();       
        while(1)
    {
    if(INT0flag==1)
       {
              HEXtoBCD_shi(miao);                 
        HEXtoBCD_miao(count);
         INT0flag=0;
         display_LED();
        }
      else if(T1keyflag==1)
      {
        T1keyflag=0;
         display_LED();                 //数码管显示
       }
                              
                }
}       
//======================================T0    T1   中断函数========================               
void T0_ISR(void) interrupt 1
{
   TH0 = 0xDC;                                             // 定时10ms
        TL0 = 0x00;
     count++;
             if(count==100)
        {
        count=0;
        miao++;
        led=~led;
         flag=~flag;
        if(miao>59)
        miao=0;
        }

}
void T1_ISR(void) interrupt 3
  {
    TL1 = 0xF0;                //设置定时0初值
        TH1 = 0xD8;                //设置定时初值
        LED=~LED;
     flaghandle();

        key = key_read(); //没10ms得到一次 key_return
    T1keyflag=1;
                        if (key == L_key)  //长按清零
                        {
                          lflag=1;

                        }
                else if(key == S_key) //单击
            {
                                sflag=1;
                        }
            else if(key == D_key) //双击停止
            {
               dflag=1;
                        }

  }
  void INT0_ISR(void) interrupt 0
  {
  delay20ms();
  EA=0;
  counter++;
  INT0flag=1;
  counterhandle();
  }
       






分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:79544 发表于 2016-5-1 10:33 | 只看该作者
按键函数好复杂啊,看不懂
回复

使用道具 举报

板凳
ID:99341 发表于 2016-5-2 15:13 | 只看该作者
楼主把电路图发上来说不定有人帮你
回复

使用道具 举报

地板
ID:99341 发表于 2016-5-2 15:15 | 只看该作者
有个2051电子钟带跑秒 新建文件夹.rar (76.62 KB, 下载次数: 8)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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