-
        

Ergebnis 1 bis 6 von 6

Thema: interrupt ein/ausschaltprobleme

  1. #1
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    25.03.2006
    Ort
    Hinsdorf
    Alter
    42
    Beiträge
    379

    interrupt ein/ausschaltprobleme

    Anzeige

    Hallo,

    ich detektiere über int0 eine steigende Flanke und will dies Auswerten:
    Code:
    Int0_isr:
    Portd.7 = 1
    Disable Int0
    Return
    Nach einmaligem Sprung in die Interruptroutine soll der Interrupt ausgeschalten werden, das Funktioniert so weit.
    In:
    Code:
    If Portd.7 = 1 Then Set Relon
    If Pinc.2 = 0 And Portd.7 = 1 Then
     Portd.7 = 0
     Irq_z = 0                                                                      'Netzspannung wieder da?  Or Batmin = 0
     Enable Int0
     Reset Relon
    End If
    soll der Interrupterkennung wieder eingeschalten werden. Nach dem einmal die Interruptroutine angesprungen wurde wird diese aber leider nicht wieder "aktiviert".
    Kompletter Code.
    Code:
    $regfile = "m644pdef.dat"
    $crystal = 14745600
    
    $include "MyTWI.bas"
    
    $baud = 19200
    
    $hwstack = 100
    $swstack = 100
    $framesize = 100
    
    Ddrb = &B00000000                                                               'PortB als Eingang für die Funksensorüberwachung
    Portb = &B11111111                                                              'PullUp's einschalten
    Ddrc = &B00000000                                                               'PortB als Eingang
    Portc = &B00000100
    Ddrd = &B11111000
    Portd = &B00000100
    
    Config Adc = Single , Prescaler = Auto , Reference = Off
    Start Adc
    
    Config Timer1 = Timer , Prescale = 1024                                         'Timer1 (16bit, 65535) läuft mit Quarztakt/1024
    Const Timervorgabe = 36735                                                      'Anfangswert ab der der Timer1 beginnen soll zu zählen (von 58336=>65535)
    Enable Timer1                                                                   ' Schalte Überlaufinterupt von Timer1 ein
    On Timer1 Timer_irq                                                             ' 1secint => Sprungmarke an die gesprungen wird, wenn timer1 übergelaufen ist => danach weiter Start ADC
    
    Config Int0 = Rising                                                            'Interrupt zur Netzspannungsdedektion
    On Int0 Int0_isr                                                                'Sprungmarke interrupt nach dem infrarot Signal anliegt
    Enable Int0
    Enable Interrupts
    Dim Irq_z As Byte
    
    '------------------------------------------------------------------------------- Programmvariablen
    Dim Relon As Bit
    
    
    
    '-------------------------------------------------------------------------------   Config TWI
    Dim Batterie As Word
    Dim Batspannung As Single
    Dim Tuerkontakt As Byte
    Dim Absender As Byte
    
    Declare Sub Twi_show_state(byref State As Byte)                                 ' Fehleranzeige für TWI übertragung
    Const Mn1_adr = &H5A                                                            'lokale I2C Adresse   (als Slave)
    Dim Twi_mst_buff(24) As Byte                                                    'Buffer für Masterfunktionen
    Dim Twi_slv_buff(24) As Byte                                                    'Buffer für Slavefunktionen
    
    Dim Temp As Byte
    
    Dim Slave_adress As Byte , Send_byte As Byte , Speicherpointer As Byte
    Declare Sub Master_transmit(byref Slave_adress As Byte , Byref Send_byte As Byte , Byref Speicherpointer As Byte)       'Declarierung der Sub =>mit byref wird immer nur ein Zeiger auf die Speicherstelle
                                                                                              ' verwiesen und nicht ein Wert übergeben
    Twi_slv_addr = Mn1_adr                                                          'lokale I2C-Adresse
    Twi_sr_data = Varptr(twi_slv_buff(1))                                           'datenbuffer empfang
    Twi_st_data = Varptr(batspannung)                                               'datenbuffer senden, von dort holt sich der Master die Daten
    
      Twar = Twi_slv_addr + 1                                                       'I2C Adress Mega32 + GCA
      Config Twi = 100000                                                           'I2C Speed
      On Twi Twi_mst_slv_isr , Nosave                                               'ISR f. TWI
      Gosub Twi_sense                                                               'Aktivieren Slave-Funktion
      Enable Interrupts                                                             'Generell
    
    
    
    '############################################################################### Programmstart
    
    Do
    
    
    If Portd.7 = 1 Then Set Relon
    If Pinc.2 = 0 And Portd.7 = 1 Then
     Portd.7 = 0
     Irq_z = 0                                                                      'Netzspannung wieder da?  Or Batmin = 0
     Enable Int0
     Reset Relon
    End If
    
    '******************************************************************************* Überwachung Batteriespannung
    Batterie = Getadc(1)
    
    Batspannung = Batterie * 4.5                                                    ' Potivoreinstellung 4,5V = 10V Battspannung
    Batspannung = Batspannung / 920                                                 ' Spannung auf Wandlerrate umstellen
    Batspannung = Batspannung * 2.22                                                ' Faktor für Umrechnung in tatsächlichen Bat-Wert 10V/4,5V
    If Portd.7 = 1 Then                                                             ' Unterspannungsüberwachung
      If Batspannung =< 6.7 Then
         Portd.7 = 0
      End If
    End If
    If Relon = 1 Then                                                               ' Übermittlung das Netzausfall vorliegt => Meldung an Zentrale
      Tuerkontakt.7 = 1
      Else
      Tuerkontakt.7 = 0
    End If
    
    '******************************************************************************* Überwachung Türkontakte
    
    
    If Pinb.0 = 1 Then
      Tuerkontakt.0 = 1
     Else
      Tuerkontakt.0 = 0
      End If
    If Pinb.1 = 0 Then
      Tuerkontakt.1 = 1
      Else
      Tuerkontakt.1 = 0
      End If
    If Pinb.2 = 1 Then
      Tuerkontakt.2 = 1
      Else
      Tuerkontakt.2 = 0
      End If
    If Pinb.3 = 1 Then
      Tuerkontakt.3 = 1
      Else
      Tuerkontakt.3 = 0
      End If
    If Pinb.5 = 1 Then
      Tuerkontakt.4 = 0
     Else
      Tuerkontakt.4 = 0
      End If
    If Pinb.6 = 1 Then
      Tuerkontakt.5 = 1
      Else
      Tuerkontakt.5 = 0
      End If
    If Pinb.7 = 1 Then
      Tuerkontakt.6 = 1
      Else
      Tuerkontakt.6 = 0
      End If
    
    
    '******************************************************************************* TWI Slavefunktion, hier wird gehört, ob ein andere Master etwas sendet
    
    If Twi_slv_flag <> 0 Then                                                       'ständige Abfrage ob als Slave Daten anliegen  =>Vorsicht, der Bus ist solange blockiert
    
             Select Case Twi_slv_flag
             Case &H60 :
                         Print ; "Slave empfängt" ;                                 'es ist was empfangen worden
                         Print Hex(twi_slv_addr) ; " ";                             'von Adresse in Hex
                         For Temp = 1 To Twi_sr_cntr                                'Daten aus Twi_sr_cntr in den puffer schreiben
                         Print Hex(twi_slv_buff(temp));                             'print der Daten
                         Next
             Case &HA8 :
    
                         Print ; "Slave sendet" ;                                   'es ist was abgeholt worden  Spc(30)
                         Print Hex(twi_slv_addr) ; " ";
                         For Temp = 1 To Twi_st_cntr
                         Print Twi_slv_buff(temp);                                  'print der Daten Hex(twi_slv_buff(temp));
                           Next
    
             Case &H70 : Print Spc(30) ; "SLAVE GCA :" ;                            'ein General Call ist gekommen
                         Print Hex(twi_slv_addr) ; " ";
                         For Temp = 1 To Twi_sr_cntr
                         Print Hex(twi_slv_buff(temp));                             'print der Daten
                           Next
             Case Else:
                         Print " Fehler als Slave " ; Chr(7) ; Hex(twi_mst_addr) ; " ";       'Irgendein Fehler
                         Call Twi_show_state(twi_slv_flag)                          'Print status-text
    
    
    
             End Select
             Print
             Twi_slv_flag = 0                                                       'löschen marker
             Twi_slv_stat = 0                                                       'löschen marker
             Gosub Twi_sense                                                        'alles wieder enablen
                                       'und Bus freigeben
          End If
    '*******************************************************************************
    
    
    
    Print " IRQ-Zaehler " ; Irq_z
    Waitms 200
    Print " Batspannung " ; Batspannung
    Waitms 200
    Print " Relon " ; Relon
    Waitms 200
    Loop
    End
    
    '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SUBROUTINEN
    '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Timerschaltung für Impulse Resetbaustein Netzüberwachung
    Timer_irq:
    Toggle Portd.6
    Timer1 = Timervorgabe
    Return
    
    '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Interruptabfrage Netzausfall
    Int0_isr:
    Portd.7 = 1
    Disable Int0
    Return
    
    
    '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    $include "Twi_show_state.bas"
    '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Senderoutine TWI
    Run_wait_master:
          Gosub Mst_start                                                           'aufruf LIBRARY
          Select Case Twi_mst_flag                                                  'ergebnis ?
          Case Twi_m_sent:                                                          'gesendet
                   Print "<<<<<<MASTER sent:" ;
                   Print Hex(twi_mst_addr) ; " ";
                   For Temp = 1 To Twi_mt_cntr
                         Print Hex(twi_mst_buff(temp));
                   Next
                   Print
                   Twi_mst_flag = 0
          Case Twi_m_recv:                                                          'geholt
                    Print ">>>>>>MASTER read:" ;
                   Print Hex(twi_mst_addr) ; " ";
                   For Temp = 1 To Twi_mr_cntr
                         Print Hex(twi_mst_buff(temp));
                   Next
                   Print
                   Twi_mst_flag = 0
          Case Else:                                                                'irgendein Problem
                    Print "Fehler als Run_wait_master  " ; Chr(7) ; Hex(twi_mst_addr) ; " ";
                    Call Twi_show_state(twi_mst_flag)
          End Select
       Return
    
    
    
    '############################################################################### Sendesub
    Sub Master_transmit(byref Slave_adress As Byte , Byref Send_byte As Byte , Byref Speicherpointer As Byte)       'Sub in der die Adresse des Empfängers steht und der Zeiger aus der Callprozedur
    
       Twi_mst_addr = Slave_adress                                                  'I2C Adresse Slave
       Twi_mt_cntr = Send_byte                                                      '4 Byte senden
       Twi_mt_data = Varptr(speicherpointer(1))                                     'Daten senden => Varptr(Speicherpointer(1)) Speicherpointer = Zeiger auf eine
                                                                                     ' Speicherstelle, nicht auf den Wert, aus der Callsubroutine (Temperaturbyte(1))
       Twi_mr_cntr = 0
    
       'Twi_mr_cntr = 1                                          ' dann 3 Byte empfangen
       'Twi_mr_data = Varptr(twi_mst_buff(1))                    ' empfangsbuffer
    
       Gosub Run_wait_master                                                        ' auf gehts
    
       End Sub
       Return
    Nun leider kann ich mir das nicht erklären. Kann ich den Interrupt für int0 so benutzen?

    MAT

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.112

    Re: interrupt ein/ausschaltprobleme

    Zitat Zitat von mat-sche
    Hallo,

    ich detektiere über int0 eine steigende Flanke und will dies Auswerten:
    Code:
    Int0_isr:
    Portd.7 = 1
    Disable Int0
    Return
    Nach einmaligem Sprung in die Interruptroutine soll der Interrupt ausgeschalten werden, das Funktioniert so weit.
    In:
    Code:
    If Portd.7 = 1 Then Set Relon
    If Pinc.2 = 0 And Portd.7 = 1 Then
     Portd.7 = 0
     Irq_z = 0                                                                      'Netzspannung wieder da?  Or Batmin = 0
     Enable Int0
     Reset Relon
    End If
    Da PortD.7 als Eingang konfiguriert ist, wird hiermit nur der PullUp eingeschaltet:
    Portd.7 = 1
    Willst du das wirklich?
    In allen Abfragen musst du aber sicher den Port durch den Pin ersetzen, also so
    If Pind.7 = 1 Then Set Relon

    Gruß

    Rolf

    Edit: Ich sehe gerade, dass du D.7 als Ausgang konfiguriert hast. Das passt dann gar nicht zusammen. Das soll in den Abfragen dann doch bestimmt einer der Eingänge D.0, D.1 oder D.2 sein.

  3. #3
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    25.03.2006
    Ort
    Hinsdorf
    Alter
    42
    Beiträge
    379
    Hi for_ro,

    gut.. dann werde ich die Abfrage, ob der Ausgang D.7 gesetzt ist, über Pind.7 = 1 machen und probieren.
    Die frage ist nun, ob man in einer isr einen Interrupt ausschalten kann?

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    33
    Beiträge
    2.378
    ja das sist kein problem, wenn du das interrupt-enable an der entsprechenden stelle löscht wird der interrupt solagen nicht ausgelöst, wie du das enable-flag wieder setzt

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.112
    Zitat Zitat von mat-sche
    Hi for_ro,

    gut.. dann werde ich die Abfrage, ob der Ausgang D.7 gesetzt ist, über Pind.7 = 1 machen und probieren.
    Sorry, ich glaube ich hatte nicht verstanden, was du machen willst.
    Du willst also abfragen, ob von deinem Programm der Ausgang D.7 gesetzt worden ist. Wenn das der Fall ist, dann musst du das tatsächlich so machen, wie in deinem Code angegeben. Zumindest geht es im Simulator so. Mit Pin wird das jedenfalls nicht gehen.
    Falls dies im µC anders funktioniert, könntest du auch eine Variable benutzen, um den Zustand nachzuhalten. Oder du fragst direkt das Register ab, welches den Zustand des Int0 hält, also EIMSK.0.

    Bist du denn sicher, dass C.2 = 0 kommt?

    Gruß

    Rolf

  6. #6
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    25.03.2006
    Ort
    Hinsdorf
    Alter
    42
    Beiträge
    379
    moin Rolf,

    genau wie Du es erkannt hast möchte ich den Ausgang D.7 überwachen ob er geschalten wurde, so kann ich mir einen zusätzlichen Merker sparen. Das Programm läuft insoweit auch. Nur wenn ich in der ISR den Interrupt ausschalte (ne Art der Entprellung) und ihn wieder ein schalte, wird der Interrrupt nicht wieder eingeschalten. C.2 ist tatsächlich 0.
    Das Programm nehme ich für eine unterbrechungsfreie Spannungsversorgung.
    Die direkte Registerabfrage werde ich mir näher anschauen.
    Danke für Deine Hilfe!

Berechtigungen

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