STM32

STM32 ADC 설정 및 사용하기

임베디드 친구 2024. 11. 26. 13:22
반응형

이번 포스팅에서는 STM32 마이크로컨트롤러의 ADC(Analog-to-Digital Converter)를 설정하고 사용하는 방법에 대해 설명하겠습니다. STM32CubeIDE를 통해 IO 핀을 설정하고, 아날로그 신호를 디지털 값으로 변환하는 기본적인 개념을 이해하며, 코드 예제를 통해 실습해보도록 하겠습니다. ADC 설정 과정은 STM32CubeMX를 활용하여 간단하게 할 수 있으며, 이를 통해 개발자가 필요한 설정을 GUI로 직관적으로 진행할 수 있습니다.

ADC란 무엇인가?

ADC는 아날로그 신호를 디지털 값으로 변환하는 장치입니다. 아날로그 신호는 연속적인 값을 가지는 반면, 디지털 신호는 불연속적인 비트를 나타내므로, 우리가 MCU와 같은 디지털 장치를 통해 아날로그 신호를 처리하려면 반드시 이를 디지털 값으로 변환해야 합니다. ADC는 이러한 변환 작업을 수행하며, 주로 센서나 외부 입력 신호의 값을 읽어올 때 사용됩니다.

STM32 마이크로컨트롤러는 다양한 해상도의 ADC 모듈을 내장하고 있으며, 최대 12비트의 해상도로 아날로그 값을 읽어올 수 있습니다. 이는 0~4095 사이의 값을 가지며, 입력 전압에 따라 이 값이 결정됩니다.

STM32CubeIDE를 통한 IO 핀 설정하기

STM32CubeIDE에서 ADC 설정을 하기 위해서는 먼저 IO 핀 설정을 진행해야 합니다. ADC는 특정한 아날로그 입력 핀을 통해 값을 읽어들이므로, 해당 핀을 아날로그 모드로 설정하는 것이 중요합니다. 아래의 단계들을 통해 설정을 진행해보겠습니다.

  1. 프로젝트 생성 및 MCU 선택
  2. STM32CubeIDE를 실행하고, 새로운 프로젝트를 생성합니다. 사용할 MCU를 선택하고 프로젝트 이름을 설정합니다.
  3. Pinout 탭에서 IO 핀 설정하기
    • PA0 핀을 클릭하고, 기능 목록에서 ADC_IN0를 선택합니다. 이를 통해 PA0 핀을 ADC 입력 핀으로 설정할 수 있습니다.
    • 이때, ADC1을 사용하도록 설정되며, ADC의 채널 0에 연결된 것으로 표시됩니다.
  4. 프로젝트가 생성되면 Pinout & Configuration 탭이 나타납니다. 이곳에서 ADC 입력에 사용할 핀을 선택합니다. 예를 들어, PA0 핀을 ADC 입력으로 사용한다고 가정해 보겠습니다.
  5. ADC 설정하기
    • 왼쪽의 Configuration 탭에서 ADC1을 선택합니다.
    • Parameter Settings에서 해상도(Resolution), 데이터 정렬(Data Alignment) 등을 설정합니다. 일반적으로 12비트 해상도를 사용하며, 오른쪽 정렬(Right Alignment)을 선택합니다.
    • Regular Conversion Mode에서는 단일 모드(Single Conversion) 또는 연속 모드(Continuous Conversion)를 설정할 수 있습니다. 여기서는 단일 변환 모드를 설정하도록 하겠습니다.
  6. Clock 설정
  7. ADC의 정확한 동작을 위해서는 클럭 설정도 중요합니다. Clock Configuration 탭에서 시스템 클럭과 ADC 클럭을 적절히 설정하여 ADC가 안정적으로 동작하도록 합니다.
  8. 코드 생성하기
  9. 설정이 완료되면 상단의 Project 메뉴에서 Generate Code를 클릭하여 코드 생성을 진행합니다. 생성된 코드는 main.c 파일에서 확인할 수 있으며, 초기화 코드가 자동으로 포함됩니다.

예제 코드: ADC 사용하기

아래는 PA0 핀을 통해 아날로그 값을 읽어오는 ADC 예제 코드입니다. 코드에는 IO 설정 부분과 ADC 값을 읽어오는 전체 흐름이 포함되어 있습니다.

#include "main.h"
#include "stm32f4xx_hal.h"

ADC_HandleTypeDef hadc1;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);

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

    HAL_ADC_Start(&hadc1);

    while (1)
    {
        if (HAL_ADC_PollForConversion(&hadc1, 1000) == HAL_OK)
        {
            uint32_t adcValue = HAL_ADC_GetValue(&hadc1);
            // adcValue에는 PA0 핀을 통해 읽어온 아날로그 값이 저장됩니다.
        }
    }
}

/**
  * @brief ADC1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_ADC1_Init(void)
{
    ADC_ChannelConfTypeDef sConfig = {0};

    hadc1.Instance = ADC1;
    hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
    hadc1.Init.Resolution = ADC_RESOLUTION_12B;
    hadc1.Init.ScanConvMode = DISABLE;
    hadc1.Init.ContinuousConvMode = DISABLE;
    hadc1.Init.DiscontinuousConvMode = DISABLE;
    hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
    hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
    hadc1.Init.NbrOfConversion = 1;
    hadc1.Init.DMAContinuousRequests = DISABLE;
    hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
    if (HAL_ADC_Init(&hadc1) != HAL_OK)
    {
        Error_Handler();
    }

    sConfig.Channel = ADC_CHANNEL_0;
    sConfig.Rank = 1;
    sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
    if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
    {
        Error_Handler();
    }
}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // PA0 핀을 아날로그 모드로 설정합니다.
    GPIO_InitStruct.Pin = GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
    // 시스템 클럭 설정 코드 (STM32CubeMX에서 자동 생성된 코드 사용)
}

/**
  * @brief Error Handler
  * @retval None
  */
void Error_Handler(void)
{
    // 오류 발생 시 실행되는 코드
    while (1)
    {
    }
}

코드 설명

  1. 초기화 함수
    • HAL_Init(), SystemClock_Config(), MX_GPIO_Init(), MX_ADC1_Init() 등의 초기화 함수는 MCU와 주변 장치의 초기 설정을 담당합니다.
  2. MX_GPIO_Init()
    • GPIO 초기화 함수에서 PA0 핀을 아날로그 모드로 설정합니다. 이 설정을 통해 PA0 핀을 ADC 입력 핀으로 사용할 수 있습니다.
  3. MX_ADC1_Init()
    • ADC 설정 함수에서는 hadc1 구조체를 사용하여 ADC1 모듈을 초기화하고, 채널 0을 설정합니다. 해상도는 12비트로 설정하며, 샘플링 시간은 3 사이클로 설정합니다.
  4. ADC 값 읽기
    • HAL_ADC_Start() 함수로 ADC 변환을 시작하고, HAL_ADC_PollForConversion() 함수를 통해 변환이 완료될 때까지 대기합니다. 변환이 완료되면 HAL_ADC_GetValue() 함수를 사용하여 ADC 값을 읽어옵니다.

결론

이번 포스팅에서는 STM32CubeIDE를 활용하여 STM32 마이크로컨트롤러의 ADC 설정 및 사용하는 방법을 알아보았습니다. 아날로그 신호를 디지털 값으로 변환하는 ADC는 센서 값 읽기 등 많은 임베디드 시스템 응용에서 중요한 역할을 합니다. STM32CubeIDE를 사용하면 이러한 설정을 GUI를 통해 쉽게 진행할 수 있으며, 코드 생성 기능을 통해 복잡한 초기화 과정을 자동화할 수 있습니다.

ADC 사용에 대한 더 깊이 있는 주제나 실습에 대한 요청이 있다면 댓글로 남겨주시기 바랍니다. 앞으로도 STM32 관련 다양한 주제를 다루어보겠습니다. 감사합니다!

반응형