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

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

        用51單片機中斷編寫的4x4鍵盤程序

        作者:未知   來源:山澗一溪流   點擊數:  更新時間:2014年06月22日   【字體:
            應用查詢掃描編寫鍵盤程序,由于要給按鍵去抖動,程序變得比較復雜和冗長(詳見2013年9月29日博文《MSP430和AT89C51單片機4x4鍵盤C程序》),如果用中斷編寫,設置中斷響應在下降沿時執行中斷,則程序編寫不用去抖動判斷,所以相比較要簡單很多!下面用匯編和C語言兩種方式編寫4X4鍵盤程序!
            一、匯編程序
                    ORG 0000H
                    LJMP MAIN
                    ORG 0003h
                    Ljmp ZD0
                    ORG 000Bh
                    LJMP TZD0
                    ORG 0013h
                    Ljmp ZD1
                    ORG 001Bh
                    LJMP TZD1
                   ORG 0040H
        MAIN: Mov TMOD,#66h
                   MOV TH0,#0ffh
                   MOV TL0,#0ffh
                   MOV TH1,#0ffh
                   MOV TL1,#0ffh
                   SETB EA
                   SETB ET0
                   SETB TR0
                   SETB ET1
                   SETB TR1
                   SETB IT0
                   SETB IT1
                   SETB EX0
                   SETB EX1
        xh:      mov P1,#0feh
                  Lcall Delay
                  mov P1,#0fdh
                  Lcall Delay
                  mov P1,#0fbh
                  Lcall Delay
                  mov P1,#0f7h
                  Lcall Delay
                  SJMP xh
        ZD0:  JNB P1.0,dat1
                 JNB P1.1,dat2
                 JNB P1.2,dat3
                 JNB P1.3,dat4
        dat1: mov P2,#06h  ;1
                 sjmp ZD0R
        dat2: mov P2,#5bh  ;2
                 sjmp ZD0R
        dat3: mov P2,#4fh  ;3
                 sjmp ZD0R
        dat4: mov P2,#66h  ;4
        ZD0R: reti

        ZD1:  JNB P1.0,dat5
                 JNB P1.1,dat6
                 JNB P1.2,dat7
                 JNB P1.3,dat8
        dat5: mov P2,#6dh  ;5 0110
                 sjmp ZD1R
        dat6: mov P2,#7dh  ;6
                 sjmp ZD1R
        dat7: mov P2,#07h  ;7
                 sjmp ZD1R
        dat8: mov P2,#7fh  ;8
        ZD1R: reti
        TZD0: JNB P1.0,dat9
                   JNB P1.1,dat0
                   JNB P1.2,dat10
                   JNB P1.3,dat11
        dat9:   mov P2,#6fh  ;9
                   sjmp ZD0R
        dat0:   mov P2,#3fh  ;0
                   sjmp ZD0R
        dat10: mov P2,#77h  ;A
                   sjmp ZD0R
        dat11: mov P2,#7ch  ;B
        TZD0R:reti

        TZD1: JNB P1.0,dat12
                   JNB P1.1,dat13
                   JNB P1.2,dat14
                   JNB P1.3,dat15
        dat12: mov P2,#39h  ;C
                   sjmp TZD1R
        dat13:mov P2,#5eh  ;D
                  sjmp TZD1R
        dat14:mov P2,#79h  ;E
                  sjmp TZD1R
        dat15:mov P2,#71h  ;F
        TZD1R:reti
        Delay:mov r7,#10d
              djnz r7,$
              ret
              end  
           

        二、C語言程序(掃描P1)
          #include"reg51.h"
        int yu[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
                  0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
        int i,j,k,time,temp,dat;
        void delay(time)
        {
          while(time--)
           for(i=0;i<120;i++);
        }
        void main()
        {
          P2=0x40;
          TMOD=0x66;  //設定定時計數器T0、T1為方式2計數模式
          TH0=0xFF;
          TL0=0xFF;
          TH1=0xFF;
          TL1=0xFF;
          IE=0x8F;    //開總中斷和定時計數器兩個中斷,兩個外中斷
          IT0=1;
          IT1=1;      //設置外中斷為下降沿觸發
          TR0=1;
          TR1=1;       //打開定時計數器開始計數
          while(1)
            {
             P1=0xfe;
             delay(1);
             P1=0xfd;
             delay(1);
             P1=0xfb;
             delay(1);
             P1=0xf7;
             delay(1);
            }
        }
        void intsvr0(void) interrupt 0  using 1
        {
         
          temp=P1;
          switch(temp)
                    {
                   case 0xfe:key=0;break;
                   case 0xfd:key=1;break;
                   case 0xfb:key=2;break;
                   case 0xf7:key=3;break;
                   default:break;
                    }

          P2=yu[dat];
        }
        void timer0(void) interrupt 1 using 1
        {
         
          temp=P1;
          if(temp==0xfe)  dat=4;
          if(temp==0xfd) dat=5;
          if(temp==0xfb) dat=6;
          if(temp==0xf7) dat=7;  
          P2=yu[dat];
        }
        void intsvr1(void) interrupt 2 using 1
        {
         
          temp=P1;
          if(temp==0xfe) dat=8;
          if(temp==0xfd) dat=9;
          if(temp==0xfb) dat=10;
          if(temp==0xf7) dat=11;  

          P2=yu[dat];
        }
        void timer1(void) interrupt 3 using 1
        {
          int dat;
          temp=P1;
          switch(temp)
                    {
                   case 0xfe:key=12;break;
                   case 0xfd:key=13;break;
                   case 0xfb:key=14;break;
                   case 0xf7:key=15;break;
                   default:break;
                    }

          P2=yu[dat];
          
        } 
        /*************************************************************/
        三、C語言(掃描P3的P3.0、P3.1、P3.6、P3.7)
        從這個程序也可以看出51單片機I/O口沒有方向性,輸入輸出都可讀寫,而且在一個寄存器中。注意該程序對應電路圖與上圖的區別。

        #include"reg51.h"
        sbit pp0=P3^0;
        sbit pp1=P3^1;
        sbit pp2=P3^6;
        sbit pp3=P3^7;
        int yu[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
                  0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
        int i,j,k,time,temp,dat;
        void delay(time)
        {
          while(time--)
           for(i=0;i<120;i++);
        }
        void main()
        {
          P2=0x40;
          TMOD=0x66;  //設定定時計數器T0、T1為方式2計數模式
          TH0=0xFF;
          TL0=0xFF;
          TH1=0xFF;
          TL1=0xFF;
          IE=0x8F;    //開總中斷和定時計數器兩個中斷,兩個外中斷
          IT0=1;
          IT1=1;      //設置外中斷為下降沿觸發
          TR0=1;
          TR1=1;       //打開定時計數器開始計數
          while(1)
            {
             pp0=0;
             delay(5);
             pp0=1;
             pp1=0;
             delay(5);
             pp1=1;
             pp2=0;
             delay(5);
             pp2=1;
             pp3=0;
             delay(5);
             pp3=1;
             /*以上可用下列這段代替
             P3=0xfe;
             delay(5);
             P3=0xfd;
             delay(5);
             P3=0xbf;
             delay(5);
             P3=0x7f;
             delay(5);*/ 

            }
        }
        void intsvr0(void) interrupt 0  using 1
        {
         
          temp=P3;
          switch(temp)                  
            {
              case 0xfa:dat=0;break;   
              case 0xf9:dat=1;break;    
              case 0xbb:dat=2;break; 
              case 0x7b:dat=3;break;
              default: break;
            }
          P2=yu[dat];
        }
        void timer0(void) interrupt 1 using 1
        {
         
          temp=P3;
          if(temp==0xee) dat=8;
          if(temp==0xed) dat=9;
          if(temp==0xaf) dat=10;
          if(temp==0x6f) dat=11;
          P2=yu[dat];
        }
        void intsvr1(void) interrupt 2 using 3
        {
         
          temp=P3;
          if(temp==0xf6) dat=4;
          if(temp==0xf5) dat=5;
          if(temp==0xb7) dat=6;
          if(temp==0x77) dat=7;
          P2=yu[dat];
        }
        void timer1(void) interrupt 3 using 1
        {
          int dat;
          temp=P3;
          switch(temp)                  
            {
              case 0xde:dat=12;break;   
              case 0xdd:dat=13;break;    
              case 0x9f:dat=14;break; 
              case 0x5f:dat=15;break;
              default: break;
            }
          P2=yu[dat];
        關閉窗口

        相關文章

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