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

📄 hl_key.c

📁 这是MPS430的FLASH存储器的汇编程序
💻 C
字号:
/*****************************************************************************\
文件名:key.c
编写者:czhang
描述:MSP430行列式键盘。适用于MSP430F149,其他型号的需要适当改变。
      行:P2.0~P2.3     列:P2.4~P2.7
      行端口接上拉电阻。行端口为输入状态,列端口输出0,当有键按下时,行端口
      产生下降沿,引发中断,判断按键值,关闭键盘中断,打开定时器A延时,防止抖动。
      时间到后,再次判断键值。
      判断键值的方法为:
      行端口被下拉为低电平的为按键的行值。
      判断列值时,逐个将列端口变为高电平,当行端口的输入值由低电平变为高电平时,
      此时变为高电平的列端口为按键的列值。
      将行值与列值组合即为键值。
      按键的排列如下(中间的数字为键值):
      P2.4	P2.5	P2.6	P2.7
      P2.0	0x11	0x21	0x41	0x81
      P2.1      0x12	0x22	0x42	0x82
      P2.2	0x14	0x24	0x44	0x84
      P2.3	0x18	0x28	0x48	0x88

版本:1.0	2004-5-10
\*****************************************************************************/
#include <MSP430x14x.h>
#include "hl_key.h"
#include "df_timera.h"

//选用端口定义
#define KEYDIR P2DIR
#define KEYIES P2IES
#define KEYIE P2IE
#define KEYIN P2IN
#define KEYOUT P2OUT
#define KEYIFG P2IFG

//定义键盘管脚
#define KEY_H0 BIT0
#define KEY_H1 BIT1
#define KEY_H2 BIT2
#define KEY_H3 BIT3
#define KEY_L0 BIT4
#define KEY_L1 BIT5
#define KEY_L2 BIT6
#define KEY_L3 BIT7
#define KEY_MOD_H (KEY_H0+KEY_H1+KEY_H2+KEY_H3) //行端口的模
#define KEY_MOD_L (KEY_L0+KEY_L1+KEY_L2+KEY_L3) //列段口的模
#define KEY_LIE  4 										//列数

unsigned char KeyZhi=KEY_NONE;  						//经过确认的键值
unsigned char KeyCnt;									//某次连续按键的次数
unsigned char KeyDown=KEY_NONE; 						//被按下的键

#define KEY_TIME 50    		//连续按键经过此时间,按键次数加1
unsigned char KeyTime; 		//记录连续按键的时间
/*****************************************************************************
初始化
*****************************************************************************/
void InitKey()
{
	KEYDIR &= ~KEY_MOD_H;   //设置行端口为输入
	KEYDIR |= KEY_MOD_L;    //设置列端口为输出
	KEYOUT &= ~KEY_MOD_L;	//设置列端口输出低电平
	KEYIES |= KEY_MOD_H;    //设置行端口下降沿中断
	KEYIE |= KEY_MOD_H; 	//打开行端口中断
	KeyCnt=0;					//按键次数请零
}

/*****************************************************************************
打开或者关闭键盘中断
sw: 0:关闭   100:打开
*****************************************************************************/
void GoKey(unsigned char sw)
{
	if(sw==0)
		KEYIE &= ~KEY_MOD_H; //关闭端口中断
	else
		KEYIE |= KEY_MOD_H;  //打开端口中断
}

/*****************************************************************************
获得键值和连续按下的键的有效次数,并清除记录的键值和有效次数
key_cnt:返回某一键被连续按下的有效次数
返回值:按下的有效的键的键值
*****************************************************************************/
unsigned char GeiKeyZhi(unsigned char *key_cnt)
{
	unsigned char q0;
	q0=KeyZhi;
	KeyZhi=KEY_NONE;   		//清除键值
	*key_cnt =KeyCnt;
	KeyCnt=0;
	return q0;
}

/*****************************************************************************
判断按键的有效性
*****************************************************************************/
void IsKey()
{
	unsigned char key;

	key=ReadKey();
	if(key==KEY_NONE)
	{
		//没有键按下
		KeyDown=KEY_NONE;
		GotimeDfA(0);      	//关闭定时器
		GoKey(100);        	//打开键盘中断
	}
	else
	{
		if(KeyTime==0)  	//延时时间到
		{
			KeyTime=KEY_TIME;
			if(key==KeyDown)
			{
				KeyCnt++;
				KeyZhi=key;
			}
			else
			{
				KeyDown=KEY_NONE;
				GotimeDfA(0);   //关闭定时器
				GoKey(100);   	//打开键盘中断
			}
		}
		else
			KeyTime--;
	}
}

/*****************************************************************************
端口1中断函数
多中断中断源:P1IFG.0~P1IFG7,只响应行端口的中断
进入中断后应首先判断中断源,退出中断前应清除中断标志,否则将再次引发中断
******************************************************************************/
#pragma vector=PORT2_VECTOR
__interrupt void Port2()
{
	if((KEYIFG&KEY_MOD_H)!=0) //判断是否是按键引发的中断
	{
		KeyDown=ReadKey();
		if(KeyDown!=KEY_NONE)
		{
		  GoKey(0);		//关闭键盘中断
        KeyTime=0;
        KeyCnt=0;
        GotimeDfA(100);			//打开定时器A
       }
	}
	KEYIFG=0;  			//清除中断标志
}

/*****************************************************************************
行列式键盘读取键值,判断哪一个键被按下了
返回值:读取的键值
******************************************************************************/
unsigned char ReadKey()
{
	unsigned char key=0,hang,q0=0,q1;
	unsigned char lie=(KEY_MOD_L&(~KEY_L0))+KEY_MOD_H; //判断按键的列的掩码

	//确定按键的行
	hang= (~KEYIN)&KEY_MOD_H;  //读入的数据取反,然后屏蔽不需要的位
	if(hang!= 0)
	{
		//确定按键的列
		for(q0=0;q0<KEY_LIE-1;q0++)
		{
		   KEYOUT =0xFF;
			KEYOUT &=lie;   	//某一列端口输出低电平,其他输出高电平
			q1=KEYIN&KEY_MOD_H;
			if(( q1&hang)==0)
			{
				break;   	//确定了列值
			}
			lie <<=1 ;
		}
		if(q0!=KEY_LIE)
		{
			key=hang+((~lie)&KEY_MOD_L);  //键值为行值+列值
		}
		else
			key=KEY_NONE;
	}
	else
		key=KEY_NONE;
	KEYOUT &= ~KEY_MOD_L;		//设置列端口输出低电平
	return key;
}

⌨️ 快捷键说明

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