STM32F4 STM32L152: DAC Ausgabe DDS Spannungseinbruch

Gast #5149099
Lesenswert?
• ▲
▼
Hallo,

ich benutze ein STM32F4 und STM32L152 Discovery Board. Ich lasse auf 
beiden nahezu 1:1 die selbe Software laufen.

Ich lasse mit 60kSps einen Sinus ausgeben. Ich messe direkt am Port Pin 
GPIO A:4 mit meinem Oszilloskop. Der STM32F4 hat absolut keine Probleme, 
alles sauber. Beim STM32L152 hingegen bricht die Spannung ab einer 
Frequenz von 500Hz langsam ein, bis ich irgendwann nur noch einn 
winziges Dreieck Signal sehe.

Ich denke nicht, dass es ein prinzipielles Software Problem, eher ein 
Konfigurationsproblem. Oder überlese ich eine Spzifikation bzgl. der 
maximalen Frequenz des DACs? Brauche ich eine Last? Wie kann ich mir das 
erklären? Die Frequenz der DDS stimmt, aber die Spannung bricht immer 
mehr ein.

Danke für Ideen.

Mein Code mit ausgeblendeter Look-Up Table:
1
#include "stm32l1xx.h"
2
#include "timer.h"
3

4
#define SZ 1024
5
#define ML (4294967296 / SZ)
6
#define BS 200
7
#define SPS 60000
8

9
short sample[SZ] ={
10
    [...]
11
};
12

13
unsigned short DMAB0[BS];
14
unsigned short DMAB1[BS];
15
unsigned long long dwFreq = 55;
16

17
struct sTon{
18
  unsigned long wPos;
19
  unsigned long wVol;
20
  unsigned long wStepsize;
21
};
22

23
volatile struct sTon aoToene[10];
24

25
#define CALC(a) (sample[aoToene[(a)].wPos/ML]) * aoToene[(a)].wVol / 0x100
26
void calcbuffer(unsigned short * buffer){
27
  for(int x = 0; x < BS; x++){
28

29
    aoToene[0].wPos += aoToene[0].wStepsize;
30

31
    *buffer++ = CALC(0);
32
  }
33
}
34

35
void DMA1_Channel2_IRQHandler(void){
36
  DMA1->IFCR |= (1<<5);
37
  g_dwTime++;
38
  DMA1_Channel2->CCR &= ~1;
39

40
  if(DMA1_Channel2->CMAR == (unsigned long)&DMAB0[0]){
41
    DMA1_Channel2->CNDTR = BS;
42
    DMA1_Channel2->CMAR = (unsigned long)&DMAB1[0];
43
    DMA1_Channel2->CCR |= 1;
44

45
    calcbuffer(DMAB0);
46
  }else{
47
    DMA1_Channel2->CNDTR = BS;
48
    DMA1_Channel2->CMAR = (unsigned long)&DMAB0[0];
49
    DMA1_Channel2->CCR |= 1;
50

51
    calcbuffer(DMAB1);
52
  }
53
}
54

55

56

57
int main(void)
58
{
59

60
  RCC->CR |= 1;
61
  while(!(RCC->CR & 0b10));
62
  RCC->CFGR |= 0b01;
63
  while(!(RCC->CFGR & 0b0100));
64
  RCC->CFGR |= (0b000 << 11);      //APB2 Prescaler = 0
65
  RCC->CFGR |= (0b000 << 8);      //APB1 Prescaler = 0
66
  RCC->CFGR |= (0b0000 << 4);      //AHB Prescaler = 0
67

68
  RCC->AHBENR |= 1UL;            //GPIOA CLK
69
  RCC->AHBENR |= (1<<25);          //DMA1  CLK
70
  RCC->APB1ENR |= (1<<4);          //TIM6 CLK
71
  RCC->APB1ENR |= (1UL << 29);      //DAC CLK
72

73
  //GPIOA->OSPEEDR |= (0b11 << 2*4);
74
  GPIOA->MODER |= (0b11 << 2*4);      //PA4 analog
75

76
  TIM6->PSC   = 0;
77
  TIM6->ARR   = 16000000 / SPS - 1;
78
  TIM6->CR2 |= (1<<5);
79
  TIM6->CR1  |= 0x01;
80

81
  DAC->CR |= (1<<12);            //DMA enable
82
  DAC->CR |= 0b000100;          //TIM2 trigger
83
  DAC->CR |= 1;              //DAC ON
84

85
  DMA1_Channel2->CCR |= (0b11<<12);    //high priority
86
  DMA1_Channel2->CCR |= (0b01<<10);    //16 Bit peripherie
87
  DMA1_Channel2->CCR |= (0b01<<8);    //16 Bit memory
88
  DMA1_Channel2->CCR |= (1<<7);      //inc memory adress
89
  DMA1_Channel2->CCR |= (1<<4);      //mem to peripherie
90
  DMA1_Channel2->CCR |= (1<<1);      //TCIE enable
91
  DMA1_Channel2->CNDTR = BS;
92
  DMA1_Channel2->CMAR = (unsigned long)&DMAB0[0];
93
  DMA1_Channel2->CPAR = (unsigned long)&DAC->DHR12R1;
94
  DMA1_Channel2->CCR |= 1;
95

96
  NVIC->ICPR[DMA1_Channel2_IRQn/32] |= (1<<DMA1_Channel2_IRQn%32);
97
  NVIC->ISER[DMA1_Channel2_IRQn/32] |= (1<<DMA1_Channel2_IRQn%32);
98

99
  aoToene[0].wStepsize = dwFreq * SZ * ML / SPS;
100
  aoToene[0].wVol = 0xff;
101

102
  while(1){
103
  }
104
}

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.