51测试网 单片机教程XL2000开发板 单片机学习 自制编程器 单片机资料 软件下载 电子技术产品介绍如何购买 论坛

点击察看说明书(64页彩色PDF文档)

1.1 系统简介

4.3 ISP引脚连接

端口按键判断

红外线遥控555硬件振荡器

1.2 模块接口定义

5.1 仿真概述

矩阵按键识别技术

汉字显示屏PS2键盘实验
2.1 软件安装  5.2 KEIL软件指南

74LS14反向器

1602液晶显示屏SD卡实验
2.2 软件界面介绍 

51引脚说明

74LS138译码器

8155试验

485通信实验 
2.3 软件操作

八路跑马灯

74LS164串入并出

24C02储存

DS1302实时时钟
3.1 USB驱动安装

继电器控制

74LS165并入串出步进电机产生hex文件
3.2 特别usb安装 

8路拨动开关

dac0832应用

93c46演示

常见问题解答
4.1 ISP介绍 

数码管静态扫描 

模拟/数字转换器

串行双向通信系统配置指南
4.2 下载头之插头定义

数码管动态扫描

小喇叭警报器18B20温度显示购买方式

 

实验7 矩阵按键识别技术 


        矩阵按键部份由16个轻触按键按照4行4列排列,连接到JP50端口。将行线所接的单片机的I/O口作为输出端,而列线所接的I/O口则作为输入。这样,当按键没有按下时,所有的输出端都是高电平,代表无键按下。行线输出是低电平,一旦有键按下,则输入线就会被拉低,这样,通过读入输入线的状态就可得知是否有键按下了。

相关原理:

程序运行照片:

接线方法:

1、用一条8PIN数据排线,把矩阵按键部份的JP50,接到CPU部份的P1口JP44.
2、接8位数码管的数据线。将数码管部份的数据口 JP5接到CPU部份的P0口JP51.
3、接8位数码管的显示位线。将数码管部份的显示位口 JP8接到CPU部份的P2口JP52.
;本程序实现扫描按键显示功能.
;分别按16个键盘显示分别显示数字123A456B789C*0#D
;键盘口P1,数码管显示第二位p21, 数码管段位p0口
  确定矩阵式键盘上何键被按下,介绍一种“行扫描法”。行扫描法又称为逐行(或列)扫描查询法,是一种最常用的按键识别方法.

程序流程图:

 

     8031单片机的P1口用作键盘I/O口,键盘的列线接到P1口的低4位,键盘的行线接到P1口的高4位。列线P1.0-P1.3设置为输入线,行线P1.4-P.17设置为输出线。4根行线和4根列线形成16个相交点。
1、检测当前是否有键被按下。检测的方法是P1.4-P1.7输出全“0”,读取P1.0-P1.3的状态,若P1.0-P1.3为全“1”,则无键闭合,否则有键闭合。
2、去除键抖动。当检测到有键按下后,延时一段时间再做下一步的检测判断。
3、若有键被按下,应识别出是哪一个键闭合。方法是对键盘的行线进行扫描。P1.4-P1.7按下述4种组合依次输出:

在每组行输出时读取P1.0-P1.3,若全为“1”,则表示为“0”这一行没有键闭合,否则有键闭合。由此得到闭合键的行值和列值,然后可采用计算法或查表法将闭合键的行值和列值转换成所定义的键值。
4、为了保证键每闭合一次CPU仅作一次处理,必须去除键释放时的抖动。

汇编语言参考程序:

org 0000h
ajmp main
org 0080h
main:
mov dptr,#tab ;将表头放入DPTR
lcall key ;调用键盘扫描程序
movc a,@a+dptr ;查表后将键值送入ACC
mov p0,a ;将Acc值送入P0口
CLR P2.1 ;开显示
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
MOV A,#08H ;将第三行的行值送入ACC
AJMP LK ;跳转到键值处理程
L3: JB P1.3,NEXT ;P1.3等于1跳转到NEXT处
MOV A,#0cH ;将第四行的行值送入ACC
LK: ADD A,R4 ;行值与列值相加后的键值送入A
PUSH ACC ;将A中的值送入堆栈暂存
K4: LCALL DELAY2 ;调用延时去抖动程序
LCALL KS ;调用按键检测程序
JNZ K4 ;按键没有松开继续返回检测
POP ACC ;将堆栈的值送入ACC
RET
NEXT:
INC R4 ;将列值加一
MOV A,R2 ;将R2的值送入A
JNB ACC.7,KEY ;扫描完至KEY处进行下一扫描
RL A ;扫描未完将A中的值右移一位进行下一列的扫描
MOV R2,A ;将ACC的值送入R2暂存
AJMP K3 ;跳转到K3继续
KS: MOV P1,#0FH ;将P1口高四位置0低四位值1
MOV A,P1 ;读P1口
XRL A,#0FH ;将A中的值与A中的值相异或
RET ;子程序返回
DELAY2: ;40ms延时去抖动子程序
MOV R5,#08H
L7: MOV R6,#0FAH
L8: DJNZ R6,L8
DJNZ R5,L7
RET
tab:
db 28h,34h,28h,34h,0a9h,60h,20h,7ah,20h,21h,61h,74h,30h,62h,0a2h,7eh
;0h0hc9878654a321 轮流显示键盘因为无法表达*# 就用H表示,B用8表示
end
c语言参考程序:

#include <reg52.h>
#include <intrins.h>
sbit BEEP = P3 ^ 7; //蜂鸣器驱动线
unsigned char key;
unsigned char code disp_code[] =
{
//显示码数组0,C,8,A,H,9,6,3,0,8,5,2,H,7,4,1
0x28,0xa9,0x20,0x30,0x34,0x60,0x21,0x62,0x28,0x20,0x61,0xa2,0x34,0x7a,0x74,0x7e
};
unsigned char code key_code[] =
{
//键编码数组
0xee, 0xed, 0xeb, 0xe7, 0xde, 0xdd, 0xdb, 0xd7, 0xbe, 0xbd, 0xbb,
0xb7, 0x7e, 0x7d, 0x7b, 0x77
};
char code SST516[3] _at_ 0x003b; //保留仿真器
/**********************************************************
延时子函数
**********************************************************/
void delayms(unsigned int ms)
{
unsigned char t;
while (ms--)
{
for (t = 0; t < 114; t++)
;
}
}
/**********************************************************
x*0.14MS 延时子函数
**********************************************************/
void delayus(unsigned char x)
{
unsigned char i;
while (x--)
{
for (i = 0; i < 14; i++)
{
;
}
}
}
/**********************************************************
蜂鸣器驱动子函数
**********************************************************/
void beep()
{
unsigned char i;
for (i = 0; i < 250; i++)
{
delayus(6);
BEEP = !BEEP; //BEEP取反
}
BEEP = 1; //关闭蜂鸣器
delayms(150); //延时
}
/**********************************************************
键盘扫描子函数
**********************************************************/
unsigned char keyscan()
{
unsigned char scan1, scan2, keycode, j;
P1 = 0xf0;
scan1 = P1;
if (scan1 != 0xf0)
//判键是否按下
{
delayms(10); //延时10ms
scan1 = P1;
if (scan1 != 0xf0)
//二次判键是否按下
{
P1 = 0x0f;
scan2 = P1;
keycode = scan1 | scan2; //组合成键扫描编码
for (j = 0; j < 16; j++)
{
if (keycode == key_code[j])
//查表得键值
{
key = j;
return (key); //返回有效键值
}
}
}
}
else
P1 = 0xff;
return (key = 16); //返回无效码
}
/**********************************************************
主函数
**********************************************************/
void main(void)
{
P0 = 0xf7; //数码管初始显示"-"
P2 = 0xfd;//数码管显示在第二位
P1 = 0xff;
while (1)
{
keyscan();
if (key < 16)
//有效键值
{
P0 = disp_code[key]; //显示键值
beep(); //蜂鸣器响一声
}
}
}
/*********************************************************/

精致外观

精致外观

精致外观

精致外观

精致外观

精致包装

精致包装

精致包装

配套附件

配套附件

使用手册

使用手册

使用手册

配套附件

配套附件

配套附件

配套附件

配套附件

配套附件

配套附件

精致细节

精致细节

精致细节

精致细节

配套光盘