Hallo,
ich möchte einen AtTiny13A-SU programieren
Pin3 soll ein Eingang sein und 2 & 1 ein Ausgang.
Der Interrupt soll auf Steigende Flanken reagieren (INT0).
Hier mein Code
rjmp RESET ;Reset
rjmp PPM ;Interupt Pin1
reti ;PCINT0 -> Pin Change Interrupt Request 0
reti ;TIM0_OVF -> Timer/Counter Overflow
reti ;EE_RDY -> EEPROM Ready
reti ;ANA_COMP -> Analog Comparator
reti ;TIM0_COMPA -> Timer/Counter Compare Match A
reti ;TIM0_COMPB -> Timer/Counter Compare Match B
reti ;WDT -> Watchdog Time-out
reti ;ADC -> ADC Conversion Complete
RESET:
LDI r16, low (RAMEND)
OUT SPL, r16 ;Setzt sen StackPointer auf Anfang
LDI r16, 0b00000110
OUT DDRB, r16 ;Setzt Pin1->Output, Pin2->Output, Pin3->Input
LDI r16, 0b00001000
OUT PORTB, r16 ;PullUp
LDI r16, 0b01000000
OUT GIMSK, r16 ;Aktiviert Interupt INT0
LDI r16, 0b00000011
OUT MCUCR, r16 ;Interupt nur bei Steigender Flanke
SEI
Loop:
nop
rjmp Loop
PPM:
CLI
IN R15,SREG
... Tu was...
OUT SREG,R15
SEI
RETI
Wenn ich im Simulator unter I/O dem Pin3 Signal gebe, interesiert das
den Interrupt nicht!
Warum?
Irgendwie sind bei dir die Pins anscheinend komplett durcheinander: Armin A. schrieb: > ich möchte einen AtTiny13A-SU programieren > Pin3 soll ein Eingang sein und 2 & 1 ein Ausgang. > Der Interrupt soll auf Steigende Flanken reagieren (INT0). INT0 liegt nicht auf Pin 3, sondern auf Pin 6. > rjmp RESET ;Reset > rjmp PPM ;Interupt Pin1 Hier soll es plötzlich Pin 1 sein? > LDI r16, 0b00000110 > OUT DDRB, r16 ;Setzt Pin1->Output, Pin2->Output, Pin3->Input Nein, das setzt PB1 und PB2 auf Ausgang. Das sind Pin 6 und 7. > LDI r16, 0b00001000 > OUT PORTB, r16 ;PullUp Und zwar bei Pin 2. > LDI r16, 0b01000000 Es wäre besser, hier mit Registernamen zu arbeiten, damit man nicht Bits abzählen muss. > OUT GIMSK, r16 ;Aktiviert Interupt INT0 > LDI r16, 0b00000011 > OUT MCUCR, r16 ;Interupt nur bei Steigender Flanke > SEI > > Loop: > nop > rjmp Loop > > PPM: > CLI Ein CLI ist nicht nötig, das macht der Prozessor schon selber. > IN R15,SREG > ... Tu was... > OUT SREG,R15 > SEI Und ein SEI sollte niemals in einer ISR stehen, wenn man nicht explizit will, dass sich ISRs gegenseitig unterbrechen können. > RETI > > Wenn ich im Simulator unter I/O dem Pin3 Signal gebe, interesiert das > den Interrupt nicht! > > Warum? Weil Pin 3 der falsche ist.
Hallo, vielen Dank für deine Antwort. Wollte eigentlich PB anstatt Pin schreiben. Heist das, dass ich PCINT3 aktivieren muss, damit Interupts an PB3 gefeuert werden? Heist doch, dass PCMSK auf 0b00001000 gesetzt werden muss? Wenn ich das aber richtig verstehe, reagiert der Interupt auf jede art von Änderung (Steigende-, und Fallende Flanke). Welcher Interrupt wird gefeuert?
Armin A. schrieb: > Heist doch, dass PCMSK auf 0b00001000 gesetzt werden muss? Um auch in zwei Wochen durchzublicken, gewöhne dir besser so eine Schreibweise an:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
Damit musst du die absolute Position des Bits gar nicht kennen - der Assembler wühlt für dich in den Datenblättern. Als nächstes stimmt die Vektor Tabelle nicht, siehe Tabelle 18 im DB:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
Entscheide dich also, ob du den INT0 oder den PCINT benutzen willst. der PC interrupt reagiert auf beide Flanken, der INT0 ist programmierbar, auf welche Flanke er reagiert. INT0 liegt fest auf PB1 (Pin 6).
Matthias S. schrieb: > Als nächstes stimmt die Vektor Tabelle nicht Deshalb nimmt man ja auch keine Tabelle, sondern die im Datenblatt angegebenen Vektornamen. Besonders einfach geht das mit folgendem Macro: Beitrag "Re: avr asm: interrupt int0 löst bei fallender flanke nicht aus" Generell: Immer wenn es für etwas einen vordefinierten Namen gibt, benutzt man diesen und keine magischen Hexwerte oder Adressen, wo niemand mehr durchsieht.
Hallo, ich werde das heute Abend mal ausprobieren. In der Doku, die ich hatte, war die bei mir genannte Liste. Scheine da wohl eine falsche Doku gehabt zu haben. Wusste nicht, dass es sowas wie (1 << PCINT3) gibt. In den Beispielen die ich gesehen habe, werfen die immer mit Hex-Angaben rum. Da fand ich Binär überschaulicher. Muss ich ein Include einbauen, damit ich sowas wie eine Intelisense habe für diese Hilfen wie (1 << PCINT3)?
Hallo, man kann es auch so machen:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
dann muß man nur die benutzten eintragen und der Assembler weiß auch, wie lang die Interrupttabelle beim konkreten AVR ist. Gruß aus Berlin Michael
Gast
#4822294
Hallo Armin, schaut man sich mal die Include Datei tn13def.inc des Atmel Assembler für denen Attiny13 an, so findet man sehr viele Definitionen. Z.B. Der Abschnitt "INTERRUPT VECTORS" Dann könnte man sich fragen, was die alle bedeuten und schaut gespannt in das Atmel AVR Datenblatt des Attiny13. # http://www.atmel.com/Images/doc8126.pdf Voila, da steht dann "alles" und vielleicht noch mehr zu den Internas eines Atmel AVR µC. Hilft Dir dies weiter ? Weiteres Basiswissen gibt es unterhalb Dokumente: http://www.atmel.com/devices/ATTINY13A.aspx?tab=documents # AVR Instruction Set Manual # AVR001: Conditional Assembly and portability macros # AVR072: Accessing 16-bit I/O Registers
Armin A. schrieb: > Muss ich ein Include einbauen, damit ich sowas wie eine Intelisense habe > für diese Hilfen wie (1 << PCINT3)? Nein, das steht bereits alles fertig in der "tn13def.inc" die du im Atmel Studio ja sowieso schon "included" hast.
Das include fehlt bei mir. Werde das nachziehen. Danke
Mal ne frage. die INC ist mehrere KB groß der Tiny hat aber nur 1K. Nimmt der Compiler nur das raus, was auch benötigt wird?
Armin A. schrieb: > Das include fehlt bei mir. Wenn man im AVR Studio ein neues Projekt anlegt wird man ja nach dem Controller gefragt. Danach steht in der ersten Codezeile automatisch:
1 | |
Wenn nicht dann schreib das einfach von Hand dahin. Armin A. schrieb: > die INC ist mehrere KB groß > der Tiny hat aber nur 1K. Die Definitionsdatei wird nicht in Assembler übersetzt. Das ist nur eine Hilfsdatei für den AVRAssembler. Damit werden die Namen wie PCINT3 im Code wieder in den Binärcode (wie du ganz zu Anfangs auch verwendet hast) zurück übersetzt.
Kleines Beispiel:
Armin A. schrieb:1 | |
Da stehen jetzt z.B. GIMSK. Der Assembler schaut jetzt in der .inc nach und findet:
1 | |
Der Assembler ersetzt jetzt GIMSK zu:
1 | |
Fertig.
alles klar, Danke
Armin A. schrieb: > Hallo, > > vielen Dank für deine Antwort. > Wollte eigentlich PB anstatt Pin schreiben. Stimmt aber so oder so nicht, denn INT0 ist weder Pin 3, noch PB3. > Heist das, dass ich PCINT3 aktivieren muss, damit Interupts an PB3 > gefeuert werden? Ja. Der PCINT hat den Vorteil, dass er auf mehrere Pins reagieren kann, während der INT immer an einen einzelnen Pin gebunden ist. Dafür kann man beim INT mehr einstellen. > Wenn ich das aber richtig verstehe, reagiert der Interupt auf jede art > von Änderung (Steigende-, und Fallende Flanke). Ja, richtig. Du kannst dann in der ISR den Wert des Pins auslesen, um zu erkennen, ob es eine steigende oder fallende Flanke war, wenn der Puls am Eingang nicht gerade kürzer ist als die Latenz des Interrupts.
Hallo,
habe jetzt mal weiter probiert.
Das .include macht irgendwie Probleme. Wenn ich das verwende und dann
einmal Ausführe, meckert der über Zuordnumgen innerhalb der Datei.
Deshalb alles nochmal Binär.
Jetzt habe ich alles so eingestellt, dass Pin6 (PB1) ein Eingang ist.
Pin 2 & 3 ein Ausgang (PB3 & 4).
Der Interrupt wird aber immer noch nicht gefeuert!
rjmp RESET ; Reset Handler
rjmp INT0H ; IRQ0 Handler
RETI ; PCINT0 Handler
RETI ; Timer0 Overflow Handler
RETI ; EEPROM Ready Handler
RETI ; Analog Comparator Handler
RETI ; Timer0 CompareA Handler
RETI ; Timer0 CompareB Handler
RETI ; Watchdog Interrupt Handler
RETI ; ADC Conversion Handler
RESET:
LDI r16, low (RAMEND)
OUT SPL, r16 ; Setzt sen StackPointer auf Anfang
LDI r16, 0b00011000
OUT DDRB, r16 ; Setzt Pin6->Input, Pin2->Output, Pin3->Output
LDI r16, 0b00000010
OUT PORTB, r16 ; PullUp
LDI r16, 0b01000000
OUT GIMSK, r16 ; Aktiviert Interupt INT0
LDI r16, 0b00000011
OUT MCUCR, r16 ; Interupt nur bei Steigender Flanke
SEI
Loop:
nop
rjmp Loop
INT0H:
CLI
IN R15,SREG
... Mach was ...
OUT SREG,R15
SEI
RETI
Gast
#4823138
Woran merken Sie, dass der Interrupt nicht ausgelöst wird? (Nur am Rande: in der ISR sind cli und sei überflüssig, denn beim Einsprung wird cli von der Hardware ausgeführt, und reti beinhaltet das sei.)
Armin A. schrieb:1 | |
2 | |
Der Kommentartext passt nicht zu den Bits. Ansonsten sollte das Programm funktionieren. Da du den Pull-up eingeschalten hast musst du PB1 auf Masse ziehen und dann wieder loslassen.
Gast
#4823155
> Der Kommentartext passt nicht zu den Bits. Passt schon, wenn man > Pin 2 & 3 ein Ausgang (PB3 & 4) berücksichtigt.
Ich setze einen brakpoint unter Loop und einen unter INT0H. Mit F10 gehe ich Zeile für Zeile durch. Wenn ich im I/O Fenster jetzt aus Pin6 Signal gebe, müsste er doch eigentlich auf den 2. Breakpoint springen. Selbst wenn ich den Pullup nicht setze kommt er nie zum INT0H. Müsste der doch eigentlich. Deshalb die fragte, was ich falsch mache.
Gast
#4823196
> Wenn ich im I/O Fenster jetzt aus Pin6 Signal gebe
Sollte das nicht PINB1 (==INT0) sein?
Der 2. von rechts in der Bitreihe. Ich meinte den Physikalischen Pin.
Gast
#4823202
Hi > LDI r16, 0b00011000 > OUT DDRB, r16 ; Setzt Pin6->Input, Pin2->Output, Pin3->Output Setzt Pin3->Output, Pin4->Output MfG Spess
Gast
#4823203
Das ist jetzt doppelt schlecht, ich arbeite noch mit einem steinalten AVR-Studio und habe keinen ATtiny13, nur einen 85. Konkret läuft Ihr Programm auf meinem ATtiny85 (mutatis mutandis), wie ja Thomas Forster auch schon schrieb, aber darüber hinaus kann ich nichts sagen, da muss jemand anders helfen.
Gast
#4823221
Habe ich das richtig verstanden, Sie arbeiten ausschließlich mit dem Simulator? Ich habe nun Ihr Programm in meinen, wie gesagt steinalten, AVR-Studio-Simulator gesteckt, und es funktioniert. Könnte es sein, dass Sie Ihren irgendwie falsch bedienen? Und wie wäre es, das Ganze konkret in Hardware aufzubauen und auszuprobieren, ist ja nichts Großes?
Armin A. schrieb: > Mit F10 gehe ich Zeile für Zeile durch. > Wenn ich im I/O Fenster jetzt aus Pin6 Signal gebe, müsste er doch > eigentlich auf den 2. Breakpoint springen. > Selbst wenn ich den Pullup nicht setze kommt er nie zum INT0H. > > Müsste der doch eigentlich. > > Deshalb die fragte, was ich falsch mache. Du machst nichts falsch, AVR Studio macht das für dich. Schmeiss den Sch... raus, baue das Ganze auf einem Breadboard auf. P.S. Natürlich feuert dein INT erst beim loslassen (ev. beim Prellen).
Gast
#4823297
Liegt das Problem mit Ihrem Simulator vielleicht daran: Beitrag "Re: AVR-Studio Simulation/Debugging springt nicht in ISR" ?
spess53 schrieb: > Hi > >> LDI r16, 0b00011000 >> OUT DDRB, r16 ; Setzt Pin6->Input, Pin2->Output, Pin3->Output > > Setzt Pin3->Output, Pin4->Output Es setzt PB3 und PB4 als Output. Das sind Pin 2 und Pin 3.
Ha, genau das Problem ist es! Habe jetzt "Mask interrupts while stepping" auf False gesetzt und er springt in den Interrupt! Vielen Dank!
Armin A. schrieb: > Das .include macht irgendwie Probleme. Wenn ich das verwende und dann > einmal Ausführe, meckert der über Zuordnumgen innerhalb der Datei. Eigenartig. Eigentlich sollte ein
1 | |
2 | |
3 | |
4 | |
5 | |
am Anfang der Datei bestens funktionieren. "Gänsefüsschen" nicht vergessen.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.