drv_key.c

来自「在EPSON开发平台上实现键盘控制 并通过外部LED显示出来」· C语言 代码 · 共 215 行

C
215
字号
/********************************************************************************************************
 *													*
 *	Copyright (C) SEIKO EPSON CORP. 2002								*
 *													*
 *	File name: Drv_key.c										*
 *	  This is key matrix driver for Star.								*
 *													*
 *													*
 *	Revision history										*
 *		2002.05.30	Andrew Yin	Start.							*
 *		2002.09.29	Andrew Yin	Modify( Change the P26, P27 to P15, P16 for KeyMatrix).	*
 *													*
 *******************************************************************************************************/

#include "common.h"
#include "int.h"
#include "io.h"
#include "main.h"

void vInitKey( void );
void vIntKey( void );
//void delay();

unsigned char rucK5PortData;
unsigned char gucKeyCode =0;//键盘缓冲。当键被按下,该键码被保存在键盘缓冲区中。目前该缓冲区大小为一个,所以只能保存一个键。


void vInitKey( void )//初始化键盘,设置键盘的触发方式和条件(比较寄存器和掩码寄存器),中断优先级(目前为4),最后打开键盘中断。
{
	*(volatile unsigned char *)0x402D8 &= 0x0FC;// p20,p21功能设定为io
	
	*(volatile unsigned char *)0x402D4 &= 0x9F; // p15,p16功能设定为io
	
	*(volatile unsigned char *)0x402DA |= 0x03; // p20,p21方向设定为输出
	
	*(volatile unsigned char *)0x402D6 |= 0x60; // p15,p16方向设定为输出
	
	*(volatile unsigned char *)0x402D9 &= 0x0FC;// P20 = P21 ='L'
	
	*(volatile unsigned char *)0x402D5 &= 0x9F; // P15 = P16 ='L'
	
	//[0x402ca]
	*(volatile unsigned char *)IN_SPPK_ADDR &= 0x0fc;	//中断源为K50, K51,K52,K53,K54
	//[0x402cc]
	*(volatile unsigned char *)IN_SCPK0_ADDR |= 0x1F;	//set K50-K54 下降沿中断
	//[0x402ce]
	*(volatile unsigned char *)IN_SMPK0_ADDR |= 0x1F;	//set K50-K54 中断使能
	//[0x40262]
	*(volatile unsigned char *)INT_PK0_PK1_ADDR &= 0x0f8;
	*(volatile unsigned char *)INT_PK0_PK1_ADDR |= INT_PRIL_LVL4;	//set Key input0 interruput level 4
	//[0x40280]
	*(volatile unsigned char *)INT_FP0_FK_ADDR &= 0xef;		// 清除键盘中断标志
	//[0x40270]
	*(volatile unsigned char *)INT_EP0_EK_ADDR |= 0x10;		// 使能键盘总中断
	
}

void vIntKey( void )//键盘中断服务程序。将按键保存到键盘缓冲中,由用户读取。并且清除键盘中断标志。
{
	asm("pushn	%r15");			// save r1,r2...r15
	asm("ld.w	%r9,%psr");		// EI,enable interrupt 
	asm("or 	%r9,0x10");
	asm("ld.w	%psr,%r9");
  *(volatile unsigned char *)INT_EP0_EK_ADDR &= ~0x10;//关闭键盘中断
  
  	//check No 1,4,7,Menu,*   set P15 = 0, other = 1
	*(volatile unsigned char *)IO_P2D_ADDR |= 0x03;	// set P15 = 0
	*(volatile unsigned char *)IO_P1D_ADDR &= 0x0DF;
	*(volatile unsigned char *)IO_P1D_ADDR |= 0x40;
  	
  	rucK5PortData = *(volatile unsigned char *)IN_K5D_ADDR & 0x1F;
 	while (1)                                      //去抖动
 	{

 		if (rucK5PortData == (*(volatile unsigned char *)IN_K5D_ADDR & 0x1F))
 			break;
 		else
 			rucK5PortData = *(volatile unsigned char *)IN_K5D_ADDR & 0x1F;	// [0x402c1]
 	}

 	if(rucK5PortData == 0x17 )
 		gucKeyCode = 35;
 	else 
 		gucKeyCode = NULL;
	
	if (gucKeyCode == NULL)
	{
		//check No 2,5,8,0,Cancel,   set P21 = 0, other = 1
		*(volatile unsigned char *)IO_P2D_ADDR &= 0xfd;	// set P21 = 0
		*(volatile unsigned char *)IO_P2D_ADDR |= 0x01;
		*(volatile unsigned char *)IO_P1D_ADDR |= 0x60;
			 	
	 	rucK5PortData = *(volatile unsigned char *)IN_K5D_ADDR & 0x1F;	// [0x402c1]
	  /*
	   	switch( rucK5PortData )
	 	{
	 		case 0x1E:
	 			gucKeyCode = RIGHTKEY;		//K50
	 			break;
	 		case 0x1D:
	 			gucKeyCode = MENUKEY;		//K51
	 			break;
	 		case 0x1B:
	 			gucKeyCode = NO7KEY;		//K52
	 			break;
	 		case 0x17:
	 			gucKeyCode = NO8KEY;		//K53
	 			break;
	 		case 0x0F:
	 			gucKeyCode = NO9KEY;		//K54
	 			break;
	 		default:
	 			gucKeyCode = NULL;
	 	}
	 	*/
	 	if(rucK5PortData == 0x1E )
 		  gucKeyCode = 29;
 		else 
 			gucKeyCode = NULL;
	}
	
	if (gucKeyCode == NULL)
	{
		//check No 3,6,9,#,ONOFF,   set P20 = 0, other = 1
		*(volatile unsigned char *)IO_P2D_ADDR &= 0xfe;	// set P20 = 0
		*(volatile unsigned char *)IO_P2D_ADDR |= 0x02;
		*(volatile unsigned char *)IO_P1D_ADDR |= 0x60;
	 	
	 	rucK5PortData = *(volatile unsigned char *)IN_K5D_ADDR & 0x1F;	// [0x402c1]
	   /*
	   	switch( rucK5PortData )
	 	{
	 		case 0x1E:
	 			gucKeyCode = LEFTKEY;		//K50
	 			break;
	 		case 0x1D:
	 			gucKeyCode = CALLKEY;		//K51
	 			break;
	 		case 0x1B:
	 			gucKeyCode = ASTERISKKEY;		//K52
	 			break;
	 		case 0x17:
	 			gucKeyCode = NO0KEY;		//K53
	 			break;
	 		case 0x0F:
	 			gucKeyCode = SHARPKEY;		//K54
	 			break;
	 		default:
	 			gucKeyCode = NULL;
	 	}
	 	*/
	if(rucK5PortData == 0x17 )
 		gucKeyCode = 37;
 	else 
 		gucKeyCode = NULL;
	 	
	}
	
	if (gucKeyCode == NULL)
	{
		//check Call,Down,Right,Left,Done,   set P16 = 0, other = 1
		*(volatile unsigned char *)IO_P2D_ADDR |= 0x03;	// set P16 = 0
		*(volatile unsigned char *)IO_P1D_ADDR &= 0x0BF;
		*(volatile unsigned char *)IO_P1D_ADDR |= 0x20;
	 	
	 	rucK5PortData = *(volatile unsigned char *)IN_K5D_ADDR & 0x1F;	//	 [0x402c1]
	  /*
	   	switch( rucK5PortData )
	 	{
	 		case 0x1E:
	 			gucKeyCode = DONEKEY;		//K50
	 			break;
	 		case 0x1D:
	 			gucKeyCode = ONOFFKEY;		//K51
	 			break;
	 		case 0x1B:
	 			gucKeyCode = NO1KEY;		//K52
	 			break;
	 		case 0x17:
	 			gucKeyCode = NO2KEY;		//K53
	 			break;
	 		case 0x0F:
	 			gucKeyCode = NO3KEY;		//K54
	 			break;
	 		default:
	 			gucKeyCode = NULL;
	 	}
	 	*/
	if(rucK5PortData == 0x0F )
 		gucKeyCode = 28;
 	else 
 		gucKeyCode = NULL;
	}
		
	*(volatile unsigned char *)0x402D9 &= 0x0FC; // P20 = P21 ='L'
	
	*(volatile unsigned char *)0x402D5 &= 0x9F;  // P15 = P16 ='L'
	
	*(volatile unsigned char *)INT_FP0_FK_ADDR &= 0xef;		// 清除键盘中断标志
	//[0x40270]
	*(volatile unsigned char *)INT_EP0_EK_ADDR |= 0x10;		// 使能键盘中断

	asm("popn	%r15");			// restore r1,r2...r15
	asm("reti");

}

/*
void delay()
{
	int i,j;
	for (i = 0;i<20000;i++)
		j += (i >1000)?i/2 *3 +10: i;
}
*/

⌨️ 快捷键说明

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