单片机按键 扫描原理_51单片机独立按键扫描原理 - CSDN
  • 矩阵键盘扫描原理详解根据原理图 键盘扫描方法是:行线P10~P13为输出线,列线P14~P17为输入线。一开始单片机将行线(P10~P13)全部输出低电平,此时读入列线数据,若列线全为高电平则没有键按下,当列线有出现低电...

    矩阵键盘扫描原理详解


    这里写图片描述


    根据原理图
    键盘扫描方法是:行线P10~P13为输出线,列线P14~P17为输入线。一开始单片机将行线(P10~P13)全部输出低电平,此时读入列线数据,若列线全为高电平则没有键按下,当列线有出现低电平时调用延时程序以此来去除按键抖动。延时完成后再判断是否有低电平,如果此时读入列线数据还是有低电平,则说明确实有键按下。最后一步确定键值。现在我们以第二行的S5键为例,若按下S5后我们应该怎么得到这个键值呢?当判断确实有键按下之后,行线轮流输出低电平,根据读入列线的数据可以确定键值。首先,单片机将P10输出为低电平,其它P11~P13输出高电平,此时读取列线的数据全为高电平,说明没有在第一行有键按下;其次,单片机将P11输出低电平,其它P10、P12、P13仍为高电平,此时再来读取列线数据,发现列线读到的数据有低电平,数值为1011(0x0B),如果我们的键盘布局已经确定,那么0x0B就代表S5的值了。转到S5键功能处理子程序就可以达到目的。


    /*  
        功能:矩阵键盘扫面,按键显示键值程序 
        作者:siriuszxn
                                      */
    #include "reg51.h"                                                                                                                
    #define KEYPORT = P1                                                                                                   
    
    unsigned char i;                                                                                                                                         
    unsigned char Keynum;                                                                                                        
    unsigned char Line;                                       //行                                                                 
    unsigned char Mask;                                                                                                         
    unsigned char Col;                                        //列                                                                      
    unsigned char ScanCode;                                                                                              
    
    unsigned char code psegs_table[] =                                                                                            {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};                                                                //共阳极数码管0-F                                                                                                                                            
    
    void delay_ms(unsigned int t)                      //ms延时程序                                                                      
    {                                                                                                                                       
        unsigned char i;                                                                                                                 
         unsigned int x;                                                                                                                  
         x=t;                                                                                                                              
         while(x--)                                                                                                                        
         {                                                                                                                                          
                 for(i=0;i<113;i++);                                                                                                              
         }                                                                                                                                           
    }                                                                                                                                        
    /* 键盘扫描程序 */                                                                                                                                        
    void keyscan()                                                                                                           
    {                                                                                                                                   
        while (1)              //循环扫描键盘       
        {                                                                                                                            
           P1 = 0xff;          //开始                                                         
            Line = 1;                                                                                         
            Mask = 0x01;                                                                                         
    
            for(i = 0; i < 4; i++)                                                                                   
            {                                                                                                                                                                                    
                P1 = ~Mask;                                                                                    
    
                ScanCode = P1 & 0xf0;                                                                                          
    
                if (ScanCode != 0xf0)                                                                                         
                {                                                                                                                                                                                    
                    delay_ms(5);                                                                               
                }                                                                                                                                                                                    
    
                ScanCode = P1 & 0xf0;                                                                                          
    
                switch(ScanCode)                                                
                {                                                                                                                                                                                    
                    case 0xe0:Col=1;break;                                                                                          
                    case 0xd0:Col=2;break;                                                                   
                    case 0xb0:Col=3;break;                                                                          
                    case 0x70:Col=4;break;                                                                  
                    default  :Col=0;break;                                                                                          
                }                                                                                                                                                                                    
    
                if (Col > 0)                                                                                                                                           
                {   
                    //根据行列计算键值                                                                                                                                                         
                    Keynum = (Line - 1) * 4 + Col;                                                                  
                    //通过P0口接数码管显示                                                                                                          
                    P0 = psegs_table[Keynum-1];                                                                                          
    
                    while(1)                                                                                           
                    {                                                                                
                        ScanCode = P1 & 0xf0;                                                                                
                        if(ScanCode == 0xf0)                                                               
                        {                                                                                                                                              
                            break;                                                    
                        }                                                                                                                       
                    }                                                                                
                    Mask <<= 1;                                                                                                      
                    Line++;                                                                                                 
                }                                                                                                                        
            }                                                                                                                                      
        }  
    }                                                                                                                                   
    
    void main()                                                                                         
    {                                                                                                                                     
        while(1)                                                                                                                      
        {                                                                                                                                 
            keyscan();                                                                                         
        }                                                                                                                                 
    }                                                                      
    展开全文
  • 单片机检测按键原理

    2018-03-25 12:40:26
    单片机检测按键原理按键的一端接地,另一端与单片机的某个I/O口相连,开始先给I/O赋一高电平,然后让单片机不断检测该I/O口是否变为低电平,当按键闭合时,相当于I/O口与地相连,就会变为低电平。在单片机检测...

          首先说一下独立键盘检测,在单片机外围电路中  ,通常用到的按键都是机械弹性开关,当开关闭合时,线路导通,开关断开时,线路断开。单片机检测按键的原理:按键的一端接地,另一端与单片机的某个I/O口相连,开始先给I/O赋一高电平,然后让单片机不断检测该I/O口是否变为低电平,当按键闭合时,相当于I/O口与地相连,就会变为低电平。在单片机检测按键是否被按下时,电压的实际波形与理想波形时有一点=定差别的,波形在按下和释放瞬间都有抖动现象,抖动时间的长短和按键的机械特性有关 。所以单片机在检测键盘是否被按下都要加上去抖操作,所以在编写单片机的键盘检测程序时,一般在检测按下时加入去抖延时。独立键盘与单片机连接时每一个按键都需要一个I/O口,会过多占用I/O口资源。所以就引出了矩阵键盘。

         矩阵键盘的连接方式,每一行将每个按键的一端连接在一起构成行线,每一列将按键的另一端连接在一起构成列线。这样的话,16个按键排成4行4列就只要8根线。它的按键检测,简单点说,就是先送一列低电平,其余均为高电平,然后轮流检测,确认行列。

         这里就要提到另外一个东西,switch-case语句又称开关语句,它是一个专门用于处理多分支结构的条件选择语句。使用switch语句可直接处理多个分支。

        

        

    展开全文
  • 51单片机按键扫描

    2020-05-30 23:31:18
    #include <reg52.h> sbit ADDR0 = P1^0; sbit ADDR1 = P1^1; sbit ADDR2 = P1^2; sbit ADDR3 = P1^3;...sbit ENLED = P1^4;...unsigned char code LedChar[] = { //数码管显示字符转换表 0xC0, 0xF9, 0xA4,

    #include <reg52.h>

    sbit ADDR0 = P1^0;
    sbit ADDR1 = P1^1;
    sbit ADDR2 = P1^2;
    sbit ADDR3 = P1^3;
    sbit ENLED = P1^4;
    sbit KEY1 = P2^4;
    sbit KEY2 = P2^5;
    sbit KEY3 = P2^6;
    sbit KEY4 = P2^7;

    unsigned char code LedChar[] = { //数码管显示字符转换表
    0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
    0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
    };

    void main()
    {
    bit backup = 1; //定义一个位变量,保存前一次扫描的按键值
    unsigned char cnt = 0; //定义一个计数变量,记录按键按下的次数
    ENLED = 0; //选择数码管DS1进行显示
    ADDR3 = 1;
    ADDR2 = 0;
    ADDR1 = 0;
    ADDR0 = 0;
    P2 = 0xF7; //P2.3置0,即KeyOut1输出低电平
    P0 = LedChar[cnt]; //显示按键次数初值

    while (1)
    {
        if (KEY4 != backup)   //当前值与前次值不相等说明此时按键有动作
        {
            if (backup == 0)  //如果前次值为0,则说明当前是由0变1,即按键弹起
            {
                cnt++;        //按键次数+1
                if (cnt >= 10)
                {             //只用1个数码管显示,所以加到10就清零重新开始
                    cnt = 0;
                }
                P0 = LedChar[cnt];  //计数值显示到数码管上
            }
            backup = KEY4;   //更新备份为当前值,以备进行下次比较
        }
    }
    

    }

    这是金沙滩51单片机按键部分的代码。我想问一下,while(1)那里进入循环后按键按下与弹起的时候,KEY4和backup的值具体怎样变化?这里我不太懂,希望有大佬能列举解答一下,谢谢!

    展开全文
  • STC单片机按键扫描程序 最近在做一个电子秤相关项目,使用STC系列单片机作为主控芯片,项目第一阶段直接使用IAP15W4K58S4驱动两个矩阵键盘,一切调试顺利,在项目即将结束时老板要求使用另一块单片机驱动矩阵键盘,...

    STC单片机按键扫描程序

    最近在做一个电子秤相关项目,使用STC系列单片机作为主控芯片,项目第一阶段直接使用IAP15W4K58S4驱动两个矩阵键盘,一切调试顺利,在项目即将结束时老板要求使用另一块单片机驱动矩阵键盘,读取键值后通过串口传回之前的IAP主控(理由是为了节省从矩阵键盘到主控板之间的长排线的成本,16P+10P);OK ,老板发话了,还能说什么呢,做呗,于是问题出现了。下面先简单介绍矩阵键盘的检测原理,然后说一说一些容易遇到的问题。

    1.先简单介绍下矩阵键盘的扫描原理

    对于N*M的矩阵键盘(N>=M),我们在编写程序的过程中,为提高扫描效率与降低程序的复杂程度,常设计N为列检测,M为行扫描,对应于程序上的检测输入与扫描输出。下图为矩阵键盘的示意图。

    矩阵键盘示意图

    检测原理:在上图示意键盘中,规定竖向为列,即是P10,P11,P12,P13为列检测;P14,P15,P16,P17为行扫描。没有按键按下是,列检测为到电平(一般为准双向IO,弱上拉),行扫描为低电平输出。当按键S5被按下后,P10与P15接通,P10由高电平变为低电平,单片机检测到P10-P13有任何一位被拉低时,认为有按键按下,此时程序应记录下哪一列按键被按下(得到按键的列坐标),然后按序拉高P14-P14,直到P10-P13全为初始状态(高电平),此时拉高的行即为被按下的按键的行坐标。例如:S5被按下后,P10为0,得到列坐标为1,当P15拉高后,P10-P14均为1,得到行坐标为2,最后得到按键坐标为2行1列--S5。其他按键检测原理相同。

    单片机驱动扫描按键原理很简单,但是在实际使用中对不同单片机的配置有要求,配置不当容易检测到错误的键值。一下简要说明几个容易遇到的问题。

    1.现在市面上的单片机IO基本都有4种标准模式(准双向IO、推挽输出、开漏输出、高阻输入)详解见:(https://blog.csdn.net/jbh18401/article/details/76048843)。一般列检测配置为准双向IO,但准双向IO的输出为弱上拉啊,拉电流弱,抗干扰性差,所以在列检测IO外部,应外加上拉电阻(10-100K),一确保按键的稳定性。

    2.在按键扫描的程序中,由于单片机程序执行速度快,在检测按键行坐标时,拉高对应行后应适当延时,等待IO端口稳定后再检测行输入是否改变(程序如下)。若不加入延时,会导致因IO还没来得及完全拉高,列检测程序已经执行完毕,最终导致按键动作检测不到或者误检。

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    展开全文
  • 适合于单片机初学者,通过这个资料可以很好的理解动态扫描原理
  • 目标:获取矩阵键盘的按键值(按下按键,在单个数码管上显示出键值) 连线: P1与矩阵键盘连接,P0 与单个数码管连接 代码如下: #include &lt;reg51.h&gt; unsigned char code table[] = {0x80,0x40,0...

    硬件: STC89C50

    目标:获取矩阵键盘的按键值(按下按键,在单个数码管上显示出键值)

    连线: P1与矩阵键盘连接,P0 与单个数码管连接

    代码如下:

    #include <reg51.h>

    unsigned char code table[] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
    //数码管共阴级
    unsigned char code table1[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
    //数码管共阳级
    unsigned char code table2[]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

    void delay(unsigned char num)
    {
         while(num--);
    }

    int KeyNum()
    {
        int m;int n;
        int keyVal;
        P1 = 0xf0;
        if(P1 != 0xf0)
        {
            delay(5);
            if(P1 == 0xB0)
            {
                m = 1;
            }
            else if(P1 == 0xD0)
            {
                m = 2;
            }
            else if(P1 == 0xE0)
            {
                m = 3;
            }
        }
        P1 = 0x0f;
        if(P1 != 0x0f)
        {
            delay(5);
            if(P1 == 0x07)
            {
                n = 1;
            }
            else if(P1 == 0x0B)
            {
                n = 2;
            }
            else if(P1 == 0x0D)
            {
                n = 3;
            }
            else if(P1 == 0x0E){
                n = 4;
            }
        }
        keyVal = (m-1)*4+n;
        return keyVal;
    }

    int main()
    {
         int keyVal;
         P1 = 0xf0;
         while(1)
         {
                if(P1 != 0xf0)
                {
                    keyVal = KeyNum();
                    P0 = table1[keyVal];
                }
                P1 = 0xf0;
         }
    }

    展开全文
  • 一个51单片机的键盘扫描程序,算法简单有效  发一个51单片机的键盘扫描程序,算法简单有效   再给大家分享一个不错按键程序(来自ourdev) /****************************************  键盘_不采用...
  • 按键扫描方式用于产品按键较多产品。可以用较少的端口控制较多的按键。 以8个IO口为例子,普通按键扫描最多控制,16个按键(矩形扫描)。采用该方式可以控制28个按键 二、扫描方式 原理图: IO1输出低IO0...
  • 关注【电子开发圈】微信公众号,一起学习吧!...电子DIY、Arduino、51单片机、STM32单片机、FPGA…… 电子百科、开发技术、职业经验、趣味知识、科技头条、设备拆机…… 点击链接,免费下载100G+电子设计学习资料! ...
  • 一、基本知识  1.按键分类与输入原理 ...在单片机应用系统中,除了复位按键有专门的复位电路及专一的复位功能外,其他按键都是以开关状态来设置控制功能或输入数据的。当所设置的功能键或数字键按下时
  • 单片机按键扫描

    2017-10-11 11:04:25
    新型的按键扫描程序  不过我在网上游逛了很久,也看过不少源程序了,没有发现这种按键处理办法的踪迹,所以,我将他共享出来,和广大同僚们共勉。我非常坚信这种按键处理办法的便捷和高效,你可以移植到任何一种...
  • 新型的按键扫描程序  不过我在网上游逛了很久,也看过不少源程序了,没有发现这种按键处理办法的踪迹,所以,我将他共享出来,和广大同僚们共勉。我非常坚信这种按键处理办法的便捷和高效,你可以移植到任何一种...
  • 而现在介绍的按键扫描法是“快速识别”方法(以独立按键为例,因为矩阵键盘的扫描与独立按键类似)。 首先附上按键的原理图: 用跳帽连接排针 J5 的2脚与3脚,将键盘设置为独立按键(只有S4~S7有效)。此时,S4~S7...
  • 按键输入一、独立按键1.1 独立按键的原理1.2 独立按键的仿真电路1.3 按键消抖二、矩阵键盘2.1 矩阵键盘原理2.2 矩阵键盘扫描原理矩阵键盘扫描程序 单片机与外界的信息交互主要有两大类,输入信息和输出信息。 之前的...
  • 我们讲独立按键扫描的时候,大家已经简单认识了矩阵按键是什么样子了。矩阵按键相当于 4 组每组各 4 个独立按键,一共是 16 个按键。那我们如何区分这些按键呢?想一下我们生活所在的地球,要想确定我们所在的位置,...
  • 原理搞清楚了,那么下面我们就先编写一个独立按键的程序,把最基本的功能验证一下。 #include &lt;reg52.h&gt; sbit ADDR0 = P1^0; sbit ADDR1 = P1^1; sbit ADDR2 = P1^2; sbit ADDR3 = P1^3; sbit ENLED =...
  • 矩阵键盘扫描原理详解 根据原理图 键盘扫描方法是:行线P10~P13为输出线,列线P14~P17为输入线。 一开始单片机将行线(P10~P13)全部输出低电平,此时读入列线数据,若列线全为高电平则没有键按下,当列线有出现...
  • 1.按键分类与输入原理 按键按照结构原理科分为两类,一类是触点式开关按键,如机械式开关、导电橡胶式开关灯;另一类是无触点式开关按键,如电气式按键,磁感应按键等。前者造价低,后者寿命长。目前,微机系统中最...
  • 在我们的实际产品开发过程中,为了节省成本,常常会...(上一讲已经讲过,我个人比较喜欢状态机编程,因此这里还是采用状态机编程的方法,来实现按键和LED复用扫描功能)。 一、按键和LED复用原理图如下: LED...
1 2 3 4 5 ... 20
收藏数 1,599
精华内容 639
关键字:

单片机按键 扫描原理