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

📄 drv_key.c

📁 Epson系列芯片开发的例子
💻 C
字号:
/********************************************************************************************************
 *													*
 *	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 );
unsigned char rucK5PortData;
unsigned char gucKeyCode;

void delay();

void vInitKey( void )
{
	//P2 setting, P20,P21, as IO ports
	*(volatile unsigned char *)0x402D8 &= 0x0FC;
	//P1 setting, P15,P16, as IO ports
	*(volatile unsigned char *)0x402D4 &= 0x9F;
	
	//P2 input_output selection(for IO ports only), P20, P21, output
	*(volatile unsigned char *)0x402DA |= 0x03;
	//P1 input_output selection(for IO ports only), P15,P16, output
	*(volatile unsigned char *)0x402D6 |= 0x60;
	
	// P20 = P21 ='L'
	*(volatile unsigned char *)0x402D9 &= 0x0FC;
	// P15 = P16 ='L'
	*(volatile unsigned char *)0x402D5 &= 0x9F;
	
	
	//[0x402c0] set K50, K51,K52,K53,K54=KEYI0,KEYI1,KEYI2,KEYI3 KEYI4
	*(volatile unsigned char *)IN_CFK5_ADDR &= 0xe0;	// select K5 function: K50, K51,K52,K53,K54
	//[0x402c9]
	*(volatile unsigned char *)IN_SEP_ADDR &= 0xe0;
	//[0x402ca]
	*(volatile unsigned char *)IN_SPPK_ADDR &= 0x0fc;	//set FPK0 interrupt input port K5
	//[0x402cc]
	*(volatile unsigned char *)IN_SCPK0_ADDR |= 0x1F;	//set K50-K54 input comparison register 0 
	//[0x402ce]
	*(volatile unsigned char *)IN_SMPK0_ADDR |= 0x1F;	//set K50-K54 interrupt mask enable
	//[0x40262]
	*(volatile unsigned char *)INT_PK0_PK1_ADDR &= 0x0f0;
	*(volatile unsigned char *)INT_PK0_PK1_ADDR |= INT_PRIL_LVL4;	//set Key input0 interruput level 4
	//[0x40280]
	*(volatile unsigned char *)INT_FP0_FK_ADDR |= 0x10;		// reset Key input0 interrupt flag
	//[0x40270]
	*(volatile unsigned char *)INT_EP0_EK_ADDR |= 0x10;		// enable Key input0 interrupt
	
	//[0x402c6]
//	*(volatile unsigned char *)IN_SPT0_SPT3_ADDR |= 0x55;	//select K50,K51,K52,K53,K54 input pin for port interrupt
//	*(volatile unsigned char *)IN_SPT0_SPT3_ADDR &= 0x55;
	//[0x402c7]
//	*(volatile unsigned char *)IN_SPT4_SPT7_ADDR |= 0x01;
//	*(volatile unsigned char *)IN_SPT4_SPT7_ADDR &= 0x0fd;
	//[0x402c8]
	//*(volatile unsigned char *)IN_SPP_ADDR &= 0x0e0;		//set FPT0-FPT4 high level triger
}

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");

  	//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;	// [0x402c1]
 	while (1)
 	{
 		delay();
 		if (rucK5PortData == (*(volatile unsigned char *)IN_K5D_ADDR & 0x1F))
 			break;
 		else
 			rucK5PortData = *(volatile unsigned char *)IN_K5D_ADDR & 0x1F;	// [0x402c1]
 	}
   	switch( rucK5PortData )
 	{
 		case 0x1E:
 			gucKeyCode = DOWNKEY;		//K50
 			break;
 		case 0x1D:
 			gucKeyCode = CANCELKEY;		//K51
 			break;
 		case 0x1B:
 			gucKeyCode = NO4KEY;		//K52
 			break;
 		case 0x17:
 			gucKeyCode = NO5KEY;		//K53
 			break;
 		case 0x0F:
 			gucKeyCode = NO6KEY;		//K54
 			break;
 		default:
 			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 (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 (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 = UPKEY;		//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;
	 	}
	}
	
 	//[0x40280]
	*(volatile unsigned char *)INT_FP0_FK_ADDR |= 0x10;		// reset Key input0 interrupt flag
	
	// P20 = P21 ='L'
	*(volatile unsigned char *)0x402D9 &= 0x0FC;
	// P15 = P16 ='L'
	*(volatile unsigned char *)0x402D5 &= 0x9F;

	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 + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -