Che Guevara
17.06.2009, 16:09
Hallo Leute,
ich habe wieder mal ein Problem:
Für mein derzeitiges Projekt (ein Roboter mit 2 Motoren) wollte ich eine Kommunikation zwischen PC und dem Robi über zwei RFM12 funkmodule herstellen. Das Senden und Empfangen funktioniert mit beiden Modulen problemlos! Damit die µC nicht immer warten müssen, bis etwas "reingeflogen" kommt, wollte ich einen Interrupt auslösen lassen! Dazu habe ich den FFIT-Pin auf INT0 beim Mega32 gelegt. Das funktioniert auch, das überprüfe ich, indem ich eine LED in der ISR toggeln lasse. Wenn ich jetzt aber in der ISR die Daten holen möchte, bleibt das Programm irgendwo hängen :-( Hier mal mein Code eines µC:
' ################################################## #################################################
' ### generated. Take care that the chip supports all fuse bytes ###
' ### RF12-Test in Bascom ###
' ### Basiert auf Code von Benedikt K. ###
' ### Joachim Fossie Bär Reiter 04/2007 ###
' ### weiterentwickelt von: ###
' ### Wigbert Picht 18.06. ###
' ### Stringkennung 24.08 ###
' ### Hardware siehe Pollinboard ###
' ################################################## ################################################## ########
' ### ###
' ### RFM12 Master ###
' ### --------------- ###
' ################################################## ################################################## ######################################
$regfile = "m32def.dat"
$hwstack = 100 ' default use 32 for the hardware stack
$swstack = 100 'default use 10 for the SW stack
$framesize = 100
'$PROG &HFF,&HFF,&HD9,&H00' generated. Take care that the chip supports all fuse bytes.
$crystal = 16000000 'Hier Dein Quarz
$baud = 19200
Baud = 19200
Declare Sub Rf12_init
Declare Function Rf12_trans(byval Wert As Word) As Word
Declare Sub Rf12_setfreq(byval Freq As Single)
Declare Sub Rf12_setbandwith(byval Bandwith As Byte , Byval Gain As Byte , Byval Drssi As Byte)
Declare Sub Rf12_setbaud(byval Rfbaud As Long)
Declare Sub Rf12_setpower(byval Outpower As Byte , Byval Fskmod As Byte)
Declare Sub Rf12_ready
Declare Sub Rf12_txdata(byval Maxchar As Byte)
Declare Sub Rf12_rxdata(byval Maxchar As Byte)
Declare Sub Sendetext
Const Rf12freq = 433.92
Const Rf12baud = 19200
Const Maxchar = 32
'config the SPI in master mode.The clock must be a quarter of the slave cpu
' Hier ggf. den SoftSPI reinmachen
Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 128 , Noss = 1
' werden benötigt für rf12_ready
Spi_cs Alias Portb.4
Config Spi_cs = Output
Spi_sdo Alias Pinb.6
Set Spi_cs
'init the spi pins
Spiinit
' was so gebraucht wird
' Kennung
Dim Count As Byte
Dim Temp As Word
Dim Rfdata(32) As Byte
Dim Text As String * Maxchar At Rfdata Overlay
Dim Laenge As Byte
Dim Lean As Byte
Dim La As Byte
Dim L As Byte
Dim C As Byte
Dim Empf_wait As Byte
Dim Rufzeichen As String * 32
Dim Sendedata As String * 32
Dim Ruf As String * 32
Config Portc.7 = Output
Portc.7 = 1
Config Lcd = 20 * 4
Config Lcdpin = Pin , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.3 , E = Portc.4 , Rs = Portc.5
Config Lcdbus = 4
Initlcd
Cls
Cursor On Blink
Print "Init"
Call Rf12_init ' ein paar Register setzen (z.B. CLK auf 10MHz)
Print "Set Frequenz"
Call Rf12_setfreq(rf12freq) ' Sende/Empfangsfrequenz auf 433,92MHz einstellen
Print "Set Bandwith"
Call Rf12_setbandwith(4 , 1 , 4) ' 200kHz Bandbreite, -6dB Verstärkung, DRSSI threshold: -79dBm
Print "Set Baudrate"
Call Rf12_setbaud(rf12baud) ' 19200 baud
Print "Set Power" ' 1mW Ausgangangsleistung, 120kHz Frequenzshift
Call Rf12_setpower(0 , 6)
Config Pind.2 = Input
Portd.2 = 0
Config Int0 = Rising
Enable Int0
On Int0 Isr_von_int2
Enable Interrupts
' ################################################## ######################
' ###### Hauptproggi ################################################## ##
' ################################################## ######################
' Rufzeichen
Rufzeichen = "00000000"
' ################################################## #######################
Sendetext
' ################################################## #######################
Do
Call Rf12_rxdata(maxchar)
If Text = "Hallo" Then
Text = "return"
Call Rf12_txdata(maxchar)
Text = ""
Else
Text = "wrong"
Call Rf12_txdata(maxchar)
Text = ""
End If
Loop
End
' ################################################## ######################
' ###### Unterroutinen
' ################################################## ######################
Sub Rf12_init:
Waitms 150
Temp = Rf12_trans(&Hc0e0)
Temp = Rf12_trans(&H80d7)
Temp = Rf12_trans(&Hc2ab)
Temp = Rf12_trans(&Hca81)
Temp = Rf12_trans(&He000)
Temp = Rf12_trans(&Hc800)
Temp = Rf12_trans(&Hc4f7)
End Sub
Sub Rf12_setfreq(byval Freq As Single)
Freq = Freq - 430.00
Temp = Freq / 0.0025
If Temp < 96 Then
Temp = 96
Elseif Temp > 3903 Then
Temp = 3903
End If
Temp = Temp + &HA000
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_setbandwith(byval Bandwith As Byte , Byval Gain As Byte , Byval Drssi As Byte)
Drssi = Drssi And 7
Gain = Gain And 3
Temp = Bandwith And 7
Shift Temp , Left , 2
Temp = Temp + Gain
Shift Temp , Left , 3
Temp = Temp + Drssi
Temp = Temp + &H9400
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_setbaud(byval Rfbaud As Long )
Local Ltemp As Long
If Rfbaud < 663 Then Exit Sub
If Rfbaud < 5400 Then
Temp = 43104 / Rfbaud
Temp = Temp + &HC680
Else
Ltemp = 344828 / Rfbaud
Temp = Ltemp
Temp = Temp + &HC600
End If
Decr Temp
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_setpower(byval Outpower As Byte , Byval Fskmod As Byte)
Outpower = Outpower And 7
Temp = Fskmod And 15
Shift Temp , Left , 4
Temp = Temp + Outpower
Temp = Temp + &H9800
Temp = Rf12_trans(temp)
End Sub
'##########################
Sub Sendetext 'Aufbereitung des Text="Teststring"
Sendedata = Rufzeichen 'welcher String gebraucht wird
Laenge = Len(sendedata)
Lean = Laenge + 3
La = Laenge + 52 '50 Bei Empfänger subtrahieren-um bei Print Steuerzeichen zu umgehen
Ruf = Chr(la) + Sendedata
C = Checksum(ruf)
Text = Ruf + Chr(c)
Text = Text + " "
'Print Text 'Testprint
'Print L ; Sendedata ; C; 'Testprint
End Sub
'##########################
Sub Rf12_txdata(byval Maxchar As Byte)
'Disable Interrupts
Temp = Rf12_trans(&H8238)
Rf12_ready
Temp = Rf12_trans(&Hb8aa)
Rf12_ready
Temp = Rf12_trans(&Hb8aa)
Rf12_ready
Temp = Rf12_trans(&Hb8aa)
Rf12_ready
Temp = Rf12_trans(&Hb82d)
Rf12_ready
Temp = Rf12_trans(&Hb8d4)
Rf12_ready
For Count = 1 To Lean 'Veriable Länge duch Stringberechnung
'For Count = 1 To Maxchar
Rf12_ready 'hier kann das gesendete Datenpaket eingesehen werden
'Print Rfdata(count) ; "-";
Temp = &HB800 + Rfdata(count)
Temp = Rf12_trans(temp)
Next Count
Rf12_ready
Temp = Rf12_trans(&H8208)
'Enable Interrupts
End Sub
Sub Rf12_rxdata(byval Maxchar As Byte)
'Disable Interrupts
Temp = Rf12_trans(&H82c8)
Temp = Rf12_trans(&Hca81)
Temp = Rf12_trans(&Hca83)
For Count = 1 To Maxchar
Rf12_ready
Temp = Rf12_trans(&Hb000)
Rfdata(count) = Temp
Next Count
Temp = Rf12_trans(&H8208)
'Enable Interrupts
End Sub
Function Rf12_trans(byval Wert As Word) As Word
Local Lowbyte As Byte
Local Highbyte As Byte
Lowbyte = Wert And 255
Shift Wert , Right , 8
Reset Spi_cs
Highbyte = Spimove(wert)
Lowbyte = Spimove(lowbyte)
Set Spi_cs
Temp = Highbyte * 256
Temp = Temp + Lowbyte
Rf12_trans = Temp
End Function
Sub Rf12_ready
Reset Spi_cs
While Spi_sdo = 0 'In der Sim. auf 1 stellen
Wend
End Sub
'################################################# ##############################
Isr_von_int2:
Set Flag
Toggle Portc.7
Return
So funktioniert es noch! Wenn ich jetzt aber diesen Code in die ISR von INT0 (Hier falscher name, aber kein problem) schreibe, dann bleibt der µC hängen:
Call Rf12_rxdata(maxchar)
If Text = "Hallo" Then
Text = "return"
Call Rf12_txdata(maxchar)
Text = ""
Else
Text = "wrong"
Call Rf12_txdata(maxchar)
Text = ""
End If
Kann es sein, dass die SPI in der ISR deaktiviert wird??
Was muss ich machen, damit es auch funktioniert, wenn diese Text-Passage auch in der ISR funktioniert?!
Was macht eigentlich die Sub Sendetext? Also kann ich mit ihr etwas senden?
Muss man eigentlich so senden, wie ich es mache, also:
Text = "......"
Call RF12_txdata(maxchar)
Text = ""
oder geht es auch einfacher?
Gruß
Chris
ich habe wieder mal ein Problem:
Für mein derzeitiges Projekt (ein Roboter mit 2 Motoren) wollte ich eine Kommunikation zwischen PC und dem Robi über zwei RFM12 funkmodule herstellen. Das Senden und Empfangen funktioniert mit beiden Modulen problemlos! Damit die µC nicht immer warten müssen, bis etwas "reingeflogen" kommt, wollte ich einen Interrupt auslösen lassen! Dazu habe ich den FFIT-Pin auf INT0 beim Mega32 gelegt. Das funktioniert auch, das überprüfe ich, indem ich eine LED in der ISR toggeln lasse. Wenn ich jetzt aber in der ISR die Daten holen möchte, bleibt das Programm irgendwo hängen :-( Hier mal mein Code eines µC:
' ################################################## #################################################
' ### generated. Take care that the chip supports all fuse bytes ###
' ### RF12-Test in Bascom ###
' ### Basiert auf Code von Benedikt K. ###
' ### Joachim Fossie Bär Reiter 04/2007 ###
' ### weiterentwickelt von: ###
' ### Wigbert Picht 18.06. ###
' ### Stringkennung 24.08 ###
' ### Hardware siehe Pollinboard ###
' ################################################## ################################################## ########
' ### ###
' ### RFM12 Master ###
' ### --------------- ###
' ################################################## ################################################## ######################################
$regfile = "m32def.dat"
$hwstack = 100 ' default use 32 for the hardware stack
$swstack = 100 'default use 10 for the SW stack
$framesize = 100
'$PROG &HFF,&HFF,&HD9,&H00' generated. Take care that the chip supports all fuse bytes.
$crystal = 16000000 'Hier Dein Quarz
$baud = 19200
Baud = 19200
Declare Sub Rf12_init
Declare Function Rf12_trans(byval Wert As Word) As Word
Declare Sub Rf12_setfreq(byval Freq As Single)
Declare Sub Rf12_setbandwith(byval Bandwith As Byte , Byval Gain As Byte , Byval Drssi As Byte)
Declare Sub Rf12_setbaud(byval Rfbaud As Long)
Declare Sub Rf12_setpower(byval Outpower As Byte , Byval Fskmod As Byte)
Declare Sub Rf12_ready
Declare Sub Rf12_txdata(byval Maxchar As Byte)
Declare Sub Rf12_rxdata(byval Maxchar As Byte)
Declare Sub Sendetext
Const Rf12freq = 433.92
Const Rf12baud = 19200
Const Maxchar = 32
'config the SPI in master mode.The clock must be a quarter of the slave cpu
' Hier ggf. den SoftSPI reinmachen
Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 128 , Noss = 1
' werden benötigt für rf12_ready
Spi_cs Alias Portb.4
Config Spi_cs = Output
Spi_sdo Alias Pinb.6
Set Spi_cs
'init the spi pins
Spiinit
' was so gebraucht wird
' Kennung
Dim Count As Byte
Dim Temp As Word
Dim Rfdata(32) As Byte
Dim Text As String * Maxchar At Rfdata Overlay
Dim Laenge As Byte
Dim Lean As Byte
Dim La As Byte
Dim L As Byte
Dim C As Byte
Dim Empf_wait As Byte
Dim Rufzeichen As String * 32
Dim Sendedata As String * 32
Dim Ruf As String * 32
Config Portc.7 = Output
Portc.7 = 1
Config Lcd = 20 * 4
Config Lcdpin = Pin , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.3 , E = Portc.4 , Rs = Portc.5
Config Lcdbus = 4
Initlcd
Cls
Cursor On Blink
Print "Init"
Call Rf12_init ' ein paar Register setzen (z.B. CLK auf 10MHz)
Print "Set Frequenz"
Call Rf12_setfreq(rf12freq) ' Sende/Empfangsfrequenz auf 433,92MHz einstellen
Print "Set Bandwith"
Call Rf12_setbandwith(4 , 1 , 4) ' 200kHz Bandbreite, -6dB Verstärkung, DRSSI threshold: -79dBm
Print "Set Baudrate"
Call Rf12_setbaud(rf12baud) ' 19200 baud
Print "Set Power" ' 1mW Ausgangangsleistung, 120kHz Frequenzshift
Call Rf12_setpower(0 , 6)
Config Pind.2 = Input
Portd.2 = 0
Config Int0 = Rising
Enable Int0
On Int0 Isr_von_int2
Enable Interrupts
' ################################################## ######################
' ###### Hauptproggi ################################################## ##
' ################################################## ######################
' Rufzeichen
Rufzeichen = "00000000"
' ################################################## #######################
Sendetext
' ################################################## #######################
Do
Call Rf12_rxdata(maxchar)
If Text = "Hallo" Then
Text = "return"
Call Rf12_txdata(maxchar)
Text = ""
Else
Text = "wrong"
Call Rf12_txdata(maxchar)
Text = ""
End If
Loop
End
' ################################################## ######################
' ###### Unterroutinen
' ################################################## ######################
Sub Rf12_init:
Waitms 150
Temp = Rf12_trans(&Hc0e0)
Temp = Rf12_trans(&H80d7)
Temp = Rf12_trans(&Hc2ab)
Temp = Rf12_trans(&Hca81)
Temp = Rf12_trans(&He000)
Temp = Rf12_trans(&Hc800)
Temp = Rf12_trans(&Hc4f7)
End Sub
Sub Rf12_setfreq(byval Freq As Single)
Freq = Freq - 430.00
Temp = Freq / 0.0025
If Temp < 96 Then
Temp = 96
Elseif Temp > 3903 Then
Temp = 3903
End If
Temp = Temp + &HA000
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_setbandwith(byval Bandwith As Byte , Byval Gain As Byte , Byval Drssi As Byte)
Drssi = Drssi And 7
Gain = Gain And 3
Temp = Bandwith And 7
Shift Temp , Left , 2
Temp = Temp + Gain
Shift Temp , Left , 3
Temp = Temp + Drssi
Temp = Temp + &H9400
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_setbaud(byval Rfbaud As Long )
Local Ltemp As Long
If Rfbaud < 663 Then Exit Sub
If Rfbaud < 5400 Then
Temp = 43104 / Rfbaud
Temp = Temp + &HC680
Else
Ltemp = 344828 / Rfbaud
Temp = Ltemp
Temp = Temp + &HC600
End If
Decr Temp
Temp = Rf12_trans(temp)
End Sub
Sub Rf12_setpower(byval Outpower As Byte , Byval Fskmod As Byte)
Outpower = Outpower And 7
Temp = Fskmod And 15
Shift Temp , Left , 4
Temp = Temp + Outpower
Temp = Temp + &H9800
Temp = Rf12_trans(temp)
End Sub
'##########################
Sub Sendetext 'Aufbereitung des Text="Teststring"
Sendedata = Rufzeichen 'welcher String gebraucht wird
Laenge = Len(sendedata)
Lean = Laenge + 3
La = Laenge + 52 '50 Bei Empfänger subtrahieren-um bei Print Steuerzeichen zu umgehen
Ruf = Chr(la) + Sendedata
C = Checksum(ruf)
Text = Ruf + Chr(c)
Text = Text + " "
'Print Text 'Testprint
'Print L ; Sendedata ; C; 'Testprint
End Sub
'##########################
Sub Rf12_txdata(byval Maxchar As Byte)
'Disable Interrupts
Temp = Rf12_trans(&H8238)
Rf12_ready
Temp = Rf12_trans(&Hb8aa)
Rf12_ready
Temp = Rf12_trans(&Hb8aa)
Rf12_ready
Temp = Rf12_trans(&Hb8aa)
Rf12_ready
Temp = Rf12_trans(&Hb82d)
Rf12_ready
Temp = Rf12_trans(&Hb8d4)
Rf12_ready
For Count = 1 To Lean 'Veriable Länge duch Stringberechnung
'For Count = 1 To Maxchar
Rf12_ready 'hier kann das gesendete Datenpaket eingesehen werden
'Print Rfdata(count) ; "-";
Temp = &HB800 + Rfdata(count)
Temp = Rf12_trans(temp)
Next Count
Rf12_ready
Temp = Rf12_trans(&H8208)
'Enable Interrupts
End Sub
Sub Rf12_rxdata(byval Maxchar As Byte)
'Disable Interrupts
Temp = Rf12_trans(&H82c8)
Temp = Rf12_trans(&Hca81)
Temp = Rf12_trans(&Hca83)
For Count = 1 To Maxchar
Rf12_ready
Temp = Rf12_trans(&Hb000)
Rfdata(count) = Temp
Next Count
Temp = Rf12_trans(&H8208)
'Enable Interrupts
End Sub
Function Rf12_trans(byval Wert As Word) As Word
Local Lowbyte As Byte
Local Highbyte As Byte
Lowbyte = Wert And 255
Shift Wert , Right , 8
Reset Spi_cs
Highbyte = Spimove(wert)
Lowbyte = Spimove(lowbyte)
Set Spi_cs
Temp = Highbyte * 256
Temp = Temp + Lowbyte
Rf12_trans = Temp
End Function
Sub Rf12_ready
Reset Spi_cs
While Spi_sdo = 0 'In der Sim. auf 1 stellen
Wend
End Sub
'################################################# ##############################
Isr_von_int2:
Set Flag
Toggle Portc.7
Return
So funktioniert es noch! Wenn ich jetzt aber diesen Code in die ISR von INT0 (Hier falscher name, aber kein problem) schreibe, dann bleibt der µC hängen:
Call Rf12_rxdata(maxchar)
If Text = "Hallo" Then
Text = "return"
Call Rf12_txdata(maxchar)
Text = ""
Else
Text = "wrong"
Call Rf12_txdata(maxchar)
Text = ""
End If
Kann es sein, dass die SPI in der ISR deaktiviert wird??
Was muss ich machen, damit es auch funktioniert, wenn diese Text-Passage auch in der ISR funktioniert?!
Was macht eigentlich die Sub Sendetext? Also kann ich mit ihr etwas senden?
Muss man eigentlich so senden, wie ich es mache, also:
Text = "......"
Call RF12_txdata(maxchar)
Text = ""
oder geht es auch einfacher?
Gruß
Chris