GPIO

Pages List
List view
Home
Portfolio
HW
FW
SW
FPGA / Adaptive SoC
Daily
Photo
Etc
 
STM32 Peripheral

GPIO


notion image

GPIO에 대하여


  • GPIO MODE register의 Reset Value
    • notion image
 
  • GPIO가 Input 모드일 때는 Output driver가 Off이지만, Output 모드일 때는 Input Driver가 On이므로, 출력값을 다시 읽을 수 있다.
  • GPIO Output Type 레지스터, GPIO Output Speed 레지스터는 오로지 GPIO가 Output 모드일 때에만 적용된다.
    • OSPEED 레지스터로, GPIO의 H -> L 또는 L to H의 Transition 속도를 결정할 수 있다. (즉, Pin의 Slew rate를 control할 수 있다.)
      (각 속도 옵션이 의미하는 스위칭 속도(주파수)는 stm32f407vg 데이터시트의 117p 참고)
      • notion image
 
  • GPIO 핀에는 16개의 Alternative Functionality가 존재한다. (AF0 ~ AF15. stm32f407vg 데이터시트 참고)
    • GPIO_AFRL : 핀 0~7, GPIO_AFRH : 핀 8~15
 
  • RCC는 mcu의 모든 영역의 clock을 제어하는 engine이다. (AHB domain, APB domain, processor domain, memory domain, etc)
    • notion image
 
 

프로젝트의 전체 구조


  • 프로젝트의 전체 아키텍처
    • < High level project architecture >
      < High level project architecture >
      MCU의 Peripheral들을 제어하기 위한 Driver Layer가 존재하고, 이 Driver Layer들로 APIs를 작성한다.
 
  • Device Header 파일(stm32f407vg.h)에 들어갈 내용들은 다음과 같다.
    • notion image
 
  • Application과 Driver 소스 파일들은 MCU의 특정 세부사항에 접근하기 위해 device header 파일을 include한다.
    • notion image
 
 

Peripheral 레지스터에 대한 구조체 작성


  • MCU의 모든 레지스터 주소를 다루기 위해 Memories, Peripheral들의 Base address처럼 매크로를 작성하는 것은 매우 비효율적이기 때문에 구조체를 이용하는 것이 바람직하다.
    • notion image
      Derefernce 부분을 더 깔끔하게 정리하면, 다음과 같다.
       
      notion image
 
  • volatile qualifier를 각 레지스터 주소에 달아주는 이유는 레지스터에 데이터를 읽거나 쓸 때, 컴파일러가 반복적인 레지스터 접근을 최적화시키는 것을 방지하기 위함이다.
    (다시 말해, 레지스터에 값을 쓰거나 읽을 때마다 해당 주소를 매번 참조하도록 하는 것이다.)
    • notion image
 
 

Peripheral에 대한 Macro 작성


  1. Peripheral Definitions를 작성한다.
    1. notion image
 
  1. Peripheral Macros를 작성한다.
    1. notion image
 
 

GPIO Handle Structure와 Configurable Structure


  • Driver Layer는 User application이 Config 할 수 있는 구조체를 제공해주어야 한다.
    (User API는 주어진 구조체에 조작하고 싶은 GPIO의 port를 알려주고, 해당 port의 각 pin의 세팅을 설정한다.)
    • < stm32f407xx_gpio_driver.h >
      < stm32f407xx_gpio_driver.h >
 
 

Driver APIs 작성


Peripheral의 Driver API를 이용해 Peripheral을 제어할 수 있다.
Peripheral의 Driver API를 이용해 Peripheral을 제어할 수 있다.
 
notion image
Driver APIs의 Definition은 “stm32f407xx_gpio.c”를 참고해라.
(섹션 24~26이 API함수의 정의부분을 작성하는 내용인데, 해당 c파일을 참고해서 이해되면 끝이다.)
 

Tip) do-while condition zero loop

C 프로그래밍에서 하나의 C 매크로를 사용해, 여러개의 statement를 실행하는 테크닉이다.
(이 매크로를 쓰는 곳에서 세미콜론을 붙이기 때문에, do-while 끝에는 세미콜론을 붙이지 않는다.)
notion image
 
 

예제 1) LED Toggling


Output type을 Push-Pull (with No Pull-Up/Down) 으로 설정하면, LED가 정상적으로 깜빡거린다.
그러나 Output type을 Open-Drain (with No Pull-Up/Down) 으로 설정하면, LED가 전혀 깜빡거리지 않는다.
Pull-Up 저항이 없는 Open-Drain 상태에서의 출력은 Low 또는 Floating(Hi-z)이기 때문이다.
여기서 Pull-Up 저항을 Enable하면, 출력은 High 또는 Low가 되어 LED가 깜빡거리기는 하는데 Pull-Up 저항의 크기가 매우 커서(40kohm) LED의 밝기가 매우 어둡다.
notion image
특정한 이유가 없는 일반적인 상황에서는 GPIO의 Output Type을 Push-Pull로 설정한다.
 
 

예제 2) LED ON/OFF by using Button


GPIO를 사용할 때, 주의해야할 점이 있다. 다음과 같이 PA15, PA14, PA13, PB4, PB3는 Debug에 사용되는 Pin이므로, 해당 Pin을 GPIO로 사용하지 않는 것이 바람직하다.
notion image
 
PA15, PA14, PA13, PB4, PB3 은 Reset 직후에 Alternative Function 모드로 설정된다.
notion image
 
 

GPIO Interrupt


notion image
EXTI0-> IRQ6
EXTI4 -> IRQ10
EXTI5-9 -> IRQ23(single IRQ number. GPIO의 Pin5~9는 1개의 IRQ로 간주된다.)
EXTI10-15 -> IRQ40(single IRQ number. GPIO의 Pin10~15는 1개의 IRQ로 간주된다.)
 
EXTI block은 Edge detection과 Processor(NVIC)로의 interrupt delivery를 Enable/Disable 한다.
NVIC에서는 NVIC 레지스터로 각각의 IRQ를 Enable/Disable한다.
어떤 GPIO port가 EXTI line을 차지할지는 SYSCFG_EXTICR에서 결정된다.
 
EXTI와 NVIC은 각각 Pending register를 갖고 있다.
IRQ를 disable해도 해당 IRQ가 이미 NVIC pending register에 들어와 있으면, ISR이 실행된다.
[ GPIO Pin Interrupt 설정 방법 ]
[ GPIO Pin Interrupt 설정 방법 ]
 
  1. GPIO Pin configuration as Input mode
  1. Configure EXTI block such as Edge trigger setting(RT, FT, RFT), IMR(Interrupt mask)
  1. Enable Clock of SYSCFG and Configure SYSCFG block such as PortCode
  1. Configure NVIC block such as IRQ number, priority
  1. Write ISR corresponding IRQ number
  1. Make sure that Store the address of ISR at the vector address location corresponding to the IRQ number
 
[ Startup 파일에 weak로 정의된 ISR ]
[ Startup 파일에 weak로 정의된 ISR ]
 
Startup 파일에 가보면, ISR들이 weak attribute로 이미 존재하는 것을 볼 수 있다.
User application에서 동일한 이름으로 ISR을 작성하여, override하면 된다.
 

Tip) memset

구조체를 처음 생성할 때, 구조체의 멤버들에 쓰레기값이 들어있을 수 있다.
이 쓰레기값들을 모두 0으로 초기화하지 않으면, 심각한 문제를 초래할 수 있기 때문에 구조체를 생성할 때는 항상 “memset”을 사용해 0으로 초기화해주는 습관을 갖는 것이 바람직하다.
notion image