Actions
Mise en oeuvre d'un DMA¶
Présentation du DMA RX62N¶
L'utilisation d'un DMA lors d'un projet de développement sur microcontroleur est parfois fastidieuse et longue. Cependant, ce périphérique permet d'exploiter toute la puissance du microcontroleur. Dans le cas précis du RX62N, un DMA Controller est disponible, possédant lui même 4 canaux. Ces canaux permettent le transfert de données de manières bien différentes:- Le mode bloc (1 activation = transfert de X octets)
- Le mode répété
- Le mode simple
Exemple de démonstration proposé¶
Il est proposé ici de développer un code de démarrage simple, utilisant le DMA en mode répétition, sur source de déclenchement de type interruption. Concrètement, il s'agit d'effectuer l'acquisition de données analogique, via le convertisseur analogique/numérique, à cadence fixée par un timer. Un transfert est effectué automatiquement vers une zone de données en RAM, contenant 640 points. Cela illustre l'utilisation faite dans l'oscilloscope.
Code source associé¶
// The destination of the data acquired unsigned short dma_data[640]; // DMA channel 0 interrupt - activated when 640 x 16bits have been transfered #pragma interrupt (ISR_DMAC0 (vect=198, enable)) void ISR_DMAC0() { DMAC0.DMCNT.BIT.DTE = 1; //Enable channel } // Entry point void main() { Config_ADC(); Config_TMR(); Config_DMA(); while (true); } // Configuration of analog to digital converter void Config_ADC() { SYSTEM.MSTPCRA.BIT.MSTPA22 = 0; // Enable AD1 module AD1.ADCSR.BIT.ADIE = 0; // No interrupts AD1.ADCSR.BIT.CH = 0; // AN4 in continuous scan mode AD1.ADCR.BIT.MODE = 2; // Continuous scan mode AD1.ADCR.BIT.CKS = 3; // Clock Select PCLK AD1.ADCR.BIT.TRGS = 0; // Conversion starts by software AD1.ADDPR.BIT.DPSEL = 0; // LSB padding AD1.ADCSR.BIT.ADST = 1; // Start AD1 } // Configuration of timer (CMT2 module) void Config_TMR() { MSTP(CMT2) = 0; CMT2.CMCOR = 18750/2; // Sampling frequency : 640Hz CMT2.CMCR.BIT.CKS = 0; // Divide PCLK by 8 - 6MHz CMT.CMSTR1.BIT.STR2 = 1; } // Configuration of the DMA void Config_DMA() { // Power on DMA module MSTP(DMACA) = 0; // Timer CMT2 will enable a transfert ICU.DMRSR0 = 30; // Transfert from ADC - AN4 DMAC0.DMSAR = (void*)&AD1.ADDRA; // Transfert to RAM data - an array DMAC0.DMDAR = (void*)dma_data; // Transfert 640 x 16bits DMAC0.DMCRA = (640<<16) + 640; DMAC0.DMCRB = 0; DMAC0.DMTMD.BIT.MD = 1; //Repeat mode DMAC0.DMTMD.BIT.DTS = 0; //Destination is the repeat area DMAC0.DMTMD.BIT.SZ = 1; //16 bits transfert DMAC0.DMTMD.BIT.DCTG = 1; //Interrupts are the transfert clock DMAC0.DMAMD.BIT.SM = 0; //Source is fixed - AN4 DMAC0.DMAMD.BIT.SARA = 0; DMAC0.DMAMD.BIT.DM = 2; //Destination is incremented DMAC0.DMAMD.BIT.DARA = 0; DMAC0.DMCSL.BIT.DISEL = 0; DMAC0.DMINT.BIT.RPTIE = 1; // Repeat end interrupt enabled DMAC0.DMINT.BIT.ESIE = 1; // Repeat end interrupt enabled _IEN(_DMACA_DMAC0I) = 1; // Enable interrupt _IPR( _DMACA_DMAC0I ) = 6; // Priority DMAC.DMAST.BIT.DMST = 1; //DMA Module Enabled DMAC0.DMCNT.BIT.DTE = 1; //Enable channel // Enable TMR interrupt CMT2.CMCR.BIT.CMIE = 1; _IEN( _CMT2_CMI2 ) = 1; // Enable interrupt }
Mis à jour par Anonyme il y a plus de 14 ans · 4 révisions