Hallo an Alle,
mein Projekt läuft auf einem Nucleo Board mit STM32 L476. Ich nutze ein
SD-Karten-Breakout mit SPI-Kommunikation und die
FatFS-SD-Implementierung von Eziya
(https://github.com/eziya/STM32_SPI_SDCARD).
Zum Umriss was ich versuche:
ADC-Messung soll laufen, über die HAL_ADC_ConvCpltCallback sollen 2
Buffer abwechselnd auf eine SD-Karte geschrieben werden
(Ping-Pong-Style). Die Messung läuft also und wird zeitgleich
gespeichert bis man sie per Tastendruck beendet.
Mein Ursprungsdesign zum Test basierte darauf, dass nur ein Buffer
vollgeschrieben und dieser dann an eine extra Funktion weitergegeben
wird, welche die SD-Karte mountet, eine neue Datei erstellt, diese mit
dem Array beschreibt und dann die Datei schließt. Dies funktioniert auch
problemlos, weswegen ich Hardwarefehler und allgemeine Probleme mit der
Library ausschließe.
Meine neue PingPong-Implementierung soll nun zuerst eine gesonderte
Funktion "initSD" aufrufen, welche die ersten Schritte der alten
Funktion übernimmt (f_mount(), f_open()) und dann die durch f_open()
erstellte Datei zurückgibt. In der Callback-Funktion des ADC soll nun
dieses File genommen und mittels f_puts() beschrieben werden.
Allerdings wird f_puts() nicht korrekt ausgeführt und die Funktion
landet in einer Endlosschleife, ein verwertbares fresult wird nicht
zurückgegeben. Googlen zu diesem Problem hat mir bis jetzt nichts
gebracht. In der init-Funktion() wird überall FR_OK zurückgegeben, das
scheint zu funktionieren. Auch das durch die Funktion rückgegebene
file-Struct existiert in der Callback und sieht eigentlich gut aus
(Breakpoint und Expression Viewer).
Lange Rede, kurzer Sinn. Hier meine Codebeispiele.
*Initfunktion in sd-card.c:*
1 | //Structs
|
2 | FATFS fs; // file system
|
3 | FIL fil; // File
|
4 | FRESULT fresult; // result
|
5 |
|
6 | //Initfunktion
|
7 | FIL initSD()
|
8 | {
|
9 | //SD-Card - Mount
|
10 | fresult = f_mount(&fs, "/", 1);
|
11 |
|
12 | /*
|
13 | Hier würde vermutlich irrelevanter Code stehen, welcher die SD-Karte liest und einen neuen,ungenutzten Dateinamen findet.
|
14 | Ausgabe ist das char[]-Array measurement_name (funktioniert).
|
15 | */
|
16 |
|
17 | //Öffnen der Datei
|
18 | fresult = f_open(&fil,measurement_name , FA_OPEN_ALWAYS | FA_READ | FA_WRITE);
|
19 |
|
20 | //Return der Datei
|
21 | return fil;
|
22 | }
|
*Precode beim Start der Messung in main.c:*
1 | FATFS fs; // file system
|
2 | FIL fil; // File
|
3 | FRESULT fresult; // result
|
4 |
|
5 | uint32_t k = 0; //Zählvariable für Buffer-Switching
|
6 |
|
7 | //Initialisierung der SD Karte - Erstellung der Datei
|
8 | fil = initSD();
|
9 |
|
10 | //Initialisierung ADC
|
11 | HAL_ADC_Start_DMA(&hadc2, (uint32_t*)&adc_buff1, adc_buff_size);
|
12 |
|
13 | //Initialisierung Timer
|
14 | HAL_TIM_OC_Start(&htim4, TIM_CHANNEL_4);
|
*ADC-Callback etwas später im Code der main.c:*
1 | void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
|
2 | {
|
3 | if(k % 2 == 0)
|
4 | {
|
5 | //ADC-Buffer-Switching (Ping-Pong)
|
6 | /*
|
7 | Es gibt 2 gleich lange Buffer adc_buff1 und adc_buff2, welche abwechselnd gefüllt oder auf die SD-Karte geschrieben werden sollen.
|
8 | */
|
9 | HAL_ADC_Stop_DMA(&hadc2);
|
10 | HAL_ADC_Start_DMA(&hadc2,(uint32_t* ) adc_buff2 ,adc_buff_size);
|
11 |
|
12 | //Char Array measurement data
|
13 | char measurement_value[4];
|
14 |
|
15 | //SD-Card - Write measurement data
|
16 | for(int i = 0; i <= ((adc_buff_size)-1) ; i++)
|
17 | {
|
18 | //Converting measurement to char - 1
|
19 | sprintf(measurement_value, "%d", adc_buff1[i]);
|
20 |
|
21 | //Writing measurement data (HIER IST DAS PROBLEM - Infinite Loop)
|
22 | f_puts(measurement_value, &fil);
|
23 |
|
24 | //Writing new column (Diese geht auch nicht, es liegt also nicht an "measurement_value")
|
25 | f_puts(";\n", &fil);
|
26 | }
|
27 |
|
28 | else
|
29 | {
|
30 | //Gleicher Code für adc_buff2
|
31 | }
|
32 | k++;
|
33 | }
|
Ich vermute ja es geht etwas bei der Weitergabe des Datei-Structs "fil"
schief, habe auch schon versucht diese in der main.c als externe
Variable zu definieren, jedoch mit selben Ergebnis.
Ich weiß nicht, ob man mir auf dieser Art und Weise groß helfen kann,
aber vielleicht habe ich irgendetwas ganz offensichtliches übersehen
(bin auf dem Gebiet gewiss kein Experte).
Vielleicht hatte auch jemand schon eine ähnliche Problemstellung mit der
permanenten ADC-Wert-Speicherung und hat einen alternativen, besseren
Vorschlag.
Ich bin euch für jeden Ratschlag/Hilfe dankbar, weil ich nun schon seit
Tagen daran sitze.
Mit freundlichen Grüßen
Basti