Forum: Mikrocontroller und Digitale Elektronik PIC EEPROM Hilfe C


von andreas (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

Ich habe ein iButton Schloss gebaut, auf Basis des PIC16F628A
Damit können 4 Ausgänge geschalten werden, für jeden dieser Ausgänge 
können 4 Schlüssel gespeichert werden( ein iButton benötigt 8 Byte) der 
PIC hat 128 Byte EEPROM Speicher, somit sind also insgesamt 16 Schlüssel 
möglich.
Angelernt werden die Schlüssel mittels 4 Taster, für jeden Ausgang ein 
Taster, also Taster 1 wird gedrückt, angesteckter Schlüssel gespeichert, 
Ausgang 1 geschaltet, das gleiche für die jeweils anderen 
Taster/Ausgänge.

Funktioniert soweit auch alles einwandfrei, nur das Problem ist wenn die 
ersten 4 Speicherplätze belegt sind und ich versuche einen 5. Schlüssel 
auf dem jeweiligen Ausgang zu speichern springt er automatisch auf den 
Speicherbereich des nächsten Ausgangs, und dementsprechend wird auch der 
nächste Ausgang geschaltet, das soll aber nicht so sein !

Ich möchte, dass wenn die 4 Speicherplätze belegt sind, kein weiterer 
Schlüssel mehr für den jeweiligen Ausgang gespeichert werden kann.
Also wirklich nur fix 4 für jeden Kanal.

Da ich von C Programmierung nicht wirklich viel Ahnung habe, hat 
vielleicht jemand eine Idee wie man den Code entsprechend ändern könnte.
Danke !

Anbei der Code Teil fürs Speichern und suchen im EEPROM.

von Max H. (hartl192)


Lesenswert?

andreas schrieb:
> Funktioniert soweit auch alles einwandfrei, nur das Problem ist wenn die
> ersten 4 Speicherplätze belegt sind und ich versuche einen 5. Schlüssel
> auf dem jeweiligen Ausgang zu speichern springt er automatisch auf den
> Speicherbereich des nächsten Ausgangs
1
  for(bytes = 0; bytes < 8; bytes++)
2
  {
3
    eeprom_write(((keys * 8) + bytes), pData[bytes]);
4
  }
Dieser Teil wird auf jeden Fall ausgeführ, auch wenn oben alle 
Platzebesetzt waren. Ich würde davor noch ein return einbauen wenn alle 
Platze voll sind.



andreas schrieb:
> von C Programmierung nicht wirklich viel Ahnung
Noch ein Tipp:
mMn hast du zu viele Funktionalitäten in diese Funktionen gepackt, 
dadurch wird der Code unübersichtlich. Ich würde für ein paar eigene 
Funktionen schreiben und diese dann von WriteEEPROM aufrufen lassen.
Ich würde z.B. eine Funktion writeKey, readKey, keyEmpty schreiben:
1
writeKey(uint8_t *key, uint8_t key_number)
2
{
3
  uint8_t byte_counter = 0;
4
  key_number *= 8;
5
  for( ; byte_counter < 8; byte_counter++)
6
    eeprom_write(key_number++, *key++);
7
}
1
readKey(uint8_t *key, uint8_t key_number)
2
{
3
  uint8_t byte_counter = 0;
4
  key_number *= 8;
5
  for( ; byte_counter < 8; byte_counter++)
6
    *key++ = eeprom_read(key_number++);
7
}
1
uint8_t keyEmpty(uint8_t *key)
2
{
3
  uint8_t byte_counter = 0;
4
  for( ; byte_counter < 8; byte_counter++)
5
  {
6
    if(*key++ != 0xFF)
7
      return 0;
8
  }   
9
  return 1;
10
}

Danach in der Funktion WriteEEPROM in etwa so verwenden:
1
uint8_t WriteEEPROM(uint8_t *new_key, uint8_t out_number) 
2
{
3
  out_number *= 4;
4
  uint8_t key_counter = 0;
5
  uint8_t read_key[8];
6
  for( ; key_counter < 4; key_counter++)
7
  {
8
    readKey(read_key, out_number)
9
    if(keyEmpty(read_key)
10
    {
11
      writeKey(out_number, new_key);
12
      return 1; // New key saved
13
    }
14
    else
15
      out_number++;
16
  }
17
  return 0; // No free space for the key
18
}


P.S. Wenn du die *.C Endung behältst funktioniert hier das Syntax 
Highlighting.

: Bearbeitet durch User
von andreas (Gast)


Lesenswert?

Hallo Max,
Ja, mein Code ist wirklich überladen, das stimmt schon, bin aber schon 
froh das es überhaupt funktioniert.
Max H. schrieb:
1
  for(bytes = 0; bytes < 8; bytes++)
2
  {
3
    eeprom_write(((keys * 8) + bytes), pData[bytes]);
4
  }
> Dieser Teil wird auf jeden Fall ausgeführ, auch wenn oben alle
> Platzebesetzt waren. Ich würde davor noch ein return einbauen wenn alle
> Platze voll sind.

leider bringe ich das mit dem Return nicht zusammen, dann wird überhaupt 
nichts mehr gespeichert.
1
for(keys; keys < keysl; keys++)
2
  {
3
  for(bytes = 0; bytes < 8; bytes++)
4
    {
5
    if(eeprom_read((keys * 8) + bytes) == 0xFF)
6
      counter++;
7
    }
8
9
  if(counter == 8) break;
10
  else counter = 0;
11
  }

Ich denke hier müsste irgendwo ein Return rein ?

Dein Code Vorschlag sieht auf jeden Fall gut aus, ich weiß im Moment nur 
noch nicht wie ich den einbauen kann.

von Max H. (hartl192)


Lesenswert?

andreas schrieb:
> Ich denke hier müsste irgendwo ein Return rein ?
Versuch mal nach der for(keys; keys < keysl; keys++) schleife ein
1
if(!counter)
2
  return 0;
einzubauen.

Oder du machst die ganze Schleife so:
1
  for(keys; keys < keysl; keys++)
2
  {
3
    for(bytes = 0; bytes < 8; bytes++)
4
    {
5
      if(eeprom_read((keys * 8) + bytes) == 0xFF)
6
        counter++;
7
    }
8
9
    if(counter == 8)  // If a space is free
10
    {
11
      //Write the key to the EEPROM
12
      for(bytes = 0; bytes < 8; bytes++)
13
        eeprom_write(((keys * 8) + bytes), pData[bytes]);
14
      return 1;
15
    }
16
    else 
17
      counter = 0;
18
  }
19
  return 0;
20
}

: Bearbeitet durch User
von andreas (Gast)


Lesenswert?

So:
•
1
for(keys; keys < keysl; keys++)
2
  {
3
if(!counter)
4
  return 0;
dann wird überhaupt nichts mehr gespeichert.

von Max H. (hartl192)


Lesenswert?

andreas schrieb:
> for(keys; keys < keysl; keys++)
>   {
> if(!counter)
>   return 0;
> dann wird überhaupt nichts mehr gespeichert.
Was auch logisch ist und weswegen ich
>> nach der for(keys; keys < keysl; keys++) Schleife
und nicht in der Schleife geschrieben habe.

P.S. Wenn du konsequent gleich einrücken und die geschwungene Klammern 
gleich setzten würdest, würde man Anfang und Ende der Schleifen auch 
leichter erkennen.

: Bearbeitet durch User
von andreas (Gast)


Lesenswert?

Max H. schrieb:
> Oder du machst die ganze Schleife so:
1
  for(keys; keys < keysl; keys++)
2
  {
3
    for(bytes = 0; bytes < 8; bytes++)
4
    {
5
      if(eeprom_read((keys * 8) + bytes) == 0xFF)
6
        counter++;
7
    }
8
9
    if(counter == 8)  // If a space is free
10
    {
11
      //Write the key to the EEPROM
12
      for(bytes = 0; bytes < 8; bytes++)
13
        eeprom_write(((keys * 8) + bytes), pData[bytes]);
14
      return 1;
15
    }
16
    else 
17
      counter = 0;
18
  }
19
  return 0;
20
}

Ja, das funktioniert !!!, Klasse
Vielen Dank !

von andreas (Gast)


Lesenswert?

Max H. schrieb:
> Was auch logisch ist und weswegen ich
>>> nach der for(keys; keys < keysl; keys++) Schleife
> und nicht in der Schleife geschrieben habe.

Ich habe das in unterschiedlichen Versionen auch danach versucht, nur, 
mehr als 1 Key wurde da auch nicht gespeichert.

Ja, ja, die Klammern..., ich weiß.

Ich bedanke mich herzlich für deine Geduld und Hilfe,
Gruß, Andreas.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.