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
Gast
#2442066
> 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 | |
2 | |
3 | |
Zahlenfetischist?
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
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 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
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?
Gast
#2442567
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
Gast
#2442659
Der Fehler liegt in den Zeilen > sts EIMSK, temp > sts EICRA, temp Damit beschreibst Du falsche Registeradressen. Richtig wäre:
1 | |
oder
1 | |
und für "sts EICRA, temp" analog. Lies die Erläuterungen dazu im Datenblatt, Kapitel I/O-Memory.
Vuvuzelatus schrieb: > und für "sts EICRA, temp" analog. Falsch. EICRA liegt bei Adresse 0x69 und muss deshalb mit lds/sts angesprochen werden.
Gast
#2442868
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
Gast
#2442907
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
Gast
#2443015
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
Gast
#2443016
>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:
1 | |
2 | |
3 | |
4 | |
5 | |
oder
1 | |
2 | |
3 | |
4 | |
5 | |
Vuvuzelatus schrieb: > Man kommt > ja ganz durcheinander... Geht mir auch immer so... ;-) Das Datenblatt beseitigt dann die letzten Zweifel.
Gast
#2443047
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
Ja, auch immer wieder gerne genommen ;-)
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
Gast
#2443444
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
Gast
#2457760
Hallo, da macht das programmieren gleich wieder mehr Spaß. 8kByte mehr Platz ;-) Danke! Gruß patt
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.