이 영역을 누르면 첫 페이지로 이동
천천히 꾸준히 조용히 블로그의 첫 페이지로 이동

천천히 꾸준히 조용히

페이지 맨 위로 올라가기

천천히 꾸준히 조용히

천천히 꾸준히 조용히.. i3months 블로그

[Embedded] General Purpose Input Output

  • 2026.04.30 16:23
  • Computer Science/Embedded Software
반응형

 

 

GPIO는 General Purpose Input Output의 약자로 범용적으로 사용할 수 있는 프로세서의 표준 인터페이스이다.

핀들을 Input / Ouput / Alternate Function / Analog 등으로 설정해서 사용할 수 있음. 

 

GPIO 핀 하나를 제어하려면 클럭을 켜고, 레지스터로 모드를 설정하고, 데이터 레지스터로 읽기 쓰기 작업을 수행해야 함.

 

 

 

 

 

STM32F429는 Cortex-M4 코어를 사용하는 SoC로, 버스가 두 종류로 나뉜다.

AHB 버스는 고속으로 CPU와 메모리 사이를 중개하고, APB 버스는 저속으로 CPU와 주변장치를 중개함.

 

메모리는 CPU와 같은 속도로 돌아야 하지만 UART 같은 주변장치는 대충 돌아도 된다. (이미 외부 통신 속도가 정해짐)

당연히 같은 속도로 돌면 좋지만 전력을 아끼기 위해.. 

GPIO는 AHB1에 붙어있음. 토글 속도가 중요하기 때문

 

 

GPIO는 무조건 레지스터를 통해 사용된다.

즉, GPIO 핀은 메모리에 매핑된 8개의 레지스터로 제어한다는 것.

 

4개 레지스터는 핀 모드, 출력 타입 및 속도를 정의하고, 2개 레지스터는 읽기 쓰기 역할을 정의하고, 나머지 레지스터는 비트를 조작함.

모두 AHB1 영역의 정해진 주소에 박혀있고 정해진 Offset에 차례대로 배치된다. 

 

 

 

 

 

설정 예시를 보면 MODER 레지스터는 핀당 2비트를 할당하고, 2비트는 정확히 모드 4개와 매칭된다. (Input, Output, AF, Analog)

표에 각 모드마다 어떤 조합이 가능한지 정리되어있음. 필요할 때 참고해서 사용.. 

 

STM32는 기본적으로 모든 주변장치 클럭이 꺼져있고, RCC 레지스터로 활성화하지 않으면 GPIO가 동작하지 않음에 주의.

 

 

 


 

 

 

 

메모리에 매핑된 레지스터를 C로 안전하게 읽기 쉽게 다뤄보자. struct, #define, volatile 키워드를 사용함.

 

레지스터에 접근하는 방식은 크게 두 가지로 나뉜다.

 

#define GPIOA_CRL  (*((volatile unsigned long *)(0x40010800)))
#define GPIOA_ODR  (*((volatile unsigned long *)(0x4001080C)))

void GPIOA_reset(void) {
    GPIOA_CRL = 0;
    GPIOA_ODR = 0;
}

 

 

직접 주소를 명시하거나 struct로 묶을 수 있음.

C 컴파일러는 struct 내부 멤버를 선언 순서대로 메모리에 배치하니 하드웨어 메모리가 그대로 struct로 이어진다.

이런 특징 덕분에 

 

1. *((volatile uint32_t*)(BASE+0x14))
2. GPIOA->ODR

 

 

1번 대신 2번으로 간결하게 표현할 수 있음.

 

 

코드 작성 시 보기 힘든 16진수가 많으면 가독성도 떨어지고 뭐라는지 모르니까 GPIO 관련 핀번호를 레지스터에서 관련된 위치 값으로 정의해둔다.

이 때 ENUM과 매크로를 사용하기도 함 

 

임베디드 프로그래밍에서는 volatile 키워드를 잘 사용해야 함. 다른 파트에서는 컴파일러의 최적화가 도움이 되지만, 임베디드에서는 조심해야 한다.

일반 변수에는 적당한 최적화지만 하드웨어 레지스터에는 치명적인 최적화가 있을 수 있음. 

 

GPIOA->ODR = 1;
GPIOA->ODR = 0;
GPIOA->ODR = 1;

 

 

이 경우 컴파일러가 마지막 라인을 지워버리면 하드웨어 레지스터에게 치명적이다.

 

 

 

void BSP_LED_Init(Led_TypeDef Led)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    // ① 클럭 enable
    LEDx_GPIO_CLK_ENABLE(Led);
    
    // ② 핀 모드 설정 (struct에 옵션 채우기)
    GPIO_InitStruct.Pin   = GPIO_PIN[Led];
    GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull  = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
    HAL_GPIO_Init(GPIO_PORT[Led], &GPIO_InitStruct);
    
    // ③ 초기 출력값
    HAL_GPIO_WritePin(GPIO_PORT[Led], GPIO_PIN[Led], GPIO_PIN_SET);
}

 

 

클럭을 켜고 모드를 설정하고 데이터를 쓰는 과정.

4단계 절차를 그대로 따라간다. 

 

 

디버깅 시에는 시리얼 포트나 LED 출력을 사용하거나 assert_param() 함수를 사용한다.

 

#ifdef USE_FULL_ASSERT
  #define assert_param(expr) \
    ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
#else
  #define assert_param(expr) ((void)0)
#endif

 

 

assert_param(IS_GPIO_PIN(pin)) 코드는 위의 빌드 설정에 따라 두 가지로 컴파일됨.

릴리즈 설정에서는 아예 저 부분이 코드에서 사라지고, 디버깅 설정에서는 Parameter를 검사해 출력해준다.

 

프론트 개발할때 env에 빌드 설정 박아두고 console.log 치는 것과 비슷함. 

 

실제 사용할 때는 함수 진입 직후에 박혀서 잘못된 인자가 들어오면 실행을 중단하고 위치를 출력함.

 

반응형
저작자표시 (새창열림)

'Computer Science > Embedded Software' 카테고리의 다른 글

[Embedded] ARM Assembly  (0) 2026.05.10
[Embedded] Interrupt  (0) 2026.03.31
[Embedded] Cortex-M4 Processor  (0) 2026.03.18

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • [Embedded] ARM Assembly

    [Embedded] ARM Assembly

    2026.05.10
  • [Embedded] Interrupt

    [Embedded] Interrupt

    2026.03.31
  • [Embedded] Cortex-M4 Processor

    [Embedded] Cortex-M4 Processor

    2026.03.18
다른 글 더 둘러보기

정보

천천히 꾸준히 조용히 블로그의 첫 페이지로 이동

천천히 꾸준히 조용히

  • 천천히 꾸준히 조용히의 첫 페이지로 이동

검색

방문자

  • 전체 방문자
  • 오늘
  • 어제

카테고리

  • 분류 전체보기 (695) N
    • Algorithm (205)
      • Data Structure (5)
      • Theory && Tip (33)
      • Baekjoon (166)
      • ALGOSPOT (1)
    • Spring (123)
      • Spring (28)
      • Spring Web MVC (20)
      • Spring Database (14)
      • Spring Boot (6)
      • Spring 3.1 (11)
      • Spring Batch (6)
      • Spring Security (16)
      • JPA (12)
      • Spring Data JPA (5)
      • QueryDSL (4)
      • eGovFramework (1)
    • Programming Language (74)
      • C (25)
      • C++ (12)
      • Java (19)
      • JavaScript (15)
      • Python (1)
      • PHP (2)
    • Computer Science (154) N
      • Machine Learning (38)
      • Operating System (18)
      • Computer Network (28)
      • System Programming (22)
      • Universial Programming Lang.. (8)
      • Data Science (8) N
      • Embedded Software (4) N
      • Computer Architecture (4)
      • Compiler Design (11)
      • Computer Security (13)
      • BlockChain (0)
    • Database (21)
      • Database (7)
      • MySQL (3)
      • Oracle (3)
      • Redis (5)
      • Elasticsearch (3)
    • DevOps (20)
      • Docker && Kubernetes (8)
      • Jenkins (4)
      • Amazon Web Service (8)
    • Mobile (28)
      • Android (21)
      • Flutter (7)
    • 💡 솔루션 (17)
    • 👥 모각코 (12)
    • 💬 기록 (9)
    • 📚 공부 (7)
    • -------------- (25)

최근 글

나의 외부 링크

메뉴

  • 홈
반응형

정보

i3months의 천천히 꾸준히 조용히

천천히 꾸준히 조용히

i3months

블로그 구독하기

  • 구독하기
  • RSS 피드

티스토리

  • 티스토리 홈
  • 이 블로그 관리하기
  • 글쓰기
Powered by Tistory / AXZ. Copyright © i3months.

티스토리툴바