Research Institute
  • Hello World (Blink LED)
    2024년 11월 01일 15시 39분 33초에 업로드 된 글입니다.
    작성자: IIIIIIIIIIIIIIIIIIIIl

    보통 프로그래밍 언어를 배우는 과정에서 "Hello World"라는 메시지를 화면에 출력하는 간단한 프로그램을 가장 먼저 작성합니다. 그러나 임베디드 프로그래밍의 경우 디스플레이가 없거나 구현에 여러 코드 작성이 필요하기 때문에 보편적으로 첫 번째 프로그램으로 LED를 깜빡이는 애플리케이션을 작성하는 경우가 많습니다. 그래서 대부분의 개발 보드는 하나 이상의 LED를 탑재하고 있으며 이를 GPIO 핀을 통해 제어할 수 있습니다. 본 장에서는 Blue Pil보드에 내장된 LED 조작을 통해 기본적으로 STM32 프로젝트 개발 과정을 살펴보도록 하겠습니다.

    프로젝트 개발환경 구성

    아래 그림과 같이 File -> New -> STM32 Project를 클릭하고 개발보드에서 사용중인 MCU를 입력한 뒤 Next를 클릭합니다. 이후 프로젝트 이름을 작성하고 Next를 클릭하고 마지막으로 Finish를 클릭하면 프로젝트의 기본적인 환경 구성이 완료됩니다.

     

    구성이 완료되면 아래와 같이 Pinout & Configuration이 열리게 됩니다. 자동으로 실행이 되지 않는다면 프로젝트 폴더에 있는 "프로젝트명.ioc" 파일을 클릭하여 실행할 수 있습니다. 해당 탭에서 MCU의 PIN 설정을 진행하는 경우 IDE에서는 자동으로 설정 코드를 생성합니다. 

     

    Pinout & Configuration 구성 탭에서 System Core을 클릭하고 SYS를 선택한 다음 Debug를 클릭하고 Serial Wire를 선택합니다. 해당 설정은 디버깅 및 프로그램 업로드를 위한 인터페이스 설정으로 STM32 보드에서 SWD(Serial Wire Debug) 디버깅을 활성화하는 옵션입니다.

     

    Blue Pil보드에 내장된 LED 조작을 진행하기 위해서는 어떤 PIN에 LED가 연결되어 있는지 PIN MAP과 회로도 분석이 필요합니다. 아래 그림을 살펴보면 "C13" PIN 에 D2 Blue LED가 연결되어 있는것을 확인할 수 있습니다.

     

     

    따라서 PC13 핀을 왼쪽 클릭하고 "GPIO_Output"을 클릭합니다. 이 핀은 위에서 이야기 했던것 처럼 보드에 내장된 LED(D2)와

    연결된 핀입니다.

     

    설정을 완료하고 저장을 진행하면 아래 이미지와 같은 팝업창이 뜨고 yes를 클릭하면 됩니다.

    LED 제어코드 작성

    PIN에 설정된 코드들이 IDE에 의해서 설정되며 종속성이 필요한 라이브러리와 초기화 함수들을 자동으로 작성하게 됩니다. 그리고 main.c 파일을 열어 while 문에 아래와 같은 코드를 넣어줍니다. 해당 코드는 GPIOC 포트 13번 핀을 제어하여 1초 간격으로 내장 LED를 켜고 끄는 동작을 수행합니다. HAL_GPIO_WritePin 함수를 사용하여 GPIOC의 13번 핀을 LOW 상태로 설정해 LED를 끄고 HAL_Delay로 1초간 대기한 뒤 다시 13번 핀을 HIGH 상태로 설정하여 LED를 켭니다. 이후 1초 단위로 LED를 끄고 키고를 반복 작업합니다.

    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, 0);
    HAL_Delay(1000);
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, 1);
    HAL_Delay(1000);

     

    최종적인 main.c 코드는 아래와 같습니다.

    /* USER CODE BEGIN Header */
    /**
      ******************************************************************************
      * @file           : main.c
      * @brief          : Main program body
      ******************************************************************************
      * @attention
      *
      * Copyright (c) 2024 STMicroelectronics.
      * All rights reserved.
      *
      * This software is licensed under terms that can be found in the LICENSE file
      * in the root directory of this software component.
      * If no LICENSE file comes with this software, it is provided AS-IS.
      *
      ******************************************************************************
      */
    /* USER CODE END Header */
    /* Includes ------------------------------------------------------------------*/
    #include "main.h"
    
    /* Private includes ----------------------------------------------------------*/
    /* USER CODE BEGIN Includes */
    
    /* USER CODE END Includes */
    
    /* Private typedef -----------------------------------------------------------*/
    /* USER CODE BEGIN PTD */
    
    /* USER CODE END PTD */
    
    /* Private define ------------------------------------------------------------*/
    /* USER CODE BEGIN PD */
    
    /* USER CODE END PD */
    
    /* Private macro -------------------------------------------------------------*/
    /* USER CODE BEGIN PM */
    
    /* USER CODE END PM */
    
    /* Private variables ---------------------------------------------------------*/
    
    /* USER CODE BEGIN PV */
    
    /* USER CODE END PV */
    
    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    static void MX_GPIO_Init(void);
    /* USER CODE BEGIN PFP */
    
    /* USER CODE END PFP */
    
    /* Private user code ---------------------------------------------------------*/
    /* USER CODE BEGIN 0 */
    
    /* USER CODE END 0 */
    
    /**
      * @brief  The application entry point.
      * @retval int
      */
    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();
      /* USER CODE BEGIN 2 */
    
      /* USER CODE END 2 */
    
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
        /* USER CODE END WHILE */
    	  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, 0);
    
    	  HAL_Delay(1000);
    
    	  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, 1);
    
    	  HAL_Delay(1000);
    
        /* USER CODE BEGIN 3 */
      }
      /* USER CODE END 3 */
    }
    
    /**
      * @brief System Clock Configuration
      * @retval None
      */
    void SystemClock_Config(void)
    {
      RCC_OscInitTypeDef RCC_OscInitStruct = {0};
      RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    
      /** Initializes the RCC Oscillators according to the specified parameters
      * in the RCC_OscInitTypeDef structure.
      */
      RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
      RCC_OscInitStruct.HSIState = RCC_HSI_ON;
      RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
      RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
      if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
      {
        Error_Handler();
      }
    
      /** Initializes the CPU, AHB and APB buses clocks
      */
      RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                  |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
      RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
      RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
      RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
      RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    
      if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
      {
        Error_Handler();
      }
    }
    
    /**
      * @brief GPIO Initialization Function
      * @param None
      * @retval None
      */
    static void MX_GPIO_Init(void)
    {
      GPIO_InitTypeDef GPIO_InitStruct = {0};
    /* USER CODE BEGIN MX_GPIO_Init_1 */
    /* USER CODE END MX_GPIO_Init_1 */
    
      /* GPIO Ports Clock Enable */
      __HAL_RCC_GPIOC_CLK_ENABLE();
      __HAL_RCC_GPIOD_CLK_ENABLE();
      __HAL_RCC_GPIOA_CLK_ENABLE();
    
      /*Configure GPIO pin Output Level */
      HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
    
      /*Configure GPIO pin : PC13 */
      GPIO_InitStruct.Pin = GPIO_PIN_13;
      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);
    
    /* USER CODE BEGIN MX_GPIO_Init_2 */
    /* USER CODE END MX_GPIO_Init_2 */
    }
    
    /* USER CODE BEGIN 4 */
    
    /* USER CODE END 4 */
    
    /**
      * @brief  This function is executed in case of error occurrence.
      * @retval None
      */
    void Error_Handler(void)
    {
      /* USER CODE BEGIN Error_Handler_Debug */
      /* User can add his own implementation to report the HAL error return state */
      __disable_irq();
      while (1)
      {
      }
      /* USER CODE END Error_Handler_Debug */
    }
    
    #ifdef  USE_FULL_ASSERT
    /**
      * @brief  Reports the name of the source file and the source line number
      *         where the assert_param error has occurred.
      * @param  file: pointer to the source file name
      * @param  line: assert_param error line source number
      * @retval None
      */
    void assert_failed(uint8_t *file, uint32_t line)
    {
      /* USER CODE BEGIN 6 */
      /* User can add his own implementation to report the file name and line number,
         ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
      /* USER CODE END 6 */
    }
    #endif /* USE_FULL_ASSERT */

     

    최종적으로 작성한 코드를 업로드하게 되면  D2 Blue LED 부분이 초 단위로 깜빡이면 정상적으로 코드가 실행되고 있는 것을 확인할 수 있습니다.

     

     

    '네트워크 > STM32 개발' 카테고리의 다른 글

    실습환경 소개  (0) 2024.10.21
    개발환경 구축하기 - STM32CubeIDE 설치  (0) 2024.10.19
    댓글