2023. 6. 1. 01:37ㆍEmbedded/마이크로프로세서
- 외부 인터럽트 1
#include<avr/io.h>
#include<util/delay.h>
#include<avr/interrupt.h>
#define F_CPU 16000000UL
#define I 7
ISR(INT4_vect)
{
while((PINE & 1<<PE4) == 0);
}
void Initial_set(void)
{
DDRA = 0xff;
PORTA = 0x00;
DDRE &= ~(1<<DDE4) & ~(1<<DDE5) & ~(1<<DDE6) & ~(1<<DDE7) ;
PORTE |= 1<<DDE4 | 1<<DDE5 | 1<<DDE6 | 1<<DDE7;
EICRB |= 2<<ISC40;
EIMSK |= 1<<INT4;
SREG |= 1<<I;
}
int main(void)
{
unsigned char led = 0xFE;
Initial_set();
while(1){
do{
PORTA = led;
_delay_ms(500);
led <<=1;
led |= 0x01;
}while(led !=0x7F); // 0111 1111
do{
PORTA = led;
_delay_ms(500);
led >>=1;
led |= 0x80;
}while(led !=0xFE); // 1111 1110
}
}
- 코드설명
ISR(INT4_vect)
{
while((PINE & 1<<PE4) == 0);
}
ISR(인터럽트 함수)로 INT4_vect란 이름의 함수를 정하여 hile((PINE & 1<<PE4) == 0)이 실행될 때 인터럽트 함수를 실행한다는 코드이다.
(PINE & 1<<PE4) == 0는 PINE의 4번핀에 연결된 스위치를 누를시 실행된다.
DDRA = 0xff;
PORTA = 0x00;
DDRE &= ~(1<<DDE4) & ~(1<<DDE5) & ~(1<<DDE6) & ~(1<<DDE7) ;
PORTE |= 1<<DDE4 | 1<<DDE5 | 1<<DDE6 | 1<<DDE7;
EICRB |= 2<<ISC40;
EIMSK |= 1<<INT4;
SREG |= 1<<I;
BIT | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
EICRB | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
EIMSK | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
SREG | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
EICRB는 외부 인터럽트 7, 6, 5, 4 의 동작을 설정한다
EIMSK는 외부 인터럽트 7~0 개별 각각을 허용하기 위해 사용한다.
SREG는 SREG의 I 비트가 세트되어야만 EIMSK의 인터럽트가 허용이 가능한다.
지금 코드에선 4번핀에 연결된 스위치를 사용하기 때문에 EICRB에 하강에지를 넣고 EIMSK의 4번핀에 1을 집어넣는다.'
do{
PORTA = led;
_delay_ms(500);
led <<=1;
led |= 0x01;
}while(led !=0x7F);
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
PORTA | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
led<<=1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 |
led |= 0x01 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
PORTA | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
do~while반복문으로 LED가 0번핀부터 7번핀까지 순차적으로 점등된다.
do{
PORTA = led;
_delay_ms(500);
led >>=1;
led |= 0x80;
}while(led !=0xFE);
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
PORTA | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
led>>=1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 |
led |= 0x01 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 |
PORTA | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 |
do~while반복문으로 LED가 7번부터 0번까지 순차적으로 점등된다.
- 외부 인터럽트 2
#include<avr/io.h>
#include<util/delay.h>
#include<avr/interrupt.h>
#define F_CPU 16000000UL
#define I 7
unsigned char SEG[8] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8};
volatile int i = 0;
ISR(INT4_vect)
{
while((PINE & 1<<PE4) == 0){
PORTF = SEG[i];
}
}
void Initial_set(void)
{
DDRA = 0xff;
PORTA = 0x00;
DDRB = 0xff;
PORTB = 0xfe;
DDRF = 0xff;
PORTF = 0xc0;
DDRE &= ~(1<<DDE4) & ~(1<<DDE5) & ~(1<<DDE6) & ~(1<<DDE7) ;
PORTE |= 1<<DDE4 | 1<<DDE5 | 1<<DDE6 | 1<<DDE7;
EICRB |= 2<<ISC40;
EIMSK |= 1<<INT4;
SREG |= 1<<I;
}
int main(void)
{
unsigned char led = 0xFE;
Initial_set();
while(1){
do{
PORTF = 0xc0;
PORTA = led;
_delay_ms(500);
led <<=1;
led |= 0x01;
i++;
}while(led !=0x7F); // 0111 1111
do{
PORTF = 0xc0;
PORTA = led;
_delay_ms(500);
led >>=1;
led |= 0x80;
i--;
}while(led !=0xFE); // 1111 1110
}
}
- 코드설명
volatile int i = 0;
ISR(INT4_vect)
{
while((PINE & 1<<PE4) == 0){
PORTF = SEG[i];
}
}
전역변수 i를 0으로 잡고 인터럽트 함수 INT4_vect함수에 4번스위치가 작동될시 PORTF = SEG[i]코드를 작동하게 한다.
EICRB |= 2<<ISC40;
EIMSK |= 1<<INT4;
SREG |= 1<<I;
이번 실험에도 동일하게 4번핀에 연결된 스위치를 사용하기 때문에 EICRB를 통해 하강에지를 설정하고 4번핀에 외부 인터럽트를 사용하기 때문에 EIMSK에 1<<INT4로 외부 인터럽트를 설정한다.
do{
PORTF = 0xc0;
PORTA = led;
_delay_ms(500);
led <<=1;
led |= 0x01;
i++;
}while(led !=0x7F);
do~while반복문으로 led가 0번에서 7번핀까지 순차적으로 점등하며 세그먼트에는 0을 표시한다. 그리고 I++를 함으로 전역변수에 1을 증가시킨다.
do{
PORTF = 0xc0;
PORTA = led;
_delay_ms(500);
led >>=1;
led |= 0x80;
i--;
}while(led !=0xFE);
do~while반복문으로 led가 7번핀에서 0번핀까지 순차적으로 점등하며 세그먼트에 0을 표시한다.또한 전역변수인 i—를 함으로 전역변수에 1을 빼준다.
'Embedded > 마이크로프로세서' 카테고리의 다른 글
ATMEGA128 포토인터럽트 제어 실험 (0) | 2023.06.01 |
---|---|
ATMEGA128 Roullette 모형 제어 (0) | 2023.06.01 |
ATMEGA128 Motor 제어 실험 (0) | 2023.06.01 |
ATMEGA128 RELAY 제어 실험 (0) | 2023.06.01 |
ATMEGA128 FND제어 실험 (0) | 2023.06.01 |