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
ldi r16,(1 << PCIE) ; enable the PC INT
2
out GIMSK,r16 ; set the register
3
ldi r16, (1 << PCINT3) ; PC INT on PB3 - Pin 2 on Tiny13
4
out PCMSK,r16
5
ldi r16,(1 << PCIF) ; clear pending interrupts
6
out GIFR,r16
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
rjmp RESET ; Reset Handler
2
rjmp EXT_INT0 ; IRQ0 Handler
3
rjmp PCINT0 ; PCINT0 Handler
4
rjmp TIM0_OVF ; Timer0 Overflow Handler
5
rjmp EE_RDY ; EEPROM Ready Handler
6
rjmp ANA_COMP ; Analog Comparator Handler
7
rjmp TIM0_COMPA ; Timer0 CompareA Handler
8
rjmp TIM0_COMPB ; Timer0 CompareB Handler
9
rjmp WATCHDOG ; Watchdog Interrupt Handler
10
rjmp ADC ; ADC Conversion Handler
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 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.
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
.include "tn13def.inc"
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.
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
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.)
OUT DDRB, r16 ; Setzt Pin6->Input, Pin2->Output, Pin3->Output
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.
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.
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.
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).
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.
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
; general device setup
2
; this is for the ATtiny 13
3
.NOLIST ; Disable listfile generation
4
.include "tn13def.inc"
5
.LIST
am Anfang der Datei bestens funktionieren. "Gänsefüsschen" nicht
vergessen.