Forum: Mikrocontroller und Digitale Elektronik ATXmega DMA mit DAC funktioniert nicht richtig


von Holger K. (holgerkraehe)


Lesenswert?

Hallo zusammen

Ich möchte eine Sinustabelle mittels DMA am DAC des Atxmega128A3U 
ausgeben.
Leider wechselt die Ausgangsspannung aktuell von ca. 0.8V zu 1V hin und 
her.

Vielleicht sieht jemand was das Problem sein könnte?

Danke!
1
#define SYMBOL_BUFFER_SIZE  32
2
3
const uint16_t sineLUT[SYMBOL_BUFFER_SIZE * 2] =
4
{
5
  // 100%
6
  0x800,0x98f,0xb0f,0xc71,0xda7,0xea6,0xf63,0xfd8,
7
  0xfff,0xfd8,0xf63,0xea6,0xda7,0xc71,0xb0f,0x98f,
8
  0x800,0x670,0x4f0,0x38e,0x258,0x159,0x9c,0x27,
9
  0x0,0x27,0x9c,0x159,0x258,0x38e,0x4f0,0x670,
10
  0x800,0x98f,0xb0f,0xc71,0xda7,0xea6,0xf63,0xfd8,
11
  0xfff,0xfd8,0xf63,0xea6,0xda7,0xc71,0xb0f,0x98f,
12
  0x800,0x670,0x4f0,0x38e,0x258,0x159,0x9c,0x27,
13
  0x0,0x27,0x9c,0x159,0x258,0x38e,0x4f0,0x670,  
14
};
15
16
void vInitDAC()
17
{
18
  DACB.CTRLA = DAC_CH0EN_bm;  // Enable CH0
19
  DACB.CTRLB = DAC_CH0TRIG_bm;  // AutoTrigger CH0
20
  DACB.CTRLC = 0x0;  // Refernece Voltage
21
  DACB.EVCTRL = DAC_EVSEL_0_gc;  // Event Channel 1
22
  DACB.CTRLA |= DAC_ENABLE_bm;
23
  PORTB.DIRSET = 0x04;
24
}
25
26
void vInitDMA()
27
{
28
  vInitDAC();
29
30
  // set TCC1 to 11024Hz overflow, actually 11019.2838Hz (-0.052% error)
31
  TCC1.CTRLA = 0; // stop if running
32
  TCC1.CNT = 0;
33
  TCC1.PER = 0xFFFF;
34
35
  EVSYS.CH0MUX = EVSYS_CHMUX_TCC1_OVF_gc; // trigger on timer overflow  
36
37
  // reset DMA controller
38
  DMA.CTRL = 0;
39
  DMA.CTRL = DMA_RESET_bm;
40
  while ((DMA.CTRL & DMA_RESET_bm) != 0);
41
  
42
  DMA.CTRL = DMA_CH_ENABLE_bm | DMA_DBUFMODE_CH01_gc; // double buffered with channels 0 and 1
43
  
44
  //Bei Double Buffering wird automatisch aus Channel 0 und 1 ein "Pair" gebildet. 
45
  //Siehe dazu AVR1304.P8
46
  
47
  // channel 0
48
  // **** TODO: reset dma channels
49
  DMA.CH0.REPCNT    = 0;
50
  DMA.CH0.CTRLA    = DMA_CH_BURSTLEN_2BYTE_gc | DMA_CH_SINGLE_bm | DMA_CH_REPEAT_bm; // ADC result is 2 byte 12 bit word
51
  DMA.CH0.CTRLB    = 0x1;
52
  DMA.CH0.ADDRCTRL  = DMA_CH_SRCRELOAD_TRANSACTION_gc | DMA_CH_SRCDIR_INC_gc | // reload source after every burst
53
  DMA_CH_DESTRELOAD_BURST_gc | DMA_CH_DESTDIR_INC_gc; // reload dest after every transaction
54
  DMA.CH0.TRIGSRC    = DMA_CH_TRIGSRC_TCC1_OVF_gc;
55
  DMA.CH0.TRFCNT    = SYMBOL_BUFFER_SIZE * 2; // always the number of bytes, even if burst length > 1
56
  DMA.CH0.DESTADDR0  = ((uint16_t)(&DACB.CH0DATA)>>0) & 0xFF;
57
  DMA.CH0.DESTADDR1  = ((uint16_t)(&DACB.CH0DATA)>>8) & 0xFF;
58
  DMA.CH0.DESTADDR2  = 0;
59
  DMA.CH0.SRCADDR0  = ( (uint16_t) (&sineLUT[0]) >> 0) & 0xFF;
60
  DMA.CH0.SRCADDR1  = ( (uint16_t) (&sineLUT[0]) >> 8) & 0xFF;
61
  DMA.CH0.SRCADDR2  = 0;
62
63
  // channel 1
64
  DMA.CH1.REPCNT    = 0;
65
  DMA.CH1.CTRLA    = DMA_CH_BURSTLEN_2BYTE_gc | DMA_CH_SINGLE_bm | DMA_CH_REPEAT_bm; // ADC result is 2 byte 12 bit word
66
  DMA.CH1.CTRLB    = 0x1;
67
  DMA.CH1.ADDRCTRL  = DMA_CH_SRCRELOAD_TRANSACTION_gc  | DMA_CH_SRCDIR_INC_gc | // reload source after every burst
68
  DMA_CH_DESTRELOAD_BURST_gc  | DMA_CH_DESTDIR_INC_gc; // reload dest after every transaction
69
  DMA.CH1.TRIGSRC    = DMA_CH_TRIGSRC_TCC1_OVF_gc;
70
  DMA.CH1.TRFCNT    = SYMBOL_BUFFER_SIZE * 2;
71
  DMA.CH1.DESTADDR0  = ((uint16_t)(&DACB.CH0DATA)>>0) & 0xFF;
72
  DMA.CH1.DESTADDR1  = ((uint16_t)(&DACB.CH0DATA)>>8) & 0xFF;
73
  DMA.CH1.DESTADDR2  = 0;
74
  DMA.CH1.SRCADDR0  = ( (uint16_t) (&sineLUT[0]) >> 0) & 0xFF;
75
  DMA.CH1.SRCADDR1  = ( (uint16_t) (&sineLUT[0]) >> 8) & 0xFF;
76
  DMA.CH1.SRCADDR2  = 0;
77
78
  DMA.CH0.CTRLA    |= DMA_CH_ENABLE_bm;
79
  
80
  TCC1.CTRLA      = TC_CLKSEL_DIV1024_gc; // start timer, and in turn ADC
81
82
83
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.