PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Hilfestellung für DAC-Initialisierung beim STM32F4 gesucht



erik_wolfram
22.02.2016, 13:18
Hallo,

ich beschäftige mich seid einigen Monaten mit einem STM32F407VGT Discovery-Board. Nach vielem Programmieren stolpere ich doch öfters über Probleme mit dem DAC. Teilweise bekomme ich diesen nicht initialisiert, bzw. ist dieser diesbezüglich ziehmlich störrisch.

Als neustes habe ich ein Problem das mir zu rästeln aufgibt. Initialisiere ich den PIN für den DAC innerhalb der Main läuft alles. Packe ich die Initialisierung des PINs mit in die Initialisierungsfunktion des DACs läuft dieser nicht mehr. Ich konnte das Problem mittlerweile auf die Initialisierung des PINs begrenzen, komme damit aber nicht weiter. Auch wenn ich die Initialisierung anderer PINs mit der gleichen Initialisierungs-Struktur mit in die Funktion packe läuft es nicht.

Ich bin ganzschön ratlos. Da mein Programm immer mächtiger wird möchte ich die Main der Übersicht halber gerne vereinfachen um noch durchsehen zu können.

Die Ausgabe des DACs soll über den Channel2 am Pin PA5 erfolgen - und das funktioniert ja mit der jetzigen initialisierung...

Hier mal der Code:

main:


...
GPIO_InitTypeDef GPIO_InitStructure;
...
// Der Code darf nicht in die Funktion init_DAC ????
RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA, ENABLE );

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_Init( GPIOA, &GPIO_InitStructure );

// Hier die eigentliche Initialisierung:
init_DAC();
...


init_DAC():


void init_DAC()
{
// Enable DAC clock
RCC_APB1PeriphClockCmd( RCC_APB1ENR_DACEN, ENABLE );

DAC_InitTypeDef DAC_InitStruct;

DAC_InitStruct.DAC_Trigger = DAC_Trigger_None;
DAC_InitStruct.DAC_WaveGeneration = DAC_WaveGeneration_None;
DAC_InitStruct.DAC_OutputBuffer = DAC_OutputBuffer_Enable;

DAC_Init( DAC_Channel_2, &DAC_InitStruct );

// Enable DAC Channel 1
DAC_Cmd( DAC_Channel_2, ENABLE );
}


Arbeiten tue ich mich CooCox IDE ohne Optimierung.

Ich denke/hoffe es handelt sich hier nur um eine Kleinigkeit, die ich einfach übersehen.
Ich bin für jede Hilfestellung dankbar!

Gruß Erik

Peter(TOO)
23.02.2016, 21:39
Hallo Erik,

Ich sehe da:
RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA, ENABLE );
RCC_APB1PeriphClockCmd( RCC_APB1ENR_DACEN, ENABLE );

MfG Peter(TOO)

erik_wolfram
29.02.2016, 13:37
Hallo,
leider habe schaffe ich es jetzt erst zu schreiben. Aber großes Danke für die schnelle Antwort.
Falls du den Unterschied meinst - der ist mir auch aufgefallen - das muss aber wohl so.

Ich habe jetzt nochmal alles sehr gründlich durchgelesen um die Initialisierungreihenfolge einzuhalten.

Kurioser Weise funktioniert es wenn ich die DAC-Initialisierung universeller abfrage:


void initDAC( uint32_t DAC_Channel )
{
RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA, ENABLE );

GPIO_InitTypeDef GPIO_InitStructure;

if( DAC_Channel == DAC_Channel_1 )
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
else
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_Init( GPIOA, &GPIO_InitStructure );

// Enable DAC clock
RCC_APB1PeriphClockCmd( RCC_APB1ENR_DACEN, ENABLE );

DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;

DAC_DeInit();
DAC_Init( DAC_Channel, &DAC_InitStructure );

// Enable DAC Channel
DAC_Cmd( DAC_Channel, ENABLE );
}

Damit kann ich zunächst erstmal leben.

Allerdings finde ich die Dokumentation ganzschön mangelhaft.
Im späteren Programm wechsle ich zwischen manueller DAC-Ausgabe mittels DAC_SetChannel2Data und der DAC Ausgabe mittels DMA.
Leider kann man hier nicht einfach so wechseln, sondern muss den DAC neu initialisieren. Da ich das für meinen Zweck eigentlich nich machen darf ist das unschön!
(Die DAC-Ausgabe muss/sollte flüssig und lückenlos erfolgen)

Es steht auch nirgends wie man den DAC mit DMA richtig initialisiert. Wenn ein Timer zum triggern genutzt wird bleibt der Ausgangswert des DACs Null nach dem Aktivieren bis der Timer das erste mal überläuft.

Gruß Erik

Anbei: Auf dem STM32F4 Discovery stört die blöde LED für die Verbindung zum Computer erheblich den DAC!

Peter(TOO)
29.02.2016, 15:09
Hallo Erik,

Allerdings finde ich die Dokumentation ganzschön mangelhaft.
Im späteren Programm wechsle ich zwischen manueller DAC-Ausgabe mittels DAC_SetChannel2Data und der DAC Ausgabe mittels DMA.
Leider kann man hier nicht einfach so wechseln, sondern muss den DAC neu initialisieren. Da ich das für meinen Zweck eigentlich nich machen darf ist das unschön!
(Die DAC-Ausgabe muss/sollte flüssig und lückenlos erfolgen)

Es steht auch nirgends wie man den DAC mit DMA richtig initialisiert. Wenn ein Timer zum triggern genutzt wird bleibt der Ausgangswert des DACs Null nach dem Aktivieren bis der Timer das erste mal überläuft.

Das ist halt das Problem, wenn man mit fertigen Bibliotheken arbeitet.

Ein weiteres Problem ist, dass man die Bibliotheken nicht entsprechend allgemein halten kann, sodass sie jeden Anwendungsfall abdecken.
Wenn man versucht jeden Fall abzudecken, wird die Bibliothek zu gross und zu langsam. :-(

Als ich angefangen hatte, gab es kaum Bibliotheken und man musste sowieso alles selber schreiben, Jetzt kann ich es und benutze kaum Bibliotheken.

Ich sehe da kein grossen Probleme mit dem Umschalten des DACs, aber du wirst es wohl selber programmieren müssen um nur diejenigen Register-Bits umzustellen, welche nötig sind.
Wenn man das selber macht, kann man den Timer auch initialisieren und zwar auf Max-1. Dann hast du beim nächsten Takt einen Überlauf des Timers. Bibliotheken stellen den immer auf 0, damit der erste Überlauf erst nach der gewünschten Zeit kommt.

MfG Peter(TOO)

erik_wolfram
29.02.2016, 18:11
Danke für den Hinweis mit dem Timer "MAX-1".
Ich nutzt meistens auch nur die Bibleotheken, um mir die Grundstruktur anzugucken. Viele Funktionen kopiere ich mir dann und passe sie meinen Wünschen an.
Da gabs schon einige böse Fallen bei den vorgefertigten...