4.6.第十一个实验--使用数码管显示矩阵按键的键值
2016-06-13 23:31
337 查看
实验目的:使用数码管显示矩阵按键的键值
之前我们学过了独立按键,先回顾一下,今天我们要了解的是矩阵按·键,预备知识:
(1)什么是矩阵按键
1. 横向纵向分割
2. 案件的两端分别接不同的IO引脚
3. 按下接通电路,弹起断开电路
( 2 )矩阵按键原理图分析
分析原理图
1.横向有4个按键,纵向有4个按键
2.JP4插座上有8个引脚,1-4这4个引脚接纵向的4列的一极,5-8这4个引脚接横向的4行的一极。
3.1-4的引脚上接有四个电阻,保护电路。
4.电阻的作用:S1按键的一极接在8上,一极接在4上,当8输入高电平、4输入低电平时,按键s1两极接通,按键被按下。这时候原来8的高电平也被拉成低电平。按键被按下之前JP4IO端口的二进制数为0000 1111(从低位到高位)当被按下时,该IO端口值变成0000 1110(从低位到高位)是不是发现第8的Io口从高电平拉低为低电平
5.什么是键值,第一个按键的键值是1,第二个按键的键值是2···以此类推~~~
(3)矩阵按键的工作过程
第一步:先送(IO引脚输入)0x0f,若有按键接收到的不是0x0f,从收到数据的判断哪一行按下了
第二步:再送(IO引脚输入)0xf0,若有按键接收到的不是0xf0,从收到数据的判断哪一列按下了
第三步:寻找行和列的交叉点找到那一个按键被按下
实验过程分析
第零步:
(1)按键接P3端口。JP4插座上的8是低位,1是高位,(具体还和原理图有关,高地位和接线有关)
第一步:
(1)输入0x0f,这时从低位到高位(8-1)的电平对应为1111 0000
(2)按下按键s1,s1按键接的是8和4IO引脚,8是高电平,s1被按下后,8IO引脚被拉成低电平
(3)再读IO端口值,从低位到高位对应电平为0111 0000 转化成0x0e
(4)8号IO引脚接s1、s2、s3、s4的一极,8号IO引脚被拉低,说明这四个按键有一个被按下了。确定是这一行。
第二步:
(1)输入0xf0, 这时从低位到高位(8-1)的电平对应为0000 1111
(2)按下按键s1,s1接的是8和4 io引脚,4是高电平,s1被按下之后,4io引脚电平从高电平被拉成低电平。
(3)再读IO端口值,从低位到高位对应为 0000 0111 转换成0xe0
第三步:从第一步中的(3)中读出端口值是0x0e,找到第一行s1、s2、s3、s4有一个被按下。从第二步的(3)中读出端口值是0xe0,找到第一列s1,s5、s9、s13有一个被按下。这样就得到了行列交叉的那一个点s1。
第四步:编写函数,1.按键检测函数。2.数码管显示函数。3.延时函数用于消抖。
实验代码:
#include <reg51.h> // P0端口接数码管 // P3端口接矩阵键盘 #define KEY P3 #define DIG P0 //数码管接P0 unsigned char GetKey(void); //检测按键键值函数 void delay10ms(void); //延时10毫秒,用于消抖 // 独立数码管的段码表 unsigned char val[16] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e}; void main(void) { unsigned char key = 0; while (1) { key = GetKey(); //返回值为键值 if (key != 0) { DIG = val[key]; } } } unsigned char GetKey(void) { unsigned char hang = 0, lie = 0; unsigned char keyvalue = 0; // 第一步的(1) KEY = 0x0f; // 从IO口输出,写IO口 if (KEY != 0x0f) // 从IO口输入,读IO口 { // 读出的不是0x0f说明有按键被按下 // 第一步的(3):读出端口从读出值来判断是哪一行 delay10ms(); // 第一步的(3) switch (KEY) { case 0x0e: hang = 1; break; case 0x0d: hang = 2; break; case 0x0b: hang = 3; break; case 0x07: hang = 4; break; default: break; } // 第二步的(1) KEY = 0xf0; if (KEY != 0xf0) { switch (KEY) { //第二步的(3) case 0xe0: lie = 1; break; case 0xd0: lie = 2; break; case 0xb0: lie = 3; break; case 0x70: lie = 4; break; default: break; } // //经过两步后hang和lie都知道了,然后根据hang和lie去计算键值即可 keyvalue = (hang - 1) * 4 + lie; return keyvalue; } } return 0; } void delay10ms(void) //误差 0us { unsigned char a,b,c; for(c=5;c>0;c--) for(b=4;b>0;b--) for(a=248;a>0;a--); }
总结;
这节课我学了两遍,第一遍不知道这是在干嘛,第二遍学完有点懂了,但是真正的理解还是当我写完这篇文章后,重在理解和逻辑上如何进行试验,反而写代码成了辅助。当逻辑上通了以后,写代码一会就完成了,若是知道逻辑上是怎样的但是写不出了,那就是C语言功底的事了。
相关文章推荐
- 单片机矩阵按键长短按
- 独立按键与矩阵按键的使用
- 关于矩阵按键
- 蓝桥杯单片机独立按键和矩阵按键
- i2c矩阵按键
- LayoutInflater.from(this) 这个this是什么,加载完后的View 就是谁的。
- 图的割点、桥和双连通分支的基本概念
- OMNeT++工具的简单介绍
- 遇到问题为何该自己动手
- 那些可能被你忽略的MySQL优化技巧
- Linux中安装配置spark集群
- Mac下清空DNS缓存
- Android APK安装后点击[打开]与[完成]的区别
- c# 文件流读写信息
- 前端学习_Series2_01.JavaScript_03
- tomcat下jndi的三种配置方式
- Java 继承Thread类和实现Runnable接口的区别
- Java 继承Thread类和实现Runnable接口的区别
- Java 继承Thread类和实现Runnable接口的区别
- 基于STM32的简单数字示波器