1.实验目的
掌握两种按键扫描方法:行扫描,行列扫描(高低电平翻转)。
2.实验流程图
3.代码分析
(1)行扫描
复制代码
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119#include "stm32f10x.h" u16 keyz=0; u8 a[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; void delay(u32 k) { for(;k>0;k--); } u16 keyscan(void) { u16 L,H,k,i=0; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE); //??PORTA,PORTF?? GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3; //KEY0-KEY3 矩阵键盘的列 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //??????? GPIO_Mode_Out_OD GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOD, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7; //KEY4-KEY7 矩阵键盘的行 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOD, &GPIO_InitStructure); GPIO_SetBits(GPIOD,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7); GPIO_Write(GPIOD, 0xF0); //11110000 //D0-D3拉低,D4-D7拉高 if((GPIO_ReadInputData(GPIOD)&0xF0)!=0xF0) //有按键按下 { delay(24000); //去抖 if((GPIO_ReadInputData(GPIOD)&0xF0)!=0xF0) //再次判断是否按下 { H=GPIO_ReadInputData(GPIOD); //读取按键按下后得到的代码 L=H; //将代码复制给列 H=~H; //将键码取反,例如:按下某个键得到0111 0000,取反后得到1000 1111 H=H&0XF0; //得到行1000 1111&1111 0000得到1000 0000,得到列数,与运算 for(i=0;i<4&&((L&0xF0)!=0xF0);i++) //逐次将列拉高,判断列数中原来变低的位是否变高 { //读到之前检测到为低的行变高则推出 GPIO_Write(GPIOD, (L&0xF0)|(0x01<<i)); //进行列扫描,逐次将列口线拉高,行保持为按下的状态 L=GPIO_ReadInputData(GPIOD); //读取IO口,用以判断是否扫描到列坐标 } L&=0x0F; //将列值取出 k=H|L; //行列相加则得到键码 GPIO_Write(GPIOD, 0xF0); //D0-D3拉低,D4-D7拉高,此处用来将列状态初始化为未按下时的状态 while((GPIO_ReadInputData(GPIOD)&0xF0)!=0xF0) { delay(2400); //后延消抖。时间需要长一点 } return k; //返回键码 } } return (0); //无键按下,返回0 } void smg(char num) {GPIO_SetBits(GPIOE,GPIO_Pin_All); GPIO_Write(GPIOA,a[0]); //位选 GPIO_ResetBits(GPIOE,GPIO_Pin_0); GPIO_Write(GPIOA,a[num]); delay(2000); } int main() { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; // 段选 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; //位选 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOE, &GPIO_InitStructure); GPIO_SetBits(GPIOE,GPIO_Pin_All); if(keyz==0) { GPIO_Write(GPIOA,a[0]); GPIO_SetBits(GPIOE,GPIO_Pin_All); GPIO_ResetBits(GPIOE,GPIO_Pin_0); } while(1) { keyz=keyscan(); switch(keyz) { case 0x88:smg(0);break; case 0x84:smg(1);break; case 0x82:smg(2);break; case 0x81:smg(3);break; case 0x48:smg(4);break; case 0x44:smg(5);break; case 0x42:smg(6);break; case 0x41:smg(7);break; case 0x28:smg(8);break; case 0x24:smg(9);break; case 0x22:smg(10);break; case 0x21:smg(11);break; case 0x18:smg(12);break; case 0x14:smg(13);break; case 0x12:smg(14);break; case 0x11:smg(15);break; default:break; } } }
复制代码
1
复制代码
1
复制代码
1
(2)行列扫描(高低电平翻转)
复制代码
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131#include "stm32f10x.h" u8 KeyValue=0; u8 a[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x8c,0xbf,0x89,0xb6,0xf6,0x7f,0xc0}; void delay(u32 k) { for(;k>0;k--); } void KeyDown(void) { char a=0; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE ); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;//KEY0-KEY3 矩阵键盘的列 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOD, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;//KEY4-KEY7 矩阵键盘的行 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOD, &GPIO_InitStructure); GPIO_Write(GPIOD,0X0F); if((GPIO_ReadInputData(GPIOD)&0x0f)!=0x0f) { delay(24000); if((GPIO_ReadInputData(GPIOD)&0x0f)!=0x0f) switch(GPIO_ReadInputData(GPIOD)&0x0f) { case(0X07): KeyValue=0;break; case(0X0b): KeyValue=1;break; case(0X0d): KeyValue=2;break; case(0X0e): KeyValue=3;break; } } GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;//KEY0-KEY3 矩阵键盘的行 0X0E GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOD, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;//KEY4-KEY7 矩阵键盘的列 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOD, &GPIO_InitStructure); GPIO_Write(GPIOD,0XF0); if((GPIO_ReadInputData(GPIOD)&0xF0)!=0xF0) { delay(2400); if((GPIO_ReadInputData(GPIOD)&0xF0)!=0xF0) switch(GPIO_ReadInputData(GPIOD)&0xf0) { case(0X70): KeyValue=KeyValue;break; case(0Xb0): KeyValue=KeyValue+4;break; case(0Xd0): KeyValue=KeyValue+8;break; case(0Xe0): KeyValue=KeyValue+12;break; } while((a<50)&&(GPIO_ReadInputData(GPIOD)!=0xf0)) { delay(24000); a++; } } } void smg(char num) { GPIO_Write(GPIOA,a[0]); GPIO_ResetBits(GPIOB,GPIO_Pin_0); //位选 GPIO_Write(GPIOA,a[num]); delay(20000); } int main() { u8 a,b,c; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; // 段选 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; //位选 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(GPIOB,GPIO_Pin_All); while(1) { KeyDown(); switch(KeyValue) { case 0:smg(0);break; case 1:smg(1);break; case 2:smg(2);break; case 3:smg(3);break; case 4:smg(4);break; case 5:smg(5);break; case 6:smg(6);break; case 7:smg(7);break; case 8:smg(8);break; case 9:smg(9);break; case 10:smg(10);break; case 11:smg(11);break; case 12:smg(12);break; case 13:smg(13);break; case 14:smg(14);break; case 15:smg(15);break; default:break; } } }
最后
以上就是娇气绿草最近收集整理的关于矩阵按键的两种扫描方法的全部内容,更多相关矩阵按键内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复