<acronym id="xonnx"></acronym>
      <td id="xonnx"></td>
    1. <pre id="xonnx"></pre>

      1. 專注電子技術學習與研究
        當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

        AVR單片機掃描4X4矩陣鍵盤并數碼管顯示程序

        作者:huqin   來源:本站原創   點擊數:  更新時間:2014年02月26日   【字體:

         /*
                  program name :   keyboard ;
             功能描述 :  掃描16個按鍵(4X4),并把鍵值顯示在數碼管上(兩位);
         
             要點 :  在掃描按鍵時運用了比較復雜的兩個for()循環嵌套式
             掃描方案,大大減少了程序量,循環嵌套方案讓我糾結了好久,
         鍵值有0~9,上,下,左,右,確認,清零;
         
          體會:  又一個里程碑,淚奔啊...我似乎成了 代碼男神  啊...;
          實驗用時:  約等于14小時(每天2小時X7天);
         
         
         完成時間: 2013-11-19 23:58:22
         
        */
        #include <iom16v.h>
        #include <macros.h>

        #define uint8  unsigned char      //宏定義8位數據類型;
        #define uint16 unsigned int       //宏定義16位數據類型;

         

                  //  0 , 1  ,  2  , 3  , 4  , 5  , 6  ,
        uint8 ak[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
                //    7  , 8  , 9 , 上  , 下   左 , 右  ;
                    0x07,0x7f,0x6f,0x62 ,0x54,0x21,0x0c};
        uint8  ge=8,shi=8 ,si=0;

        void bit(uint8 h)    //數碼管位選使能函數;
        {
           PORTB|=0X02;   //數碼管位選置1(透明狀態);
           if(h==0)
            {
        PORTB&=0XFD;   //清零(鎖存狀態);
        }
        }


        void dat(uint8 u)   //數碼管數據使能函數;  
        {
           PORTB|=0X01;  
           if(u==0)
           {
             PORTB&=0XFE;
           }
        }

        void buzz(uint8 k)    //蜂鳴器函數;
        {
           if(k==0)
            {
         PORTC&=~(0X80);
        }
              else  PORTC|=0X80;

        }


        void delay(uint8 j)          //1=1000個計數周期;
        {
           uint16  h=0;
           while(j--)
            {
        for(h=0;h<1000;h++);
        }
        }


        void mega16()       //初始化各個IO口;
        {

          DDRA=0XFF;    //PA輸出;
          DDRB=0XFF;    //PB輸出;
          PORTA=0X00;   //PA 輸出全0;
          delay(1);     //延時一下,1000個計數周期;
          bit(0);          //數碼管共陰極全零;
          PORTA=0X3F;    //數碼管數據口裝載數據顯示0;
          PORTB=1<<2;    //打開led流水燈燈;
          dat(0);        //鎖存數碼管數據口數據,八個數碼管顯示0;

          delay(30);    //延時一下;  
          DDRD=0X0F;   //PD口高四位輸入,第四位輸出;
          PORTD=0XFF;  //PD輸入口內部上拉,輸出口輸出全1;
          DDRC=0XFF;   //PC口全部輸出模式;
          PORTC=0X00;   //PC口輸出全零;
        }

        void led()
        {
           static uint8 g=0;
          
        PORTA=0Xff;  //向數碼管輸入顯示數據時,必先將共陰極全部置一,
                 //否則數碼管會出現陰影;
        bit(0);     //八個數碼管共陰極置一(低電平有效);
           switch(g)
        {  case 0:  PORTA=ak[ge] ;dat(0);PORTA=0XFE;break;//數碼管個位;
          case 1:  PORTA=ak[shi];dat(0);PORTA=0XFD;break; //數碼管十位;
          default: break;   //否則...
        }
              bit(0);
               g++;
                    if(g==2)
        {
          g=0;
        }
        }

         

        shu(uint8 c)
        {
                  if(c<=2) {c++;}  //1~3;
        else if(c==3) {ge=10;shi=10; return 0;}   //上;
             else if(c==11){ge=c ; shi=c; return 0;}   //下;
        else if(c==7) {ge=12,shi=12; return 0;}   //左;
        else if(c==15) {ge=13,shi=13; return 0;}   //右;
        else if(c==13){return 0;}      //enter 確認;  ;
        else if(c==14){ge=0; shi=0;  return 0;}  //清零;
        else if((c>=8)&&(c<=10)){c-=1;}  //7~9;
        else if(c==12){ge=0;return 0;}
        else { ;}    //4~6;
         
         ge=c; shi=0;      
           
         
           
         

        }


         key()
        {   
            uint8  i=0 ,y=0,temp=0x10 ,v=0,ke=0 ,en[]={0xfe,0xfd,0xfb,0xf7};
        //  temp用于檢測每一行某個鍵是否按下; en數組是四列檢測;            
           
        for(v=0;v<4;v++)     //v每加一代表檢測一列;

         PORTD=en[v];     //檢測四列;
         temp=0x10;       
        for(y=0;y<4;y++)    //y每加一,代表檢測一列中的一個按鍵;
        {
        if((PIND&temp)==0)    //如果有鍵被按下,進入;
         { 
            for(i=0;i<250;i++){led();}   //去抖延時并且掃描數碼管;
        if((PIND&temp)==0)        //再次確認有鍵被按下;
        {
           buzz(1);      //蜂鳴器開;
        for(i=0;i<200;i++){led();}   //鳴響延時;
        for(i=0;i<200;i++){led();}   //鳴響延時;
        buzz(0);      //蜂鳴器關;            
          
        //===============生成鍵值部分================
        if(v==1)y+=3;       //檢測到第二行;        //
        else if(v==2)y+=6;  //檢測到第三行;        //
        else if(v==3)y+=9;  //檢測到第四行;        //
         else {;}          //檢測到第一行;        //
        ke=v+y;    //生成鍵值;                     //
        //===========================================
        shu(ke);    // 發送鍵值;
            while((PIND&temp)==0)led();   //等待按鍵彈起;
          for(i=0;i<250;i++){led();}    //等待一下;
           while((PIND&temp)==0)led();   //再次確認一下按鍵是否彈起;
         
         
          return 0;    //結束函數;
        }
                                      
           
         } 
         
          temp=temp<<1;  //左移一下代表檢測下一個按鍵;
         
         }
               
                  
             }
          
        }


        void main(void)
        {
         

             mega16();  //初始化各個IO口;
        buzz(1);   //蜂鳴器開;
        delay(15); //延時1.5萬計數周期;
        buzz(0);   //蜂鳴器關;
        PORTA=0xff;   //載入全1;
        bit(0);       //把全1數據鎖存在數碼管共陰極(數碼管滅);
        delay(15);   //延時1.5萬計數周期;
         
        while(1)
         {
            led();  //掃描數碼管; 
        key();  //掃描鍵盤;
                 
         
          }
        }
         

        關閉窗口

        相關文章

        欧美性色欧美精品视频,99热这里只有精品mp4,日韩高清亚洲日韩精品一区二区,2020国自产拍精品高潮