/*
오버플로우 인터럽트 500ms돌다가
인터럽트 4번이 들어오면 모두 끄기
인터럽트 7을 하나씩 점멸
인터럽트 5가 초기 상태로
*/
#include<avr/io.h>
#include<avr/interrupt.h>
#include<avr/signal.h>
#define OVERFLOW 256
#define CPU_CLOCK 16000000
#define TICKS_PER_SEC 1000
#define PRESCALER 64
volatile unsigned int tic_time;
volatile unsigned char STATE_CNT;
volatile unsigned char STATE_FLAG;
void init_device(void);
void init_int(void);
void init_timerCounter(void);
int main(void){
init_device();
init_timerCounter();
init_int();
sei(); // set enable interrupt
for(;;){
if(tic_time==500){
tic_time=0; // tic_time 초기화
if(STATE_FLAG==0) PORTF=~PORTF;
else{
if(STATE_CNT>8) STATE_CNT=0;
if(STATE_CNT==0) PORTF=0x00;
else if(STATE_CNT==1) PORTF=0x01;
else if(STATE_CNT==2) PORTF=0x03;
else if(STATE_CNT==3) PORTF=0x07;
else if(STATE_CNT==4) PORTF=0x0F;
else if(STATE_CNT==5) PORTF=0x1F;
else if(STATE_CNT==6) PORTF=0x3F;
else if(STATE_CNT==7) PORTF=0x7F;
else PORTF=0xFF;
STATE_CNT++;
/* 비트 연산자를 사용해서 조금더 코드 줄을 줄일수 있다....
if(STATE_CNT>8){
STATE_CNT=0;
PORTF=0x00;
continue;
}
PORTF=PORTF|(1<<STATE_CNT);
STATE_CNT++;
*/
}
}
}
return 1;
}
void init_device(){
// 디바이스 관련 초기화
DDRF=0xFF; // DDRF 방향 설정 >> 출력
PORTF=0xFF; // PORTF LED 초기화
}
void init_int(){
// 외부인터럽트 관련 초기화
cbi(DDRE,4);
cbi(DDRE,5);
cbi(DDRE,7);
EIFR=0x00;
EICRB=0x8A;
EIMSK=0xB0;
}
void init_timerCounter(){
// 타이머 카운터 관련 초기화
TIFR=0x00;
TCCR0=0x04; // Prescaler 설정
TCNT0= OVERFLOW - (CPU_CLOCK / TICKS_PER_SEC / PRESCALER); // 오버플로우에 사용될 초기값
TIMSK=0x01; // 오버플로우 인터럽트 허용
}
SIGNAL(SIG_INTERRUPT4){
// 오버 플로우 인터럽트 스탑 & 불다 끄기
PORTF=0xFF;
TIMSK=0x00;
}
SIGNAL(SIG_INTERRUPT5){
// 오버 플로우 인터럽트 시작 초기상태로
PORTF=0xFF;
TIMSK=0x01;
STATE_FLAG=0;
}
SIGNAL(SIG_INTERRUPT7){
// 500ms마다 불 하나씩 점멸
PORTF=0x00;
TIMSK=0x01;
STATE_FLAG=1;
STATE_CNT=1;
}
SIGNAL(SIG_OVERFLOW0){
tic_time++; // 1000ms마다 생기는 오버 플로우를 카운팅함.
TCNT0 = OVERFLOW - (CPU_CLOCK / TICKS_PER_SEC / PRESCALER); // 오버 플로우 한후에 TCNT0값을 초기화 시켜줌.
}
Posted by rCan

