#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 int tic_time;
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);
int main(void){
CURRENT_KEY_STATE=0xFF;
LAST_KEY_STATE=0xFF;
init_port();
init_timer();
init_timer0();
init_timer1();
init_timer3();
sei();
while(1){
CURRENT_KEY_STATE=PINA; // 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를 출력으로 설정
}
}
}
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){
DDRA=0x00;
}
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++;
TCNT0 = OVERFLOW - (CPU_CLOCK / TICKS_PER_SEC / Prescaler);
}
SIGNAL(SIG_OUTPUT_COMPARE1A){}
SIGNAL(SIG_OUTPUT_COMPARE3A){}
Posted by rCan

