定时扫描矩阵按键

还是和之前一样,在大佬ReCclay的代码上稍加了修改和注释。

真的十分感谢ReCclay的博客

《关于按键的故事》 作者 ReCclay (https://blog.csdn.net/ReCclay/article/details/79293182)

这次的矩阵按键是在独立按键的基础上改造的:

理解独立按键,必须理解应用层KeyDriver()和底层KeyScan(),KeyAction()三者的联系

  1. KeyScan()在中断里扫描键值 运用移位操作,静态变量,循环,判断按下的键值
  2. KeyDriver()在主函数循环里刷新 使用静态变量keyback,进行按键松开,按下,按住的判断
  3. KeyAction()根据扫描的键值操作 使用多个if语句,或者case语句进行直接操作或flag操作

只是多加了一个 j,判断4* 4键盘状态。
流程:判断按下的哪个键,进行松开,按下,按住的判断,最后执行按键的指令

《定时扫描独立按键》https://blog.csdn.net/qq_28997735/article/details/88320420
按键
注意:矩阵按键P36,P37转接为P42,P44!!!

与独立按键(2ms一扫)不同,这次扫描时间为1ms一扫,1* 4* 4=16ms,这样就和独立按键扫描时间一样了

******************************************************************************
* 文件名:定时扫描矩阵按键
* 描  述:
* 作  者:思索与猫
* 日  期:  19/3/13 
* 备  注: 
*         
******************************************************************************
#include<stc15f2k60s2.h>
typedef unsigned char uchar;
typedef unsigned int uint;

sbit Key_Out_1 = P3^0;      //横排
sbit Key_Out_2 = P3^1;
sbit Key_Out_3 = P3^2;
sbit Key_Out_4 = P3^3;

sbit Key_In_1 = P4^4;       //纵排
sbit Key_In_2 = P4^2;
sbit Key_In_3 = P3^5;
sbit Key_In_4 = P3^4;

uchar code duan[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0x40}; //10black,11-
uchar dispbuff[8];
uchar num = 0;

uchar KeySta[4][4] = {{1, 1, 1, 1},      //4*4矩阵按键的状态,1为抬起,0为按下
					  {1, 1, 1, 1},
					  {1, 1, 1, 1},
					  {1, 1, 1, 1}};

uchar KeyCodeMap[4][4] = {{'1', '2', '3', '0'},   //注意这里用的是字符,可以直接写数字,那就不用加引号了
						  {'4', '5', '6', '0'},
						  {'7', '8', '9', '0'},
						  {'0', '0', '0', '0'}};

													
//function
void Timer0Init();
void CloseFucker();
void Display();
void ShowNumber();
void KeyScan();
void KeyAction(uchar temp);
void KeyDriver();
													
void main()
{
		CloseFucker();
		Timer0Init();          //2ms 12Mhz
		while(1)
		{
				ShowNumber();
				KeyDriver();
		}
}

void T0_time() interrupt 1
{
		Display();
		KeyScan();
}

void KeyDriver()
{
		uchar i = 0, j = 0;
	    static uchar keyback[4][4] = {{1,1,1,1},    //备用键,用来判断抬起,按下
									  {1,1,1,1},
									  {1,1,1,1},
									  {1,1,1,1},};
		for(i = 0; i < 4; i++)
		{
				for(j = 0; j <4; j++)
				{
						if(KeySta[i][j] != keyback[i][j])     //按键状态发生变化
						{
								if(KeySta[i][j] != 0)            //按键状态又发生变化,说明按下又抬起
								{
										KeyAction(KeyCodeMap[i][j]);      //执行按键指令
								}
								keyback[i][j] = KeySta[i][j];       //将变化后的按键状态值储存
						}
				}
		}
}

void KeyAction(uchar temp)       //按键执行
{
		num = temp-'0';      
}

void KeyScan()
{
		uchar i = 0;
		static uchar keyout = 0;
		static uchar KeyBuf[4][4] = {{0xff,0xff,0xff,0xff},     
									 {0xff,0xff,0xff,0xff},
									 {0xff,0xff,0xff,0xff},
									 {0xff,0xff,0xff,0xff}};
									 
		switch(keyout)
		{
				case 0:Key_Out_1 = 0;Key_Out_4 = 1;break;
				case 1:Key_Out_2 = 0;Key_Out_1 = 1;break;
			    case 2:Key_Out_3 = 0;Key_Out_2 = 1;break;
				case 3:Key_Out_4 = 0;Key_Out_3 = 1;break;
		}
		
		KeyBuf[keyout][0] = KeyBuf[keyout][0]<<1|Key_In_1;
		KeyBuf[keyout][1] = KeyBuf[keyout][1]<<1|Key_In_2;
		KeyBuf[keyout][2] = KeyBuf[keyout][2]<<1|Key_In_3;
		KeyBuf[keyout][3] = KeyBuf[keyout][3]<<1|Key_In_4;
		
		for(i = 0;i<4; i++)
		{
				if((KeyBuf[keyout][i]&0x0f) == 0x00)      //键盘按下
				{
						KeySta[keyout][i] = 0;
				}
				else if((KeyBuf[keyout][i]&0x0f) == 0x0f)      //键盘抬起
				{
						KeySta[keyout][i] = 1;
				}
		}	
		keyout++;
		keyout &= 0x03;
}

void ShowNumber()
{
		dispbuff[0] = num/10;
		dispbuff[1] = num%10;
		dispbuff[2] = 10;
		dispbuff[3] = 10;
		dispbuff[4] = 10;
		dispbuff[5] = 10;
		dispbuff[6] = 10;
		dispbuff[7] = 10;
}

void Display()
{
		static uchar index = 0;
		P2 = P2&0x1f|0xe0;
		P0 = 0xff;
		P2 = P2&0x1f;

		P2 = P2&0x1f|0xc0;
		P0 = 1<<index;
		P2 = P2&0x1f;

		P2 = P2&0x1f|0xe0;
		P0 = ~duan[dispbuff[index]];
		P2 = P2&0x1f;
	
		index++;
		index &= 0x07;
}

void Timer0Init()		//1ms 12Mhz
{
		AUXR |= 0x80;		
		TMOD &= 0xF0;		
		TL0 = 0x20;		
		TH0 = 0xD1;		
		TF0 = 0;		
		TR0 = 1;	
		ET0 = 1;
		EA = 1;
}

void CloseFucker()
{
		P2 = P2&0x1f|0xa0;
		P0 = 0xaf;
		P2 = P2&0x1f;
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值