[ATMEGA128] 키스캔 + fun

/*
0번핀 500ms 토글
1번 200ms 토글
2번핀입력일경우 나머지 6개 LED 로테이트 200ms
3번 모두 오프
4번 모두 온
5번 3개 온 3개 오프
6번 2개씩 led  프래쉬
7번 징검다리 온오프 온오프
*/
#include<stdio.h>
#include<avr/interrupt.h>
#include<avr/signal.h>

#define CPU_CLOCK 16000000
#define TICKS_PER_SEC 1000
#define Prescaler 64
#define OVERFLOW 256

volatile unsigned int cnt;
volatile unsigned int tic_time;
volatile unsigned int tic_time2;
volatile unsigned int oc1cnt;
volatile unsigned int oc3cnt;
volatile unsigned int FUN_MODE;

volatile unsigned char KEY_STATE;
volatile unsigned char CURRENT_KEY_STATE;
volatile unsigned char LAST_KEY_STATE;

void init_port(void);
void init_timer(void);
void init_timer0(void);
void init_timer1(void);
void init_timer3(void);
void fun_run(void);

int main(void){
        CURRENT_KEY_STATE=0xFF;
        LAST_KEY_STATE=0xFF;

        init_port();
        init_timer();
        init_timer0();
        init_timer1();
        init_timer3();
        sei();

        while(1){
                if(FUN_MODE!=0)
                        if(tic_time2>=200){ tic_time2=0; fun_run(); }

                CURRENT_KEY_STATE=PINF; // SW에 값을 CURRENT_KEY_STATE에 넣어줌
                if(CURRENT_KEY_STATE!=0xFF){
                // CURRENT_KEY_STATE가 0xFF가 아닌 경우(어느 키라도 눌렸을경우)
                        if(CURRENT_KEY_STATE!=LAST_KEY_STATE){
                        // 지금 누른키와 눌린키가 아닐 경우 (키가 변경된 경우)
                                tic_time=0;
                                KEY_STATE=0;
                        }
                        if(tic_time>=50){
                                // 키를 누르고 50ms가 지났으면 (계속 눌려잇는 경우)
                                if(KEY_STATE==0){
                                        KEY_STATE=1;
                                        if(CURRENT_KEY_STATE==0xFE) sbi(DDRB,5); // oc1a를 출력으로 설정
                                        if(CURRENT_KEY_STATE==0xFD) sbi(DDRE,3); // oc3a를 출력으로 설정
                                        if(CURRENT_KEY_STATE==0xFB) FUN_MODE=1;
                                        if(CURRENT_KEY_STATE==0xF7) FUN_MODE=2;
                                        if(CURRENT_KEY_STATE==0xEF) FUN_MODE=3;
                                        if(CURRENT_KEY_STATE==0xDF) FUN_MODE=4;
                                        if(CURRENT_KEY_STATE==0xBF) FUN_MODE=5;
                                        if(CURRENT_KEY_STATE==0x7F) FUN_MODE=6;
                                }
                        }
                }
                else KEY_STATE=0; // PINA가 0xFF인경우는 KEY_STATE를 0으로 초기화 시켜준다.
                LAST_KEY_STATE=CURRENT_KEY_STATE; // 현재 눌린키를 눌려진 키로 넣어줌
                if(tic_time>=1000){

                // 키를 누르지 않을 경우에 생기는 문제점을 해결하기 위해서
                // tic_time은 int형 변수이기에 넘어가게 되면 오버 플로우가 발생될가능성도 있다.
                // 그것뿐만 아니라 예를 들어 키보드 방향키 위를 생각해보면
                // 위를 한번 꾸우우우욱 누른경우랑
                // 위를 한번  꾹 누른 경우랑 같게 된다는것이다.
                        tic_time=0;
                        LAST_KEY_STATE=0xFF;
                }

        }
        return 0;
}

void init_port(void){
        DDRF=0x00;
        DDRC=0xFF;
        PORTC=0xFF;
}
void init_timer(void){
        // 타이머에 관한 전반적인 공통사항을 기술
        TIFR=0x00;
}
void init_timer0(void){
        // 타이머0에 대한 설정
        TCCR0=0x04;
        TCNT0=OVERFLOW - (CPU_CLOCK / TICKS_PER_SEC / Prescaler);
        TIMSK=0x01;
}
void init_timer1(void){
        // 타이머1에 대한 설정
        TCNT1H=0x00;
        TCNT1L=0x00;

        TCCR1A=0x40;
        TCCR1B=0x0C;
        TCCR1C=0x00;

        OCR1AH=0x7A;
        OCR1AL=0x12;
        TIMSK=TIMSK|(1<OCIE1A);
}
void init_timer3(void){
        // 타이머3에 대한 설정
        TCNT3H=0x00;
        TCNT3L=0x00;

        TCCR3A=0x40;
        TCCR3B=0x0C;
        TCCR3C=0x00;

        OCR3AH=0x18;
        OCR3AL=0x6A;
        TIMSK=ETIMSK|(1<OCIE3A);
}
SIGNAL(SIG_OVERFLOW0){
        // 오버 플로우 인터럽트 발생시 (timer0에서 발생되는..)
        tic_time++;
        tic_time2++;
        TCNT0 = OVERFLOW - (CPU_CLOCK / TICKS_PER_SEC / Prescaler);
}
SIGNAL(SIG_OUTPUT_COMPARE1A){

}
SIGNAL(SIG_OUTPUT_COMPARE3A){

}

void fun_run(void){
        switch(FUN_MODE){
                case 1:
                break; // 6개 로테이트
                case 2: PORTC=0x3F; break; // 6개 OFF 해결
                case 3: PORTC=0x00; break; // 6개 on 해결
                case 4: PORTC=0x38; break; // 6개 3on 3off 해결
                case 5: PORTC=0xFF<<cnt);
                break; // 2개씩 반복
                case 6: PORTC=0xAA; break; // onoffonoff 해결
        }
}

Posted by rCan

2008/10/15 16:55 2008/10/15 16:55
Response
No Trackback , No Comment
RSS :
http://rcan.net/rss/response/580

Trackback URL : http://rcan.net/trackback/580

Leave a comment
« Previous : 1 : ... 21 : 22 : 23 : 24 : 25 : 26 : 27 : 28 : 29 : ... 439 : Next »

블로그 이미지

- rCan

Calendar

«   2012/02   »
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29      

Notices

  1. About Me

Site Stats

Total hits:
113575
Today:
6
Yesterday:
43