mikrocontroller.net

Forum: Compiler & IDEs Zustand vom Port speichern beim Attiny2313


Autor: Feissy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin, kann ich beim Attiny2313 den Zustand von PORTB im eeprom 
speichern, damit wenn ich ihn aus- und wiedereinschalte, der Zustand an 
den Pins gleichbleibt. Ich hab einfach Taster an PORTD hängen, die ich 
per Software entprellt habe und dann auf PORTB ausgegeben werden.
Ich möchte aber gerne den Zustand gespeichert haben, wenn ich den Strom 
abschalte.
Ist das so ohne Weiteres möglich?
Gruß stefan

Autor: Michael Sch. (schmichael)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja!

Michael

Autor: Daniel B. (inox5) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#include <stdint.h>          //Variablen
#include <avr/eeprom.h>        //EEPROM

//Speichervariable
uint8_t foo EEMEM = 0;

int main (void)
{
PORTB=0b11110000;

...

eeprom_write_byte(&foo, PORTB);  //schreibt PORTB in den EEPROM

...

PORTB = eeprom_read_byte(&foo);  //liest den Wert aus dem EEPROM
}

MfG
Inox

Autor: avr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Feissy, @Daniel

Das geht eine gewisse Zeit gut, aber dann ????
 128 Bytes In-System Programmable EEPROM
  Endurance: 100,000 Write/Erase Cycles

Besser: VCC mit Diode Entkoppeln und mit "großem" Elko
buffern, Spannung vor Diode abfragen und bei Spannung aus
Zustand speicher (keine Verbraucher mit durchfüttern z.B.LEDs).

avr

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
http://www.mikrocontroller.net/articles/Speicher#E...

Oder man schaltet den AVR nie wirklich aus und nutzt den Power-Down 
Sleep Mode

MfG
Falk

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
avr schrieb:
> @Feissy, @Daniel
>
> Das geht eine gewisse Zeit gut, aber dann ????

Die Frage ist: Was ist eine gewisse Zeit?

Da der TO da Taster drann hängen hat, kann man mit großer 
Wahrscheinlichkeit davon ausgehen, dass dieser Taster nicht alle 2 
Sekunden, 24 Stunden am Tag, 7 Tage die Woche betätigt wird.

Wenn er jede halbe Stunde einen Taster betätigt, 24-7, reicht das 
immerhin für ~2080 Tage oder rund 5.5 Jahre

Wenn er dann noch in der Nacht schläft anstatt auf den Taster zu 
drücken, sind wir bei 10 Jahren ....

.... bis die garantierte Nutzungsdauer abgelaufen ist. Was ja nicht 
automatisch heißt, dass das EEPROM mit dem 100001 Schreibzugriff 
ausfällt.

Will man auf Nummer sicher gehen, kann man ja immer noch die Anzahl der 
bisherigen Schreibzyklen im EEPROM selbst vermerken (als uint16_t) und 
bei Bedarf auf die nächsten 3 Bytes ausweichen, 128/3 = ~42, womit wir 
bei 420 Jahren wären, wenn die angenommene Nutzungsgewohnheits-Schätzung 
halbwegs zutreffend ist.

Autor: avr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Karl heinz

Das stimmt, aber wenn er in der Main/while(1) einfach
immer speichert (evtl. sogar ohne Zeitfenster) dann geht es
340 Sekunden und die Grenze ist erreicht.

Ich wollte nur zur Vorsicht mahnen!

avr

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
avr schrieb:
> @Karl heinz
>
> Das stimmt, aber wenn er in der Main/while(1) einfach
> immer speichert (evtl. sogar ohne Zeitfenster) dann geht es
> 340 Sekunden und die Grenze ist erreicht.

Das da oben war ja auch nur ein Codefragment, welches den Zugriff auf 
das EEPROM zeigt. Da fehlt doch das meiste, zb die Hauptschleife, die 
Tastenauswertung, das eigentliche Portsetzen, etc. Ich gehe schon davon 
aus, dass der TO so schlau ist, den Zustand am Port nur dann neu zu 
setzen bzw. im EEPROM zu verändern, wenn sich der Zustand auch geändert 
hat.

Autor: Feissy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok also wenn der es nur 2 jahre tut reicht vollkommen dann gibts eben 
einen neuen Attiny. ;-) danke für die Antworten.
Aber wo genau muss ich diese Funktion einfügen??
In der for schleife ??? Hier ist mein Code aber so funzt das nich so 
ganz.
#include <avr/io.h>
#include <inttypes.h>
#include <stdint.h>          //Variablen
#include <avr/eeprom.h>        //EEPROM
#include <util/delay.h>     

 uint8_t foo EEMEM = 0;

/* Einfache Funktion zum Entprellen eines Tasters */
inline uint8_t debounce(volatile uint8_t *port, uint8_t pin)
{
    if ( ! (*port & (1 << pin)) )
    {
        /* Pin wurde auf Masse gezogen, 100ms warten   */
        _delay_ms(50);  // max. 262.1 ms / F_CPU in MHz
        _delay_ms(50); 
        if ( *port & (1 << pin) )
        {
            /* Anwender Zeit zum Loslassen des Tasters geben */
            _delay_ms(50);
            _delay_ms(50); 
            return 1;
        }
    }
    return 0;
}
 
int main(void)
{
    DDRD = 0x00;          // PORTD als Eingang      
    DDRB=  0xff;          // PORTB als Ausgang
   
              
 PORTB = eeprom_read_byte(&foo);  //liest den Wert aus dem EEPROM   

for(;;)
  {  

        if (debounce(&PIND, PD5))            
        PORTB = PINB ^ ( 1 << PB5 );      
         
  if (debounce(&PIND, PD4))             
        PORTB = PINB ^ ( 1 << PB4 );  
       
  if (debounce(&PIND, PD3))             
        PORTB = PINB ^ ( 1 << PB3 );     
              
  if (debounce(&PIND, PD2))             
        PORTB = PINB ^ ( 1 << PB2 );     
       
  if (debounce(&PIND, PD1))             
        PORTB = PINB ^ ( 1 << PB1 );

  }
}


Autor: Feissy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ups das lesen des eeproms muss da noch in die schleife mit rein seh ich 
grade

Autor: Gast4 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Meine erste Idee waere, das Lesen des EEPROM nach der 
Einschaltinitialisierung einzubauen.

Gast4

Autor: Feissy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich habe das jetzt so gelöst:
#include <avr/io.h>
#include <inttypes.h>
#include <stdint.h>          //Variablen
#include <avr/eeprom.h>        //EEPROM
#include <util/delay.h>     

 uint8_t foo EEMEM = 0;

/* Einfache Funktion zum Entprellen eines Tasters */
inline uint8_t debounce(volatile uint8_t *port, uint8_t pin)
{
    if ( ! (*port & (1 << pin)) )
    {
        /* Pin wurde auf Masse gezogen, 100ms warten   */
        _delay_ms(50);  // max. 262.1 ms / F_CPU in MHz
        _delay_ms(50); 
        if ( *port & (1 << pin) )
        {
            /* Anwender Zeit zum Loslassen des Tasters geben */
            _delay_ms(50);
            _delay_ms(50); 
            return 1;
        }
    }
    return 0;
}
 
int main(void)
{
    DDRD = 0x00;                             
  DDRB=  0xff;
   
     
     PORTB = eeprom_read_byte(&foo);  //liest den Wert aus dem EEPROM
         

  for(;;)
  {  

    if (debounce(&PIND, PD5)) 
            
       { PORTB = PINB ^ ( 1 << PB5 ); 
       eeprom_write_byte(&foo, PORTB);  //schreibt PORTB in den EEPROM
    }
    else
    {
     eeprom_write_byte(&foo, PORTB); //schreibt PORTB in den EEPROM
     }  
         
  if (debounce(&PIND, PD4))             

        PORTB = PINB ^ ( 1 << PB4 );  

       
  if (debounce(&PIND, PD3))             

        PORTB = PINB ^ ( 1 << PB3 );     

              
  if (debounce(&PIND, PD2))             

        PORTB = PINB ^ ( 1 << PB2 );     
       
  if (debounce(&PIND, PD1))             

        PORTB = PINB ^ ( 1 << PB1 );

  }
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Feissy schrieb:
> Also ich habe das jetzt so gelöst:

Viel zu kompliziert

#include <avr/io.h>
#include <inttypes.h>
#include <stdint.h>          //Variablen
#include <avr/eeprom.h>        //EEPROM
#include <util/delay.h>

uint8_t foo EEMEM = 0;
 
/* Einfache Funktion zum Entprellen eines Tasters */
inline uint8_t debounce(volatile uint8_t *port, uint8_t pin)
{
    if ( ! (*port & (1 << pin)) )
    {
        /* Pin wurde auf Masse gezogen, 100ms warten   */
        _delay_ms(50);  // max. 262.1 ms / F_CPU in MHz
        _delay_ms(50);
        if ( *port & (1 << pin) )
        {
            /* Anwender Zeit zum Loslassen des Tasters geben */
            _delay_ms(50);
            _delay_ms(50);
            return 1;
        }
    }
    return 0;
}

int main(void)
{
  uint8_t oldState;
  uint8_t newState;

  DDRD = 0x00;
  DDRB=  0xff;


  newState = oldState = PORTB = eeprom_read_byte(&foo);  //liest den Wert aus dem EEPROM

  for(;;)
  {
    if (debounce(&PIND, PD5))
      newState ^= ( 1 << PB5 );
 
    if (debounce(&PIND, PD4)) 
      newState ^= ( 1 << PB4 );

    if (debounce(&PIND, PD3))
      newState ^= ( 1 << PB3 );

    if (debounce(&PIND, PD2))
      newState ^= ( 1 << PB2 );

    if (debounce(&PIND, PD1))
      newState ^= ( 1 << PB1 );

    if( newState != oldState )
    {
      oldState = newState;
      PORTB = newState;
      eeprom_write_byte(&foo, newState);
    }
  }
}

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.