zoukankan      html  css  js  c++  java
  • PIC16F877A矩阵键盘的用法

    原文地址:http://www.pic16.com/bbs/dispbbs.asp?boardid=24&id=53801&page=6&move=next

    /*******************************************************************************
    Platform: PIC1687A
    Project : 实验16:矩阵式按键
    Clock F : 外部4M
    Software: PICC
    Author  : 竹林清风
    comments:
    学习使用矩阵式按键的用法
    本例功能是按一下相应键,数码管显示相应的值
    0-9;不带连发,不带组合,希望有兴趣的人帮忙完成
    并共享
    UP键按键计数
    proteus仿真通过;
    *******************************************************************************/
    #include <pic.h>
    #include <pic1687x.h>
    #include"delay.h"
    #include"key.h"

    unsigned char led_7[]={0x3f,0x06,0x5b,0x4F,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//数码管显示值

    unsigned char key_temp;
    void main(void)
    {
      unsigned char ID=0;
      TRISB=0X00;//所有B0端口输出
      PORTB=0XFF;
     
      TRISD=0X0F;//初始化键盘接口
      PORTD=0XFF;//置输出为高电平
     
    while(1){ 
               delay_nms(5);
               key_temp = read_keyboard();  // 调用键盘接口函数读键盘
       if (key_temp != No_key)
       {       // 有按键按下
                   
        switch(key_temp)
        {
          case 1:
          PORTB=led_7[1];
          break;
          case 2:
          PORTB=led_7[2];
          break;
                      case 3:
                      PORTB=led_7[3];
                      break;
                      case 4:
                      PORTB=led_7[4];
                      break;
                      case 5:
                      PORTB=led_7[5];
                      break;
                      case 6:
                      PORTB=led_7[6];
                      break;
                      case 7:
                      PORTB=led_7[7];
                      break;
                      case 8:
                      PORTB=led_7[8];
                      break;
                      case 9:
                      PORTB=led_7[9];
                      break;
                      case K3_2:
                      PORTB=led_7[0];
                      break;
                      case 13:
                      if(++ID>=10)
                       {
                       ID=0;
                       }
                      PORTB=led_7[ID];
                      
                      break;
                      }
                 }
              }
    }                  
    下面为延时函数:文件delay.c     

    void delay_1us(void)                 //1us
      {
       asm("nop");
      }

    void delay_nus(unsigned int n)       //N us延时函数
      {
       unsigned int i=0;
       for (i=0;i<n;i++)
       delay_1us();
      }
     
    void delay_1ms(void)                 //1ms延时函数
      {
       unsigned int i;
       for (i=0;i<1140;i++);
      }
     
    void delay_nms(unsigned int n)       //N ms延时函数
      {
       unsigned int i=0;
       for (i=0;i<n;i++)
       delay_1ms();}
     

    头文件:delay.h

    void delay_1us(void);
    void delay_nus(unsigned int n);       //N us延时函数
    void delay_1ms(void);                 //1ms延时函数
    void delay_nms(unsigned int n);       //N ms延时函数

    键盘key.h

    #define No_key  255
    #define K1_1 1
    #define K1_2 2
    #define K1_3 3
    #define k1_4    4
    #define K2_1 5
    #define K2_2 6
    #define K2_3 7
    #define K2_4 8
    #define K3_1 9
    #define K3_2 0
    #define K3_3 10
    #define K3_4 11
    #define K4_1 12
    #define K4_2 13
    #define K4_3 14
    #define K4_4 15
    #define Key_mask 0b00001111

    unsigned char read_keyboard()

     static unsigned char key_state = 0, key_value, key_line;
        unsigned char key_return = No_key,i,key_time;
     
     switch (key_state)
     {
      case 0:
       key_line = 0b00010000;
       for (i=1; i<=4; i++)     // 扫描键盘
       { 
        PORTD = ~key_line;     // 输出行线电平
        PORTD = ~key_line;     // 必须送2次!!!
                    key_value = Key_mask & PORTD;  // 读列电平
        if (key_value == Key_mask)
         key_line <<= 1;    // 没有按键,继续扫描
        else
        {
         key_state++;     // 有按键,停止扫描
         break;      // 转消抖确认状态
        }
       }
       break;
      case 1:
       if (key_value == (Key_mask & PORTD))  // 再次读列电平,
       {
        switch (key_line | key_value)  // 与状态0的相同,确认按键
        {        // 键盘编码,返回编码值
         case 0b00011110:
          key_return = K1_1;      //"1"
          key_state++; 
          break;
         case 0b00011101:
          key_return = K1_2;      //"2"
          key_state++; 
          break;
          case 0b00011011:
          key_return = K1_3;     //"3"
          key_state++; 
          break;
         case 0b00010111:
          key_return = k1_4;     //"4"
          key_state++; 
          break;
          case 0b00101110:
          key_return = K2_1;     //"5"
          key_state++; 
          break;
         case 0b00101101:
          key_return = K2_2;     //"6"
          key_state++; 
          break;
          case 0b00101011:
          key_return = K2_3;     //"7"
          key_state++; 
          break;
          case 0b00100111:
          key_return = K2_4;    //"8"
          key_state++; 
          break;
         case 0b01001110:        
          key_return = K3_1;     //"9"
          key_state++; 
          break;
          case 0b01001101:         
          key_return = K3_2;    //"0"
          key_state++; 
          break;
          case 0b01001011:         
          key_return = K3_3;    //"A"
          key_state++; 
          break;
         case 0b01000111:         
          key_return = K3_4;     //"B"
          key_state++; 
          break;
         case 0b10001110:        
          key_return = K4_1;    //"C"
          key_state++; 
          break;
         case 0b10001101:         
             //key_return = K4_2; //"D"
            // key_state++; 
               key_time=0;
          key_state=3;
          break;
         case 0b10001011:         
          key_return = K4_3;   //"E"
          key_state++; 
          break;
         case 0b10000111:
          key_return = K4_4;    //"F"
          key_state++; 
          break;
        }
           // 转入等待按键释放状态
       }
       else
        key_state--;    // 两次列电平不同返回状态0,(消抖处理)
       break;      
      case 2:       // 等待按键释放状态
       PORTD = 0b00000111;   // 行线全部输出低电平
       PORTD = 0b00000111;   // 重复送一次
       if ( (Key_mask & PORTD) == Key_mask)
        key_state=0;    // 列线全部为高电平返回状态0
       break;
      case 3:
      PORTD = 0b00000111;   // 行线全部输出低电平
      PORTD = 0b00000111;   // 重复送一次
      if ( (Key_mask & PORTD) == Key_mask)
        {
        key_state=0;    // 列线全部为高电平返回状态0
        key_return = K4_2;
        }
        //break;
       else if( (Key_mask & PORTD)!=Key_mask)
       {
       if(++key_time>=100)
         {
         key_state=4;
          key_time=0;
       
       key_return=20;
       
       }
       }
         break;
        case 4:
       PORTD = 0b00000111;   // 行线全部输出低电平
       PORTD = 0b00000111;   // 重复送一次
      if ( (Key_mask & PORTD) == Key_mask)
        {
          key_state=0;    // 列线全部为高电平返回状态0
          //key_return = K4_2;
        }
       else if(++key_time>=20)
             {
                key_time=0;
           
             key_return=20;
            }
       break; 
     }
     return key_return;
    }




  • 相关阅读:
    python 基础笔记十
    python 基础笔记十一
    python 基础笔记九-集合
    python 基础笔记八-time模块
    python 基础笔记七-OS模块
    python 基础笔记六-函数
    Python 基础笔记四
    4-5 元祖
    4-4 修改文件
    4-3 高效读取文件 --待完成
  • 原文地址:https://www.cnblogs.com/hnrainll/p/1912945.html
Copyright © 2011-2022 走看看