먼저 나의 환경은 Ubuntu 20.04, NUCLEO-F411RE 사용 중이다.
1. 설명
STM32는 내부에서 CPU의 온도를 측정할 수 있다. 계산방법은 모르겠어서 코드만 GPT 것을 가져왔다.
Polling, Interrupt, DMA 3가지 방법이 있는데, 온도는 1초에 한 번 체크해도 무방하다 생각하기에 Interrupt 방식을 택할 것이다.
설명은 아래와 같이 있지만 구현은 Interrupt 방식만 해볼 것이다.
(Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c 주석 중)
(#) ADC 드라이버는 폴링(Polling), 인터럽트(interruption), 세 가지 모드 중에서 사용할 수 있습니다, DMA에 의한 양도. *** 폴링모드 IO동작 *** ================================= [..] (+) HAL_ADC_Start()를 사용하여 ADC 주변기기를 시동합니다 (+) HAL_ADC_PollForConversion()을 사용하여 변환 종료 대기(), 이 단계에서 사용자는 자신의 최종 응용 프로그램에 따라 시간 초과 값을 지정할 수 있습니다 (+) ADC 변환값을 읽으려면 HAL_ADC_GetValue() 기능을 사용합니다. (+) HAL_ADC_Stop()을 사용하여 ADC 주변 장치를 중지합니다 *** 인터럽트 모드 IO 작업 *** =================================== [..] (+) HAL_ADC_Start_IT()를 사용하여 ADC 주변기기를 시동합니다 (+) ADC_IRQHandler() Interrupt 서브루틴에서 호출된 HAL_ADC_IRQHandler()를 사용합니다 (+) ADC 변환 종료 시 HAL_ADC_ConvCpltCallback() 기능이 실행되어 사용자는 다음과 같이 할 수 있습니다 함수 포인터 HAL_ADC_ConvCpltCallback을 사용자 지정하여 자신의 코드를 추가합니다 (+) ADC Error의 경우 HAL_ADC_ErrorCallback() 기능이 실행되어 사용자는 함수 포인터 HAL_ADC_ErrorCallback을 사용자 정의하여 자신의 코드를 추가합니다 (+) HAL_ADC_Stop_IT()를 사용하여 ADC 주변기기를 정지합니다 *** DMA 모드 IO 작동 *** ============================== [..] (+) HAL_ADC_Start_DMA()를 사용하여 ADC 주변 장치를 시작합니다. 이 단계에서 사용자가 길이를 지정합니다 변환이 끝날 때마다 전송할 데이터의 (+) HAL_ADC_ConvCpltCallback() 기능에 의한 데이터 전송 종료 시 실행되며 사용자는 다음을 수행할 수 있습니다 함수 포인터 HAL_ADC_ConvCpltCallback을 사용자 지정하여 자신의 코드를 추가합니다 (+) 전송오류의 경우 HAL_ADC_ErrorCallback() 기능이 실행되어 사용자는 함수 포인터 HAL_ADC_ErrorCallback을 사용자 정의하여 자신의 코드를 추가합니다 (+) HAL_ADC_Stop_DMA()를 사용하여 ADC 주변기기를 정지합니다 |
2. 설정
[Analog] - [ADC1]-[Mode]에서 스크롤을 아래로 내리면 "Temperature Sensor Channel"이 존재하는데, 체크하고 [Parameter Settings]에서 "Continuous Conversion Mode"를 Enable로 변경한다.
"ADC1 global interrupt"도 Enable 체크해준다.
3. 코드
getCPUTemp()에서 HAL_ADC_Start_IT함수를 수행하면 인터럽트가 수행되어 HAL_ADC_ConvCpltCallback함수가 실행되는 방식이다.
#include "adc.h"
#include "stm32f4xx_hal_adc.h"
static float cpu_temp = 0.0f;
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){
uint16_t rawValue = HAL_ADC_GetValue(&hadc1);
float temperature = ((float)rawValue / 4095) * 3300; // ADC 값을 전압으로 변환
cpu_temp = ((temperature - 760.0) / 2.5) + 25.0; // 온도로 변환
}
float getCPUTemp(){
HAL_ADC_Start_IT(&hadc1);
return cpu_temp;
}
main.c의 while문에서는 1초에 한 번씩 인터럽트를 발생시켜 print로 출력한다.
while (1)
{
printf("TEMP: %.2f\n", getCPUTemp());
HAL_Delay(1000);
}
실행을 시켜보면 같은 숫자가 반복되어 좀 수상하긴 한데, 선풍기를 틀면 온도가 내려가는 것을 보아 정상작동으로 보인다.
+) 아래는 ChatGPT에서 알려준 방식인데 Polling 방식이며 global interrupt 체크 해제해야 한다.
while (1) {
// ADC 변환 시작
HAL_ADC_Start(&hadc1);
// ADC 변환 완료 대기
HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
// 변환된 값 읽기 (CPU 온도 센서 채널 사용)
uint16_t rawValue = HAL_ADC_GetValue(&hadc1);
// CPU 온도 계산 (참고: STM32 데이터 시트)
float temperature = ((float)rawValue / 4095) * 3300; // ADC 값을 전압으로 변환
temperature = ((temperature - 760.0) / 2.5) + 25.0; // 온도로 변환
// CPU 온도 출력 (예를 들어 시리얼 포트를 통해)
printf("CPU 온도: %.2f°C\n", temperature);
// 일정한 시간 동안 대기
HAL_Delay(1000);
}
}
'프로그래밍 > STM32' 카테고리의 다른 글
[STM32] Timer 설정하기(feat. 이론) (0) | 2023.10.07 |
---|---|
[STM32] USART를 활용한 print찍기 (0) | 2023.09.30 |
[STM32] EXTI(External Interrupt) 제어 (0) | 2023.09.24 |
[STM32] STM32CubeMX로 CMake설정하기 (0) | 2023.09.10 |
[STM32] VSCode 에서 STM32 디버깅하기(.vscode) (0) | 2023.09.03 |
댓글