GPIO 구동용 함수
STM32F429의 HAL 드라이버의 GPIO 구동용 함수에는 크게 3가지가 있다.
1. 초기화 및 초기화 해제용 함수
2. 입출력용 함수
3. 인터럽트 처리용 함수
1. 초기화 및 초기화 해제용 함수
HAL_GPIO_Init() : GPIO를 설정 조건에 맞추어 초기화한다.
HAL_GPIO_DeInit() : GPIO를 reset 이후 디폴트 값으로 설정(초기화 해체)한다.
2. 입출력용 함수
HAL_GPIO_ReadPin() : GPIO의 지정된 핀의 값을 읽어온다.
HAL_GPIO_WritePin() : GPIO의 지정된 핀을 0 또는 1로 설정한다.
HAL_GPIO_TogglePin() : GPIO의 지정된 핀의 값을 토글(toggle) 시킨다.
HAL_GPIO_LockPin() : GPIO의 지정된 핀의 설정 값을 변경 금지(lock) 시킨다.
3. 인터럽트 처리용 함수
HAL_GPIO_EXTI_IRQHandler() : EXTI 인터럽트의 핸들러 함수
HAL_GPIO_EXTI_Callback() : EXTI 인터럽트를 처리하기 위한 콜백 함수, 이 함수는 EXTI 핸들러 함수 EXTIx_IRQHandler() 내에서 사용된다.
HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_init)
Board Select을 통해 코드를 생성할 경우 HAL_GPIO_Init이 아닌 MX_GPIO_Init()을 확인할 수 있다.
이는 CubeIDE에서 자동으로 생성한 것으로 둘의 차이점이 존재한다.
HAL_GPIO_Init : 단일 GPIO 핀을 초기화한다.
MX_GPIO_Init : 여러 GPIO 핀과 포트를 초기화한다.
둘이 차이점이 존재하기 때문에 상황에 맞게 수정하여 사용하면 된다.
MX_GPIO_Init();을 확인해보게 되면
MX_GPIO_Inio(void)
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, LD1_Pin|GPIO_PIN_2|LD3_Pin|LD2_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(USB_PowerSwitchOn_GPIO_Port, USB_PowerSwitchOn_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin : PC13 */
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pins : PCPin PCPin PCPin */
GPIO_InitStruct.Pin = RMII_MDC_Pin|RMII_RXD0_Pin|RMII_RXD1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pins : PAPin PAPin PAPin */
GPIO_InitStruct.Pin = RMII_REF_CLK_Pin|RMII_MDIO_Pin|RMII_CRS_DV_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : PBPin PB2 PBPin PBPin */
GPIO_InitStruct.Pin = LD1_Pin|GPIO_PIN_2|LD3_Pin|LD2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pin : PF14 */
GPIO_InitStruct.Pin = GPIO_PIN_14;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = RMII_TXD1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
HAL_GPIO_Init(RMII_TXD1_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = USB_PowerSwitchOn_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(USB_PowerSwitchOn_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = USB_OverCurrent_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(USB_OverCurrent_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : PAPin PAPin PAPin PAPin */
GPIO_InitStruct.Pin = USB_SOF_Pin|USB_ID_Pin|USB_DM_Pin|USB_DP_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = USB_VBUS_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(USB_VBUS_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : PGPin PGPin */
GPIO_InitStruct.Pin = RMII_TX_EN_Pin|RMII_TXD0_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
}
위 코드와 같이 많은 Pin과 포트들을 초기화 시키고 있는 것들을 확인할 수 있다.
* 하지만 위와 같이 많은 Pin과 Port들이 초기화 되는 것은 Board Select에 의해 프로젝트가 생성될 경우 위와 같이 #define을 통해 정의된 많은 변수들에 의해 초기화된 것을 확인할 수 있다.
MCU/MPU를 통해 프로젝트를 생성할 경우
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_14, GPIO_PIN_RESET);
/*Configure GPIO pin : PC13 */
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pin : PF14 */
GPIO_InitStruct.Pin = GPIO_PIN_14;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
}
위와 같이 가장 기본 Pin에 대한 정보만 초기화 되는 것을 확인할 수 있다. (참고로 PC13은 스위치 회로에 해당한다.)
* 추가로 Board Select에 의해 프로젝트가 생성된 코드를 보게 되면
LD1_Pin|GPIO_PIN_2|LD3_Pin|LD2_Pin
위와 같이 LD1_Pin과 같이 미리 선언된 변수들을 확인할 수 있다.
Board Select에 의해 생성된 프로젝트들은 아래와 같이 미리 선언된 변수들을 통해 편리하게 사용할 수 있다.
main.h (Board Selector에 의한 생성)
...
#define MCO_Pin GPIO_PIN_0
#define MCO_GPIO_Port GPIOH
#define RMII_MDC_Pin GPIO_PIN_1
#define RMII_MDC_GPIO_Port GPIOC
#define RMII_REF_CLK_Pin GPIO_PIN_1
#define RMII_REF_CLK_GPIO_Port GPIOA
#define RMII_MDIO_Pin GPIO_PIN_2
#define RMII_MDIO_GPIO_Port GPIOA
#define RMII_CRS_DV_Pin GPIO_PIN_7
#define RMII_CRS_DV_GPIO_Port GPIOA
#define RMII_RXD0_Pin GPIO_PIN_4
#define RMII_RXD0_GPIO_Port GPIOC
#define RMII_RXD1_Pin GPIO_PIN_5
#define RMII_RXD1_GPIO_Port GPIOC
#define LD1_Pin GPIO_PIN_0
#define LD1_GPIO_Port GPIOB
#define RMII_TXD1_Pin GPIO_PIN_13
#define RMII_TXD1_GPIO_Port GPIOB
#define LD3_Pin GPIO_PIN_14
#define LD3_GPIO_Port GPIOB
#define STLK_RX_Pin GPIO_PIN_8
#define STLK_RX_GPIO_Port GPIOD
#define STLK_TX_Pin GPIO_PIN_9
#define STLK_TX_GPIO_Port GPIOD
#define USB_PowerSwitchOn_Pin GPIO_PIN_6
#define USB_PowerSwitchOn_GPIO_Port GPIOG
#define USB_OverCurrent_Pin GPIO_PIN_7
#define USB_OverCurrent_GPIO_Port GPIOG
#define USB_SOF_Pin GPIO_PIN_8
#define USB_SOF_GPIO_Port GPIOA
#define USB_VBUS_Pin GPIO_PIN_9
#define USB_VBUS_GPIO_Port GPIOA
#define USB_ID_Pin GPIO_PIN_10
#define USB_ID_GPIO_Port GPIOA
#define USB_DM_Pin GPIO_PIN_11
#define USB_DM_GPIO_Port GPIOA
#define USB_DP_Pin GPIO_PIN_12
#define USB_DP_GPIO_Port GPIOA
#define TMS_Pin GPIO_PIN_13
#define TMS_GPIO_Port GPIOA
#define TCK_Pin GPIO_PIN_14
#define TCK_GPIO_Port GPIOA
#define RMII_TX_EN_Pin GPIO_PIN_11
#define RMII_TX_EN_GPIO_Port GPIOG
#define RMII_TXD0_Pin GPIO_PIN_13
#define RMII_TXD0_GPIO_Port GPIOG
#define LD2_Pin GPIO_PIN_7
#define LD2_GPIO_Port GPIOB
...
Borad Selector로 생성하게 될 경우 많은 #define 매크로가 설정되어 있기 때문에 쉽게 가져다가 활용할 수 있다.
하지만 MCU/MPU를 통해 프로젝트를 생성하게 될 경우 어떤값도 선언되지 않을 것을 확인할 수 있다.
main.h (MCU/MPU Selector를 통해 생성)
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/
void Error_Handler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */
/* Private defines -----------------------------------------------------------*/
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
#ifdef __cplusplus
}
#endif
#endif /* __MAIN_H */
초기화에 필요한 가장 기본적인 코드 외에 어떤 코드도 작성되지 않은 것을 확인할 수 있다.
HAL, MX_GPIO_Init() 둘 전부 아래 GPIO_InitTypeDef 구조체를 사용하고 있다.
GPIO_InitTypeDef
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_InitTypeDef는 위와 같이 Pin, Mode, Pull, Speed, Alternate에 대한 구조체가 정의되어 있다.
HAL Driver에서 지원하는 ReadPin, WritePin 함수를 보게 되면 아래와 같이GPIO Port 및 Pin의 정보를 받아 조건문을 통해 결과값을 반환하고 있는 것을 확인할 수 있다.
HAL_GPIO_ReadPin, WritePin
HAL_GPIO_ReadPin
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
GPIO_PinState bitstatus;
/* Check the parameters */
assert_param(IS_GPIO_PIN(GPIO_Pin));
if((GPIOx->IDR & GPIO_Pin) != (uint32_t)GPIO_PIN_RESET)
{
bitstatus = GPIO_PIN_SET;
}
else
{
bitstatus = GPIO_PIN_RESET;
}
return bitstatus;
}
ReadPin의 경우 GPIO Port와 Pin번호를 받아 조건문을 통해 Pin 상태를 1 또는 0으로 초기화 하고 있다.
HAL_GPIO_WritePin
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
{
/* Check the parameters */
assert_param(IS_GPIO_PIN(GPIO_Pin));
assert_param(IS_GPIO_PIN_ACTION(PinState));
if(PinState != GPIO_PIN_RESET)
{
GPIOx->BSRR = GPIO_Pin;
}
else
{
GPIOx->BSRR = (uint32_t)GPIO_Pin << 16U;
}
}
WritePin의 경우 GPIO Port와 Pin 번호와 PinState 상태를 받아 Port의 Pin에 데이터를 전달하는 것을 확인할 수 있다.
'Embedded > 1. STM32, Arduino' 카테고리의 다른 글
STM32 - GPIO / 7_segment Counter 0~9까지 숫자 나타내기 (0) | 2024.05.22 |
---|---|
STM32 - GPIO 레지스터에 대하여 (MODER ~ AFRH) (0) | 2024.05.22 |
STM32 - HAL Driver / 프로잭트 생성 / GPIO (+실습) (0) | 2024.05.17 |
디지털 타이머 - (아두이노, C언어(포인터)) (0) | 2024.05.10 |
디지털 논리회로 설계 - 가산기, 인코더, 디코더, 멀티플렉서, 7_Segment (0) | 2024.04.25 |