아 머리 빠개지는군. 그냥 변수에 포인터 강제형 변환을 수행하면 알기 쉬운데 숫자에 바로 포인터 강제형 변환을 수행하니깐 헷갈린다.

(*(volatile unsigned *))0x40021018 의미를 정리하기 전에 먼저 포인터에 대해서 다시 한번 정리하자.




포인터


한마디로 포인터(pointer)는 메모리의 주소를 의미한다.

int *pTemp; 이라고 했을 때, 정확히 말하면 pTemp는 포인터가 아니라 포인터를 저장할 수 있는 변수명을 말한다. 다음 예를 보자.


int temp;

int *pTemp;


printf("%p \n", (char *)temp);

printf("%p \n", &pTemp);

printf("%p \n", pTemp);


 위에서 보면 (%p 는 주소값을 출력하고 기본 자료형은 void * 이다) temp 변수를 강제로 char 형 포인터로 형변환을 시켰다. 따라서 이것은 주소값을 의미하고 바로 %p 서식자에 의해서 출력이 된다. 반면 pTemp 는 int 형 포인터 변수를 의미하므로  pTemp 변수 자체의 주소값이 존재하고 &pTemp 연산을 통해서 그 주소를 확인할 수 있다. 세번째 출력에는 pTemp 변수가 담고 있는 주소값을 출력하게 된다. 지금 당장은 쓰레기값이 입력 되었으니 이상한 주소가 출력 될 것이다.




(*(volatile unsigned *))0x40021018 


(*(volatile unsigned *)0x40021018) |= 0x8; 


'의미 자체는 0x40021018 주소에 찾아가서 0x8을 입력시켜라'이다.  0x40021018 자체는 단순한 숫자에 불과하지만 포인터로 강제형 변환을 하게 되면 주소를 나타내는 의미를 갖게 된다. 과정을 보면 (volatile unsigned *)0x40021018 에서 ()는 형변환 연산,  volatile unsigned * 형으로 숫자 0x40021018를 주소값으로 변환.




 포인터 변수나 직접 위처럼 주소값을 나타내는 정수 앞에 붙어있는 '*'연산자의 정의 : 해당 주소의 메모리 공간으로 접근해라.


char num = 0;

char *pNum;


pNum = #

*pNum = 5;


 위와 같은 문장이 있을 때 *pNum 을 좀더 자세히 분석하면 pNum 포인터 변수는 num 의 주소를 저장하고 있다. 그러므로 *연산이 실행되기 전에 pNum 은 num 의 주소값을 반환된다. 그리고 * 연산에 의해서 반환된 주소값의 메모리 공간으로 접근한다.

'MCU > ARM' 카테고리의 다른 글

ADC independent DMA (2)  (0) 2016.08.14
ADC main feature(1)  (0) 2016.08.13
SPI 통신 (3)  (0) 2016.08.11
SPI 통신 (2)  (0) 2016.08.11
SPI 통신 (1)  (0) 2016.08.11
Posted by 나무길 :