PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Int0 = Falling wird immer 2x ausgelöst (software uart)



-tomas-
24.02.2006, 11:28
Problem: Config Int0 = Falling
Ich habe das Problem, dass Bascom 1.11.8.1 beim MEGA32 nach der Abarbeitung der Interruptroutine (Falling) diese noch ein zweites Mal aufruft, obwohl zu diesem Zeitpunkt keine Flanke mehr anliegt.
Das passiert nur bei Int0 = Falling. Bei Config Int0 = LOW LEVEL läuft alles wie erwartet.

Beispiel:
Ich habe den Code mal stark eingedampft. An Pina.0 sitzt eine LED.

$regfile = "m32def.dat" 'bascom 1.11.8.1
$crystal = 8000000

Config Pina.0 = Output 'LED 1


On Int0 Int0_int
Enable Int0
Config Int0 = Falling
Enable Interrupts

Do
Waitms 100
Loop
End

'The Interrupt Handler For The Int0 Interrupt
Int0_int:
Porta.0 = 1
Waitms 500 '0,5sec LED 1 = ON
Porta.0 = 0
Waitms 250
Return
Es ist D.2 (INT0)=High (externer Pullup).
Wird jetzt der Pegel mit einer prellenden Taste kurz (z.B. 100ms) auf LOW gebracht, wird die 750ms andauernde Interrupt-Routine 2x aufgerufen. D.h. die LED blinkt zweimal Der zweite Interrupt wird ausgelöst, obwohl definitiv keine Flanke anliegt. Ich habe mit einem Oszi nachgemessen.
Waitms xx im Interrupt-Handler dient nur der Verdeutlichung. Daran liegt es nicht. Ich habe auch im Interrupt-Handler alle Varianten von Disable/Enable Interrupt getestet... die LED blinkt immer zweimal.

Das dient hier nur der Verdeutlichung meines Problemes. In meinem Beispiel geht es um eine Software UART, bei der ich INKEY(#2) mit INT0 verknüpft habe.

SprinterSB
24.02.2006, 11:58
Wenn der Taster prellt, musst du am Ende der ISR das Flag von Hand zurücksetzen. Ansonsten merkt die AVR-Hardware das Flag, wenn in der ISR eine IRQ auftritt und triggert nach der ISR diesen IRQ.

::Edit::

Genz nebenbei, ist es keine gute Idee, in einer ISR zu warten. Das ganze System 'hängt' in dieser Zeit.

-tomas-
24.02.2006, 14:30
...merkt die AVR-Hardware das Flag, wenn in der ISR eine IRQ auftritt und triggert nach der ISR diesen IRQ.
Ich hatte bisher nur erfolglos 'Disbale Int0' und 'Enable Int0' eingebaut...

Danke für den Tip :-)

Zum General Interrupt Control Register (GICR) steht im Atmega32-Datenblatt

Bit 6 INTF0: External Interrupt Flag 0
When an event on the INT0 pin triggers an interrupt request, INTF0 becomes set (one).
The flag is cleared when the interrupt routine is executed.
Alternatively, the flag can be cleared by writing a logical one to it.

d.h. wenn vor dem RETI ein neues Ereignis auftritt, dann wird das gelöschte INTF0 wieder gesetzt.

Nett formuliert: Setzen ist 'becomes set (one)' und Löschen ist 'writing a logical one' :-)

SprinterSB
24.02.2006, 14:41
Das Setzen kann nur die Hardware, das Löschen geht, indem man eine 1 schreibt (in GIFR), oder indem eine IRQ bedient wird (gilt aber nicht für alle Flags!, etw TWI, UDRE, level-Triggered INT, ...).

-tomas-
24.02.2006, 20:41
es funktioniert jetzt :-)
hier der Code-Ausschnitt mit Soft UART als einfaches ECHO der Tastatur (Demo - ansonsten sollte ein SoftUart-Printbin einer einer ISR nie verwenden).

$regfile = "m32def.dat"
$crystal = 8000000
$baud = 9600 'Die Baudrate für RS232 Ausgabe.

Open "comB.1:9600,8,n,1" For Output As #1 'pin for output
Open "comD.2:9600,8,n,1" For Input As #2 'INT0 pin for input

On Int0 Int0_int
Enable Int0
Config Int0 = Falling
Enable Interrupts

Dim A As Byte

Do
Waitms 100
Loop


End


Rem The Interrupt Handler For The Int0 Interrupt
Int0_int:
A = Inkey(#2) 'get it
Printbin #1 , A
Gifr = Gifr Or &H40 ' flag INT0 cleared (logical one)
Return

Erwähnen will ich noch, dass BASCOM die Inkey-Routine für die Software UART der Atmel application note AVR305 entsprechen.
http://www.atmel.com/dyn/resources/prod_documents/doc0952.pdf
http://www.atmel.com/dyn/resources/prod_documents/avr305.asm

hier zum Vergleich der BASCOM-Code für 8MHz (Dissambler)

; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦


sub_CF: ; CODE XREF: ROM:0070 p
sbis PINB, 0 ; Inkey()
rjmp loc_D3
clr r24
ret
; ---------------------------------------------------------------------------

loc_D3: ; CODE XREF: sub_CF+1 j
ldi r18, 9

loc_D4: ; CODE XREF: sub_CF+6 j
sbic PINB, 0
rjmp loc_D4
rcall sub_C6

loc_D7: ; CODE XREF: sub_CF+11 j
rcall sub_C6
rcall sub_C6
clc
sbic PINB, 0
sec
dec r18
breq locret_E1
ror r24
ror r25 ; warum R24 und R25 ?
rjmp loc_D7
; ---------------------------------------------------------------------------

; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦


sub_C6: ; CODE XREF: sub_CF+7 p
; sub_CF+8 p ...
push r24
push r25 ;R25 ist unnötig
ldi r24, 0x63 ; 'c' ; 99 Dezimal
ldi r25, 0

loc_CA: ; CODE XREF: sub_C6+5 j
sbiw r24, 1
brne loc_CA
pop r25
pop r24
ret
; End of function sub_C6

...schön zu sehen, wie Bascom immer ein paar Register zu viel mit herumschleppt