Quellcode |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
; .include "Header.inc" ;Label und Werte Zuweisungen .include "Hardware.inc" ;Hardware Label Zuweisungen ; ;Programmstart nach RESET ( Interrupt Vektoren Tabelle ) ; .CSEG ;Was ab hier folgt kommt in den FLASH-Speicher .ORG $0000 ;Programm beginnt an der FLASH-Adresse 0x0000.. rjmp _reset ;..mit der RESET-Vectortabelle .include "IRQt13.inc" ;Restliche Interrupt Vektortabelle .ORG INT_VECTORS_SIZE ;Programmadresse nach den ganzen IRQ-Vektoren ; ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII ;I Erstinitialisierungen ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII ; ;Stapelzeiger initialisieren (fuer Unterprogramme und / oder Interrupts) ; _reset: ;ldi a,High(RAMEND) ;RAMEND, also das Ende vom SRAM, ist in der.. ;out SPH,a ;..Definitions-datei festgelegt ldi a,Low (RAMEND) ;Hier reicht ein Byte, weil das... out SPL,a ;...SRAM nur 64Byte gross ist ; ;Ports Erstkonfiguration ; sbi DDRB,pin.pla ;PORT-Bit als Ausgang f. PLA-LED sbi DDRB,led.ora ;PORT-Bit als Ausgang f. SLEEP-LED sbi DDRB,led.ge ;PORT-Bit als Ausgang f. Wake-Up sbi PORTB,led.ge ;LED Gelb ausschalten sbi PORTB,pin.int0 ;Pull-up f. INT0 Low Level Interrupt ; ;Variablen initialisieren ( r0-r31 haben unbestimmten Inhalt ) ; clr flag_reg ;Allgemeines Flaggenregister; clr ovf0_zlr ;Timer0 Overflow-Zaehler initialisieren sbr flag_reg,1<<slp ;Sleep ist gewuenscht ; ;Systemtakt ( 4,8MHz ) durch 256 teilen ( 18,750kHz = 53,333µs ) ; in a,CLKPR ;Clock Prescaler Register laden.. sbr a,1<<CLKPCE ;..Sicherheitsprozedur.. cbr a,1<CLKPS3|1<<CLKPS2|1<<CLKPS1|1<<CLKPS0;.. out CLKPR,a ;..durchfuehren.. cbr a,1<<CLKPCE ;..jetzt den Teiler.. sbr a,1<<CLKPS3 ;..neu einstellen.. out CLKPR,a ;..und ueberschreiben ; ;EXTERNAL INTERRUPT -> INT0 Low Level ist default ; in a,GIMSK ;General Interrupt Masken Register laden.. sbr a,1<<INT0 ;..INT0 Interruput Freigabebit setzen.. out GIMSK,a ;..INT0 Interrupt freigeben sei ;Alle programmierbaren Interrupts freigeben ; ;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH ;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH ;H Hauptprogrammschleife ;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH ;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH ; _main: ;sbi PINB,pin.pla ;++++++++LED-PLA toggeln f. die Systemtaktbestimmung ;rjmp PC-1 ;+++++++++++++++++++++++++++++++++++++++++++++++++++ sbr flag_reg,1<<pla.flg ;Programmlaufanzeige-Flag quitieren sbrs flag_reg,slp ;SLEEP erwuenscht? rjmp _nsleep ;Nein -> No Sleep ; ;SLEEP-MODE -> Power Down ; in a,MCUCR ;MCU Control Register laden.. sbr a,1<<SM1|1<<SE ;..Power-Down-Mode und Sleep Enable vorbereiten.. out MCUCR,a ;..und freigeben sleep ;µC in den Schlaf-Modus versetzen in a,MCUCR ;MCU Control Register laden.. cbr a,1<<SM1|1<<SE ;..PD-Mode & SE rueckgaengig.. out MCUCR,a ;..machen cbi PORTB,led.ge ;LED Gelb einschalten _nsleep: rjmp _main ;Ja -> Jetzt mit rising INT0 ;rjmp PC ;Endlosschleife ; ;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ ;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ ;Q Beginn der verwendeten Interrupt Service Routinen ( ISR ) ;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ ;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ ; .include "ISR.inc" ;Interrupt Service Routinen .EXIT ;Ende des Quelltextes |
Bin skeptisch, ob das sein kann.Als Systemtakt wird der Interne RC-Oszillator mit 4,8Mhz per FUSE BYTES ( $FF39 ) eingestellt und dieser durch 256 geteilt, was einem SYS-Takt von nominal 18,750kHz bzw. eine Zeit von 53,333µs pro Takt ergibt.
Da der µC mit 5V betrieben wird,ist natürlich der von der Fabrik kalibrierte Takt ( für 3V bei 25°C ) dermaßen daneben, dass bei mir ein SYS-Takt von 12,776kHz ( 78,272µs ) entsteht.
Tja, vermutlich wegen dem, was Du selbst zitierst:Warum wird der µC dann schon nach 10µs aus dem Power-Down-Modus geweckt?
"asynchronously" ...9.2.1 Low Level Interrupt
A low level interrupt on INT0 is detected asynchronously.
Will sagen: Das mit den Interrupts ist so eine Sache ... da muss man schon allerhand Versuche machen, denn rein aus dem Datenblatt wird man da nicht schlau (ich jedenfalls nicht). Bzw. das was passiert ist nicht unbedingt immer das, was man nach Studium des Datenblatts erwarten würde.
Hänge den AVR doch mal an ein Labornetzteil und regele die Spannung hoch/runter, während Du die Frequenz misst.
Die Frequenzstabilität war jedenfalls über den vollen Temperaturbereich genau genug, um eine Infrarot-Fernbedienung zu decodieren, ohne einen Quarz verbauen zu müssen.
Ich war bisher der Meinung, dass der RC-Oszillator an der internen Referenzspnnungsquelle hängt (könnte mich aber irren).
"asynchronously" ...
Also wenn Du einen asynchronen Interrupt verwendest, dann würde ich tatsächlich genau das erwarten, was bei Dir ja auch passiert. Nämlich dass es mit dem Takt nüschts zu tun hat.
Note that if a level triggered interrupt is used for wake-up from Power-down, the required level must be held long enough for the MCU to complete the wake-up to trigger the level interrupt. If the level disappears before the end of the Start-up Time, the MCU will still wake up, but no interrupt will be generated.
Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Machtwas« (5. März 2020, 16:47)
Ja, es geht ratzfatz, den Controiller aus dem Schlaf aufzuwecken ... aber er braucht seine Zeit, bis er sich aus dem Bett erhoben hat und "ganz da" ist.Ah, hab mir das jetzt selbst noch mal durchgelesen. Die meinen vielleicht, dass der µC geweckt wird, aber die INT0-ISR nicht angesprungen wird. Aber warum gibt es dann diese quasi "Wake-Up Zeitangabe" im DB?
Forensoftware: Burning Board® 3.1.7, entwickelt von WoltLab® GmbH