历史上的今天
返回首页

历史上的今天

今天是:2025年06月22日(星期日)

2018年06月22日 | 矩阵键盘扫描原理详解——单片机

2018-06-22 来源:eefocus

这里写图片描述


根据原理图 
键盘扫描方法是:行线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();                                                                                         

    }                                                                                                                                 

}     


推荐阅读

史海拾趣

磁联达(CND-tek)公司的发展小趣事

为了进一步扩大市场份额,磁联达(CND-tek)公司决定拓展海外市场。公司组建了一支专业的国际销售团队,积极参加国际电子展会和交流活动,与全球各地的客户建立了紧密的合作关系。同时,公司还加大了对海外市场的投入,设立了多个海外办事处和仓库,为客户提供更加便捷的服务。这些举措使得磁联达(CND-tek)的产品迅速走向全球,赢得了广泛的赞誉。

HANA Micron公司的发展小趣事

Hama公司成立于1923年,最初在德勒斯登作为一家个人作坊起家,专门批发摄影设备及制造实验室和录音设备。随着电子技术的兴起,Hama敏锐地捕捉到市场变化,开始逐步将产品线扩展到电子配件领域。通过不断的技术研发和产品创新,Hama成功转型为一家电子配件的领军企业,其产品线涵盖了从电线、存储卡、天线到相机配件等广泛品类。这一转型不仅巩固了Hama在市场上的地位,也为其后续的发展奠定了坚实基础。

Analog Modules Inc公司的发展小趣事

除了工业检测仪表外,Hama在家用视听设备领域也取得了显著成就。公司推出的哈曼卡顿音响系列,以其卓越的音质表现和时尚的外观设计,迅速成为消费者心中的首选品牌。这些家用视听设备不仅为消费者带来了高品质的视听享受,也进一步丰富了Hama的产品线,提升了公司的市场竞争力。随着消费者对高品质生活的追求日益增强,Hama的家用视听设备业务有望继续保持快速增长。

Don Connex Electronics Co Ltd公司的发展小趣事

Don Connex Electronics Co Ltd成立于上世纪90年代初,当时电子行业正处于快速发展阶段。公司的创始人李明凭借其在半导体领域的深厚技术背景,带领团队研发出了一款高性能的电源管理芯片,这款芯片在业界引起了广泛关注。该芯片以其低功耗、高效率的特性,迅速在市场上打开了局面,为公司的初创阶段奠定了坚实的基础。

ADMOS公司的发展小趣事

面对不断变化的市场需求和技术趋势,ADMOS公司始终保持着对创新的热情和追求。公司投入大量资源用于研发新的技术和产品,不断推出具有创新性和竞争力的产品。这些创新成果不仅提升了ADMOS在市场上的竞争力,也为公司的未来发展指明了方向。

Capax Technologies Inc公司的发展小趣事

Capax Technologies Inc在市场定位和产品策略上表现出色。公司深入调研市场需求,发现高端电子设备市场对于高性能、高可靠性的组件有着旺盛的需求。于是,Capax Technologies Inc将产品定位为高端市场,专注于研发和生产高品质的电子组件。通过精准的市场定位和优质的产品,Capax Technologies Inc迅速在高端市场中占据了一席之地。

问答坊 | AI 解惑

电子产业中的绿色设计

作者:Tamim P. Sidiki 博士,Ine Cox, Rinus de Vos, DSM 工程塑料 摘要 当前在通信,计算和消费行业中,绿色电子是最重要的课题之一。电子产业中的原始设备制造商们( OEM )不仅注重能源节约,同时也禁用了一些在塑料中作为阻燃物质的卤化物。整 ...…

查看全部问答>

电子书

自适应滤波的书…

查看全部问答>

浅析RFID(射频识别)的信息安全及其对策

RFID(RadioFrequencyIdentification,即射频识别)技术是从20世纪80年代走向成熟的一项自动识别技术。本文针对RFID系统产生的安全隐患进行了详细分析并有针对性地总结提出了相关对策。         RFID作为无线应用领域 ...…

查看全部问答>

按键控制LED

大家好,我刚刚写了个按键控制LED的程序,可是在调试的时侯发现没有读到按键按下,具体情况如下: 我用的是2440的开发板,用了两个IO口, 有键按下的时侯,GPF0为低,否则,为高。 GPA21与LED相连,为低的时侯LED亮,为高的时侯灭。 程序如下: ...…

查看全部问答>

求助关于如何将串口接收的汉字存入txt文件

现在已将串口接收汉字转换为unicode,且可以通过messagebox或edit显示汉字,但为什么使用cfile类进行写入txt文件后,通过word打开文件显示的不是汉字,而是汉字unicode码中每个字节所对应的ascii码呢?我写入的类型是wchar呀?请高手帮助!谢谢!…

查看全部问答>

开发 - eeworld - 外包

目的: 公司有项目需外包,寻工作室或个人开发。想了解一下大家信赖哪些外包网站。 问题: 请教eeworld上的高手,你们一般会通过哪些方式接私活?eeworld的外包频道效用如何? 备注:我们公司是开发工具软件的,主要是做 PC 维护方面的工具。 项 ...…

查看全部问答>

LPC2214的问题

我用的是lpc2214,看了周立功出的中文文档上面写着当p1,p2,p3口用做输入的时候,可通过内置上拉电阻将电平拉高,我认为这就是说这三个口应该是有内置上拉电阻的,p0口是没有这句话的,我认为是没有的上拉电阻的,那么现在就是p0口我用的都是第二 ...…

查看全部问答>

LM3S9B96开发板,晶振不起振?

为什么LM3S9B96的开发板,就是群星的那款,16M的外部晶振用示波器测试没有波形呢?9B96不是没有内部震荡源吗?程序可以正常下载、调试、运行…

查看全部问答>

使用STM8S105S写入ADC_CSR该引脚就会有一个干扰波

                                 问题如题,这样正常吗?…

查看全部问答>