Hallo,
ich versuche gerade 2 Bytes die ich über I2C gesendet bekomme zusammen
zusetzen und zwar in der Rheinfolge erst High Byte dann Low Byte.
ist das logisch korrekt ?
new schrieb:> ist das logisch korrekt ?
ja aber recht umständlich. üblich schreibt man einfach
Akkuspannung = (Akkuspannung_Wert2_high_byte << 8) |
Akkuspannung_Wert1_low_byte;
zum einen ist das ja nicht BASCOM, wo man jede kompliziertere Berechnung
in mehrere Teile aufteilen muss, zum anderen ist der COmpiler schon so
intelligent, dass er weiß, das eine Multiplikation mit 256 ganz einfach
durch Verschieben bzw. entsprechende Bytezuweisungen erfolgen kann. Es
gibt da keinen Grund, schlauer als der Compiler sein zu wollen - man
benutzt einfach die Schreibweise, die die Absicht am besten ausdrückt
und der Compiler kümmert sich darum, wie das effizient zu implementieren
ist.
Karl Heinz Buchegger schrieb:> zum anderen ist der COmpiler schon so intelligent, dass er weiß, das eine> Multiplikation mit 256 ganz einfach durch Verschieben bzw. entsprechende> Bytezuweisungen erfolgen kann.
Man muß aber auch nicht unbedingt überall eine Multiplikation
hinschreiben, nur um dem Compiler die Gelegenheit zu geben, besonders
schlau zu sein.
> Es gibt da keinen Grund, schlauer als der Compiler sein zu wollen - man> benutzt einfach die Schreibweise, die die Absicht am besten ausdrückt> und der Compiler kümmert sich darum, wie das effizient zu implementieren> ist.
Ich finde aber, daß gerade dort der Bit-Schiebe-Operator besser
ausdrückt, was man machen will. Es geht ja hier gerade nicht darum, eine
Zahl mit 256 zu multiplizieren, sondern darum, das erste Byte in die
oberen 8 Bit rüberzuschieben.
Rolf Magnus schrieb:> Ich finde aber, daß gerade dort der Bit-Schiebe-Operator besser> ausdrückt, was man machen will. Es geht ja hier gerade nicht darum, eine> Zahl mit 256 zu multiplizieren, sondern darum, das erste Byte in die> oberen 8 Bit rüberzuschieben.
Ja, du hast natürlich recht. An dieser Stelle wäre Schieben für mich
auch 'natürlicher'.
Mir ging es eher darum, dass das Original vom TO
in Bezug auf dieses Thema deshalb nicht falsch ist. Wenn für ihn die
Multiplikation natürlicher ist, dann ist das ok und keineswegs ein Grund
die Hände über dem Kopf zusammenzuschlagen und 'Ineffizenz!' zu rufen.
Hätte das vielleicht besser ausdrücken sollen.
Ich würde ja auch die ganze Operation sowieso erst mal in eine Funktion
kapseln, deren Aufgabe es ist einen 16 Bit Wert auszulesen und die dann
benutzen. Aber das ist eine andere Geschichte. Genauso wie da natürlich
in der while Schleife ein logischer Fehler steckt (denn wie soll sich
denn der Wert in der Schleife verändern. ISR wäre noch möglich, aber
dann müsste man unter Interruptsperre die Variable auslesen).
Karl Heinz Buchegger schrieb:>> Ich würde ja auch die ganze Operation sowieso erst mal in eine Funktion> kapseln, deren Aufgabe es ist einen 16 Bit Wert auszulesen und die dann> benutzen. Aber das ist eine andere Geschichte. Genauso wie da natürlich> in der while Schleife ein logischer Fehler steckt (denn wie soll sich> denn der Wert in der Schleife verändern. ISR wäre noch möglich, aber> dann müsste man unter Interruptsperre die Variable auslesen).
was meinst du mit in der Schleife ist ein logischer Fehler kannst du das
bitte erörtern?
new schrieb:> was meinst du mit in der Schleife ist ein logischer Fehler kannst du das> bitte erörtern?
Hat er doch:
new schrieb:> wie soll sich denn der Wert in der Schleife verändern. ISR wäre noch> möglich, aber dann müsste man unter Interruptsperre die Variable auslesen
Du fragst in der Schleife bei jedem Durchlauf die Variable
"Akkuspannung" ab. Da du sie aber innerhalb der Schleife nie
beschreibst, wird sich ihr Wert auch nie mehr ändern.
Rolf Magnus schrieb:> new schrieb:>> wie soll sich denn der Wert in der Schleife verändern. ISR wäre noch>> möglich, aber dann müsste man unter Interruptsperre die Variable auslesen
Ups. Das war natürlich nicht "new", der das geschrieben hat, sondern
Karl Heinz.
new schrieb:> also muss ich dann folgendes machen?>
Oh. Mann.
Warum lernst du nicht einfach mal ein bischen Grundlagen in C.
Das hat doch keinen Sinn, jedes Codestück im Editor auf Biegen und
Brehcen zu duplizieren
1
uint16_tValueFrom(uint8_tAddress)
2
{
3
uint16_tvalue;
4
uint8_tlowByte,HighByte;
5
6
smb_start_wait(AdresseSlave_1+SMB_WRITE);
7
smb_write(Address);
8
smb_rep_start(AdresseSlave_1+SMB_READ);
9
10
lowByte=smb_readAck();
11
highByte=smb_readNak();
12
smb_stop();
13
14
value=(highByte<<8)|lowByte;
15
16
returnvalue;
17
}
damit hast du erst mal eine Funktion, die dir den ganzen Teil 'Hole
einen 16 Bit Wert aus einem bestimmten Register abnimmt, so dass du das
nicht jedesmal immer wieder neu ausformulieren brauchst.
Und damit schreibt sich dann der Rest unter Verwendung dieser Funktion
als
siehst du, um wieviel einfacher und verständlicher der ganze Code durch
die Funktion plötzlich geworden ist?
Und wenn man dann auch noch die 'magische Konstante' 0x5A mittels
#define mit einem sprechenden Namen ersetzt
dann wird das ganze schon immer mehr zu einem fast natürlichsprachigen
Text, bei dem ein paar Zwischenwörter fehlen.
Lern ordentlich programmieren. Es lohnt sich auf lange Sicht!
Oder bist du bereits mit dem Auto rumgefahren, als du ausser dem
Blinkerhebel noch keine anderen Kontrollen in deinem Auto gekannt hast?
Nicht? Na also!
Vielen Dank das ist sehr schön erklärt, bis auf die spöttischen
Bemerkungen ;-).
Macht natürlich mehr Sinn mit eine Funktion zu arbeiten mit
Rückgabewert.
Allerdings bekomme ich einen Konflikt beim compilieren:
"conflictings types for ValueForm"
Karl Heinz Buchegger schrieb:> uint16_t ValueFrom( uint8_t Address )> {> uint16_t value;> uint8_t lowByte, HighByte;>> smb_start_wait(AdresseSlave_1+SMB_WRITE);> smb_write (Address);> smb_rep_start(AdresseSlave_1+SMB_READ);>> lowByte = smb_readAck();> highByte = smb_readNak();> smb_stop();>> value = ( highByte << 8 ) | lowByte;>> return value;> }
Wieso steht bei smb_write (Adresse)? Wo ist denn Adresse als 0x5A
definiert oder wird es hier
Akkuspannung = ValueFrom( 0x5A );
while(Akkuspannung >= 8320)
{
//__enable_interrupt();
PORTB &= ~ ( 1 << PB1 | 1 << PB2 );
__disable_interrupt();
PORTB |= (1 << PB2);
//PORTC &= ~ (1 << PC0 | 1 << PC4 | 1 << PC1 | 1 << PC5 | 1 <<
PC3 | 1 << PC2);
Akkuspannung = ValueFrom( 0x5A );
}
übergeben?
new schrieb:> Vielen Dank das ist sehr schön erklärt, bis auf die spöttischen> Bemerkungen ;-).
Die sind in all den Jahren entstanden, in denen ich gemerkt habe, dass
immer mehr Leute immer weniger Basiswissen haben und trotzdem meinen,
ein Projekt stemmen zu können. Wenn ich keine Ahnung von klempnern habe,
wie kommt man dann auf die Idee, man könne in seinem Haus die Heizung in
Eigenregie aufbauen?
Eben. Bei solchen Dingen sieht das jeder ein. Nur seltsamerweise beim
Programmieren nicht. Da glaubt jeder, das geht so in ein paar Stunden. 3
Schlüsselwörter genügen und dann passt das schon.
> Allerdings bekomme ich einen Konflikt beim compilieren:> "conflictings types for ValueForm"
Da ich den Rest deines Programms nicht kenne, bzw. wie du die Codestücke
eingebaut hast, kann ich dazu nicht viel sagen. Aber ich schätze mal,
dass du die Funktion unterhalb von main() angeordnet hast und keinen
Protoyp für die Funktion gemacht hast.
> Wieso steht bei smb_write (Adresse)? Wo ist denn Adresse als 0x5A> definiert oder wird es hier
Siehst du. Genau das meine ich mit fehlendem Basiswissen.
Schau in deinem bevorzugtem C-Lehrbuch unter "Funktionen" bzw.
"Funktionsargumente" nach. Das entsprechende Kapitel sollte sich
irgendwo im ersten Drittel des Buches finden lassen.