Hallo Leute, kann mal bitte jemand in den Code gucken und mir sagen,
warum die werte in dem Struct nicht aktualisiert werden, bzw. nur
unvollständig ich bekomme es irgendwie einfach nicht zum laufen...
Dankeschön
Antny schrieb:> Hallo Leute, kann mal bitte jemand in den Code gucken und mir sagen,> warum die werte in dem Struct nicht aktualisiert werden,
welche Struct?
> bzw. nur> unvollständig
Welche werden aktualisiert, welche nicht?
> ich bekomme es irgendwie einfach nicht zum laufen...
Das könnte an deiner Codeformatierung liegen.
Viel zu dicht.
Das sieht seltsam aus:
> switch (nextChannel)> {> case TempCh1: read_adc(&(Ch1.Temperatur[2]));> Ch1.Temperatur[2]&=0x0F;> read_adc(&(Ch1.Temperatur[1]));> read_adc(&(Ch1.Temperatur[0]));> nextChannel=ULast1;> break;
beim nächsten Aufruf gehts also weiter mit ULast1
> case CurrCh1: read_adc(&Ch1.Strom[2]);> Ch1.Strom[2]&=0x0F;> read_adc(&Ch1.Strom[1]);> read_adc(&Ch1.Strom[0]);> nextChannel=ULast1;> break;
auch hier gehts beim nächsten mal weiter mit ULast1
> case ULast1: read_adc(&Ch1.Spannung[2]);> Ch1.Spannung[2]&=0x0F;> read_adc(&Ch1.Spannung[2]);> read_adc(&Ch1.Spannung[2]);> nextChannel=TempCh1;> break;
und wieder von vorne, beim nächsten mal mit TempCh1.
Wenn du ausserhalb nie nextChannel auf CurrCh1 setzt, wirst du den Fall
das nextChannel irgendwann CurrCh1 ist, nie haben. Damit sind schon mal
Ch1.Strom[2], [1], [0] ohne Werte. Ich vermute mal im Fall TempCh1
sollte nextChannel eigentlich auf CurrCh1 gesetzt werden und nicht auf
ULast1
Aus Analogiegründen sieht auch das seltsam aus:
> case ULast1: read_adc(&Ch1.Spannung[2]);> Ch1.Spannung[2]&=0x0F;> read_adc(&Ch1.Spannung[2]);> read_adc(&Ch1.Spannung[2]);> nextChannel=TempCh1;> break;
In allen anderen Fällen verteilst du die ADC Ergebnisse jeweils auf [2],
[1], [0]. Nur hier nicht. Hier landen alle 3 Ergebnisse in [2], die
letzte Zuweisung gewinnt.
Hallo danke für die schnelle Antwort, joa das ist "richtig" so weil ich
den Code gerade komplett durchgeplügt habe um das System zu verstehen
was da schief geht, allerdings bisher erfolglos.
Hier nocheinmal der komplette Code, TempCh1 usw. sind defines, später
wenn es irgendwann mal laufen sollte... ist die switch/case- Struktur
dazu gedacht periodisch die Kanäle durchzuscannen und die Structs zu
aktualisieren.
Ich kann mir nicht vorstellen, dass dich hier
uart_sendc(&Ch1.Temperatur[2]);
das Low-Byte der Adresse interessiert, an der Ch1.Temperatur[2]
gespeichert ist.
Hat dein Compiler da gar nichts dazu gesagt, dass die Funktion einen
char haben möchte und du ihm aber einen unsigned char* (mit der Betonung
auf *) anbietest?
>> Was sollen denn dies Initialiser??? Du initialisierst ein uint8-Array> mit char*?
Ist zwar ein wenig seltsam, letzten Endes werden dadurch nur
Temperatur[0], Strom[0] und Spannung[0] mit '\0' initialisiert, die
anderen haben keine definierten Werte.
ist auch nichts anders als
char Dummy[20] = "Hallo World";
Vielleicht hab ich mich verzählt und brauche eine neue Brille, aber ich
sehe da sechs Member in der struct und nur fünf davon werden
initialisiert. Wenn schon denn schon.
@Mark uups richtig, der Ordnung halber...
@Karl- Heinz mensch auf dich ist immer noch Verlass, bei meinen ersten
Gehversuchen mit dem µP hast du mir schon super das mit Bittoggeln mit
Hilfe von und/ oder erklärt, und jetzt wieder den Fehler gefunden
dankeschön :)
Karl heinz Buchegger schrieb:> Ist zwar ein wenig seltsam, letzten Endes werden dadurch nur> Temperatur[0], Strom[0] und Spannung[0] mit '\0' initialisiert, die> anderen haben keine definierten Werte.
Doch, die Variablen haben static storage duration, deshalb werden alle
nicht explizit aufgeführten Elemente implizit mit 0 initialisiert.
Andreas
Andreas Ferber schrieb:> Doch, die Variablen haben static storage duration, deshalb werden alle> nicht explizit aufgeführten Elemente implizit mit 0 initialisiert.
Bzw., um mich selbst zu ergänzen: selbst bei automatic storage duration
werden bei teilweiser Initialisierung (sei es wegen weniger Elementen in
einer Initializer-Liste oder eben auch einem Stringliteral) die
restlichen Elemente implizit mit 0 initialisiert (bzw. NULL-Pointer bei
Pointertypen). Siehe Absatz 21 in Abschnitt 6.7.8 im C99-Standard.
Andreas
Ingrid^2: die Initialisierung des uint8_t-Arrays mit einem Stringliteral
ist allerdings eigentlich nicht zulässig, nur "array of character
type" darf so initialisiert werden, und "character type" sind
ausschliesslich "char", "signed char" und "unsigned char".
Vermutlich wird man aber den Bastard C-Compiler From Hell suchen müssen,
um einen zu finden, bei dem der Unterschied in diesem Fall wirklich
relevant wird.
Andreas
Andreas Ferber schrieb:> ist allerdings eigentlich nicht zulässig, nur "array of character> type" darf so initialisiert werden, und "character type" sind> ausschliesslich "char", "signed char" und "unsigned char".
wird daran liegen das uint8_t eigentlich ein unsigned char ist.
(typedef)
Über den Sinn und Unsinn, einen Zahlenwert mit dem NUL-Symbol zu
initialisieren, kann man sich streiten :-D
Andreas Ferber schrieb:> Doch, die Variablen haben static storage duration, deshalb werden alle> nicht explizit aufgeführten Elemente implizit mit 0 initialisiert.
Ah ja. Du hast natürlich recht.
Darauf hab ich jetzt nicht geachtet.
Ich geh normalerweise nach dem Grundsatz vor:
Wenn ich initialisiere, dann alles.
Das ist mir nämlich zu mühsam, bei einer Strukturänderung im Nachhinein
wieder abzählen zu müssen, was ich initialisiert habe, was der Compiler
für mich macht und was keine Initialisierung bekommt.
Florian Löffler schrieb:> Über den Sinn und Unsinn, einen Zahlenwert mit dem NUL-Symbol zu> initialisieren, kann man sich streiten :-D
Ich denke das Problem wird gewesen sein, dass die korrekte Syntax nicht
bekannt war
1
structKanalMesswerte{
2
uint8_tTemperatur[3];
3
uint8_tStrom[3];
4
uint8_tSpannung[3];
5
uint8_tPWM_Fan;
6
uint16_ttemp_old;
7
int16_tt_delta_sum;
8
}
9
10
Ch1={{0,0,0},
11
{0,0,0},
12
{0,0,0},
13
PWM_Start,
14
0,
15
0
16
},
17
18
Ch2={{0,0,0},
19
{0,0,0},
20
{0,0,0},
21
PWM_Start,
22
0,
23
0
24
};
Das ich von solchen 'all in one line' Rundumschlägen nicht viel halte,
genausowenig von diesem 'möglichst alles in eine Deklaration quetschen
und am besten noch ein typedef davor' Kompaktschreibweisen, sollte
diejenigen die meinen Stil mittlerweile kennen, nicht weiter wundern.
Karl heinz Buchegger schrieb:> Ich geh normalerweise nach dem Grundsatz vor:> Wenn ich initialisiere, dann alles.>> Das ist mir nämlich zu mühsam, bei einer Strukturänderung im Nachhinein> wieder abzählen zu müssen, was ich initialisiert habe,
In aller Regel benutze ich bei struct-Initializern inzwischen
grundsätzlich Designatoren, damit die Initialisierung komplett
unabhängig von der Abfolge der struct-Felder wird. Erspart schonmal ein
paar Fehlerquellen.
> was der Compiler> für mich macht und was keine Initialisierung bekommt.
Wie gesagt, selbst bei automatischen Variablen, sobald auch nur ein
einziges Feld initialisiert wird, wird der gesamte Rest (rekursiv) in
jedem Fall auf 0 initialisiert, exakt wie es bei statischen Objekten der
Fall wäre. Oder anders: ein "teilweise" initialisiertes Aggregate gibt
es in C nur im Zusammenhang mit dynamischer Speicherverwaltung, in allen
anderen Fällen wird entweder ganz oder garnicht initialisiert.
Andreas
Hey, das finde ich gut, dass ihr mir gleich noch gezeigt habt wie es
besser geht, in der Tat ich wußte einfach nicht wie man sie anders
initialisieren kann.