矩阵键盘
矩阵键盘原理图
开发板设置:
J13跳线帽:IO模式
J5跳线帽:KBD模式(矩阵键盘模式) --> KBD模式是将上述的一、二引脚相连接
矩阵键盘与LED灯及数码管的结合使用:
//1、使用矩阵键盘的方式点击S7键盘后第一个数码管显示7,点击S6键盘后第二个数码管显示6,点击S5键盘后第三个数码管显示5,点击S4键盘后第4个数码管显示4.
#include<stc15.h>
typedef unsigned int uint;
typedef unsigned char uchar;
uchar tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
uchar SEG1, SEG2, SEG3, SEG4, SEG5, SEG6, SEG7, SEG8;
uchar one, two, three, four, five, six, seven, eight;
uchar P30_flag = 0, P31_flag = 0, P32_flag = 0, P33_flag = 0;
void keypad();
void delay_tm(uint ms);
void SEG_open(one, two, three, four, five, six, seven, eight);
void main()
{
P2 = 0XA0; P0 = 0X00; P2 = 0X80; P0 = 0XFF;
P2 = 0XC0; P0 = 0X01; P2 = 0XFF; P0 = 0XFF;
P44 = 0; //将P44引脚设置为低电位 需要哪一列亮时就将哪一列的引脚电位赋值为低电位。
while(1){
keypad();
if(P30_flag == 1){
P30_flag = 0;
SEG1 = 7;
}
if(P31_flag == 1){
P31_flag = 0;
SEG2 = 6;
}
if(P32_flag == 1){
P32_flag = 0;
SEG3 = 5;
}
if(P33_flag == 1){
P33_flag = 0;
SEG4 = 4;
}
SEG_open(SEG1, SEG2, SEG3, SEG4, SEG5, SEG6, SEG7, SEG8);
}
}
void keypad() //判断键盘是否按下
{
if(P30 == 0){
delay_tm(10);
if(P30 == 0)
P30_flag = 1;
while(!P30);
}
if(P31 == 0){
delay_tm(10);
if(P31 == 0)
P31_flag = 1;
while(!P31);
}
if(P32 == 0){
delay_tm(10);
if(P32 == 0)
P32_flag = 1;
while(!P32);
}
if(P33 == 0){
delay_tm(10);
if(P33 == 0)
P33_flag = 1;
while(!P33);
}
}
void delay_tm(uint ms)
{
uint i, j;
for(i = 0; i < 853 ; i++)
for(j = 0; j < ms; j++);
}
void SEG_open(one, two, three, four, five, six, seven, eight)//点亮数码管程序
{
P2 = 0XC0; P0 = 0X01; P2 = 0XFF; P0 = tab[one];
delay_tm(1);
P0 = 0XFF;
P2 = 0XC0; P0 = 0X02; P2 = 0XFF; P0 = tab[two];
delay_tm(1);
P0 = 0XFF;
P2 = 0XC0; P0 = 0X04; P2 = 0XFF; P0 = tab[three];
delay_tm(1);
P0 = 0XFF;
P2 = 0XC0; P0 = 0X08; P2 = 0XFF; P0 = tab[four];
delay_tm(1);
P0 = 0XFF;
P2 = 0XC0; P0 = 0X10; P2 = 0XFF; P0 = tab[five];
delay_tm(1);
P0 = 0XFF;
P2 = 0XC0; P0 = 0X20; P2 = 0XFF; P0 = tab[six];
delay_tm(1);
P0 = 0XFF;
P2 = 0XC0; P0 = 0X40; P2 = 0XFF; P0 = tab[seven];
delay_tm(1);
P0 = 0XFF;
P2 = 0XC0; P0 = 0X80; P2 = 0XFF; P0 = tab[eight];
delay_tm(1);
P0 = 0XFF;
}
//2、将矩阵键盘前两列所对应的数字依次显示到数码管屏幕上
#include<stc15.h>
typedef unsigned int uint;
typedef unsigned char uchar;
uchar tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
uchar SEG1, SEG2, SEG3, SEG4, SEG5, SEG6, SEG7, SEG8;
uchar one, two, three, four, five, six, seven, eight;
uchar S7_flag = 0, S6_flag = 0, S5_flag = 0, S4_flag = 0, S11_flag = 0, S10_flag = 0, S9_flag = 0, S8_flag = 0;//使用标志位,方便后续使用。
void keypad();
void delay_tm(uint ms);
void SEG_open(one, two, three, four, five, six, seven, eight);
void main()
{
P2 = 0XA0; P0 = 0X00; P2 = 0X80; P0 = 0XFF;
P2 = 0XC0; P0 = 0X01; P2 = 0XFF; P0 = 0XFF;
while(1){
keypad();
if(S7_flag == 1){
S7_flag = 0;
SEG1 = 7;
}
if(S6_flag == 1){
S6_flag = 0;
SEG2 = 6;
}
if(S5_flag == 1){
S5_flag = 0;
SEG3 = 5;
}
if(S4_flag == 1){
S4_flag = 0;
SEG4 = 4;
}
if(S11_flag == 1){
S11_flag = 0;
SEG5 = 11;
}
if(S10_flag == 1){
S10_flag = 0;
SEG6 = 10;
}
if(S9_flag == 1){
S9_flag = 0;
SEG7 = 9;
}
if(S8_flag == 1){
S8_flag = 0;
SEG8 = 8;
}
SEG_open(SEG1, SEG2, SEG3, SEG4, SEG5, SEG6, SEG7, SEG8);
}
}
void keypad()
{
P44 = 0; P42 = 1; //当使用第二一列的数码管时,将P44引脚赋值为低电位
if(P30 == 0){
delay_tm(10);
if(P30 == 0)
S7_flag = 1;
while(!P30);
}
if(P31 == 0){
delay_tm(10);
if(P31 == 0)
S6_flag = 1;
while(!P31);
}
if(P32 == 0){
delay_tm(10);
if(P32 == 0)
S5_flag = 1;
while(!P32);
}
if(P33 == 0){
delay_tm(10);
if(P33 == 0)
S4_flag = 1;
while(!P33);
}
P44 = 1; P42 = 0; //当使用第二列的数码管时,将P42引脚赋值为低电位
if(P30 == 0){
delay_tm(10);
if(P30 == 0)
S11_flag = 1;
while(!P30);
}
if(P31 == 0){
delay_tm(10);
if(P31 == 0)
S10_flag = 1;
while(!P31);
}
if(P32 == 0){
delay_tm(10);
if(P32 == 0)
S9_flag = 1;
while(!P32);
}
if(P33 == 0){
delay_tm(10);
if(P33 == 0)
S8_flag = 1;
while(!P33);
}
}
void delay_tm(uint ms)
{
uint i, j;
for(i = 0; i < 853 ; i++)
for(j = 0; j < ms; j++);
}
void SEG_open(one, two, three, four, five, six, seven, eight)
{
P2 = 0XC0; P0 = 0X01; P2 = 0XFF; P0 = tab[one];
delay_tm(1);
P0 = 0XFF;
P2 = 0XC0; P0 = 0X02; P2 = 0XFF; P0 = tab[two];
delay_tm(1);
P0 = 0XFF;
P2 = 0XC0; P0 = 0X04; P2 = 0XFF; P0 = tab[three];
delay_tm(1);
P0 = 0XFF;
P2 = 0XC0; P0 = 0X08; P2 = 0XFF; P0 = tab[four];
delay_tm(1);
P0 = 0XFF;
P2 = 0XC0; P0 = 0X10; P2 = 0XFF; P0 = tab[five];
delay_tm(1);
P0 = 0XFF;
P2 = 0XC0; P0 = 0X20; P2 = 0XFF; P0 = tab[six];
delay_tm(1);
P0 = 0XFF;
P2 = 0XC0; P0 = 0X40; P2 = 0XFF; P0 = tab[seven];
delay_tm(1);
P0 = 0XFF;
P2 = 0XC0; P0 = 0X80; P2 = 0XFF; P0 = tab[eight];
delay_tm(1);
P0 = 0XFF;
}
//3、使用第一、第二列矩阵程序按下S7、S6、S5、S4、S11、S10、S9、S8按键,依次用第一个数码管显示1、2、3、4、5、6、7、8数值。
#include<stc15.h>
typedef unsigned int uint;
typedef unsigned char uchar;
uchar tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
uchar key_change = 0;
void keypad();
void delay_tm(uint ms);
void main()
{
P2 = 0XA0; P0 = 0X00; P2 = 0X80; P0 = 0XFF;
P2 = 0XC0; P0 = 0X01; P2 = 0XFF; P0 = 0XFF;
while(1)
{
keypad();
if(!key_change == 0){ //使用key_change对P0的数值进行交换,使得P0可以直接显示出所按键盘对应的数字。
P0 = tab[key_change];
key_change = 0;
}
}
}
void keypad()
{
P44 = 0; P42 = 1;
if(P30 == 0){
delay_tm(10);
if(P30 == 0)
key_change = 1; //将需要的数值赋值给key_change,以便主程序使用。以下key_change均为该原因。
while(!P30);
}
if(P31 == 0){
delay_tm(10);
if(P31 == 0)
key_change = 2;
while(!P31);
}
if(P32 == 0){
delay_tm(10);
if(P32 == 0)
key_change = 3;
while(!P32);
}
if(P33 == 0){
delay_tm(10);
if(P33 == 0)
key_change = 4;
while(!P33);
}
P44 = 1; P42 = 0;
if(P30 == 0){
delay_tm(10);
if(P30 == 0)
key_change = 5;
while(!P30);
}
if(P31 == 0){
delay_tm(10);
if(P31 == 0)
key_change = 6;
while(!P31);
}
if(P32 == 0){
delay_tm(10);
if(P32 == 0)
key_change = 7;
while(!P32);
}
if(P33 == 0){
delay_tm(10);
if(P33 == 0)
key_change = 8;
while(!P33);
}
}
void delay_tm(uint ms)
{
uint i, j;
for(i = 0; i < 853 ; i++)
for(j = 0; j < ms; j++);
}
//4、使用矩阵键盘当 按下S4时LED灯全部亮;按下S5时LED灯全部灭;按下S6时LED奇数灯亮;按下S7时LED偶数灯亮。
#include<stc15.h>
typedef unsigned char uchar;
typedef unsigned int uint;
uchar S7_flag = 0,S6_flag = 0,S5_flag = 0,S4_flag = 0;
void keypad();
void delay_tm(uint ms);
void main()
{
P2 = 0XA0; P0 = 0X00; P2 = 0X80; P0 = 0XFF;
while(1){
keypad();
if(S7_flag == 1){
S7_flag = 0;
P0 = 0X55;
}
if(S6_flag == 1){
S6_flag = 0;
P0 = 0XAA;
}
if(S5_flag == 1){
S5_flag = 0;
P0 = 0XFF;
}
if(S4_flag == 1){
S4_flag = 0;
P0 = 0X00;
}
}
}
void keypad()
{
P44 = 0;
if(P30 == 0){
delay_tm(10);
if(P30 == 0)
S7_flag = 1;
while(!P30);
}
if(P31 == 0){
delay_tm(10);
if(P31 == 0)
S6_flag = 1;
while(!P31);
}
if(P32 == 0){
delay_tm(10);
if(P32 == 0)
S5_flag = 1;
while(!P32);
}
if(P33 == 0){
delay_tm(10);
if(P33 == 0)
S4_flag = 1;
while(!P33);
}
}
void delay_tm(uint ms)
{
uint i, j;
for(i = 0; i < 853 ; i++)
for(j = 0; j < ms; j++);
}
//使用矩阵键盘按下S4-S16键盘依次显示1-9(按照列扫描的方法进行)
#include<stc15.h>
typedef unsigned int uint;
typedef unsigned char uchar;
uchar tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
uchar key_change = 0; //标志位:用来记录数码管将要显示的数字
void keypad();
void delay_tm(uint ms);
void main()
{
P2 = 0XA0; P0 = 0X00; P2 = 0X80; P0 = 0XFF;
P2 = 0XC0; P0 = 0X01; P2 = 0XFF; P0 = 0XFF;
while(1){
keypad();
if(key_change != 0){
P0 = tab[key_change]; //将tab表格中第key_change个值赋给P0,即将第key_change个数在数码管上进行显示
key_change = 0;
}
}
}
void keypad()
{
uint temp; //定义中间变量,将后续P3的值赋值个temp中间变量
P44 = 0; P3 = 0X7F; //0111 1111 P42 = 1;//
temp = P3;
temp = temp&0X0F; //意思为temp = P3&0X0F
if(temp != 0X0F){ //判断P3是否等于0X0F
delay_tm(10);
//temp = P3;
//temp = temp&0X0F; //这两处可以省略
if(temp != 0X0F){ //0000 1111
temp = P3;
switch(temp){ //此处switch中的参数为temp而不是P3是为了后续方便退出循环
case 0X7E :key_change = 1; break; //0111 1110
case 0X7D :key_change = 2; break; //0111 1101
case 0X7B :key_change = 3; break; //0111 1011
case 0X77 :key_change = 4; break; //0111 0111
default : break;
}
while(temp != 0X0F){ //当P3=0X0F时退出循环,即当按键松开时退出循环
temp = P3;
temp = temp&0X0F;
}
}
}
P44 = 1; P42 = 0; P3 = 0XBF; //1011 1111 P42 = 1; //将串口连接至P42串口
temp = P3;
temp = temp&0X0F;
if(temp != 0X0F){
delay_tm(10);
//temp = P3;
//temp = temp&0X0F; //这两处可以省略
if(temp != 0X0F){ //0000 1111
temp = P3;
switch(temp){
case 0XBE :key_change = 5; break; //1011 1110
case 0XBD :key_change = 6; break; //1011 1101
case 0XBB :key_change = 7; break; //1011 1011
case 0XB7 :key_change = 8; break; //1011 0111
default : break;
}
while(temp != 0X0F){
temp = P3;
temp = temp&0X0F;
}
}
}
P44 = 1; P42 = 1; P3 = 0XDF; //1101 1111 P42 = 1;//此处代码中的P44 = 1; P42 = 1;不可以省略,省略后会出现bug
temp = P3;
temp = temp&0X0F;
if(temp != 0X0F){
delay_tm(10);
//temp = P3;
//temp = temp&0X0F; //这两处可以省略
if(temp != 0X0F){ //0000 1111
temp = P3;
switch(temp){
case 0XDE :key_change = 9; break; //1101 1110
case 0XDD :key_change = 10; break; //1101 1101
case 0XDB :key_change = 11; break; //1101 1011
case 0XD7 :key_change = 1; break; //1101 0111
default : break;
}
while(temp != 0X0F){
temp = P3;
temp = temp&0X0F;
}
}
}
P44 = 1; P42 = 1; P3 = 0XEF; //1110 1111 P42 = 1;
temp = P3;
temp = temp&0X0F;
if(temp != 0X0F){
delay_tm(10);
//temp = P3;
//temp = temp&0X0F; //这两处可以省略
if(temp != 0X0F){ //0000 1111
temp = P3;
switch(temp){
case 0XEE :key_change = 2; break; //1110 1110
case 0XED :key_change = 3; break; //1110 1101
case 0XEB :key_change = 4; break; //1110 1011
case 0XE7 :key_change = 5; break; //1110 0111
default : break;
}
while(temp != 0X0F){
temp = P3;
temp = temp&0X0F;
}
}
}
}
void delay_tm(uint ms)
{
uint i, j;
for(i = 0; i < 853 ; i++)
for(j = 0; j < ms; j++);
}