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 |
45 | ldi temp1, 0xF0 |
46 | out PortB, temp1 |
47 | |
48 | |
49 | |
50 | flash: ;abwechselnd nur eine LED leuchten lassen |
51 | out portB, rota |
52 | ;rcall wait ;Aufruf UP Warteschleife |
53 | rcall rotat1 |
54 | ldi temp1, 0x00 |
55 | out portB, temp1 |
56 | ;rcall wait |
57 | rjmp flash ;und endlos weitermachen |
58 | |
59 | |
60 | rotat1: |
61 | sbic PINB, 7 ;Wenn Portbit2=0 (Taster),dann überspringe,sonst |
62 | lsl rota ;Rotation links |
63 | sbrc rota, 4 ;überspring nächsten Befehl,solange 5.Bit "0" ist |
64 | ldi rota, 0x01 ;und wieder in Ausgangssituation zurück |
65 | ret |
66 | |
67 | |
68 | int0_handler: |
69 | push temp1 |
70 | IN temp1, SREG |
71 | PUSH temp1 |
72 | |
73 | sbic PIND, 2 ;Wenn Portbit2=0 (Taster),dann überspringe,sonst |
74 | lsl rota ;Rotation links |
75 | sbrc rota, 4 ;überspring nächsten Befehl,solange 5.Bit "0" ist |
76 | ldi rota, 0x01 ;und wieder in Ausgangssituation zurück |
77 | |
78 | pop temp1 |
79 | OUT SREG,temp1 |
80 | pop temp1 |
81 | RETI |
82 | |
83 | |
84 | wait: ;Warteschleife |
85 | ldi w1, 0x40 ;Zählvariable setzen |
86 | m2: ldi w2, 0xFF |
87 | m1: dec w2 ;runterzählen 1.Stufe |
88 | brne m1 ;wenn z<>0 springe zur Marke 1.Stufe |
89 | dec w1 ;runterzählen 2.Stufe |
90 | brne m2 ;wenn z<>0 springe zur Marke 2.Stufe |
91 | ret |
Frank schrieb: > Ext. Int. sind nur über Bit 2/3 vom PortD möglich und > nicht auf andere Ports anwendbar??? jap
Hi Du bist sicher, das du einen AT90S8515 und nicht einen ATMega8515 hast? Sonst würde das Include-File nicht passen. MfG Spess
@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...
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.