Forum: Mikrocontroller und Digitale Elektronik STM32F4 DAC + DMA


von Moritz M. (avrprogger)


Lesenswert?

Hallo,

ich versuche grade ein buffer über die DMA mit einem DAC auszugeben.

Leider funktioniert dies nicht.

Ich verwende DAC Channel 1 und DMA1 Stream 5 Channel 7 des 
STM32F4Discovery Board (STM32F407VG).  Ich schätze, das liegt daran, das 
ich das falsche Register als PeripheralBaseAdress ausgewählt habe 
(DAC->DOR1). Wer weiß welches Register ich nehemen muss? (DAC->?????). 
Oder ist es doch ein anderes Problem??

Hier noch mal mein Code:
1
#include "stm32f4xx.h"
2
3
void DAC_CH1_Init(void);
4
5
uint16_t buffer[4096];
6
int i;
7
8
int main(void)
9
{
10
  SystemInit();
11
12
  for(i = 0; i < 4096; i++)
13
  {
14
    buffer[i] = i;
15
  }
16
17
  DAC_CH1_Init();
18
19
20
    while(1)
21
    {
22
    }
23
24
    return 1;
25
}
26
27
void DAC_CH1_Init(void)
28
{
29
  //GPIO
30
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
31
32
  GPIO_DeInit(GPIOA);
33
34
  GPIO_InitTypeDef GPIO_A4;
35
36
  GPIO_A4.GPIO_Mode = GPIO_Mode_AN;
37
  GPIO_A4.GPIO_OType = GPIO_OType_PP;
38
  GPIO_A4.GPIO_Pin = GPIO_Pin_4;
39
  GPIO_A4.GPIO_PuPd = GPIO_PuPd_NOPULL;
40
  GPIO_A4.GPIO_Speed = GPIO_Speed_50MHz;
41
42
  GPIO_Init(GPIOA, &GPIO_A4);
43
44
  //TIM6
45
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
46
47
  TIM_DeInit(TIM6);
48
49
  TIM_TimeBaseInitTypeDef TIM6_Init_Struct;
50
51
  TIM6_Init_Struct.TIM_ClockDivision = TIM_CKD_DIV1;
52
  TIM6_Init_Struct.TIM_CounterMode = TIM_CounterMode_Up;
53
  TIM6_Init_Struct.TIM_Period = 0xFF;
54
  TIM6_Init_Struct.TIM_Prescaler = 0;
55
  TIM_TimeBaseInit(TIM6, &TIM6_Init_Struct);
56
57
  TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);
58
59
  TIM_Cmd(TIM6, ENABLE);
60
61
  //DAC
62
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
63
64
  DAC_DeInit();
65
66
  DAC_InitTypeDef DAC_CH1;
67
68
  DAC_CH1.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
69
  DAC_CH1.DAC_Trigger = DAC_Trigger_T6_TRGO;
70
  DAC_CH1.DAC_WaveGeneration = DAC_WaveGeneration_None;
71
72
  DAC_Init(DAC_Channel_1, &DAC_CH1);
73
74
  //DMA
75
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
76
77
  DMA_DeInit(DMA1_Stream5);
78
79
  DMA_InitTypeDef DMA1_STR5_CH7;
80
81
  DMA1_STR5_CH7.DMA_BufferSize = 4096;
82
  DMA1_STR5_CH7.DMA_Channel = DMA_Channel_7;
83
  DMA1_STR5_CH7.DMA_DIR = DMA_DIR_MemoryToPeripheral;
84
  DMA1_STR5_CH7.DMA_FIFOMode = DMA_FIFOMode_Disable;
85
  DMA1_STR5_CH7.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
86
  DMA1_STR5_CH7.DMA_Memory0BaseAddr = (uint32_t)&buffer;
87
  DMA1_STR5_CH7.DMA_MemoryBurst = DMA_MemoryBurst_Single;
88
  DMA1_STR5_CH7.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
89
  DMA1_STR5_CH7.DMA_MemoryInc = DMA_MemoryInc_Enable;
90
  DMA1_STR5_CH7.DMA_Mode = DMA_Mode_Circular;
91
  DMA1_STR5_CH7.DMA_PeripheralBaseAddr = DAC->DOR1; //-----??????????------
92
  DMA1_STR5_CH7.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
93
  DMA1_STR5_CH7.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
94
  DMA1_STR5_CH7.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
95
  DMA1_STR5_CH7.DMA_Priority = DMA_Priority_High;
96
97
  DMA_Init(DMA1_Stream5, &DMA1_STR5_CH7);
98
99
  DMA_Cmd(DMA1_Stream5, ENABLE);
100
101
  DAC_Cmd(DAC_Channel_1, ENABLE);
102
103
  DAC_DMACmd(DAC_Channel_1, ENABLE);
104
}

mfg
Moritz

von Moritz M. (avrprogger)


Lesenswert?

PS: Es muss an der DMA liegen, da ich mit dem GPIO, Timer, DAC ohne 
Probleme ein Triangle/Noise Signal erzeugen kann.

von holger (Gast)


Lesenswert?

>  DMA1_STR5_CH7.DMA_Memory0BaseAddr = (uint32_t)&buffer;

  DMA1_STR5_CH7.DMA_Memory0BaseAddr = (uint32_t)buffer;


>  DMA1_STR5_CH7.DMA_PeripheralBaseAddr = DAC->DOR1; //-----??????????------

These bits are read-only, they contain data output for DAC channel1.

Also ich würde sagen es ist DAC_DHR12R1.

von Moritz M. (avrprogger)


Lesenswert?

Hallo,

warum = (uint32_t)buffer?

es memory0address soll doch die anfangsaddresse sein oder?

Es kommt allerdings auch die ganze Zeit 3.3V.

Moritz

von Michael F. (startrekmichi)


Lesenswert?

Moritz M. schrieb:
> Hallo,
>
> warum = (uint32_t)buffer?
>
> es memory0address soll doch die anfangsaddresse sein oder?

Eben.
"buffer" ist ein Zeiger auf das erste Element des Arrays. "&buffer" ist 
die Adresse der Adresse ;)
Du könntest natürlich "&(buffer[0])" schreiben.

von Moritz M. (avrprogger)


Lesenswert?

funktioniert trotzdem nicht.

Moritz

von Moritz M. (avrprogger)


Lesenswert?

Hallo nochmal,

hat niemand eine Idee. Also UART mit DMA funktioniert. Und da verwende 
ich:
1
Memory0BaseAddr = (uint32_t)&buffer;

Moritz

von holger (Gast)


Lesenswert?

>hat niemand eine Idee. Also UART mit DMA funktioniert. Und da verwende
>ich:
>
>Memory0BaseAddr = (uint32_t)&buffer;

Dann zeig doch mal wie buffer da deklariert ist.

von Moritz M. (avrprogger)


Lesenswert?

Hallo:

also der Buffer ist so deklariert:
1
uint16_t buffer[4096];
2
3
for(int i = 0; i < 4096; i++)
4
{
5
    buffer[i] = i;
6
}

Moritz

von Tomas Poruba (Gast)


Lesenswert?

Hi,

I'm using libopenstm and this helped me:

DMA1_S5PAR = (u32*)&DAC_DHR12R1; (first i have here DMA1_S5PAR = 
(u32*)DAC_DHR12R1; and DMA always stops with transfer error)

Regards

Tomas

von pp (Gast)


Lesenswert?

#define DAC_DHR12R1_ADDRESS    0x40007408


DMA1_STR5_CH7.DMA_PeripheralBaseAddr = DAC->DOR1; 
//-----??????????------


DMA1_STR5_CH7.DMA_PeripheralBaseAddr = DAC_DHR12R1_ADDRESS;

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.