Hallo, ich versuche mich gerade daran einen Interrupt (INT0) auszulösen. Mit dem Beispielprogramm aus dem "AVR-Tutorial interrupts" komme ich in dem AVR Studio 3.56 aber nicht ganz klar. Nach dem Assemblieren versuche ich den Interrupt in einem IO-Fenster Port D 0x12 Portpin PD2 von Hand auszulösen, aber nichts passiert. Erst wenn im DDRD 0x11 den DDD2 auf 1 setze klappt das auslösen von Hand nur dass dann ja der PD2 als Ausgang geschaltet ist. So ungefähr verhält sich auch meine Schaltung da allerdings mit einem AT90S2313. Für einen Tipp was ich falsch mache, wäre ich dankbar. Gruß Olaf
AVR Studio 3.56 ist schon eine Zeit lang abgehangen und ich könnte das nur mit einem neueren AVR Studio testen (4.12 oder 4.13). Hängst du trotzdem mal deinen Quelltext an?
Es ist eigentlich ähnlich gemacht, wie im "AVR-Tutorial interrupts". das Verhalten ist bei beiden Quelltexten gleich.
So hat etwas länger gedauert. Ich hatte zuerst das falsche Target (Attiny2313 statt AT90S2313) und ein paar Probleme mit dem AVR Studio Simulator bis ich begriffen hatte wie und wann man PIND2 ändern darf (im Break). Dein Programm habe ich auf das wesentliche (INT0-Demo) abgespeckt.
1 | ; ################ |
2 | ; ### Includes ### |
3 | ; ################ |
4 | .include "2313def.inc" |
5 | ; TARGET = AT90S2313 |
6 | |
7 | ; #################### |
8 | ; ### Definitionen ### |
9 | ; #################### |
10 | .def temp =r16 |
11 | |
12 | ; ##################### |
13 | ; ### Vektortabelle ### |
14 | ; ##################### |
15 | .org 0x0000 |
16 | rjmp main ; Reset Handler |
17 | .org INT0addr |
18 | rjmp INT0_Handler ; IRQ0 Handler |
19 | |
20 | ; ##################### |
21 | ; ### Hauptprogramm ### |
22 | ; ##################### |
23 | main: |
24 | ; ######################## |
25 | ; ### Stack einrichten ### |
26 | ; ######################## |
27 | ldi temp, RAMEND |
28 | out SPL, temp |
29 | |
30 | ; ############################# |
31 | ; ### Interrupts einstellen ### |
32 | ; ############################# |
33 | |
34 | ; ISC01 (1<<1) 1 und ISC00 (1<<0) 0 |
35 | ; => FALLENDE Flanke von INT0 erzeugt Interrupt |
36 | ldi temp, 0b00000010 |
37 | ; ldi temp, 0b00000000 ; altern.: LOW an PD2 gibt INT0 |
38 | out MCUCR, temp |
39 | |
40 | ldi temp, 0b01000000 ; INT0 (1<<6) an PD2 zulassen |
41 | out GIMSK, temp |
42 | |
43 | sei ; Interrupts allgemein aktivieren |
44 | |
45 | ; ####################### |
46 | ; ### Arbeitsschleife ### |
47 | ; ####################### |
48 | loop: |
49 | rjmp loop ; loop forever |
50 | |
51 | ; ######################## |
52 | ; ### Interrupthandler ### |
53 | ; ######################## |
54 | ; ############ |
55 | ; ### Int0 ### |
56 | ; ############ |
57 | INT0_Handler: |
58 | push temp |
59 | in temp,sreg |
60 | ; hier Nutzcode einfügen |
61 | out sreg,temp |
62 | pop temp |
63 | reti |
64 | |
65 | ; Simulation in AVR Studio |
66 | ; |
67 | ; Der Interrupt bei fallender Flanke tritt auf, |
68 | ; wenn PIND2 auf HIGH gesetzt war und im Break |
69 | ; auf LOW gesetzt wird. |
70 | ; |
71 | ; 1/ Breakpoint auf "push temp" in INT0_Handler |
72 | ; 2/ Run (F5) |
73 | ; 3/ Break (Strg-F5) |
74 | ; 4/ PIND2 ändern in Fenster I/O-View |
75 | ; 1/ ... |
76 | ; |
77 | ; ENDE |
Hallo Stefan, vielen Dank für Deine Hilfe, aber mein eigentliches Problem ist offenbar nicht ganz deutlich geworden, ich habe mich wohl missverständlich ausgerückt. Das Problem besteht weniger darin, dass ich mit der Konfiguration des Interuts oder des Simulators nicht klar komme. Der Portpin scheint das Problem zu sein. Konfiguriere ich ihn als Eingang ldi temp, 0b11111011 out DDRD, temp dann reagiert er nicht, weder im Simulator noch in der Schaltung. Konfiguriere ich ihn als Ausgang ldi temp, 0b11111111 out DDRD, temp dann funktioniert es zwar im Simulator, aber in der Schaltung bedeutet das für den angeschlossenen Temperatursensor SMT 160-30 quasie ein Kurzschluss und ein Interrupt wird schon gar nicht ausgelöst. Ich habe schon alles (mir) mögliche ausprobiert, aber alles ohne Erfolg. Gruß Olaf
Der Simulator kann keine externen Ereignisse erkennen, die must Du also manuell auslösen. Die Hardware in Deinem Fall wird nur funktionieren, wenn der Interruptpin als Eingang geschaltet ist. Warum probierst Du das Programm nicht auf dem Controller selbst? Schalte in der Interruptservice-Routine eine LED an / aus.
ja richtig alle Deine Vorschläge habe ich schon ausprobiert, ohne Erfolg. Wenn ich Port D Pin 2 (0x12 bit 2), bei auf Eingang (0x11 bit 2 auf 0) konfigurierten DDRD, im Simulator hin und her schalte wird kein Interrupt ausgelöst. Die Sache mit der LED im INT0_Handler habe ich auch schon probiert, es verhält sich wie oben beschrieben. Gruß Olaf
Ich kenne zwar Deinen Sensor nicht, vermute aber, dass er einen open-Collector (open-Drain)-Ausgang hat, da brauchst Du einen PullUp-Widerstand. Oder bringt der Sensor selbst L- und H-Pegel? Wenn Du den internen PullUp nutzen willst, dann muss DDR auf 0 (Eingang) und PORT auf 1 (PullUp ein). ...
Ich hatte auch schon einen Schalter am PD2 angeschlossen, aber der SMT160 ist TTL/CMOS- kompatibel. Ich verstehe das nicht, es ist ja letzlich die gleiche Situation wie im AVR-Tutorial interrupts, das haben doch bestimmt schon viele Leute ausprobiert. Also muss der Fehler doch in meinem Aufbau/Programm liegen. Gruß Olaf
Abgesehen davon, Du benutzt einen Tiny2313, richtig? Nicht etwa einen 90S2313? Noch ein Gedanke: der Sensor spuckt eine Rechteckfrequenz mit variablem Tastverhältnis aus. Wäre es in dem Fall nicht besser, den Input Capture Interrupt zu benutzen? Das würde die Zeitmessung erheblich vereinfachen.
Noch etwas: es hat sich allgemeinhin als sinnvoll erwiesen, eine komplette Interrupt-Vektorentabelle an den Anfang des Codes zu stellen (anstatt einzelner .org-Segmente) und das eigentliche Programm immer nach den Interruptvektoren anfangen zu lassen. Somit können versehentlich aktivierte und ausgelöste Interrupts abgefangen werden, die ansonsten ein Chaos beim Einspringen in durch Programmcode belegte Vektoren anrichten könnten.
Doch es ist der 90S2313 gibt es mit dem ein Problem? Natürlich kann ich das auch anders machen, das werde ich auch sicher irgendwann, wenn ich mich erst mal richtig in die AVR´s eingearbeitet habe. Aber ich werde sicher wieder auf das Problem stoßen einen Interrupt auslösen zu müssen, und dann fange ich wieder an dieser Stelle an. Das ist sicher auch ein persönliches Problem, wenn ich mich erst mal an einer Sache festgebissen habe, dann kann ich nicht mehr loslassen. Gruß Olaf
Das kenne ich. Nein es gibt keine Probleme mit dem 90S2313, zumindest dort nicht. Es sollte gehen. Allerdings solltest Du das temp, in das Du das SREG gesichert hast, noch auf den Stack schreiben, sonst kannst Du es in der gesamten ISR nicht mehr verwenden. Hast Du denn jetzt auf dem Controller von Hand schon einen Interrupt ausgelöst? Wie sieht die Portregisterdefinition aus? Poste doch mal das Gesamtprogramm!
Nein, das ist ja das Problem, ich kriege den Interrupt nicht ausgelöst. An dem Quellcode habe ich noch nichts geändert (Posting gestern 16:08). Zur Sicherheit habe ich noch mal den eigentlich bekanntetn Schaltplan dran gehängt, den SMT160 bzw. einen Schalter gegen Masse mit PullUp kann man sich sicher leicht dazudenken. Hilfreich wäre ja auch ein Projekt, in dem die Sache mit einem Interrupt in der AVR-Basicline schon mal umgesetzt wurde und nachweislich funktioniert hat, ich habe noch nichts passendes gefunden. Gruß Olaf
Ich hatte mir Dein Programm gestern schonmal kurz angesehen, hatte es aber gleich wieder geschlossen, weil es sehr schwer lesbar ist. Da passen die Kommentare nicht zu dem Code, da werden Bits nicht beim Namen genannt, sondern als kryptische Binärzahlen. Da fehlte mir echt die Lust, wegen jedem Bit im Datenblatt nachzuschauen, was denn nun gemeint ist. Dazu kommt dann noch die Art der Interrupt-Vektoren und der unverständliche Unsinn in der Mainloop. Da aber zur Zeit einige Leute darüber meckern, wie hier Anfänger behandelt werden, habe ich mich mit der Kritik erstmal zurückgehalten. Du fragst nach einem Programmcode, der im 2313 mit externem Interrupt arbeitet. Hier ist einer, der macht aber nicht das, was Du brauchst: http://www.hanneslux.de/avr/mobau/impdecoder/idec2313.asm Die Beschreibung dazu ist hier: http://www.hanneslux.de/avr/mobau/impdecoder/idec.html Nun zur Aufgabe, die Du erledigen willst... Du willst eine Impulsbreite mit einem externen Interrupt messen, also ein Software-ICP. Du hast in Deinem Programmentwurf in Main Int0 auf fallende Flanke eingestellt (MCUCR). Um eine Impulsbreite zu messen, brauchst Du aber beide Flanken. Du musst in der ISR die Flanke umschalten. Hier ist eine Impulsbreitenmessung mit ext.-Int für Tiny15: http://www.hanneslux.de/avr/mobau/fr_t15/T15frb01.asm mit Beschreibung http://www.hanneslux.de/avr/mobau/fr_t15/fr_t15.html und hier http://www.hanneslux.de/avr/index.html noch ein paar andere Beispiele. Hier http://www.hanneslux.de/avr/pollin_ir8/index.html findest Du eine Impulsbreitenmessung im Tiny2313, die mit ext.-Int arbeitet. Da ist auch zu sehen, wie ich jetzt die Int-Vektoren anordne. Zum Analysieren Deines Quelltextes bis ins Detail fehlt mir aufgrund der kryptischen Bitnamen immernoch die Lust, sorry. ...
Der Interrupt funktioniert mit Sicherheit. Hast Du den Spannungswechsel an PD2 mal mit einem Multimeter gemessen, ob Du tatsächlich Low erreichst?
@ Oilaf Was du mit DDRD rummachst, verstehe ich nicht. Hier die Erweiterung zum Toggeln der LED an PB0 aus deinem Schaltbild, wenn ein INT0 (Fallende Flanke: PD2 wechselt von HIGH auf LOW) auftritt.
1 | ; ################ |
2 | ; ### Includes ### |
3 | ; ################ |
4 | .include "2313def.inc" |
5 | ; TARGET = AT90S2313 |
6 | |
7 | ; #################### |
8 | ; ### Definitionen ### |
9 | ; #################### |
10 | .def temp =r16 |
11 | .def temp2 =r17 |
12 | |
13 | ; ##################### |
14 | ; ### Vektortabelle ### |
15 | ; ##################### |
16 | .org 0x0000 |
17 | rjmp main ; Reset Handler |
18 | .org INT0addr |
19 | rjmp INT0_Handler ; IRQ0 Handler |
20 | |
21 | ; ##################### |
22 | ; ### Hauptprogramm ### |
23 | ; ##################### |
24 | main: |
25 | ; ######################## |
26 | ; ### Stack einrichten ### |
27 | ; ######################## |
28 | ldi temp, RAMEND |
29 | out SPL, temp |
30 | |
31 | ; ############################################ |
32 | ; ### LOW ACTIVE LED an PB0 initialisieren ### |
33 | ; ############################################ |
34 | ; Toggelt später in INT0_Handler |
35 | ldi temp, 0b00000000 ; PB0 LOW (LED_AN) |
36 | out PORTB, temp |
37 | ldi temp, 0b00000001 ; PB0 Ausgang |
38 | out DDRB, temp |
39 | |
40 | ; ############################# |
41 | ; ### Interrupts einstellen ### |
42 | ; ############################# |
43 | |
44 | ; ISC01 (1<<1) 1 und ISC00 (1<<0) 0 |
45 | ; => FALLENDE Flanke von INT0 erzeugt Interrupt |
46 | ldi temp, 0b00000010 |
47 | ; ldi temp, 0b00000000 ; altern.: LOW an PD2 gibt INT0 |
48 | out MCUCR, temp |
49 | |
50 | ldi temp, 0b01000000 ; INT0 (1<<6) an PD2 zulassen |
51 | out GIMSK, temp |
52 | |
53 | sei ; Interrupts allgemein aktivieren |
54 | |
55 | ; ####################### |
56 | ; ### Arbeitsschleife ### |
57 | ; ####################### |
58 | loop: |
59 | rjmp loop ; loop forever |
60 | |
61 | ; ######################## |
62 | ; ### Interrupthandler ### |
63 | ; ######################## |
64 | ; ############ |
65 | ; ### Int0 ### |
66 | ; ############ |
67 | INT0_Handler: |
68 | push temp |
69 | in temp,sreg |
70 | ; Anfang Nutzcode |
71 | ; => PB0 toggeln |
72 | push temp |
73 | push temp2 |
74 | ldi temp2, 0b00000001 |
75 | in temp, PORTB |
76 | eor temp, temp2 |
77 | out PORTB, temp |
78 | pop temp2 |
79 | pop temp |
80 | ; Ende Nutzcode |
81 | out sreg,temp |
82 | pop temp |
83 | reti |
84 | |
85 | ; Simulation in AVR Studio |
86 | ; |
87 | ; !/ Keine Breakpoints |
88 | ; 2/ Auto-Step (ALT-F5) |
89 | ; 3/ PIND2 manipulieren und PORTB0 beobachten |
90 | ; PORTB0 toggelt, wenn PIND2 von HIGH => LOW wechselt |
91 | ;. |
92 | ; ENDE |
Anschluss eines Schalters an PD2:
1 | ^ Vcc +5V |
2 | | |
3 | | |
4 | +-+ |
5 | | | Pull-Up |
6 | | | 10K |
7 | +-+ |
8 | | |
9 | | |
10 | +--------+ PD2 |
11 | | |
12 | | | |
13 | L + + H (bei PD2) |
14 | / |
15 | / |
16 | / Schalter |
17 | + |
18 | | |
19 | | |
20 | --- GND |
Erstmal vielen Dank für die Hilfe, ich will Euch auch nicht zu sehr nerven. @ Hannes Lux, da gebe ich Dir Recht, übersichtlich ist der Quelltext nicht gerade. Das liegt daran, dass ich in den Programmen immer viel ausprobiere und nach dem Ausprobieren nicht immer alles lösche. Ich habe sicher nicht so einen ganz profesionellen Programmierstil. Ich werde mir Deine Beispiele mal in Ruhe ansehen. Vielen Dank @ Travel Rec.Ich schwöre, mit Oszilloskop direkt am Beinchen gemessen. @ Stefan, ich probier deinen Quellcod nochmal aus, merkwürdig finde ich nur, dass das Verhalten im Simulator (AVR Studio 3.56) das Verhalten in der Hardware wiederspiegelt. Gruß Olaf
AVR-Studio 3.5x nimmt Niemand mehr, Du solltest aus Gründen der Kompatiblität mit den Helfenden auf AVR-Studio 4.xx updaten. Es muss ja nicht immer die allerneueste Version sein, aber zwischen 3.5x und 4.xx hat sich allerhand geändert. ...
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.