백인감자

[STM-32] LED 켜기 실험 본문

하드웨어

[STM-32] LED 켜기 실험

백인감자 2016. 9. 10. 18:20

p.11 에서 할 때 auto configure 한 다음 save 해서 디폴트 경로로 저장하게 해야 기본경로에 rvc 파일이 저장되어서




DS-5 Command Prompt 에서 아래의 명령어를 입력할 수 있다.


cdbimporter -c 메인타겟DB경로 -t 타겟DB주소 rcv파일명.rvc    -c 옵션은 사용 안해도 된다.(디폴트 경로로 설정 됨)




참고:http://www.ctplex.com/tech/debugger/ds-5-%EC%82%AC%EC%9A%A9%EC%9E%90-db-device-database-%EC%83%9D%EC%84%B1/

http://prosigi.tistory.com/72




LED 켜기 실험-(1) LED 에 해당하는 Port 를 사용가능하도록 설정


목표: LED 1 2 3 4 를 순서대로 램프에 불이 켜지게 하는 것.


전체적인 시스템 구조도 이다.



데이터시트 49 페이지 

PD 2 3 4 7 이 LED 1 2 3 4 에 각각 대응된다.(조교님 설명)

PD 는 GPIO Port D 를 의미한다.

LED는 외부 회로상에 연결 된거기때문에.. GPIO  에서 다뤄야한다.


GPIO는 APB2 버스를 통해 접근된다. 




APB2 버스를 활성화시켜야 하기 때문에 RCC 레지스터에서 APB2 버스에 관련된 clock 을 찾아야한다.

Reset and clock control register --> RCC



레퍼런스 메뉴얼 : 121 페이지.


위의 RCC 레지스터 맵을 보면 RCC_APB2ENR  이 있다.






--레퍼런스 메뉴얼 146 쪽 --
(RM0008) 해당비트를 1로 설정하면 해당기능의 클럭이 활성화 된단다.


해당기능을 사용하기 위해서는 
RCC_APB2ENR 에서 실험에 맞는 port의 bit를 1로 만들어줘서 클럭을 공급해줘야한다.


이번실험에서는 port D 를 사용하기 때문에 위 그림에서 Bit 5(IOPD EN) 를 제어 해줘야한다. 
이 레지스터의 값을 0x20 (0010 0000)으로 하면 IOPD EN 이 1이 되기 때문에 활성화 되는 것이다.
(참고: 0x 를 쓰는 것은 16진수 를 의미한다. ex>0xFF 는 1111 1111   -->10진수 255 를 의미한다.)

   Bit

 16진수



그러면 RCC_APB2ENR 레지스터의 주소에 접근해야 한다. 



--데이터시트 33쪽--




 RCC 레지스터 영역의 시작주소(base address)가 0x40021000 이고  RCC_APB2ENR 레지스터의 

 address offset가  0x18 이므로 0x40021000 + 0x18 = 0x40021018 이  RCC_APB2ENR 레지스터의 주소가 된다.


 Address offset이 의미하는 것은
GPIO Port A부터 G까지 각각의 base address에서 Address offset 만큼을
더한 것이 해당 레지스터의 주소값이라는 것을 나타내 주고 있는 것입니다.

C/C++ 코드로 작성을 해보면

#define RCC_APB2ENR (*(volatile unsigned int *) 0x40021018)   와 같이 레지스터의 주소를 가리키고

RCC_APB2ENR  |= 0x20;  로 GPIO D  의 clock 를 활성화 시키게 한다. ( | 는 OR 연산,   Reset value가 0이라서  = 로 해도 됨)





LED 켜기 실험-(2) LED Port 제어



위의 과정으로 clock 이 공급되므로 이제는 GPIO port 에 Data를 전달해줘야한다. 


레퍼런스 매뉴얼 P.194  

GPIOx_CRL : Port configuration register low
GPIOx_CRH : Port configuration register high
GPIOx_IDR : Port input data register
GPIOx_ODR : Port output data register
GPIOx_BSSR : Port bit set/reset register
GPIOx_BRR : Port bit reset register
GPIOx_LCKR : Port configuration lock register


(CPU입장에서) LED를 켠다는것은 GPIO PORT로 High든 Low든 출력을 내보내야 함으로
GPIOx_CRL,  GPIOx_CRH,  
 GPIOx_ODR

이 3가지 레지스터를 봐야한다.
우리가 Port D 의 2 3 4 7 을 제어해야하므로 CRL 레지스터에 접근해야한다.


** CRL 과 CRH 차이는 CRL은 0~7 핀(bit?)에 관여하고 CRH는 8~15 핀에 관여한다.  port D 2 3 4 7 사용하므로 CRL 만 설명한다.

   그 외의 CNF나 MODE 의 설정 등 의 속성은 모두 동일하다.**

레퍼런스 매뉴얼 P.171

Reset Value 가  0x4444 4444  인 것을 보면 (0100 0100 ... 0100)  모든 bit 에서 CNF 가 01 이고 MODE 가 00 임을 의미한다.
MODE 가  00 인 경우는 Input mode 라서 LED 에 아무런 출력이 안되기 때문에 출력을 하려면 
00 을 제외한 나머지  MODE 중 아무거나 하면된다.
max speed 의 주파수 차이 일 뿐이라서 이번 실험에서는 01 10 11 아무 MODE 로 해도 상관없음.
General purpose output push-pull(00) 로 하면 정상적으로 됨 ( push-pull과 open-drain 차이 , General purpose 와 Alternate function 의 차이는 아직 잘 몰겠..)


CNF 의 경우 우리는 MODE 가 00 보다 무조건 큰 경우에 해당하므로  In output mode 만 신경 써주면 된다.
 GPIOD(0x400114), address offset(0x00)임을 이용하여 0x40011400으로 주소지정한다.
코드상으로는 
#define GPIOD_CRL (*(volatile unsigned int *) 0x40011400)  로 정의할 수 있다.
PD 2  3 4 7 에 해당하는 부분의 MODE 를 11로 동일하게 설정한다고 하면
GPIOD_CRL = 0x30033300;  로 해주면 된다.(OR  연산으로 할 경우 CRL 을 0으로 초기화 시킨 후 OR 시켜주면 됨) 

여기까지의 과정을 통해서 Port D 의  2 3 4 7 핀을 output mode 로 세팅한 것이다.




LED 켜기 실험-(3) port bit 제어

port bit 를 설정하려면 


레퍼런스 매뉴얼 P.173

위의 그림에서 설명하는 GPIOD_BSRR 레지스터를 사용하면 된다.

상위 16비트는 reset에 관여하고 하위 16비트는 set에 관여한다.


Address offset 을 고려하면 이 레지스터는 아래와 같이 표현할 수 있다.

#define GPIOD_BSRR (*(volatile unsigned int *) 0x40011410)


LED1 (PD 2) 에 불이 켜지게 하려면 Port D 의 Bit 2 를  set 으로  설정해줘야한다.


GPIOD_BSRR |= 0x04;//0000 0100 이므로 Bit 2 를 set 한 것임. 

이렇게 하면 LED1 에 불이 들어온다.

디버깅과정을 통해서 값이 제대로 들어갔나 보려고 BSRR 을 찍어보면 0x0000 0000 으로 된 것을 확인 할 수 있는데
이는 위의 래퍼런스에 나와있듯이 이 레지스터가 write-only 이기 때문에 값을 넣는다 해도 계속 초기화 되는 것 같다?

그렇다면 어떻게 LED1 은 불이 켜지는 것일까를 고민하다가 아래의 레지스터를 발견했다.





설명을 보면 GPIOx_BSRR 레지스터에 writing 되는 값이 이 레지스터에 set 된다고 나와있다. 
결국 디버깅과정에서 확인하려면 BSRR 레지스터가 아닌 ODR 레지스터를 봐야 하는 것이다.

LED 의 불을 끄려면 reset 을 시키면 되는데 BSRR 에서 해주거나 BRR 레지스터를 사용하면 된다.
(개인적으론 코드의 가독성을 위해서 BRR 추천)


BRR 레지스터는 reset 에만 관여하고 해당 bit가 1 되면 reset이 되기때문에 set 시키던 코드에서 레지스터주소만 BSRR에서 BSR 로 바꿔주면 된다.


#define GPIOD_BRR (*(volatile unsigned int *) 0x40011414)



LED 이 불이 켜지고 꺼지는 과정을 잘 확인하기 위해서 set과 reset 사이에 어느정도 시간 텀을 줘야 한다.



Comments