그라운드 임베디드 유튜브 구독

노트 / MCU 펌웨어

DMA 활용: ADC와 UART를 CPU 없이

ADC 값을 순환 버퍼로 계속 채우고, UART로 길이를 모르는 패킷을 받는 실전 DMA 설정 두 가지.

GROUND EMBEDDED · 정리 노트펌웨어 09DMA 활용 1uint16_t adc_buf[4]; 2HAL_ADC_Start_DMA(&hadc1, (uint32_t *)a…// 순환…

ADC + 순환 DMA

ADC 스캔 결과를 DMA가 배열에 계속 채웁니다. CPU는 배열을 읽기만 하면 최신 값이 들어 있습니다.

uint16_t adc_buf[4];
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc_buf, 4);   // 순환 모드로 설정해 두면 계속 갱신

긴 파형을 모을 때는 버퍼를 둘로 나눠 절반 완료 / 완료 인터럽트마다 반대쪽 절반을 처리합니다(더블 버퍼링).

UART 수신 + IDLE 라인

패킷 길이를 모를 때의 정석입니다.

  1. UART RX를 순환 DMA로 큰 버퍼(예: 256바이트)에 계속 받음
  2. 선이 1바이트 시간 이상 조용하면 IDLE 인터럽트 발생
  3. DMA 남은 개수(NDTR)로 현재 쓰기 위치를 계산해 새로 들어온 구간만 처리

HAL에는 HAL_UARTEx_ReceiveToIdle_DMA()가 있습니다.

체크할 것

  • DMA 스트림과 채널 번호는 주변장치마다 정해져 있습니다(레퍼런스 매뉴얼 표).
  • DMA가 접근할 수 없는 메모리 영역이 있는 칩도 있습니다(일부 STM32의 CCM RAM, DTCM).
  • 캐시가 있는 칩(H7, F7)은 DMA 버퍼를 캐시 비활성 영역에 두거나 캐시 정리·무효화를 합니다.