Forum: Compiler & IDEs Zustand vom Port speichern beim Attiny2313


von Feissy (Gast)


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

von Michael S. (schmichael)


Lesenswert?

Ja!

Michael

von Daniel B. (inox5) Benutzerseite


Lesenswert?

1
#include <stdint.h>          //Variablen
2
#include <avr/eeprom.h>        //EEPROM
3
4
//Speichervariable
5
uint8_t foo EEMEM = 0;
6
7
int main (void)
8
{
9
PORTB=0b11110000;
10
11
...
12
13
eeprom_write_byte(&foo, PORTB);  //schreibt PORTB in den EEPROM
14
15
...
16
17
PORTB = eeprom_read_byte(&foo);  //liest den Wert aus dem EEPROM
18
}

MfG
Inox

von avr (Gast)


Lesenswert?

@Feissy, @Daniel

Das geht eine gewisse Zeit gut, aber dann ????
1
 128 Bytes In-System Programmable EEPROM
2
  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

von Falk B. (falk)


Lesenswert?

http://www.mikrocontroller.net/articles/Speicher#EEPROM_Schreibzugriffe_minimieren

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

MfG
Falk

von Karl H. (kbuchegg)


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.

von avr (Gast)


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

von Karl H. (kbuchegg)


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.

von Feissy (Gast)


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.
1
#include <avr/io.h>
2
#include <inttypes.h>
3
#include <stdint.h>          //Variablen
4
#include <avr/eeprom.h>        //EEPROM
5
#include <util/delay.h>     
6
7
 uint8_t foo EEMEM = 0;
8
9
/* Einfache Funktion zum Entprellen eines Tasters */
10
inline uint8_t debounce(volatile uint8_t *port, uint8_t pin)
11
{
12
    if ( ! (*port & (1 << pin)) )
13
    {
14
        /* Pin wurde auf Masse gezogen, 100ms warten   */
15
        _delay_ms(50);  // max. 262.1 ms / F_CPU in MHz
16
        _delay_ms(50); 
17
        if ( *port & (1 << pin) )
18
        {
19
            /* Anwender Zeit zum Loslassen des Tasters geben */
20
            _delay_ms(50);
21
            _delay_ms(50); 
22
            return 1;
23
        }
24
    }
25
    return 0;
26
}
27
 
28
int main(void)
29
{
30
    DDRD = 0x00;          // PORTD als Eingang      
31
    DDRB=  0xff;          // PORTB als Ausgang
32
   
33
              
34
 PORTB = eeprom_read_byte(&foo);  //liest den Wert aus dem EEPROM   
35
36
for(;;)
37
  {  
38
39
        if (debounce(&PIND, PD5))            
40
        PORTB = PINB ^ ( 1 << PB5 );      
41
         
42
  if (debounce(&PIND, PD4))             
43
        PORTB = PINB ^ ( 1 << PB4 );  
44
       
45
  if (debounce(&PIND, PD3))             
46
        PORTB = PINB ^ ( 1 << PB3 );     
47
              
48
  if (debounce(&PIND, PD2))             
49
        PORTB = PINB ^ ( 1 << PB2 );     
50
       
51
  if (debounce(&PIND, PD1))             
52
        PORTB = PINB ^ ( 1 << PB1 );
53
54
  }
55
}

von Feissy (Gast)


Lesenswert?

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

von Gast4 (Gast)


Lesenswert?

Meine erste Idee waere, das Lesen des EEPROM nach der 
Einschaltinitialisierung einzubauen.

Gast4

von Feissy (Gast)


Lesenswert?

Also ich habe das jetzt so gelöst:
1
#include <avr/io.h>
2
#include <inttypes.h>
3
#include <stdint.h>          //Variablen
4
#include <avr/eeprom.h>        //EEPROM
5
#include <util/delay.h>     
6
7
 uint8_t foo EEMEM = 0;
8
9
/* Einfache Funktion zum Entprellen eines Tasters */
10
inline uint8_t debounce(volatile uint8_t *port, uint8_t pin)
11
{
12
    if ( ! (*port & (1 << pin)) )
13
    {
14
        /* Pin wurde auf Masse gezogen, 100ms warten   */
15
        _delay_ms(50);  // max. 262.1 ms / F_CPU in MHz
16
        _delay_ms(50); 
17
        if ( *port & (1 << pin) )
18
        {
19
            /* Anwender Zeit zum Loslassen des Tasters geben */
20
            _delay_ms(50);
21
            _delay_ms(50); 
22
            return 1;
23
        }
24
    }
25
    return 0;
26
}
27
 
28
int main(void)
29
{
30
    DDRD = 0x00;                             
31
  DDRB=  0xff;
32
   
33
     
34
     PORTB = eeprom_read_byte(&foo);  //liest den Wert aus dem EEPROM
35
         
36
37
  for(;;)
38
  {  
39
40
    if (debounce(&PIND, PD5)) 
41
            
42
       { PORTB = PINB ^ ( 1 << PB5 ); 
43
       eeprom_write_byte(&foo, PORTB);  //schreibt PORTB in den EEPROM
44
    }
45
    else
46
    {
47
     eeprom_write_byte(&foo, PORTB); //schreibt PORTB in den EEPROM
48
     }  
49
         
50
  if (debounce(&PIND, PD4))             
51
52
        PORTB = PINB ^ ( 1 << PB4 );  
53
54
       
55
  if (debounce(&PIND, PD3))             
56
57
        PORTB = PINB ^ ( 1 << PB3 );     
58
59
              
60
  if (debounce(&PIND, PD2))             
61
62
        PORTB = PINB ^ ( 1 << PB2 );     
63
       
64
  if (debounce(&PIND, PD1))             
65
66
        PORTB = PINB ^ ( 1 << PB1 );
67
68
  }
69
}

von Karl H. (kbuchegg)


Lesenswert?

Feissy schrieb:
> Also ich habe das jetzt so gelöst:

Viel zu kompliziert

1
#include <avr/io.h>
2
#include <inttypes.h>
3
#include <stdint.h>          //Variablen
4
#include <avr/eeprom.h>        //EEPROM
5
#include <util/delay.h>
6
7
uint8_t foo EEMEM = 0;
8
 
9
/* Einfache Funktion zum Entprellen eines Tasters */
10
inline uint8_t debounce(volatile uint8_t *port, uint8_t pin)
11
{
12
    if ( ! (*port & (1 << pin)) )
13
    {
14
        /* Pin wurde auf Masse gezogen, 100ms warten   */
15
        _delay_ms(50);  // max. 262.1 ms / F_CPU in MHz
16
        _delay_ms(50);
17
        if ( *port & (1 << pin) )
18
        {
19
            /* Anwender Zeit zum Loslassen des Tasters geben */
20
            _delay_ms(50);
21
            _delay_ms(50);
22
            return 1;
23
        }
24
    }
25
    return 0;
26
}
27
28
int main(void)
29
{
30
  uint8_t oldState;
31
  uint8_t newState;
32
33
  DDRD = 0x00;
34
  DDRB=  0xff;
35
36
37
  newState = oldState = PORTB = eeprom_read_byte(&foo);  //liest den Wert aus dem EEPROM
38
39
  for(;;)
40
  {
41
    if (debounce(&PIND, PD5))
42
      newState ^= ( 1 << PB5 );
43
 
44
    if (debounce(&PIND, PD4)) 
45
      newState ^= ( 1 << PB4 );
46
47
    if (debounce(&PIND, PD3))
48
      newState ^= ( 1 << PB3 );
49
50
    if (debounce(&PIND, PD2))
51
      newState ^= ( 1 << PB2 );
52
53
    if (debounce(&PIND, PD1))
54
      newState ^= ( 1 << PB1 );
55
56
    if( newState != oldState )
57
    {
58
      oldState = newState;
59
      PORTB = newState;
60
      eeprom_write_byte(&foo, newState);
61
    }
62
  }
63
}

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.