ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

矩阵按键_单片机_普中

2022-01-25 20:04:47  阅读:169  来源: 互联网

标签:普中 value 单片机 按下 key 按键 PORT MATRIX


1 矩阵按键介绍

  4*4矩阵按键,又称行列式键盘,它用4条I/O线作为行线,它用4条I/O线作为列线组成键盘。在行线和列线的每一个交叉点上设置一个按键,这样键盘按键就有4*4个,这种行列式键盘结构能够有效的提高单片机系统的I/O口利用率。

 

2 功能要求:通过数码管显示矩阵按键S1-S16按下后键值0-F。

3 硬件设计

3.1 系统框图

3.2 矩阵按键和数码管电路

  

4 软件设计

4.1 行列式扫描法

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

 1 #include "reg52.h"
 2 
 3 typedef unsigned int             u16;
 4 typedef unsigned char    u8;
 5 
 6 #define KEY_MATRIX_PORT     P1          //矩阵按键控制端口
 7 #define SMG_SEG_PORT        P0        //数码管段选控制端口
 8 
 9 u8 gsmg_code[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
10                 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};  //0-F的字形码,共阴型数码管
11 
12 //延时函数,ten_us=1时,大约延时10us
13 void delay_10us(u16 ten_us)
14 {
15      while(ten_us--);
16 }
17 
18 //矩阵按键扫描函数,采用行列式扫描法,监测按键是否按下,返回对应值
19 u8 key_matrix_ranks_scan(void)
20 {
21       u8 key_value=0;        //存储按键值
22 
23     //从第一列开始,监测第1、2、3、4行,是否有按键按下
24     KEY_MATRIX_PORT=0xf7;    //0B1111_0111,给第一列赋值0,其余为1
25     if(KEY_MATRIX_PORT!=0xf7)    //判断第一列是否按键按下
26     {
27          delay_10us(1000);        //延时10ms,滤除按下抖动区域
28         switch(KEY_MATRIX_PORT)        //返回第一列按键按下后的键值
29         {
30             case 0x77: key_value=1;break; //0B0111_0111
31             case 0xb7: key_value=5;break; //0B1011_0111
32             case 0xd7: key_value=9;break; //0B1101_0111
33             case 0xe7: key_value=13;break; //0B1110_0111
34         }
35     }
36     while(KEY_MATRIX_PORT!=0xf7);      //等待按键松开
37 
38      
39     //从第二列开始,监测第1、2、3、4行,是否有按键按下
40        KEY_MATRIX_PORT=0xfb;    //0B1111_1011,给第二列赋值0,其余为1
41     if(KEY_MATRIX_PORT!=0xfb)    //判断第二列是否按键按下
42     {
43          delay_10us(1000);        //延时10ms,滤除按下抖动区域
44         switch(KEY_MATRIX_PORT)        //返回第二列按键按下后的键值
45         {
46             case 0x7b: key_value=2;break; //0B0111_1011
47             case 0xbb: key_value=6;break; //0B1011_1011
48             case 0xdb: key_value=10;break; //0B1101_1011
49             case 0xeb: key_value=14;break; //0B1110_1011
50         }
51     }
52     while(KEY_MATRIX_PORT!=0xfb);      //等待按键松开
53 
54     //从第三列开始,监测第1、2、3、4行,是否有按键按下
55     KEY_MATRIX_PORT=0xfd;    //0B1111_1101,给第三列赋值0,其余为1
56     if(KEY_MATRIX_PORT!=0xfd)    //判断第三列是否按键按下
57     {
58          delay_10us(1000);        //延时10ms,滤除按下抖动区域
59         switch(KEY_MATRIX_PORT)        //返回第三列按键按下后的键值
60         {
61             case 0x7d: key_value=3;break;     //0B0111_1101
62             case 0xbd: key_value=7;break;     //0B1011_1101
63             case 0xdd: key_value=11;break;     //0B1101_1101
64             case 0xed: key_value=15;break;     //0B1110_1101
65         }
66     }
67     while(KEY_MATRIX_PORT!=0xfd);      //等待按键松开
68 
69 
70     //从第四列开始,监测第1、2、3、4行,是否有按键按下
71     KEY_MATRIX_PORT=0xfe;        //0B1111_1110,给第一列赋值0,其余为1
72     if(KEY_MATRIX_PORT!=0xfe)    //判断第四列是否按键按下
73     {
74          delay_10us(1000);        //延时10ms,滤除按下抖动区域
75         switch(KEY_MATRIX_PORT)        //返回第四列按键按下后的键值
76         {
77             case 0x7e: key_value=4;break; //0B0111_0111
78             case 0xbe: key_value=8;break; //0B1011_0111
79             case 0xde: key_value=12;break; //0B1101_0111
80             case 0xee: key_value=16;break; //0B1110_0111
81         }
82     }
83     while(KEY_MATRIX_PORT!=0xfe);      //等待按键松开
84 
85     return key_value;
86 }
87 
88 void main()
89 {
90      u8 key=0;
91     while(1)
92     {
93          key=key_matrix_ranks_scan();
94         if(key!=0)
95             SMG_SEG_PORT=gsmg_code[key-1];
96     }
97 }    
key4x4.c

4.2 线翻转法

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

 1 #include "reg52.h"
 2 
 3 typedef unsigned int     u16;
 4 typedef unsigned char    u8;
 5 
 6 #define KEY_MATRIX_PORT     P1          //矩阵按键控制端口
 7 #define SMG_SEG_PORT        P0        //数码管段选控制端口
 8 
 9 u8 gsmg_code[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
10                 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};  //0-F的字形码,共阴型数码管
11 
12 //延时函数,ten_us=1时,大约延时10us
13 void delay_10us(u16 ten_us)
14 {
15      while(ten_us--);
16 }
17 
18 //矩阵按键扫描函数,采用线翻转扫描方法
19 u8 key_matrix_flip_scan(void)
20 {
21       static u8 key_value=0;        //存储按键值
22     KEY_MATRIX_PORT=0x0f;         //给所有行赋值0,列全为1,即0b0000_1111
23     if(KEY_MATRIX_PORT!=0x0f)      //判断按键是否按下
24     {
25          delay_10us(1000);         //消抖
26         if(KEY_MATRIX_PORT!=0x0f)
27         {
28              //测试列
29             KEY_MATRIX_PORT=0x0f;         //0b0000_1111
30             switch(KEY_MATRIX_PORT)
31             {
32                 case 0x07: key_value=1;break;  //监测到第1列有按键按下
33                 case 0x0b: key_value=2;break;  //监测到第2列有按键按下
34                 case 0x0d: key_value=3;break;  //监测到第3列有按键按下
35                 case 0x0e: key_value=4;break;  //监测到第4列有按键按下
36             }
37 
38             //测试行
39             KEY_MATRIX_PORT=0xf0;         //1111_0000
40             switch(KEY_MATRIX_PORT)
41             {
42                 case 0x70: key_value=key_value;break;          //监测到第1行有按键按下
43                 case 0xb0: key_value=key_value+4;break;      //监测到第2行有按键按下
44                 case 0xd0: key_value=key_value+8;break;      //监测到第3行有按键按下
45                 case 0xe0: key_value=key_value+12;break;      //监测到第4行有按键按下
46             }
47             while(KEY_MATRIX_PORT!=0xf0);
48         }
49     }
50     else 
51         key_value=0;
52     return key_value;
53 }
54 
55 void main()
56 {
57      u8 key=0;
58     while(1)
59     {
60          key=key_matrix_flip_scan();
61         if(key!=0)
62             SMG_SEG_PORT=gsmg_code[key-1];
63     }
64 }
key4x4_flip.c

5 实验现象:当按下S1-S16键,数码管对应显示0-F。

参考资料

(1)(79条消息) 51单片机(V51)———独立按键、4x4矩阵按键_正弦定理的博客-CSDN博客

 

标签:普中,value,单片机,按下,key,按键,PORT,MATRIX
来源: https://www.cnblogs.com/zclv/p/15843259.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有