STM32F103 ADC 편
- ADC Multi Channel CUBEMX로 초기설정하기
- ADC Multi Channel 코드 작성하기
- CUBEMX로 ADC DMA 초기설정하기
- ADC DMA 코드 작성하기 (현재 포스팅)
- 코드 작성하기 – 인터럽트
- UART ADC 데이터 송신하기
일주일 만의 포스팅이다. 이전 포스팅에서 생성한 코드에서 ADC코드를 사용하는 방법이다. 이 포스팅에서는 퍼포먼스보다는 사용자 편의성과 코드의 간결함을 우선시 한다.
- ADC는 DMA(직접 메모리 접근)를 이용해 구성한다.
- ADC 캘리브레이션 기능을 적용한다.
위 두가지를 염두하고 코드를 작성했다.
말은 거창하나 코드는 두 줄 밖에 안쓴다. 정말이다. (변수 생성 제외)
먼저 캘리브레이션을 시작하고, ADC DMA를 적용하면 된다. 여기서는 사용자 사용자 편의성을 우선시한 HAL드라이버를 사용하므로 CMSIS 드라이버를 사용하는 코더는 적용되지 않는 점을 유의하시라.
프로젝트의 main.c 파일을 열면 CUBEMX로 생성된 기초 코드들이 있다. 이 상태에서 while문이 있는데, 전원을 인가한 후에 기초 설정이 끝나면 프로그램은 while문을 계속 반복한다. 우리는 ADC 값을 계속 읽기를 원하므로, 이 코드들을 while문 안에 작성하면 동작한다.
아래와 같이 코드를 작성하면 정상 동작한다.
코드는 두 줄 밖에 안되므로, 이에 대한 설명을 추가한다.
1. HAL_ADCEx_Calibration_Start
라이브러리에서 달아놓은 주석과 함수의 형태를 표시한다.
함수에서는 캘리브레이션을 하기에 앞서 ADC가 반드시 비활성화 된 상태여야 한다고 적혀있다. 그리고 이 함수가 완료되면 ADC가 동작한다고 서술되어 있다. 입력인수로는 ADC 핸들 타입을 적도록 되어 있다. 인자로 주소 값을 넘겨주므로, 실제 코드에서는 HAL_ADCEx_Calibration_Start(&hadc1);로 코드를 기입하면 된다.
2. HAL_ADC_Start_DMA
이 함수를 사용하면 DMA 전송이 완료되거나 half transfer가 되었을 때 인터럽트가 활성화 된다. 각 경우에따른 전용 콜백함수가 있다. 그리고 이 함수는 싱글-ADC모드만 지원한다. 다중 ADC 모드를 원하면 MultimodeStart함수를 사용해야 한다. STM32F1시리즈 는 ADC1과 ADC3에만 DMA를 가지고 있다. ADC2는 멀티 ADC 모드를 사용할 때 ADC1이 가지고 있는 DMA를 사용할 수 있는 듯 하다. 단, 반드시 Half Word로 설정해야 한다. 아니면 데이터가 넘쳐서 사용 못하나보다.
hadc는 위에 서술했던 &hadc1을 입력 변수로 넣으면 된다.
pData는 ADC DMA에 있는 데이터를 저장한 임시버퍼를 기입한다. 따라서 이것도 데이터가 배열이면 데이터 변수 명을, 배열이 아니라면 &를 붙여 주소 값을 넘겨줘야 한다. 이번에는 사용하는 ADC 갯수가 2개이므로 배열로 선언했고, 배열의 이름은 ADCvalue이다.
Length는 데이터의 갯수이다. 전 포스팅에서 사용하는 ADC의 갯수는 2개이므로 2를 기입하면 된다.
마지막으로 전역변수로 __IO uint32_t ADCvalue[2];로 선언해준다. __IO는 volatile를 의미하고, 이는 최적화하는 과정에서 주소 값을 바꾸지 못하게 설정해준다. uint32_t는 32비트 unsigned int를 의미한다. 만약에 half word로 설정했다면, uint16_t로 설정하면 될 것이다.
위와 같이 설정하면 ADC가 정상동작 한다. Nucleo 보드의 경우 STMSTUDIO로 ADC 값을 실시간으로 읽을 수 있다.
끗