PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RFM12 mit ATMEGA32 - Interrupt problem



Che Guevara
17.06.2009, 15: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

Che Guevara
18.06.2009, 18:03
Kann mir den niemand helfen?!
Das ganze ist echt wichtig und ich habe momentan ein kleines Zeitproblem :-(
Bitte schreibt irgendwas (*verzweifel*)... mir genügt auch schon ein "Was meinst du damit jetzt? Ich verstehe deine Frage nicht!" , etc.....

Gruß
Chris

peterfido
18.06.2009, 21:08
Kann sein, dass deine Interrupst-Routine zu lang ist und während der Abarbeitung bereits ein neuer kommt. Am besten nur ein Flag im Interrupt setzen und dieses in der Hauptschleife abfragen und dann zum Empfangen übergehen. Oder halt als erstes den Int0 disablen und am Ende der Routine wieder enablen.

Che Guevara
18.06.2009, 21:29
Hallo peterfido,

erstmal danke für deine Antwort!
Jedoch habe ich beides schon ausprobiert, aber ohne Erfolg! Das hätte ich vielleicht in meinem ersten Post noch erwähnen sollen!!

Welchen Pin soll ich den jetzt überhaupt benutzen? FFIT oder nIRQ?
Was ich auch noch sagen sollte ist, dass wenn ich in der ISR den Teil aus der Hauptschleife einfüge, die LED dann nicht mehr getoggelt wird!

Gruß
Chris

stefan_Z
19.06.2009, 08:56
Ich würde sagen, dass der INT immer weiter ausgelöst wird, denn der Zustand verschwindet erst nach dem Auslesen des RFM, oder?
Also als 1. in der ISR den INT ausschalten und dann als letztes, bzw. nach dem Auslesen der Daten, wieder anschalten.

Che Guevara
21.06.2009, 15:07
Hallo stefan_Z,

danke für deine Antwort, aber das habe ich schon ausprobiert (steht glaube ich auch oben;-))!

Hat jemand sowas vielleicht schon am laufen??

Gruß
Chris

Che Guevara
25.06.2009, 20:50
Hat den keiner eine Idee??
Oder hat jemand das selbst schon am laufen??

Gruß
Chris

Che Guevara
05.07.2009, 14:48
Hallo Leute,

bitte helft mir! Das ganze ist sehr wichtig, ich muss das bis zum 15. Juli am laufen haben, den da muss ich das projekt in der Schule vorstellen! Und ich habe noch andere Probleme, welche ich erst lösen kann, wenn dieses gelöst ist! Es wäre wirklich toll, wenn jemand eine Idee hätte?!

Es ginge auch, wenn ich das RFM12 an einen ATTiny2313 anschließen könnte, allerdings passt da der Code nicht drauf :-(
Mit dem könnte ich dann empfangen, das empfange unverarbeitet an den ATMega32 (Hauptcontroller) weitersenden und dort verarbeiten. Der ATTiny2313 müsste dann nurnoch das empfange zurücksenden, um sicherzugehen, dass alles richtig empfangen wurde... Hat jemand vielleicht dafür einen Code?

Gruß
Chris

stefan_Z
05.07.2009, 16:19
Sonst schau dir mal bei Elektor das Projekt mit den RFM12 aus der Januarausgabe an!
Wenn du dich bei Elektor.de einloggst, kasst du den source laden.

Che Guevara
05.07.2009, 16:57
Hallo stefan_Z,

danke für deine Antwort, allerdings kannte ich den Code schon.

Er beantwortet leider keine meiner Fragen, weder die Frage nach einem Code für den ATTina2313 noch die Frage, welchen Anschluss ich für einen Interrupt verwenden muss!

Gruß
Chris

CPU_Heizer
05.07.2009, 18:25
Wieso denn grad ein ATTiny2313? nimm doch einen, auf den dein Prog passt, und der genug Pins hat.

Und versuch mal in der Interrupt-Prozedur nur ein Flag zu setzen und die Kommunikation dann in der Hauptschleife durchzuführen.

Che Guevara
05.07.2009, 20:23
Hallo CPU_Heizer,

danke für deine Antwort!
Der ATTiny2313 deßhalb, weil ich noch ein paar rumliegen habe und nicht mehr bestellen möchte! Notfalls würde ich noch einen 2. ATMega32 nehmen, aber der wäre sooooooooooooooooooooo stark oversized XD

Das mit dem Flag hab ich schon probiert:



Isr_von_int2:
Set Flag
Toggle Portc.7
Return


Das funktioniert allerdings nicht! Der 1. Code auf dieser Seite beinhaltet diese Textpassage!
Was könnte ich den noch machen??

Gruß
Chris

Besserwessi
05.07.2009, 20:45
Die Version mit der Ausgabe in der ISR ging nicht, weil die ISR viel zu lang ist. Ein Ausganbe von text per Print, aufs LCD und ähnliches sind in einer ISR fast immer zu langsam.

Der letzte Code ist das selbe wie die ISR im ersten Code. Daran kann es also nicht liegen, muß also der Rest sein, der hier nicht gzeigt wird.

Che Guevara
05.07.2009, 22:08
Hallo Besserwessi,

danke für deine Antwort!
Hier ist mein aktueller Code:


' ################################################## ################################################## ######################################
' ### 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 Text As String * Lean At Rfdata Overlay 'Text mit variabler Länge
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



Dim Flag_int0_input As Bit

Flag_int0_input = 0

Config Portc.7 = Output
Portc.7 = 1
Config Portc.0 = Output
Portc.0 = 1



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_int0
'Disable Int0

Enable Interrupts
' ################################################## ######################
' ###### Hauptproggi ################################################## ##
' ################################################## ######################

' Rufzeichen

Rufzeichen = "Christoph" 'mein Rufzeichen oder sonst ein String

'mit Timer
' ################################################## #######################

Sendetext 'Sub Stringverarbeitung zum Datenpaket
'später in Schleife
' ################################################## #######################


'Text = "Dies ist ein 433MHz Test !!!!!{013}{010}"

' Je nachdem ob Sender oder Empfänger die entsprechenden Zeilen aktivieren
Do


If Flag_int0_input = 1 Then
Disable Int0
Flag_int0_input = 0
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
Enable Int0
End If


Loop


End 'end program


' ################################################## ######################
' ###### 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_int0:
Disable Int0
Toggle Portc.7
Flag_int0_input = 1
Waitms 100
Enable Int0
Return


Mir ist aufgefallen, dass sobald die "If Flag_int0_input = 1 then" Abfrage herausgenommen wird aus dem Code, wird die Led getoggelt! Daraus schließe ich, dass die Abfrage die ISR_von_int0 irgendwie blockiert!
ABER WARUM??

Das mit den Waitms xy in der ISR ist übrigens nur dazu da, weil nicht nur immer ein Impuls kommt, sondern so ca. 10 Highs in kurzen Abständen hintereinander! Wenn ich das rausmache, ändert sich überhaupt nichts!

Gruß
Chris

Che Guevara
05.07.2009, 22:32
Mir ist jetzt noch etwas aufgefallen:

Wenn ich "Call rf12_rxdata(maxchar)" vor die "If flag_int0_input = 1 then" Abfrage schreibe, dann funktionierts! Wenn ich jedoch die Sub in die Isr_von_int0 - Routine schreibe und nicht mehr im loop, dann funktionierts nicht mehr!
Wichtig aus der Routine sind folgende Zeilen:


Temp = Rf12_trans(&H82c8)
Temp = Rf12_trans(&Hca81)
Temp = Rf12_trans(&Hca83)
Rf12_ready
Temp = Rf12_trans(&Hb000)
Temp = Rf12_trans(&H8208)


Was machen den diese Zeilen??
Und wie kann ich mein Problem jetzt beheben?

Gruß
Chris

Besserwessi
05.07.2009, 22:38
Der Aufruf von wait 100 ms hat in einer ISR nichts zu suchen. Eine ISR sollte in der Regel (das heißt für einen Anfänger erst mal immer) nicht länger als etwa 1 ms (besser 10 µs) dauern.

Auch das auschalten und wieder einschalten des interrupts in der ISR macht wenig Sinn, denn in der ISR sind weitere Interrupts ohnehin blockiert. Das verhindert nur das noch eine Int0 ISR ausgelöst wird, die dann später ausgeführt wird. Wenn man die Wartezeit raus hat, ist da auch fast kein code mehr zwischen und man kann das aus-/Ein-schalten auch ganz sparen.

So wie der Code ist, wartet die ISR etwa 100 ms und verpaßt damit die ganze Nachricht. Der code hinter dem IF ... wartet dann auf eine Nachricht mit etwa 8 Zeichen, die natürlich nicht so schnell kommt. An sich solle die 2 te Nachricht dann aber ankommen und die LED zum Tooglen bringen.

Che Guevara
05.07.2009, 22:52
Ok, hab jetzt das Waitms und Enable/Disable rausgemacht!
Hat jedoch keine Besserung gebracht!

Habs jetzt so gemacht:


' ################################################## ################################################## ######################################
' ### 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 Text As String * Lean At Rfdata Overlay 'Text mit variabler Länge
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



Dim Flag_int0_input As Byte

Flag_int0_input = 0

Config Portc.7 = Output
Portc.7 = 1
Config Portc.0 = Output
Portc.0 = 1



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_int0
'Disable Int0

Config Timer2 = Timer , Prescale = 256
Timer2 = 156
Enable Timer2
On Timer2 Isr_von_timer2

Enable Interrupts
' ################################################## ######################
' ###### Hauptproggi ################################################## ##
' ################################################## ######################

' Rufzeichen

Rufzeichen = "Christoph" 'mein Rufzeichen oder sonst ein String

'mit Timer
' ################################################## #######################

Sendetext 'Sub Stringverarbeitung zum Datenpaket
'später in Schleife
' ################################################## #######################


'Text = "Dies ist ein 433MHz Test !!!!!{013}{010}"

' Je nachdem ob Sender oder Empfänger die entsprechenden Zeilen aktivieren
Do



If Flag_int0_input = 1 Then

Flag_int0_input = 0
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

End If

Loop


End 'end program


' ################################################## ######################
' ###### 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 Int0
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 Int0
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_int0:
Toggle Portc.7
Flag_int0_input = 1
Return

Isr_von_timer2:
Timer2 = 156
Call Rf12_rxdata(maxchar)
Return


Das funktioniert jetzt!
Da ich in meinem anderen Code, der auf dem Roboter läuft, auch einen Timer-Interrupt mit ähnlicher Häufigkeit habe, brauche ich dafür auch keinen extra Timer! Das ganze ist zwar nicht sehr elegant, aber da ich mich jetzt schon seit 2 Wochen damit herumplage, lasse ich es jetzt so, bis mir jemand eine andere, elegantere Lösung sagen kann :-D

Gruß
Chris