Chapter. 13 KeyPAD 를이용한비밀번호입력기 HBE-MCU-Multi AVR Jaeheung, Lee
목차 1. 키패드 (KeyPAD) 2. KeyPAD 를이용한비밀번호입력기
키패드 (KeyPAD) 키패드 (KeyPAD) 마이크로컨트롤러활용에서사용자의입력을받아들이기위한장치 전화기, 컴퓨터, 핸드폰, 냉장고등거의모든가전제품에서사용 키패드인터페이스방식 n 정적인터페이스 (Static Interface) 방식 : n 키를포트에일대일로연결하여입력을검사하는방식 n 하드웨어구성이간편하고, 소프트웨어구현이쉬운장점이있다. n 많은키입력이필요할때는키의개수만큼의포트를사용하기때문에포트사용이비효율적이다. n 동적인터페이스 (Dynamic Interface) 방식 : n 키스위치를매트릭스형태로구성하여출력상태에따른입력값을비교하여키입력을판별하는방법 n 적은포트로여러개의키를제어할수있다. n 눌린스위치의검출방법이좀복잡해진다.
키패드 (KeyPAD) 키패드 (KeyPAD) 정적인터페이스 (Static Interface) 방식
키패드 (KeyPAD) 키패드 (KeyPAD) 동적인터페이스 (Dynamic Interface) 방식
키패드 (KeyPAD) 키패드 (KeyPAD) 동적인터페이스방식에서의신호에따른스위치눌림검출표 KEY_C0~2=100 KEY_C0~2=010 KEY_C0~2=001 KEY_R0~3=1000 S1 S2 S3 KEY_R0~3=0100 S4 S5 S6 KEY_R0~3=0010 S7 S8 S9 KEY_R0~3=0001 S10 S11 S12
실습개요 12 키키패드를이용하여자동문개폐기등에사용되는비밀번호입력기를만들도록한다. 키패드모듈과 TEXT LCD 를사용하여, 프로그램을작성한다. 편이상비밀번호는미리정의해두기로하고, 4 자리수비밀번호를사용하기로한다. 실습목표 키패드의동작원리를이해 ATmega128의 GPIO를이용한키패드데이터입력방법습득 TEXT-LCD, FND, GPIO 제어의복합적인프로그램능력배양
사용모듈 : MCU 모듈, TEXT-LCD 모듈, 키패드모듈, FND 모듈 MCU 모듈 E 포트 FND 모듈연결 TEXT LCD 모듈 C,D 포트 TEXT LCD 모듈연결 F 포트키패드모듈연결 Data BUS (D0~D7) Control 신호 (Rs, RW, E) FND 모듈 Signal FND 모듈 KeyPAD 신호 키패드모듈
사용모듈 : 키패드모듈회로
모듈결선방법 MCU 모듈포트 C 의 PC0~PC7 은 TEXT LCD 모듈의 D0~D7 핀에연결 MCU 모듈포트 D 의 PD5~PD7 은각각 TEXT LCD 모듈의 RS, RW, E 에연결 MCU 모듈포트 A 의 PA0~ PA2 은키패드모듈의 C0~C2 에, PA3~PA6 은키패드모듈의 R 0~R3 에연결 MCU 모듈포트 E 의 PE0~PE7 은 FND 모듈의 SB_A~SA_H 까지연결
구동프로그램 : 사전지식 동작 n 키패드를이용하여비밀번호를입력하고, n 비밀번호가입력되면 4자리가입력될때까지기다렸다가미리지정된비밀번호와비교하여, 맞는지여부를판단하고결과를 TEXT LCD에알려주기로한다. 키패드입력루틴 n 키패드모듈의 KEYPAD_R0~KEYPAD_R3에차례대로 1000, 01 00, 0010, 0001 을인가해가면서, KEYPAD_C0~KEYPAD_ C2값을보면어떤키가눌러졌는지검출이가능 소스구성 n key.c : 메인프로그램파일 n key_pad.c : 키패드와비밀번호입력 / 비교함수등이예제의핵심기능을하는함수들포함 n lcd.c : TEXT LCD 관련함수들포함 n avr_lib.c : 부가적으로자주사용되는사용자함수들포함
구동프로그램 : 사전지식 키패드입력루틴 n 키패드모듈의 KEYPAD_R0~KEYPAD_R3 에차례대로 1000, 0100, 0010, 0001 을인가해가면서, KEYPAD_C0~K EYPAD_C2 값을보면어떤키가눌러졌는지검출이가능 n 함수 get_passwd() 동작 n n n 키패드로키패드체크신호 (R0~R3) 을차례대로출력 키패드로부터키입력신호 (C0~C1) 를받아어떤키가눌렸는지확인하여 FND 에출력 비밀번호체크함수에비밀번호비교를의뢰
Get_passwd u08 get_passwd(){ ROW_PORT = ROW_1; ms_delay(1); 키패드입력루틴 if((column_pin & KEY_1)){ FND_PORT = FND_DATA_TBL[1]; passcheck('1'); else if((column_pin & KEY_2)){ FND_PORT = FND_DATA_TBL[2]; passcheck('2'); else if((column_pin & KEY_3)){ FND_PORT = FND_DATA_TBL[3]; passcheck('3'); ms_delay(10);
Get_passwd ROW_PORT = ROW_2; ms_delay(1); if(column_pin & KEY_1){ FND_PORT = FND_DATA_TBL[4]; passcheck('4'); else if(column_pin & KEY_2){ FND_PORT = FND_DATA_TBL[5]; passcheck('5'); else if(column_pin & KEY_3){ FND_PORT = FND_DATA_TBL[6]; passcheck('6'); 키패드입력루틴 ms_delay(10);
Get_passwd ROW_PORT = ROW_3; ms_delay(1); if(column_pin & KEY_1){ FND_PORT = FND_DATA_TBL[7]; passcheck('7'); else if(column_pin & KEY_2){ FND_PORT = FND_DATA_TBL[8]; passcheck('8'); else if(column_pin & KEY_3){ FND_PORT = FND_DATA_TBL[9]; passcheck('9'); ms_delay(10); 키패드입력루틴
Get_passwd ROW_PORT = ROW_4; ms_delay(1); if(column_pin & KEY_1){ FND_PORT = FND_DATA_TBL[15]; reset_check(); else if(column_pin & KEY_2){ FND_PORT = FND_DATA_TBL[0]; passcheck('0'); else if(column_pin & KEY_3){ FND_PORT = FND_DATA_TBL[11]; back_pass(); ms_delay(10); return _loop; 키패드입력루틴
구동프로그램 : 소스분석 Lcdconf.h #ifdef LCD_PORT_INTERFACE #ifndef LCD_CTRL_PORT #define LCD_CTRL_PORT PORTD #define LCD_CTRL_DDR DDRD #define LCD_CTRL_RS 5 #define LCD_CTRL_RW 6 #define LCD_CTRL_E 7 #endif #ifndef LCD_DATA_POUT #define LCD_DATA_POUT PORTC #define LCD_DATA_PIN PINC #define LCD_DATA_DDR DDRC #endif #endif
구동프로그램 : 소스분석 Key_pad.h 1-1) #ifndef KEY_PAD_H #define KEY_PAD_H #include<avr/io.h> #include"lcd.h" #include"avr_lib.h #define ROW_PORT PORTA #define ROW_DDR #define ROW_DDR_ADDR #define COLUMN_PORT #define COLUMN_DDR #define COLUMN_PIN DDRA 0x78 PORTA DDRA PINA
1-1) #define FND_PORT PORTE #define FND_DDR DDRE #define KEY_1 0x01 #define KEY_2 0x02 #define KEY_3 0x04 #define ROW_1 0x08 #define ROW_2 0x10 #define ROW_3 0x20 #define ROW_4 0x40 void init_keypad(); u08 get_passwd(); u08 passwd_check(u08 pass[]); #endif
구동프로그램 : 소스분석 Key_pad.c 2-1) #include"key_pad.h" u08 cnt=0; u08 pass[4]={0; u08 _loop=1; u08 FND_DATA_TBL[]={0x3F,0X06,0X5B,0X4F,0X66,0X6D,0X7C,0X07,0X7F,0X67,0X77,0X7C,0X39,0X5E,0X79,0X71,0X08,0X80; u08 PASSWD[]="1234";
2-2) void init_keypad(){ ROW_DDR = ROW_DDR_ADDR; ROW_PORT &= ~(ROW_DDR_ADDR); COLUMN_DDR &= ~(KEY_1 KEY_2 KEY_3); COLUMN_PORT &= ~(KEY_1 KEY_2 KEY_3); FND_DDR = 0xff; FND_PORT = 0x00; lcdinit(); lcdgotoxy(0,0); lcdprintdata("password?",sizeof("password?")-1); lcdgotoxy(0,1); lcddatawrite('>');
2-4) void reset_check(){ // 패스워드체크리셋 lcdclear(); ms_delay(10); lcdgotoxy(0,0); lcdprintdata("reset!!",sizeof("reset!!")-1); ms_delay(500); lcdgotoxy(0,0); lcdprintdata("password?",sizeof("password?")-1); lcdgotoxy(0,1); lcddatawrite('>'); while((column_pin & 0x07)!=0); cnt=0;
2-5) void passcheck(u08 data){ // 4 자리의패스워드가맞는지확인하는함수 if(cnt!=3){ //4자리입력이아닌경우 lcddatawrite('*'); pass[cnt++]=data; else if(cnt==3){ lcddatawrite('*'); pass[cnt]=data; if(passwd_check(pass)!=0){ // 비밀번호 1234 와다른경우 lcdgotoxy(0,0); lcdprintdata("wrongpassword!",sizeof("wrongpassword!")-1); lcdgotoxy(0,1); lcdprintdata("plz Check U Pass",sizeof("Plz Check U Pass")-1);
2-5) cnt=0; ms_delay(950); lcdclear(); ms_delay(50); lcdprintdata("password?",sizeof("password?")-1); lcdgotoxy(0,1); lcddatawrite('>'); else{ // 패스워드가맞는경우 lcdclear(); lcdgotoxy(0,0); lcdprintdata("hello MCU_WORLD",sizeof("Hello MCU_WORLD")-1); cnt=0; _loop=0; ms_delay(1000); while((column_pin & 0x07)!=0);
2-6) u08 get_passwd(){ ROW_PORT = ROW_1; ms_delay(1); if((column_pin & KEY_1)){ FND_PORT = FND_DATA_TBL[1]; passcheck('1'); else if((column_pin & KEY_2)){ FND_PORT = FND_DATA_TBL[2]; passcheck('2'); else if((column_pin & KEY_3)){ FND_PORT = FND_DATA_TBL[3]; passcheck('3'); ms_delay(10);
2-6) ROW_PORT = ROW_2; ms_delay(1); if(column_pin & KEY_1){ FND_PORT = FND_DATA_TBL[4]; passcheck('4'); else if(column_pin & KEY_2){ FND_PORT = FND_DATA_TBL[5]; passcheck('5'); else if(column_pin & KEY_3){ FND_PORT = FND_DATA_TBL[6]; passcheck('6'); ms_delay(10);
2-6) ROW_PORT = ROW_3; ms_delay(1); if(column_pin & KEY_1){ FND_PORT = FND_DATA_TBL[7]; passcheck('7'); else if(column_pin & KEY_2){ FND_PORT = FND_DATA_TBL[8]; passcheck('8'); else if(column_pin & KEY_3){ FND_PORT = FND_DATA_TBL[9]; passcheck('9'); ms_delay(10);
2-6) ROW_PORT = ROW_4; ms_delay(1); if(column_pin & KEY_1){ FND_PORT = FND_DATA_TBL[15]; reset_check(); else if(column_pin & KEY_2){ FND_PORT = FND_DATA_TBL[0]; passcheck('0'); else if(column_pin & KEY_3){ FND_PORT = FND_DATA_TBL[11]; back_pass(); ms_delay(10); return _loop;
2-7) u08 passwd_check(u08 pass[]){ u08 _error=0; u08 i; for(i=0;i<4;i++){ if(pass[i]!=passwd[i]) _error++; return _error;
구동프로그램 : 소스분석 Key.c 3-1) #include<avr/io.h> #include"key_pad.h" int main(){ char loop = 1; // 키패드제어헤더 init_keypad(); 3-2) while(loop){ loop=get_passwd(); return 0; // 키패드설정초기화, Textlcd 초기화 // 반복문을돌려서비밀번호가맞는지찾아냄
실행결과