Hallo.
Ich mache grad meine ersten Schritte in der Assembler-Programmierung und
hab da mal ne Frage zur Simulation im AVR-Studio 4.13:
Ich wollte mittels Taster einen ext.Interrupt erzeugen. Die
entsprechenden Festlegungen in den Registern MCUCR, GIMSK hab ich
festgelegt.
Das Problem:
Während der Simulation setze ich manuell das Häckchen für den zu
drückenden Taster, der ja den Interrupt auslösen soll - aber nichts
passiert!!
Erst wenn ich zusätzlich in der I/O View unter ext.Interrupts bei GIFR
das INTF0-Bit setze funktionierts...
Hab ich was vergessen, oder muss das so sein??????
Für Antworten vielen Dank im voraus.
Setzt du den Haken im PIN-Register oder im Portregister?
Ich würde mal den Haken im PINx Register setzen/löschen. Dan sollte der
IRQ theoretisch ausgelöst werden. Wie ist eigentlich die IRQ-Sense
definiert? (Steigende Flanke, fallende Flanke, Level, oder PinChange?)
Moin.
Wenn ich in der I/O-View meinen Port erweitere, sehe ich unten 3
Reihen(PortB DDRB PinB). Die Markierung setze ich dann in der
PinB-Reihe (an dem dafür vorgesehen Bit).
In MCUCR hab ich ne fallende Flanke eingestellt. Wobei der Interrupt
auch nicht auslöst beim Wegnehmen der Markierung. Erst wenn ich ihn
zwinge (Markierung des Flags in GIFR setzen) löst er den Int. aus.
"SEI" steht bei mir nach der Festlegung von MCUCR, etc.
???
Ich stelle mir jetzt die Frage, woher er wissen soll, dass ich mit dem
expliziten Bit in PinB einen Interrupt auslösen möchte.
Könnte ich da noch ne Vereinbarung vergessen haben?
Oder sagt er sich, ich lös mal nen Int. aus, egal welcher Eingang sich
ändert... Aber wie unterscheidet er dann zwischen INT0 und INT1 ?
So, hab nochmal in meinen Tutorials gesucht und bin dabei auf PD2 und
PD3 gestoßen. Habe meine Eingänge aber eigentlich auf B liegen - wenn
ich jetzt in der Simulation in D die Bits 2/3 markiere, dann wird Int.
ausgelöst!!!
Da merkt man halt, dass ich blutiger Anfänger bin...
ALLERDINGS funktioniert das Auslösen des Interrupts dann nur über
PortD?!?!
Gibt es keine Möglichkeit, das über einen anderen Port zu machen???
Man ist da doch sehr eingeschränkt...
>>> für den zu drückenden Taster, der ja den Interrupt auslösen soll
Treten wir hier einfach mal einen Schritt zurück und halten fest:
Es ist grundsätzlich eine schlechte Idee, mechanische Schalter und
Kontakte auf einen Interrupt zu legen. Die Dinger prellen, und du hast
im Nu 20 Interrupts für einen Tastendruck... :-/
> Da merkt man halt, dass ich blutiger Anfänger bin...
Ja, so ist es. Wenn du etwas weiter bist, wirst du für solche Aufgaben
sowieso eine Entprellfunktion verwenden. Bei Tastern kommt es ja idR.
nicht auf die Mikrosekunde an. Wichtiger ist, das 1 Tastendruck genau 1
Aktion auslöst.
Frank schrieb:> ALLERDINGS funktioniert das Auslösen des Interrupts dann nur über> PortD?!?!
An dieser Stelle wird es Zeit, dein Programm zu sehen um rauszufinden,
was genau du machst.
> Gibt es keine Möglichkeit, das über einen anderen Port zu machen???> Man ist da doch sehr eingeschränkt...
Wie Lothar schon sagte: Für Tasten gibt es bessere Methoden als einen
Interrupt.
Das man Tasten entprellen muss, hab ich schon gehört - sollte hier jetzt
aber noch keine Rolle spielen.
Das Prog hat eigentlich ganz simple Fkt.
(4-Bit blinkendes Lauflicht)
Ist halt mein Einstieg in die Assemblerprogrammierung und wurde Stück
für Stück erweitert.
Ist jetzt ein bissl umgeschrieben - so das in der Endlosschleife nicht
nur geblinkt, sondern auch der Taster abgefragt wird. Den
Interrupt-Handler hab ich drin gelassen. Wahrscheinlich sind par Sachen
unschlüssig, da ich viel rumprobiere...
Hab festgestellt, dass ich ziemliche Probleme mit dem "Zeitgefühl" habe.
Im Simulator dauern Warteschleifen, in denen er eben auf Eingaben nicht
reagiert, immer ewig. In Wahrheit geht es ja schneller, das muss erst
noch in mein Köpfchen rein...
Nichtsdestotrotz sollte ich mich eh mit Interrupts beschäftigen - daher
bleibt die Frage: Ext. Int. sind nur über Bit 2/3 vom PortD möglich und
nicht auf andere Ports anwendbar???
Desweiteren soll ich mich auch noch in Programmierung von Timer,
Sleep-Modes, Watchdogs, Entprellung, I2C einlesen...
Also wenn jemand gute Einsteigerlektüre hat - immer her damit.
1
2
3
; Das ist ein testprogram
4
;
5
.NOLIST
6
.include "8515def.inc"
7
.LIST
8
;
9
.DEF vgl = r16
10
.DEF rota = r17 ;Register zum rotieren
11
.DEF temp1 = r18
12
.DEF w1 = r19 ;für Warteschleife
13
.DEF w2 = r20 ;für Warteschleife
14
;
15
.CSEG
16
.ORG 0000
17
18
rjmp start
19
rjmp int0_handler ; IRQ0 Handler
20
.org INT1addr ; IRQ1 Handler
21
reti
22
23
reset:
24
ldi temp1, HIGH(RAMEND) ;STACK einrichten
25
out SPH, temp1 ;STACK einrichten
26
ldi temp1, LOW(RAMEND) ;STACK einrichten
27
out SPL, temp1 ;STACK einrichten
28
29
ldi temp1,(1<<ISC11)|(1<<ISC01)|(1<<ISC00)
30
; INT1 auf fallende Flanke + INT0 auf steigende Flanke konfigurieren
31
out MCUCR, temp1
32
ldi temp1, (1<<INT0) | (1<<INT1) ; INT0 und INT1 aktivieren
33
out GIMSK, temp1
34
35
SEI ;Interrupts sind zugelassen
36
37
38
ldi rota, 0x01 ;Anfangswert für Rotation setzen (Bit0)
39
ldi temp1, 0x0F ;benötigten 4 pins Port B auf Ausgang
40
out DDRB, temp1
41
ldi temp1, 0x00
42
out DDRD, temp1
43
ldi temp1, 0xFF
44
out PortD, temp1 ;interne Pull-Ups für Eingänge aktivieren
@spess53
Ja, der alte ist vorhanden (aufn STK500-Board) :o)
Wobei ichs weniger verwende, da das AVR-Studio ja ne schöne
Simulationsumgebung hat...
Vielen Dank für die Antworten und falls jemand zu den obigen Themen noch
gute Tutorials hat - BITTE posten
ACHTUNG WICHTIGER HINWEIS!
Bei neueren Controllern wird durch das Setzen eines Bits N im PINx
Register das Bit N im PORTx Register getoggelt!
Man darf wohl annehmen, dass sich der Simulator ähnlich verhält!
Also bitte meine Info nicht für In-Circuit-Debugging anwenden ;-)
Gilt aber nur für neuere Controller (siehe Datenblatt unter GPIOs)
Bei den xmegas haben die wenigstens separate register für's toggeln...