- Labornetzteil AliExpress         
Ergebnis 1 bis 5 von 5

Thema: Int0 = Falling wird immer 2x ausgelöst (software uart)

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    28.03.2004
    Beiträge
    185

    Int0 = Falling wird immer 2x ausgelöst (software uart)

    Anzeige

    Praxistest und DIY Projekte
    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.
    Code:
     $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.

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    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.
    Disclaimer: none. Sue me.

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    28.03.2004
    Beiträge
    185
    Zitat Zitat von SprinterSB
    ...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'

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    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, ...).
    Disclaimer: none. Sue me.

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    28.03.2004
    Beiträge
    185
    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).
    Code:
     $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/p...ts/doc0952.pdf
    http://www.atmel.com/dyn/resources/p...nts/avr305.asm

    hier zum Vergleich der BASCOM-Code für 8MHz (Dissambler)
    Code:
     ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ 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

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Labornetzteil AliExpress