데이터쉬트의 Regitster Summary에 나와있는 표에서 다음과 같은 내용을 볼 수 있다. 위의 표를 보면 PORT 레지스터가 PIN, DDR, PORT순으로 놓여져 있음을 알 수 있다. 이런 경우 구조체를 이용하면 훨씬 코드를 짜임새 있게 구현할 수 있게 된다. struct port { unsigned char pin; unsigned char ddr; unsigned char port; }; PORT B블럭안에 있는 레지스터는 PINB, DDRB, PORTB이다. 이 세개의 레지스터를 제어하기 위해서 다음과 같이 하면 된다. struct port *portb = (void*)0x23; portb변수에는 0x23이라는 주소가 들어간다. portb는 struct port라고 생긴 구조체 모양을 하고..
이번에는 조금 고급 테크닉을 사용하여 LED를 제어해 보도록 하겠다. 앞에서 매크로를 사용해서 코드를 보기 좋게 만들었다. 앞의 코드는 Data memory 공간을 이용했다면, 이번에는 C코드에서 직접 I/O 메모리 공간을 바로 접근하는 방법에 대해서 설명하겠다. 이미 LED 제어 4에서 I/O 메모리 공간에 접근하기 위해서 "in", "out"명령을 사용해야 한다고 설명했었다. 그러나 I/O 주소를 직접 사용할 수 없고 0x20만큼 offset값을 더해서 사용해야된다고 했다. C프로그램을 하다보면 C코드로는 도저히 사용할 수 없는 명령어를 사용해야 되는 경우와 어셈블러로 구현하는게 훨씬 효율적인 경우가 생긴다. 이런 요구사항을 해결하기 위해서 inline assembler기능을 사용하면 된다. #def..
이번에는 앞에서 작성했던 코드를 매크로를 이용하여 좀더 깔끔하게 수정해 보도록 하겠다. 앞에서 어떤 레지스터에 값을 쓰기 위하여 포인터를 사용했는데 다음과 같은 코드를 사용하였다. *(unsigned char*)DDRB = (GREEN_LED|RED_LED); 위의 코드를 매크로를 사용하면 다음과 같이 수정할 수 있다. #define write8(addr, val) (*(volatile unsigned char *)(addr) = (val)) 전체 코드를 위의 매크로를 이용하여 정리하면 다음과 같은 모양으로 나온다. 훨씬 깔끔하게 보일 것이다. #define F_CPU 1000000 //#include #include #define IO_REG_OFFSET 0x20 #define PINB (IO_REG_..