You are on page 1of 13

Application Note : 4 X 4 Key Matrix

AT91SAM7SXXX를 이용한 4 X4 KEY MATRIX :


4X4 KEY MATRIX를 구현하기 위해서는 8개의 INPUT/OUTPUT I/O
포트가 필요합니다.

1. 구성사진

PROCHILD
1
Application Note : 4 X 4 Key Matrix

2. I/O SETTING
아래의 표와 같이 포트를 설정해 주시고 COLUMNS 으로 설정된 부
분은 PULL UP REGISTER를 셋팅하여 저항을 사용하지 않고 사용할 수
있습니다.
PIO14 ROWS 0 OUTPUT PIO16 COLUMNS 0 INPUT/PULL UP
PIO15 ROWS 1 OUTPUT PIO20 COLUMNS 1 INPUT/PULL UP
PIO19 ROWS 2 OUTPUT PIO22 COLUMNS 2 INPUT/PULL UP
PIO21 ROWS 3 OUTPUT PIO23 COLUMNS 3 INPUT/PULL UP
표1. 포트설정
3. FLOW CHART

KEY SCAN()
INITIALIZATION()

ROWS 0번째 핀을 LOW


ROWS 1,2,3번째 핀 HIGH
KEYSCAN()

COLUMNS 핀을 읽어온다.

ROWS 1번째 핀을 LOW


TIMER0 INTERRUPT
ROWS 0,2,3번째 핀 HIGH

COLUMNS 핀을 읽어온다.
40msCOUNT증가.

COUNT>5
눌린키가있나?

모든 변수값 CLEAR 눌린키값을 UART로 PC에 전송

END END

PROCHILD
2
Application Note : 4 X 4 Key Matrix

4.Software

keyscan.c

#include "keyscan.h"

#include "Board.h"

//*----------------------------------------------------------------------------

//* File Name : keyscan.c

//* Object : keyscan menu

//*----------------------------------------------------------------------------

unsigned char Keytime,Keychange;

unsigned char Old_Key,NewKey,Diff_key;

unsigned int Key_count;

unsigned int temp,Key_pressed;

extern void delay ( void );

extern int count_timer0_interrupt;

void Keyscan(void)

//*begin

unsigned char i;

for(i = 0;i<4;i++){

AT91F_PIO_SetOutput( AT91C_BASE_PIOA, ROWS_MASK);

if(i == 0) AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, ROW0 );

else if(i == 1) AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, ROW1 );

else if(i == 2) AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, ROW2 );

else if(i == 3) AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, ROW3 );

delay();

// temp = AT91F_PIO_GetInput(AT91C_BASE_PIOA);

Key_pressed = (AT91F_PIO_GetInput(AT91C_BASE_PIOA) &COLUMNS_MASK);

switch(Key_pressed){

case (SW_C0):

NewKey = Keytime+1; Diff_key = 1;

PROCHILD
3
Application Note : 4 X 4 Key Matrix
break;

case (SW_C1):

NewKey = Keytime+2; Diff_key = 1;

break;

case (SW_C2):

NewKey = Keytime+3; Diff_key = 1;

break;

case (SW_C3):

NewKey = Keytime+4; Diff_key = 1;

break;

Keytime +=4;

Keytime = 0;

if(Diff_key == 1)

if(Old_Key != NewKey){

Old_Key = NewKey;

Keychange = 1;

else{

if(Keychange == 1 )

Keychange = 0;

Diff_key =0;

AT91F_US_PutChar((AT91PS_USART)AT91C_BASE_DBGU,NewKey);

else{

if(count_timer0_interrupt > 3)

count_timer0_interrupt =0;

NewKey = 0; Old_Key = 0;

Keychange = 0; Diff_key =0;

PROCHILD
4
Application Note : 4 X 4 Key Matrix
}

//*end

Keyscan.h

#ifdef KEY_GLOBALS

#define KEY_EXT

#else

#define KEY_EXT extern

#endif

void Keyscan(void);

//*----------------------------------------------------------------------------

//* Function Name : main

//* Object : Main function

//* : 16Key scan 4X4

//* Input Parameters : none

//* Output Parameters : TRUE

//*----------------------------------------------------------------------------

#include "Board.h"

//* Global variable

int count_timer0_interrupt;

// External Function Prototype

extern void timer_init (void );

extern void AT91F_DBGU_Init(void);

extern void Keyscan(void);

void delay ( void )

//* Set in Volatile for Optimisation

PROCHILD
5
Application Note : 4 X 4 Key Matrix
volatile unsigned int i;

//* loop delay

for ( i = 0 ;(i < MCK/1000 );i++ ) ;

Main.c

int main(void)

//*Begin

//* Load System pAic Base address

AT91PS_AIC pAic;

pAic = AT91C_BASE_AIC;

//* Enable User Reset and set its Minimal assertion to 960 us

AT91C_BASE_RSTC->RSTC_RMR = AT91C_RSTC_URSTEN | (0x4<<8) | (unsigned int)(0xA5<<24);

//*First, enable the clock of the PIOA

AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC,1<<AT91C_ID_PIOA);

AT91F_PIO_CfgOutput(AT91C_BASE_PIOA,ROWS_MASK);

AT91F_PIO_SetOutput( AT91C_BASE_PIOA, ROWS_MASK ) ;

AT91F_PIO_CfgOutput( AT91C_BASE_PIOA, LED_MASK ) ; // led output setting

AT91F_PIO_SetOutput( AT91C_BASE_PIOA, LED_MASK ) ; // led off

AT91F_PIO_CfgPullup(AT91C_BASE_PIOA,COLUMNS_MASK);

AT91F_PIO_CfgInput(AT91C_BASE_PIOA,COLUMNS_MASK);

//* Init timer interrupt

timer_init();

AT91F_DBGU_Init();

for(;;)

Keyscan();

asm("nop");

PROCHILD
6
Application Note : 4 X 4 Key Matrix
}

//*End

interrupt_timer0.c

//*----------------------------------------------------------------------------

//* File Name : interrupt_timer.c

//* Object : Timer interrupt management

//*----------------------------------------------------------------------------

// Include Standard LIB files

#include "Board.h"

//* Global variable

extern int count_timer0_interrupt;

extern void Keyscan(void);

#define TIMER0_INTERRUPT_LEVEL 1

/*-----------------*/

/* Clock Selection */

/*-----------------*/

#define TC_CLKS 0x7

#define TC_CLKS_MCK2 0x0

#define TC_CLKS_MCK8 0x1

#define TC_CLKS_MCK32 0x2

#define TC_CLKS_MCK128 0x3

#define TC_CLKS_MCK1024 0x4

//*------------------------- Internal Function --------------------------------

//*----------------------------------------------------------------------------

//* Function Name : AT91F_TC_Open

//* Object : Initialize Timer Counter Channel and enable is clock

PROCHILD
7
Application Note : 4 X 4 Key Matrix
//* Input Parameters : <tc_pt> = TC Channel Descriptor Pointer

//* <mode> = Timer Counter Mode

//* : <TimerId> = Timer peripheral ID definitions

//* Output Parameters : None

//*----------------------------------------------------------------------------

void AT91F_TC_Open(AT91PS_TC TC_pt,unsigned int Mode,unsigned int TimerId)

//*begin

unsigned int dummy;

//*First,enable the clock of the TIMER

AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC,1<<TimerId);

//*Disable the clock and the interrupts

TC_pt->TC_CCR = AT91C_TC_CLKDIS;

TC_pt->TC_IDR = 0xFFFFFFFF;

//* Clear status bit

dummy = TC_pt-> TC_SR;

//* Suppress warning variable "dummy" was set but never used

dummy =dummy;

//* Set the Mode of the Timer Counter

TC_pt->TC_CMR = Mode;

//*Enable the clock

TC_pt->TC_CCR = AT91C_TC_CLKEN;

//*end

//*------------------------- Interrupt Function -------------------------------

//*----------------------------------------------------------------------------

//* Function Name : timer0_c_irq_handler

//* Object : C handler interrupt function called by the interrupts

//* assembling routine

//* Output Parameters : increment count_timer0_interrupt

//*----------------------------------------------------------------------------

void timer0_c_irq_handler(void)

PROCHILD
8
Application Note : 4 X 4 Key Matrix
//*begin

AT91PS_TC TC_pt = AT91C_BASE_TC0;

unsigned int dummy;

//* Acknowledge interrupt status

dummy = TC_pt->TC_SR;

//* Suppress warning variable"dummy" was set but never used

dummy = dummy;

count_timer0_interrupt++;

//* Read the output state

if ( (AT91F_PIO_GetInput(AT91C_BASE_PIOA) & LED4 ) == LED4 )

AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, LED4 );

else

AT91F_PIO_SetOutput( AT91C_BASE_PIOA, LED4 );

//*end

//*-------------------------- External Function -------------------------------

//*----------------------------------------------------------------------------

//* Function Name : timer_init

//* Object : Init timer counter

//* Input Parameters : none

//* Output Parameters : TRUE

//*----------------------------------------------------------------------------

void timer_init(void)

//*begin

//init the timer interrupt counter

count_timer0_interrupt=0;

PROCHILD
9
Application Note : 4 X 4 Key Matrix
//* Open timer0

AT91F_TC_Open(AT91C_BASE_TC0,TC_CLKS_MCK32,AT91C_ID_TC0);

//* Open Timer0 interrupt

AT91F_AIC_ConfigureIt(AT91C_BASE_AIC,AT91C_ID_TC0,TIMER0_INTERRUPT_LEVEL,

AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE,timer0_c_irq_handler);

AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS; // IRQ enable CPC

AT91F_AIC_EnableIt(AT91C_BASE_AIC,AT91C_ID_TC0);

//* Generate interrupt by software

AT91F_AIC_Trig(AT91C_BASE_AIC,AT91C_ID_TC0);

//* Start timer0

AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;

//*end

Debug.c

//*----------------------------------------------------------------------------

//* File Name : Debug.c

//* Object : Debug menu

//*----------------------------------------------------------------------------

// Include Standard files

#include "Board.h"

#include "dbgu.h"

//*--------------------------1--------------------------------------------------

//* \fn AT91F_DBGU_Init

//* \brief This function is used to send a string through the DBGU channel

//* (Very low level debugging)

//*----------------------------------------------------------------------------

void AT91F_DBGU_Init(void)

//*begin

//* Open PIO for DBGU

AT91F_DBGU_CfgPIO();

PROCHILD
10
Application Note : 4 X 4 Key Matrix
//* Configure DBGU

AT91F_US_Configure(

(AT91PS_USART) AT91C_BASE_DBGU, // DBGU base address

MCK,

AT91C_US_ASYNC_MODE, // Mode Register to be programmmed

AT91C_DBGU_BAUD, // Timeguard to be programmed

0);

//* Enable Transmitter & reciver

((AT91PS_USART)AT91C_BASE_DBGU)->US_CR = AT91C_US_RXEN |AT91C_US_TXEN;

//*end

//*--------------------------1--------------------------------------------------

//* \fn AT91F_DBGU_Printk

//* \brief This function is used to send a string through the DBGU channel

//* (Very low level debugging)

//*----------------------------------------------------------------------------

void AT91F_DBGU_Printk(char *buffer)

//*begin

while(*buffer != '\0'){

while(!AT91F_US_TxReady((AT91PS_USART)AT91C_BASE_DBGU));

AT91F_US_PutChar((AT91PS_USART)AT91C_BASE_DBGU,*buffer++);

//*end

//*----------------------------------------------------------------------------

//* \fn AT91F_US_Get

//* \brief Get a Char to USART

//*----------------------------------------------------------------------------

int AT91F_US_Get(char *val)

//*begin

if((AT91F_US_RxReady((AT91PS_USART)AT91C_BASE_DBGU)) == 0) return (false);

else

PROCHILD
11
Application Note : 4 X 4 Key Matrix
*val=AT91F_US_GetChar((AT91PS_USART)AT91C_BASE_DBGU);

return(true);

//*end

//*----------------------------------------------------------------------------

//* \fn AT91F_DBGU_scanf

//* \brief Get a string to USART manage Blackspace and echo

//*----------------------------------------------------------------------------

void AT91F_DBGU_scanf(char *type,unsigned int *val)

//*begin

unsigned int read = 0;

char buff[10];

unsigned int nb_read = 0;

while((read != 0x0D) &(nb_read != sizeof(buff)) ){

//* wait the USART Ready for reception

while((AT91C_BASE_DBGU->DBGU_CSR & AT91C_US_RXRDY) == 0);

//* Get a char

read = AT91C_BASE_DBGU-> DBGU_RHR;

buff[nb_read] = (char)read;

//* Manage Blackspace

while((AT91C_BASE_DBGU->DBGU_CSR & AT91C_US_TXRDY) == 0){}

if((char)read == 0x08){

if(nb_read != 0){

nb_read--;

AT91C_BASE_DBGU->DBGU_THR = read;

//*echo

else{

AT91C_BASE_DBGU->DBGU_THR = read;

nb_read++;

PROCHILD
12
Application Note : 4 X 4 Key Matrix
}

//* scan the value

sscanf(buff,type,val);

//*end

PROCHILD
13

You might also like