Feb 202010
 

기본적으로 하위비트에서 상위비트로 LED가 shift되는 실험이다. 만약 인터럽트가 발생하면 반대방향으로 작동된다. 책의 예제에서는 한 주기를 마친다음에 적용되었었는데, 바로바로 방향이 바뀌도록 수정한 코드이다.

 

  

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h> 

typedef unsigned char byte;

volatile byte state = 0;

ISR(INT0_vect)
{
    state = !state;
}

int main(void)
{
    byte count = 0xfe;
    EICRA = 0x02; /* 하강앳지 인터럽트 */
    EIMSK = 0x01; /* int0 사용 */
    DDRD = 0x00;
    SREG = 0x80; /* sei */
    DDRB = 0xff;

    while(1)
    {
        if (state)
        {
            count = count << 1;
            count |= 0x01;
            if (count == 0xff)
            {
                count = 0xfe;
            }
        }
        else
        {
            count = count >> 1;
            count |= 0x80;
            if (count == 0xff)
            {
                count = 0x7f;
            }
        }

        PORTB = count;

        _delay_ms(200);
    }

    return 0;
}

Feb 152010
 

ATmega128보드에 간단하게 외부 인터럽트가 발쌩할 때마다 현재 Count를 나타내는 2진수 값을 LED로 출력하는 코드를 연습삼아 만들어 보았다.

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
typedef unsigned char Byte;
volatile Byte count;

ISR(INT0_vect)
{
    count++;
}
void Interrupt_init(void)
{
    EICRA = 0x02; // 트리거 방식설정
    EIMSK = 0x01; // 인터럽트 Enable
    DDRD = 0x00;
    SREG |= 0x80;
}
int main(void)
{
    Interrupt_init();
    DDRB = 0xff;
    count = 0;
    while(1)
    {
        PORTB = ~count;
        if (count >= 0xff) count = 0;
    }

    return 0;
}

여기서 중요한 점은 전역변수로 선언되어 있는 ‘count’변수는 ‘volatile’이라는 키워드가 설정되어 있어야 한다는 것이다.

 

 

volatile 키워드는 레지스터 변수로 사용되지 않아야한다는 것을 알리는 키워드이다. 보통 하드웨어 주소 또는 다른프로그램과 공유되는 데이터에 지정한다고 한다.

 

Reference

[1]이응혁 외 2명, “AVR ATmega128 마이크로컨트롤러”, ITC, 2009