본문 바로가기
DSP, MCU/STM32 (ARM Cortex-M)

STM32 레지스터에 접근해 GPIO 제어하기

by eteo 2022. 5. 19.

보드명 : STM32F429ZI

 

직접 메모리를 들여다보고 레지스터에 접근해 출력을 제어해보도록 하겠다.

 

이전 게시글의 코드를 그대로 사용한다.

 

2022.05.19 - [MCU/STM32 (ARM Cortex-M)] - [STM32CubeIDE] STM32 개발보드 GPIO 제어하기 (by MCU/MPU Selector)

 

[STM32CubeIDE] STM32 개발보드 GPIO 제어하기 (by MCU/MPU Selector)

보드명 : STM32F429ZI 개인 참고용 자료입니다. 새 프로젝트 생성 보드선택 프로젝트명 짓고 생성 프로젝트 매니저에서 다음 체크 주변장치 별로 소스파일, 헤더파일을 따로 생성해준다. RCC (Reset and

eteo.tistory.com

 

 

 

 

 

 

아래와 같이 파란선에서 원하는 위치에 중단점을 찍고 디버그를 시작한 후 resume 을 누르면 중단점에서 멈춘다.

 

 

 

 

 

화면 우측의 SFRs를 클릭한다. 먼저 들여다 볼 것은 GPIOB이다.

 

 

 

 

 

열어보니 GPIOB의 주소는 0x40020400 부터 시작한다.

 

 

레퍼런스 매뉴얼 65페이지에서 확인한 내용과 일치한다.

 

 

 

매뉴얼을 보니 8번부터 GPIO에 대한 내용이 나온다.

 

 

 

 

 

 

281페이지. 모드설정이 잘되어있는지부터 확인해보도록 하겠다. MODER 모드 레지스터이다.

 

설명을 보니 01이어야 General purpose output mode라고 한다.

 

 

매뉴얼에서 확인한 것과 같이

MODER0이 최하위 비트 LSB

 

MODER15가 최상위 비트 MSB이다.

 

 

 

그런데 우리가 궁금한건 GPIOB 7번핀. MODER7

다시 SFRs 화면에서 GPIOB MODER7을 확인해보면 실제 0x1 값을 가지고 있는걸 보니 output 모드인 01로 잘 설정이 돼있다.

 

참고로 16진수로 앞자리가 0이면 표시를 생략한다.

 

 

 

 

 

다음으로 ODR, output data register를 확인해보도록 한다.

1비트 단위로 제어한다.

 

 

0부터 15번핀 가운데 관심있는 핀은 7번핀이다. 지금은 값이 0x0이고 LED가 꺼져있는 상태이다.

 

 

 

 

근데 이걸 0x1로 바꾸면 LED가 켜진다.

 

 

 

 

 

참고로 그 아래에서 시각적으로 해당 비트를 클릭해서 제어하는 방법도 있다.

 

 

 

 

 

 

다른방법

 

Windows- show View- Memory를 클릭한다.

 

 

 

 

아래에서 Add Memory Monitor를 클릭하고

 

 

GPIOB의 시작번지를 입력한다.

 

그럼 이렇게 메모리를 들여다 볼 수도 있다.

 

 

 

 

ODR 번지의 Value를 찾아서 여기서 직접 값을 변경해도 LED를 조작할 수 있다. 

 

 

근데 이건 읽는 순서가 약간 애매하다. IDR을 예로 들어서 보면

 

 

GPIOB의 IDR은 1비트짜리 16개가 있어서 실제 사용하는건 총 2바이트인데 메모리맵을 보면 Reserved 된 2바이트가 있어서 IDR이 차지하는건 4바이트이다.

 

SFRs에서 보면 0x3f58 값을 가진다.

 

근데 메모리에서 해당번지를 들여다보면 583F이다.

 

상위 2바이트는 Reserved된거라 사용안하고 하위 2바이트만 사용한다. 근데 위에서 봤던 SFRs화면이랑 MSB, LSB 위치가 다르다.

 

이점만 주의하면 될 것 같다.

 

 

 

다음은 직접 소스코드를 수정해 PB7을 켜고 꺼보도록 한다.

 

GPIO_PIN_7 은 16진수로 0x0080 값을 갖는다.

 

코드의 의미는 옆에 주석처리 해두었다.

 

|= 연산으로 원하는 비트만 켜고

&= ~(반전) 연산으로 원하는 비트만 끈다.

 

 

0.5초 간격으로 켜고 꺼지는걸 볼 수 있다.

 

 

 

 

 

 

 

 

켜고 끄는데 아래처럼 하는 방법도 있다.

 

 

^= 연산하면 원하는 비트를 현재 상태에서 토글한다. 1이었으면 0이되고 0이었으면 1이 된다.

 

 

 

 

 

다음은 내장된 LD3도 같이 켜보도록 하겠다.

 

 

 

이번엔 16진수를 사용해 본다.

 

 

 

 

 

매뉴얼이랑 같이 보면 16진수로 쉽게 변환해 이해할 수 있다.

 

 

 

output의 default 상태가 0이니까 while문 위에서 PB14번만 켜둔 뒤 while문 내에서 같이 토글시키면

 

둘이 초기상태가 달랐어서 교차로 번갈아가면서 켜진다.

 

결과

 

 

 

 

 

다음은 shift 연산을 사용해서 PB7과 PB14를 통시에 켜보았다.

 

 

 

 

BSRR은 bit set/reset register로 총 4바이트인데 0-15는 셋 설정, 16-31은 리셋설정이다.

 

set 상태에서 << 16 하면 reset이 된다.

 

 

 

 

 

처음에 세팅해줄 핀이 여러개라면 아래와 같이 함수화 해두는 것도 좋은 방법이다.

 

 

 

 

 

GPIO input도 같은방법으로 제어 가능하다. 다만 IDR, input data register를 사용해야 한다.

 

그리고 아직 해보진 않았지만 IDR로 구한 값을 비트연산해서 원하는 비트들의 상태만 확인하는 식으로 코드를 짜야 활용가능할 것 같다.