找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2755|回復: 4
打印 上一主題 下一主題
收起左側

矩陣鍵盤輸入數(shù)字,數(shù)碼管實現(xiàn)倒計時,單片機初學者,不知道這個哪里錯了

[復制鏈接]
跳轉到指定樓層
樓主
ID:882907 發(fā)表于 2021-2-4 21:40 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
#include <REGX52.H>

unsigned char NixieTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

unsigned char KeyNumber=0,sec;

void Delay(unsigned int xms)
{
  unsigned char i,j;
  while(xms)
  {
        i = 2;
        j = 239;
        do
        {
           while (--j);
        }while (--i);
        xms--;
  }
}

void Nixie(unsigned char Location,Number)
{
        switch(Location)
        {
                case 1:P2_4=1;P2_3=1;P2_2=1;break;
                case 2:P2_4=1;P2_3=1;P2_2=0;break;
                case 3:P2_4=1;P2_3=0;P2_2=1;break;
                case 4:P2_4=1;P2_3=0;P2_2=0;break;
                case 5:P2_4=0;P2_3=1;P2_2=1;break;
                case 6:P2_4=0;P2_3=1;P2_2=0;break;
                case 7:P2_4=0;P2_3=0;P2_2=1;break;
                case 8:P2_4=0;P2_3=0;P2_2=0;break;
        }
        P0=NixieTable[Number];
        Delay(1);
        P0=0x00;
}

unsigned char MatrixKey()
{
       

        P1=0xFF;
        P1_3=0;
        if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=1;}
        if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=5;}
        if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=9;}
        if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=13;}

        P1=0xFF;
        P1_2=0;
        if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=2;}
        if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=6;}
        if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=10;}
        if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=14;}

        P1=0xFF;
        P1_1=0;
        if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=3;}
        if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=7;}
        if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=11;}
        if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=15;}

        P1=0xFF;
        P1_0=0;
        if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=4;}
        if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=8;}
        if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=12;}
        if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=16;}

        return KeyNumber;
}

void Timer0Init(void)                //1毫秒@12.000MHz
{
        TMOD &= 0xF0;                //設置定時器模式
        TMOD |= 0x01;                //設置定時器模式
        TL0 = 0x18;                //設置定時初值
        TH0 = 0xFC;                //設置定時初值
        TF0 = 0;                //清除TF0標志
        TR0 = 1;                //定時器0開始計時
        ET0=1;
        EA=1;
        PT0=0;                    
}

void main()
{
       
        Timer0Init();
        while(1)
        {       
                if(P3_0==0)
                {
                Delay(20);
                while(P3_0==0);
                Delay(20);
                sec=MatrixKey();
                }
                Nixie(1,sec);
        }
}


void Timer0_Routine() interrupt 1
{       
        static unsigned int T0Count;
        TL0 = 0x18;                //設置定時初值
        TH0 = 0xFC;                //設置定時初值
        T0Count++;
        if(T0Count>=1000)
        {
                T0Count=0;
                sec--;
        }
}

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發(fā)
ID:332444 發(fā)表于 2021-2-5 09:35 | 只看該作者
矩陣代碼寫的太多了,看得亂就不想看了,可參https://blog.csdn.net/xianfajushi/article/details/80884859  寫得簡潔些
回復

使用道具 舉報

板凳
ID:213173 發(fā)表于 2021-2-5 14:38 | 只看該作者
  1. #include <REGX52.H>

  2. unsigned char NixieTable[]={
  3.                 0x3f,0x06,0x5b,0x4f,
  4.                 0x66,0x6d,0x7d,0x07,
  5.                 0x7f,0x6f,0x77,0x7c,
  6.                 0x39,0x5e,0x79,0x71,0x3d};

  7. unsigned char KeyValue=0;
  8. bit flag=0;

  9. void Delay(unsigned int xms)
  10. {
  11.   unsigned char i,j;
  12.   while(xms)
  13.   {
  14.         i = 2;
  15.         j = 239;
  16.         do
  17.         {
  18.            while (--j);
  19.         }while (--i);
  20.         xms--;
  21.   }
  22. }

  23. void Nixie(unsigned char Number)
  24. {
  25.         static unsigned char i;
  26.         unsigned char a[2];

  27.         if(Number>9)
  28.                 a[0]=NixieTable[Number/10];
  29.         else a[0]=0x00;
  30.         a[1]=NixieTable[Number%10];
  31.         P0=0x00;
  32.         P2&=0xe3;
  33.         P2|=~((0x00+i)<<2);
  34.         P0=a[i];
  35.         i=++i%2;
  36.         Delay(1);
  37. }

  38. void MatrixKey()
  39. {
  40.         static unsigned char count=0;
  41.         static bit sign=0;
  42.         P1=0xf0;                                        //賦值P1 1111 0000
  43.         if(P1!=0xf0)                                //檢測有按鍵按下
  44.         {
  45.                 if(++count>=10 && sign==0)
  46.                 {                       
  47.                         sign=1;                        //按鍵自鎖標志置1
  48.                         switch(P1)
  49.                         {
  50.                                 case(0Xe0):KeyValue = 0;break;
  51.                                 case(0Xd0):KeyValue = 1;break;
  52.                                 case(0Xb0):KeyValue = 2;break;
  53.                                 case(0X70):KeyValue = 3;break;
  54.                         }
  55.                         P1=0x0f;                        //賦值P1 0000 1111
  56.                         switch(P1)
  57.                         {
  58.                                 case(0X0e):KeyValue+= 1;break;
  59.                                 case(0X0d):KeyValue+= 5;break;
  60.                                 case(0X0b):KeyValue+= 9;break;
  61.                                 case(0X07):KeyValue+=13;break;
  62.                         }
  63.                 }
  64.         }
  65.         else                                                //鍵抬起
  66.         {
  67.                 sign=0;                                //按鍵自鎖標志清0
  68.                 count=0;                                //消抖計數(shù)清0
  69.         }
  70. }

  71. void Timer0Init(void)                //1毫秒@12.000MHz
  72. {
  73.         TMOD= 0x01;                //設置定時器模式
  74.         TL0 = 0x18;                //設置定時初值
  75.         TH0 = 0xFC;                //設置定時初值
  76.         TR0 = 1;                //定時器0開始計時
  77.         ET0 = 1;
  78.         EA  = 1;         
  79. }

  80. void main()
  81. {        
  82.         Timer0Init();
  83.         while(1)
  84.         {        
  85.                 if(flag==0)
  86.                         MatrixKey();
  87.                 if(P3_0==0)
  88.                         flag=1;
  89.                 Nixie(KeyValue);
  90.         }
  91. }

  92. void Timer0_Routine() interrupt 1
  93. {        
  94.         static unsigned int T0Count;
  95.         TL0 = 0x18;                //設置定時初值
  96.         TH0 = 0xFC;                //設置定時初值
  97.         if(KeyValue>0&&flag==1)
  98.         {
  99.                 T0Count++;
  100.                 if(T0Count>=1000)
  101.                 {
  102.                         T0Count=0;
  103.                         KeyValue--;
  104.                         if(KeyValue==0)
  105.                         {
  106.                                 flag=0;
  107.                         }
  108.                 }
  109.         }
  110. }
復制代碼
回復

使用道具 舉報

地板
ID:883031 發(fā)表于 2021-2-5 15:38 | 只看該作者
if(P3_0==0)
                {
                Delay(20);
                while(P3_0==0);
                Delay(20);
                sec=MatrixKey();
                }
紅色部分,如果是抖動,可能會誤動作。
另外,你的鍵值掃描,如果沒有按鍵按下,返回的是什么值?可能會是上次的值。

評分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

5#
ID:883031 發(fā)表于 2021-2-5 15:49 | 只看該作者
unsigned char idata DrvKey;                        //驅動線值
unsigned char idata ScnKey;                        //掃描線值
unsigned char KeyValue;
/*******************************************************************************
*   函數(shù)原型:bit KeyScan(void);
*   功    能:鍵盤掃描子程序,判斷是否有鍵按下。
*******************************************************************************/
bit KeyScan(void)
{
        DRVKEY &= 0xf0;
        HX = 0;
        ScnKey = ~SCNKEY;      // ^ 0xff列線值取反,以便判斷
        ScnKey &= 0x1e;       

        if (ScnKey != 0)                //列線值不全為0,則有鍵按下
        {
                return TRUE;
        }
        else                    //否則,無鍵按下
        {
                return FALSE;
        }       
}

/*******************************************************************************
*   函數(shù)原型:void Delay(unsigned char i);
*   功    能:延時子程序,用于去抖。
*******************************************************************************/
void Delay(unsigned char i)
{
        int j = 0;
        int k = 0;
        k = i * i;
        while (j < k)
        {
                j++;
        }
}
/*******************************************************************************
*   函數(shù)原型:bit AvoidWobble(void);
*   功    能:去抖子程序,用于消除抖動,判斷是否真有鍵按下。
*******************************************************************************/
bit AvoidWobble(void)
{
        Delay(5);                //延時再讀
        if (KeyScan())                        //仍有鍵按下,返回1
        {
                return TRUE;
        }
        else                    //無鍵按下則為抖動
        {
                return FALSE;
        }
}
/*******************************************************************************
*   函數(shù)原型:unsigned char GetKey(void);
*   功    能:鍵盤子程序。最大8*8鍵盤。
*******************************************************************************/
unsigned char GetKey(void)
{
        unsigned char i;
        unsigned char j;
        unsigned char Key_Value = 0;
        unsigned char temp = 0x01;
        HX = 1;
       
    if (KeyScan())              //有鍵按下取其值
    {
            if (AvoidWobble())                //確實有鍵按下,取其值
            {
                           for (i = 0;i < DRV_NUM;i++)   //行線移位送0
                    {
                            DRVKEY = (temp << i) ^ 0x0f;

                            for (j =1;j < SCN_NUM + 1;j++)   //列線移位掃描
                            {
                                ScnKey = SCNKEY;         //讀列線值
                                    ScnKey >>= j;            
                                    ScnKey &= 0x01;
                                    if (ScnKey == 0)         //判斷第j位是否為0
                                    {
                                            Key_Value += (j - 1);        //計算健值
                                              while(KeyScan())       //等待按鍵松開
                        {
                            ;
                        }
                                            return Key_Value;
                                    }
                            }
                            Key_Value += SCN_NUM;          //第i行無按鍵按下,鍵值加列線值,掃描第i+1行
                    }
                   return 255;
            }
    }
    else
    {
        return 255;
    }
}

評分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表