728x90
반응형
맨 위로 올라가기
Program Flowchart.

 

Start
Hardware Initialization HAL_Init()
System Clock Configuration SystemClock_Config()
GPIO Initialization(Configuration) MX_GPIO_Init()
@Turning on the LED HAL_GPIO_WritePin()
0.5sec delay HAL_Delay()
Turning off the LED HAL_GPIO_WritePin()
0.5sec delay HAL_Delay()

 

 

먼저 하드웨어 초기화 함수인 HAL_Init()은 Firmware Library Package에서 제공하는 함수이다.

 

HAL_StatusTypeDef HAL_Init(void)

- Description: STM32F4의 HAL을 초기화.

- Header: stm32f4xx_hal.h

- Input: void

- Return: HAL_StatusTypeDef

 

다음으로 SystemClock_Config() 함수를 호출한다. 이 함수는 main() 함수 바로 아래에 구현되어 있다.

 

GPIO에 대한 설정은 단순 반복작업으로 귀찮기도 하고 실수할 여지가 많다.

그런 의미에서 STM32CubeMX에서 제공하는 코드 생성 기능은 상당히 편리한데, 아무리 편리하더라도

어느 정도 코드의 구조와 내용을 이해할 필요는 있다.

 

static void MX_GPIO_Init(void)

- Description: GPIO를 초기화.

- Header: 없음. main.c 파일에 구현

- Input: void

- Return: void

 

/*
 * ap.c
 *
 *  Created on: Jan 23, 2024
 *      Author: chmnq
 */

#include "ap.h"

void apInit(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);

  /*Configure GPIO pin : PA5 */
  GPIO_InitStruct.Pin = GPIO_PIN_5;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void apMain(void)
{
  while(1)
  {
    //HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
    HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
    delay(500);
//    HAL_Delay(500);
  }
}

 

MX_GPIO_Init() 함수 내 가장 위 코드 확인

 

GPIO_InitTypeDef 자료형은 stm32f4xx_hal_gpio.h에 정의된 구조체이다.

GPIO_InitTypeDef 구조체는 GPIO의 각종 설정 정보를 저장하며 아래와 같이 정의되어 있다.

 

typedef struct
{
  uint32_t Pin;       /*!< Specifies the GPIO pins to be configured.
                           This parameter can be any value of @ref GPIO_pins_define */

  uint32_t Mode;      /*!< Specifies the operating mode for the selected pins.
                           This parameter can be a value of @ref GPIO_mode_define */

  uint32_t Pull;      /*!< Specifies the Pull-up or Pull-Down activation for the selected pins.
                           This parameter can be a value of @ref GPIO_pull_define */

  uint32_t Speed;     /*!< Specifies the speed for the selected pins.
                           This parameter can be a value of @ref GPIO_speed_define */

  uint32_t Alternate;  /*!< Peripheral to be connected to the selected pins. 
                            This parameter can be a value of @ref GPIO_Alternate_function_selection */
}GPIO_InitTypeDef;

 

 

 

다음으로 GPIO Clock을 활성화한다.

모든 주변장치는 동기화된 디지털 회로로 클록을 필요로 한다.

다만 전력 소모를 낮추기 위해 사용하지 않는 주변장치는 Clock 을 deactivated 하는데,

반대로 주변장치를 사용하기 위해서는 Clock을 activate해야 한다.

 

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

 

 

위 코드는 클록 활성화를 위한 매크로로 stm32f4xx_hal_rcc_ex.h에 정의되어 있다.

STM32F4XX_HARDWARE ABSTRACTION LAYER_RESET AND CLOCK CONTROL_EXTENSION.HEADER

(GPIOX 클록 비/활성화, GPIO 클록 비/활성화 여부 체크)

/* Exported macro ------------------------------------------------------------*/
/** @defgroup RCC_Exported_Macros RCC Exported Macros
  * @{
  */

/** @defgroup RCC_AHB1_Clock_Enable_Disable AHB1 Peripheral Clock Enable Disable
  * @brief  Enable or disable the AHB1 peripheral clock.
  * @note   After reset, the peripheral clock (used for registers read/write access)
  *         is disabled and the application software has to enable this clock before
  *         using it.
  * @{
  */
#define __HAL_RCC_GPIOA_CLK_ENABLE()   do { \
                                        __IO uint32_t tmpreg = 0x00U; \
                                        SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);\
                                        /* Delay after an RCC peripheral clock enabling */ \
                                        tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);\
                                        UNUSED(tmpreg); \
                                          } while(0U)
#define __HAL_RCC_GPIOB_CLK_ENABLE()   do { \
                                        __IO uint32_t tmpreg = 0x00U; \
                                        SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOBEN);\
                                        /* Delay after an RCC peripheral clock enabling */ \
                                        tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOBEN);\
                                        UNUSED(tmpreg); \
                                          } while(0U)

 

Clock Frequency가 낮으면 동작은 느려지지만 보다 저전력에서 동작하고

Clock Frequency가 높으면 동작은 빨라지지만 전력소모는 다소 올라간다.

 

GPIO 동작의 속도는 공급전압(Vdd), 부하 캐패시터(Cl)의 영향을 받는다.

공급전압이 높아질수록, 또는 부하 캐패시터가 작을수록 동작 주파수가 높아진다.

따라서 이렇게 구조체 변수 GPIO_InitStruct에 값을 대입한다고 해서 하드웨어적인 설정이 완료되는 것은 아니다.

이 변수는 포인터 변수가 아니기 때문에 이 값을 해당 레지스터에 써주어야 한다.

이러한 동작을 하는 함수가 stm32f4xx_hal_gpio.c에 정의된 HAL_GPIo_Init() 함수이다.

 

void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)

 

- Description: GPIO를 설정에 맞게 초기화

- Header: stm32f4xx_hal_gpio.h

- Input:

GPIO_TypeDef *GPIOx: STM32F4의 GPIO.x는 A부터 K까지

GPIO_InitTypeDef *GPIO_Init: GPIO 설정정보를 가지고 있는 구조체 포인터.

- Return: void

 

HAL_GPIO_INIT(LD2_GPIO_Port, &GPIO_InitStruct);

 

 

첫번째 입력변수 LD2_GPIO_Port 는 위에서 본 바와 같이 GPIOA의 재정의 매크로로서 설정을 하고자 하는 포트가 들어간다. 다음으로 &GPIO_InitStruct는 구조체 변수 GPIO_InitStruct의 주소값이 입력으로 들어가는 것으로 여기에 대입된 값들을 해당 레지스터에 복사된다.

HAL_GPIOI_Init() 함수는 프로젝트 하위 Driver/SRC/stm32f4xx_hal_gpio.c에 정의되어 있다.

 


 

이제 LED를 점멸시키기 위한 코드가 필요하다.

LED를 점멸시키기 위해서는 GPIOA의 출력 데이터 레지스터의 5번째 비트에 1 또는 0을 써 넣어야 한다.

LED를 점멸하는 동작은 무한루프를 이용한다.

보통 임베디드 시스템은 전원을 켜면 동작을 시작하여 전원을 끄기 전까지는 정해진 동작을 계속 수행하게 된다.

이것은 임베디드 시스템에서 가장 기본적인 패턴이며 거의 모든 프로그램은 이 구조로 되어 있다.

STM32CubeMX를 활용하여 코드를 자동으로 생성하였기 때문에 이 무한루프가 이미 만들어져 있고

무한 루프 내부에 반복 수행하는 사용자 코드를 입력하면 된다.

GPIO의 핀에 값을 출력하는 함수는 HAL_GPIO_WritePin()이다.

 

void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_Pinstate Pinstate)

 

GPIO_Pinstate Pinstate: GPIO_PIN_SET > 1 || GPIO_PIN_RESET > 0

 

 

728x90
반응형

'Firmware & Embedded > ARM' 카테고리의 다른 글

About Bootloader.  (0) 2024.02.13
STM32CubeIDE for mac  (0) 2024.02.12
USB CDC(Communication Device Class)  (0) 2024.01.24
How to connect to a debugger  (0) 2024.01.23
Nucleo-F401RE Dev-Board with STM32F401RE MCU  (0) 2024.01.19

+ Recent posts