⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scan_key.c

📁 这是一个扫描16个键并可返回32个键号的小MCU程序,它对16上按键分单按和长按两种情况做区分.
💻 C
字号:
/*************************************************
功能说明: 扫描键盘并返回键位
*************************************************/
#pragma SMALL
//#pragma disable
#include<absacc.h>
#include<reg51.h>
#include<intrins.h>

#include"D:\exercise_C51\_inc\keyword.h"	//在自己的电脑上
//#include"F:\ldr\exercise_C51\_inc\keyword.h"				//在培训中心的电脑上

///////////////////////////////////////////
//PORT & COMMAND ADDRESS的定义
#define PORT_A8255	XBYTE[0x2000]	//chip enable & PortA
#define PORT_B8255	XBYTE[0x2001]	//在这里,用不到的pin应该设为1还是设为0好点呢?
#define PORT_C8255	XBYTE[0x2002]	//好像常见的都是设为1的.
#define COMMAND8255 XBYTE[0x2003]	//chip enable & A1A0=11

#define SEG7_COM	P1

//工作方式定义,之所以这样做是为了在函数调用时不会去改变之前的其它PORT的工作方式,
//一定程度上提高了代码的安全性.
#define KEY_PAD_SET0	0xfe	//for Port C
#define KEY_PAD_SET1	0x88
#define LED7SEG_SET0	0xf9		//for Port B
#define LED8BIT_SET0	0b8f	//for Port A	

///////////////////////////////////////
#define DISPLAY_DIGIT_TIME 1000
#define DISPLAY_NUM_TIME 50
#define DISPLAY_KEY_TIME 50
#define SCAN_REMOVE_SHAKE_TIME 6
#define EXPEND_KEY_SCAN_TIMES0 40
#define EXPEND_KEY_DELAY_TIME0 10
#define LONG_KEY_TIME 2000
///////////////////////////////////////
void delay_self(uchar x);
void delay_display(ulong x);
void seg7_display(uchar *x);
void pre_display(const uint x);
uchar scan_key(void);
///////////////////////////////////////
code uchar bcd_code_num[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0 to 9
//code uchar bcd_code_char[]={0x77,0x7c,0x39,0x5e,0x79,0x71,					//A to F
//							0x73,	//P
//							0x3e,	//U
//							0xff,	//8.
//							0x00};	//"灭"		说明:全部为共阴之数据.
code uchar seg7com[]={0xf1,0xf2,0xf4,0xf8};
//						0		1		2		3		4		5		6		7		8		9
code uint lg_data[256]={0,		0,		3010,	4771,	6021,	6990,	7782,	8451,	9031,	9541};
code uchar scan_data[]={0xf7,0xfb,0xfd,0xfe};
code uchar scan_pad[]={	231,235,237,238,
						215,219,221,222,
						183,187,189,190,
						119,123,125,126};
/////////////////////////////////////////////////////////////////////						
//typedef struct 
//{
//	uint d0:4;
//	uint d1:4;
//	uint d2:4;
//	uint d3:4;
//} seg7;
//seg7 digit={0,1,2,3};
uchar digit[]={0,1,2,3};
sbit cs138=P1^6;

void main(void)
{
	uchar key=0;
	
	cs138=0;	//***
	COMMAND8255=0x88;
	PORT_A8255=0xff;
	
	pre_display(scan_key());
	while(1)
	{
		delay_display(DISPLAY_KEY_TIME);
		
		if(!(key=scan_key()))	continue;
//		key++;
		pre_display(key);
	}
}



////////////////////////////Begin of subroutine//////////
//*****************************
//功能:返回从左到右,从上往下为1,2,3,4-->5,6,7,8...的键码.
//
uchar scan_key(void)
{
	uchar i;
	uint j;
	uchar temp;
	uchar temp_key;
	bit b_long_press=0;
	
	for(i=0;i<4;i++)
	{
		PORT_C8255=scan_data[i];
//		_nop_();
//		P0=0xff;
		temp=PORT_C8255;
		temp&=0xf0;
		if(0xf0==temp)	continue;
		
		temp_key=temp;
		delay_self(SCAN_REMOVE_SHAKE_TIME);	//
		temp=PORT_C8255;
		temp=temp&0xf0;
		if(0xf0==temp)	return 0;
		if(temp_key==temp)
		{
			temp=temp_key|(scan_data[i]&0x0f);
			j=LONG_KEY_TIME;
			while(1)
			{
				PORT_C8255=0x00;
				temp_key=PORT_C8255;
				temp_key=temp_key&0xf0;
				if(temp_key==0xf0)	break;
				if(j>0)
				{
					delay_display(1);
					j--;
				}
				else
				{
					b_long_press=1;
					break;
				}
			}


			for(i=1;i<17;i++)
			{
				if(scan_pad[i-1]==temp)
					return (b_long_press==0)?i:(i+32);
			}
		}
		else
			return 0;
	}
	return 0;
}
		
				
void delay_display(ulong x)
{
	for(;x>0;x--)
	seg7_display(digit);
}
//*******************************
void delay_self(uchar x)
{
	for(;x>0;x--);
}
//***************
//说明:本subroutine没有对7SEG LED进行初始化.
void seg7_display(uchar *x)
{
	uchar i;
//	cs138=0;
//	COMMAND8255=LED7SEG_SET0;
	for(i=0;i<4;i++)
	{
		PORT_B8255=bcd_code_num[x[i]];
		
//		delay(DISPLAY_NUM_TIME);	
		SEG7_COM=seg7com[i];
		delay_self(DISPLAY_NUM_TIME);
		SEG7_COM=0x00;
	}
}
/*-----------------------------
digit[]要先被定义过.
------------------------------*/
void pre_display(const uint x)	//change x to bcd code and transist to digit[]
{
	digit[0]=x/1000;
	digit[1]=(x%1000)/100;
	digit[2]=(x%100)/10;
	digit[3]=x%10;
}
/*------------------------------

------------------------------*/
//uchar expend_key_code(void)
//{
//	uchar temp0;
//	uchar temp1;
//	uchar i;
//	
//	temp0=scan_key();
//	for(i=EXPEND_KEY_SCAN_TIMES0;i>0;i--)
//	{
//		delay_display(EXPEND_KEY_DELAY_TIME0);
//		temp1=scan_key();
//		if(0==temp1)
//		{
//			if(b_loosen)	continue;
//			else
//			{
//				b_loosen=1;
//				continue;
//			}
//		}
//		else
//		{
//			if(temp1==temp0)
//			{
//				if(b_loosen)	break;
//				else			continue;
//			}
//			else
//				break;
//		}
//	}
//	if(!i&&!b_loosen)	return temp0+32;
//	if(i&&b_loosen)		return temp0+16;
//	return temp0;
//}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -