Struct ins EEPROM schreiben

OP #2620278
Lesenswert?

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.
1
volatile uint16_t   adresse = 0x05;
2

3

4
struct {
5
  unsigned V_1:1; // 
6
  unsigned V_2:1; // 
7
  unsigned V_3:1; // 
8
  unsigned P_1:1; // 
9
  unsigned P_2:1; // 
10
  unsigned P_3:1; // 
11
  unsigned P_4:1; // 
12
  unsigned P_5:1; //
13
  unsigned M_1:1; 
14
  unsigned M_2:1;
15
  unsigned M_3:1;
16
  unsigned KW:1;
17
  unsigned KF:1;
18
  unsigned Temp_Diff:1;     
19
} state;

Und im Programm kommt dann der Aufruf:
1
cli();
2
eeprom_write_block(state, adresse, sizeof(state));
3
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
#2621212
Lesenswert?

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
1
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.
OP #2621419
Lesenswert?

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?

1
state.V_2 = 0;
2
PORT_OUT |= (1<<V2);
3

4

5
if ( ( (state.V_2) != (PORT_OUT & (1<<V2) ) ) )
6
{
7
  bStatus_geandert = TRUE;
8
        state.V_2 = 1;
9
}
10

11
if ( ( (state.V_2) != (PORT_OUT & (1<<V2) ) ) )
12
{
13
  bStatus_geandert = TRUE;
14
  state.V_2 = 1;
15
}
#2621495
Lesenswert?

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.
#2621881
Lesenswert?

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
1
uint8_t EqualBitValues( uint8_t Bit1, uint8_t Bit2 )
2
{
3
  return ( Bit1 && Bit2 ) || ( !Bit1 && !Bit2 );
4
}
5

6
  ....
7
  if( EqualBitValues( state.V_2, PORT_OUT & (1<<V2) ) )
8
    ....

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.
Gast #2621932
Lesenswert?

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!)
1
#include <stdio.h>
2

3
#define XOR(x,y) ((!(x) && (y) ) || ((x) && !(y)))
4
#define XNOR(x,y) (!XOR(x,y))
5

6
int main(void)
7
{
8
  int x,y;
9
  printf("x     y     XOR     XNOR\n");
10
  printf("========================\n");
11
  for (x=0; x<2; x++)
12
    for (y=0; y<2; y++)
13
      printf("%d     %d     %d       %d\n", x,y,XOR(x,y),XNOR(x,y));
14
}

Ausgabe (http://de.wikipedia.org/wiki/Wahrheitstabelle)
1
x     y     XOR     XNOR
2
========================
3
0     0     0       1
4
0     1     1       0
5
1     0     1       0
6
1     1     0       1
Gast #2622055
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren