2007. 2. 27. 17:13

AVR을 사용하여 할 수 있는 가장 기본적인 기능은 자체 내에 가진 입출력 포트에 신호를 제어하는 것이다.

포트를 제어하는 레지스터는
포트 방향 레지스터(DDRn), 포트 출력 레지스터(PORTn), 포트 입력핀 어드레스(PINn)로 세 개의 레지스터를 이용한다.

포트를 입력으로 이용할 때는
포트 방향 레지스터(DDRn)에 '0'을 넣어 입력으로 설정한 후,
포트 입력핀 어드레스(PINn)의 데이터를 읽어오면 된다.

포트를 출력으로 사용할 때는
포트 방향 레지스터에 '1'을 넣어 출력으로 설정한 후,
포트 출력 레지스터(PORTn)로 데이터를 써 넣으면 된다.

여기서 주의해야 할 부분은 데이터 입력시 조건이다.
포트 방향 레지스터를 입력으로 설정하고 데이터를 입력받을 때, 포트 출력 레지스터의 조건에 따라 포트 입력 레지스터의 상태가 달라지기 때문이다.

포트 출력 레지스터로 '1'을 출력하면, 포트 입력 레지스터가 내부 풀업이 연결된 형태로 구성되므로 외부에서 풀업저항을 추가할 필요가 없게 된다. 하지만, 다른 디바이스와 핀을 공유할 때는 해당핀을 입력이나 출력으로 사용하지 않을 때, 포트 출력 레지스터에 '0'을 출력시켜 해당핀을 하이 임피던스 상태로 만들어 주어야 한다.

Atmega128에서는 포트 A(8), B(8), C(8), D(8), E(8), F(8), G(5)에 해당되는 53개의 핀을 일반 입출력 핀으로 사용할 수 있다. 하지만, Atmega103 compatibility mode로 사용하게 되면, 포트 C는 입력전용, 포트 F는 출력전용, 포트 G는 입출력핀으로 사용할 수 없고, TOSC1, TOSC2, /WR, /RD, ALE의 기능으로만 사용가능하다.


프로그램 예제
포트 D로부터 외부 신호를 입력받아 포트 A로 카운트된 값을 출력하는 프로그램 portD.0의 입력은 내부 변수값을 1씩 증가시키며, portD.1의 입력은 내부 변수값을 1씩 감소시키는 역할을 한다.

#include <iom128.h>
#include <ina90.h>

void Port_Init(void)
     
    outp(0xFF, DDRA);    //Port_A setting up output
    outp(0x00, DDRD);     //Port_D setting up input
    outp(0xFF, PORTD);
}

int main(void)
{
     unsigned Tmp;
     int Count;
 
     outp(0x00, MCUCR);    // External Memory Disable

     Port_Init();
     Count = 0;
     while(1)
    {
      Tmp = inp(PIND)&0x03;
          if (Tmp == 0x02)
                {
                   outp(Count, PORTA);
                   Count++;
                    if (Count >=256) Count=0;
      }
      else if (Tmp == 0x01)
                {
                   outp(Count, PORTA);
                   Count--;
                    if (Count < 0) Count=255;
      }
     }
     return 0;
}

Posted by Paul Hwang