서론
이전 글에서 PT100 전용 IC인 MAX31865 대신 ADC로 읽기 위한 아날로그 인터페이스 보드를 설계해 보았고,
실제로 Breakout 보드를 제작하여 증폭이 잘 되는지까지 확인하였습니다.
PT100 온도 측정을 위한 AFE(Analog Front End) 설계 글 보기
아래는 실제 제작한 C9HW-PT100ADC-v1.0 보드입니다.

이번 글에서는 위 보드를 이용하여 STM32F103의 ADC를 통해
아날로그 보드(C9HW-PT100ADC-v1.0)에서 출력되는 전압을 직접 읽어 보겠습니다.
온도 센서인 PT100 대신 두 개의 고정 저항을 연결하여,
ADC로 측정한 값과 실제 전압을 비교하는 것을 목표로 하였습니다.
즉, STM32의 ADC가 실제 아날로그 신호를 얼마나 정확하게 읽을 수 있는지를 확인하는 실험입니다.
실험
준비사항
- PT100 아날로그 인터페이스 보드(AFE) – 직접 제작
- STM32F103 개발보드 – Aliexpress에서 구매
- Debugger(ST-LINK V2 or V3) – 본 실험에서는 NUCLEO-F429ZI 보드의 내장 디버거 사용
- 고정 저항 2개(99옴 1개, 149.3옴 1개)
- 멀티메터
- 개발 환경: STM32CubeIDE
실험구성
위 준비물을 이용하여 실험 구성을 완료하였습니다.
아래는 실제 연결 상태를 촬영한 사진으로, 각 구성 요소와 연결 관계를 표시하였습니다.

본 실험에서는 PT100 대신 고정 저항 149.3Ω을 연결하여 아날로그 인터페이스 보드의 출력 특성을 확인하였습니다.
비교 측정을 위해 99Ω(100Ω 대체용) 저항도 준비하여 149.3Ω과 교체 연결하며 실험을 진행하였습니다.
100Ω은 PT100의 0°C에서의 저항값을 의미합니다.
따라서 두 저항을 이용하여 온도 변화에 따른 출력 전압의 변화를 간접적으로 확인할 수 있습니다.
보드에는 3.3V 전원을 공급하고, 출력 신호를 STM32F103의 PC0(ADC1_IN10) 핀으로 직접 연결하였습니다.
특히 안정적인 측정을 위해 아날로그 인터페이스 보드와 STM32F103 개발보드의 GND를 공통(Common)으로 연결하였습니다.
이는 아날로그 인터페이스 보드에서 출력되는 전압과 STM32F103의 ADC 입력 전압이 동일한 기준 전위를 갖도록 하기 위한 것으로, 정확한 측정을 위해 매우 중요한 요소입니다.
ADC 설정
다음은 STM32F103 개발보드에서 ADC를 설정하는 과정입니다.
ADC를 사용하기 위해서는 몇 가지 설정이 필요하며, 가장 먼저 ADC 입력 핀을 지정해야 합니다.
본 실험에서는 PC0 핀을 ADC 입력으로 사용하였으며, 해당 채널은 ADC1_IN10에 해당합니다.
이와 같은 설정은 STM32CubeIDE에 포함된 CubeMX를 이용하여 손쉽게 구성할 수 있습니다.
아래는 PC0 핀을 ADC1_IN10으로 설정한 화면입니다.

다음으로 할 일은 ADC의 각종 파라미터를 설정하는 것입니다.
STM32CubeIDE의 CubeMX에서 Pinout & Configuration 탭으로 이동한 후,
좌측의 Analog → ADC1을 선택하면 Mode와 Configuration 항목이 나타납니다.
Mode에서는 별도로 설정할 내용이 없으며, 핀 설정 과정에서 자동으로 구성됩니다.
따라서 실제로 중요한 설정은 Configuration 항목입니다.
본 실험에서는 단일 채널, 단일 변환(Single Conversion) 방식을 사용하므로 아래와 같이 설정하였습니다.

Data Alignment는 Right alignment로 설정하였으며,
Scan Conversion Mode와 Continuous Conversion Mode는 단일 채널 측정이므로 Disable로 설정하였습니다.
External Trigger는 Software Start를 사용하였고,
Regular Channel은 PC0에 해당하는 ADC1_IN10으로 설정하였습니다.
Sampling Time은 초기값인 1.5 cycles에서는 측정값이 불안정하여,
안정적인 측정을 위해 239.5 cycles로 변경하였습니다.
마지막으로 ADC의 동작 클럭을 설정해야 합니다.
이 설정은 CubeMX의 Clock Configuration 탭에서 수행할 수 있습니다.
본 실험에서는 시스템 클럭 72MHz를 기준으로 ADC Prescaler를 /6으로 설정하여,
ADC 동작 클럭을 12MHz로 구성하였습니다.
아래는 해당 설정 화면입니다.

STM32F103의 ADC는 클럭이 너무 높을 경우 측정 오차가 증가할 수 있으므로,
일반적으로 12MHz 내외로 설정하는 것이 안정적인 측정에 유리합니다.
Clock설정을 마지막으로 ADC설정이 완료 되었습니다. 저장을 하면 자동으로 코드가 생성됩니다.
펌웨어 작성
ADC 설정이 완료되었으므로, 다음으로 펌웨어를 작성합니다.
본 실험에서는 전체 프로젝트의 유지보수와 확장성을 고려하여,
ADC를 위한 별도의 헤더 파일과 소스 파일을 만들어서 구현하였습니다.
헤더 파일은 pt100_adc.h, 소스 파일은 pt100_adc.c로 구성하였습니다.
헤더파일(pt100_adc.h)
헤더파일에는 ADC 관련 함수 원형과 기준값을 정의하였습니다.

여기서 PT100_ADC_VREF는 ADC 기준 전압을 의미하며, PT100_ADC_RESOLUTION은 12비트 ADC의 최대값인 4095를 의미합니다.
또한 초기화, 원시값 읽기, 평균값 읽기, 전압 변환을 위한 함수들을 선언하였습니다.
즉, 헤더 파일은 ADC 기능을 외부에서 사용할 수 있도록 인터페이스를 정의하는 역할을 합니다.
소스파일(pt100_adc.c)
소스파일에서는 실제 ADC 동작을 구현하였습니다.
초기화 함수

이 함수에서는 ADC 보정을 수행합니다.
STM32F103에서는 ADC 측정 전에 Calibration을 수행하는 것이 좋으며, 이를 통해 보다 안정적인 측정값을 얻을 수 있습니다.
보정이 정상적으로 완료되면 내부 플래그를 설정하여 이후 ADC 읽기 함수가 동작할 수 있도록 하였습니다.
단일 ADC 값 읽기

이 함수는 ADC를 한 번 시작하고, 변환이 완료될 때까지 기다린 후 변환된 값을 읽어 반환합니다.
본 실험에서는 폴링(Polling) 방식을 사용하였기 때문에,
HAL_ADC_PollForConversion() 함수를 통해 변환 완료 여부를 확인하였습니다.
즉, 이 함수는 ADC를 이용한 가장 기본적인 1회 샘플 읽기 함수입니다.
HAL 라이브러리에서 제공하는 ADC 관련 함수들은
Project Explorer의 Drivers → STM32F1xx_HAL_Driver → Src 폴더에서 확인할 수 있습니다.

평균값 계산

ADC 값은 측정 시점에 따라 약간씩 흔들릴 수 있기 때문에, 한 번만 읽는 것보다 여러 번 읽어 평균을 내는 것이 더 안정적입니다.
이 함수에서는 지정한 횟수만큼 ADC 값을 읽은 후 평균을 계산하여 반환합니다.
본 실험에서는 16회를 읽어 평균값을 사용하였습니다.
즉, 이 함수는 노이즈를 줄이기 위한 간단한 소프트웨어 필터 역할을 합니다.
전압 변환

이 함수는 ADC 원시값을 실제 전압값으로 변환합니다.
STM32F103의 ADC는 12비트이므로, 읽은 값은 0~4095 사이의 정수로 표현됩니다. 이를 기준 전압 3.3V에 맞추어 실제 전압으로 환산합니다.
즉, ADC 값과 멀티미터로 측정한 실제 전압을 비교하기 위해 필요한 함수입니다.
평균 전압 계산

이 함수는 여러 번 읽은 평균 ADC 값을 전압으로 변환합니다.
실험에서는 이 함수를 통해 보다 안정적인 전압값을 얻을 수 있었습니다.
다만 실제 사용 시에는 평균 ADC 값을 한 번만 구한 뒤, 그 값을 이용하여 전압을 계산하는 방식이 더 효율적입니다.
즉, PT100_ADC_ReadAverage(16)로 평균값을 먼저 구하고, 그 값을 전압으로 바꾸는 방식이 더 적절합니다.
Application에 적용
우리 프로젝트에서는 app.h와 app.c 파일을 중심으로 전체 기능이 동작하도록 구성하였습니다.
ADC를 사용하기 위해서는 먼저 초기화를 수행해야 하며,
초기화 함수인 PT100_ADC_Init()은 appInit() 함수에서 호출하였습니다.

appInit() 함수는 시스템 초기화 단계에서 한 번만 실행되며,
여기서 ADC를 포함한 각종 모듈의 초기화를 수행합니다.
실제 ADC 값을 읽는 동작은 appMain() 함수의 100ms 주기 루틴에서 수행하였습니다.
온도와 같은 물리량은 빠르게 변화하지 않기 때문에,
100ms 정도의 주기로 측정하는 것만으로도 충분히 안정적인 값을 얻을 수 있습니다.

Scheduler_GetFlag_100ms() 함수는 100ms마다 설정되는 플래그를 확인하는 역할을 하며,
해당 조건이 만족되면 ADC 값을 읽도록 구성하였습니다.
PT100_ADC_ReadAverage(16) 함수를 이용하여 16회 샘플의 평균값을 구하고,
이를 기준 전압(3.3V)과 ADC 해상도(4095)를 이용하여 실제 전압으로 변환하였습니다.
ADC 읽기 실험
펌웨어 작성이 완료되었으므로 프로젝트를 빌드한 후, Debug 모드를 통해 펌웨어를 다운로드합니다.
실시간으로 ADC 값을 확인하기 위해 pt100_raw와 pt100_voltage 변수를 Live Expression에 추가하였습니다.
이후 실행(Resume) 버튼을 눌러 코드를 동작시키면, Live Expression 창에서 해당 변수의 값이 실시간으로 업데이트되는 것을 확인할 수 있습니다.

위 값은 99.3Ω 저항을 연결하였을 때의 측정 결과입니다.
Live Expression 기능을 이용하면 프로그램을 정지하지 않고도 변수 값을 실시간으로 확인할 수 있어,
디버깅 및 측정값 검증에 매우 유용합니다.
위와 같은 방법으로 두 개의 저항(99.3Ω, 149.3Ω)을 교대로 연결하여 아날로그 인터페이스 보드의 입력값 및 출력값 그리고 pt100_raw와 pt100_voltage 값을 기록하였습니다.
아래는 실험 결과 입니다.
| 조건 | 저항값 (Ω) | 입력 전압 (V) | 보드 출력 (V) | ADC Raw | ADC 전압 (V) |
|---|---|---|---|---|---|
| 기준 1 | 99.3 | 0.1153 | 1.614 | 2019 | 1.627 |
| 기준 2 | 149.3 | 0.17 | 2.39 | 2990 | 2.40 |
| Open | ∞ | – | 약 3.3 | 4095 | 3.29 |
99.3Ω과 149.3Ω에서 모두 ADC 전압값은 보드 출력 전압과 유사하게 측정되었으며, 저항값이 증가함에 따라 출력 전압과 ADC Raw 값도 함께 증가하는 것을 확인할 수 있었습니다.
또한 Open 상태에서는 ADC Raw가 4095까지 올라가며 입력이 상단으로 포화되는 것을 확인할 수 있었습니다.
이를 통해 STM32F103의 ADC가 아날로그 인터페이스 보드의 출력 전압을 정상적으로 읽고 있음을 확인할 수 있었습니다.
맺음말
이번 실험에서는 STM32F103의 ADC를 이용하여 아날로그 인터페이스 보드의 출력 전압을 직접 측정하고, 실제 전압과 비교하는 과정을 확인해 보았습니다.
고정 저항(99.3Ω, 149.3Ω)을 이용한 측정 결과, ADC로 환산한 전압값은 보드 출력 전압과 유사한 값을 보였으며, 저항값 변화에 따라 출력 전압과 ADC 값이 선형적으로 증가하는 것을 확인할 수 있었습니다. 또한 Open 상태에서는 ADC 값이 최대값에 근접하는 것을 통해 ADC 동작이 정상적으로 이루어지고 있음을 확인할 수 있었습니다.
특히 이번 실험을 통해 Sampling Time, ADC 클럭, GND 공통 구성과 같은 하드웨어적인 요소가 측정 결과에 중요한 영향을 미친다는 점을 확인할 수 있었으며, 단순한 설정뿐만 아니라 전체 시스템 구성의 중요성도 함께 이해할 수 있었습니다.
결론적으로 STM32F103의 ADC는 적절한 아날로그 인터페이스 회로와 함께 사용할 경우, 별도의 전용 IC 없이도 충분히 실용적인 수준의 측정이 가능함을 확인할 수 있었습니다.
다음 글에서는 폴링 방식 대신 DMA를 이용하여 CPU 개입 없이 ADC 데이터를 자동으로 수집하는 방법에 대해 정리해 보겠습니다.