◎ 개발 환경 설정
● Tool chain 구성
1. 컴파일러 - Stm32cubeide
프로그램 메모리 용량 제한이 있는 keil 무료 버전에 문제를 극복하기 위해 Stm32cubeide 로 컴파일러 구성
우선 프로젝트 파일을 제작하기에 앞서 다음 아래에 4가지 과정은 필수적으로 설정을 해야 합니다.
① MCU 모델 선택
MCU 모델은 STM32F407IGT6 입니다.
② RCC 설정
회로상 외부 오실레이터를 적용하기 때문에 HSE는 Crystal/Ceramic Resonator를 선택합니다.
③ System mode 설정
SWD를 활성화 하며 디버그 모드를 사용하기 위해서는 Serial Wire로 설정 합니다.
④ System configuration 설정
• 외부 오실레이터를 적용하기 때문에 HSE (High Speed External)을 선택합니다.
• PLL 소스를 설정합니다.
입력 클록을 1MHz로 분주하기 위해 M (Division Factor)를 25로 설정 합니다.
PLL은 정확한 주파수를 (Lock) 고정하기 위해서 입력클록을 조정 하는 역할을 합니다.
N은 Multiplication Factor (높은 배율을 위해 곱셈을 합니다), 336을 입력하면 1MHz 입력을 336MHz VCO로 주파수로 변환 합니다.
P 는 Output Division Factor , VCO 주파수 336MHz 를 시스템 클록 168MHz 를 적용하기 위해 분주를 나누는 역할을 합니다.
※ 참고로 데이터 시트를 보면 STM32F407IGT6 모델은 시스템 클록을 최대 168MHz로 설정할수 있습니다. 한마디로 최대 설정을
위해 N 값을 336으로 하고 P를 2로 해서 168MHz 설정을 하는 겁니다.
APB1 에 주변 장치 클록 42MHz 와 타이머 클록을 84MHz로 설정하기 위해서는 APB1 값을 4로 설정합니다. 위의 그림을 보면 APB1에 클록값은 최대 42MHz로 설정할수 있습니다.
APB2도 마찬 가지로 위의 그림을 보면 최대 84MHz 로 설정 할 수 있습니다. 타이머 클록은 x2를 하여 168MHz로 설정됩니다.
AHB 주변 장치는 위의 그림을 보면 일반 포트 입니다. Cortex system clock 값은 그래도 1로하고 최대 168MHz로 진행합니다.
⑤ 이제 모든 세팅은 완료 했습니다. 키보드로 Ctrl + S 키를 눌러서 Generate code 과정을 진행합니다.
※ 사실 그다음 핀 설정이나 대체 기능(alternate function)을 설정하는 부분도 진행해야 하지만, 저는 직접 코드 방식으로 설정하는 것을 선호합니다. 이를 위해서는 간단하지만 STM32CubeIDE 구조를 파악해야 합니다. 이 구조를 파악하면 코드 방식으로 직접 구성하는 것이 개인적으로 더 편하고 안정적이라고 생각합니다.
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2025 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"
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
while (1)
{
}
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 25;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
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_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/* 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 */
위의 과정을 모두 진행하면 이렇게 기본적인 프레임에 코드가 생성됩니다. 여기에는 아직 아무런 핀 설정이나 드라이버 설정이 없습니다. 단, System Clock 설정에 대한 코드는 완성된 것을 확인할 수 있습니다.
'STM32 (Cortex-M4)' 카테고리의 다른 글
STM32 media 보드 - TFT LCD 제어 PART2 (0) | 2025.03.31 |
---|---|
STM32 media 보드 - delay (0) | 2025.03.27 |
STM32 media 보드 - TFT LCD 제어 PART1 (0) | 2025.03.27 |
STM32 media 보드 - GPIO 제어 (0) | 2025.03.25 |
STM32 media 보드 - 글 소개 (0) | 2025.03.24 |