Hallo,
warum kommt nach folgendem Initialisierungscode ein Interrupt, wenn
PD2=0 und der Interrupt auf steigende Flanke eingestellt ist ?
(habe nur im AVR-Studio 3.56 simuliert ...)
.INCLUDE "1200def.inc"
.DEF sreg_int_ext = r0
.DEF temp = r16
.DEF temp_int_ext = r18
.DEF temp_int_ext2 = r19
.EQU INT0_FALLING_EDGE = 2
.EQU INT0_RISING_EDGE = 3
.CSEG
.ORG 0x0
rjmp RESET
rjmp EXT_INT0 ;External Interrupt0 Vector Address
reti ;Overflow0 Interrupt Vector Address
reti ;Analog Comparator Interrupt Vector Address
RESET:
cli ; Global Interrupt Disbale
clr temp
out DDRD, temp ; Port D = Inputs
ser temp
out PORTD, temp ; Enable Internal Pull-Up resistors for Port D
clr temp
out GIMSK, temp ; Disable External Interupt0
ldi temp, INT0_FALLING_EDGE
sbis PIND, BL_INP_PORT_BIT
ldi temp, INT0_RISING_EDGE
out MCUCR, temp ; negatived edge of the input pin state
ldi temp, 0x40
out GIMSK, temp ; Enable External Interupt0
sei ; Global Interrupt Enable
rjmp MAIN
EXT_INT0:
in sreg_int_ext, SREG ; save the status register
; Eigentlicher Code ...
ldi temp_int_ext, INT0_FALLING_EDGE
sbis PIND, BL_INP_PORT_BIT
ldi temp_int_ext, INT0_RISING_EDGE
out MCUCR, temp_int_ext ; negatived edge of the input pin state
out SREG, sreg_int_ext
reti
MAIN:
rjmp MAIN
Vielen Dank für eure Hilfe !
Hi!
Vermutlich wird das (leider) nicht löschbare Flag beim setzen der
PullUp's mit gesetzt und löst bei "sei" dann aus. Du muust das ganze
also irgendwie anders abfangen.
Was ich aber noch gesehen habe:>.DEF sreg_int_ext = r0
Wenn ich mich nicht irre sollte
>in sreg_int_ext, SREG ; save the status register
einen Fehler erzeugen weil "in" mit Rd-Registern angegeben ist und
Rd=R16-R31 ist.
MFG Uwe
Halo Uwe,
>Du muust das ganze also irgendwie anders abfangen.
Aber wie, ohne viel Zeit zu verschwenden ?
Ein korrekter Interrupt wäre, wenn MCUCR Bit0 ungleich dem INPD Bit 0
ist.
.DEF temp_int_ext = r18
.DEF temp_int_ext2 = r19
; Am Anfang des Interrupts
in temp_int_ext, PIND
lsr temp_int_ext
lsr temp_int_ext
andi temp_int_ext, 1
in temp_int_ext2, MCUCR
andi temp_int_ext2, 1
cp temp_int_ext, temp_int_ext2
breq int0_ok
reti ; check if the interrupt is correct (must be: MCUCR Bit 0
!=
PD2) [costs 9µs]
int0_ok:
Kenntst du eine schnellere Lösung ?
>einen Fehler erzeugen weil "in" mit Rd-Registern angegeben ist und>Rd=R16-R31 ist.
Also bei mir in der Hilfe steht folgendes:
IN Rd,A 0 ≤ d ≤ 31, 0 ≤ A ≤ 63
PC <- PC + 1
Hi!
"temp_int_ext" ist doch bei Init=0(notfalls ldi temp_int_ext,0)
In der ISR schreibst du dann:
EXT_INT0:
in sreg_int_ext, SREG ; save the status register
tst temp_int_ext
breq null
; Eigentlicher Code ...
ldi temp_int_ext, INT0_FALLING_EDGE
sbis PIND, BL_INP_PORT_BIT
ldi temp_int_ext, INT0_RISING_EDGE
out MCUCR, temp_int_ext ; negatived edge of the input pin state
null: out SREG, sreg_int_ext
reti
Das könnte etwas schneller sein.
>Also bei mir in der Hilfe steht folgendes:>IN Rd,A 0 ≤ d ≤ 31, 0 ≤ A ≤ 63> PC <- PC + 1
Komische Sache. Im Instruktion Set steht es tatsache so, nur dann ist
die Unterscheidung in Rr und Rd sinnlos wenn sich keiner drann hält.
MFG Uwe
Hallo Uwe,
vielen Dank für deine Idee !
In deiner Lösung war nur ein kleiner Fehler: nach dem ersten falschen
Interrupt muss sich das Register "temp_int_ext" verändern.
Ich habe es nun so gemacht:
EXT_INT0:
in sreg_int_ext, SREG ; save the status register
tst temp_int_ext
brne int0_ok
ser temp_int_ext
reti
int0_ok:
Hi!
Ja, ist mir später auch noch eingefallen.
Kürzere Variante wäre:
.
.
.
clr temp_int_ext
out DDRD, temp_int_ext ; Port D = Inputs
ser temp
out PORTD, temp ; Enable Internal Pull-Up resistors for Port D
sei ; Global Interrupt Enable (Falscher Interr.)
ldi temp_int_ext, INT0_FALLING_EDGE (Jetzt OK)
rjmp MAIN
EXT_INT0:
in sreg_int_ext, SREG ; save the status register
tst temp_int_ext
breq null
; Eigentlicher Code ...
ldi temp_int_ext, INT0_FALLING_EDGE
sbis PIND, BL_INP_PORT_BIT
ldi temp_int_ext, INT0_RISING_EDGE
out MCUCR, temp_int_ext ; negatived edge of the input pin state
null: out SREG, sreg_int_ext
reti
Nun sollte es aber hinhauen. Ach ja, du wolltest hoffentlich noch ein
"reti" einbauen.
MFG Uwe
Eine eigene Frage?
Dieser Thread ist über 23 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.