[STM32] GPIO

pikamon·2020년 12월 31일
0

STM32

목록 보기
4/12

본 글은 STM32F769I MCU를 기준으로 작성되었습니다.
세부적인 내용은 제품군마다 조금씩 다를 수 있습니다.


1. GPIO란?

GPIO란 General Purpose Input Output 약자로, 사용자가 SW를 통해 직접 용도와 동작을 정의할 수 있는 디지털 신호 핀을 의미한다.

2. 예제

보드에 달려있는 푸시 버튼과 LED를 제어해보자.

STM32F769I-DISC1 보드의 푸시 버튼과 LED는 아래와 같다. 푸시 버튼은 두 개가 있으며, 하나는 유저용, 또 하나는 리셋 버튼임을 알 수 있다. LED는 8개가 있으며, LD1과 LD2만 유저 디파인이 가능하다. 나머지는 특정 용도로 사용되는 LED임을 알 수 있다.

B1로부터 입력을 받아서 LD1과 LD2에 출력을 내보내는 코드를 만들어보자.

1. Configuration

유저 매뉴얼에 의하면 LD1, LD2, B1이 각각 PJ13, PJ5, PA0에 매핑되어 있다고 한다.

따라서 우리가 사용할 GPIO 포트는 GPIOA, GPIOJ이며, 나머지는 비활성화해도 된다.

클럭도 시스템 클럭과 AHB 클럭 빼고는 모두 비활성화해도 된다.

2. 코드 작성

초기화 및 main 코드는 아래와 같다.

#include "main.h"

void SystemClock_Config(void)
{
	RCC_OscInitTypeDef RCC_OscInitStruct = { 0, };
	RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0, };

	__HAL_RCC_PWR_CLK_ENABLE();
	__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);

	RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
	RCC_OscInitStruct.HSIState = RCC_HSI_ON;
	RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
	RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
	RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
	RCC_OscInitStruct.PLL.PLLM = 8;
	RCC_OscInitStruct.PLL.PLLN = 192;
	RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
	RCC_OscInitStruct.PLL.PLLQ = 4;
	RCC_OscInitStruct.PLL.PLLR = 2;
	HAL_RCC_OscConfig(&RCC_OscInitStruct);

	RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK;
	RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
	RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
	HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3);
}

static void MX_GPIO_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = { 0, };

	__HAL_RCC_GPIOA_CLK_ENABLE();
	__HAL_RCC_GPIOJ_CLK_ENABLE();

	// Initialize LD1, LD2
	GPIO_InitStruct.Pin = GPIO_PIN_13 | GPIO_PIN_5; // LD_USER1_Pin, LD_USER2_Pin
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
	HAL_GPIO_Init(GPIOJ, &GPIO_InitStruct);

	// Initialize B1
	GPIO_InitStruct.Pin = GPIO_PIN_0; // B_USER_Pin
	GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

int main(void)
{
	HAL_Init();
	SystemClock_Config();
	MX_GPIO_Init();

	unsigned char bits = 0;

	while (1)
	{
		if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_SET)
		{
			bits = (bits + 1) & 0x3;
		}
		HAL_GPIO_WritePin(GPIOJ, GPIO_PIN_13, (bits & 0x2));
		HAL_GPIO_WritePin(GPIOJ, GPIO_PIN_5,  (bits & 0x1));
	}
}

3. 빌드 및 실행 결과

Ctrl + B 를 통해 빌드하면 정상 빌드되는 것을 볼 수 있다.

실제 타겟 보드에 올려서 실행해보자.

F11 을 누르면 창이 디버그 창으로 변경되며, Resume 버튼을 누르면 멈춤 없이 실행된다.

푸시 버튼이 고장난 건지 LED가 제멋대로 동작하고는 있지만, GPIO 제어 자체는 잘 되는 것을 볼 수 있다.

profile
개발자입니당 *^^* 깃허브 https://github.com/pikamonvvs

0개의 댓글