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