STM32F103 ADC 코드 작성하기 – 인터럽트편

STM32F103 ADC 코드 작성하기 – 인터럽트편

STM32F103 ADC 편 (STM32F1)

  1. ADC Multi Channel CUBEMX로 초기설정하기 
  2. ADC Multi Channel 코드 작성하기
  3. CUBEMX로 ADC DMA 초기설정하기
  4. ADC DMA 코드 작성하기
  5. 코드 작성하기 – 인터럽트(현재 포스팅)
  6. UART ADC 데이터 송신하기

지난번 포스팅에 이어서 작성한다.

이전에 언급했듯이, DMA를 시작하는 함수를 실행하면, 인터럽트 기능도 사용할 수 있다. 오늘은 그 콜백함수를 사용할 것이다.

HAL_ADC_Start_DMA 코드는 인터럽트가 가능하다.

UM1850문서에 인터럽트 함수가 기술되어 있다.

여기서 우리는 Half Word가 아닌, Word를 사용했으므로

HAL_ADC_ConvCpltCallback()을 쓸 것이다.

그리고 stm32f1XX_hal_adc.c 파일을 찾아보면 그 함수가 있다.

찾았다 요놈.

그래서 이 놈을 main.c에 가져다가 코드를 작성하면 된다. 데이터 컨버젼이 끝나면 어떤 함수를 실행할지는 사용자 마음대로다.

필자는 ADC로 값을 읽으면, 그 전압 값으로 변환한 후, 블루투스로 송신하는 프로젝트를 만들었다. 코드는 여기있다.

참! 전달 인자로 ADC_HandleTypeDef* hadc가 있는 이유가 궁금한 사람도 있을 것이다. 필자는 hadc1만을 사용하기 때문에 굳이 if문으로 걸러내야 할 이유가 없지만, hadc가 2개 이상일 경우 어떤 hadc에서 인터럽트가 걸리는지 걸러내야 할 필요가 있다. 어떤 hadc이던 상관없이 인터럽트가 걸리면 HAL_ADC_ConvCpltCallback함수가 호출되기 때문이다. 따라서 if문으로 hadc를 걸러내기 위해서는 전달 인자가 필요하기 때문에 존재한다. 만약에 if문으로 hadc1을 걸러낸다면..음

if(hadc->Instance == hadc1.Instance)

{

….

}

위 처럼 구성하면 될 것이다.

총 정리를 하자면, 인터럽트를 쓸 때 main.c파일에

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{

//필요한 코드 작성

//만약 어떤 adc인지 가려야 할 필요가 있다면 아래와 같이 조건문 작성

if(hadc->Instance == hadc1.Instance)

{

….

}

}

위와 같이 작성하면 된다.

7 Replies to “STM32F103 ADC 코드 작성하기 – 인터럽트편”

  1. 글 잘 보았습니다.
    제가 ADC를 사용하지 않아 잘은 모르겠지만

    CubeMX 에서 생성해주는 다른 코드에서 Peripheral 을 특정할 때 사용하는 방법으로,

    if(spiHandle->Instance==SPI1)
    이런식으로 핸들의 Instance 를 체크하는 방법으로 사용하는것이 좀더 일관성이 있을거같아 리플 남겨봅니다.

    1. 안녕하세요. 요 근래에 개발 업무가 많아서 확인이 늦었습니다. instance를 체크하는 방법이 많이 쓰이네요. 인스턴스를 사용한다면 사용 인자가 hadc->instance = ADC1와 같이 사용하면 될 듯 싶습니다.
      요즘은 ESP관련 개발을 하다보니, 정확한 검증을 하려면 시간이 걸릴 듯 싶군요. 소중한 답글 감사드립니다.

    2. 안녕하세요 오랜만에 답변드립니다. 포스팅에서 기술한 방법대로 if(hadc == &hadc1)로 작성해도 구동은 됩니다. 다만 문의주신 내용처럼 구체적으로 구성하길 원한다면
      if(hadc->Instance == hadc1.Instance)
      로 구성하면 될 듯 합니다.

      감사합니다.

  2. 핑백: STM32F1XX ADC 코드 작성하기 - DKMIN
  3. 자세한 설명 감사드립니다.
    한가지 질문이 있는데 HAL_ADC_Start_DAM(hadc1, ADCvalue, 8) 로 하게된다면 8개의 채널에서 각각 ADC값이 모두 넘어왔을 때 인터럽트함수가 실행이 되는지 아니면 1개의 채널에서만이라도 ADC값을 받게 되면 인터럽트 함수가 실행되는지 궁금합니다.

    1. 안녕하세요. HAL_ADC_Start_DMA 함수의 경우 UART 인터럽트 챕터랑 비슷하게 호출이 될겁니다. HAL_ADC_Start_DMA함수 내에 8개의 데이터가 ADCvalue에 저장이 된 뒤에 IRQ핸들러가 호출되고, 그 성격을 분류해서 최종적으로 콜백함수가 호출하게 되는 것입니다. 결국 HAL_ADC_Start_DMA 함수가 종료된 뒤에 핸들러가 호출되므로 8개가 모두 넘어왔을 때 콜백 함수가 호출 될 것이라 생각합니다.
      현재 저는 내장 ADC를 사용하지 않고 있어 이 함수를 사용하지 않습니다. 기약드릴 수는 없습니다만 추후에 사용해보고 내용이 다르다면 다시 피드백 드리겠습니다.

      감사합니다.

댓글 남기기

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d 블로거가 이것을 좋아합니다: