当前位置:文档之家› 矩阵键盘反转扫描

矩阵键盘反转扫描

矩阵键盘反转扫描
矩阵键盘反转扫描

/*-----------------------------------------------

名称:矩阵键盘依次输入控制

论坛:https://www.doczj.com/doc/a718354482.html,

编写:shifang

日期:2009.5

修改:无

内容:如计算器输入数据形式相同从右至左

------------------------------------------------*/

#include //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义

#define DataPort P0 //定义数据端口程序中遇到DataPort 则用P0 替换

#define KeyPort P1

sbit LATCH1=P2^2;//定义锁存使能端口段锁存

sbit LATCH2=P2^3;// 位锁存

unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,

0x77,0x7c,0x39,0x5e,0x79,0x71};// 显示段码值0~F

unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码

unsigned char TempData[8]; //存储显示值的全局变量

void DelayUs2x(unsigned char t);//us级延时函数声明

void DelayMs(unsigned char t); //ms级延时

void Display(unsigned char FirstBit,unsigned char Num);//数码管显示函数

unsigned char KeyScan(void);//键盘扫描

unsigned char KeyPro(void);

void Init_Timer0(void);//定时器初始化

/*------------------------------------------------

主函数

------------------------------------------------*/

void main (void)

{

unsigned char num,i,j;

unsigned char temp[8];

Init_Timer0();

while (1) //主循环

{

num=KeyPro();

if(num!=0xff)

{

if(i<8)

{

temp[i]=dofly_DuanMa[num];

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

TempData[7-i+j]=temp[j];

}

i++;

if(i==9)//多出一个按键输入为了清屏原本应该为8

{

i=0;

for(j=0;j<8;j++)//清屏

TempData[j]=0;

}

}

//Display(0,8); //显示全部8位

//主循环中添加其他需要一直工作的程序

}

}

/*------------------------------------------------

uS延时函数,含有输入参数unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是

0~255 这里使用晶振12M,精确延时请使用汇编,大致延时长度如下T=tx2+5 uS

------------------------------------------------*/

void DelayUs2x(unsigned char t)

{

while(--t);

}

/*------------------------------------------------

mS延时函数,含有输入参数unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是

0~255 这里使用晶振12M,精确延时请使用汇编

------------------------------------------------*/

void DelayMs(unsigned char t)

{

while(t--)

{

//大致延时1mS

DelayUs2x(245);

DelayUs2x(245);

}

}

/*------------------------------------------------

显示函数,用于动态扫描数码管

输入参数FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示

如输入0表示从第一个显示。

Num表示需要显示的位数,如需要显示99两位数值则该值输入2

------------------------------------------------*/

void Display(unsigned char FirstBit,unsigned char Num)

{

static unsigned char i=0;

DataPort=0; //清空数据,防止有交替重影

LATCH1=1; //段锁存

LATCH1=0;

DataPort=dofly_WeiMa[i+FirstBit]; //取位码

LATCH2=1; //位锁存

LATCH2=0;

DataPort=TempData[i]; //取显示数据,段码

LATCH1=1; //段锁存

LATCH1=0;

i++;

if(i==Num)

i=0;

}

/*------------------------------------------------

定时器初始化子程序

------------------------------------------------*/

void Init_Timer0(void)

{

TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响

//TH0=0x00; //给定初值

//TL0=0x00;

EA=1; //总中断打开

ET0=1; //定时器中断打开

TR0=1; //定时器开关打开

}

/*------------------------------------------------

定时器中断子程序

------------------------------------------------*/

void Timer0_isr(void) interrupt 1

{

TH0=(65536-2000)/256; //重新赋值2ms

TL0=(65536-2000)%256;

Display(0,8); // 调用数码管扫描

}

/*------------------------------------------------

按键扫描函数,返回扫描键值

------------------------------------------------*/

unsigned char KeyScan(void) //键盘扫描函数,使用行列反转扫描法{

unsigned char cord_h,cord_l;//行列值中间变量

KeyPort=0x0f; //行线输出全为0

cord_h=KeyPort&0x0f; //读入列线值

if(cord_h!=0x0f) //先检测有无按键按下

{

DelayMs(10); //去抖

if((KeyPort&0x0f)!=0x0f)

{

cord_h=KeyPort&0x0f; //读入列线值

KeyPort=cord_h|0xf0; //输出当前列线值

cord_l=KeyPort&0xf0; //读入行线值

while((KeyPort&0xf0)!=0xf0);//等待松开并输出

return(cord_h+cord_l);//键盘最后组合码值

}

}return(0xff); //返回该值

}

/*------------------------------------------------

按键值处理函数,返回扫键值

------------------------------------------------*/

unsigned char KeyPro(void)

{

switch(KeyScan())

{

case 0x7e:return 0;break;//0 按下相应的键显示相对应的码值

case 0x7d:return 1;break;//1

case 0x7b:return 2;break;//2 case 0x77:return 3;break;//3 case 0xbe:return 4;break;//4 case 0xbd:return 5;break;//5 case 0xbb:return 6;break;//6 case 0xb7:return 7;break;//7 case 0xde:return 8;break;//8 case 0xdd:return 9;break;//9 case 0xdb:return 10;break;//a case 0xd7:return 11;break;//b case 0xee:return 12;break;//c case 0xed:return 13;break;//d case 0xeb:return 14;break;//e case 0xe7:return 15;break;//f default:return 0xff;break;

}

}

汇编矩阵键盘程序

方法一、 ORG 0000H LJMP MAIN ORG 0100H MAIN: MOV P1,#0F0H //P1口设初值F0,矩阵按键高四位置1,低四位置0, JNB P1.4,Y0 //用JNB检测按键端口,P1.4口低电平跳转 Y0 JNB P1.5,Y1 JNB P1.6,Y2 JNB P1.7,Y3 SJMP MAIN Y0: MOV 30H,#00H MOV P1,#0EFH JNB P1.4,X0 MOV P1,#0DFH JNB P1.4,X1 MOV P1,#0BFH JNB P1.4,X2 MOV P1,#07FH JNB P1.4,X3 Y1: MOV 30H,#01H MOV P1,#0EFH JNB P1.0,X0 MOV P1,#0DFH JNB P1.1,X1 MOV P1,#0BFH JNB P1.2,X2 MOV P1,#7FH JNB P1.3,X3 Y2: MOV 30H,#02H MOV P1,#0EFH JNB P1.0,X0 MOV P1,#0DFH JNB P1.1,X1 MOV P1,#0BFH JNB P1.2,X2 MOV P1,#7FH JNB P1.3,X3 Y3: MOV 30H,#03H MOV P1,#0EFH

MOV P1,#0DFH JNB P1.1,X1 MOV P1,#0BFH JNB P1.2,X2 MOV P1,#7FH JNB P1.3,X3 X0: MOV 31H,#00H ACALL DELAY MOV P1,#0F0H LJMP JISUAN X1: MOV 31H,#01H ACALL DELAY MOV P1,#0F0H LJMP JISUAN X2: MOV 31H,#02H ACALL DELAY MOV P1,#0F0H LJMP JISUAN X3: MOV 31H,#03H ACALL DELAY MOV P1,#0F0H LJMP JISUAN JISUAN: MOV A,31H MOV B,#04H MUL AB ADD A,30H MOV DPTR,#TAB MOVC A,@A+DPTR MOV P0,A CC: MOV A,P1 ANL A,#0F0H XRL A,#0F0H JNZ CC LCALL MAIN DELAY: MOV R4,#0C5H D1: MOV R5,#43H D0: MOV R6,#10H

51单片机04矩阵按键逐行扫描,行列扫描代码

矩阵键盘扫描原理 方法一: 逐行扫描:我们可以通过高四位轮流输出低电平来对矩阵键盘进行逐行扫描,当低四位接收到的数据不全为1的时候,说明有按键按下,然后通过接收到的数据是哪一位为0来判断是哪一个按键被按下。 方法二: 行列扫描:我们可以通过高四位全部输出低电平,低四位输出高电平。当接收到的数据,低四位不全为高电平时,说明有按键按下,然后通过接收的数据值,判断是哪一列有按键按下,然后再反过来,高四位输出高电平,低四位输出低电平,然后根据接收到的高四位的值判断是那一行有按键按下,这样就能够确定是哪一个按键按下了。

//行列扫描 #include #define GPIO_KEY P0 #define GPIO_LCD P2 unsigned char code a[17]= {~0xfc,~0x60,~0xda,~0xf2,~0x66,~0xb6,~0xbe,~0xe0, ~0xfe,~0xf6,~0xee,~0x3e,~0x9c,~0x7a,~0xde,~0x8e,~0x00}; //按位取反的用法 void delay10ms(); void keydown();//要与下面的定义一致 void main() { GPIO_LCD=a[16];//初始化数码管 while(1) { keydown(); } }

void delay10ms() { unsigned char a,b; for(a=38;a>0;a--) for(b=130;b>0;b--); } void keydown() //检测按下,按下时需要消抖,检测松开,返回按键值//没有按键时保持 { unsigned char n=0,key; GPIO_KEY=0x0f; if(GPIO_KEY!=0x0f)//读取按键是否按下 { delay10ms(); //延时10ms消抖 if(GPIO_KEY!=0x0f)//再次检测按键是否按下 { GPIO_KEY=0x0f;//测试列 switch(GPIO_KEY) { case 0x07: key=0;break;

单片机矩阵键盘扫描程序

#include #include #define uint unsigned int #define uchar unsigned char sbit E=P2^7; //1602使能引脚 sbit RW=P2^6; //1602读写引脚 sbit RS=P2^5; //1602数据/命令选择引脚 uint keyflag ; //键盘正在读取标志位,如果Keyflag为1 ,表示正在读取键盘,停止其他功能; char x,y,m,n,c; //Keyflag为0,读取键盘结束,恢复其他功能 char flag1=0; //频率范围10~1000Hz uchar Hrate = 0; //一个周期内高点平占据时间 uchar Lrate = 0; //一个周期内低电平占据时间 uint FREQ0; //定时器T0的计数变量// uint FREQ1; //定时器T1的计数变量// sbit P2_1=P2^0; //设置P2.1,作为信号输出口// uint disbuf[3]; uint figure=0; int sum2=0; int sum1=0; int flag=0; uint count=0; uint max=0; uint disbuf_temp=0; /******************************************************************** * 名称: 1602显示延时函数delay() * 功能: 延时,延时时间大概为5US。

* 输出: 无 ***********************************************************************/ void delay() { _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); } /******************************************************************** * 名称: bit Busy(void) * 功能: 这个是一个读状态函数,读出函数是否处在忙状态 * 输入: 输入的命令值 * 输出: 无 ***********************************************************************/ bit Busy(void) { bit busy_flag = 0; RS = 0; RW = 1; E = 1; delay(); busy_flag = (bit)(P0 & 0x80); E = 0; return busy_flag; } /******************************************************************** * 名称: wcmd(uchar del) * 功能: 1602命令函数 * 输入: 输入的命令值 * 输出: 无 ***********************************************************************/ void wcmd(uchar del) { while(Busy()); RS = 0; RW = 0; E = 0; delay(); P0 = del; delay(); E = 1;

行列反转扫描法在矩阵键盘中的应用及编程思想

行列反转扫描法在矩阵键盘中的应用及编程思想 我现在正在学习51单片机,学到矩阵键盘时,遇到了一些小问题,感觉行列扫描法原理简单,但编程较啰嗦,而且没有固定的编程模式,一个人一个编法,代码复杂,一会儿就能把人绕晕。于是我就想寻找有没有一种编程思想灵巧,代码简便的程序,通过苦苦在网上寻觅,终于找到了反转法。 行列反转扫描法法可能有些教材资料里都有,但是介绍都不够详细,我找到一个资料,代码非常简单,但是并不好理解,我苦苦思索了一个晚上才弄明白。于是根据反转法的思想,我写了一个代码不是最少,但却是非常容易理解的程序,在此拿来与大家共享。此程序已在开发板及Proteus软件中仿真成功。 电路原理图: P1口接矩阵键盘,其中P1.0~P1.3接行线,P1.4~P.7接列线,P0口接共阴极7段数码管。

反转法的原理: 反转法就是通过给单片机的端口赋值两次,最后得出所按键的值的一种算法。 for example: 如图1所示,取P1口的低四位为行线,高四位为列线。 1.我们给P1口赋值0x0f,即00001111,假设0键按下了,则这时P1口的实际值为00001110;

2.我们给P1口再赋值0xf0,即11110000,如果0键按下了,则这时P1口的实际值为11100000; 3.我们把两次P1口的实际值相加得11101110,即0xee。 由此我们便得到了按下0键时所对应的数值0xee,以此类推可得出其他15个按键对应的数值,有了这种对应关系,矩阵键盘编程问题也就解决了,也就是程序的算法已经有了。对应关系见图2. 以下为程序: /*反转法矩阵键盘的应用,我认为这是一个编程简便又容易理解的矩阵键盘编程应用*/ #include //头文件

矩阵键盘扫描实验

实验矩阵键盘扫描实验 一、实验要求 利用4X4 16位键盘和一个7段LED构成简单的输入显示系统,实现键盘输入和LED 显示实验。 二、实验目的 1、理解矩阵键盘扫描的原理; 2、掌握矩阵键盘与51单片机接口的编程方法。 三、实验电路及连线 Proteus实验电路

1、主要知识点概述: 本实验阐述了键盘扫描原理,过程如下:首先扫描键盘,判断是否有键按下,再确定是哪一个键,计算键值,输出显示。 2、效果说明: 以数码管显示键盘的作用。点击相应按键显示相应的键值。 五、实验流程图

1、Proteus仿真 a、在Proteus中搭建和认识电路; b、建立实验程序并编译,加载hex文件,仿真; c、如不能正常工作,打开调试窗口进行调试 参考程序: ORG 0000H AJMP MAIN ORG 0030H MAIN: MOV DPTR,#TABLE ;将表头放入DPTR LCALL KEY ;调用键盘扫描程序 MOVC A,@A+DPTR ;查表后将键值送入ACC MOV P2,A ;将ACC值送入P0口 LJMP MAIN ;返回反复循环显示 KEY: LCALL KS ;调用检测按键子程序 JNZ K1 ;有键按下继续 LCALL DELAY2 ;无键按调用延时去抖 AJMP KEY ;返回继续检测按键 K1: LCALL DELAY2 LCALL DELAY2 ;有键按下延时去抖动 LCALL KS ;再调用检测按键程序 JNZ K2 ;确认有按下进行下一步 AJMP KEY ;无键按下返回继续检测 K2: MOV R2,#0EFH ;将扫描值送入R2暂存MOV R4,#00H ;将第一列值送入R4暂存 K3: MOV P1,R2 ;将R2的值送入P1口 L6: JB P1.0,L1 ;P1.0等于1跳转到L1 MOV A,#00H ;将第一行值送入ACC AJMP LK ;跳转到键值处理程序 L1: JB P1.1,L2 ;P1.1等于1跳转到L2 MOV A,#04H ;将第二行的行值送入ACC AJMP LK ;跳转到键值理程序进行键值处理 L2: JB P1.2,L3 ;P1.2等于1跳转到L3

经典的矩阵键盘扫描程序

键盘是单片机常用输入设备,在按键数量较多时,为了节省I/O口等单片机资源,一般采取扫描的方式来识别到底是哪一个键被按下。即通过确定被按下的键处在哪一行哪一列来确定该键的位置,获取键值以启动相应的功能程序。 4*4矩阵键盘的结构如图1(实物参考见万用板矩阵键盘制作技巧)。在本例中,矩阵键盘的四列依次接到单片机的P1.0~P1.3,四行依次接到单片机的P1.4~P1.7;同时,将列线上拉,通过10K电阻接电源。 查找哪个按键被按下的方法为:一个一个地查找。 先第一行输出0,检查列线是否非全高; 否则第二行输出0,检查列线是否非全高; 否则第三行输出0,检查列线是否非全高; 如果某行输出0时,查到列线非全高,则该行有按键按下; 根据第几行线输出0与第几列线读入为0,即可判断在具体什么位置的按键按下。 下面是具体程序:

void Check_Key(void) { unsigned char row,col,tmp1,tmp2; tmp1 = 0x10; //tmp1用来设置P1口的输出,取反后使 P1.4~P1.7中有一个为0 for(row=0;row<4;row++) // 行检测 { P1 = 0x0f; // 先将p1.4~P1.7置高 P1 =~tmp1; // 使P1.4~p1.7中有一个为0 tmp1*=2; // tmp1左移一位 if ((P1 & 0x0f) < 0x0f) // 检测P1.0~P1.3中是否有一位为0,只要有,则说明此行有键按下,进入列检测 { tmp2 = 0x01; // tmp2用于检测出哪一列为0 for(col =0;col<4;col++) // 列检测 { if((P1 & tmp2)==0x00) // 该列如果为低电平则可以判定为该列 { key_val =key_Map[ row*4 +col ]; // 获取键值,识别按键;key_Map为按键的定义表 return; // 退出循环 } tmp2*=2; // tmp2左移一位 } } } } //结束 这是一种比较经典的矩阵键盘识别方法,实现起来较为简单,程序短小精炼。

扫描式矩阵键盘课程设计

扫描式矩阵键盘课程设 计 Company number【1089WT-1898YT-1W8CB-9UUT-92108】

4X4扫描式矩阵键盘课程设计课程设计名称: 4_4扫描式矩阵键盘设计 姓名: DUKE 班级:电子1008班 学号: 10086 成绩: 日期: 2014年1月6日 摘要 随着21世纪的到来,电子信息行业将是人类社会的高科技行业之一,式设施现代化的基础,也是人类通往科技巅峰的直通路。电子行业的发展从长远来看很重要,但最主要的还是科技问题。 矩阵式键盘提高效率进行按键操作管理有效方法,它可以提高系统准确性,有利于资源的节约,降低对操作者本身素质的要求。是它能准时、实时、高效地显示按键信息,以提高工作效率和资源利用率。 矩阵式键盘乃是当今使用最为广泛的键盘模式,该系统以N个端口连接控制N*N个按键,显示在LED数码管上。单片机控制依据这是键盘显示系统,该系统可以对不同的按键进行实时显示,其核心是单片机和键盘矩阵电路部分,主要对按键与显示电路的关系、矩阵式技术及设备系统的硬件、软件等各个部分进行实现。 4*4矩阵式键盘采用AT89C51单片机为核心,主要由矩阵式键盘电路、译码电路、显示电路等组成,软件选用C语言编程。单片机将检测到的按键信号

转换成数字量,显示于LED显示器上。该系统灵活性强,易于操作,可靠性高,将会有更广阔的开发前景。 目录 第一章:系统功能要求-------------------------------------------------------- 1.1 4*4 矩阵式键盘系统概述------------------------------------------------ 1.2 本设计任务和主要内容--------------------------------------------------- 第二章:方案论证--------------------------------------------------------------- 第三章:系统硬件电路的设计------------------------------------------------ 3.1 单片机控制系统原理----------------------------------------------------- 3.2 原理图绘制说明---------------------------------------------------------- 3.3 画出流程图---------------------------------------------------------------- 3.4 原理图绘制---------------------------------------------------------------

矩阵键盘的工作原理和扫描确认方式

9.3.1 矩阵键盘的工作原理和扫描确认方式 来源:《AVR单片机嵌入式系统原理与应用实践》M16华东师范大学电子系马潮 当键盘中按键数量较多时,为了减少对I/O 口的占用,通常将按键排列成矩阵形式,也称为行列键盘,这是一种常见的连接方式。矩阵式键盘接口见图9-7 所示,它由行线和列线组成,按键位于行、列的交叉点上。当键被按下时,其交点的行线和列线接通,相应的行线或列线上的电平发生变化,MCU 通过检测行或列线上的电平变化可以确定哪个按键被按下。 图9-7 为一个 4 x 3 的行列结构,可以构成12 个键的键盘。如果使用 4 x 4 的行列结构,就能组成一个16 键的键盘。很明显,在按键数量多的场合,矩阵键盘与独立式按键键盘相比可以节省很多的I/O 口线。 矩阵键盘不仅在连接上比单独式按键复杂,它的按键识别方法也比单独式按键复杂。在矩阵键盘的软件接口程序中,常使用的按键识别方法有行扫描法和线反转法。这两种方法的基本思路是采用循环查循的方法,反复查询按键的状态,因此会大量占用MCU 的时间,所以较好的方式也是采用状态机的方法来设计,尽量减少键盘查询过程对MCU 的占用时间。 下面以图9-7 为例,介绍采用行扫描法对矩阵键盘进行判别的思路。图9-7 中,PD0、PD1、PD2 为3 根列线,作为键盘的输入口(工作于输入方式)。PD3、PD4、PD5、PD6 为4根行线,工作于输出方式,由MCU(扫描)控制其输出的电平值。行扫描法也称为逐行扫描查询法,其按键识别的过程如下。 √将全部行线PD3-PD6 置低电平输出,然后读PD0-PD2 三根输入列线中有无低电平出现。只要有低电平出现,则说明有键按下(实际编程时,还要考虑按键的消抖)。如读到的都是高电平,则表示无键按下。 √在确认有键按下后,需要进入确定具体哪一个键闭合的过程。其思路是:依

矩阵键盘程序c程序,51单片机.

/*编译环境:Keil 7.50A c51 */ /*******************************************************/ /*********************************包含头文件********************************/ #include /*********************************数码管表格********************************/ unsigned char table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x 8E}; /**************************************************************************** 函数功能:延时子程序 入口参数: 出口参数: ****************************************************************************/ void delay(void) { unsigned char i,j; for(i=0;i<20;i++) for(j=0;j<250;j++); } /**************************************************************************** 函数功能:LED显示子程序 入口参数:i 出口参数: ****************************************************************************/ void display(unsigned char i) { P2=0xfe; P0=table[i]; } /**************************************************************************** 函数功能:键盘扫描子程序 入口参数: 出口参数: ****************************************************************************/ void keyscan(void) { unsigned char n; //扫描第一行 P1=0xfe;

矩阵键盘简易计算器要点

《微处理器系统与接口技术》课程实践报告 计算器 班级: 学号: 学生姓名: 指导老师: 日期: 2014.7.5 ******电子与信息工程学院

目录 1、设计题目:计算器 (3) 2、设计目的 (3) 3、计算器总体设计框图 (3) 4、计算器详细设计过程 (4) 4.1输入模块 (4) 4.2键盘输入电路 (5) 4.3主程序模块 (6) 5、分析与调试 (6) 7、运行结果 (8) 8、结束语 (8) 8、参考文献 (8) 9、源程序附录 (9) 9.1主程序 (9) 9.2延时函数delay (12) 9.3显示函数display (12) 9.4键盘扫描函数 (14) 9.5预定义函数 (15)

1、设计题目:计算器 2、设计目的 此次课程实践题目是基于单片机简单计数器的设计,本此设计使用的是Intel公司MCS-51系列的8051AH单片机。设计的计算器可以实现2位小数的加、减、乘、除运算以及整数的乘方运算,其中用4*4矩阵键盘来输入待参与运算的数据和运算符;八位数码管动态显示输入待参与运算的数据以及运算后产生的结果,每个硬件模块的调用过程中涉及到了函数入口及出口参数说明,函数调用关系描述等。 3、计算器总体设计框图 计算器以MCS-51系列的8051AH单片机作为整个系统的控制核心,应用其强大的I/O功能和计算速度,构成整个计算器。通过矩阵键盘输入运算数据和符号,送入单片机进行数据处理。经单片机运算后控制LED数码管的输出。整体框图如图1所示: 图3 整体框图 本系统硬件主要由矩阵键盘、独立键盘I/O输入输出、数码管显示等主要部分组成。各模块的主要功能如下: (1)矩阵键盘将十六进制编码的数字送到单片机。 (2) 单片机扫描键盘信号并接收,对输入的键盘信号进行处理 (3) LED以动态扫描的方式移位显示每次输入的数据和最后的运算结果。实践设计的具体流程图如下图2所示:

PIC单片机自学手记之矩阵键盘 行扫描法

PIC单片机自学手记——PIC单片机矩阵键盘+行扫描法 /*采用行扫描法RAM占用空间较少(呵呵起码我写的程序是这样的,因为我刚开始学,还不是很懂各方面的程序优化)*/ #include __CONFIG(0x3F32); //芯片配置字 #define uchar unsigned char #define uint unsigned int void delay10ms(uchar x); void beep(); void init(); uchar key; uchar LED_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8, 0x80,0x90,0xbf}; void keyscan(){uchar temp; PORTB=0x07;//将列线置0,行线作为输入状态检测。 temp=PORTB;//读回B端口状态值 if((temp&0x07)!=0x07)//将读取的值跟0x07做与运算然后再判断是否不等于0x07,如果不等于说明有按键按下{delay10ms (1);//延时10毫秒,去抖动(去干扰) PORTB=0x07;//同上 temp=PORTB;//同上

if((temp&0x07)!=0x07)//延时消抖后再次判断是否真的有按键按下,如果有再判断是此行的哪个按键(这里我们用的是3x3矩阵键盘,则每行有3种情况){PORTB=0x37;//第一行状态 temp=PORTB;//读回B端口状态值 switch(temp)//判断第一行按键按下后可能产生的情况{case 0x33:key=7;break;//第一种情况:1号按键按下_0B0011 0011 case 0x35:key=4;break;//第二种情况:2号按键按下_0B0011 01 case 0x36:key=1;break;//第三种情况:3号按键按下_0B0011 0110}PORTB=0x2F;//第二行状态 temp=PORTB;//读回B端口状态值 switch(temp)//判断第二行按键按下后可能产生的情况{case 0x2b: key=8;break;//第一种情况:4号按键按下_0B0010 1011 case 0x2d: key=5;break;//第二种情况:5号按键按下_0B0010 1101 case 0x2e: key=2;break;//第三种情况:6号按键按下_0B0011 1110}PORTB=0x1F;//第三行状态 temp=PORTB;//读回B端口状态值 switch(temp)//判断第三行按键按下后可能产生的情况{case 0x1b: key=9;break;//第一种情况:7号按键按下_0B0001 1011 case 0x1d: key=6;break;//第二种情况:8号按键按下_0B0001 1101 case 0x1e:

51单片机矩阵键盘扫描程序

/*----------------------------------------------- 名称:矩阵键盘依次输入控制使用行列逐级扫描 论坛:https://www.doczj.com/doc/a718354482.html, 编写:shifang 日期:2009.5 修改:无 内容:如计算器输入数据形式相同从右至左使用行列扫描方法 ------------------------------------------------*/ #include //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义 #define DataPort P0 //定义数据端口程序中遇到DataPort 则用P0 替换 #define KeyPort P1 sbit LATCH1=P2^2;//定义锁存使能端口段锁存 sbit LATCH2=P2^3;// 位锁存 unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, 0x77,0x7c,0x39,0x5e,0x79,0x71};// 显示段码值0~F unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码 unsigned char TempData[8]; //存储显示值的全局变量 void DelayUs2x(unsigned char t);//us级延时函数声明 void DelayMs(unsigned char t); //ms级延时 void Display(unsigned char FirstBit,unsigned char Num);//数码管显示函数 unsigned char KeyScan(void);//键盘扫描 unsigned char KeyPro(void); void Init_Timer0(void);//定时器初始化 /*------------------------------------------------ 主函数 ------------------------------------------------*/ void main (void) { unsigned char num,i,j; unsigned char temp[8]; Init_Timer0(); while (1) //主循环 { num=KeyPro();

51单片机矩阵键盘程序

/*风清云扬*/ # include #define uchar unsigned char #define uint unsigned int void delay(uint i) { uchar x,j; for(j=0;j

} else if(temp0==0x0b) { switch (temp1) { case 0xe0: num=12;break; case 0xd0: num=11;break; case 0xb0: num=10;break; case 0x70: num=9;break; default:num=0;break; } } else if(temp0==0x07) { switch (temp1) { case 0xe0: num=16;break; case 0xd0: num=15;break; case 0xb0: num=14;break; case 0x70: num=13;break; default:num=0;break; } } } } return num; } void main() { char num; while(1) { num=key_scan(); P2=num/10; P3=num%10; } }

单片机矩阵键盘行列扫描程序学习资料

//行列扫描程序,可以自己定义端口和扫描方式,这里做简单介绍 #include //包含头文件 #define uchar unsigned char #define uint unsigned int unsigned char const dofly[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, 0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F uchar keyscan(void); void delay(uint i); void main() { uchar key; P2=0x00;//1数码管亮按相应的按键,会显示按键上的字符 while(1) { key=keyscan();//调用键盘扫描, switch(key) { case 0x7e:P0=dofly[0];break;//0 按下相应的键显示相对应的码值 case 0x7d:P0=dofly[1];break;//1 case 0x7b:P0=dofly[2];break;//2 case 0x77:P0=dofly[3];break;//3 case 0xbe:P0=dofly[4];break;//4 case 0xbd:P0=dofly[5];break;//5 case 0xbb:P0=dofly[6];break;//6 case 0xb7:P0=dofly[7];break;//7 case 0xde:P0=dofly[8];break;//8 case 0xdd:P0=dofly[9];break;//9 case 0xdb:P0=dofly[10];break;//a case 0xd7:P0=dofly[11];break;//b case 0xee:P0=dofly[12];break;//c case 0xed:P0=dofly[13];break;//d case 0xeb:P0=dofly[14];break;//e case 0xe7:P0=dofly[15];break;//f } } } uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法 {

X4扫描式矩阵键盘课程设计

X4扫描式矩阵键盘课程设计 (总13页) -CAL-FENGHAI.-(YICAI)-Company One1 -CAL-本页仅作为文档封面,使用请直接删除

4X4扫描式矩阵键盘课程设计 课程设计名称: 4_4扫描式矩阵键盘设计 姓名: DUKE 班级:电子1008班 学号: 10086 成绩: 日期: 2014年1月6日

摘要 随着21世纪的到来,电子信息行业将是人类社会的高科技行业之一,式设施现代化的基础,也是人类通往科技巅峰的直通路。电子行业的发展从长远来看很重要,但最主要的还是科技问题。 矩阵式键盘提高效率进行按键操作管理有效方法,它可以提高系统准确性,有利于资源的节约,降低对操作者本身素质的要求。是它能准时、实时、高效地显示按键信息,以提高工作效率和资源利用率。 矩阵式键盘乃是当今使用最为广泛的键盘模式,该系统以N个端口连接控制N*N 个按键,显示在LED数码管上。单片机控制依据这是键盘显示系统,该系统可以对不同的按键进行实时显示,其核心是单片机和键盘矩阵电路部分,主要对按键与显示电路的关系、矩阵式技术及设备系统的硬件、软件等各个部分进行实现。 4*4矩阵式键盘采用AT89C51单片机为核心,主要由矩阵式键盘电路、译码电路、显示电路等组成,软件选用C语言编程。单片机将检测到的按键信号转换成数字量,显示于LED显示器上。该系统灵活性强,易于操作,可靠性高,将会有更广阔的开发前景。

目录 第一章:系统功能要求-------------------------------------------------------- 4*4 矩阵式键盘系统概述------------------------------------------------ 本设计任务和主要内容--------------------------------------------------- 第二章:方案论证--------------------------------------------------------------- 第三章:系统硬件电路的设计------------------------------------------------ 单片机控制系统原理----------------------------------------------------- 原理图绘制说明---------------------------------------------------------- 画出流程图---------------------------------------------------------------- 原理图绘制--------------------------------------------------------------- 第四章:系统程序的设计------------------------------------------------------ 程序的编写步骤-----------------------------------------------------------

矩阵键盘数码管显示键值 程序

#include #include #define uchar unsigned char #define uint unsigned int uchar dis_buf; //显示缓存 uchar temp; uchar key; //键顺序吗 void delay0(uchar x); //x*0.14MS #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();}; // 此表为LED 的字模0 1 2 3 4 5 6 7 8 9 a b c d e f unsigned char code LED7Code[] = {~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,~0x07,~0x7F,~0x6F,~0x77,~0x7C,~0x39,~0x5 E,~0x79,~0x71}; /*************************************************************/ /* */ /* 延时子程序*/ /* */ /*************************************************************/ void delay(uchar x) { uchar j; while((x--)!=0) { for(j=0;j<125;j++) {;} } } /*************************************************************/ /* */ /* 键扫描子程序(4*3 的矩阵) P1.4 P1.5 P1.6 P1.7为行*/ /* P1.1 P1.2 P1.3为列*/ /* */ /*************************************************************/ void keyscan(void)

4×5矩阵键盘驱动程序

4×5矩阵键盘驱动程序 一、工作原理及接口电路 4×5矩阵键盘有4条列线,5条行线共20个按键。每个按键对应不同键值,键盘扫描采用外部中断扫描方式,本系统中键盘为无源结构,键盘工作时不依靠任何外部电源。4×5矩阵键盘结构图如图2-10 所示。 图2-10 4×5矩阵键盘结构图 1)4×5矩阵键盘结构及按键抖动消除 当键盘中按键数量较多时为减少I/O口的占用,通常将按键排列成矩阵形式,如图2-12所示。在矩阵式键盘中,每条行线和列线在交叉处不直接连通,而是通过一个机械弹性开关加以连接。这样5条列线(R0~R4)和4条行线(L0~L3)就可以构成20个按键的矩阵键盘。键盘采用了无源结构,工作是不依靠任何外部电源。 由于机械弹性开关的机械触点的弹性作用,一个按键开关在闭合时并不会马上稳定的闭合,在断开时也不会马上断开,因而机械开关在闭合及断开瞬间均伴有一连串的抖动,如图2-11所示。

图2-11 按键时的抖动 抖动的时间长短由按键开关机械特性及按键的人为因素决定,一般为5ms~20ms。按键抖动如果处理不当会引起一次按键被误处理多次,所以消除抖动是必要的。消除抖动的有硬件处理和软件处理两种方法。当按键较多一般采用软件消抖方式。软件消抖原理为当检测出按键闭合后执行一个延时程序(产生5ms~20ms的延时),待前沿抖动消失后再次检测按键的状态,如果按键仍保持闭合状态则可确认为有键按下。当检测到按键释放并执行延时程序,待后沿抖动消失后才转入按键的处理程序。 1)矩阵键盘的工作原理 从4×5矩阵键盘的4条列线和5条行线分别引出9条端线接于单片机的9个I/O 口,由于键盘采用了无源结构所以行列线的电平由单片机I/O口的电平决定。进入按键处理程序后先使4条列线全为低电平,5条行线全为高电平,为读行线状态做准备,没有按键时这种状态不会被改变。当键盘上的某个按键闭合时,则该键所对应的行线和列线被短路。例如:6号键被按下时列线L2与行线R1被短路,此时行线R1电平被列线L2拉低,由原来的高电平变为低电平而其它行线电平依然不变,为低电平。此时单片机可读得行线状态进而判断按键所在行并记录下行号。之后使得4条列线全为高电平,5条行线全为低电平,为读列线状态做准备。同理6号键被按下时列线L2与行线R1被短路,此时列线L2电平被行线R1拉低,由原来的高电平变为低电平而其它行线电平依然不变,为低电平。此时单片机可读得列线状态进而判断按键所在列并记录下列号。然后按一定的按键编码规则可计算出6号键的键值。 2)键盘扫描方式 键盘扫描方式一般有三种:循环扫描方式,定时扫描方式,外部中断扫描方式。循环扫描方式需要不停地扫描键盘,影响其它功能执行工作效率低。定时扫描方式是利用单片机内部的定时器,产生一个适当时间的定时中断,单片机响应中断时对键盘进行扫描取键值过程,但是这种扫描方式不管键盘上是不是有键闭合单片机总是定时地扫描工作效率还是不高。外部中断扫描方式是只在键盘上有

经典的矩阵键盘扫描程序

经典的矩阵键盘扫描程序 查找哪个按键被按下的方法为:一个一个地查找。 先第一行输出0,检查列线是否非全高; 否则第二行输出0,检查列线是否非全高; 否则第三行输出0,检查列线是否非全高; 如果某行输出0时,查到列线非全高,则该行有按键按下; 根据第几行线输出0与第几列线读入为0,即可判断在具体什么位置的按键按下。 下面是具体程序: void Check_Key(void) { unsigned char row,col,tmp1,tmp2; tmp1 = 0x10; //tmp1用来设置P1口的输出,取反后使 P1.4~P1.7中有一个为0 for(row=0;row<4;row++) // 行检测 { P1 = 0x0f; // 先将p1.4~P1.7置高 P1 =~tmp1; // 使P1.4~p1.7中有一个为0 tmp1*=2; // tmp1左移一位 if ((P1 & 0x0f) < 0x0f) // 检测P1.0~P1.3中是否有一位为0,只要有,则说明此行有键按下,进入列检测 { tmp2 = 0x01; // tmp2用于检测出哪一列为0 for(col =0;col<4;col++) // 列检测

{ if((P1 & tmp2)==0x00) // 该列如果为低电平则可以判定为该列 { key_val =key_Map[ row*4 +col ]; // 获取键值,识别按键;key_Map为按键的定义表 return; // 退出循环 } tmp2*=2; // tmp2左移一位 } } } } //结束 这是一种比较经典的矩阵键盘识别方法,实现起来较为简单,程序短小精炼。 4*4矩阵键盘扫描程序 /* 设置行线为输入线,列线为输出线 */ uchar KeyScan(); //按键扫描子程序 void delay10ms(); //延时程序 uchar key_free(); //等待按键释放程序 void key_deal(); //键处理程序 //主程序 void main() { while(1) { KeyScan(); key_free(); key_deal(); } } //按键扫描子程序 uchar KyeScan() { unsigned char key,temp; P1=0xF0; if(P1&0xF0!=0xF0) { delay10ms(); //延时去抖动 if(P1&0xF0!=0xF0) { P1=0xFE; //扫描第一列

相关主题
文本预览
相关文档 最新文档