// 키패드 7-SEG LED제작
// KEY PAD 입력기
// 1. 처음에는 오른쪽 끝에 0이 하나만 표시된다
// 2. KEYPAD를 누르면 해당숫자를 4자리 FND에 오른쪽부터 왼쪽으로 밀려가며 표시
// 3. Leading0은 표시하지 않는다..
// sw1:0~sw16:F 

#include<avr/io.h>
#include<util/delay.h>
#include<stdio.h>

#define N_COL 4                        // 스캔할 키패드의 열수
 
#define KEY_OUT PORTA                  // Keypad 출력포트
#define KEY_IN PINA                    // keypad 입력포트
#define KEY_DIR DDRA                   // KEYPAD 입출력 방향 레지스터

static unsigned char key_scan(void);   // 맞는지 안맞는지 확인
static unsigned char pin = NO_KEY;     // former code  

void key_init(void){
KEY_OUT = 0xF0;       // 출력조기값으로 0을 출력 <ㅡ 1번
KEY_DIR = 0x0F;       // 하위니블 출력 0-3 까지 상위니블 입력 4-7까지

}

unsigned char key_intput(void) {
unsigned char in,in1;                  // in,in1 초기화
in = key_scan();                       // 키 스캔을 하여서 코드값을 읽는다
while(1){                               // 무한반복
in1= key_scan();        //  한번더 읽는다
if( in==in1) break;                   // 같을시 그만
in = in1 ;          // in = in1 같다
}
if(!(in & 0xF0)){         // in 이라는 key값을 리셋  
                                       
   pin = 0;                           // 이전에잇던 키 값을 리셋 
   return =0;                         // 
   }

   if ( pin ==in)                    // 0이라는 pin 값과 in의 값이 같을때
    return 0;                        // 비어잇던 키를 다시 돌아온다
 pin = in;       // pin에 in이라는 키 값을 넣는다
    return in;       // 키코드를 복귀시킨다
 }

 static unsigned char key_scan(void){   // key code를 스캔한다.
 unsigned char out. i,in;                // out ,i, in 설정
 out = 0x01;
 for (i=0; i<N_COL;i++){                 // i는 0부터 시작 4보다 작을시 i++한다 0 ,1,2,3
    KEY_OUT = ~out;       // KEY_OUT =~out 즉 11111110
 asm("nop";;);       // 지연
    in = (~KEY_IN) & 0xF0;                  // PINA 입력 포트 KEY_IN과  AND 11110000
                                         // AND값의 결과에 나온값을 ~ 부호 시켜준다
           // SW값이 0이어야  커진다
   if (in){                                 // in이 트루인지 펄스인지 펄스=0
      in+=out;                        // in에다가 out을 더한다
   break;                          // 된것으로 판단
 
 out <<=1;                               // out은 왼쪽으로 1비트 쉬프트한다. 
 }
 return in;           // 펄스일시 in값이 복귀한다.
 }
 
 
unsigned char key_number(unsigned char key_code_{
unsigned char number;
switch(key_code){
case SW0: number=0; break;
case SW1; number=1; break;
case SW2; number=2; break;
case SW3; number=3; break;
case SW4; number=4; break;
case SW5; number=5; break; 
case SW6; number=6; break;
case SW7; number=7; break;
case SW8; number=8; break;
case SW9; number=9; break;
case SWA; number=10; break;
case SWB; number=11; break;
case SWC; number=12; break;
case SWD; number=13; break;
case SWE; number=14; break;
case SWF; number=15; break;
default number=16; break; 
 }
 return(number);
 }

//keypad.h
#ifndef _KEYPAD_H_
#define _KEYPAD_H_
//key codes
#define SW0  0x18     // row0
#define SW1  0x14
#define SW2  0x12
#define SW3  0x11
#define SW4  0x28     // row1
#define SW5  0x24
#define SW6  0x22
#define SW7  0x21
#define SW8  0x48     // row2
#define SW9  0x44
#define SWA  0x42
#define SWB  0x41
#define SWC  0x18   // row3
#define SWD  0x84
#define SWE  0x82
#define SWF  0x81
#define NO_KEY 0x00

void key_init(void);
unsigned char key_intput(void);
unsigned char key_number(unsigned char);
#endif


// keypad_test.c

#include<avr/io.h>
#include<util/delay.h>

#include "keypad.h"

#define SEG_DATA POTB         // 7segment LED data
#define DDR_DATA DDRB

void display_7(void);

static unsigned char buffer = {16};

static unsigned char SegTable[17]
= { 0xC0, 0xF9, 0xA4, 0xB0, 0x99 , 0x92, 0x82, 0xF8
  0x80 , 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x8E, 0x7F};

int main(void){

unsigned char keycode;

DDR_>DDRE 0xF0;
key_init();

while(1) {
   if((keycode=key_intput()))){
 buffer = key_number(keycode);
 }
 display_70;
 }
}

void display_7(void){
     PORTE = 0x00; 
     SEG_>

}