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 Register의 7번 비트‘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)을 통해 반복문을 나오게 된다.