라바 세마리

[아두이노] 레지스터로 포트 직접 제어(LED예제) 본문

개발일기

[아두이노] 레지스터로 포트 직접 제어(LED예제)

3larvas 2020. 8. 15. 22:56

*

아래는 아두이노 제일 기본 예제인 LED예제이다.

(거의 Hello world 급)

const int LED_PIN_1 = 23; 

void setup() {
   pinMode(LED_PIN_1, OUTPUT);
}

void loop() {
   digitalWrite(LED_PIN_1, HIGH);
   delay(1000);
   digitalWrite(LED_PIN_1, LOW);
   delay(1000);
}

LED가 1초를 주기로 깜박이는 코드이다.

이 정도 예제야...

요새는 초등학생도 돌릴 줄 안다.

그래도 비싼 돈 주고 다니며 배우는 대학생인데

좀 더 멋지고 있어보이게 코드를 짜보자.

먼저 준비물

(아두이노 듀에 보드 기준)

- 아두이노 보드 회로도

arduino-Due-schematic.pdf
0.07MB

- 아두이노 보드 MCU datasheet

Atmel-11057-32-bit-Cortex-M3-Microcontroller-SAM3X-SAM3A_Datasheet.pdf
5.83MB

먼저 코드부터 보면

int *PTR_OER  = (int*) 0x400E0E10;
int *PTR_ODSR = (int*) 0x400E0E38;

void setup() {
  *PTR_OER = 16384;
}

void loop() {
   *PTR_ODSR = 16384;
   delay(1000);
   *PTR_ODSR = 0;
   delay(1000);
}

크.....

있어보인다.

결과적으로 위의 코드와 동일하게 동작한다.

다음의 차례를 따라가면 위와 같은 코드를 짤 수 있다.

1. 포트정보 확인

아두이노 보드 회로도로 해당 핀의 포트정보를 확인한다.

(아두이노 듀에 보드 기준)

23번 핀을 LED output으로 사용할 예정인데

해당 핀은 PORTA14 포트와 연결되어있음을 확인하였다.

2. 사용할 레지스터 주소확인

LED예제에 필요한 레지스터는 총 2개다.

- OER (output enable register)

: 해당 포트를 output모드로 설정해주는 레지스터이다.

pinMode(LED_PIN_1, OUTPUT);

위의 코드에 해당하는 기능을 담당한다.

- ODSR (output data status register)

: 해당 포트에 data상태를 설정하는 레지스터이다.

digitalWrite(LED_PIN_1, HIGH);

위의 코드에 해당하는 기능을 담당한다.

각각의 레지스터 주소는 MCU datasheet에서 확인할 수 있다.

* OER (636p)

사용할 포트가 PORTA이므로 주소는 0x400E0E10이다.

* ODSR(644p)

사용할 포트가 PORTA이므로 주소는 0x400E0E38이다.

3. 해당 레지스터에 값 저장

이제 레지스터의 주소를 알았으니 값을 넣어주면된다.

코드를 다시 살펴보면.

int *PTR_OER  = (int*) 0x400E0E10;
int *PTR_ODSR = (int*) 0x400E0E38;

void setup() {
  *PTR_OER = 16384;
}

void loop() {
   *PTR_ODSR = 16384;
   delay(1000);
   *PTR_ODSR = 0;
   delay(1000);
}

레지스터 주소를 포인터 변수로 지정해준 뒤

먼저, PTR_OER주소에 16384값을 저장하였다.

16384정체는 바로

2^14

이진수로 표현하면

0100 0000 0000 0000

이다.

오호 14번째 자리에만 1로 지정되어있다.

왜냐하면 사용할 output 핀인 PORTA 14 포트이기 때문이다.

만약 2개의 핀, PORTA14와 PORT5를 output 핀으로 설정하고 싶다면

16416 = 16384 + 32

2^14 + 2^5

이진수로는

0100 0000 0010 0000

을 해당 레지스터에 저장해주면 된다.

신기하다.

위와 마찬가지로

PRT_ODSR 레지스터에도 16384값을 입력했다가. (digitalWrite HIGH)

1초의 딜레이 후에 0값을 다시 입력해준다. (digitalWrite LOW)