USART_KESSEL_Transmit(sizeof(kommando));//sollte eigentlich 10 sein, ist aber 8
7
}
8
voidSIMKNX_wert_senden(unsignedintvalue,unsignedintobjectnumber,unsignedintlength)// Wert, SIMKNX Objektnummer, Länge in byte
9
{
10
11
// Wert auf Objekt setzen: ovs(ObjNr) Wert
12
13
if(length==2)
14
{
15
unsignedcharlengthvalue[4];
16
lengthvalue[0]=length+1;
17
lengthvalue[1]=((value/2));//Vorkommastelle
18
lengthvalue[2]=0x2C;//,
19
lengthvalue[3]=(value%2);//Nachkommastelle
20
21
USART_KESSEL_Transmit(sizeof(lengthvalue));//Hier steht noch eine 4
22
SIMKNX_wert_setzen(objectnumber,lengthvalue);
Warum ist in der Funktion SIMKNX_wert_setzen sizeof(value) nur noch 2?
Liegt ja bestimmt an dem Pointer.
Könntet ihr mich mal aufklären?
Falls ihr Vorschläge zur Verbesserung habt bin ich auch offen.
Beschreib mal genauer was du fabrizieren willst.
Das sind mir sehr nach Zeichenketten aus.
Allerdings musst du beim "Anhängen" von Zeichen sicherstellen, das der
Speicherplatz nach dem String noch frei ist, sonst gibt es böse
Laufzeitfehler.
:-)
Ja da werden Zeichenketten gebaut:-)
Also folgendes SIMKNX_wert_senden bastellt den Wert der später gesendet
werden soll, dieser ändert sich natürlich immer mal.
Dieser Wert wird dann mit SIMKNX_wert_setzen(objectnumber, lengthvalue);
in einen Befehl verpackt der dann später gesendet wird.
Hier mal der ganze Code von SIMKNX_wert_setzen:
2 Möglichkeiten:
1. die Länge des Feldes als PArameter mitübergeben
2. die übergebene Zeichenkette mit einem Nullbyte terminieren, um in der
Funktion die Länge ermitteln zu können.
Was davon besser ist, darfst du entscheiden :-)
sizeof wird zu gern verwendet .. ist aber ein präprozessoraufruf ..
nachem kompilieren is das wech ..
bzw stehen da zahlen ..
anhand des pointers bekommst du die länge nicht raus ...
dynamischer speicherbereich ist schön .. auf einem AVR ist so ein
aufwnad meist aber eher negaiv ..
warum nicht e8infach ein festes array ...
die 10 byte für das array auf dem stack machen den kohl nicht fetter
Die Ursache liegt in der Dir fehlenden Differenzierung zwischen Vektor
und Zeiger. Ihr ist in K&R, ein ganzes Kapitel gewidmet, das Du mal
lesen solltest, ebenso wie die Beschreibung von sizeof dort.
In main ist lengthvalue ein Vektor, was als Argument von sizeof eben die
definierte Länge des Vektors ergibt. In der Funktion allerdings hast Du
aus dem Vektor einen Zeiger auf char gemacht, dessen Grösse sizeof
korrekt als Grösse des Zeigers angibt, nicht des Vektors. Die
Information, ob und wieviele chars denn auf den ersten folgen, ist
verlorengegangen.
sizeof, angewendet auf Vektoren, wertet zur Compile-Zeit, nur die
definierten Längen dieser Vektoren aus, also die in der eckigen Klammer
ausdrücklich angegebene Länge.
Es ist, nach oberflächlichem Studium, verführerisch, anzunehmen, das
sizeof ein bequemer Ersatz für strlen ist, mit dem man zur Compile-Zeit
sowohl Vektor- als auch String-Längen ermitteln kann, weil zwischen
diesen kein wesentlicher Unterschied zu bestehen scheint. Dem ist aber
nicht grundsätzlich so.
Das gilt auch, obwohl einige Unterschiede nur deswegen gültig zu sein
scheinen, weil sie definiert worden sind, aber intuitiv kein
funktionaler Grund zur Definition dieses Unterschieds vorzuliegen
scheint.
So könnte man unterstellen, das der Compiler wissen müsste, das ein
Zeiger auf einen Vektor auf einen Speicherbereich mit der Länge des
ursprünglichen Vektors verweist. Aber dann bliebe die Frage, wie man mit
sizeof die Länge eines Zeigers auf einen String ermittelt, bzw. eine
Ungleicheit in der Behandlung von Zeigern auf Vektoren im Gegensatz zu
andere Typen.
So aber, in dem man die einmal festgesetzte Unterscheidung zwischen
Vektor und String-Array auch im Zusammenhang mit sizeof bzw. der
Typumwandlung zwischen beiden, beibehält, bleibt man konsistent.
Es gibt andererseits gewisse syntaktische Übereinstimmungen in der
Benutzung von Vektoren und Zeigern, die einen irreführen können.
Na, das hast Du jetzt ja hinter Dir. ;-)
..ich war mal so frei und hab Dein Programmstück etwas umgebaut - etwas
kürzer und wesentlich leichter lesbar. Und weniger unnötiges rumkopiere
:-) Funktioniert aber nur, wenn Du wirklich ∗Strings∗ verschicken willst
(falls nicht musst Du einen expliziten Längenparameter mitziehen und die
Schleifenbedingung in der while-Schleife adäquat anpassen). Ich hoffe
ich habe die Semantik erhalten..
Der Einfachheit halber hab ich die transmit-Funktionen zu einer
zusammengefasst.
Ich übergeb es jetzt als Parameter ;-)
Darf ich nochmal kurz ne Frage nachschieben ? Lohnt sich nicht dafür nen
extra Thread aufzumachen.
1
voidSIMKNX_wert_senden(unsignedintvalue,unsignedintobjectnumber,unsignedintlength)// Wert, SIMKNX Objektnummer, Länge in byte
2
{
3
4
// Wert auf Objekt setzen: ovs(ObjNr) Wert
5
6
if(length==2)
7
{
8
unsignedcharlengthvalue[4];
9
lengthvalue[0]=length+1;
10
lengthvalue[1]=((value/2));//Vorkommastelle
11
lengthvalue[2]=0x2C;//,
12
lengthvalue[3]=(value%2);//Nachkommastelle
nehmen wir an es wurde für value 155(dez) übergeben.
dann steht in lengthvalue[1] nach der Zuweisung 77, da geh ich mit, ist
richtig.
Aber in lengthvalue[3] steht 1 obwohl eigentlich 5 drinnen stehen
sollte.
Wo liegt der Fehler? an der Deklararion oder ?
Christian Hohmann schrieb:> Aber in lengthvalue[3] steht 1 obwohl eigentlich 5 drinnen stehen> sollte.
Wieso 5?
Irgendwas modulo 2 kann nur 0 oder 1 sein (Rest der
ganzzahligen Division durch 2)
> lengthvalue[3] = (value%2); //Nachkommastelle
[..]
> Aber in lengthvalue[3] steht 1 obwohl eigentlich 5 drinnen stehen> sollte.
Modulo n (n>1) kann nur Werte 0..(n-1) ergeben. Für n=2 liegt 5
definitiv nicht in jenem Bereich :-)
dann hab ich was falsch verstanden, ok was ich da drin stehen haben will
ist 5.
155 / 2 = 77,5 deswegen soll da 5 stehen aber hab wohl wieder was
vermehrt.
Muss nochmal den tread missbrauchen da ich wieder so einen Hänger
drinnen hab. Und weis wiede rnicht warum das nicht so geht wie ich mir
das vorstelle:
Diese If Anweisung wird immer wieder durchlaufen obwohl nach dem 1.
Durchlauf Kesseltemp gleich 155(dez) und nutzdaten[7] auch 155 ist.
Das lass ich mir mit USART_KESSEL über seriell ausgeben. Warum
durchläuft der die if Anweisung obwohl die Bedingung eigentlich nicht
erfüllt sein sollte?