2005|1

1669

帖子

0

TA的资源

五彩晶圆(初级)

楼主
 

MSP430F5529与常见的矩阵键盘 [复制链接]

键盘外观


键盘外观一般是这个样子的,淘宝上常见的有4x4和4x3的,也有不是薄膜而是按键矩阵的键盘,但是原理都大同小异。
一个普普通通的4x4键盘

键盘原理图


                                                   键盘的原理图

一般来说,键盘有多少行多少列,就有行数+列数这么多的管脚。当按钮按下后,按钮所在行列开关合上,行列之间的管脚就连通了。

单片机实现
4x3键盘
根据键盘的原理图,不难想到我们要用管脚扫描的方式来检测哪个键按下。

将行管脚设为输入,列管脚设为输出(当然也可以反着来),每次只让一个列管脚为高电平,再检测行管脚的电平高低情况,即可检测键盘是哪个键按下了。

初始化管脚
void keyboard_init(){

 //设置行管脚为输入
 P3DIR &= ~BIT6; //P3.6端口设为输入
 P3REN |= BIT6;  //使P3.6能上拉/下拉电阻
 P3OUT &= ~BIT6;  //置P3.6为下拉电阻模式
 P3SEL &= ~BIT6; //P3.6为I/O接口

 P7DIR &= ~BIT0; //P7.0端口设为输入
 P7REN |= BIT0;  //使P7.0能上拉/下拉电阻
 P7OUT &= ~BIT0;  //置P7.0为下拉电阻模式
 P7SEL &= ~BIT0; //P7.0为I/O接口

 P6DIR &= ~BIT4; //P6.4端口设为输入
 P6REN |= BIT4;  //使P6.4能上拉/下拉电阻
 P6OUT &= ~BIT4;  //置P6.4为下拉电阻模式
 P6SEL &= ~BIT4; //P6.4为I/O接口

 P6DIR &= ~BIT3; //P6.3端口设为输入
 P6REN |= BIT3;  //使6.3能上拉/下拉电阻
 P6OUT &= ~BIT3;  //置P6.3为下拉电阻模式
 P6SEL &= ~BIT3; //P6.3为I/O接口

 //设置列管脚为输出
 P6DIR |= BIT2+BIT1+BIT0; //P6.2,1,0端口设为输出
 P6OUT &=~(BIT2+BIT1+BIT0);

}

扫描管脚
    思路是在一个do-while循环里面,依次设置第一列、第二列……为高电平,然后检测第一行、第二行……的电平是否为高,如果为高则说明有按键按下,行列导通,跳出循环,返回按键值。

char scanKey(){
 //扫描列
 char key_value=0;
 unsigned char state=0;
 do{
     key_value=0;
     if(state==0){

         P6OUT |= BIT0;
         P6OUT &=~ (BIT1+BIT2);

     }else if(state==1){

         P6OUT |= BIT1;
         P6OUT &=~ (BIT0+BIT2);

     }else if(state==2){

         P6OUT |= BIT2;
         P6OUT &=~ (BIT0+BIT1);

     }

     if(++state==3) state=0;


     if(P6OUT & BIT0)
         key_value = BIT5;

     if(P6OUT & BIT1)
         key_value = BIT6;

     if(P6OUT & BIT2)
         key_value = BIT7;

     if(P3IN & BIT6) key_value |= BIT0;
     else key_value &= ~BIT0;

     if(P7IN & BIT0) key_value |= BIT1;
     else key_value &= ~BIT1;

     if(P6IN & BIT4) key_value |= BIT2;
     else key_value &= ~BIT2;

     if(P6IN & BIT3) key_value |= BIT3;
     else key_value &= ~BIT3;

 }while((key_value&0x0f)==0);//直到有行被按下

 switch(key_value){//返回按下的字符
     case 129: return '1';
     case 65: return '2';
     case 33: return '3';
     case 130: return '4';
     case 66: return '5';
     case 34: return '6';
     case 132: return '7';
     case 68: return '8';
     case 36: return '9';
     case 136: return '*';
     case 72: return '0';
     case 40: return '#';
     default: return 0;
 }
}


4x4的键盘
    同样,4x4的键盘也是通过行列扫描的方式检测按下的按钮是哪个。读者可以自行修改程序实现。

以下为参考代码:

初始化端口
void keyboard_init(){

    //设置行管脚为输入

    P3DIR &= ~BIT5; //P3.5端口设为输入
    P3REN |= BIT5;  //使3.5能上拉/下拉电阻
    P3OUT &=~ BIT5;  //置P3.5为下拉电阻模式
    P3SEL &= ~BIT5; //P3.5为I/O接口

    P3DIR &= ~BIT6; //P3.6端口设为输入
    P3REN |= BIT6;  //使P3.6能上拉/下拉电阻
    P3OUT &=~ BIT6;  //置P3.6为下拉电阻模式
    P3SEL &= ~BIT6; //P3.6为I/O接口

    P7DIR &= ~BIT0; //P7.0端口设为输入
    P7REN |= BIT0;  //使P7.0能上拉/下拉电阻
    P7OUT &=~ BIT0;  //置P7.0为下拉电阻模式
    P7SEL &= ~BIT0; //P7.0为I/O接口

    P6DIR &= ~BIT4; //P6.4端口设为输入
    P6REN |= BIT4;  //使P6.4能上拉/下拉电阻
    P6OUT &=~ BIT4;  //置P6.4为下拉电阻模式
    P6SEL &=~ BIT4; //P6.4为I/O接口

    //设置列管脚为输出
    P6DIR |= BIT3+BIT2+BIT1+BIT0; //P6.3,2,1,0端口设为输出
    P6OUT &=~(BIT3+BIT2+BIT1+BIT0);

}

扫描管脚
char scanKey(){
    //扫描列
    char key_value=0;
    unsigned char state=0;
    do{
        key_value=0;
        if(state==0){

            P6OUT |= BIT0;
            P6OUT &=~ (BIT1+BIT2+BIT3);

        }else if(state==1){

            P6OUT |= BIT1;
            P6OUT &=~ (BIT0+BIT2+BIT3);

        }else if(state==2){

            P6OUT |= BIT2;
            P6OUT &=~ (BIT0+BIT1+BIT3);

        }else if(state==3){

            P6OUT |= BIT3;
            P6OUT &=~ (BIT0+BIT1+BIT2);

        }

        if(++state==4) state=0;


        if(P6OUT & BIT0)
            key_value = BIT4;

        if(P6OUT & BIT1)
            key_value = BIT5;

        if(P6OUT & BIT2)
            key_value = BIT6;

        if(P6OUT & BIT3)
            key_value = BIT7;


        if(P3IN & BIT5) key_value |= BIT0;
        else key_value &=~ BIT0;

        if(P3IN & BIT6) key_value |= BIT1;
        else key_value &=~ BIT1;

        if(P7IN & BIT0) key_value |= BIT2;
        else key_value &=~ BIT2;

        if(P6IN & BIT4) key_value |= BIT3;
        else key_value &=~ BIT3;

    }while((key_value&0x0f)==0);//直到有行被按下

    switch(key_value){//返回按下的字符
        case 129: return '1';
        case 65: return '4';
        case 33: return '7';
        case 17: return '*';
        case 130: return '2';
        case 66: return '5';
        case 34: return '8';
        case 18: return '0';
        case 132: return '3';
        case 68: return '6';
        case 36: return '9';
        case 20: return '#';
        case 136: return 'A';
        case 72: return 'B';
        case 40: return 'C';
        case 24: return 'D';
        default: return 0;
    }
}


结语
        键盘是MSP430F5529最简单的外设之一,只要掌握了扫描行/列的方式,面对各种各样不同的键盘也能得心应手~

        文中的scanKey()函数用的是循环的方式来检测按键,MSP430F5529的PORT1和PORT2是支持中断功能的,大家也可以把键盘插到PORT1或者PORT2,用中断方式来检测按键是否按下。

最新回复

不错的资料,谢谢分享。   详情 回复 发表于 2020-10-7 14:08
 
点赞 关注

回复
举报

2618

帖子

0

TA的资源

纯净的硅(高级)

沙发
 

不错的资料,谢谢分享。

 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表