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
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
@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
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
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.
@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
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.
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 | }
|
ups das lesen des eeproms muss da noch in die schleife mit rein seh ich grade
Meine erste Idee waere, das Lesen des EEPROM nach der Einschaltinitialisierung einzubauen. Gast4
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 | }
|
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.