Embedded/마이크로프로세서

ATMEGA128 Roullette 모형 제어

장영현 2023. 6. 1. 01:23
728x90
  • Roullette 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define F_CPU 16000000UL
#define I 7

unsigned char SEG[16] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E};

void Initial_set(){
	DDRA = 0xFF;
	PORTA = 0xFE;

	DDRF = 0xFF;
	PORTF = 0xC0;

	DDRB |= 1<<DDB0;
	PORTB &= ~(1<<PB0);

	DDRE &= ~(1<<DDE4); 
	PORTE |= 1<<PE4;

	EIMSK |= 1<<INT4;
	EICRB |= 2<<ISC40;
	SREG |= 1<<I;
}

ISR(INT4_vect){
	while((PINE & 1<<PE4) == 0){
		switch(PORTA){
        			case 0xFE : PORTF = SEG[1];
			break;
			case 0xFD : PORTF = SEG[2];
			break;
			case 0xFB : PORTF = SEG[3];
			break; 
			case 0xF7 : PORTF = SEG[4];
			break; 
			case 0xEF : PORTF = SEG[5];
			break;
			case 0xDF : PORTF = SEG[6];
			break;
			case 0xBF : PORTF = SEG[7];
			break;
			case 0x7F : PORTF = SEG[8];
			break;
	}
}

int main(){
	unsigned char led = 0xFE;
	Initial_set();
	while(1){
		do{
			PORTA = led;
			_delay_ms(50);
			led <<= 1;
			led |= 0x01;
		}while(led != 0x7F);
		do{
			PORTA = led;
			_delay_ms(50);
			led >>= 1;
			led |= 0x80;
		}while(led != 0xFE);
	}
	return 0;
}
  • 코드설명

입출력과 관련된 레지스터들의 초기조건

Bit 7 6 5 4 3 2 1 0
DDRA DDA7 DDA6 DDA5 DDA4 DDA3 DDA2 DDA1 DDA0
1 1 1 1 1 1 1 1
PORTA PA7 PA6 PA5 PA4 PA3 PA2 PA1 PA0
1 1 1 1 1 1 1 1
Bit 7 6 5 4 3 2 1 0
DDRB DDB7 DDB6 DDB5 DDB4 DDB3 DDB2 DDB1 DDB0
DDB7 DDB6 DDB5 DDB4 DDB3 DDB2 DDB1 1
PORTB PB7 PB6 PB5 PB4 PB3 PB2 PB1 PB0
PB7 PB6 PB5 PB4 PB3 PB2 PB1 0
Bit 7 6 5 4 3 2 1 0
DDRF DDF7 DDF6 DDF5 DDF4 DDF3 DDF2 DDF1 DDF0
1 1 1 1 1 1 1 1
PORTF PF7 PF6 PF5 PF4 PF3 PF2 PF1 PF0
1 1 0 0 0 0 0 0
Bit 7 6 5 4 3 2 1 0
DDRE DDE7 DDE6 DDE5 DDE4 DDE3 DDE2 DDE1 DDE0
0 0 0 0 DDE3 DDE2 DDE1 DDE0
PORTE PE7 PE6 PE5 PE4 PE3 PE2 PE1 PE0
0 0 0 1 PE3 PE2 PE1 PE0

 

외부 인터럽트와 관련된 레지스터의 조건(하강에지에서 동작)

Bit 7 6 5 4 3 2 1 0
EIMSK X X X 1 X X X X
EICRB X X X X X X 1 0
SREG 1 X X X X X X X

(1) EIMSK = 사용하는 푸쉬버튼이 PE4/INT4이므로 INT4 자리에만 1BIT 전송

(2) EICRB = 외부 인터럽트에서 하강에지 동작 시 작동하게 해야 하므로 1(ISC41 자리),0(ISC40 자리) 전송

/ 상승에지 동작 시 1(ISCn1자리),1(ISCn0 자리)전송

(3) SREG = AVR에서 Status Register7번 비트‘i'는 모든 인터럽트에 대한 허가를 결정하는 비트이므로 7번 비트에만 1을 설정.

EIMSK레지스터를 통해 외부 인터럽트를 허가하고, SREG레지스터의 7번 비트 ‘I’를 통해 인터럽트를 사용

 

ISR(INT4_vect)
	{ while((PINE & 1<<PE4) == 0);	}

회로에서 푸쉬버튼이 연결된 PE4/INT4이 작동 시 while문의 조건이 참이 되므로 while문 안의 조건 실행.

 

EICRB |= 2<<ISC40;

외부 인터럽트는 하강에지에서 작동하게 하므로 ISC41 = HIGH, ISC40= LOW로 설정.

 

		do{		// (1)
			PORTA = led; // led = 1111 1110
			_delay_ms(50);
			led <<= 1;	// led = led << 1
			led |= 0x01; // led = led | 0000 0001
		}while(led != 0x7F); // led가 0111 1111시 do~while문 나옴	
		do{	    // (2)
			PORTA = led; // led = 0111 1111
			_delay_ms(50);	
			led >>= 1; // led = led >> 1
			led |= 0x80; // led = led | 1000 0000
		}while(led != 0xFE);// led가 1111 1110시 do~while문 나옴
Bit 7 6 5 4 3 2 1 0
PORTA = led 1 1 1 1 1 1 1 0
led << 1 1 1 1 1 1 1 0 0
0x01 0 0 0 0 0 0 0 1
led | 0x01 1 1 1 1 1 1 0 1

 

Bit 7 6 5 4 3 2 1 0
led 0 1 1 1 1 1 1 1
led != 0x7F 0 1 1 1 1 1 1 1

led << 1을 통해 비트이동을 하여 led의 점등을 순차적으로 이동시킨다.

그 후 do~while문의 while(led != 0x7F)을 통해 반복문을 나오게 된다.

 

Bit 7 6 5 4 3 2 1 0
PORTA = led 0 1 1 1 1 1 1 1
led >> 1 0 0 1 1 1 1 1 1
0x80 1 0 0 0 0 0 0 0
led | 0x80 1 0 1 1 1 1 1 1

 

Bit 7 6 5 4 3 2 1 0
led 1 1 1 1 1 1 1 0
led != 0xFE 1 1 1 1 1 1 1 0

led >> 1을 통해 비트이동을 하여 led의 점등을 순차적으로 이동시킨다.

그 후 do~while문의 while(led != 0xFE)을 통해 반복문을 나오게 된다.