第十一课:矩阵按键
独立按键:一端接单片机引脚,一端接地或电源,一个按键对应一个端口。
矩阵按键:有限端口实现更多按键,按键检测比独立按键慢。
按键识别原理:端口默认为高电平,实时读取到引脚为低电平是表示按下。①第一步:现将P0.0-P0.3输出低电平,P0.6- P0.7输出高电平,如果有按键按下,按下的那一行的IO就会变成低电平,就可以判断出哪一行按下了。②第二步:现将P0.0-P0.3输出高电平,P0.6-P0.7输出低电平,如果有按键按下,按下的那一列的IO就会变成低电平,就可以判断出哪一列按下了。③第三步:行列组合一下就可以判断出是哪个按键按下了。
跟着视频写了程序:
任务1:数码管显示当前的按键号
- #include "io.h"
- u8 SEG_NUM[]=
- {
- 0x3F, /*'0', 0*/
- 0x06, /*'1', 1*/
- 0x5B, /*'2', 2*/
- 0x4F, /*'3', 3*/
- 0x66, /*'4', 4*/
- 0x6D, /*'5', 5*/
- 0x7D, /*'6', 6*/
- 0x07, /*'7', 7*/
- 0x7F, /*'8', 8*/
- 0x6F, /*'9', 9*/
- 0x77, /*'A', 10*/
- 0x7C, /*'B', 11*/
- 0x39, /*'C', 12*/
- 0x5E, /*'D', 13*/
- 0x79, /*'E', 14*/
- 0x71, /*'F', 15*/
- 0x40, /*'-', 16*/
- 0x00, /*' ', 17*/
- 0x80, /*'.', 18*/
- };
-
- u8 T_NUM[8]=
- {
- 0X01,0X02,0X04,0X08,0X10,0X20,0X40,0X80
- };
-
- /*
- #define ROW1 P06 //端口定义
- #define ROW2 P07
- #define COL1 P00
- #define COL2 P01
- #define COL3 P02
- #define COL4 P03
- */
-
- u8 key_num = 0xff;
-
- //任务1:数码管显示当前的按键号
- void Task_1(void)
- {
-
- //①第一步:现将P0.0-P0.3输出低电平,P0.6-P0.7输出高电平,如果有按键按下,按下的那一行的IO就会变成低电平,就可以判断出哪一行按下了。
- COL1 = 0;
- COL2 = 0;
- COL3 = 0;
- COL4 = 0;
- ROW1 = 1;
- ROW2 = 1;
-
- if((ROW1 == 0)||(ROW2 == 0)) //如果行按键有按下
- {
- if((ROW1 == 0)&&(ROW2 == 0)) //如果两行都有按键按下,不处理
- {
-
- }
- else if(((ROW1 == 1)&&(ROW2 == 0))||((ROW1 == 0)&&(ROW2 == 1))) //如果有按键按下,而且只有一颗
- {
- if(ROW1 == 0) //判断哪一行,输出行开始的序号
- key_num = 0;
- else if(ROW2 == 0)
- key_num = 4;
-
- //②第二步:现将P0.0-P0.3输出高电平,P0.6-P0.7输出低电平,如果有按键按下,按下的那一列的IO就会变成低电平,就可以判断出哪一列按下了。
- COL1 = 1;
- COL2 = 1;
- COL3 = 1;
- COL4 = 1;
- ROW1 = 0;
- ROW2 = 0;
-
- if(COL1 == 0)
- {
- // key_num = key_num+0;
- }
- else if(COL2 == 0)
- {
- key_num = key_num+1;
- }
- else if(COL3 == 0)
- {
- key_num = key_num+2;
- }
- else if(COL4 == 0)
- {
- key_num = key_num+3;
- }
- }
- COL1 = 0;
- COL2 = 0;
- COL3 = 0;
- COL4 = 0;
- ROW1 = 1;
- ROW2 = 1;
- }
- else
- {
- key_num = 0xff;
- }
-
- //③第三步:行列组合一下就可以判断出是哪个按键按下了。
- }
-
- void Init_595(void)
- {
- HC595_SER = 0;
- HC595_RCK = 0;
- HC595_SCK = 0;
- }
-
- void Send_595(u8 dat)
- {
- u8 i;
- for(i=0;i<8;i++)
- {
- dat <<=1; //dat = (dat<<1); //最高位CY
- HC595_SER = CY; //先把数据写到引脚上
- HC595_SCK = 1; //输出上升沿的时钟信号
- HC595_SCK = 0;
- }
- }
-
- void Display_Seg(u8 HC595_1,u8 HC595_2)
- {
- Send_595(HC595_1); //数码管段码先输出 高电平点亮
- Send_595(HC595_2); //数码管位码输出 低电平点亮
-
- HC595_RCK = 1; //数据输出
- HC595_RCK = 0;
- }
-
- void SEG_Task(void)
- {
- if(key_num == 255)
- Display_Seg(SEG_NUM[17],~T_NUM[0]); //数码管刷段码和位码
- else
- Display_Seg(SEG_NUM[key_num],~T_NUM[0]);
- }
复制代码
任务2:密码锁
- #include "io.h"
-
- u8 SEG_NUM[]=
- {
- 0x3F, /*'0', 0*/
- 0x06, /*'1', 1*/
- 0x5B, /*'2', 2*/
- 0x4F, /*'3', 3*/
- 0x66, /*'4', 4*/
- 0x6D, /*'5', 5*/
- 0x7D, /*'6', 6*/
- 0x07, /*'7', 7*/
- 0x7F, /*'8', 8*/
- 0x6F, /*'9', 9*/
- 0x77, /*'A', 10*/
- 0x7C, /*'B', 11*/
- 0x39, /*'C', 12*/
- 0x5E, /*'D', 13*/
- 0x79, /*'E', 14*/
- 0x71, /*'F', 15*/
- 0x40, /*'-', 16*/
- 0x00, /*' ', 17*/
- 0x80, /*'.', 18*/
- };
-
- u8 T_NUM[8]=
- {
- 0X01,0X02,0X04,0X08,0X10,0X20,0X40,0X80
- };
-
- /*
- #define ROW1 P06 //端口定义
- #define ROW2 P07
- #define COL1 P00
- #define COL2 P01
- #define COL3 P02
- #define COL4 P03
- */
-
- u8 key_num = 0xff;
-
- //任务1:数码管显示当前的按键号
- void Task_1(void)
- {
-
- //①第一步:现将P0.0-P0.3输出低电平,P0.6-P0.7输出高电平,如果有按键按下,按下的那一行的IO就会变成低电平,就可以判断出哪一行按下了。
- COL1 = 0;
- COL2 = 0;
- COL3 = 0;
- COL4 = 0;
- ROW1 = 1;
- ROW2 = 1;
-
- if((ROW1 == 0)||(ROW2 == 0)) //如果行按键有按下
- {
- if((ROW1 == 0)&&(ROW2 == 0)) //如果两行都有按键按下,不处理
- {
-
- }
- else if(((ROW1 == 1)&&(ROW2 == 0))||((ROW1 == 0)&&(ROW2 == 1))) //如果有按键按下,而且只有一颗
- {
- if(ROW1 == 0) //判断哪一行,输出行开始的序号
- key_num = 0;
- else if(ROW2 == 0)
- key_num = 4;
-
- //②第二步:现将P0.0-P0.3输出高电平,P0.6-P0.7输出低电平,如果有按键按下,按下的那一列的IO就会变成低电平,就可以判断出哪一列按下了。
- COL1 = 1;
- COL2 = 1;
- COL3 = 1;
- COL4 = 1;
- ROW1 = 0;
- ROW2 = 0;
-
- if(COL1 == 0)
- {
- // key_num = key_num+0;
- }
- else if(COL2 == 0)
- {
- key_num = key_num+1;
- }
- else if(COL3 == 0)
- {
- key_num = key_num+2;
- }
- else if(COL4 == 0)
- {
- key_num = key_num+3;
- }
- }
- COL1 = 0;
- COL2 = 0;
- COL3 = 0;
- COL4 = 0;
- ROW1 = 1;
- ROW2 = 1;
- }
- else
- {
- key_num = 0xff;
- }
-
- //③第三步:行列组合一下就可以判断出是哪个按键按下了。
- }
-
- void Init_595(void)
- {
- HC595_SER = 0;
- HC595_RCK = 0;
- HC595_SCK = 0;
- }
-
- void Send_595(u8 dat)
- {
- u8 i;
- for(i=0;i<8;i++)
- {
- dat <<=1; //dat = (dat<<1); //最高位CY
- HC595_SER = CY; //先把数据写到引脚上
- HC595_SCK = 1; //输出上升沿的时钟信号
- HC595_SCK = 0;
- }
- }
-
- void Display_Seg(u8 HC595_1,u8 HC595_2)
- {
- Send_595(HC595_1); //数码管段码先输出 高电平点亮
- Send_595(HC595_2); //数码管位码输出 低电平点亮
-
- HC595_RCK = 1; //数据输出
- HC595_RCK = 0;
- }
-
- u8 password[8] = {16,16,16,16,16,16,16,16};
- u8 Seg_no = 0;
-
- void SEG_Task(void)
- {
- u8 num = 0;
- if(Seg_no==0)
- {
- Display_Seg(SEG_NUM[password[0]],~T_NUM[0]); //数码管刷段码和位码
- }
- else if(Seg_no==1)
- {
- Display_Seg(SEG_NUM[password[1]],~T_NUM[1]); //数码管刷段码和位码
- }
- else if(Seg_no==2)
- {
- Display_Seg(SEG_NUM[password[2]],~T_NUM[2]); //数码管刷段码和位码
- }
- else if(Seg_no==3)
- {
- Display_Seg(SEG_NUM[password[3]],~T_NUM[3]); //数码管刷段码和位码
- }
- else if(Seg_no==4)
- {
- Display_Seg(SEG_NUM[password[4]],~T_NUM[4]); //数码管刷段码和位码
- }
- else if(Seg_no==5)
- {
- Display_Seg(SEG_NUM[password[5]],~T_NUM[5]); //数码管刷段码和位码
- }
- else if(Seg_no==6)
- {
- Display_Seg(SEG_NUM[password[6]],~T_NUM[6]); //数码管刷段码和位码
- }
- else if(Seg_no==7)
- {
- Display_Seg(SEG_NUM[password[7]],~T_NUM[7]); //数码管刷段码和位码
- }
- Seg_no ++;
- if(Seg_no>7)
- Seg_no = 0;
- }
-
- u8 Key_Vol3 = 0;
- u8 key_no = 0;
-
- void PW_write_Task(void)
- {
- if(key_num<0xff)
- {
- Key_Vol3++;
- if(Key_Vol3 == 5)
- {
- if(key_no == 0)
- {
- password[0] = 16;
- password[1] = 16;
- password[2] = 16;
- password[3] = 16;
- password[4] = 16;
- password[5] = 16;
- password[6] = 16;
- password[7] = 16;
- }
- password[key_no] = key_num;
- key_no++;
- // password[7] = 17;
- if(key_no == 8)
- {
- if((password[0]==1)&&(password[1]==2)&&(password[2]==3)&&(password[3]==4)&&(password[4]==5)&&(password[5]==6)&&(password[6]==7)&&(password[7]==0))
- {
- password[0] = 17;
- password[1] = 17;
- password[2] = 17;
- password[3] = 17;
- password[4] = 17;
- password[5] = 17;
- password[6] = 17;
- password[7] = 1;
- }
- else
- {
- password[0] = 16;
- password[1] = 16;
- password[2] = 16;
- password[3] = 16;
- password[4] = 16;
- password[5] = 16;
- password[6] = 16;
- password[7] = 16;
- }
- key_no = 0;
- }
- }
- }
- else
- {
- Key_Vol3 = 0;
- }
- }
复制代码
附件程序包:
AI8051U教学视频第11集矩阵按键学习程序1.zip
(155.78 KB, 下载次数: 22)
AI8051U教学视频第11集矩阵按键学习程序2.zip
(159.94 KB, 下载次数: 22)
|