矩阵按键 矩阵按键

原创

矩阵按键

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_43616727/article/details/84337895

*觉得有用有帮助的评论下,谢谢~

矩阵按键

原理图

​ 独立按键一个按键就要占用一个IO口,整个单片机也就32个IO口,全部用完也控制不了几个按键,太占用资源,而矩阵按键则在这方面更有优势,可以只用8个IO口就可以控制16个按键。

矩阵按键原理图

使用方法

  • 逐行扫描:我们可以通过高四位轮流输出低电平来对矩阵键盘进行逐行扫描,当低四位接收到的数据不全为1的时候,说明有按键按下,然后通过接收到的数据是哪一位为0来判断是哪一个按键被按下。

P-10~P-17 的电平为0111 1111 ,假如这时 S2 按键被按下,这时 P-10~P-17数据则则为0111 1011

P-10~P-13 的电平轮流为0 ,0111-1011-1101-1110,每变一次就查一遍低四位的电平数据

  • 行列扫描:我们可以通过高四位全部输出高电平,低四位输出低电平。当接收到的数据,高四位不全为高电平时,说明有按键按下,然后通过接收的数据值,判断是哪一行有按键按下,然后再反过来,高四位输出低电平,低四位输出高电平,然后根据接收到的低四位的值判断是那一行有按键按下,这样就能够确定是哪一个按键按下了。

如先把P-10~P-17 设置为1111 0000 进行 测试,假如这时第一行有按键按下,这时JP4 的数据则为1110 0000 ,这时还不知道第一行的哪个按键按下,我们就反过来,设置 JP4 值为0000 1111,如果测得JP4的值为0000 1011,则可知是 第2列 有按键按下,再结合行测试,就可知是 S2 按下。

C语言语句

  • 这里我们要用到 switch 语句,这是一个选择语句
switch(表达式)
			{
				case(常量表达式1): 语句1; break;
				case(常量表达式2): 语句2; break;
				case(常量表达式3): 语句3; break;
				case(常量表达式4): 语句4; break;
				default:break;//默认..可以省略
			}

      
      
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

表达式与哪个常量表达式值相同就执行哪个语句

程序

  • 效果:按下 S1~S16 ,在静态数码管上一一对应显示 1~F
#include <reg52.H>
#include "intrins.h"
typedef unsigned char u8;
#define GPIO_DIG P0  //通用接口输入
#define GPIO_KEY P1	 //按键接口输入

u8 KeyValue; //定义一个全局变量,用来存放按键的值

u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共阴

void delay10ms() //误差 0us
{
unsigned char a,b,c;
for(c=1;c>0;c)
for(b=38;b>0;b)
for(a=130;a>0;a);
}

void JzKey() //矩阵按键程序
{
u8 a=0;
GPIO_KEY=0xf0; //矩阵按键低4位低电平,高四位为高电平,测试行
if(GPIO_KEY!=0xf0)
{
delay10ms(); //消抖
if(GPIO_KEY!=0xf0)
{
switch(GPIO_KEY)
{
case(0xe0): KeyValue=0;break;
case(0xd0): KeyValue=1;break;
case(0xb0): KeyValue=2;break;
case(0x70): KeyValue=3;break;

			<span class="token punctuation">}</span>

			GPIO_KEY<span class="token operator">=</span><span class="token number">0x0f</span><span class="token punctuation">;</span><span class="token comment">//与上相反,测试列			</span>
			<span class="token keyword">switch</span><span class="token punctuation">(</span>GPIO_KEY<span class="token punctuation">)</span>
			<span class="token punctuation">{</span>
				<span class="token keyword">case</span><span class="token punctuation">(</span><span class="token number">0x0e</span><span class="token punctuation">)</span><span class="token punctuation">:</span> KeyValue<span class="token operator">=</span>KeyValue<span class="token punctuation">;</span><span class="token keyword">break</span><span class="token punctuation">;</span>
				<span class="token keyword">case</span><span class="token punctuation">(</span><span class="token number">0x0d</span><span class="token punctuation">)</span><span class="token punctuation">:</span> KeyValue<span class="token operator">=</span>KeyValue<span class="token operator">+</span><span class="token number">4</span><span class="token punctuation">;</span><span class="token keyword">break</span><span class="token punctuation">;</span>
				<span class="token keyword">case</span><span class="token punctuation">(</span><span class="token number">0x0b</span><span class="token punctuation">)</span><span class="token punctuation">:</span> KeyValue<span class="token operator">=</span>KeyValue<span class="token operator">+</span><span class="token number">8</span><span class="token punctuation">;</span><span class="token keyword">break</span><span class="token punctuation">;</span>
				<span class="token keyword">case</span><span class="token punctuation">(</span><span class="token number">0x07</span><span class="token punctuation">)</span><span class="token punctuation">:</span> KeyValue<span class="token operator">=</span>KeyValue<span class="token operator">+</span><span class="token number">12</span><span class="token punctuation">;</span><span class="token keyword">break</span><span class="token punctuation">;</span>					
			<span class="token punctuation">}</span>
			<span class="token keyword">while</span><span class="token punctuation">(</span><span class="token punctuation">(</span>a<span class="token operator">&lt;</span><span class="token number">50</span><span class="token punctuation">)</span><span class="token operator">&amp;&amp;</span><span class="token punctuation">(</span>GPIO_KEY<span class="token operator">!=</span><span class="token number">0x0f</span><span class="token punctuation">)</span><span class="token punctuation">)</span>	 <span class="token comment">//检测按键松手检测</span>
			<span class="token punctuation">{</span>
				<span class="token function">delay10ms</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
				a<span class="token operator">++</span><span class="token punctuation">;</span>
			<span class="token punctuation">}</span>
		
	<span class="token punctuation">}</span>
<span class="token punctuation">}</span>

}

void main()
{
while(1)
{
JzKey();
GPIO_DIG=~smgduan[KeyValue];//数码管显示
}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65

扩展

  • 当我做完上面的实验时,突然想起来以前用计算器的时候,每按一下,都会响一声,这样就可以知道你按到没有,因此我就想在这实现每当按键按下时,蜂鸣器就响,松开时,蜂鸣器就停。

定时器中断

  • 为了实现上述功能,我在这里用到了 定时器 ,这里我就直接介绍它的用法

用法

工作模式

  • 一般比较常用的 方式1方式2

要注意的是,用 方式1 时,要手动重装初值!

定时器中断程序

void InitTimer0(void)     //定时器0程序
{
    TMOD = 0x01;         //设置工作方式
    TH0 = 0x0FF;         //设置初值
    TL0 = 0x9C;
    EA = 1;              //中断总开关
    ET0 = 1;             //定时/计数器0中断允许控制
    TR0 = 1;             //定时器开关

}
void Timer0Interrupt(void) interrupt 1 //定时器中断程序
{
TH0 = 0x0FF; //重装初值
TL0 = 0x9C;
fmq=~fmq; //蜂鸣器
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 要实现扩展功能,只需加个定时器中断, 定时器中断 来控制 蜂鸣器 的响与停,先把 定时器0程序 里的定时器开关 TR0=0 ;在按键按下后,在让 TR0=1 ,让定时器开始定时,蜂鸣器就响了,在检测到按键松开后,这时在让 TR0=0 ,停止定时器,这时蜂鸣器就停了。

完美收工~~~~

                                </div>
            <link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-e9f16cbbc2.css" rel="stylesheet">
                </div>
</article>
<div class="postTime"> 
    <div class="article-bar-bottom">
        <span class="time">
            文章最后发布于: 2018-11-22 13:44:57            </span>
    </div>
</div>
发布了23 篇原创文章 · 获赞 0 · 访问量 238
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_43616727/article/details/84337895

*觉得有用有帮助的评论下,谢谢~

矩阵按键

原理图

​ 独立按键一个按键就要占用一个IO口,整个单片机也就32个IO口,全部用完也控制不了几个按键,太占用资源,而矩阵按键则在这方面更有优势,可以只用8个IO口就可以控制16个按键。

矩阵按键原理图

使用方法

  • 逐行扫描:我们可以通过高四位轮流输出低电平来对矩阵键盘进行逐行扫描,当低四位接收到的数据不全为1的时候,说明有按键按下,然后通过接收到的数据是哪一位为0来判断是哪一个按键被按下。

P-10~P-17 的电平为0111 1111 ,假如这时 S2 按键被按下,这时 P-10~P-17数据则则为0111 1011

P-10~P-13 的电平轮流为0 ,0111-1011-1101-1110,每变一次就查一遍低四位的电平数据

  • 行列扫描:我们可以通过高四位全部输出高电平,低四位输出低电平。当接收到的数据,高四位不全为高电平时,说明有按键按下,然后通过接收的数据值,判断是哪一行有按键按下,然后再反过来,高四位输出低电平,低四位输出高电平,然后根据接收到的低四位的值判断是那一行有按键按下,这样就能够确定是哪一个按键按下了。

如先把P-10~P-17 设置为1111 0000 进行 测试,假如这时第一行有按键按下,这时JP4 的数据则为1110 0000 ,这时还不知道第一行的哪个按键按下,我们就反过来,设置 JP4 值为0000 1111,如果测得JP4的值为0000 1011,则可知是 第2列 有按键按下,再结合行测试,就可知是 S2 按下。

C语言语句

  • 这里我们要用到 switch 语句,这是一个选择语句
switch(表达式)
			{
				case(常量表达式1): 语句1; break;
				case(常量表达式2): 语句2; break;
				case(常量表达式3): 语句3; break;
				case(常量表达式4): 语句4; break;
				default:break;//默认..可以省略
			}

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

表达式与哪个常量表达式值相同就执行哪个语句

程序

  • 效果:按下 S1~S16 ,在静态数码管上一一对应显示 1~F
#include <reg52.H>
#include "intrins.h"
typedef unsigned char u8;
#define GPIO_DIG P0  //通用接口输入
#define GPIO_KEY P1	 //按键接口输入

猜你喜欢

转载自blog.csdn.net/qq_41518179/article/details/102805135