PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C ATtiny13 - Wie Sleep beenden ohne externes Signal



oberallgeier
13.01.2022, 10:31
Bitte um Hilfe.
Aufgabe: Aufwecken eines tiny13 aus dem idle- oder einem sonstigen sleep ohne externes Signal.

Hintergrund.
Tiny85/sleep :
Mein Pacer läuft auf nem tiny85 mit internem Oszillator und mit nem 9V-Block seit Monaten. Hier der Schaltplan (https://dl.dropbox.com/s/pndxyfaoyhf2655/Pcr81-t85_SCH_x30.JPG?dl=0) und die Bestückung (Board) auf Lochplatte (https://dl.dropbox.com/s/9yl8h5v8ophm3mp/Pcr81-t85_Board_x30.JPG?dl=0). Zur bequemen Bedienung sind zwei Tasten ausreichend.

Tiny85 - Aufgabe/Nutzung: mehrmals wöchentlich wird jeweils mehrere Minuten der Blinkrhythmus bei Fitnessübungen benutzt.
Beim ersten Bestromen geht der Pacer sofort in den sleep, ebenso bei geeignetem Tastendruck (TAB länger als 2 sec). Durch Tastendruck (TAB, PB1) länger als 2 sec wird er aus dem Sleep geweckt, das gewünschte Blinkprogramm wird mit den Tasten gewählt, läuft einmal ab und endet mit sleep (siehe Code). So ein Ablauf dauert zwei bzw. fünfundzwanzig (25) Minuten; danach geht der Pacer wieder in den sleep.
Fazit: das Ding läuft und läuft (wie seit Jahren) und der popelige 9V-Block hält ca. 6 Monate !
// ================================================== =============================
// === Ruhemodus fuer tiny85 =============== // entnommen 28Nov2021 aus Datei
// D:\D_pro-fils\compu_MC\C2\PCR_80\alter_code
// \PCR80_x64_statsquo_Stand-13-Okt-2010\PCR_80_tmr_x64.c
// x64 14Mai10 1930 PWM - dabei blinkt grünLED gaaanz kurz
// > > > > A B E R : PCINT von 2 auf 1 (PB1) gesetzt
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SLEEP1 (void) // Ruhemodus ein, wake up durch PCINT1 auf PIN PB1
// war: void schlafPC2 (void) // Controller in Ruhemodus schalten
// Ende des Ruhemodus durch PCINT1 auf PIN1/TAB
// Start "normal" mit "Resetblink", danach warten auf Tastendruck ohne LEDs,
// nach Tastendruck nochmal Resetblink und dann einschlafen.
// Dies zur Messung des Strombedarfs ausserhalb und im Schlafmodus.
// - - - - - - - - - - - - - - - -
{ //
GIMSK |= (1<<PCIE); // PinChangeInterrupt enable doc S 53
PCMSK |= (1<<PCINT1); // PinChangeInterrupt auf Pin PB1/PCINT1 doc S 54
MCUCR |= (1<<SM1)|(1<<SE); // SM1: Power Down, SE: Sleep enable
//
// - - - - - - - - - - - - - - - -
sei(); //
asm volatile ("sleep"); // Inline-Assembler
// Möglich statt "asm volatile ("sleep");.." auch die folgenden zwei Befehle
// sleep_mode ( ); sleep_disable ( ); //
//
MCUCR &= ~(1<<SM1)|(1<<SE); // Folgende 3 Zeilen: alten Zustand / zurücksetzen
GIMSK &= ~(1<<PCIE); // PinChangeInterrupt disable
PCMSK &= ~(1<<PCINT1); // PinChangeInterrupt disable Pin PCINT2 doc S 54
//sei(); //
// - - - - - - - - - - - - - - - -
return;
} // Ende void SLEEP1 (void) -- Ruhemodus ein, wake up dur
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// ================================================== =========================== =

Mein Problem:
Tiny13 :
Meine Weihnachtsbeleuchtung hat einige kurze Lichterketten die durch je eine minimalistischen Schaltung mit nem tiny13 und einer 3xAA-Batteriebox sieben Stunden eingeschaltet werden. Ausschalten erfolgt nach Ablauf der Zeit durch return 0; Einschalten nach dem ersten Bestromen bzw. durch den /RESET; da ist also IMMER händische Aktion erforderlich. Die schnelle Lösung erfolgte so - Ende durch return 0; - weil mir eine geeignete Lösung mit sleep nicht gelang.
Zur Stromersparnis in den Ruhephasen wird der interne 128kHz-Oszillator genutzt, schneller ist bei der einfachen, zeitunkritischen Arbeitsweise nicht nötig, langsamer ist - ohne externen Quarz nicht möglich (? - klick mal) (https://dl.dropbox.com/s/lxkxcob0vrufof0/Pcr81-t85_71SleepModus_Doc.JPG?dl=0).

Nun suche ich DOCH nach einer Lösung mit dem internen sleep um mir das tägliche wieder-Einschalten zu ersparen.
Schwierig.
Allenfalls möglich finde ich eine dummy-ADC-Wandlung die mir den Controller aufweckt. Durch ne entsprechende Anzahl von Weckwiederholungen kann eine geeignete Schleife die gewünschte Dunkelphase von ca. vierzehn Stunden erreichen. Dumm nur dass die sleep-Pausen durch den ADC ziemlich kurz sind, siehe Auszug/Zitat:

Zitat aus ATtiny13_doc2535J 08/10
... A normal conversion takes 13 ADC clock cycles. The first conversion after the ADC is switched on (ADEN in ADCSRA is set) takes 25 ADC clock cycles in order to initialize the analog circuitry, as shown in Figure 14-4 below ...

Selbst der popelige 8-Bit-Timer könnte das in einer maximal langen Schleife über zehn Mal langsamer - und entsprechend stromsparender. Aber - es gibt nach dem eben genannten Arbeitsblatt keine Möglichkeit - oder doch ? Oder gibt es Quarze oder ähnliche Bauteile zur energiesparenden (energielosen) Takterzeugung?

Frage:
Gibt es vielleicht doch ne Möglichkeit - wie auch immer? Nur Energie sollte sie nicht zusätzlich benötigen.

Danke im Voraus

Gnom67
13.01.2022, 11:34
Ich hab zwar dein Problem nicht wirklich verstanden, aber wenn du was nach Zeitvorgaben steuern willst, dann hast du mindestens diese zwei Möglichkeiten.

Entweder den Tiny immer in den Sleep Modus schicken und nach der maximalen Sleep-Timer-Zeit (ich glaube 4 Sekunden - je nach Modell) aufwachen lassen, dann einen Zähler hochzählen und damit kannst du bestimmen, wie lange er "nichts" macht und wann er wieder die LEDs schaltet oder sowas.

Oder du hängst eine Real Time Clock daran (DS3231 ist wohl derzeit das zu empfehlende Modell) und programmierst dort die entsprechenden Alarmzeiten mit denen du den Tiny per Interrupt aus dem Tiefschlaf wecken kannst.

oberallgeier
13.01.2022, 17:01
.. hast du mindestens diese zwei Möglichkeiten .. Tiny immer in den Sleep Modus schicken und .. aufwachen lassen .. Oder .. eine Real Time Clock ..GENAU dieses "Entweder" ist meine Absicht - eine INTERNE Wake up Quelle. Die externe Quelle RTC brauchts dann ja nicht.

Der Teufel steckt wie immer im Detail, denn ich will ja, siehe oben, dass der Controller OHNE externen Eingriff wieder aus dem sleep Modus kommt. Dumm, denn welcher Sleep Modus des tiny13 kann das? (GENAU DAS versteh ich nicht).

Zur Verfügung stehen beim tiny13 die Wake-up Sources (siehe Datenblatt) :

......https://dl.dropbox.com/s/9fd1cw6y0o33uq6/tiny15_7-1-SleepModus_Doc.JPG?dl=0

INT0 oder Pin Change...- nur von EXTERN, ich will aber eine interne Aktion
EEPROM Ready............- beim EEPROM-lesen schafft der Controller doch ! ?
ADC . . . . . . . . . . . . .- im Eingangspost erwähnt, ist zu kurz für Ersparungen (und beim Wandeln benötigt der µC Strom!?)
Other I/O . . . . . . . . ..- sind auch EXTERN, ich benötige eine interne Aktion
Watchdog . . . . . . . . .- ? ? ? gibt nen Systemstart <=> alles wird zurückgesetzt, auch die Zählschleife . . .

Daher die Bitte:
a) Welcher sleep Modus macht mir das OHNE Zurücksetzen des Controllers UND ohne externe Quelle?
b) Wie bitte sieht dann der geänderte Code aus (siehe funktionierende Sequenz oben).

Searcher
13.01.2022, 18:01
Hallo,
das müßte schon mit dem Watchdog gehen. Der läßt sich anscheinend nicht nur auf Reset sondern auch auf Watchdog Interrupt konfigurieren und wenn es sein muß sogar auf Beides damit in einer ISR vor Reset gesichert werden kann.

Der Watchdog Timer läuft wohl mit 128kHz. Die maximale Laufzeit ist 8 Sekunden. Also alle 8 Sekunden raus aus dem sleep, in der ISR nachsehen, ob es schon Zeit ist oder eine Variable inkrementieren und dann wieder in den sleep.

Das ist die Idee. Mal sehen, ob ich auch die Programmzeilen dazu zusammen bekomme.

Könnte aber was dauern. zZ kämpfe ich noch mit einem Breadboardset, das so ein Powermodul für Input 6,5 bis 12V und Output 5V und 3,3V hat. Auf dem Ding scheint es gefälschte AMS1117 Spannungswandler verbaut zu haben. Es sollten LDOs sein. Droput Voltage ist beim 5V Wandler aber fast zwei Volt anstatt maximal 1,3V. Und 'ne normale, keine Schottky Verpolschutzdiode. Mein 7V Steckernetzteil, das ich immer verwende reicht da also nicht aus. ... Für 3,50€ incl. Steckbrett und 'ner ganzen Menge Steckkabel ... Was soll man machen?

Gruß
Searcher

Gnom67
13.01.2022, 19:38
Im Datenblatt DS40002307A Kapitel 8.4 kannst du nachlesen, dass man zwischen Interrupt Mode und Reset Mode umschalten kann. Dafür ist das WDTIE-Flag zuständig. Damit müsste das lösbar sein. In Kapitel 8.5.2 findest du noch was zu den Registern und Flags.
Wenn ich das richtig sehe, muss WDE = 0 und WDTIE = 1 sein, damit der Interrupt ausgelöst wird.

Andre_S
14.01.2022, 08:03
Hallo,

ist zwar nicht taufrisch, aber im Prinzip wie hier im Tread schon beschrieben:
https://arduino-projekte.webnode.at/meine-projekte/attiny-im-schlafmodus/wecken-mit-wdt/


Gruß André

Searcher
14.01.2022, 08:20
Hallo,

ich habe ein BASCOM Demo Programm gemacht. Leider bin ich in C nicht so fit, daß ich das schnell hinbekomme. Habe aber versucht, möglichst gut zu kommentieren. Programm ist auf Tiny44 getestet. Auf Tiny13 heißen, so meine ich, nur zwei relevante Bits anders. Ist im Programm kommentiert.

Gruß
Searcher



'################################################# ##
'
'ATtiny44
'
'WATCHDOG DEMO
'
'IMPORTANT prerequisite:
'WDTON fuse is default (unprogrammed = 1, watchdog timer interrupt function is enabled)
'
'three LEDs are used to visually monitor the success of sleep mode pauses
' 1. after start of program (or a reset) all three leds lit for one second
' 2. 8 seconds wdt pause
' 3. wdt led flash, life led flash
' 4. 8 seconds pause
' 5. wdt led flash, life led flash
' 6. 8 seconds pause
' 7. wdt led flash, life led flash
' 8. directly after 7. action led flash
' 9 5 seconds pause in action sub, another action led flash
' 10. continue step 2. with 8 sconds pause
'
' control overall sleep duration by value in watchdog_ovf
'
'################################################# ######
$regfile = "attiny44.dat"
$framesize = 24
$swstack = 24
$hwstack = 38
$crystal = 8000000 'internal oscillator

Config Portb.0 = Output 'WDT LED, switched in watchdog isr (200ms flash)
Config Porta.3 = Output 'Action LED indicates action after watchdog controlled sleep
Config Porta.7 = Output 'Life LED, monitor wether sleep mode ist entered

Rem : all LEDs for 1 second ON (check for program begin and/or µC reset)
portb.0 = 1
porta.3 = 1
porta.7 = 1
wait 1
portb.0 = 0
porta.3 = 0
porta.7 = 0
Rem : check end for program begin and/or µC reset

dim watchdog_action_flag as byte 'set in watchdog interrupt, indicates end of sleep pause
dim watchdog_ovf as word 'counts watchdog timer overflows before action

set mcucr.sm1 'prepare sleepmode as power down, SM1 Bit in MCUcR
on wdt isr_watchdog 'watchdog interrupt vector to watchdog isr

wdtcsr = bits(wdp0 , wdp3) 'set wdp0,wdp3 bits, watchdog prescaler to 8 seconds

Rem : ### !wdr 'asm instruction "wdr" resets the watchdog timer

set WDTCSR.wdie 'watchdog interrupt enable
Rem attiny13 : set WDTCSR.wdtie 'watchdog interrupt enable
enable interrupts 'global interrupt enable (sei)


Rem : ################################################## #############################
Rem : ### main loop
Do
set mcucr.se 'enable following sleep command, SE Bit in MCUCR
!sleep 'asm sleep command. enters sleepmode which is prepared in MCUCR by SM bits
reset mcucr.se 'disable sleep commands: recomended in datasheet

porta.7 = 1 'Life LED ON
waitms 200 '200ms flash, monitor sleep state
porta.7 = 0 'Life LED OFF
Rem : ### if sleepmode ist not entered , Life LED OFF is not noticable (to fast, LED appears continiously on exept during action)

if watchdog_action_flag = 1 then
gosub sub_watchdog_action
watchdog_action_flag = 0
end if
Loop
Rem : main loop end
Rem : ################################################## #############################



Rem : ################################################## #############################
Rem : ### in subroutine do whatever to be done after watchdog controlled long sleep break
sub_watchdog_action:
porta.3 = 1 'Action LED ON
waitms 200 '200ms flash
porta.3 = 0 'Action LED OFF
wait 5 '5 seconds do nothing, just wait
porta.3 = 1 'Action LED ON
waitms 200 '200ms flash
porta.3 = 0 'Action LED OFF

Rem : ### !wdr 'asm instruction "wdr" resets the watchdog timer
set WDTCSR.wdif 'clear eventually set interrupt flag before enabling wdt interrupt
set WDTCSR.wdie 'watchdog interrupt enable
Rem attiny13 : set WDTCSR.WDTIF 'clear eventually set interrupt flag before enabling wdt interrupt
Rem attiny13 : set WDTCSR.WDTIE 'watchdog interrupt enable
return
Rem : ################################################## #############################


isr_watchdog: 'controls invoking of "sub_watchdog_action"
portb.0 = 1
waitms 200 '200ms flash - monitor watchdog interrupt
portb.0 = 0
watchdog_ovf = watchdog_ovf + 1 'count wdt timer overflows/interrupts
if watchdog_ovf >= 3 then
reset WDTCSR.wdie 'watchdog interrupt disable
Rem attiny13 : reset WDTCSR.wdtie 'watchdog interrupt disable
watchdog_action_flag = 1 'flag will be processed in main loop
watchdog_ovf = 0
end if
return

end 'end program

oberallgeier
14.01.2022, 08:22
Danke Euch für die konstruktiven Hinweise.

m Datenblatt DS40002307A Kapitel 8.4 kannst du nachlesen . . .Danke Gnom67 - jaaa, das ist DER Hinweis! .. steht auf den an die zwanzig Seiten Datenblatt die ich (noch) nie gelesen, nicht mal überflogen hatte. Sprich: bins selber schuld. Ich geh die nächsten Tage dran (jetzt erstmal an die Kletterwand - in der Halle - weils draussen deutlich unter Null ist *brrrr* aber der Himmel ist uni bayerisch-blau)

@André : ach jee, und die Arduinohilfen gehören auch nicht zu meiner üblichen Literatur. Schade wie ich sehe!

@Searcher : danke für Deine Mühe. PS: haste im Postfach nachgesehen?

Danke nochmal für Eure Hilfen. Ich werde berichten.

oberallgeier
23.01.2022, 16:24
Es geht weiter? Ja, blos funktionieren tuts nicht :-/ Da muss ich mal (noch) gründlich (..er) drüberschauen.


// ================================================== =========================== =
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// N E U Basis "alter" SLEEP1, Adaption aus searcher´s tiny44_WDT_Demo-in-BAS
// ================================================== =========================== =
// Dok D:\D_pro-fi...blätter\atmel-controller_Datenblätter_App-Notes
// \ATtiny13_doc2535J_08-10-akt-neueste-13-13V_13neu_13-13Vneu_13-13Vneu.pdf
// ================================================== =========================== =
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SLP0init (void) // Ruhemodus vorbereiten / initialisieren
{ //
// __watchdog_reset();
// Siehe https://arduino-projekte.webnode.at
// /meine-projekte/attiny-im-schlafmodus/wecken-mit-wdt/
// Setzen des Registers fuer Watchdog Time-out Interrupt
cli();
wdt_reset(); // Reset Watchdog Timer
MCUSR &= ~(1 << WDRF); //Ruecksetzen des Watchdog System Reset Flag
MCUCR |= (1 << SM1); // SM1: Power Down 46
/* Set new prescaler(time-out) */
WDTCR |= (1<<WDE) | (1<<WDCE) | (1<<WDP3);
// WDTCR |= (1 << WDTIE); // Watchdog Timer Interrupt Enable 41
WDTCR |= (1 << WDTE); // Watchdog Timer Interrupt Enable setzen 41
// sei();

return;
} // Ende void SLEEP1 (void) -- Ruhemodus ein, wake up dur
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// ================================================== =========================== =



// ================================================== =========================== =
// Dok D:\D_pro-fi...blätter\atmel-controller_Datenblätter_App-Notes
// \ATtiny13_doc2535J_08-10-akt-neueste-13-13V_13neu_13-13Vneu_13-13Vneu.pdf
// Dann - neu: D:\D_pro-fi...blätter\atmel-controller_Datenblätter_App-Notes
// \ATtiny13A-Data-Sheet-DS40002307A-2021_neu-Microchip
// ================================================== =========================== =
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SLEEP0 (void) // Ruhemodus SLEEP0 starten
{ //
MCUCR |= (1<<SM1)|(1<<SE); // SM1: Power Down, SE: Sleep enable 46
sei(); //
asm volatile ("sleep"); // Inline-Assembler
MCUCR &= ~(1<<SM1)|(1<<SE); // => alten Zustand / zurücksetzen

WDTCR &= ~(1<<WDE); // Watchdog Timer Interrupt D I S able 41
WDTCR |= (1<<WDTIE); // Watchdog Timer Interrupt Enable 41

// - - - - - - - - - - - - - - - -
return;
} // Ende void SLEEP1 (void) -- Ruhemodus ein, wake up dur
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// ================================================== =========================== =

Wird im main aufgerufen :
..
SetBit (PORTB, kLED); wms ( 5 ); // Port für/mit PB0/rLED
SLP0init ( ); // Ruhemodus SLEEP0 vorbereiten / initialisieren
ClrBit (PORTB, kLED); wms ( 5 ); // Port für/mit PB0/rLED

while ( 1 ) // Hier folgt das eigentliche Hauptprogramm
{ //
SetBit (PORTB, kLED); wms ( 10 );
//
SLEEP0 ( ); // Ruhemodus SLEEP0
//
ClrBit (PORTB, kLED); wms ( 10 ); // LED aus
//
// SLEEP0 ( ); // Ruhemodus SLEEP0
//
} // Ende while ( 1 )
..

*grübel*

Searcher
23.01.2022, 17:29
Hallo,

ich finde keine Interrupt Routine. Springt der µC ins Leere?

Die Zeile "WDTCR &= ~(1<<WDE); // Watchdog Timer Interrupt D I S able 41" ist unnötig und wird vermutlich auch nicht ausgeführt.

Gruß
Searcher

oberallgeier
23.01.2022, 18:54
.. ich finde keine Interrupt Routine. Springt der µC ins Leere?
..
Die Zeile "WDTCR &= ~(1<<WDE); // Watchdog Timer Interrupt D I S able 41" ist unnötig und wird vermutlich auch nicht ausgeführtDanke! Richtig, ich finde auch keine WDT-ISR. Hab ich nachgetragen. Die genannte Zeile gelöscht . . .
Noch immer gibts nur so ´n Blinzeln im Oskar (klick) (https://dl.dropbox.com/s/u79nef6pkqmjxl2/LED-Port-ohne-LED.JPG?dl=0).

Searcher
23.01.2022, 19:23
WDTCR |= (1<<WDE) | (1<<WDCE) | (1<<WDP3);
Diese Zeile hatte ich eben auch übersehen. WDE setzt den Watchdog RESET. Du möchtest aber den Watchdog Interrupt. Muß also auch weg zusammen mit WDCE.
MIT WDP3 wird der Timer auf 4 Sekunden eingestellt. OK.
Bleibt nur WDTCR |= (1<<WDP3); von der Zeile übrig.

oberallgeier
23.01.2022, 22:32
. . Bleibt nur WDTCR |= (1<<WDP3); von der Zeile übrig . .Danke - läuft. Anfangs mit Stolpersteinen. Ausführlich erst morgen.

oberallgeier
24.01.2022, 09:24
Es läuft.
Sprich: der Controller wird bestromt, fährt eine Blinksignatur ab - mit waits, ohne Interrupt - und startet die eigentliche Watchdog-Testsequenz:
// ================================================== =========================== =
// === HAUPTProgramm ================================================== ======== =
// Initialisierungen, LED kurzblinken = Signal für Programmstart ============== =
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int main (void) //
{ //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Pins/Ports als Ein- (0) oder Ausgang (1) konfigurieren, Pull Ups mit (1) aktiv
// EEEEEAEA
DDRB = 0b00000101; // Anschlussbelegung s.oben, tiny85 hat nur PB0..PB4(PB5)
PORTB = 0b11111010; // PB0 = Test.LED, nur für TestAnzeige des "Stundentakts"
// PB1 = Taster, akt. PullUp, Eingang: NUR durch /RESET
// PB2 = LED-Kette, default auf Dunkelphase eingestellt
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Vorstart-Blink => x Blinkies rot - damit man sieht, dass etwas geht
for ( u8 st = 0; st < 3; st ++ ) // Anzahl Blinkies rot
{ //
SetBit (PORTB, rLED); wms ( 20 ); // Port PB0 rLED ein
ClrBit (PORTB, rLED); wms ( 10 ); // Port PB0 aus
} // Ende for ( STdAnz = 0; STdAnz <?; STdAnz ++ )
SetBit (PORTB, rLED); wms ( 100 ); // Port PB0 rLED ein
ClrBit (PORTB, rLED); // Port PB0 aus
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SetBit (PORTB, kLED); wms ( 20 ); // Port für/mit PB0/rLED
ClrBit (PORTB, kLED); wms ( 20 ); // Port für/mit PB0/rLED

SLP0init ( ); // Ruhemodus SLEEP0 vorbereiten / initialisieren

while ( 1 ) // Hier folgt das eigentliche Hauptprogramm
{ //
SetBit (PORTB, kLED); //
SLEEP0 ( ); // Ruhemodus SLEEP0 - dauert ca. 8 sec
ClrBit (PORTB, kLED); // Port für/mit PB2/gLED aus
SLEEP0 ( ); // Ruhemodus SLEEP0 - dauert ca. 8 sec
} // Ende while ( 1 )
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
return 0; // Traditionelles Ende von main
} // Ende main
// ================================================== =========================== =

Das sollte also ordentlich arbeiten. Tat es nicht, siehe Link auf Oszillogramm (https://dl.dropbox.com/s/u79nef6pkqmjxl2/LED-Port-ohne-LED.JPG?dl=0). (Anm.: für das Oszillogramm wurde die LED aus dem Steckbrett entfernt). Blöd! Diese 10-Hz-Rechteckfrequenz ist mir immer noch unerklärlich. Nach einigen unsinnigen und überflüssigen Überprüfungen des Quelltextes hatte ich das Testboard komplett von der Stromversorgung abgeklemmt und dann wieder bestromt. Siehe da . . . nu läufts wie gewolltgehofftgeplant - 8sec LED=an, 8sec LED=aus.

Nachfolgende Versuche konnten das Fehlverhalten reproduzieren: Im Programmier-/Flashmodus des Controllers Taktfrequenz erhöhen, Flashtakt erhöhen, flashen, Controllertakt auf 128kHz runter - und das 10-Hz-Blinken kommt (gefühlt immer, bin aber nicht gaanz sicher). Stromversorgung völlig aus nach dem Flashen bringt nach dem Wieder-Bestromen die gewünschte Funktion. Stromverbrauch mit METRAHit 12S: 00.00 mA. Genauer wurde noch nicht gemessen. Mit der Ampere-am-Volteingang-Methode sinds im Alle-LED-aus-Zustand ca. 0,4 µA bei 4,7 V.

Was jetzt noch folgt wird ein Zähler in der while-Schleife mit dem eine längere Zeitspanne realisiert werden kann.

Danke allen Helfern.

- - - Aktualisiert - - -

Der Vollständigkeit halber die Codesammlung WDT etc:

/* >>
Stand D:\D_pro-fils\compu_MC\C1 mC Projekte\C_test1\Ctst1_tmrxx.c
================================================== ============================= =
Target MCU : siehe main Tiny13
Target Hardware : siehe main
Target cpu-frequ. : siehe main
================================================== ============================= =
*** Version / Versionsgeschichte:
x12 23Jan22 2252 Seltsame Probleme beim Flashen. Läuft ganz gut
x11 15Jan22 16hh Div. Aenderungen
x10 17Jan22 1758 Erste Versuche mit WDT (erfolglos)
x00 Nur ~wms~
================================================== ============================= =
Doku: D:\D_pro-fils\compu_MC\Datenblätter\atmel-controller_Datenblätter_App-Notes
\ATtiny13_doc2535J_08-10-akt-neueste.pdf
================================================== ============================= =
*** Aufgabenstellung : WDT-Timer für längere Pausen mit minimalist. Strombedarf
================================================== ============================ */


// ================================================== =============================
// ================================================== =============================
/*##### Variablenliste, global #####*/
// ================================================== =============================
// ================================================== =============================
// ##>> Macros zum Setzen, Löschen und toggeln von Bits bzw. Ausgängen
#define SetBit(ADDR,BIT) ((ADDR) |= (1<<(BIT))) // Setz PORTC |= (1<<5);
#define ClrBit(ADDR,BIT) ((ADDR) &= ~(1<<(BIT))) // Lösch PORTC &= ~(1<<5);
//#define ToggleBit(ADDR,BIT) ((ADDR) ^= (1<<(BIT))) // Toogel PORTC ^= (1<<5);
//#define IsBitClr(ADDR,BIT) (~ADDR & (1<<BIT)) // Bit=0?
//#define IsBitSet(ADDR,BIT) (((ADDR)&(1<<BIT))?1:0) // Bit=1? IsBitSet (P, RC5pin
// if (!(PINC & (1<<4))) // Wenn RC-5-Sensor LOW <=> IR ist on, und
// .. ==> praktisch keine Abschaltung
// if (!(PINC & 0x10)) ADCMMM = 2; // Ist Bit 4 gelöscht? 0x10 = 0b 0001 0000
//
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#define PB PORTB // Kurzwort für PORTB
#define kLED 2 // Lichterkette LED auf PB2
#define rLED 0 // Rote LED auf PB0
//
// ================================================== =============================


// FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP =
// FP FP FP FP Funktionsprototypen FP FP FP FP FP FP FP FP FP FP FP FP FP FP =
void SLP0init (void) ; // Ruhemodus SLEEP0 vorbereiten / initialisieren
void SLEEP0 (void) ; // Ruhemodus SLEEP0 startem
ISR(WDT_vect) { } ; // Ende ISR(WDT_vect)
void wms( uint16_t ms ) ; // Der Pausenwert ist nur experimentell !
// FP FP FP FP E N D E FP FP FP FP FP FP FP FP FP FP FP FP FP FP =
// FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP FP =


// ================================================== =========================== =
// N E U Basis "alter" SLEEP1, Adaption aus searcher´s tiny44_WDT_Demo-in-BAS
// ================================================== =========================== =
// Dok D:\D_pro-fi...blätter\atmel-controller_Datenblätter_App-Notes
// \ATtiny13_doc2535J_08-10-akt-neueste.pdf
// ================================================== =========================== =
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SLP0init (void) // Ruhemodus SLEEP0 vorbereiten / initialisieren
{ //
cli();
wdt_reset(); // Reset Watchdog Timer
MCUSR &= ~(1 << WDRF); //Ruecksetzen des Watchdog System Reset Flag
MCUCR |= (1 << SM1); // SM1: Power Down 46
WDTCR |= (1<<WDP3) | (1<<WDP0);
WDTCR |= (1 << WDTIE); // Watchdog Timer Interrupt Enable 41
return;
} // Ende void SLEEP1 (void) -- Ruhemodus ein, wake up dur
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// ================================================== =========================== =



// ================================================== =========================== =
// SLEEP - Test für sleep per Watchdog
// ================================================== =========================== =
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SLEEP0 (void) // Ruhemodus SLEEP0 startem
{ //
MCUCR |= (1<<SE); // SE: Sleep enable 46
sei(); //
asm volatile ("sleep"); // Inline-Assembler
MCUCR &= ~(1<<SE); // => alten Zustand / zurücksetzen
return;
} // Ende void SLEEP1 (void) -- Ruhemodus ein, wake up dur
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// ================================================== =========================== =


// ================================================== =========================== =
ISR(WDT_vect) { } // ISR(WDT_vect) - Nur Ansprungstelle
// Mehr Infos: https:
//arduino-projekte.webnode.at/meine-projekte/attiny-im-schlafmodus/wecken-mit-wdt/
// ================================================== =========================== =


// ================================================== =========================== =
//### Programm pausiert !! Dauer experimentell ! schwankt >> mit Temperatur !
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void wms ( uint16_t ms ) // Der Pausenwert ist nur experimentell !
// - - - - - - - - - - - - - - - -
{ // Weiter Messwerte in L3_tmr10.c und früher
for(; ms>0; ms--)
{ //
uint16_t __c = 1000; // 17Jan22.18h08 :
// Zeitmessung 50 "ms" sind 2,0 sec, 500 "ms" = 20 sec
__asm__ volatile ( // siehe hierzu main, ca. Zeile 156ff
"1: sbiw %0,1" "\n\t" // schwankt >> mit Temperatur ! ! !
"brne 1b"
: "=w" (__c) : "0" (__c)
);
}
}
// ================================================== =========================== =


// ================================================== =========================== =
// ===== ENDE Subroutinen ================================================= =
// ================================================== =========================== =