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

📄 key_board.c

📁 键盘操作 键盘扫描 用的是单片机mega16
💻 C
字号:
/**************************************
** Filename: key_board.c
** Describe: 矩阵键盘程序
** Author : 古欣 www.avrvi.com
** Time  :   2007-2-15
**************************************/

#include "..\config.h"

const uint8 key_board_table[]={0,1,2,3,
	  						   4,5,6,7,
							   8,9,10,11,
							   12,13,14,15};
//键值可以任意设定,请不要使用0xFF
//const uint8 key_board_table[]={0,1,2,3,4,5,6,7,8,9,10,11,'A','B','C','D'};

//如果使用中断
#if KEY_USE_INT==1
	volatile uint8 KEY_FLAG=0,key=0xff;						 //加 volatile 允许在中断中修改
	#pragma interrupt_handler int_isr:IV_number
	void int_isr(void)
	{
	 KEY_FLAG = 1; //中断中标记已经产生按键中断,由于使用低电平触发方式,不用再考虑防抖问题
	 key = key_board_get_key();				//读取键值
	}
#endif

/***********************************************************
** 函数名称: void key_board_int(void)
** 功能描述: 中断脚初始化
** 输 入: 无
** 输出   : 无
** 全局变量: 无
** 调用模块: 
** 说明:输入,并使能内部上拉
** 注意:
**********************************************************/
void key_int_init(void)
{
 KEY_INT_DDR &=~ (1<<KEY_INT);
 KEY_INT_RORT |= (1<<KEY_INT);
 GICR  |= (1<<INT_BIT);		  //中断允许位,如INT0
}

/***********************************************************
** 函数名称: void key_board_int(void)
** 功能描述: 矩阵键盘扫描初始化
** 输 入: 无
** 输出   : 无
** 全局变量: 无
** 调用模块: 
** 说明:默认初始化为行输出低,列输入,并使能内部上拉
** 注意:
**********************************************************/

void key_board_int(void)
{
 KEY_DDR_ROW   |=  KEY_ROW_ALL;							   //行输出,低
 KEY_PORT_ROW  &=~ KEY_ROW_ALL;
 KEY_DDR_COL   &=~ KEY_COL_ALL;							   //列输入,并使能内部上拉
 KEY_PORT_COL  |=  KEY_COL_ALL;
 #if BEEP_EN ==1
   BEEP_DDR |= (1<<BEEP_BIT);
   BEEP_PORT &=~ (1<<BEEP_BIT);
 #endif
}

/***********************************************************
** 函数名称: uint8 key_board_get_key(void)
** 功能描述: 矩阵键盘扫描并读取键值
** 输 入: 无
** 输出   : 按键的键值,在key_board_table[]定义,无按键返回0xFF
** 全局变量: 无
** 调用模块: void key_board_int(void)
** 说明:通过预定义#define WAIT_KEY_UP设置等待按键抬起(1),不等待按键抬起(0)
** 注意:如果不等待按键抬起,很容易产生粘贴键,注意在程序中处理。
**********************************************************/

uint8 key_board_get_key(void)
{
  uint8 key_i=0,temp_key=0;
  if(HAVE_KEY_DOWN)
  {
   #if KEY_USE_INT==0
   Delay100us(1);   //使用中断进行扫描不加延时
   #endif
   if(HAVE_KEY_DOWN)
   {
   
 #if BEEP_EN ==1
   BEEP_PORT |= (1<<BEEP_BIT);							   //蜂鸣器响
 #endif
 
    temp_key = ( KEY_COL_ALL & KEY_PIN_COL );			   //读取键值
	
	switch(temp_key)
	{
	 case (KEY_COL_ALL&(~(1<<KEY_COL_0))):
	       key_i = 0;
		   break;
	 case (KEY_COL_ALL&(~(1<<KEY_COL_1))):
	 	   key_i = 1;
		   break;
	 case (KEY_COL_ALL&(~(1<<KEY_COL_2))):
	       key_i = 2;
		   break;
	 case (KEY_COL_ALL&(~(1<<KEY_COL_3))):
	       key_i = 3;
		   break;
		   
	// 扩展
	#if PER_COL>4
	case (KEY_COL_ALL&(~(1<<KEY_COL_4))):
	       key_i = 4;
		   break;
    #endif
	#if PER_COL>5
	case (KEY_COL_ALL&(~(1<<KEY_COL_5))):
	       key_i = 5;
		   break;
    #endif
	#if PER_COL>6
	case (KEY_COL_ALL&(~(1<<KEY_COL_6))):
	       key_i = 6;
		   break;
    #endif
	#if PER_COL>7
	case (KEY_COL_ALL&(~(1<<KEY_COL_7))):
	       key_i = 7;
		   break;
    #endif
	
	default:break;
    }//end switch
   
   //翻转,与初始化恰好相反
    KEY_DDR_ROW   &=~  KEY_ROW_ALL;							   //行输入,并使能内部上拉
	KEY_PORT_ROW  |=  KEY_ROW_ALL;
	KEY_DDR_COL   |=  KEY_COL_ALL;							   //列输出,低
    KEY_PORT_COL  &=~  KEY_COL_ALL;
	
    NOP();		  	   			   							   //等待啊你家安稳定,此步骤不能少
   
    temp_key = ( KEY_ROW_ALL & KEY_PIN_ROW );			   	   //读取翻转后键值
	
	switch(temp_key)
	{
	 case (KEY_ROW_ALL&(~(1<<KEY_ROW_0))):
	       // key_i += 0; //加零,直接省掉
		   break;
	 case (KEY_ROW_ALL&(~(1<<KEY_ROW_1))):
	 	   key_i += PER_POW;
		   break;
	 case (KEY_ROW_ALL&(~(1<<KEY_ROW_2))):
	       key_i += PER_POW*2;
		   break;
	 case (KEY_ROW_ALL&(~(1<<KEY_ROW_3))):
	       key_i += PER_POW*3;
		   break;
		   
	// 扩展 PER_POW 最大值为8
	#if PER_POW>4
	case (KEY_ROW_ALL&(~(1<<KEY_ROW_4))):
	       key_i += PER_POW*4;
		   break;
	#endif
	#if PER_POW>5
	case (KEY_ROW_ALL&(~(1<<KEY_ROW_5))):
	       key_i += PER_POW*5;
		   break;
	#endif
	#if PER_POW>6
	case (KEY_ROW_ALL&(~(1<<KEY_ROW_6))):
	       key_i += PER_POW*6;
		   break;
	#endif
	#if PER_POW>7
	case (KEY_ROW_ALL&(~(1<<KEY_ROW_7))):
	       key_i += PER_POW*7;
		   break;
	#endif
	
	default:break;
    }//end switch

	//检测按键抬起
	#if WAIT_KEY_UP==1
 		 while((KEY_ROW_ALL & KEY_PIN_ROW)!=KEY_ROW_ALL)
  		 ;
	#endif
	
	key_board_int(); 		  							//恢复键盘IO口的初时状态
	
   }//end if have key
   return key_board_table[key_i];						//返回键值
  }
  else
  return 0xFF;
}

⌨️ 快捷键说明

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