求基于8051单片机用C语言编写的双矩阵键盘扫描程序(5个IO口控制25个按键)

作者&投稿:丛股 (若有异议请与网页底部的电邮联系)
单片机5个IO口扫描25个按键的程序,怎么只能扫描到下面5个键~

本文以循序渐进的思路,引导大家思考如何用最少的IO驱动更多的按键,并依次给出5种方案原理图提供参考。在实际项目中我们经常会遇到有按键输入的需求,但有的时候为了节省资源成本,我们都会选择在不增加硬件的情况下使用最少的控制器IO驱动更多的按键,那么具体是怎么做的呢,下面我们就以用5个IO引脚为例,讲下怎么设计可以实现更多的按键?共有5种设计思路,下面依次介绍。
思路一首先通常想到的可能是下面这样的设计:

上图形式的按键就是我们通常说的行列式按键,它的驱动思路是这样的:
1. 对IO1、2、3配置为推挽输出,依次只让其中一个输出为0其他输出为1。
2. 对IO4、5进行读操作,根据读出的结果判断哪个按键按下。
例如:配置IO1、2、3为011,读IO4、5,若IO4为0则SW14按下,若IO5为0则SW15按下;
依次的配置IO1、2、3为101,读IO4、5,若IO4为0则SW24按下,若IO5为0则SW25按下;
依次的配置IO1、2、3为110,读IO4、5,若IO4为0则SW34按下,若IO5为0则SW35按下;
思路二但是我们在不知道行列式按键之前我们肯定是依次将IO口接一个按键到GND或者到VCC,然后去读IO口去判断哪个按键按下,这也是最简单的方法,但是很浪费IO口,下面这种就结合了这种简单方法和行列式的思路,实现了又多增加3个按键,如下图:

这里我们的思路是先依次读IO1、2、3的电平来识别S1、2、3,哪个按键按下,其后的流程和思路一是一样的,这样就可以识别11个按键了。
思路三按照扫描的思想,某一时刻设置一个IO口为0,其他IO口读,如果有IO口读到0,则有对应按键按下。比如IO1为0,然后读到IO5也为0,那么K15就是按下的。对照这样的思路,我们可以有下面的设计:

这个电路按键识别思路是这样的:
1. 只配置IO1为0,其他IO读,若IO5读到0,则K15按下,若IO4读到0,则K14按下,依次识别K13,K12;
2. 只配置IO2为0,其他IO读,若IO5读到0,则K25按下,若IO4读到0,则K24按下,依次识别K23;
3. 只配置IO3为0,其他IO读,若IO5读到0,则K35按下,若IO4读到0,则K34按下;
4. 只配置IO4为0,其他IO读,若IO5读到0,则K45按下;
思路四对于思路3我们发现,如果只配置IO5为0,其他IO读,若IO1读到0,则K15按下,若IO2读到0,则K25按下,依次可识别K35和K45。这样就存在重复,那么有么有好的方法,解决这样的重复呢?我们发现,若配置IO1为0,K15按下,电流流向IO1的,若配置IO5为0,同样K15按下,电流是流向IO5的。这样我们就可以通过区分电流的流向来避免重复。于是就有了下图的设计:

这样就可以避免重复,IO5为0时,按K15,IO1是读不到0的。那么怎样设计,IO5为0时对应一个按键按下IO1为0呢?如是就有人想到下面的设计:

这个电路按键识别思路是这样的:
1. 只配置IO1为0,其他IO读,若IO5读到0,则K51按下,若IO4读到0,则K41按下,依次识别K31,K21;
2. 只配置IO2为0,其他IO读,若IO5读到0,则K52按下,若IO4读到0,则K42按下,依次识别K32,K21';
3. 只配置IO3为0,其他IO读,若IO5读到0,则K53按下,若IO4读到0,则K43按下,依次识别K32’,K31';
4. 只配置IO4为0,其他IO读,若IO5读到0,则K54按下,若IO4读到0,则K43’按下,依次识别K42’,K41';
5. 只配置IO5为0,其他IO读,若IO4读到0,则K54’按下,若IO3读到0,则K53’按下,依次识别K52’,K51'。
思路五很多人可能认为思路四已经识别20个按键了,但是真的就没有其他方法了吗?不要忘了,我们还没有将思路二你介绍的那种最简单的方法结合进去,于是又可以多5个按键,如下图:

这样我们可以先识别K01、K02、K03、K04、K05,若没有按键按下然后再和思路四的设计一样去识别其他按键。但这样存在一个问题,如果IO1配置为0,IO5读到0,那么怎么知道是K51按下还是K05按下呢,这里只需要在程序里做下判断,先判断下是不是K05按下,若不是就是K51,因为按键K01、K02、K03、K04、K05在5个IO口都为读取的情况下,就可以识别,不需要扫描识别处理,相当于这5个按键优先级高与其他按键。
总结综合上述,5个IO口最多可以识别25个按键,思路五程序上处理比较麻烦,若实际中只按思路四设计,也可识别20个按键,那么如果有N个IO口可识别多少按键呢?这里给出如下公式:
假设有N个IO口按照思路三可以识别N*(N-1)/2个;
按照思路四可识别N*(N-1)个;
按照思路5可以识别N*(N-1)+N个。
最后再说下,如果实际设计时,还是按思路四设计好,软件也没那么麻烦。如果是你的话你会选择哪种方法呢?你还有没有其他的设计方法呢?

这个电路复杂,而且,扩充出来的按键数目,并不多。

4*4,虽然只有 16个按键。
认真编程,就可以实现 31 个按键的效果。

http://blog.163.com/asm_c/blog/static/24820311320109178210773/

参考。

我这里有一个程序,

#include<reg51.h>

#define rowkey() (~P2)&0x0f//键盘输入端

#define OUT P0                  //数码管显示输出端

unsigned char code TAB[]=

{  0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,

   0x88,0x83,0xC6,0xA1,0x86,0x8E,0x89,0xC7,0xC8,0xC1,

   0x8C,0xA3,0xBF,0xFF,0xFF 

};

void debouncer()

{ int i;

 for(i=0;i<2400;i++);

}

void scanner()//键盘扫描程序

{ unsigned char data row,col;

 unsigned char data scan;

 unsigned char data keyin;

 scan=0xef;

 for(row=0;row<4;row++)

 { P2=scan;

  keyin=rowkey();

  debouncer();

  if(keyin!=0)

  { for(col=0;col<4;col++)

   { keyin>>=1;

    if(CY)

    { OUT=TAB[col*4+row];//数码管显示

     break; 

    }

   }

  }

  scan=(scan<<1)|0x01;

 }

}

void main()

{ while(1)

 { scanner();

 } 

}



5个IO口控制25个按键,用添加二极管的方法,这个程序,不难编写。
但是,确实就是应该先检测对地连接的按键,它们没有按下,再逐行(或列)输出低电平。
如果程序先检测各行列的,那么此时接地的键盘按下了,就会误判。
这是硬件所固有的特点,不可修改。
5个IO口控制25个按键,也无法检测复合键。
4个IO口控制16个按键,我的空间里面,有这样的文章,欢迎来踩。

5个端口最多可以接5*(5-1)=20个按键。行线和列线都接在5个端口上,但行、列相同的交叉位置不能有按键。扫描时5个口中任何时刻只有其中一个为输出,其他四个为输入,逐次变化。

怎么可能会出现优先级的问题,有键按下就是有键按下,没键按下就是没键按下。行列式键盘有两种处理方法,一种是行优先法,一种是列优先法。通常按键处理要软件去抖动,即判断有键按下时要延时20~30ms再检测,避开抖动。
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
/*延时1ms*/
void Delay(uint z)
{
uint i;
while(z--)
{
for(i=120;i>0;i--)
}
}
/*键扫描函数*/
uchar KeyScan()
{
uint i;
uchar h="0xef",b,c;
for(i=5,P1=h;i>0;i--)
{
if((P1&0x0f)!=0x0f)
{
Delay(30);
if((P1&0x0f)!=0x0f)
{
uchar key,p;
p=P1;
for(key=0;key<25;key++)
{
if(p==keytab[key])
{
do{
_nop_();
}while((P1&0x0f)==0x0f); //等待按键放开,很重要
//P1=0xff;
return(key);
}
}
}
}
}
}

5个按键确实可以控制25个按键,不过要加二极管。


已知8051单片机
你好,根据题中信息可得,12MHz晶振的机器周期就是12\/12M=1us,要能在P1.1输出4ms的方波就很简单了,你要求求初值,那么:---使用定时器0的工作方式1,TMOD=0x01; ,然后工作方式1是16位的定时器,最大定时值为65.536ms,要定时4ms就很容易,TH0=(65536-2000)\/256;TL0=(65536-2000)...

单片机C语言程序设计实训100例:基于8051+Proteus仿真的内容简介_百度知 ...
串口控制,模数与数模转换部分等;第四章在前面的基础上对扩展的外围硬件应用进行编程,包括译码器、串并转换芯片、存储器、中英文液晶屏、IIC等;第五章是综合设计部分,涉及一些具体的应用型产品的设计。读者对象:《单片机C语言程序设计实训100例:基于8051+Proteus仿真》适用于计算机专业或电子类专业在校...

8051系列单片机有何特点?有机种类型产品型号?彼此有何区别?
和其他单片机差不多嘛,还不是有cpu、rom、ram、io等等,只是它是8051内核的。不过它作为单片机领域的中低档产品从诞生到现在数十年市场占有率一直很高它便宜,操作简单,接口方便,经过发展,内嵌了很多资源,比如有的有PWM、ADC等等他的指令系统一般是CISC即复杂指令集至于种类,每个公司都有自己的产品,...

8051单片机有哪些硬件结构?
8051单片机的内部硬件结构包括:1、中央处理器CPU:它是单片机内部的核心部件,决定了单片机的主要功能特性,由运算器和控制器两大部分组成。2、存储器:8051单片机在系统结构上采用了哈佛型,将程序和数据分别存放在两个存储器内,一个称为程序存储器,另一个为数据存储器在物理结构上分程序存储器和数据...

什么是8051单片机?
8051单片机最早由Intel公司推出,其后,多家公司购买了8051的内核,使得以8051为内核的MCU系列单片机在世界上产量最大,应用也最广泛。比较常用的有ATMEL公司的51系列单片机,宏晶科技的STC系列单片机,PHILIPS公司的80C51系列单片机,华邦公司的W77、W78系列8位单片机等。

简述8051单片机的定时\/计数器的四种工作方式的特点。
具体如下所示:1、为13位计数器,由TL(1\/0)的低5位和TH(0\/1)的8位组,此时TL(1\/0)的高3位未用。C\/T:C\/T为0就是用作定时器(开关往上打),如果C\/T为1就是用作计数器(开关往下打)。GATE:GATE后非门后是一或门,GATE=0时只要TR1=0则开关闭合。2、是16位的定时\/计数方式...

stm32单片机和51单片机区别
STM32单片机和51单片机的区别如下:1、处理器内核不同。STM32单片机通常采用ARMCortex-M内核,如Cortex-M3或Cortex-M4,而51单片机则基于Intel8051架构。2、存储容量不同。STM32单片机通常具有更多的片上内存,如几十KB到几百KB的Flash和更多的RAM,处理速度不同。STM32单片机的处理速度通常更快,运算能力...

8051内核单片机xdata的处理
    在项目开发中遇到需要使用8051核的单片机去驱动oled屏显示数据量较大的一些图片,项目中使用的是新唐N76E003AT20的8051单片机,将底层OLED的驱动和显示函数从已经量产的项目中移植过来发现屏幕无法点亮。    针对这种问题,首先就去查找写给屏幕的驱动命令有没有传...

求基于8051单片机用C语言编写的双矩阵键盘扫描程序(5个IO口控制25个按 ...
我这里有一个程序,include<reg51.h> define rowkey() (~P2)&0x0f\/\/键盘输入端 define OUT P0 \/\/数码管显示输出端 unsigned char code TAB[]= { 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0x89,0xC7,0xC8,0xC1,0x8C,0xA3,...

8051单片机功能简介
8051单片机是一种在70年代中期发展起来的微型控制器,作为微计算机的重要分支,它集成了CPU、RAM、ROM、I\/O接口和中断系统于单一硅片,具有高度集成的特点。自那时以来,单片机发展迅速,广泛应用于工厂自动化和各种控制领域,成为不可或缺的技术支撑。8051单片机的标准型号是40引脚双列直插式IC,引脚分布包括...

汝阳县13919625970: 求基于8051单片机用C语言编写的双矩阵键盘扫描程序(5个IO口控制25个按键)
屠姿丽珠: main主程序 会一直循环执行两次判断P0口的值 是为了 去除按键抖动不知道我说的对不对 呵呵 刚学的 void keyscan()//矩阵键盘扫描程序 { P0=0x0f;

汝阳县13919625970: 8051单片机c语言编一个程序 8个按键按下显示相应1到8 -
屠姿丽珠: 8 个独立按键? #include<reg51.h>#define uchar unsigned char#define uint unsigned int uchar i; uchar code tab[]={ 0xC0,/*0*/ 0xF9,/*1*/ 0xA4,/*2*/ 0xB0,/*3*/ 0x99,/*4*/ 0x92,/*5*/ 0x82,/*6*/ 0xF8,/*7*/ 0x80,/*8*/ 0x90,/*9*/ }; sbit key1=P1^0; sbit key2...

汝阳县13919625970: 跪求会C8051F020单片机的,要用C语言写出测量电压,就是AD转换的程序 -
屠姿丽珠: void Timer3_Init() { TMR3CN = 0x02; TMR3R = -44236; //定时2ms TMR3 = 0xffff; EIE2 &= ~0x01; TMR3CN |= 0x04; } void ADC0_Init(void) { AMX0SL=0x00; //选择通道0 AMX0CF=0x00; //选择AIN0和AIN1为独立输入 REF0CN=0x03; //选择外...

汝阳县13919625970: 用c语言编程实现C8051F300单片机1s定时,50Hz的方波输出 -
屠姿丽珠: #include sbit wave=P1^0; void SetupTimer0() { TMOD &= 0XF0; //仅保留T1信息 TMOD |= 0X02; //设置T0: 定时功能,方式2,自动重载8位定时器/计数器 TH0 = 256-250;//定时每0.25ms中断一次 TL0 = 256-250; TR0 = 1; //开启定时器 ET0 ...

汝阳县13919625970: c语言编程:8051单片机系统的时钟为11.0592,把0~99从串行口输出. -
屠姿丽珠: #include <reg51.h>#define XTAL 11059200 // CPU晶振频率 #define baudrate 9600 // 通信波特率 #define uchar unsigned char #define uint unsigned int char aa, bb = 0; //----------------------------------------------------------- void main(void) {PCON = 0x00...

汝阳县13919625970: C语言编8051FX系列的控制LED灯的程序 -
屠姿丽珠: 是 C8051FXXX系列的单片机么?我用的编译器是Keil C程序如下: //我用的是310的片子 #include #include //初始化系统时钟 void SYSCLK_Init() {OSCICN = 0x83; }void Port_Init() {//输出为推挽方式P1MDOUT = 0xFF;//允...

汝阳县13919625970: 8051单片机的锁存器控制地址时,用c语言怎么编程? -
屠姿丽珠: 将地址定义为指针就行了,例如: unsigned char xdata *reg_addr=(char *)0x00ff;

汝阳县13919625970: 51系列单片机用c语言编程实现1s定时、1khz方波、512hz方波输出,麻烦多在程序后注释解释程序意思,谢谢 -
屠姿丽珠: 以C8051F120为例: 要先配置启动时钟,可以是内部时钟也可以是外部时钟; 再配置交叉端口输出; 之后编写定时器的配置和输出(模式要配置好); 走后别忘了页总线的 切换.具体和51没什么区别,可以参考51

汝阳县13919625970: 求一个8051单片机控制音乐喷泉C语言程序 -
屠姿丽珠: 8051做傅氏变换,开玩笑呢吧.把AD结果平均一下,看有效值多少,分成8档,控制一下LED指示一下电平,差不多也就做到这个程度了.真像做喷泉,即使不用DSP,FPGA,也得用个几十M的ARM,估计都有点勉强.程序呢,就是FFT分析音频的谐波分量.

汝阳县13919625970: 需要基于8051单片机的8键电子琴的C代码! -
屠姿丽珠: 首先你得编出8个键相应的音高和音调,分别对应信号的幅度和频率.需要键盘中断模块,用到51的外部中断来确定按键的序号,进入相应的中断处理程序,并驱动蜂鸣器发出对应频率的声音.大概步骤是这样的,具体的频率实现就是定时器那些,得反复调试才能出来合适的声音,c代码网上应该很多,大同小异!

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网