Questo articolo mira a introdurre l’applicazione della modalità DMA2D tramite la scheda di sviluppo STM32H563. La cosiddetta modalità DMA 2D significa che il DMA può regolare dinamicamente la modalità di indirizzamento e la capacità del DMA impostando in anticipo l’offset di indirizzamento intra-blocco e l’offset di indirizzamento del blocco. In altre parole, quando il DMA esegue la trasmissione dei dati, l’indirizzamento intra-blocco non è più fissato per essere memorizzato in modo adiacente, ma l’intervallo di indirizzi per l’accesso ai dati durante due trasmissioni adiacenti può essere determinato tramite la programmazione. Per i trasferimenti di blocchi ripetitivi, non si tratta più semplicemente di riavviare dalla stessa posizione ogni volta, ma l’indirizzo di partenza del nuovo trasferimento può essere regolato in base all’offset dell’indirizzo del blocco.
Il principio della trasmissione DMA 2D
Supponiamo che vengano avviati tre trasferimenti per la stessa richiesta DMA, corrispondenti a tre blocchi di trasferimento DMA.

Come mostrato nella figura sopra, 5 elementi di dati contrassegnati in rosso [ovvero, il primo blocco] vengono trasmessi per la prima volta e l’accesso ai dati viene eseguito in base alla figura. La seconda e la terza volta sono simili alla prima volta e vengono trasmessi rispettivamente 5 dati verdi [ovvero, il secondo blocco] e 5 dati blu [ovvero, il terzo blocco]. Ovviamente, le regole di accesso ai dati in ogni blocco di trasmissione sono le stesse, con due spazi di archiviazione separati da due. Allo stesso tempo, quando la seconda trasmissione viene avviata dopo che la prima trasmissione è stata completata, o la terza trasmissione viene avviata dopo che la seconda trasmissione è stata completata, l’indirizzo di partenza viene riportato indietro di 14 spazi di indirizzo dalla posizione corrente prima dell’avvio.
Come utilizzare la funzione DMA 2D?
In questo esempio, utilizziamo la scheda STM32H563ZI Nucleo. E l’USART3 del chip deve essere collegato al VCP dell’STLINK integrato. Utilizzare l’assistente di debug della porta seriale sul PC per distribuire tre set di dati all’MCU in batch, i contenuti sono 5 caratteri R, 5 caratteri G e 5 caratteri B. Abilitare la funzione DMA 2D ricevuta da USART3.
A proposito, come promemoria, non tutti i canali del GPDMA della serie STM32H5 supportano la funzione di indirizzamento DMA 2D. Se il canale DMA supporta la funzione 2D è stato chiaramente scritto nell’interfaccia di configurazione di CubeMx. Se si utilizza la configurazione CubeMx, è possibile scegliere le parole appropriate. Qui scelgo DMA CH6 di GPDMA1, che supporta la funzione DMA 2D.
La configurazione di base per l’utilizzo di STM32CubeMX è la seguente:

Il fulcro della nostra configurazione è l’indirizzamento 2D, i dettagli sono i seguenti:
Ora si tratta di USART3DMA in ricezione, ovviamente l’indirizzo sorgente è fisso, ovvero il registro dati di ricezione USART3, quindi l’offset relativo all’indirizzo sorgente qui è 0. L’indirizzo di destinazione dell’accesso DMA è la memoria, che è variabile. Ogni volta che un elemento di dati viene memorizzato nel blocco, viene spostato in avanti di due posizioni, corrispondente al valore Offset indirizzo destinazione sottostante. Quando il round successivo di trasmissione viene avviato dopo che ogni trasmissione di blocco è stata completata, l’indirizzo di partenza è esattamente 14 posizioni indietro, corrispondente al valore Offset indirizzo blocco destinazione sottostante, l’indietro è negativo e l’avanti è positivo. Qui, vengono ripetuti un totale di 3 trasferimenti di blocchi, corrispondente al valore Contatore ripetizioni sottostante.

In realtà, dopo 3 round di ripetuta trasmissione di blocchi DMA, i dati ricevuti sembrano il modello indicato dalla freccia nella figura seguente.

Utilizzare STM32CubeMx per completare la configurazione, aggiungere il codice utente per il debug e la verifica. Il codice utente che deve essere aggiunto manualmente sono principalmente le seguenti due righe:
__HAL_LINKDMA(&huart3, hdmarx, handle_GPDMA1_Channel6);
HAL_UART_Receive_DMA(&huart3,(uint8_t *)aRxBuffer, 5); //Receive 5 data per block
La figura seguente è il risultato basato sul debug. Attraverso tre ricezioni DMA indipendenti, i dati vengono memorizzati regolarmente in ordine RGB.




