STM32'de DMA ile Veri Transferini Hızlandırmak

STM32'nin DMA (Direct Memory Access) özelliği, CPU'yu meşgul etmeden bellek ve çevre birimleri arasında hızlı veri aktarımı sağlar. Özellikle UART, SPI, ADC gibi yüksek hızlı iletişim protokollerinde işlemci yükünü dramatik şekilde azaltır.

Sorun şu: CPU'nun her bayt için kesinti işlemesi gerekirse, gerçek zamanlı uygulamalarda gecikme oluşur. DMA bunu atlatarak, bellek-çevre aktarımını donanım seviyesinde gerçekleştirir. CPU diğer görevlere odaklanabilir.

Harita şöyle: DMA kanalını yapılandır kaynağı (ADC, UART vb.) belirt hedef bellek adresini ayarla transfer boyutunu set et başlat. STM32CubeMX ile otomatik kod üretebilirsin, ancak manuel kontrol daha esnek.

Pratik Örnek: UART üzerinden DMA ile veri alma

Reklam · TEST
AdSense Test ReklamıYazı arası (gönderi içi) · Yazı arası

Bu kod, UART2 üzerinden 256 baytlık veriyi DMA ile buffer'a alır. CPU kesinti beklemez; veri arka planda gelir.

1 "stm32f4xx_hal.h"
2
3uint8_t rx_buffer[256];
4UART_HandleTypeDef huart2;
5DMA_HandleTypeDef hdma_usart2_rx;
6
7void MX_DMA_Init(void) {
8__HAL_RCC_DMA1_CLK_ENABLE();
9
10hdma_usart2_rx.Instance = DMA1_Stream5;
11hdma_usart2_rx.Init.Channel = DMA_CHANNEL_4;
12hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
13hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
14hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
15hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
16hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
17hdma_usart2_rx.Init.Mode = DMA_CIRCULAR;
18hdma_usart2_rx.Init.Priority = DMA_PRIORITY_HIGH;
19
20HAL_DMA_Init(&hdma_usart2_rx);
21__HAL_LINKDMA(&huart2, hdmarx, hdma_usart2_rx);
22}
23
24void MX_USART2_UART_Init(void) {
25huart2.Instance = USART2;
26huart2.Init.BaudRate = 115200;
27huart2.Init.WordLength = UART_WORDLENGTH_8B;
28huart2.Init.StopBits = UART_STOPBITS_1;
29huart2.Init.Parity = UART_PARITY_NONE;
30huart2.Init.Mode = UART_MODE_RX_TX;
31
32HAL_UART_Init(&huart2);
33}
34
35int main(void) {
36HAL_Init();
37MX_DMA_Init();
38MX_USART2_UART_Init();
39
40// DMA ile UART alımını başlat
41HAL_UART_Receive_DMA(&huart2, rx_buffer, 256);
42
43while(1) {
44// CPU burada diğer görevleri yapabilir
45// rx_buffer arka planda doluyor
46}
47
48return 0;
49}

Beklenen çıktı: UART2'ye gönderilen veriler, CPU kesintisi olmadan rx_buffer'a yazılır. Circular mod sayesinde buffer dolduğunda baştan başlar.

Sık hata: DMA kanalını yanlış seçmek. Her UART/SPI için donanım desteklediği kanallar sabitlenmiştir; veri sayfasını kontrol et. Ayrıca bellek adresinin RAM'de olması şart, Flash'tan DMA okuyabilirsin ama yazamazsın.

DMA'nın gücü burada: 115200 baud'da 256 baytlık veri CPU'yu neredeyse hiç meşgul etmez. Sensorlardan yüksek frekansta veri çekmek, ses işleme veya ağ protokolleri için bu teknik hayati.

Reklam · TEST
AdSense Test ReklamıGönderi altı · Görüntülü
konu hakkında tepkinizi verebilirsiniz