Guten Abend,
habe leider seit geraumer Zeit nix mehr mit AVR`s gemacht --> dank
meinem Kurzzeitgedächnis steh ich jetzt da wie bestellt und nicht
abgeholt.
Mein Atmega 16 springt nicht in die Interruptroutine Timer0 OVF!
Könnte mal jemand mir unter die Arme greifen --> weiß jetzt schon, das
der Fehler zu einem Anfänger (der ich eigentlich nicht bin) passt!!!
Thanks @ all
Thanks für die Antwort.
Dumm ist nur das der Atmega jetzt immer noch nicht in den Interrupt
springt!
Werd noch irre! Wo habe ich Mist gebaut?
Liegt es am AVR Studio 4???
Woran merkst du das denn? So wie es in deinem angehängten Code steht,
führt die Interrupt-Routine nur zwei NOPs aus und fällt dann hinten
raus, da kein RETI vorhanden ist.
Weiterhin:
> ldi WorkH,-Time ; lade Arbeitsregister mit 40
Wie kommst du auf 40? Time ist 80, damit ist -Time -80 bzw. 176.
> ldi WorkH, 2 ;> out TIMSK,WorkH ;
Ok, die erste Zeile ist also dasselbe wie:
ldi WorkH, (1 << TOIE1)
(Warum schreibt das nur keiner so hin, damit man nicht erst im
Datenblatt die Bits auseinanderfummeln muß)
Aber warum schaltest du den Timer1-Interrupt ein, wenn du doch Timer0
willst?
Guten Morgen,
sorry für die späte Antwort --> hatte viel um die Ohren.
@Rolf Magnus
> ldi WorkH,-Time ; lade Arbeitsregister mit 40
das ist natürlich falsch --> mein Fehler!
> Wie kommst du auf 40? Time ist 80, damit ist -Time -80 bzw. 176.
wie ich auf 40 komme --> massiver Denkfehler nach Nachtschicht.
Ah wie kommst auf "Time ist 80"????
ldi (lade) WorkH (R17 mit Inhalt hex FF) mit -40 --> das gibt bei mir
hex FF (dez 255) - hex 28 (dez 40) = hex D7 (dez 215) --> AVR-Stubdio
sagt aber hex D8 (dez. 216) --> warum???
ldi WorkH, (1 << TOIE1) --> ist mir bekannt --> wollte ein Programm aus
einem Buch 1zu1 übernehmen --> warum siehe unten!
>Aber warum schaltest du den Timer1-Interrupt ein, wenn du doch >Timer0
willst?
Kann ich ehrlich gesagt nicht folgen???
P.S. es dreht sich um ein namhaftes AVR-Buch --> in einem Programm sagt
der Autor "dieses PWM ist besser, da pro Periode 5 PWM-Zyklen gefahren
werden???
Das kapier ich nicht --> ein PWM-Zyklus ist 1x High und 1x Low und
somit eine Periode?! Wenn er 5 PWM-Zyklen fährt hat er in meinen Augen
nur die die 5fache Frequenz???
P.P.S werde mal die Initialisierung des Timers unter die Lupe nehmen
--> da liegt der Fehler in meinen Augen!
Sorry
>Woran merkst du das denn? So wie es in deinem angehängten Code>steht,>führt die Interrupt-Routine nur zwei NOPs aus und fällt dann hinten>raus, da kein RETI vorhanden ist.
Woran ich das merke --> AVR-Studio springt den Interrupt nicht an,
sondern springt irgendwo in das Programm!
Die Routine führt nur 2 nops aus, und??? Mir geht es darum das
AVR-Studio überhaupt in die Timer_OVF Routine springt --> was da drin
steht ist im Moment egal.
Das kein reti drin steht ist auch klar!
Deine Interrupt-Sprungtabelle stimmt nicht.
Da der Mega16 im Flash 8k Adressraum hat, reicht rjmp nicht mehr
überall hin (nur -2k bis +2k). Deshalb sind in der Vektortabelle
jeweils 2 Adresse pro Sprung vorgesehen, damit man den Befehl jmp
benutzen kann, der nunmal 2 Worte lang ist.
Ich bin auch ein Freund davon, die gesamte Sprungtabelle aufzulisten,
weiß aber, dass es mit .org auch anders geht (Jede Variante hat ihre
Vorteile und Nachteile). Bei mir sieht die Sprungtabelle dann so aus:
.include"m16def.inc"
.cseg
.org 0 ;Reset- und Interrupt-Vektoren AT-Mega 16
jmp RESET ;Reset Handler
jmp nix ;EXT_INT0 ;IRQ0 Handler
jmp nix ;EXT_INT1 ;IRQ1 Handler
jmp nix ;TIM2_COMP ;Timer2 Compare Handler
jmp nix ;TIM2_OVF ;Timer2 Overflow Handler
jmp nix ;TIM1_CAPT ;Timer1 Capture Handler
jmp nix ;TIM1_COMPA ;Timer1 CompareA Handler
jmp nix ;TIM1_COMPB ;Timer1 CompareB Handler
jmp nix ;TIM1_OVF ;Timer1 Overflow Handler
jmp nix ;TIM0_OVF ;Timer0 Overflow Handler
jmp nix ;SPI_STC ;SPI Transfer Complete Handler
jmp nix ;USART_RXC ;USA RT RX Complete Handler
jmp nix ;USART_UDRE ;UDR Empty Handler
jmp nix ;USART_TXC ;USART TX Complete Handler
jmp nix ;ADC ;ADC Conversion Complete Handler
jmp nix ;EE_RDY ;EEPROM Ready Handler
jmp nix ;ANA_COMP ;Analog Comparator Handler
jmp nix ;TWSI ;Two-wire Serial Interface Handler
jmp nix ;EXT_INT2 ;IRQ2 Handler
jmp nix ;TIM0_COMP ;Timer0 Compare Handler
jmp nix ;SPM_RDY ;Store Program Memory Ready Handler
nix: ;Interrupt nicht genutzt
reti ;zurück...
;
reset:
Bei den dann benutzten Interrupts wird das "nix ;" entfernt und die
ISR geschrieben.
Der Einfachheit halber führe ich eine Textdatei, in der die
Sprungtabellen aller bisher von mir benutzten AVRs aufgelistet sind.
Die Tabellen selbst sind aus dem jeweiligen Datenblatt herauskopiert
und an meinen Stil angepasst.
...
Deine Sprungtabelle funktioniert bei einem Mega8. Da der 16er mehr
Speicher hat, sind mehr bytes in der Tabelle reserviert. Um einen
Sprungvektor zu übergehen sind deshalb 2 Befehle nötig:
.org $000
rjmp Reset ; Springe zur Initialisierung
reti
nop
reti
nop
reti
nop
reti
nop
reti
nop
reti
nop
reti
nop
reti
nop
rjmp Timer0_OVF
Funktioniert bei mir jedenfalls prima.
> ldi (lade) WorkH (R17 mit Inhalt hex FF) mit -40 -->> das gibt bei mir hex FF (dez 255) - hex 28 (dez 40) = hex D7#> (dez 215) --> AVR-Stubdio sagt aber hex D8 (dez. 216) --> warum???
weil -40 im Zweierkomplement hex D8 ist.
Hinweis: hex FF ist bereits -1
d.h. FF - 28 ist im 10-er System -1 - 40 -> -41
>> Aber warum schaltest du den Timer1-Interrupt ein, wenn du doch>> Timer0 willst?>> Kann ich ehrlich gesagt nicht folgen???
Hier:
ldi WorkH, 2 ;
out TIMSK,WorkH ;
Wenn Du in TIMSK eine 2 setzt, dann aktivierst Du Timer 0 im
Output compare Match Interrupt (und nicht wie Rolf
faelschlicherweise gesagt hat: Timer 1 im Overflow).
Wenn ich das richtig sehe, dann moechtest Du aber den
Overflow Interrupt vom Timer 0
Schreibs doch so:
ldi WorkH, (1 << TOIE0)
out TIMSK, WorkH
und lass den Assembler die Zahl ausrechnen. So sieht man sehr
schoen was Du ueberhaupt einschalten willst, ohne das man
das Bit-Gepfrimel selbst machen muss.