본문 바로가기
DSP, MCU/STM32 (ARM Cortex-M)

STM32 ] Timer 인터럽트를 사용하여 ADC 값 받기 + 그래프 보면서 디버깅하는 팁

by eteo 2022. 6. 17.

ADC : Analogue to Digital Converter, 아날로그 신호를 디지털 신호로 변환하는 것으로 샘플링(Sampling), 양자화(Quantizing), 부호화(Coding) 과정을 거친다.

 

샘플링 : 아날로그 파형을 디지털 형태로 변환하기 위해 표본을 취하는 것

양자화 : 표본화된 각 점을 어느 정도 resolution 으로 표현할지 정해 변환하는 것. 예를들어 8비트면 256단계로 세분화

부호화 : 앞의 단계를 거친 디지털 정보를 2진수로 표현하는 것

 

 

ADC를 인터럽트방식으로 사용하면 끊임없이 인터럽트가 트리거되어 다른 부분에 문제를 일으킨다. Timer 인터럽트와 ADC 폴링방식을 사용하여 ADC의 샘플링 주기를 조절하는 방법을 소개한다.

 

 

 

먼저 테스트를 위해 사용할 것은 아두이노에 호환되는 LCM1602 IIC 쉴드의 스위치이다. 내가 사용하는 STM32 보드도 아두이노와 호환되는 커넥터가 있으므로 사용 가능하다.

이 모듈은 빨간색 Reset 버튼을 제외하고 UP, DOWN, LEFT, RIGHT, SELECT 의 5개의 버튼을 가지고 있으면 회로도는 아래와 같다.

 

아날로그 핀인 A0의 전압레벨을 읽어 버튼의 눌림 상태를 확인할 수 있다.

 

아무 버튼도 안눌렀을 때 5V이고 S1을 누르면 0V이다. 직렬회로에서 합성저항의 값을 구하는건 그냥 더하면 되고 나머지는 전압분배법칙에 의해 알아낼 수 있다.

 

예를 들어 S3이 눌렸을 때를 가정하면 

Vin은 5V이고, R6 2000Ω / 총저항 2950Ω * 5V 하면 R6에 걸리는 전압이 나온다. 5V-3.9V 의 전압강하가 이루어져 A0핀이 읽는 전압레벨은 1.6V가 된다.

 

참고로 해당 모듈의 select 버튼이 눌렸을 때 A0핀 레벨이 3.6V인데 이는 STM32보드의 ADC Vref+ 레퍼런스 전압인 3.3V를 벗어나므로 제대로 측정할 수가 없다.

 

 

 

 

ADC1 3번채널로 PA3핀 사용

 

 

ADC설정

 

 

 

 

 

타이머 설정

 

 

 

타이머3에 공급되는 Clock source 는 90MHz이고 Prescaler 와 ARR(Period)는 위와같이 설정하여 100Hz(0.01초) 마다 인터럽트가 발생하도록 한다.

(참고로 1ms으로 맞추려고 하니 오류가 나서 안됐다.)

 

 

 

 

 

타이머3 인터럽트 활성화

 

 

 

stm32f4xx_hal_tim.c 에서 HAL_TIM_PeriodElapsedCallback 함수 가져와 main.c USER CODE 4 부분에 사용

 

 

 

 

+ uart 설정을 켜고 printf를 사용할 준비를 한다.

 

 

 

ADC 값을 담을 전역변수 선언

/* USER CODE BEGIN PV */
uint32_t adc_value;
/* USER CODE END PV */

 

 

 

 

while문 위에 TIM3 인터럽트 start 하고, ADC 폴링방식으로 start

  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start_IT(&htim3);
  HAL_ADC_Start(&hadc1);
  /* USER CODE END 2 */

 

 

 

 

HAL_TIM_PeriodElapsedCallback 함수 내에서 HAL_ADC_GetValue 로 ADC 값을 확인해 printf 로 출력한다.

/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  if(htim->Instance==TIM3)
  {
    adc_value = HAL_ADC_GetValue(&hadc1);
    printf("adc_value-> %lu\r\n",adc_value);

  }
}
/* USER CODE END 4 */

 

 

 

아두이노 IDE를 열고 STM32보드의 포트 선택

 

 

 

 

 

 

시리얼 모니터를 켜고 보드레이트를 맞춘다.

 

 

 

 

 

시리얼 모니터 대신 시리얼 플로터를 열고 그래프로 printf문에 있는 변수값을 확인할 수 있다.

 

 

 

기존에 진행중인 알람시계프로젝트에는 이 기능을 못넣었는데 다음 프로젝트에 사용해봐야 겠다.