mat-sche
03.09.2009, 20:39
Hallo,
ich detektiere über int0 eine steigende Flanke und will dies Auswerten:
Int0_isr:
Portd.7 = 1
Disable Int0
Return
Nach einmaligem Sprung in die Interruptroutine soll der Interrupt ausgeschalten werden, das Funktioniert so weit.
In:
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.
$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
ich detektiere über int0 eine steigende Flanke und will dies Auswerten:
Int0_isr:
Portd.7 = 1
Disable Int0
Return
Nach einmaligem Sprung in die Interruptroutine soll der Interrupt ausgeschalten werden, das Funktioniert so weit.
In:
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.
$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
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
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
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