본문으로 바로가기

GPIO 입출력 제어하기(STM32F429I Discovery)

category MCU/STM32F429 2020. 4. 5. 23:04
반응형

STM32F429I Discovery 보드에 있는 User 버튼과 User LED를 제어를 해보려고 합니다. 

소스 코드는 맨 아래를 확인하시면 됩니다.

 

 CubeMX 설정


USER LED인 LD3, LD3은 GPIO OUTPUT으로 설정되어 있습니다.




PA0는 인터럽트로 설정이 되어있는데 Input으로 설정해도 되고 읽는데는 문제 없습니다.



Configuration 탭에서 LED 핀의 설정입니다. 소스코드에는 어떻게 되어있는지 확인해보도록 하겠습니다.





 생성된 코드


생성된 소스의 메인 함수의 MX_GPIO_Init();에 GPIO 설정을 볼 수 있습니다. 코드에 대해서 살펴보겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
static void MX_GPIO_Init(void)
{
 
  GPIO_InitTypeDef GPIO_InitStruct;
 
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOG_CLK_ENABLE();
  __HAL_RCC_GPIOE_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, NCS_MEMS_SPI_Pin|CSX_Pin|OTG_FS_PSO_Pin, GPIO_PIN_RESET);
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(ACP_RST_GPIO_Port, ACP_RST_Pin, GPIO_PIN_RESET);
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOD, RDX_Pin|WRX_DCX_Pin, GPIO_PIN_RESET);
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOG, LD3_Pin|LD4_Pin, GPIO_PIN_RESET);
 
  /*Configure GPIO pins : NCS_MEMS_SPI_Pin CSX_Pin OTG_FS_PSO_Pin */
  GPIO_InitStruct.Pin = NCS_MEMS_SPI_Pin|CSX_Pin|OTG_FS_PSO_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
  /*Configure GPIO pins : B1_Pin MEMS_INT1_Pin MEMS_INT2_Pin TP_INT1_Pin */
  GPIO_InitStruct.Pin = B1_Pin|MEMS_INT1_Pin|MEMS_INT2_Pin|TP_INT1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_EVT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
  /*Configure GPIO pin : ACP_RST_Pin */
  GPIO_InitStruct.Pin = ACP_RST_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(ACP_RST_GPIO_Port, &GPIO_InitStruct);
 
  /*Configure GPIO pin : OTG_FS_OC_Pin */
  GPIO_InitStruct.Pin = OTG_FS_OC_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_EVT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(OTG_FS_OC_GPIO_Port, &GPIO_InitStruct);
 
  /*Configure GPIO pin : BOOT1_Pin */
  GPIO_InitStruct.Pin = BOOT1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(BOOT1_GPIO_Port, &GPIO_InitStruct);
 
  /*Configure GPIO pin : TE_Pin */
  GPIO_InitStruct.Pin = TE_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(TE_GPIO_Port, &GPIO_InitStruct);
 
  /*Configure GPIO pins : RDX_Pin WRX_DCX_Pin */
  GPIO_InitStruct.Pin = RDX_Pin|WRX_DCX_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
 
  /*Configure GPIO pins : LD3_Pin LD4_Pin */
  GPIO_InitStruct.Pin = LD3_Pin|LD4_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
 
}


코드를 보면 먼저 GPIO 구조체 GPIO_InitTypeDef GPIO_InitStruct;

GPIO 클럭 Enable __HAL_RCC_GPIOG_CLK_ENABLE();

사용 핀 GPIO_InitStruct.Pin

사용 모드 GPIO_InitStruct.Mode

풀업 관련 설정 GPIO_InitStruct.Pull

스피드 GPIO_InitStruct.Speed

해당 GPIO 초기화 HAL_GPIO_Init(GPIOG, &GPIO_InitStruct)

이렇게 설정을 해야 합니다.



사용하는 핀에는 GPIO 번호가 들어가게 됩니다. (ex. GPIO_InitStruct.Pin = GPIO_PIN_13)

사용 모드에서는 여러 가지 모드가 있습니다.




1
2
3
4
5
#define  GPIO_MODE_INPUT                        0x00000000U   /*!< Input Floating Mode                   */
#define  GPIO_MODE_OUTPUT_PP                    0x00000001U   /*!< Output Push Pull Mode                 */
#define  GPIO_MODE_OUTPUT_OD                    0x00000011U   /*!< Output Open Drain Mode                */
#define  GPIO_MODE_AF_PP                        0x00000002U   /*!< Alternate Function Push Pull Mode     */
#define  GPIO_MODE_AF_OD                        0x00000012U   /*!< Alternate Function Open Drain Mode    */


Input, Output, AF 등이 있는데 AF는 Alternate Function에 약자로 Uart 통신, PWM 등을 할 때 사용합니다.





1
2
3
#define  GPIO_NOPULL        0x00000000U   /*!< No Pull-up or Pull-down activation  */
#define  GPIO_PULLUP        0x00000001U   /*!< Pull-up activation                  */
#define  GPIO_PULLDOWN      0x00000002U   /*!< Pull-down activation    


Pull up 종류입니다. 저희는 Pull 없이 필요 없기 때문에 GPIO_NOPULL을 사용합니다.





1
2
3
4
#define  GPIO_SPEED_FREQ_LOW         0x00000000U  /*!< IO works at 2 MHz, please refer to the product datasheet */
#define  GPIO_SPEED_FREQ_MEDIUM      0x00000001U  /*!< range 12,5 MHz to 50 MHz, please refer to the product datasheet */
#define  GPIO_SPEED_FREQ_HIGH        0x00000002U  /*!< range 25 MHz to 100 MHz, please refer to the product datasheet  */
#define  GPIO_SPEED_FREQ_VERY_HIGH   0x00000003U  /*!< range 50 MHz to 200 MHz, please refer to the product datasheet  */


GPIO Speed 설정입니다. 주석에 Speed에 대해서 자세히 나와있네요.






1
2
3
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOG, LD3_Pin|LD4_Pin, GPIO_PIN_RESET);
 


GPIO_PIN_RESET을 하는 경우 해당핀은 '0'이 되고 GPIO_PIN_SET을 하는 경우 '1'이 됩니다.







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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;
}



GPIO_PinState HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)값을 통해서 해당 핀을 Read 할 수 있습니다.






 회로도



PA0에 버튼이 있습니다. 버튼이 눌리면 '1'이고 떼어지면 '0' 상태네요.




PG13과 PG14에 LED가 있고 '1'일 때 LED가 켜지고 '0'이면 꺼진 상태가 됩니다.






 소스 코드


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
int main(void)
{
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 1 */
 
  /* MCU Configuration----------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_CRC_Init();
  MX_DMA2D_Init();
  MX_FMC_Init();
  MX_I2C3_Init();
  MX_LTDC_Init();
  MX_SPI5_Init();
  MX_TIM1_Init();
  MX_USART1_UART_Init();
  MX_USB_HOST_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
 
  /* USER CODE END WHILE */
    MX_USB_HOST_Process();
 
  /* USER CODE BEGIN 3 */
    if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0))  
        HAL_GPIO_WritePin(GPIOG, LD3_Pin|LD4_Pin, GPIO_PIN_RESET);
    else
      HAL_GPIO_WritePin(GPIOG, LD3_Pin|LD4_Pin, GPIO_PIN_SET);
  }
  /* USER CODE END 3 */
 
}


버튼을 누르면 LED가 꺼지고 버튼을 떼면 LED가 켜집니다.





2020/03/28 - [MCU/STM32F429] - CubeMX Setting 하기

2020/02/26 - [프로그래밍/C++] - 프로그래머스 - 완주하지 못한 선수, sort algorithm 정리

2020/01/20 - [프로그래밍] - tortoise svn lock 해제 update 매크로

2020/01/11 - [프로그래밍] - 비트맵의 구조, 24비트 비트맵의 구조는 어떻게 될까?

2020/01/05 - [프로그래밍/C] - 이중 연결 리스트(Double linked list), 이중 원형 연결 리스트 예제

2019/12/22 - [프로그래밍/C] - 프로그래머스 2016년, 날짜에 따른 요일 구하기


반응형

'MCU > STM32F429' 카테고리의 다른 글

적외선 수신기 기능 구현  (1) 2020.12.03
STM32 Semihosting(STM32F429I Discovery)  (1) 2020.05.10
STM32 타이머 제어하기(STM32F429I Discovery)  (2) 2020.04.30
CubeMX Setting 하기  (1) 2020.03.28