keypad 코드

13 Feb 2018 . category: tech . Comments
#atmega128 #mechatronics #science knowledge'

어제 keypad를 번호,문자를 입력 받았을때 값을 받도록 하는 함수를 만들었고 이제 이 keypad에서 받은 값을 가지고 lcd에 나타내고 비밀번호가 맞았을때 모터가 돌아가도록 하는 코드를 만들어 보았다. 우선 처음 keypad를 하나하나 눌러서 값이 lcd에 나타내도록 하는 코드를 만들어보았는데 lcd상에 계속 오류가 나타나 이를 수정하는 것을 고민해 보았는데 처음 다시 코드를 살펴보았을때는 문제가 없어보여서 많이 헤메다가 하나하나 다시 적어보며 살펴보니 main 함수에 lcd_clear();를 넣어주지 않아서 계속 오류가 난 상태로 지속된 것을 발견했다.

void main(void)
{
    lcd_init(16);
    lcd_clear();   // -> lcd를 초기화해주지 않았었다.
    while(1)
    {
        key=KeyScan();
        lcd_gotoxy(x,y);
        if(key != 0xFF)
        {
            sprintf(buf,"%c", key);
            lcd_puts(buf);
            x++;
            str2[z] = key;
            z++;
            check();
            delay_ms(100);            
        }
    }   
}

이후에 수정후에 lcd 상에 숫자가 나타남을 확인하고 비밀번호 4자리를 받은 후에 correct를 표시하고 모터함수로 가도록 설정해보았는데 이것도 처음에 뜻대로 되지않았다. 숫자는 정상적으로 lcd상에 4자리가 나왔지만 4자리 이후에 correct 변환과 모터로 가지 않았다. 배열을 비교함으로써 비밀번호를 확인하도록 하였는데 고민끝에 처음 str1배열에 4개의 문자를 저장해 비교했어야 했는데 4개의 숫자로 저장해놓은 상태여서 비교가 안되였던 걸로 확인 후 코드를 수정하여 정상적으로 correct와 모터 함수로 가도록 할수 있었다.

unsigned char str1[4] ={1,2,3,4} // 처음 설정한 코드

unsigned char str1[4] ={'1','2','3','4'} // 바꿔준 코드

이후에는 모터함수는 전에 해보았던 대로 각도를 찾아서 인터럽트 함수로 돌려주었고 correct 이후에 ‘#’ 을 눌러주었을때 원래 풀리는 각도로 돌아가도록 코드를 넣어주었다. 전체 코드는 다음과 같다.

#include <mega128.h>
#include <lcd.h>
#include <delay.h>
#include <stdlib.h>
#include <stdio.h>

#asm
   .equ __lcd_port=0x12 ;PORTD
#endasm

#define Motor_off TCCR0 = 0x00;

unsigned char buf[30];
unsigned char key;
unsigned char x =0;
unsigned char y =0;
unsigned char z =0;
unsigned char str1[4] = {'1','2','3','4'};
unsigned char str2[4] = {0};
unsigned char str3[1] = {'#'};
unsigned int tim0_cnt, mot_pos, change;
unsigned int rc_time[2] = {230, 138};

char KeyScan(void)
{
    char KeyBuf=0xFF; //키 값이 들어갈 버퍼, 초기값 0xFF
    PORTA = 0xFF;    //포트 초기값, 입력핀 내부풀업저항 사용
    DDRA = 0x0F;     // 비트 0,1,2,3 출력으로 지정
    
    PORTA.0=0; // 1번째 줄 선택
    delay_ms(100);
    if(!PINA.4)KeyBuf='1';
    if(!PINA.5)KeyBuf='2';
    if(!PINA.6)KeyBuf='3';
    PORTA.0=1; // 1번째 줄 해제
    
    PORTA.1=0; // 2번째 줄 선택
    delay_ms(100);
    if(!PINA.4)KeyBuf='4';
    if(!PINA.5)KeyBuf='5';
    if(!PINA.6)KeyBuf='6'; 
    PORTA.1=1; // 2번째 줄 해제
    
    PORTA.2=0; // 3번째 줄 선택
    delay_ms(100);
    if(!PINA.4)KeyBuf='7';
    if(!PINA.5)KeyBuf='8';
    if(!PINA.6)KeyBuf='9';
    PORTA.2=1; // 3번째 줄 해제
    
    PORTA.3=0; //4번째 줄 선택
    delay_ms(100);
    if(!PINA.4)KeyBuf='*';
    if(!PINA.5)KeyBuf='0';
    if(!PINA.6)KeyBuf='#';
    PORTA.3=1; //4번째 줄 해제     
    
    return KeyBuf;
}

void reset(void)
{
    tim0_cnt= 0;
    mot_pos = 0;
    change = 0;  
    TIMSK = 0x01;
    TCCR0 = 0x02;
    TCNT0 = 238;
    SREG = 0x80;
    
    tim0_cnt = 0;
    PORTC = 0xFF;
    
    while(1)
    {
        if(tim0_cnt >= 2000)
        {
            tim0_cnt = 0;
            PORTC = 0xFF;
            change++;
            if(change == 100)
            {
                change = 0;
                Motor_off;
            }
        }
        if(tim0_cnt >= rc_time[1])
        {
            PORTC = 0x0;
        }
    }
    
}
void motor_off(void)
{
    Motor_off;
    TIMSK = 0x00;
    PORTC = 0x00;
    mot_pos++;
    while(1)
    {
        key=KeyScan();
        if(key == str3[0])
        {     
            reset(); 
        }
    }
}

void motor_on(void)
{
    tim0_cnt =0;
    change=0;
    TIMSK = 0x01;   //TOIE0 = 1
    TCCR0 = 0x02;   //일반모드, 프리스케일 = CK/8
    TCNT0 = 238;
    SREG = 0x80;
    
    tim0_cnt=0;
    PORTC = 0xFF;
    
    while(1)
    {
        if(tim0_cnt >= 2000)
        {   
            tim0_cnt=0;
            PORTC = 0xFF;
            change++;
            if(change == 100)
            {
                mot_pos = (mot_pos + 1) % 2;
                change = 0;  
                Motor_off;
                motor_off();
            }
        }
        if(tim0_cnt >= rc_time[0])
        {
            PORTC = 0x00;
        }
    }
}
interrupt [TIM0_OVF] void tim_int0(void)
{
    tim0_cnt++;
    TCNT0 = 238;
}

void check4(void)
{
    if(str1[3] == str2[3])
    {
        lcd_clear();
        lcd_gotoxy(0,y);
        lcd_putsf("correct"); 
        motor_on();
        delay_ms(100);
    }
}

void check3(void)
{
    if(str1[2] == str2[2])
    {
        check4();
    }
}

void check2(void)
{
    if(str1[1] == str2[1])
    {
        check3();
    }
}
void check(void)
{
    if(str1[0] == str2[0])
    {
        check2();
    }
}
void main(void)
{
    lcd_init(16);
    lcd_clear();
    while(1)
    {
        key=KeyScan();
        lcd_gotoxy(x,y);
        if(key != 0xFF)
        {
            sprintf(buf,"%c", key);
            lcd_puts(buf);
            x++;
            str2[z] = key;
            z++;
            check();
            delay_ms(100);            
        }
    }   
}

이제 코드 및 하드웨어도 어느정도 완성되었고 추가적인 개선사항만 고치면 잠금상자를 완성할 수 있을 것 같다.


Me

github를 이용해 만들어본 블로그입니다.