Mise en oeuvre d'un DMA » Historique » Version 3
Anonyme, 26/11/2010 08:44
1 | 1 | Anonyme | h1. Mise en oeuvre d'un DMA |
---|---|---|---|
2 | |||
3 | 3 | Anonyme | h2. Présentation du DMA RX62N |
4 | |||
5 | 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. |
||
6 | |||
7 | h2. Exemple de démonstration proposé |
||
8 | |||
9 | 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. |
||
10 | |||
11 | h2. Code source associé |
||
12 | |||
13 | <pre> |
||
14 | void main() |
||
15 | { |
||
16 | Config_ADC(); |
||
17 | Config_TMR(); |
||
18 | Config_DMA(); |
||
19 | |||
20 | while (true); |
||
21 | } |
||
22 | |||
23 | void Config_ADC() |
||
24 | { |
||
25 | SYSTEM.MSTPCRA.BIT.MSTPA22 = 0; // Enable AD1 module |
||
26 | AD1.ADCSR.BIT.ADIE = 0; // No interrupts |
||
27 | AD1.ADCSR.BIT.CH = 0; // AN4 in continuous scan mode |
||
28 | AD1.ADCR.BIT.MODE = 2; // Continuous scan mode |
||
29 | AD1.ADCR.BIT.CKS = 3; // Clock Select PCLK |
||
30 | AD1.ADCR.BIT.TRGS = 0; // Conversion starts by software |
||
31 | AD1.ADDPR.BIT.DPSEL = 0; // LSB padding |
||
32 | AD1.ADCSR.BIT.ADST = 1; // Start AD1 |
||
33 | } |
||
34 | |||
35 | void Config_TMR() |
||
36 | { |
||
37 | MSTP(CMT2) = 0; |
||
38 | CMT2.CMCOR = 18750/2; // Sampling frequency : 640Hz |
||
39 | CMT2.CMCR.BIT.CKS = 0; // Divide PCLK by 8 - 6MHz |
||
40 | CMT.CMSTR1.BIT.STR2 = 1; |
||
41 | } |
||
42 | |||
43 | void Config_DMA() |
||
44 | { |
||
45 | // Power on DMA module |
||
46 | MSTP(DMACA) = 0; |
||
47 | |||
48 | // Timer CMT2 will enable a transfert |
||
49 | ICU.DMRSR0 = 30; |
||
50 | |||
51 | // Transfert from ADC - AN4 |
||
52 | DMAC0.DMSAR = (void*)&AD1.ADDRA; |
||
53 | |||
54 | // Transfert to RAM data - an array |
||
55 | DMAC0.DMDAR = (void*)dma_data; |
||
56 | |||
57 | // Transfert 640 x 16bits |
||
58 | DMAC0.DMCRA = (640<<16) + 640; |
||
59 | |||
60 | DMAC0.DMCRB = 0; |
||
61 | |||
62 | DMAC0.DMTMD.BIT.MD = 1; //Repeat mode |
||
63 | DMAC0.DMTMD.BIT.DTS = 0; //Destination is the repeat area |
||
64 | DMAC0.DMTMD.BIT.SZ = 1; //16 bits transfert |
||
65 | DMAC0.DMTMD.BIT.DCTG = 1; //Interrupts are the transfert clock |
||
66 | |||
67 | DMAC0.DMAMD.BIT.SM = 0; //Source is fixed - AN4 |
||
68 | DMAC0.DMAMD.BIT.SARA = 0; |
||
69 | DMAC0.DMAMD.BIT.DM = 2; //Destination is incremented |
||
70 | DMAC0.DMAMD.BIT.DARA = 0; |
||
71 | |||
72 | DMAC0.DMCSL.BIT.DISEL = 0; |
||
73 | |||
74 | DMAC0.DMINT.BIT.RPTIE = 1; // Repeat end interrupt enabled |
||
75 | DMAC0.DMINT.BIT.ESIE = 1; // Repeat end interrupt enabled |
||
76 | _IEN(_DMACA_DMAC0I) = 1; // Enable interrupt |
||
77 | _IPR( _DMACA_DMAC0I ) = 6; // Priority |
||
78 | |||
79 | DMAC.DMAST.BIT.DMST = 1; //DMA Module Enabled |
||
80 | DMAC0.DMCNT.BIT.DTE = 1; //Enable channel |
||
81 | |||
82 | // Enable TMR interrupt |
||
83 | CMT2.CMCR.BIT.CMIE = 1; |
||
84 | _IEN( _CMT2_CMI2 ) = 1; // Enable interrupt |
||
85 | } |
||
86 | |||
87 | </pre> |