Forum: Mikrocontroller und Digitale Elektronik [STM32] DAC + DMA + Timer = Problem


von Torben H. (bauteiltoeter)


Lesenswert?

Hi,

ich versuche im Moment ein Array aus dem RAM auf den Internen DACs 
meines STM32F429 Discovery boards zu geben.
Das ganze soll dazu auch noch Timergesteuert funktionieren.

Ganz am Anfang: Ich bin ein STM32 Neuling auch wenn ich schon viel mit 
AVRs gemacht habe fehlt mir hier also komplett die Erfahrung.

Zuerst einmal hier ist der relevante Code:
1
#define SINUS_STEPS 25
2
uint8_t SINUS[SINUS_STEPS] = {126,157,186,213,233,248,255,253,244,228,204,178,148,115,85,55,32,15,4,1,7,19,38,64,93};
3
4
void rtty_maintask(void * pvParameters)
5
{
6
    rtty_init();
7
8
    while(1)
9
    {
10
11
    }
12
}
13
14
void rtty_init(void)
15
{
16
    NVIC_InitTypeDef NVIC_InitStructure;
17
18
    // Timer Interrupt konfigurieren
19
    NVIC_InitStructure.NVIC_IRQChannel = TIM6_DAC_IRQn;
20
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
21
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
22
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
23
    NVIC_Init(&NVIC_InitStructure);
24
25
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
26
    DMA1_Stream6->CR &= 0xF0100000; //ZKomplett 0 setzen, dabei "reserved" Bits unberührt lassen
27
    DMA1_Stream6->CR |= DMA_SxCR_CHSEL_2 | DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_0; //Channel 7 selected (DAC)
28
    DMA1_Stream6->CR |= DMA_SxCR_PL_1 | DMA_SxCR_PL_0; //Priority very high
29
    DMA1_Stream6->CR |= DMA_SxCR_MINC; //Memory adress pointer is incremented
30
    DMA1_Stream6->CR |= DMA_SxCR_CIRC; //Circular Mode neabled
31
    DMA1_Stream6->CR |= DMA_SxCR_DIR_0; //Memory-to-peripheral
32
    DMA1_Stream6->CR |= DMA_SxCR_PFCTRL; //Peripheral is the flow controller
33
34
    DMA1_Stream6->NDTR = SINUS_STEPS; //25 Werte
35
    DMA1_Stream6->PAR = DAC_BASE + 0x1C ; //DAC Adresse
36
    DMA1_Stream6->M0AR = (uint32_t)SINUS; //Lesen aus dem Sinus-Array
37
38
    DMA1_Stream6->FCR &= 0xFFFFFF40; //FIFO control register zurück setzen, dabei "reserved" bits unberührt lassen
39
40
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
41
    DAC->CR &= 0xC000C000;
42
    DAC->CR |= DAC_CR_DMAEN2; //DAC Channel 2 DMA mode neabled
43
    DAC->CR |= DAC_CR_TEN2; //DAC channel 2 trigger enable
44
    DAC->CR |= DAC_CR_EN2; //DAC Enable
45
46
    DMA1->HIFCR |= DMA_HIFCR_CTCIF7 |DMA_HIFCR_CHTIF7 | DMA_HIFCR_CTEIF7 | DMA_HIFCR_CDMEIF7| DMA_HIFCR_CFEIF7; //Clear corresponding flags
47
48
    DMA1_Stream6->CR |= DMA_SxCR_EN; //DMA stream enabled
49
50
    // Timer 2 konfigurieren
51
    // Sollfrequenz:
52
    //   53,125kHz (2125*25) für MARK -> 15808
53
    //   57,375kHz (2295*25) für SPACE -> 1464
54
    //~11,904nS pro Tick
55
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); // Takt für Timer2 einschalten
56
    TIM6->PSC = 0; //Prescaler 1
57
    TIM6->ARR = 1464; //Autoreload register
58
    TIM6->DIER |= TIM_DIER_UIE; //Interrupt enabled
59
    TIM6->CR2 |= TIM_CR2_MMS_1; //TRGO on Update
60
    TIM6->CR1 |= TIM_CR1_CEN;   //Tim6 enable
61
}
62
63
void TIM6_DAC_IRQHandler(void)
64
{
65
66
    TIM6->SR &= ~TIM_SR_UIF; //Interrupt pending flag zurücksetzen
67
68
    GPIOG->ODR ^= GPIO_Pin_14;
69
}

Benutzt werden sollen Timer6, DAC2 und DMA1 Stream 6 Channel 7.
Der Timer erzeugt Interrupts mit einer Frequenz von 57,3 kHz (ungefair). 
Jedes Update-Event wird an den DAC weiter gereicht (TRGO on Update).
Der DAC soll sich darauf hin ein Byte vom DMA holen und in einen 
Analogwert wandeln. Diese Freqzeunz kann ich auch am G.14 messen.
Leider habe ich jetzt grade keine Ahnung mehr wo genau ich weiter suchen 
soll - warum wird der DMA nicht ausgelöst? oder warum wird die Zahl 
nicht gewandelt?
Oder oder oder...
Ich vermute, ich habe irgendwo einen kleinen Softwarehebel übersehen mit 
dem das ganze wie auf magische Weise dazu überredet werden kann zu 
funktionieren, daher währe es unglaublich freundlich, wenn einer der 
STM32-Profis hier einmal über meinen Code gucken könnten.

lg

von So geht 's (Gast)


Lesenswert?

Das sind ja drei Wünsche auf einmal. ;-) Das könnte man auch 
scheibenweise angehen.

Aber zum STM32 gibt es Tonnen an Beispielen:
http://www.diller-technologies.de/stm32_wide.html#dac_dma
http://mikrocontroller.bplaced.net/wordpress/?page_id=1013

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.