文档库 最新最全的文档下载
当前位置:文档库 › atmega16 UART同步模式接收PS2键盘扫描码

atmega16 UART同步模式接收PS2键盘扫描码

atmega16 UART同步模式接收PS2键盘扫描码
atmega16 UART同步模式接收PS2键盘扫描码

有关PS2键盘的大多是以中断方式接收扫描码,这样不停的中断,效率低,对于实验验证是可以的,UART的格式与PS2键盘的数据发送格式相同,这里提供atmge16使用USART 的同步模式,接收PS2键盘扫描码。并在1602液晶上显示//LCD1602.h 头文件

#include

#define uint unsigned int

#define En_H PORTD|=(1<

#define En_L PORTD&=~(1<

#define RW_R PORTD|=(1<

#define RW_W PORTD&=~(1<

#define RS_H PORTD|=(1<

#define RS_L PORTD&=~(1<

void Port_init(void)

{

PORTA=0XFF;

DDRA =0X00;

PORTD=0XFF;

DDRD =0X00;

}

void En_Toggle(void)

{

En_H;

_delay_us(20);

En_L;

_delay_us(20);

}

void Write_Command(uint8_t Command) { RW_W;

RS_L;

En_H;

PORTA=Command;

En_Toggle();

}

void Write_Data(uint8_t Data)

{

RW_W;

RS_H;

En_H;

PORTA=Data;

En_Toggle();

}

void Write_Position(uint8_t row,uint8_t colum) {

uint8_t p;

if(row==0)

p=0x80+colum;

else

p=0xc0+colum;

Write_Command(p);

}

void Write_String(char *s)

{

for(;*s!='\0';s++)

Write_Data(*s);

}

void Initialize_LCD(void)

{ DDRA=0xFF;

DDRD|=(1<

_delay_ms(15);

Write_Command(0x38);

Write_Command(0x08);

Write_Command(0x01);

_delay_ms(5);

Write_Command(0x04);

_delay_ms(5);

Write_Command(0x0c);

}

//UART同步模式接收PS2扫描码#include

#include #include

#include"LCD1602.h"

#define F_CPU 7372800UL

const char unshifted[36][2]= {

{0x1c,'a'},

{0x32,'b'},

{0x21,'c'},

{0x23,'d'},

{0x24,'e'},

{0x2B,'f'},

{0x34,'g'},

{0x33,'h'},

{0x43,'i'},

{0x42,'k'}, {0x4B,'l'}, {0x3A,'m'}, {0x31,'n'}, {0x44,'o'}, {0x4D,'p'}, {0x15,'q'}, {0x2D,'r'}, {0x1B,'s'}, {0x2C,'t'}, {0x3C,'u'}, {0x2A,'v'}, {0x1D,'w'}, {0x22,'x'}, {0x35,'y'}, {0x1A,'z'}, {0x45,'0'}, {0x16,'1'}, {0x1E,'2'}, {0x26,'3'}, {0x25,'4'},

{0x36,'6'},

{0x3D,'7'},

{0x3E,'8'},

{0x46,'9'},

};

const char shifted[36][2]= {

{0x1c,'A'},

{0x32,'B'},

{0x21,'C'},

{0x23,'D'},

{0x24,'E'},

{0x2B,'F'},

{0x34,'G'},

{0x33,'H'},

{0x43,'I'},

{0x3B,'J'},

{0x42,'K'},

{0x4B,'L'},

{0x31,'N'},

{0x44,'O'},

{0x4D,'P'},

{0x15,'Q'}, // {0x2D,'R'},

{0x1B,'S'}, // {0x2C,'T'},

{0x3C,'U'},

{0x2A,'V'},

{0x1D,'W'}, // {0x22,'X'},

{0x35,'Y'},

{0x1A,'Z'},

{0x45,'0'},

{0x16,'1'},

{0x1E,'2'},

{0x26,'3'},

{0x25,'4'},

{0x2E,'5'},

{0x36,'6'},

{0x3D,'7'},

{0x46,'9'},

};

int data;

int up,shift;

SIGNAL(SIG_USART_RECV) //接收

{

int i;

data=UDR;

if (!up) //已接收的11位数据是通码(up为0) {

switch (data)//开始翻译扫描码

{

case 0x13: up=1; break;

case 0x12: shift=1; break;

case 0x59: shift=1; break;

default:

if(!shift)

{

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

if(unshifted[i][0]==data)

{

data=unshifted[i][1];

break;

}

}

else

{

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

if(shifted[i][0]==data)

{

data=shifted[i][1];

break;

}

}

}

}

else

{

up = 0;

switch (data) //检测shift键释放 {

case 0x12 : shift = 0;break; case 0x59 : shift = 0;break; default:break;

}

}

void LCDplay(int data)

{

Write_Position(0,0);

Write_Data(data);

}

void LCD_set(void)

{

Port_init();

Initialize_LCD();

Write_Command(0x01);

_delay_ms(5);

}

int main()

{

DDRB&=~(1<

PORTD&=~(1<

DDRD&=~(1<

LCD_set();

UCSRB=(1<

UCSRC=(1<

sei();

while(1)

{

LCDplay(data);

}

}

非编码键盘的扫描程序设计

摘要 ------------------------------------------------------------------------------------------------------- 1 1设计方案 ------------------------------------------------------------------------------------------------ 2 1.1设计任务 ---------------------------------------------------------------------------------------- 2 1.2设计方案 ---------------------------------------------------------------------------------------- 2 2系统硬件设计------------------------------------------------------------------------------------------ 3 2.1最小应用系统 ------------------------------------------------------------------------------------ 3 2.28155扩展电路---------------------------------------------------------------------------------- 4 2.3矩阵键盘接口电路 ---------------------------------------------------------------------------- 6 2.4LCD1602接口电路----------------------------------------------------------------------------- 6 2.5主电路设计 --------------------------------------------------------------------------------------- 8 3系统软件设计------------------------------------------------------------------------------------------ 8 3.1主程序设计 --------------------------------------------------------------------------------------- 9 3.2延时程序设计----------------------------------------------------------------------------------- 9 3.3键盘扫描子程序设计 ------------------------------------------------------------------------ 10 3.4显示子程序设计------------------------------------------------------------------------------- 11 4 系统调试与结果 ---------------------------------------------------------------------------------- 13 4.1调试内容与问题解决----------------------------------------------------------------------- 13 4.2运行结果与分析 ----------------------------------------------------------------------------- 13 小结 ------------------------------------------------------------------------------------------------------- 15 参考文献 ------------------------------------------------------------------------------------------------ 16 附录 ------------------------------------------------------------------------------------------------------- 17

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

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 三根输入列线中有无低电平出现。只要有低电平出现,则说明有键按下(实际编程时,还要考虑按键的消抖)。如读到的都是高电平,则表示无键按下。 √在确认有键按下后,需要进入确定具体哪一个键闭合的过程。其思路是:依

键盘扫描码

键盘上的每一个键都有两个唯一的数值进行标志。为什么要用两个数值而不是一个数值呢?这是因为一个键可以被按下,也可以被释放。当一个键按下时,它们产生一个唯一的数值,当一个键被释放时,它也会产生一个唯一的数值,我们把这些数值都保存在一张表里面,到时候通过查表就可以知道是哪一个键被敲击,并且可以知道是它是被按下还是被释放了。这些数值在系统中被称为键盘扫描码 2扫描码大全 扫描码键 0x011b ESC 0x3b00 F1 0x3c00 F2 0x3d00 F3 0x3e00 F4 0x3f00 F5 0x4000 F6 0x4100 F7 0x4200 F8 0x4300 F9 0x4400 F10 主键盘区: 0x2960 ~ 0x0231 1 0x0332 2 0x0433 3 0x0534 4 0x0635 5 0x0736 6 0x0837 7 0x0938 8 0x0a39 9 0x0b30 0 0x0c2d - 0x0d3d = 0x2b5c \ 0x0e08 退格键 0x0f09 Tab 0x1071 q 0x1177 w 0x1265 e 0x1372 r 0x1474 t 0x1579 y

0x1769 i 0x186f o 0x1970 p 0x1a5b [ 0x1b5d ] 0x1e61 a 0x1f73 s 0x2064 d 0x2166 f 0x2267 g 0x2368 h 0x246a j 0x256b k 0x266c l 0x273b ; 0x2827 ' 0x1c0d 回车 0x2c7a z 0x2d78 x 0x2e63 c 0x2f76 v 0x3062 b 0x316e n 0x326d m 0x332c , 0x342e . 0x352f / 0x3920 空格键 0xe05b 左Win 0xe05c 右Win 0xe05d Menu 右边数字键盘: 0x5200 Insert 0x4700 Home 0x4900 Page UP 0x5300 Delete 0x4f00 End 0x5100 PageDown 0x4800 上箭头 0x4b00 左箭头 0x5000 下箭头 0x4d00 右箭头 0x352f /

按键扫描方法

说到键盘扫描,相信大多数人第一反应就是行列矩阵扫描,这样我们可以用相对有限的IO口得到尽可能多的按键。键盘扫描是单片机技术的一种基本处理方法,学校的单片机课程都会有相应章节进行阐述,只要按照课本上讲述的方法,一般都能设计出比较可靠的键盘扫描电路与程序。 课本上的键盘扫描方法(见下图接法二)不能说是尽善尽美,从易懂性、成本、程序难易程度等方面综合看应该是不错的方法,给人感觉是已经没有太多的改善空间,至少我是这么认为的。 然而前段时间一位台湾朋友画给我的键盘扫描矩阵电路(见下图接法二),让我又一次看到到自己的思维还有许多地方被自己的所谓“经验”束缚着。 单纯的从硬件接法看,两种接法并没有明显区别,接法一甚至要复杂一些,但如果结合到键盘扫描的程序来看,就会发现接法一确实更好。 两种接法我都没有把上拉电阻包含进来,来让我们看一下两种接法到底有什么不同: 接法二: 我们熟悉的传统扫键处理电路,假定键盘行列IO口标号分别为H1/H2/H3和V1/V2/V3,扫键流程通常如下。 2.1. H1设置为输出,H2/H3和V1/V2/V3设置为输入 2.2. H1分别输出1和0,读V1/V2/V3状态,如果Vy状态与H1一致,则认为H1与Vy交叉位置的键按下 2.3. H2设置为输出,H1/H3和V1/V2/V3设置为输入 2.4. H2分别输出1和0,读V1/V2/V3状态,如果Vy状态与H2一致,则认为H2与Vy交叉位置的键按下 2.5. H3设置为输出,H1/H2和V1/V2/V3设置为输入 2.6. H3分别输出1和0,读V1/V2/V3状态,如果Vy状态与H3一致,则认为H3与Vy交叉位置的键按下

键盘按键的各种编码对照表(全)

键盘按键的各种编码对照表 本附录中的各表列举了键盘按键扫描码和其ASCII码之间的对照关系,表中数据都是十六进制形式。 在用中断16H的0号功能时,当按下任意一个键或组合键时,寄存器AH和AL分别保存着该按键的扫描码和ASCII码。 表1、ASCII码的编码方案 高位 000001010011100101110111低位 0000NUL DEL SP0@P`p 0001SOH DC1!1A Q a q 0010STX DC2“2B R b r 0011ETX DC3#3C S c s 0100EOT DC4$4D T d t 0101ENQ NAK%5E U e u 0110ACK SYN&6F V f v 0111BEL ETB‘7G W g w 1000BS CAN(8H X h x 1001HT EM)9I Y i y 1010LF SUB*:J Z j z 1011VT ESC+;K[k{ 1100FF FSN^n~ 1111SI US/?O_o Del 表2、字母和空格按键的编码表 单 键SHIFT CTRL ALT 按 键 扫描码ASCII码扫描码ASCII码扫描码ASCII码扫描码ASCII码 a and A1E611E411E011E00 b and B3062304230023000 c an d C2E632E432E032E00 d and D2064204420042000 e and E1265124512051200 f and F2166214621062100 g and G2267224722072200 h and H2368234823082300 i and I1769174917091700

经典的verilog键盘扫描程序

经典的verilog键盘扫描程序 作者:ilove314 拿到威百仕( VibesIC )的板子后就迫不及待的开始我的学习计划,从最基础的分频程序开始,但看到这个键盘扫描程序后,直呼经典,有相见恨晚的感觉,还想说一句:威百仕( VibesIC ),我很看好你!WHY?待我慢慢道来,这个程序的综合后是0error,0warning。想想自己编码的时候那个warning是满天飞,现在才明白HDL设计有那么讲究了,代码所设计的不仅仅是简单的逻辑以及时序的关系,更重要的是你要在代码中要表现出每一个寄存器,甚至每一个走线。想想我写过的代码,只注意到了前者,从没有注意过后者,还洋洋自得以为自己也算是个高手了,现在想来,实在惭愧啊!学习学习在学习,这也重新激发了我对HDL设计的激情,威百仕给了我一个方向,那我可要开始努力喽! 废话说了一大堆,看程序吧:(本代码经过ise7.1i综合并下载到SP306板上验证通过) //当三个独立按键的某一个被按下后,相应的LED被点亮;再次按下后,LED熄灭,按键控制LED亮灭

module key_debounce( clk,rst_n,s1_n,s2_n,s3_n,s4_n,s5_n,led_d1,led_d2,led_d3,led_d 4,led_d5); input clk; //主时钟信号,10MHz input rst_n; //复位信号,低有效 input s1_n,s2_n,s3_n,s4_n,s5_n; output led_d1,led_d2,led_d3,led_d4,led_d5; reg[4:0] s_rst; always @(posedge clk or negedge rst_n) if (!rst_n) s_rst <= 5'b11111; else s_rst <= {s5_n,s4_n,s3_n,s2_n,s1_n}; reg[4:0] s_rst_r; always @ ( posedge clk or negedge rst_n ) if (!rst_n) s_rst_r <= 5'b11111; else s_rst_r <= s_rst; wire[4:0] s_an = s_rst_r & ( ~s_rst); reg[19:0] cnt; //计数寄存器 always @ (posedge clk or negedge rst_n) if (!rst_n) cnt <= 20'd0; //异步复位 else if(s_an) cnt <=20'd0; else cnt <= cnt + 1'b1; reg[4:0] low_s; always @(posedge clk or negedge rst_n) if (!rst_n) low_s <= 5'b11111; else if (cnt == 20'h30D40) low_s <= {s5_n,s4_n,s3_n,s2_n,s1_n}; reg [4:0] low_s_r; always @ ( posedge clk or negedge rst_n ) if (!rst_n) low_s_r <= 5'b11111; else low_s_r <= low_s; wire[4:0] led_ctrl = low_s_r[4:0] & ( ~low_s[4:0]); reg d1,d2,d3,d4,d5; always @ (posedge clk or negedge rst_n) if (!rst_n) begin d1 <= 1'b0; d2 <= 1'b0; d3 <= 1'b0; d4 <= 1'b0; d5 <= 1'b0; end else begin // if ( led_ctrl[0] ) d1 <= ~d1; if ( led_ctrl[1] ) d2 <= ~d2; if ( led_ctrl[2] ) d3 <= ~d3; if ( led_ctrl[3] ) d4 <= ~d4; if ( led_ctrl[4] ) d5 <= ~d5; end assign led_d1 = d1 ? 1'b1 : 1'b0; //LED翻转输出assign led_d2 = d2 ? 1'b1 : 1'b0; assign led_d3 = d3 ? 1'b1 : 1'b0; assign led_d4 = d4 ? 1'b1 : 1'b0; assign led_d5 = d5 ? 1'b1 : 1'b0; endmodule

键盘扫描原理及应用键盘

本资源为网上搜集而来,如果该程序涉及或侵害到您的版权请立即写信通知我

键盘扫描 键盘是由按键构成,是单片机系统里最常用的输入设备。我们可以通过键盘输入数据或命令来实现简单的人-机通信。 1.按键及键抖动 按键是一种常开型按钮开关。平时,按键的两个触点处于断开状态,按下按键时两个触点才闭合(短路)。如图1-1所示,平常状态下,当按键K未被按下时,按键断开,PA0输入口的电平为高电平;当按键K被按下时,按键闭合,PA0输入口的电平为低电平。 图1-1 按键电路 图1-2 按键抖动 一般的按键所用开关都是机械弹性开关,由于机械触点的弹性作用,按键开

关在闭合时不会马上稳定地连接,在断开进也不会马上完全的断开,在闭合和断开的瞬间均有一连串的抖动。按键按下的电压信号波形图如图1-2所示,从图中可以看出按键按下和松开的时候都存在着抖动。抖动时间的长短因按键的机械特性不同而有所不同,一般为5ms~10ms。 如果不处理键抖动,则有可能引起一次按键被误读成多次,所以为了确保能够正确地读到按键,必须去除键抖动,确保在按键的稳定闭合和稳定断开的时候来判断按键状态,判断后再做处理。按键在去抖动,可用硬件或软件两种方法消除。由于使用硬件方法消除键抖动,一般会给系统的成本带来提高,所以通常情况下都是使用软件方法去除键抖动。 常用的去除键抖动的软件方法有很多种,但是都离不开基本的原则:就是要么避开抖动的时候检测按键或是在抖动的时候检测到的按键不做处理。这里说明一下常用的两种方法: 第一种方法是检测到按键闭合电平后先执行一个延时程序,做一个12ms~24ms的延时,让前抖动消失后再一次检测按键的状态,如果仍是闭合状态的电平,则认为真的有按键按下;若不是闭合状态电平,则认为没有键按下。若是要判断按键松开的话,也是要在检测到按键释放电平之后再给出12ms~24ms的延时,等后抖动消失后再一次检测按键的状态,如果仍为断开状态电平,则确认按键松开。这种方法的优点是程序比较简单,缺点是由于延时一般采用跑空指令延时,造成程序执行效率低。 第二种方法是每隔一个时间周期检测一次按键,比如每5ms扫描一次按键,要连续几次都扫描到同一按键才确认这个按键被按下。一般确认按键的扫描次数由实际情况决定,扫描次数的累积时间一般为50ms~60ms。比如,以5ms为基本时间单位去扫描按键的话,前后要连续扫描到同一个按键11次而达到50ms 来确认这个按键。按键松开的检测方法也是一样要连续多次检测到按键状态为断开电平才能确认按键松开。这种方法的优点是程序执行效率高,不用刻意加延时指令,而且这种方法的判断按键抗干扰能力要更好;缺点是程序结构较复杂。 在以下的介绍中,我们将使用第二种方法来去除键抖动。 2.键盘结构及工作原理 键盘一般有独立式和行列式(矩阵式)两种。当然还有其它的结构,比如交互式结构等等,不过其它的结构比较少用,在这里就不介绍了。在中颖的单片机中,有些单片机的LCD驱动引脚的SEGMENT口可以共享按键扫描口,当选择为按键扫描口时,可以使用这些口来扫描按键,所以在外部电路可以连接LCD和按键矩阵,采用分时扫描进行处理,下面也将介绍这个特殊应用的方法和注意的地方。 独立式键盘结构

矩阵键盘扫描汇编程序

4*4矩阵键盘扫描汇编程序(基于51单片机) // 程序名称:4-4keyscan.asm ;// 程序用途:4*4矩阵键盘扫描检测 ;// 功能描述:扫描键盘,确定按键值。程序不支持双键同时按下, ;// 如果发生双键同时按下时,程序将只识别其中先扫描的按键;// 程序入口:void ;// 程序出口:KEYNAME,包含按键信息、按键有效信息、当前按键状态;//================================================================== ==== PROC KEYCHK KEYNAME DATA 40H ;按键名称存储单元 ;(b7-b5纪录按键状态,b4位为有效位, ;b3-b0纪录按键) KEYRTIME DATA 43H ;重复按键时间间隔 SIGNAL DATA 50H ;提示信号时间存储单元 KEY EQU P3 ;键盘接口(必须完整I/O口) KEYPL EQU P0.6 ;指示灯接口 RTIME EQU 30 ;重复按键输入等待时间 KEYCHK: ;//=============按键检测程序========================================= ==== MOV KEY,#0FH ;送扫描信号 MOV A,KEY ;读按键状态 CJNE A,#0FH,NEXT1 ;ACC<=0FH ; CLR C ;Acc等于0FH,则CY为0,无须置0 NEXT1: ; SETB C ;Acc不等于0FH,则ACC必小于0 FH, ;CY为1,无须置1 MOV A,KEYNAME ANL KEYNAME,#1FH ;按键名称屏蔽高三位 RRC A ;ACC带CY右移一位,纪录当前按键状态 ANL A,#0E0H ;屏蔽低五位

堪称一绝的键盘扫描方法

堪称一绝的“IO口扫键”法 在做项目(工程)的时候,我们经常要用到比较多的按键,而且IO资源紧张,于是我们就想方设法地在别的模块中节省IO口,好不容易挤出一两个IO口,却发现仍然不够用,实在没办法了就添加一个IC来扫键。一个IC虽然价格不高,但对于大批量生产而且产品利润低的厂家来说,这是一笔不菲的开支! 那,我们能不能想到比较好的扫键方法:用最少的IO口,扫最多的键?可以吗?举个例:给出5个IO口,能扫多少键?有人说是2*3=6个,如图一: 图一 对,大部分技术参考书都这么做,我们也经常这样做:用3个IO口作行扫描,2个IO作列检测(为方便描述,我们约定:设置某一IO口输出为“0”――称其为“扫某IO口”)。用行线输出扫键码,列线检测是否有按键的查询方法进行扫键。扫键流程:在行线依次输出011,101,110扫键值,行线每输出一个扫键值,列线检测一次。当列线检测到有按键时,结合输出的扫键值可以判断相应的按键。 但是,5个IO真的只能扫6个键吗?有人说可以扫9个,很聪明!利用行IO与地衍生3个键(要注意上拉电阻),如图二: 图二 扫键流程:先检测3个行IO口,对K1’,K2’,K3’进行扫键,之后如上述2*3

扫键流程。5个IO口能扫9个键,够厉害吧,足足比6个键多了1/2! 动动脑,还能不能再多扫几个?就几个?一个也行!好,再想一下,硬是被逼出来了!如图三: 图三 不多不少,正好10个键!这种扫键方式比较少见吧!漂亮!扫键流程:设IO1输出为“0”,检测IO2…IO5,若判断有相应健按下,则可知有健;若无键,则继续扫键:设IO2输出为“0”,检测IO3,IO4,IO5,判断有无键按下,如此类推。这里应注意:当扫某一IO口(输出为“0”)时,不要去检测已经扫过的IO口。如:此时设置IO2输出为“0”,依次检测IO3,IO4,IO5,但不要去检测IO1,否则会出错(为什么,请思考)。 感觉怎么样?不错吧!让我们再看看图三,好有成就感!看着,看着……又看到了什么?快!见图四: 图四 真强!被您看出20个键!多了一个对称的三角形。可是,像这样的排列能正确扫20个键吗?回答是肯定的:不能!上下三角形相互对称,其对称扫出的键无法区别。有没有注意到分析图三时提到的注意点?(à“当扫某IO口时,不要去检测已经扫过的IO口,否则会出错”) 我们分析一下图四:当IO1输出“0”时,按下K11或K11’键都能被IO2检测到,但IO2检测却无法区别K11和K11’键!同理,不管扫哪个IO口,都有两个对称的键不能区分。 我们假想,如果能把对称键区分开来,我们就能正常地去判断按键。我们在思考:

数码管显示和键盘扫描实验资料

实验三LED数码管动态显示及4 X4 键盘控制实验 一、实验目的 1.巩固多位数码管动态显示方法。 2.掌握行扫描法矩阵式按键的处理方法。 3.熟练应用AT89S52学习板实验装置,进一步掌握keil C51的使用方法。二、实验内容 使用AT89S52学习板上的4位LED数码管和4 X 4矩阵键盘阵列做多位数码管动态显示及行扫描法键盘处理功能实验。用P0口做数据输出,利用P1做锁存器74HC573的锁存允许控制,编写程序使4位LED数码管按照动态显示方式显示一定的数字;按照行扫描法编写程序对4 X 4矩阵键盘阵列进行定期扫描,计算键值并在数码管上显示。 三、实验系统组成及工作原理 1.4位LED数码管和4 X 4矩阵键盘阵列电路原理图

2.多位数码管动态显示方式 a b c d e f g dp com a b c d e f g dp com a b c d e f g dp com a b c d e f g dp com D0 IO(2) IO(1) 说明4位共阴极LED动态显示3456数字的工作过程 首先由I/O口(1)送出数字3的段选码4FH即数据01001111到4个LED共同的段选线上, 接着由I/O口(2)送出位选码××××0111到位选线上,其中数据的高4位为无效的×,唯有送入左边第一个LED的COM端D3为低电平“0”,因此只有该LED的发光管因阳极接受到高电平“1”的g、d、c、b、a段有电流流过而被点亮,

也就是显示出数字3,而其余3个LED因其COM端均为高电平“1”而无法点亮;显示一定时间后, 再由I/O口(1)送出数字4的段选码66H即01100110到段选线上,接着由I/O 口(2)送出点亮左边第二个LED的位选码××××1011到位选线上,此时只有该LED的发光管因阳极接受到高电平“1”的g、f、c、b段有电流流过因而被点亮,也就是显示出数字4,而其余3位LED不亮; 如此再依次送出第三个LED、第四个LED的段选与位选的扫描代码,就能一一分别点亮各个LED,使4个LED从左至右依次显示3、4、5、6。 3.4 X 4 矩阵式按键扫描处理程序 行扫描法又称逐行零扫描查询法,即逐行输出行扫描信号“0”,使各行依次为低电平,然后分别读入列数据,检查此(低电平)行中是否有键按下。如果读得某列线为低电平,则表示此(低电平)行线与此列线的交叉处有键按下,再对该键进行译码计算出键值,然后转入该键的功能子程序入口地址;如果没有任何一根列线为低电平,则说明此(低电平)行没有键按下。接着进行下一行的“0”行扫描与列读入,直到8行全部查完为止,若无键按下则返回。 有时为了快速判断键盘中是否有键按下,也可先将全部行线同时置为低电平,然后检测列线的电平状态,若所有列线均为高电平,则说明键盘中无键按下,立即返回;若要有一列的电平为低,则表示键盘中有键被控下,然后再如上那样进行逐行扫描。 四、实验设备和仪器 PC机一台 AT89S52单片机学习板、下载线一套 五、实验步骤 1.按时实验要求编写源程序(实验前写)进行软件模拟调试。 2.软件调试好,连接硬件电路。

键盘码表:单键扫描码,ascii,组合键码

字母和空格按键的编码表 按键单键SHIFT CTRL ALT 扫描码ASCII码扫描码ASCII码扫描码ASCII码扫描码ASCII码 a 1E 61 1E 41 1E 01 1E 00 b 30 62 30 42 30 02 30 00 c 2E 63 2E 43 2E 03 2E 00 d 20 64 20 44 20 04 20 00 e 12 65 12 45 12 05 12 00 f 21 66 21 46 21 06 21 00 g 22 67 22 47 22 07 22 00 h 23 68 23 48 23 08 23 00 i 17 69 17 49 17 09 17 00 j 24 6A 24 4A 24 0A 24 00 k 25 6B 25 4B 25 0B 25 00 l 26 6C 26 4C 26 0C 26 00 m 32 6D 32 4D 32 0D 32 00 n 31 6E 31 4E 31 0E 31 00 o 18 6F 18 4F 18 0F 18 00 p 19 70 19 50 19 10 19 00 q 10 71 10 51 10 11 10 00 r 13 72 13 52 13 12 13 00 s 1F 73 1F 53 1F 13 1F 00 t 14 74 14 54 14 14 14 00 u 16 75 16 55 16 15 16 00 v 2F 76 2F 56 2F 16 2F 00 w 11 77 11 57 11 17 11 00 x 2D 78 2D 58 2D 18 2D 00 y 15 79 15 59 15 19 15 00 z 2C 7A 2C 5A 2C 1A 2C 00 SpaceBar 39 20 39 20 39 20 39 20 功能键和数字键盘的编码表·内容正文 按键单键SHIFT CTRL ALT 扫描码ASCII码扫描码ASCII码扫描码ASCII码扫描码ASCII码 F1 3B 00 54 00 5E 00 68 00 F2 3C 00 55 00 5F 00 69 00 F3 3D 00 56 00 60 00 6A 00 F4 3E 00 57 00 61 00 6B 00 F5 3F 00 58 00 62 00 6C 00 F6 40 00 59 00 63 00 6D 00 F7 41 00 5A 00 64 00 6E 00 F8 42 00 5B 00 65 00 6F 00 F9 43 00 5C 00 66 00 70 00 F10 44 00 5D 00 67 00 71 00 F11 85 00 87 00 89 00 8B 00 F12 86 00 88 00 8A 00 8C 00 键盘码表:单键扫描码,ascii,组合键码

键盘鼠标扫描码

[VB]键盘鼠标扫描码 1.??常数值描述 2.vbKeyLButton &H1 鼠标左键 3.vbKeyRButton &H2 鼠标右键 4.vbKeyCancel &H3 CANCEL 键 5.vbKeyMButton &H4 鼠标中键 6.vbKeyBack &H8 BACKSPACE键 7.vbKeyTab &H9 TAB 键 8.vbKeyClear &HC CLEAR 键 9.vbKeyReturn &HD ENTER 键 10.vbKeyShift &H10 SHIFT 键 11.vbKeyControl &H11 CTRL 键 12.vbKeyMenu &H12 MENU 键 13.vbKeyPause &H13 PAUSE 键 14.vbKeyCapital &H14 CAPS LOCK键 15.vbKeyEscape &H1B ESC 键 16.vbKeySpace &H20 SPACEBAR键 17.vbKeyPageUp &H21 PAGE UP 键 18.vbKeyPageDown &H22 PAGE DOWN键 19.vbKeyEnd &H23 END 键 20.vbKeyHome &H24 HOME 键 21.vbKeyLeft &H25 LEFT 键 22.vbKeyUp &H26 UP 键 23.vbKeyRight &H27 RIGHT 键 24.vbKeyDown &H28 DOWN 键 25.vbKeySelect &H29 SELECT 键 26.vbKeyPrint &H2A PRINT SCREEN键 27.vbKeyExecute &H2B EXECUTE 键 28.vbKeySnapshot &H2C SNAPSHOT键 29.vbKeyInsert &H2D INSERT 键 30.vbKeyDelete &H2E DELETE 键 31.vbKeyHelp &H2F HELP 键 32.vbKeyNumlock &H90 NUM LOCK键 33. 34.A至Z键与A杴Z字母的ASCII码相同: 35.常数值描述 36.vbKeyA 65 A 键 37.vbKeyB 66 B 键 38.vbKeyC 67 C 键 39.vbKeyD 68 D 键 40.vbKeyE 69 E 键 41.vbKeyF 70 F 键 42.vbKeyG 71 G 键 43.vbKeyH 72 H 键

矩阵键盘扫描代码(C语言)

#include #define unchar unsigned char #define unint unsigned int unsigned char code dula[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; unsigned char code wela[]={0,1,2,3,4,5,6,7}; unsigned char num,key; unsigned char keyscan(); unchar Keyscan(); void delay(int z) { int x,y; for(x=z;x>=0;x--) for(y=0;y<=148;y++); } void main() { P2=1; while(1) { P1 = 0xf0; if(P1 != 0xf0) //判断有无按键按下 { delay(20); //按键消抖 if(P1 != 0xf0) //第二次判断有无按键按下 { delay(20); //按键消抖 if(P1 != 0xf0) //第三次判断有无按键按下 { key = Keyscan(); } } } P0=dula[key];

} } //unchar keyscan() //{ //} unchar Keyscan(void) { unchar i,j,temp, Buffer[4] = {0xfe, 0xfd, 0xfb, 0xf7}; //让矩阵键盘的每行分别为低电? for(j=0; j<4; j++) { P1 = Buffer[j]; temp = 0x10; for(i=0; i<4; i++) { if(!(P1 & temp)) //判断P1口高4位某一行为低电平 { return (i+j*4); //返回键码 } temp<<= 1; } } }

键盘扫描方法

键盘扫描方法 传统的键盘扫描方法如图1所示,该方法虽然被广泛应用于很多场合,但有一个不足的地方,如果按键一直没有释放,或者按键坏了,一直处于闭合状态,则程序一直处于检测按键是否释放,系统将无法运行。只要对其稍加改进,就可以避免产生这个问题。 假设键盘接口电路采用独立式键盘接口,所有按键公共端接地,而且没有按键按下时IO口为高电平。当按键没有按下时,IO口为高电平;当按键按下时,IO口为低电平;当按键释放时,IO口为高电平。一个完整的按键过程是——按键未按下,按键按下,按键释放,而对应的IO口的电平变化为——高电平,低电平,高电平。所以,可以通过判断IO口电平变化的变化顺序是否满足高电平→低电平→高电平,来判断是否有按键按下,而对于其它的电平变化顺序都是无效的。那么该如何实现呢?在键盘扫描过程中,如果IO口为高电平,则需要判断是由于未按键,还是按键按下后释放引起的;如果IO口为低电平,则需要判断是由于未按键还是扫描之前本来就是低电平引起的。所以我们需要引入一个全局位变量KEY_EN,来标志按键的状态, KEY_EN=0表示按键未按下;KEY_EN=1表示按键按下。另外,我们还需引入一个全局字节变量KEY_TP来暂存键值,这是因为只有当IO口电平变化满足高电平→低电平→高电平,才表示一个按键有效,而只有在IO口为低电平的时候才能够读取到键值。具体的键盘扫描流程如图2所示,键盘初始化KEY_EN=0。

图1 传统键盘扫描

图2 改进后键盘扫描 接下来我们介绍一种代码效率极高的键盘扫描方法。键盘接口电路同样采用独立式,假设有8个按键,所有按键公共端接地,键盘扫描口为P0.7~P0.0,而且没有按键按下时为高电平,键盘扫描程序如下: unsigned char Trigger; unsigned char Continue; void delayms(unsigned char n) { …… } void key_scan() { unsigned char ReadData; if (P0!=0xff&&Trigger==0x00) delayms(20); ReadData = P0 ^ 0xff; Trigger = ReadDate & (ReadData ^ Continue);

键盘扫描码

(注:当按下“普通键”时,它的低8位数存放该字符的ASCII码。对于特殊键,低8位为0。特殊键包括箭头键、功能键等。高8位字节存放该键的扫描码。) 扫描码键 0x011b ESC 0x3b00 F1 0x3c00 F2 0x3d00 F3 0x3e00 F4 0x3f00 F5 0x4000 F6 0x4100 F7 0x4200 F8 0x4300 F9 0x4400 F10 主键盘区: 0x2960 ~ 0x0231 1 0x0332 2 0x0433 3 0x0534 4 0x0635 5 0x0736 6 0x0837 7 0x0938 8 0x0a39 9 0x0b30 0 0x0c2d - 0x0d3d = 0x2b5c " 0x0e08 退格键 0x0f09 Tab 0x1071 q 0x1177 w 0x1265 e 0x1372 r 0x1474 t 0x1579 y 0x1675 u 0x1769 i 0x186f o 0x1970 p 0x1a5b [ 0x1b5d ] 0x1e61 a

0x2064 d 0x2166 f 0x2267 g 0x2368 h 0x246a j 0x256b k 0x266c l 0x273b ; 0x2827 ' 0x1c0d 回车 0x2c7a z 0x2d78 x 0x2e63 c 0x2f76 v 0x3062 b 0x316e n 0x326d m 0x332c , 0x342e . 0x352f / 0x3920 空格键 右边数字键盘: 0x5200 Insert 0x4700 Hom e 0x4900 Page UP 0x5300 Delete 0x4f00 End 0x5100 PageDown 0x4800 上箭头 0x4b00 左箭头 0x5000 下箭头 0x4d00 右箭头 0x352f / 0x372a * 0x4a2d - (注意,这是数字键盘的) 0x4737 7 0x4838 8 0x4939 9 0x4b34 4 0x4c35 5 0x4d36 6 0x4e2b + 0x4f31 1

第一套第二套键盘扫描码

键盘扫描码 扫描码 键盘上的每一个键都有两个唯一的数值进行标志。为什么要用两个数值而不是一个数值呢?这是因为一个键可以被按下,也可以被释放。当一个键按下时,它们产生一个唯一的数值,当一个键被释放时,它也会产生一个唯一的数值,我们把这些数值都保存在一张表里面,到时候通过查表就可以知道是哪一个键被敲击,并且可以知道是它是被按下还是被释放了。这些数值在系统中被称为键盘扫描码 键盘扫描码: 键盘上的每个键都有一个包含在字节低7位(位6-0)中相应的扫描码,在高位(位7)表示是按键还是松开按键。位7=0按键按下,位7=1表示按键松开。 例如,按下键"A"的接通码是0x1E。当一个按下的键被松开时,从键盘控制器端口收到的就是一个断开码。对于XT键盘,断开码是其接通码的最高位取1,相当于加上0x80。例如,上述"A"键的断开码就是 0x80 + 0x1E = 0x9E。 表7-4是XT键盘的扫描码表。 但是对于那些PC/XT标准83键键盘以后新添加的("扩展的")AT键盘上的按键(如右边的Ctrl 键和右边的Alt键等),则其接通和断开扫描码通常有2~4B,并且第1个字节一定是0xE0。例如,按下左边的非扩展Ctrl键时会产生1B接通码0x1D,而按下右边的Ctrl键时就会产生扩展的2B接通码0xE0、0x1D。对应的断开码是0xE0、0x9D。 根据计算机的发展,目前已有三套扫描码集可供使用: 第一套扫描码集:原始XT键盘扫描码集。目前的键盘已经很少发送这类扫描码。 第二套扫描码集:现代键盘默认使用的扫描码集,通常称为AT键盘扫描码集。 第三套扫描码集:PS/2键盘扫描码集。原IBM推出PS/2微机时使用的扫描码集,已很少使用。 AT键盘默认发送的是第二套扫描码集。虽然如此,主机键盘控制器为了与PC/XT的软件兼容,仍然会把所有接收到的第二套键盘扫描码转换成第一套扫描码。因此,我们在为键盘控制器进行软件编程时通常只需要了解第一套扫描码集即可。嵌入式等单片机控制则需要使用第二套扫描码集。

键盘扫描码

键盘扫描码

这里罗列了键盘上各键的扫描码,还有ALT 、CTR 、SHIFT 与部分键的组合扫描码。 这对于编写需要键盘处理的程序应该有所帮助! #define KEY_L1 0x4F #define KEY_L2 0x50 #define KEY_L3 0x51 #define KEY_L4 0x4B #define KEY_L6 0x4D #define KEY_L7 0x47 #define KEY_L8 0x48 #define KEY_L9 0x49 #define KEY_ADD 0x2B #define KEY_SUB 0x2D #define KEY_LEFT 75 #define KEY_RIGHT 77 #define KEY_UP 72 #define KEY_DOWN 80 #define KEY_F1 59 #define KEY_F2 60 #define KEY_F3 61 #define KEY_F4 62 #define KEY_F5 63 #define KEY_F6 64 #define KEY_F7 65 #define KEY_F8 66 #define KEY_F9 67 #define KEY_F10 68 #define KEY_INSERT 82 #define KEY_HOME 71 #define KEY_PAGEUP 73 #define KEY_PAGEDOWN 81 #define KEY_DEL 83 #define KEY_END 79 #define KEY_DASH 12 #define KEY_EQUAL 13 #define KEY_LBRACKET 26 #define KEY_RBRACKET 27 #define KEY_SEMICOLON 39 #define KEY_RQUOTE 40 #define KEY_LQUOTE 41 #define KEY_PERIOD 52 #define KEY_COMMA 51 #define KEY_SLASH 53 #define KEY_BACKSLASH 43 #define KEY_ENTER 28 #define KEY_BACKSPACE 14 #define KEY_SPACE 57 #define KEY_TAB 15 #define KEY_ESC 1 #define KEY_Q 16 #define KEY_W 17 #define KEY_E 18 #define KEY_R 19 #define KEY_T 20 #define KEY_Y 21 #define KEY_U 22 #define KEY_I 23 #define KEY_O 24 #define KEY_P 25 h t t p :// h i .b a i d u .c o m /b a l l 6 48 500361

相关文档