Hallo,
ich habe ein Problem mit einem Atmega 168. Es wird die ISR vom INT0
nicht ausgeführt.
Zu dem Program. Das Program soll über ISR auf 2 Sachen reagieren.
1.An der RS232 Zeichen empfangen und reagieren --> funktioniert
2.An INT0 PD2 Pin4 vom Mega auf eine Flanke reagieren die im
Sekundentakt
anliegt. Das funktioniert nicht!!!!!
Das ganze Program soll bzw ist ein Temperaturlogger mit Echtzeituhr.
Dieses läuft schon auf einen Atmega8. Aber wegen des Platzmangels
(8kByte)
hab ich das Program jetzt auf einen Atmega168 umgeschrieben. Alle
anderen Funktionen ( twi, Pin´s schalten/lesen ) funktionieren.
Am INT0 liegt der Takt von der Echtzeituhr. Bei einer Flanke soll dann
das Datum und Uhrzeit ausgelesen werden und mit der eingelesenen
Temperatur
vom LM75 im EEprom 24C32 abgespeichert werden. Über die RS232 wird dann
mit bestimmten Zeichen/Befehlen das EEprom ( Uhrzeit mit Temp-Werten )
ausgelesen und an der RS232 ausgegeben zur weiteren Verarbeitung.
Das war es im groben. Das Program im Anhang wurde von mir stark gekürzt,
damit es übersichtlicher wird ( Aufruf von Funktionen / Auswertung
RS232,...)
Also bitte nicht an bestimmten Aufrufen stören lassen.
Ja mein Programmierstil lässt sehr zu wünschen übrig.
Wäre aber trotzdem sehr dankbar wenn mir einer den Fehler zeigt bzw
auch andere Tips gibt!!!
Hab die Funktion die den Interrupt für den INT0 einstellt vergessen:
sek_int_ein:
push temp
ldi temp,0b00000010 ; falling edge of INT0 generates ;
an interrupt request
sts EICRA,temp
; ldi temp,0b00000001 ; External interrupt request 0 ;
enable
ldi temp,0b00000001
;external interrupt request 0 enable
sts EIMSK,temp
pop temp
ret
Gruß patt
> ldi temp,0b00000010 ; falling edge of INT0 generates> ; an interrupt request> sts EICRA,temp
Schätzfrage: Wieviele Leute werden wohl Lust darauf haben, das
Datenblatt hervorzuholen, um darin das richtige Kapitel zu suchen, um
dort nachzuschauen zu können, ob 0b00000010 jetzt die richtigen Bits
einschaltet oder nicht?
>bzw auch andere Tips gibt!!!
Gerne, hier Deiner erster: Benutze Bitnamen. Dazu sind sie da.
1
; falling edge of INT0 generates an interrupt request
Was ist falsch an
.org INT0addr
richtig. Gar nix. Ich such mir jetzt nicht das Datenblatt raus um
nachzusehen, ob der Interrupt tatsächlich an 0x0002 liegt. Wenn du
INT0addr benutzen würdest, und diese Konstante vom Assembler als 'jawohl
existiert' bestätigt wird, brauch ich nix nachsehen. Der INterrupt
Vektor liegt dann genau dort wo er hingehört
Auch
1
int_rxc:
2
3
cli ; alle Interrupts sperren
4
5
6
....
7
8
sei ; alle Interrupts wieder freigeben
9
10
reti
Wozu soll das gut sein? Interrupts sind sowieso in einer ISR gesperrt.
Daher gibt es ja auch einen reti, der im Grunde nix anderes ist, als ein
ret mit einem nachfolgenden sei.
Ganz im Gegenteil: indem du selbst in der ISR noch einen cli, ganz
speziell aber einen sei machst, kannst du dir Fehler einhandeln. Die
Interrupts werden dann ein kleines bischen zu früh freigegeben und wenn
du Pech hast und die Interrupts nur häufig genug kommen, dann schachteln
sich die ISR Aufrufe auf dem Stack ineinenader, bis der Stack übergeht.
Aber:
Ich vermisse zb, wo du den Interrupt Pin auf Eingang einstellst?
Hallo,
erstmal Danke für eure Tips. So wie ich das verstehe, steht eigentlich
kein Fehler in dem Teil. --> Ich muß was übersehen bzw was vergessen
haben.
Werd vielleicht mal ein kleines Prog machen, was NUR auf den INT0
reagiert
und dort versuchen den INT zum laufen zu bewegen.
; rjmp int_int0 ; Interruptvektor für Int0== $002 ;
External Interrupt Request 0
.org 0x0002 jmp int_int0
;.org URXCaddr ; Interruptvektor für
UART-Empfang
; rjmp int_rxc
.org 0x0024 jmp int_rxc
Ich habe die Namen int_int0 nur durch HEX-Werte ersetzt damit ich sehen
kann ob dort der Fehler liegt. War nur als Test gedacht.
Das mit dem cli und dem sei in der SEI hab ich mal von jemandem
abgeschrieben
und bis jetzt einfach per copy and paste wiederverwendet. Muß aber auch
gestehen, dass ich mir dazu keine großartigen Gedanken gemacht habe :-(
Leuchtet aber ein und wie!!!!!!! --> wird geändert.
--> Aber:
Ich vermisse zb, wo du den Interrupt Pin auf Eingang einstellst?
tja da sagt jemand was. Das muß ich kontrollieren, ABER ich habe den Pin
nicht auf Ausgang geschalten und das Signal liegt ja am PIN an. -->
sollte richtig stehen, werd ich aber kontrollieren.
Hat jemand ein kurzes Bsp-Programm in Assembler was den INT0 mit ISR
bearbeitet??? Oder jemand noch eine Idee was falsch sein könnte.
Danke für eure Hilfe/Antworten.
Gruß patt
Hi
>Hat jemand ein kurzes Bsp-Programm in Assembler was den INT0 mit ISR>bearbeitet??? Oder jemand noch eine Idee was falsch sein könnte.
Anhang sollte funktionieren.
MfG Spess
Hallo,
Danke, das Bsp werd ich späte bzw am WE gleich mal testen.
Was mir beim anschauen als erstes aufgefallen ist.
Du beschreibst das Register EIFR-->
ldi r16,$00 ;INTF1,INTF0
out EIFR,r16
War eigentlich der Meinung, dass man das EIFR external Interrupt flag
register für den Interrupt bei INT0 bzw INT1 nicht benötigt bzw das
nur ein Register ist in dem man nachschauen kann ob ein Interrupt
aufgetreten
ist. Das werd ich aber sicher testen.
Danke.
Gruß patt
Hi
>War eigentlich der Meinung, dass man das EIFR external Interrupt flag>register für den Interrupt bei INT0 bzw INT1 nicht benötigt bzw das>nur ein Register ist in dem man nachschauen kann ob ein Interrupt>aufgetreten>ist.
Mach dir keine Gedanken. Ich habe mir mal ein Programm geschrieben das
mir diesen Code (IR-Tabellen, Initialisierung ...) generiert. Die beiden
Zeilen habe ich nur vergessen zu löschen.
MfG Spess
>EICRA liegt bei Adresse 0x69 und muss deshalb mit lds/sts angesprochen werden.
Ja, stimmt. Mein Fehler, sorry! "sts EICRA, temp" ist korrekt. Man kommt
ja ganz durcheinander...
Diese beiden Varianten sind richtig:
Hi
>Geht mir auch immer so... ;-) Das Datenblatt beseitigt dann die letzten>Zweifel.
Einfach erst mal mit in/out probieren. Wenn es nicht geht, meckert der
Assembler. Umgedreht allerdings nicht.
MfG Spess
Hallo,
Danke, das wars!!!!
Ich hab beim umbschreiben des Code vom Atmega8 zum 168 "jedes" out und
in
in ein sts und lds umgeschrieben. Das Register EIMSK liegt im unteren
Speicherraum --> Verwendung von out statt sts. War irgendwie der
Meinung,
dass er Fehler bringt wenn ich was "falsch" verwende, wie er es eben
auch
mit out macht wenn man sts verwenden muß. Naja, das ganze fällt unter
Erfahrungswerte.
Danke für Eure Hilfe und Tips!!!!
Jetzt freu ich mich über MEHR Speicher und ein paar schöne Features.
Gruß patt
Hi
> War irgendwie der Meinung,>dass er Fehler bringt wenn ich was "falsch" verwende, wie er es eben>auch mit out macht wenn man sts verwenden muß
Nein, warum auch. EIMSK ist in der m168def.inc definiert mit:
.equ EIMSK = 0x1d
Beim Assemblieren wird nur überprüft, ob die einem Befehl übergebenen
Argumente im zulässigen Bereich liegen. Und $1D ist für 'sts' zulässig.
MfG Spess