1.介绍
其中P30,P31,P32,P33控制行,P34,P35P42,P44控制列.
编程思路:
1.给高四位赋值0,检测低四位哪一位是0,确定按键所在“行”
2.给低四位赋值0,检测高四位哪一位是0,确定按键所在“列”
3.根据“行”和“列”,确定按键的位置。
编程注意事项:
1.每次按下按键需要单次触发
2.需要有松手检测
3.不阻塞程序
4.最好有长按功能
2.读取键码值
#include <STC15F2K60S2.H>
#include <INTRINS.h>
#include "system.h"
#include "Device.h"
#include "Timer2.h"
#include "SMG.h"
HexToBin led_ctrl;
//系统初始化函数
void vSystem_Init(void)
{
vDevice_Ctrl(0xa0,0);
led_ctrl.hex=0xff;
vDevice_Ctrl(0x80,led_ctrl.hex);
}
u8 vKBD_KeyIO()
{
u8 key_io=0;
P3=0xf0;P4=0xff;
if(P44==0) key_io=4;
if(P42==0) key_io=8;
if(P35==0) key_io=12;
if(P34==0) key_io=16;
P3=0x0f;P4=0x00;
if(P33==0) key_io=key_io+0;
if(P32==0) key_io=key_io+1;
if(P31==0) key_io=key_io+2;
if(P30==0) key_io=key_io+3;
return key_io;
}
u8 cnt_kbd;
u8 key_val;
void vKBD_Process()
{
if(cnt_kbd>=10)
{
cnt_kbd=0;
key_val=vKBD_KeyIO();
}
}
//数码管操作函数
u8 smg_buf[8];
void vSMG_Process()
{
smg_buf[0]=smg_code[key_val/100];
smg_buf[1]=smg_code[key_val/10%10];
smg_buf[2]=smg_code[key_val%10];
smg_buf[3]=0x00;
smg_buf[4]=0x00;
smg_buf[5]=0x00;
smg_buf[6]=0x00;
smg_buf[7]=0x00;
}
void main()
{
vSystem_Init();
Timer2Init();
while(1)
{
vSMG_Process();
vKBD_Process();
}
}
void Timer2_Routine(void) interrupt 12
{
cnt_kbd++;
vSmg_Display();
}
3.状态机法操作矩阵键盘
#include <STC15F2K60S2.H>
#include <INTRINS.h>
#include "system.h"
#include "Device.h"
#include "Timer2.h"
#include "SMG.h"
HexToBin led_ctrl;
//系统初始化函数
void vSystem_Init(void)
{
vDevice_Ctrl(0xa0,0);
led_ctrl.hex=0xff;
vDevice_Ctrl(0x80,led_ctrl.hex);
}
u8 vKBD_KeyIO()
{
u8 key_io=0;
P3=0xf0;P4=0xff;
if(P44==0) key_io=4;
if(P42==0) key_io=8;
if(P35==0) key_io=12;
if(P34==0) key_io=16;
P3=0x0f;P4=0x00;
if(P33==0) key_io=key_io+0;
if(P32==0) key_io=key_io+1;
if(P31==0) key_io=key_io+2;
if(P30==0) key_io=key_io+3;
return key_io;
}
//状态机法
#define KEY_NO 0
#define KEY_DOWN 1
#define KEY_UP 2
u8 vKBD_Read_State()
{
static u8 key_state=0;
u8 key_io=0,key_return=0;
key_io=vKBD_KeyIO();
switch(key_state)
{
case KEY_NO:
if(key_io) key_state=KEY_DOWN;
break;
case KEY_DOWN:
if(key_io)
{
key_state = KEY_UP;
key_return =key_io;
}
else
key_state = KEY_NO;
break;
case KEY_UP:
if(key_io==0) key_state = KEY_NO;
break;
}
return key_return;
}
u8 cnt_kbd;
u8 s4_number;
u8 key_val;
void vKBD_Process()
{
if(cnt_kbd>=10)
{
cnt_kbd=0;
key_val = vKBD_Read_State();
if(key_val==4)
{
s4_number++;
}
}
}
//数码管操作函数
u8 smg_buf[8];
void vSMG_Process()
{
if(key_val)
{
smg_buf[0]=smg_code[key_val/100];
smg_buf[1]=smg_code[key_val/10%10];
smg_buf[2]=smg_code[key_val%10];
smg_buf[3]=0x00;
smg_buf[4]=0x00;
smg_buf[5]=smg_code[s4_number/100];
smg_buf[6]=smg_code[s4_number/10%10];
smg_buf[7]=smg_code[s4_number%10];
}
}
void main()
{
vSystem_Init();
Timer2Init();
while(1)
{
vSMG_Process();
vKBD_Process();
}
}
void Timer2_Routine(void) interrupt 12
{
cnt_kbd++;
vSmg_Display();
}
实际现象:
4.三行按键法操作矩阵键盘
①:原理: 
②:代码
#include <STC15F2K60S2.H>
#include <INTRINS.h>
#include "system.h"
#include "Device.h"
#include "Timer2.h"
#include "SMG.h"
HexToBin led_ctrl;
//初始化函数
void vSystem_Init(void)
{
vDevice_Ctrl(0xa0,0);
led_ctrl.hex=0xff;
vDevice_Ctrl(0x80,led_ctrl.hex);
}
//三行按键法
u8 vKBD_KeyIO_ThreeLine()
{
u8 key_io=0xff;
P3=0xf0;P4=0xff; //列扫描
if(P44==0) key_io=0x70;
if(P42==0) key_io=0xb0;
if(P35==0) key_io=0xd0;
if(P34==0) key_io=0xe0;
P3=0x0f;P4=0x00; //行扫描
if(P33==0) key_io=key_io | 0x07;
if(P32==0) key_io=key_io | 0x0b;
if(P31==0) key_io=key_io | 0x0d;
if(P30==0) key_io=key_io | 0x0e;
return key_io;
}
unsigned char Trg_KBD;
unsigned char Cont_KBD;
void vKBD_Read_ThreeLine()
{
unsigned char ReadData = vKBD_KeyIO_ThreeLine()^0xff;
Trg_KBD = ReadData & (ReadData ^ Cont_KBD);
Cont_KBD = ReadData;
}
//矩阵键盘处理函数
u8 cnt_kbd;
u8 kbd_number;
u8 key_val;
void vKBD_Process()
{
if(cnt_kbd>=10)
{
cnt_kbd=0;
vKBD_Read_ThreeLine();
key_val = Cont_KBD;
if(Trg_KBD==0x88) //s4
{
kbd_number++;
}
}
}
//数码管操作函数
u8 smg_buf[8];
void vSMG_Process()
{
if(key_val)
{
smg_buf[0]=smg_code[key_val/16];
smg_buf[1]=smg_code[key_val%16];
smg_buf[2]=0x00;
smg_buf[3]=0x00;
smg_buf[4]=0x00;
smg_buf[5]=smg_code[kbd_number/100];
smg_buf[6]=smg_code[kbd_number/10%10];
smg_buf[7]=smg_code[kbd_number%10];
}
}
void main()
{
vSystem_Init();
Timer2Init();
while(1)
{
vSMG_Process();
vKBD_Process();
}
}
void Timer2_Routine(void) interrupt 12
{
cnt_kbd++;
vSmg_Display();
}
③.实际现象: