본문 바로가기

AVR 기초/인터럽트

[AVR 기초] 스탑워치 1

*키트는 Atmega128A를 사용하였습니다*

 

 

//StopWatch SW1 인터럽트 발생시 시간X

#include <avr/io.h>
#include <avr/interrupt.h>						
#define F_CPU 16000000UL					//실제 동작 clock Hz -> 16MHz
#include <util/delay.h>						//딜레이 헤더파일 선언

volatile int currenttime, stoptime = 0;		//변수를 선언할 때 앞에 volatile 을 붙이면 컴파일러는 해당 변수를 최적화에서 제외하여 항상 메모리에 접근하도록 만듬
											//currenttime, stoptime 이라는 변수만듬
unsigned char fnd[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x67};
unsigned char fnd_pos[4] = {0x01, 0x02, 0x04, 0x08};

volatile int count = 0;				//변수 count = 0만듬
ISR (INT4_vect){					//인터럽트 서비스 루틴 스위치 1(portE의 4번)
	
	if (count ==0)					//조건문 if >>>>count 가 0 이라면
	{
		count = 1;					// count를 1로 만듬
		_delay_ms(15);				
	}
	else{							//count 가 0 이 아니라면,
		count = 0;					//count를 0으로..
		stoptime = currenttime;		//stoptime 변수에 currenttime 의 값 넣기
		_delay_ms(15);
	}
	
}
ISR(INT5_vect){						//인터럽트 서비스 루틴 스위치 2(PORTE의 5번)
	stoptime = 0;					//stoptime = 0
	currenttime = 0;				//currenttime = 0
	count = 0;						//count = 0 ------>>>   모든것을 처음과 같이 만듬(초기화)
	
	_delay_ms(15);
}
void display_fnd(int count){		//fnd를 나타내는 함수
	int i, x[4];					//display_fnd 함수 안에서만 사용하는 변수 i,배열 x 4개
	x[3] = (count/1000)%10;				//천의자리  -->>  count를 1000으로 나눈 후, 10으로 나눈 값의 나머지를 저장
	x[2] = (count/100)%10;				//백의자리
	x[1] = (count/10)%10;				//십의자리
	x[0] = (count)%10;					//1의자리
	//위의 식을 계산하면 몇번 눌렀는지 계산이 됨 >> 그 값을 밑의 for문을 통하여 display
	
	for (i=0;i<4;i++){
		PORTC = fnd[x[i]];
		PORTG = fnd_pos[i];
		_delay_ms(2);
	}
}
int main(void)
{
	/* Replace with your application code */
	DDRC = 0xff;
	DDRG = 0x0f;
	DDRE = 0xcf;						//스위치
	EICRB = 0x0a;						//INT4번,5번에 대한 세팅을 함. \\Falling Edge 가 발생하면 인터럽트가 발생하도록 설정
	EIMSK = 0x30;						//인터럽트 4,5 사용
	sei();								//인터럽트 enable
	
	while (1)							//무한반복
	{
		if (count == 0)					//count 가 0 이라면,,,
		{
			display_fnd(stoptime);		//display_fnd함수에 stoptime 값 넣기
		}
		else{
			display_fnd(currenttime);
			currenttime++;	//count의 값이 0 이 아니라면,, display_fnd 함수에 currenttime값 넣기
		}
		
	}
}