habe etwas Probleme mit den sleep modi sleep klappt nun wakeup auch ABER nach dem wakeup kommt etwas später ein hardreset, der durchläuft richtig power on , wieso ? mir ist das Zusammenspiel EIMSK, EIFR noch nicht klar der erste sleep kommt wie gewünscht nach 10 sekunden erste Abfrage +1000 nach dem aufwecken sollte wieder ein neuer sleep kommen nach 20 sekunden, vorgeladen +1000, Abfrage auf +1000 = 20 sekunden, ABER statt 2tem sleep kommt power on reset ! Code für in sleep going: if( !bedient && fast_it>alarm_beginn+1000 ) { //stop(2); OCR1AL = 1; // hell; OCR1BL = 0; // kon; cli(); if(!alarm_set) { //stop(3); PCMSK3|=(1<<PCINT27); PCICR|=(1<<PCIE3); EIMSK|=(1<<INT1); sleep_enable(); sei(); POWER_LED_PORT |= (1 << _powerLED); // _POWER_ON LED an sleep_cpu(); sleep_disable(); _delay_up25(3); POWER_LED_PORT &= ~(1 << _powerLED); // _POWER_ON LEDaus alarm_beginn=fast_it+1000; //bedient=TRUE; //alarm_set=TRUE; bedient=FALSE; alarm_set=FALSE; OCR1AL = hell; OCR1BL = kon; res_key=get_key_press( ALL_KEYS | (1<<KEY7) ); res_key=0; EIFR|=(1<<INTF1); //stop(4); } sei(); } // if( !bedient && fast_it>(alarm_beginn+1000) ) code für int1; SIGNAL (SIG_INTERRUPT1) { UBYTE nix; nix=1; PCMSK3&=~(1<<PCINT27); PCICR&=~(1<<PCIE3); //EIFR&=~(1<<INTF1); EIMSK&=~(1<<INT1); //war_alarm=TRUE; }
Gibt es einen Handler für PCINT3_vect/SIG_PIN_CHANGE3? Wie sieht der aus? Läuft der Pin-Change Interrupt 3 ins Leere? Martin Thomas
mthomas wrote: > Gibt es einen Handler für PCINT3_vect/SIG_PIN_CHANGE3? Wie sieht der > aus? Läuft der Pin-Change Interrupt 3 ins Leere? > > Martin Thomas hmmm, leider keine Ahnung programmiert hab ich keinen weil, ich finde keine defines dafür hab mal so gesucht (in *.h signal.h, interrupt.h ioxx4.h) wie mögliche Interrupthandler heissen können ich denke es wird genauso über den interrupthandler 1 gesprungen hab heute am Oszi mögliche Fehler gefunden, der IRQ muss lange genug anliegen sonst wird der interrupt nicht ausgeführt, der Oszi meint es ist zu kurz mit um 1ms, die wakeupzeit ist ja 4,1-65ms aber egal im IRQ muss ich ja nix weiter machen als die IRQs wieder rauszunehmen PCMSK3&=~(1<<PCINT27); PCICR&=~(1<<PCIE3); und zur sicherheit mache ich es auch hinter sleep, einer wird schon wirken aber unklar bleibt EIMSK|=(1<<INT1); setzen vor sleep ? nutze ich überhaupt INT1 ? wenn ja gibt es danach einen INT1 und muss ich INTF1 manuell löschen ? EIFR=(1<<INTF1); ich war schon mal weiter, hab die CPU aus und anbekommen, je mehr ich lese umso unsicherer werde ich was mit wem gesetzt werden muss im Moment bekomme ich sie aus set_sleep_mode(SLEEP_MODE_PWR_DOWN); aber nicht mehr an ! oder aber sie geht sofort nach aus von selbst wieder an ! je nach EIMSK und EIFR Nutzung bin verwirrt ich weiss auch nicht wirklich welche Flags ich vor dem cli() setzen darf oder muss und welche ich ausserhalb des cli setzen muss ich weiss auch nicht ob ein sleep in einer unterroutine ausgeführt werden darf, springen die atmels über interrupts ? UBYTE shutdown(void) { static UBYTE pwm1, pwm2, wakeup_from; wakeup_from=0; pwm1=OCR1AL; pwm2=OCR1BL; OCR1AL=0; OCR1BL=255; set_sleep_mode(SLEEP_MODE_PWR_DOWN); //cli(); EICRA |=(1<<ISC10); EICRA |=(1<<ISC11); PCMSK3|=(1<<PCINT27); PCICR|=(1<<PCIE3); EIMSK|=(1<<INT1); EIFR=(1<<INTF1); cli(); POWER_LED_PORT |= (1 << _powerLED); // _POWER_ON LED an sleep_enable(); sei(); sleep_cpu(); _delay_up25(3); POWER_LED_PORT &=~(1 << _powerLED); // _POWER_ON LED aus EIFR=(1<<INTF1); sleep_disable(); OCR1AL=pwm1; OCR1BL=pwm2; PCMSK3&=~(1<<PCINT27); PCICR&=~(1<<PCIE3); EIMSK&=~(1<<INT1); //EIFR=1<<INTF1; if((wakeup_from=test_status_rtc())>0) return wakeup_from; else if((wakeup_from=get_key_press( ALL_KEYS ))>0) return wakeup_from; return wakeup_from; }
Ohne den Code genau durchgesehen zu haben (mir ist nicht ganz klar, warum INT1 und PCINT27 zusammen verwendet werden)
1 | PCICR|=(1<<PCIE3); |
aktivierte den Pin-Change Interrupt 3. "Any change on any enabled PCINT31..24 pin will cause an interrupt. The corresponding interrupt of Pin Change Interrupt Request is executed from the PCI3 Interrupt Vector." [Datenblatt]. Wo ist der Handler dafür? Es sieht so aus, also würde der Interrupt einfach "ins Leere" laufen, wenn bei gesetztem I-Bit eine Änderung an PCINT27 auftritt und daher der Reset ausgelöst. Das hat erstmal nichts mit dem externen Interrupt INT1 zu tun, für den es ja einen Handler gibt. > ich finde keine defines dafür hab mal so gesucht (in *.h signal.h, > interrupt.h ioxx4.h) wie mögliche Interrupthandler heissen können Hmm. Alte Version der avr-libc? Aus der iomxx4.h "hier" (aus WinAVR 5/07):
1 | /* Pin Change Interrupt Request 3 */ |
2 | #define PCINT3_vect _VECTOR(7) |
3 | #define SIG_PIN_CHANGE3 _VECTOR(7) |
Ja, für PinChange muss der "Change" eine Weile anliegen (wie lang genau weiss ich grade nicht, hatte damit aber auch Probleme für ein "wakup on pinchange an RX" bei 115200bps aus Mode power-save). Falls man "schneller" reagieren will und es nicht auf das letzte uA Stromverbrauch im Schlafmodus ankommt: (extended-)standby sleep-mode verwenden. Zwischen sleep_cpu und sleep_disable würde ich keine Anweisungen zwischenschieben. Zum Test cli() ganz nach vorn und sei() erst wenn man alles fertig initialisiert hat. Am Ende der Initialisierung sicherheitshalber auch noch die Flags PCIF3 und INTF1 löschen ("cleared by writing a logical one"). Mglw. interessant: "Note that when entering sleep mode with the INT2:0 interrupts disabled, the input buffers on these pins will be disabled. This may cause a logic change in internal signals which will set the INTF2:0 flags." [Datenblatt] Ansonsten noch ein Hinweis auf die Dokumentation der avr-libc. In neueren Versionen wurde "sleep.h" etwas erweitert. Martin Thomas
mthomas wrote: > Ohne den Code genau durchgesehen zu haben (mir ist nicht ganz klar, > warum INT1 und PCINT27 zusammen verwendet werden) war mir auch unklar , deswegen hab ich ja gefragt > #define SIG_PIN_CHANGE3 _VECTOR(7) das war der entscheidene Tipp , ich glaub ich bin auf dem richtigen Weg ausschalten per Kommando klappt nun schon + Einschalten per Taste POWER_LED_PORT |= (1 << _powerLED); // _POWER_ON LED an EICRA |=(1<<ISC10); EICRA |=(1<<ISC11); PCMSK3|=(1<<PCINT27); PCICR|=(1<<PCIE3); cli(); _delay_up25(3); WAR EIN VERSUCH UM DIE TASTENAUSSCHALTUNG ZU ÜBERLISTEN klappt nicht PCIFR=(1<<PCIF3); in der Hoffnung den Tastenwechselinterrupt zu löschen, der hängt ja schon beim Ausschalten dort und somit ist wieder an sleep_enable(); sei(); sleep_cpu(); _delay_up25(3); die Warmlaufzeit 75ms POWER_LED_PORT &=~(1 << _powerLED); // _POWER_ON LED aus sleep_disable(); PCMSK3&=~(1<<PCINT27); PCICR&=~(1<<PCIE3); > Ja, für PinChange muss der "Change" eine Weile anliegen so wie ich das DB lese ist die Zeit egal, hinter sleep gehts weiter, nur wenn der Pinchange lange genug war , dann geht es in den IRQ ! ergo zur Sicherheit, nix im IRQ machen was nicht auch hinter sleep gemacht wird oder werden kann, für mich ist der IRQ Handler nur schmückendes Beiwerk um den RTI zu erzeugen SIGNAL (SIG_PIN_CHANGE3) { UBYTE nix; nix=1; PCMSK3&=~(1<<PCINT27); PCICR&=~(1<<PCIE3); PCIFR=(1<<PCIF3); //war_alarm=TRUE; } > Zwischen sleep_cpu und sleep_disable würde ich keine Anweisungen > zwischenschieben. Zum Test cli() ganz nach vorn und sei() erst wenn man > alles fertig initialisiert hat. Am Ende der Initialisierung > sicherheitshalber auch noch die Flags PCIF3 und INTF1 löschen ("cleared > by writing a logical one"). Mglw. interessant: "Note that when entering > sleep > mode with the INT2:0 interrupts disabled, the input buffers on these > pins will be disabled. This may cause a logic change in internal signals > which will set the INTF2:0 flags." [Datenblatt] das hat mir leider nicht geholfen, mit Taste bekomme ich den nicht aus ! nur per IR , einschalten geht ich muss morgen mit dem Oszi schauen was da los ist Timing Pegel .... übrigend Danke , dein Beitrag hat mir wirklich sehr geholfen , den Knoten im Kopf zu lösen, das ist noch alles ziemlich neu für mich und dann hat das 644 Datenblatt auch noch Fehler, glücklicherweise merkt man das die 2 mal dasselbe Register geschrieben in einer Folge, ist aber doof wenn man im Kopf int1 hat und der int2: genannt wird "which will set the INTF2:0 flags"
so Tastaturaus gelöst, ein _delay_up25(4); erzeugt die notwendige Wartezeit 4 x 25ms um auch per Tastatur auszugehen, damit ist genug Zeit nach dem Tastendruck den Int zu löschen EDIT, noch besser while(get_key_press(1<<KEY6)); _delay_up25(4); shutdown(); so nun noch das Problem das der PWM Timer offensichtlich stehenbleibt wo er will, mal mit heller LED Hintergrundbeleuchtung mal ohne, obwohl ich OCR1AL=0; vorher auf NULL setze, LED Hintergrundbeleuchtung auf aus evt. muss ich den noch manuell abschalten den PWM Timer ? , oder den Port ausschalten ? so auch gelöst: HELL_KON_DDR &= ~(1 << _LED_hell); // OC1A DDR out
so alles läuft fast nur vermute ich mein idle Modus ist nicht OK, power down läuft erwartunggemäß was wird im idle modus alles getan ? der sollte lt. sleep Zeit 30s im idle schlafen und nix tun, aber er schläft idle viel kürzer, maximal 1-5 Sekunden, Int0 hab ich aus, muss ich noch die PWM und Timer ohne gesetztes Int ausschalten ? irgendwas weckt in bei idle, ich weiss nur nicht was.... Timer Overflow ?
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.