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
Bu kod, UART2 üzerinden 256 baytlık veriyi DMA ile buffer'a alır. CPU kesinti beklemez; veri arka planda gelir.
1#include "stm32f4xx_hal.h"23uint8_t rx_buffer[256];4UART_HandleTypeDef huart2;5DMA_HandleTypeDef hdma_usart2_rx;67void MX_DMA_Init(void) {8__HAL_RCC_DMA1_CLK_ENABLE();910hdma_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;1920HAL_DMA_Init(&hdma_usart2_rx);21__HAL_LINKDMA(&huart2, hdmarx, hdma_usart2_rx);22}2324void 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;3132HAL_UART_Init(&huart2);33}3435int main(void) {36HAL_Init();37MX_DMA_Init();38MX_USART2_UART_Init();3940// DMA ile UART alımını başlat41HAL_UART_Receive_DMA(&huart2, rx_buffer, 256);4243while(1) {44// CPU burada diğer görevleri yapabilir45// rx_buffer arka planda doluyor46}4748return 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.
0 yorum