32F429IDISCOVERY HAL_DMA_UART 제어

2019. 7. 2. 20:21임베디드/32F429IDISCOVERY

DMA는 Direct memory access로 CPU 개입 없이 '페리페럴-메모리' 혹은 '메모리-메모리' 데이터 이동을 하고 싶을 때 사용된다. CPU는 메모리와 주변 IO에 비해 매우 빠르기 때문에, 만일 둘 간의 전송이 이뤄진다면 CPU의 속도가 느려질 수밖에 없다. 따라서 CPU 자원을 유지시키면서 위와 같은 동작을 하고 싶을 때 DMA 제어기를 사용하게 된다

 

DMA는 시스템 최적화에 알맞은 빠른 AHB 버스 구조와 FIFO 기술을 사용하고 있다. STMF4 시리즈에는 총 2개의 DMA 제어기가 있고, 각각 8개의 하드웨어 자원(총 16개)을 등록할 수 있다. 하드웨어 우선순위 말고도 Arbiter라는 중재기를 사용해서 우선순위를 제어할 수 있다. Stream 우선순위라고 소프트웨어적으로 정의를 내릴 수 있다

 

 

 

DMA에서 지원하는 페리페럴은 TIM, I2C, USART, SPI, ADC, DAC 등이 있다. 1개의 Stream에서 하나의 채널만 가능하다. 그리고 DMA1, 2 동시에 동작이 가능하다

 

따라서 UART를 DMA로 받을 것인데, CPU가 직접 명령을 제어하는 폴링이나 인터럽트보다 빠르게 반응하게 된다. 따라서, DMA로 UART 수신 데이터를 메모리로 전달하고 정해진 문자열을 출력하면서 PG14를 toggle 시키는 코드를 작성하려고 한다

 

보드의 UART는 1번으로, DMA2에서 수신을 받을 수 있는 것으로 확인된다

 

 

1. 기본적으로 사용할 GPIO와 UART를 설정한다

 

 

2. DMA 설정은 위에서 확인한대로 DMA2에서 UART 수신을 Stream으로 잡도록 할 것이다

 

모드 변경은 Normal에서 Circular로 변경하도록 한다. Circular 모드는 지속적인 데이터 흐름을 제어할 수 있는 Circular buffer를 사용하게 된다. CIRC bit in the DMA_SxCR을 설정해서 사용할 수 있다. Circular 모드가 활성화되면 DMA Request가 지속적으로 나타나게 된다. 따라서 지속적으로 값을 취득해야하는 ADC에서 주로 사용하게 된다

 

코드 상에서는 Circular는 지속적으로 요청이 자동적으로 되기 때문에, DMA 함수를 쓸 필요가 없지만 Normal 모드에서는 요청이 왔을 때 마지막에 추가를 해줘야 한다