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

📄 key.c

📁 使用Microchip公司16F648实现4*6键盘程序. 在PICC环境下编译通过,包含RS485通讯. 代码完整,可供参考.
💻 C
字号:
// key module.
#include  "pic16f62xa.h"
#include  "pic.h"
#include  "typedefine.h"
#include  "extern.h"
	
bank2 volatile KeyInputStruct KeyInput[6];
bank2 static uchar KeyValueBuf;
bank2 static uchar KeyValueBufBuf;
const uchar  KeyValMap[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,
						13,14,15,16,17,18,19,20,21,22,23,24,
						65,66,67,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
	
//采集端口值
void key_scan(void)
{
	char bufportb,bufporta;
	bufportb = PORTB;
	bufporta = PORTA;
	TRISA |= 0b00011111;
	TRISB |= 0b11111001;      //对应一条.
	NOP();
	NOP();
    
//	delay(10);
//---------------------=================
	TRISB0 = 0;
	NOP();
	NOP();
    RB0 = 0;
    NOP();
	NOP();
	NOP();
    KeyInput[0].allbits = PORTA;
//    KeyInput[0].allbits = 0b11111110;  //#`````0912 晚
    KeyInput[0].allbits |= 0xf0; 
    TRISB0 = 1;
 	KeyInput[0].allbits ^= 0xff; 
    
	TRISB3 = 0;
	NOP();	
	NOP();
    RB3 = 0;
    NOP();
	NOP();
	NOP();
    KeyInput[1].allbits =  PORTA;
//    	KeyInput[1].allbits = 0b11111111;  //#`````0912 晚
    KeyInput[1].allbits |= 0xf0; 
    TRISB3 = 1;
 	KeyInput[1].allbits ^= 0xff; 
    
	TRISB4 = 0;
	NOP();
	NOP();    
	RB4 = 0;
    NOP();
	NOP();
	NOP();
    KeyInput[2].allbits = PORTA;   
//     KeyInput[2].allbits = 0b11111110;  //#`````0912 晚
    KeyInput[2].allbits |= 0xf0; 
	TRISB4 = 1;
 	KeyInput[2].allbits ^= 0xff; 
    
	TRISB5 = 0;
	NOP();
	NOP();
    RB5 = 0;
    NOP();
	NOP();
	NOP();
    KeyInput[3].allbits = PORTA;
//    	KeyInput[3].allbits = 0b11111111;  //#`````0912 晚
    KeyInput[3].allbits |= 0xf0;
    TRISB5 = 1;
 	KeyInput[3].allbits ^= 0xff;
    
	TRISB6 = 0;
	NOP();
	NOP();
    RB6 = 0;
	NOP();
	NOP();
	NOP();
    KeyInput[4].allbits = PORTA;
//     KeyInput[4].allbits = 0b11111111;  //#`````0912 晚
    KeyInput[4].allbits |= 0xf0;
    TRISB6 = 1;
  	KeyInput[4].allbits ^= 0xff;
	
	TRISB7 = 0;
	NOP();
	NOP();
    RB7 = 0;
    NOP();
	NOP();
	NOP();
    KeyInput[5].allbits = PORTA;
//   	KeyInput[5].allbits = 0b11111111;  //#`````0912 晚
    KeyInput[5].allbits |= 0xf0;
    TRISB7 = 1;
 	KeyInput[5].allbits ^= 0xff;
	
	
//一次扫描结束.
// come back pin's status.
	TRISA &= 0B11100000;
	NOP();
	NOP();
	PORTA = bufporta;
	
	TRISB &= 0B00000110;
	NOP();
	NOP();
	PORTB = bufportb;
//------------------
// 1为无键, 0为有键; 
// 首先,排值. 把buf的值求反.
//-----读出键值-----
}//void key_scan(void)


//对采集到的端口值进行排列   
KEYVALUESTRUCT RangeKeyValue(void)
{
	KEYBITVALUESTRUCT	KeyBitValueStruct;
	KEYVALUESTRUCT   KeyValueStructTemp; 	
	uchar icount=0,ArrCou=0,KeyUnitCou=0,tranbase=0,keyvalue_a;
		
	KeyBitValueStruct.allbits = 0;
	KeyValueStructTemp.allbits = 0;
	while(++icount <= 6)
	{
		if(KeyInput[ArrCou].bits.keyscanbit0)
		{ 
			keyvalue_a = icount;
			KeyUnitCou++;
		//置位结构体KeyValueStructTemp.    
        	KeyBitValueStruct.allbits |= 1 << (keyvalue_a - 1);
		}

		if(KeyInput[ArrCou].bits.keyscanbit1)
		{
			keyvalue_a = icount+6;
			KeyUnitCou++;
			KeyBitValueStruct.allbits |= 1 << (keyvalue_a - 1);
		}

		if(KeyInput[ArrCou].bits.keyscanbit2)
		{
			keyvalue_a = icount+12;
			KeyUnitCou++;
			KeyBitValueStruct.allbits |= 1 << (keyvalue_a - 1);
		}

		if(KeyInput[ArrCou].bits.keyscanbit3)
		{
			keyvalue_a = icount+18;
			KeyUnitCou++;
			KeyBitValueStruct.allbits |= 1 << (keyvalue_a - 1);
		}
		ArrCou++;
	}

//	*p_keyvalue = icount;
//	KeyValueStructTemp.bits.ScanKeyValueResultTag = KeyUnitCou;
	if(0 == KeyUnitCou)      	//KeyUnitCou为0表示没有键被按下.
	{
		KeyValueStructTemp.allbits = 0;
	}
	else if(1 == KeyUnitCou)    //KeyUnitCou为1表示有单键被按下.
	{
		KeyValueStructTemp.bits.OneKey = keyvalue_a;
		KeyValueStructTemp.bits.Status = 1;
	}
	else if(2 <= KeyUnitCou)    //KeyUnitCou大于2表示有多个键被按下.
	{
		//复合键判断.
		KeyValueStructTemp.bits.Status = 3; 
		if(KeyBitValueStruct.bits.KeyValue_1)
		{
			if(KeyBitValueStruct.bits.KeyValue_2)
			{
				if(KeyBitValueStruct.bits.KeyValue_4)
				{

					KeyValueStructTemp.bits.CompKey = 1;      //值.
					KeyValueStructTemp.bits.Status = 2;		  //状态. 
					return KeyValueStructTemp;
				}
			}
		}

		if(KeyBitValueStruct.bits.KeyValue_1)
		{
			if(KeyBitValueStruct.bits.KeyValue_2)
			{
				if(KeyBitValueStruct.bits.KeyValue_3)
				{
					
					KeyValueStructTemp.bits.CompKey = 2;      //值.
					KeyValueStructTemp.bits.Status = 2;		  //状态. 
					return KeyValueStructTemp;
				}
			}
		}

		if(KeyBitValueStruct.bits.KeyValue_1)
		{
			if(KeyBitValueStruct.bits.KeyValue_7)
			{
				if(KeyBitValueStruct.bits.KeyValue_13)
				{
					KeyValueStructTemp.bits.CompKey = 3;      //值.
					KeyValueStructTemp.bits.Status = 2;		  //状态. 
					return KeyValueStructTemp;
				}
			}
		}
	} 
	return KeyValueStructTemp;
}
	
	
//2ms once.
//save key value into array buffer register. 
void KeyValueAffFun(void)             
{
    bank2 static KEYVALUESTRUCT KeyValueTempBuf[3]={0,0,0};      
    bank2 static uchar KeyScanCou;      
    
	KeyValue = 0;				 //           
    key_scan(); 			     //扫描值            
    KeyValueTempBuf[KeyScanCou++] = RangeKeyValue();     
    
	if(KeyScanCou < 3)			 //	if(KeyScanCou >=3)   
	{
	  return;                
	}
  
	KeyScanCou = 0;              
		
	//判断键值处理
	if(0 == ((KeyValueTempBuf[0].allbits == KeyValueTempBuf[1].allbits) &&
	           (KeyValueTempBuf[0].allbits == KeyValueTempBuf[2].allbits)))
	{ 
		KeyValueTempBuf[0].allbits = 0;		
		KeyValueTempBuf[1].allbits = 0;		
		KeyValueTempBuf[2].allbits = 0;		
		 return;       
	}
    //错误按键处理
//	if(KeyValueTempBuf[2].bits.Status == 3)
//	{
//		KeyValueTempBuf[2].bits.Status = 0;
//		return;
//	}
	
	//无论什么键,有效的才会处理.				
    //判断状态.   !!!考虑使用全局结构体变量 代替 KeyValue 来传递.  
	//在这里更改存值结构. 因为有一个mapped关系.   
	if(KeyValueTempBuf[2].bits.Status == 0)
	{
		KeyValue = 0;
		KeyValue |= 0b10000000;
		KeyValueTempBuf[0].allbits = 0;		
		KeyValueTempBuf[1].allbits = 0;		
		KeyValueTempBuf[2].allbits = 0;		
	}                     
	else if(KeyValueTempBuf[2].bits.Status == 1) 
	{
	   KeyValue = KeyValueTempBuf[2].bits.OneKey;	
	   KeyValue |= 0b10000000;
		KeyValueTempBuf[0].allbits = 0;		
		KeyValueTempBuf[1].allbits = 0;		
		KeyValueTempBuf[2].allbits = 0;		
	}
	else if(KeyValueTempBuf[2].bits.Status == 2)
	{
	    KeyValue = KeyValueTempBuf[2].bits.CompKey + 24;	
		KeyValue |= 0b10000000;
		KeyValueTempBuf[0].allbits = 0;		
		KeyValueTempBuf[1].allbits = 0;		
		KeyValueTempBuf[2].allbits = 0;		
	}
	else if(KeyValueTempBuf[2].bits.Status == 3)  
	{
		KeyValue = 0;
		KeyValueTempBuf[0].allbits = 0;		
		KeyValueTempBuf[1].allbits = 0;		
		KeyValueTempBuf[2].allbits = 0;		
	}			
	else NOP();		
	
	
}



//8ms once.
//确定一次键值.
//并判断置位四个功能标记.

//修改为等键松开处理.
void Keybit_Manage(void)
{
 	static uchar KeyValueBufMap;
	static uchar KeyValueZeroTag;
//	bank2 static uchar KeyValueBufBuf;
	char ValueTemp_a;
		
	KeyValueBuf = 0;
// 	Key.allbits = 0x00; 

	KeyValueBuf = KeyValue;

	KeyValue = 0;
	
	//判断bit7. 为0返回.
	if( (KeyValueBuf&0b10000000)==0 ) 
	   return;	
	
	KeyValueBuf -= 128;	 
	
 	KeyValueBufMap = KeyValMap[KeyValueBuf];   //mapped.  
	KeyValueBuf = 0;
//	if(KeyValueBuf != 0)
//	   LedShowLink = KeyValueBuf;
//	复合键. 做长按键判断.
//	待处理的复合键值由自己设定.
	
//  判断
// 	if( (KeyValueBuf&0b01000000)==128 )
// 	{
// 		Key.bits.LongKeyCouTag = 1;     //标记2s延迟计时flag.
// 	}
// 	else
// 	{
// 		Key.bits.LongKeyCouTag = 0;
// 	}


//---------------------------------
	if (KeyValueBufMap == 0) 
	{
		KeyValueZeroTag = 0xff;
	}
	
 	if (KeyValueBufMap == 0)
 		return;
		
	if (KeyValueZeroTag == 0)
		return;
	KeyValueZeroTag = 0;
//---------------------------------



	if(KeyValueBufMap != 0)
	{
		KeyValueBufBuf = KeyValueBufMap;
	}
	else
	{
		if(KeyValueBufBuf==0)  //判断buf中是否有数据
		{
			KeyValueBufBuf = KeyValueBufMap;
			return;
		} 	
		else
		{
			NOP();
		}
	}



//单键值
	if((KeyValueBufBuf&0b01000000)==0)
	{
		Key.bits.UnitaryKey = 1;
	}
	else
	{
		Key.bits.UnitaryKey = 0;
	}

//	if(twoSecCou>=2000)
//	{
//		twoSecCou = 0;
//		Key.bits.MultiKey = 1;          //置位长键标记.
//	}

//对于复合键的处理.
//一次按键触发一个功能标记.
	if( KeyValueBufBuf==65 )
	{
		Key.bits.MultiKeyOne = 1;
	}

//两次按键触发一个功能标记.    tag_a 占一个bit   tag_b 占三个bit.
	if( KeyValueBufBuf==66 )
	{
		if(Key.bits.MultiKeyTwoCouTag)
		{
		    Key.bits.MultiKeyTwo = 1;   //置位功能标记.
			twoSecCou = 0;
			Key.bits.MultiKeyTwoCouTag = 0;
		}
		else
		{
			Key.bits.MultiKeyTwoCouTag = 1;
 		}
	}

//四次按键触发一个功能标记.
	if(KeyValueBufBuf==67)
	{
		if(Key.bits.MultiKeyThreeCouTag != 0)
		{
			Key.bits.MultiKeyThreeCouTag++ ;
			if(Key.bits.MultiKeyThreeCouTag >= 3)
			{
				Key.bits.MultiKeyThree = 1;
				oneSecCou = 0;
				Key.bits.MultiKeyThreeCouTag = 0;
			}
		}
		else
		{
			Key.bits.MultiKeyThreeCouTag = 1;
		}
	}

}



//9ms once.
//  此函数中,对 Keybit_Manage()中置位的标记转化为
//   此按键定义的功能.也是想对应的其它模块接口标记.
//    舍弃Keyshift.bits.UnitaryKey这种取反的标记判断下降沿方法. 
void Key_Manage(void)
{
//	if(Key.bits.UnitaryKey)
//	{
//		if(Keyshift.bits.UnitaryKey)
//		{
//			Keyshift.bits.UnitaryKey = 0;
////			if(KeyValueBuf != 0)
////			 LedShowLink = KeyValueBuf;
//		}
//	}
//	else
//	{
//		Keyshift.bits.UnitaryKey = 1;
//	}

// 修改	
//	if(Key.bits.MultiKey)
//	{
//		if(Keyshift.bits.MultiKey)
//		{
//			Keyshift.bits.MultiKey = 0;
////			if(KeyValueBuf != 0)
////			 LedShowLink = KeyValueBuf;
//		}
//	}
//	else
//	{
//		Keyshift.bits.MultiKey = 1;
//	}
	
	if(Key.bits.UnitaryKey)
	{
		Key.bits.UnitaryKey = 0;  
		UartStruct.bits.singleKeyTag = 1;  	//置位 Uart.bits.singleKeyTag
	      if(KeyValueBufBuf != 0) 
			LedShowLink = KeyValueBufBuf;
				Key_V =	(uint)	KeyValueBufBuf;
	}
	
	if(Key.bits.MultiKeyOne)
	{
		Key.bits.MultiKeyOne = 0;
		     LedShowLink = 165;
	}
	
	if(Key.bits.MultiKeyTwo)
	{
		Key.bits.MultiKeyTwo = 0;
		    LedShowLink = 166;
	}
	
	if(Key.bits.MultiKeyThree)
	{
		Key.bits.MultiKeyThree = 0;
			LedShowLink = 167;
	}
	
}




⌨️ 快捷键说明

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