Forum: Mikrocontroller und Digitale Elektronik Atmega 16 Interrups


von Harry (Gast)


Angehängte Dateien:

Lesenswert?

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

von Hubert G. (huvogs)


Lesenswert?

.org 0x000
vor dem rjmp RESET

von Harry (Gast)


Lesenswert?

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???

von Rolf Magnus (Gast)


Lesenswert?

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?

von Harry (Gast)


Lesenswert?

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!

von Harry (Gast)


Lesenswert?

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!

von Hannes L. (hannes)


Lesenswert?

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.

...

von Thomas Forster (Gast)


Lesenswert?

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.

von Hannes L. (hannes)


Lesenswert?

So geht's natürlich auch, ist mir aber aufgrund fehlender Kommentare zu
unübersichtlich...

...

von Karl H. (kbuchegg)


Lesenswert?

> 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.

von Conlost (Gast)


Lesenswert?

Hallo,

ich hatte dieses Problem mit dem ATmega16 auch schon mal
und seitdem schreibe ich das nun immer so:

.org $0000

; ***** INTERRUPT VECTORS *********************************
rjmp reset             ; Reset Handler
;.org INT0addr   ;= 0x0002  ; External Interrupt Request 0
;.org INT1addr   ;= 0x0004  ; External Interrupt Request 1
;.org OC2addr    ;= 0x0006  ; Timer/Counter2 Compare Match
;.org OVF2add    ;= 0x0008  ; Timer/Counter2 Overflow
;.org ICP1addr   ;= 0x000a  ; Timer/Counter1 Capture Event
;.org OC1Aaddr   ;= 0x000c  ; Timer/Counter1 Compare Match A
;.org OC1Baddr   ;= 0x000e  ; Timer/Counter1 Compare Match B
;.org OVF1addr   ;= 0x0010  ; Timer/Counter1 Overflow

.org OVF0addr   ;= 0x0012  ; Timer/Counter0 Overflow
rjmp timer0

;.org SPIaddr    ;= 0x0014  ; Serial Transfer Complete
;.org URXCaddr   ;= 0x0016  ; USART, Rx Complete
;.org UDREaddr   ;= 0x0018  ; USART Data Register Empty
;.org UTXCaddr   ;= 0x001a  ; USART, Tx Complete
;.org ADCCaddr   ;= 0x001c  ; ADC Conversion Complete
;.org ERDYaddr   ;= 0x001e  ; EEPROM Ready
;.org ACIaddr    ;= 0x0020  ; Analog Comparator
;.org TWIaddr    ;= 0x0022  ; 2-wire Serial Interface
;.org INT2addr   ;= 0x0024  ; External Interrupt Request 2
;.org OC0addr    ;= 0x0026  ; Timer/Counter0 Compare Match
;.org SPMRaddr   ;= 0x0028  ; Store Program Memory Ready

reset:
usw. usw.

Es grüsst,
Arno

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
Noch kein Account? Hier anmelden.