Datum:
Guten Tag zusammen, ich habe ein Problem mit dem Verständnis der Funktion "eeprom_write_block" Folgendes - ich möchte eine Struktur welche 14bit groß ist (2 Byte) ins EEPROM schreiben in dieser Struktur stehen Zustandsmeldungen. Einzelne Bytes ins EEPROM schreiben hat bei mir funktioniert, aber ich glaube ich habe den Syntax noch nicht ganz verstanden um einen ganzen Block (struct) zu schreiben: So sieht mein struct aus.
volatile uint16_t adresse = 0x05; struct { unsigned V_1:1; // unsigned V_2:1; // unsigned V_3:1; // unsigned P_1:1; // unsigned P_2:1; // unsigned P_3:1; // unsigned P_4:1; // unsigned P_5:1; // unsigned M_1:1; unsigned M_2:1; unsigned M_3:1; unsigned KW:1; unsigned KF:1; unsigned Temp_Diff:1; } state; |
Und im Programm kommt dann der Aufruf:
cli();
eeprom_write_block(state, adresse, sizeof(state));
sei();
|
Dort bekomme ich dann eine Fehler meldung und eine Warnung: Error 1 incompatible type for argument 1 of 'eeprom_write_block' Warning 2 passing argument 2 of 'eeprom_write_block' makes pointer from integer without a cast Im Tutorial für den die Fuktion sieht es auch so aus als wenn nur ein Array ins EEPROM geschrieben wird. Kann mich da vieleicht jemand mal aufklären? Das wäre super. Vielen Dank
Datum:
cli(); eeprom_write_block(&state, adresse, sizeof(state)); sei(); ^^
Datum:
Was Du falsch gemacht hast, sagen Dir die Fehlermeldungen? Und wenn "state" eine Variable ist, müsstest Du doch zumindest diese als "&state" übergeben.
Datum:
ich glaube nicht, dass man hier die Interrupts verbieten muss. Hat das bei dir einen bestimmten Grund? Adib.
Datum:
Sebastian B. schrieb: > volatile uint16_t adresse = 0x05; > Und im Programm kommt dann der Aufruf:cli(); > eeprom_write_block(state, adresse, sizeof(state)); > sei(); > Dort bekomme ich dann eine Fehler meldung und eine Warnung: > Error 1 incompatible type for argument 1 of 'eeprom_write_block' Das wurde ja schon genannt. > Warning 2 passing argument 2 of 'eeprom_write_block' makes pointer > from integer without a cast Steht doch dran, was das Problem ist. eeprom_write_block() erwartet einen Zeiger, aber du übergibst
volatile uint16_t adresse = 0x05; |
einen Integer. Übrigens: Warum ist der denn volatile? Änderst du die Adresse in einer ISR? Das würde dann auch das cli()/sei() erklären.
Datum:
Sebastian B. schrieb: > So sieht mein struct aus. > volatile uint16_t adresse = 0x05; Sebastian B. schrieb: > cli(); > eeprom_write_block(state, adresse, sizeof(state)); > sei(); warum sich alle bei eeprom immer so auf den Kopf stellen müssen und alles künstlich verkomplizieren?! https://www.mikrocontroller.net/articles/AVR-GCC-T...
Datum:
Das mit der Struktur und dem EEPROM hat soweit funktioniert nur habe ich nun irgendwie probleme mit der Struktur. Muss man die irgendwie anders handeln als normale variablen ? Ich setzte am Anfang einfach zum test in meiner Struktur "state" den eintrag V_2 auf "0" und ich sezte den Ausgang für V2 auf High. so nun teste ich ja mit != auf ungleichheit der beiden. und stelle fest das die beiden ungleich sind. in der simulation wird dann state.V_2 auf 1 gesetzt in der ersten if abfrage. Nun sollten ja in der zweiten Abfrage beide 1 sein und die abfrage sollte übersprungen werden... Dies ist aber nicht der Fall. Muss man die Struktur variablen irgendwie anders behandeln?
state.V_2 = 0; PORT_OUT |= (1<<V2); if ( ( (state.V_2) != (PORT_OUT & (1<<V2) ) ) ) { bStatus_geandert = TRUE; state.V_2 = 1; } if ( ( (state.V_2) != (PORT_OUT & (1<<V2) ) ) ) { bStatus_geandert = TRUE; state.V_2 = 1; } |
Datum:
so und wenn ich state und V2 auf 1 setzte und mit == abfrage wird das if
auch übersprungen. nun bin ich ratlos?!
was mache ich falsch ?
state.V_2 = 1;
PORT_OUT |= (1<<V2);
if ( ( (state.V_2) == (PORT_OUT & (1<<V2) ) ) )
{
bStatus_geandert = TRUE;
}
Datum:
Sebastian B. schrieb: > Dies ist aber nicht der Fall. Muss man die Struktur variablen irgendwie > anders behandeln? Nein. Aber du solltest dir mal überlegen, was du bei deinem != tatsächlich vergleichst. Links Seite - Rechte Seite. Welche Werte entstehen da jeweils. Hinweis: Das Ergebnis von (PORT_OUT & (1<<V2) ) ist NICHT 0 oder 1, sondern 0 oder (1<<V2). Dein Bit in der Struktur ist aber definitiv entweder 0 oder 1. Wenn beide 0 sind, passt das alles. Aber der '1' Fall ist nicht in Ordnung. Denn wenn V2 bspweise der Pin 3 ist, dann bedeutet der Ausdruck (PORT_OUT & (1<<V2) ), dass da bei der Abfrage numerisch 8 rauskommt. Und 1 ist nun mal nicht gleich 8.
Datum:
mhm Wie heisst denn dann mein Zauberzeichen damit ich auf ungleichnis prüfen kann ?ich müsste mein PORT 1<<V2 nur irgendwie auf TRUE bzw FALSE umwandeln müssen. Dat ist doch bestimmt auch irgendwas ganz simples Finde da gerade nur nichts in meinem Buch
Datum:
Sebastian B. schrieb: > Dat ist doch bestimmt auch irgendwas ganz simples Du kannst natürlich auch das Ergebnis von PORT_OUT & (1<<V2) auf explizit 0 oder 1 forcieren. !!( PORT_OUT & (1<<V2) ) toll ist es aber nicht. Du kannst auch den linken Teilausdruck so zurechtschieben, dass das 1 Bit an der Stelle V2 zu liegen kommt und so praktisch den linken Teilausdruck an den Wertebereich des rechten anpassen if ( ( (state.V_2<<V2) != (PORT_OUT & (1<<V2) ) ) ) finde ich immer noch nicht wirklich prickelnd. An dieser Stelle würde ich vorschlagen, tatsächlich explizit zu sein. Was willst du denn wissen? Du willst wissen ob entweder beide 0 sind oder beide ungleich 0 sind und genau so würde ich das auch schreiben. if ( ( state.V_2 && PORT_OUT & (1<<V2) ) || // beide ungleich 0? ( !state.V_2 && !( PORT_OUT & (1<<V2) ) ) ) // beide gleich 0? wenn dir das zu geschwätzig ist, dann mach dir eine Funktion dafür
uint8_t EqualBitValues( uint8_t Bit1, uint8_t Bit2 )
{
return ( Bit1 && Bit2 ) || ( !Bit1 && !Bit2 );
}
....
if( EqualBitValues( state.V_2, PORT_OUT & (1<<V2) ) )
....
|
Das hat dann auch den Vorteil, dass es die doppelte Auswertung des Ports vermeidet. Manchmal muss man eben seine 'Werkzeuge' selber bauen, wenn einem die Sprache nicht das gibt, was man braucht.
Datum:
Der einfache Ersatz des != in dem Beispiel > if ( ( (state.V_2) != (PORT_OUT & (1<<V2) ) ) ) ist das logische XOR ( http://de.wikipedia.org/wiki/XOR-Verkn%C3%BCpfung). Bzw. das logische XNOR (log. XOR gefolgt von log. NOT) in diesem Ausdruck > if ( ( (state.V_2) == (PORT_OUT & (1<<V2) ) ) ) Mögliche Umsetzung (nicht optimal und fehlerträchtig, weil x und y mehrfach ausgewertet werden!)
#include <stdio.h> #define XOR(x,y) ((!(x) && (y) ) || ((x) && !(y))) #define XNOR(x,y) (!XOR(x,y)) int main(void) { int x,y; printf("x y XOR XNOR\n"); printf("========================\n"); for (x=0; x<2; x++) for (y=0; y<2; y++) printf("%d %d %d %d\n", x,y,XOR(x,y),XNOR(x,y)); } |
Ausgabe (http://de.wikipedia.org/wiki/Wahrheitstabelle)
x y XOR XNOR ======================== 0 0 0 1 0 1 1 0 1 0 1 0 1 1 0 1 |
Datum:
Krapao schrieb: > Der einfache Ersatz des != in dem Beispiel >> if ( ( (state.V_2) != (PORT_OUT & (1<<V2) ) ) ) > ist das logische XOR Man fragt sich nur warum C das nicht hat. Alle üblichen booleschen Verküpfungen gibt es sowohl bitweise als auch als boolesche Variante. Nur das xor gibt es ausschließlich bitweise.