Projet

Général

Profil

Mise en oeuvre d'un DMA » Historique » Révision 3

Révision 2 (Anonyme, 26/11/2010 08:31) → Révision 3/4 (Anonyme, 26/11/2010 08:44)

h1. Mise en oeuvre d'un DMA 

 h2. 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.  

 h2. 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. 

 h2. Code source associé 

 <pre> 
 void main() 
 { 
   Config_ADC(); 
   Config_TMR(); 
   Config_DMA(); 

   while (true); 
 } 

 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 	
 } 

 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; 
 } 

 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 	
 } 

 </pre>