PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RFM12 Module von Pollin am AVR



robodriver
25.04.2008, 20:57
Hallo Zusammen,

ich hab mir jetzt für meinen Roboter auch 2 RFM12 Module von Pollin gekauft. Um auch mal von meinem Pc aus mit diesem kommunizieren zu können.

Dazu habe ich mir zunächst eine Schaltung gebaut die wie folgt aussieht:
PC --[RS232]--> MAX232 --[TTL-RS232]--> AVR (Mega8) --[SPI]--> RFM12

So weit so gut.
Dann hab ich auf den Controller folgendes Test-Programm aufgespielt:
(Erstmal den PC-Teil weg gelassen)


$regfile = "m8def.dat"
$crystal = 8000000

'DDR = &B76543210 ; 0=Eingang ; 1=Ausgang
Ddrb = &B00101100
Ddrc = &B00000100
Ddrd = &B01000000
Portb = &B00000000
Portc = &B00000000
Portd = &B00000000

Config Spi = Hard , Data Order = Msb , Master = Yes , Polarity = High , Phase = 0 , Clockrate = 4 , Noss = 0

Declare Sub Rfm_init
Declare Sub Rfm_send

Dim Text As String * 20
Dim Spi_data As Integer '2 Bytes
Dim Zeichen As String * 1
Dim Text_send As String * 50
Dim A As Byte
Dim B As Byte
Dim Temp As String * 1

Led Alias Portd.6

Enable Interrupts

Spiinit

wait 1

Rfm_init
Ddrc.0 = 1
Portc.0 = 1
Ddrd.2 = 0

Do
Text_send = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
Rfm_send
Wait 1
Loop


Sub Rfm_init
Set Led
Reset Portc.2 'Modulpower aus
Waitms 400
Set Portc.2 'Modulpower an
Waitms 200
Spi_data = &H80D7
Spiout Spi_data , 2
Spi_data = &H8239
Spiout Spi_data , 2
Spi_data = &HA640
Spiout Spi_data , 2
Spi_data = &HC647
Spiout Spi_data , 2
Spi_data = &H94A0
Spiout Spi_data , 2
Spi_data = &HC2AC
Spiout Spi_data , 2
Spi_data = &HCA81
Spiout Spi_data , 2
Spi_data = &HC483
Spiout Spi_data , 2
Spi_data = &H9850
Spiout Spi_data , 2
Spi_data = &HE000
Spiout Spi_data , 2
Spi_data = &HC800
Spiout Spi_data , 2
Spi_data = &HC400
Spiout Spi_data , 2
Reset Led
End Sub

Sub Rfm_send
Set Led
Spi_data = &H0000
Spiout Spi_data , 2
Spi_data = &H8239
Spiout Spi_data , 2


Spi_data = &HAA
Do
Loop Until Pind.2 = 1
Spiout Spi_data , 1
Spi_data = &HAA
Do
Loop Until Pind.2 = 1
Spiout Spi_data , 1
Spi_data = &HAA
Do
Loop Until Pind.2 = 1
Spiout Spi_data , 1
Spi_data = &H2D
Do
Loop Until Pind.2 = 1
Spiout Spi_data , 1
Spi_data = &HD4
Do
Loop Until Pind.2 = 1
Spiout Spi_data , 1
For B = 1 To 100
For A = 1 To Len(text_send)
Temp = Mid(text_send , A , 1)
Spi_data = Asc(temp)
Do
Loop Until Pind.2 = 1
Spiout Spi_data , 1
Next A
Next B
Reset Led
End Sub

End

Anschluss vom RFM zum AVR ist wie folgt:

RFM12 -> M8
SCK -> SCK
SDO -> MISO
SDI -> MOSI
nSEL -> SS
nIRQ -> INT0
VDD -> PC2
FSK -> PC0
DCLK, FFIT -> PC1
NINT, VDI -> PB1

Das programm sollte nun also alle 1 Sekunden Daten abschicken. Während des sendens müsste die LED leuchten.
Nun hab ich mal zusammen mit einem Kollegen ein Funkgerät daneben gehalten. Man konnte tatsächlich hören das was gesendet wird :)
ABER: Was mich irritiert hatte: Während die LED leuchtete war nur rauschen zu hören. Und so lange wie die LED aus war, war dann ein Piepton zu hören. Wie kann das denn sein? Ich dachte das Modul sendet sofort das was vom Bus kommt. Denn der hat doch nur ein 16 Bit FIFO. Wie kann er dann eine ganze Sekunde lang was senden, während auf dem Bus nichts geschickt wird?
Aber soll erstmal zweitrangig sein. Es wird ja schonmal irgendwas gesendet.

Nun hab ich mich auch mal an den Empfänger gewagt:
Das Gebilde schaut wie folgt aus:

RFM12 --[SPI]--> AVR (Mega32)
So, als Programm hab ich folgendes geschrieben:


$regfile = "m32def.dat"
$crystal = 8000000

Ddra = &B01111000
Ddrb = &B10110000
Ddrc = &B11110000
Ddrd = &B00010000
Porta = &B00000000
Portb = &B00000100
Portc = &B00000000
Portd = &B00001000

Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portc.7 , Db5 = Portc.6 , Db6 = Portc.5 , Db7 = Portc.4 , E = Porta.6 , Rs = Porta.4
Config Lcdbus = 4
Config Spi = Hard , Data Order = Msb , Master = Yes , Polarity = High , Phase = 0 , Clockrate = 4 , Noss = 0

Enable Interrupts

Waitms 10
Initlcd
Cursor Off
Waitms 10

Spiinit
Waitms 100

'RF12 Init:
Waitms 200
Locate 1 , 1
Lcd "Start INIT..."
Reset Porta.3 'Modulpower aus
Waitms 1200
Set Porta.3
Waitms 200 'Modulpower an

Spi_data = &H80D7
Spiout Spi_data , 2
Spi_data = &H82D9
Spiout Spi_data , 2
Spi_data = &HA640
Spiout Spi_data , 2
Spi_data = &HC647
Spiout Spi_data , 2
Spi_data = &H94A0
Spiout Spi_data , 2
Spi_data = &HC2AC
Spiout Spi_data , 2
Spi_data = &HCA81
Spiout Spi_data , 2
Spi_data = &HC483
Spiout Spi_data , 2
Spi_data = &H9850
Spiout Spi_data , 2
Spi_data = &HE000
Spiout Spi_data , 2
Spi_data = &HC800
Spiout Spi_data , 2
Spi_data = &HC400
Spiout Spi_data , 2

Spi_data = &HCA81
Spiout Spi_data , 2
'Enable FIFO
Spi_data = &HCA83
Spiout Spi_data , 2
'Set Portb.2

Locate 1 , 1
Lcd "Wait for data..."
Set Error_led

Do
Loop Until Pinb.2 = 0

Spi_data = &H0000
Spiout Spi_data , 2

Spi_data = &HB000
Spiout Spi_data , 2

Locate 1 , 1
Lcd "Jetzt kommt was"
Set Error_led

Do
Loop

End


Anschluss ist hier wie folgt:
RFM12 -> M32
SCK -> SCK
SDO -> MISO
SDI -> MOSI
nSEL -> SS
nIRQ -> INT2 (PB2)
VDD -> PA3
FSK -> PA0
DCLK, FFIT -> PA1
NINT, VDI -> PA2

Das Proggi läuft durch, bis auf dem Display drinne steht "Wait for data..."
Und da bleibt es stehen. Ganz egal was ich mit dem Sender mache. :(

Beim durchstöbern der Suche hab ich hier noch ein anderes Empfangs-Programm gefunden, welches ich getestet habe.
Bei diesem Blick ich allerdings nicht durch :(
Hier mal der Code:



$regfile = "m32def.dat"
$crystal = 8000000

'DDR = &B76543210 ; 0=Eingang ; 1=Ausgang
Ddra = &B01111000
Ddrb = &B10110000
Ddrc = &B11110000
Ddrd = &B00010000
Porta = &B00000000
Portb = &B00000100
Portc = &B00000000
Portd = &B00001000

Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portc.7 , Db5 = Portc.6 , Db6 = Portc.5 , Db7 = Portc.4 , E = Porta.6 , Rs = Porta.4
Config Lcdbus = 4

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_readys
Declare Sub Rf12_txdata(byval Maxchar As Byte)
Declare Sub Rf12_rxdata(byval Maxchar As Byte)
Declare Sub Senden
Declare Sub Empfangen

Const Rf12freq = 433.92
Const Rf12baud = 1200
Const Maxchar = 16

' 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

Led Alias Portd.4 'Im Text als Portd.7


Waitms 20

Initlcd
Cursor Off

Waitms 10

Locate 1 , 1
Lcd " Cyberdriver 2"
Locate 2 , 1
Lcd " Test-Programm"
Wait 1

' werden benötigt für rf12_ready
Spi_cs Alias Portb.4 ' SS-Pin
Config Spi_cs = Output
Spi_sdo Alias Pinb.6 ' MISO-PIN
Set Spi_cs

' init the spi pins
Spiinit

Dim Count As Byte
Dim Temp As Word
Dim Rfdata(32) As Byte
Dim Text As String * Maxchar At Rfdata Overlay
'Dim J As Byte

Locate 1 , 1 : Lcd "Init RFM12 "
Waitms 100
Call Rf12_init ' ein paar Register setzen (z.B. CLK auf 10MHz)
Locate 1 , 1 : Lcd "Set Frequenz "
Waitms 100
Call Rf12_setfreq(rf12freq) ' Sende/Empfangsfrequenz auf 433,92MHz einstellen
Locate 1 , 1 : Lcd "Set Bandwith "
Waitms 100
Call Rf12_setbandwith(4 , 1 , 4) ' 200kHz Bandbreite, -6dB Verstärkung, DRSSI threshold: -79dBm
Locate 1 , 1 : Lcd "Set Baudrate "
Waitms 100
Call Rf12_setbaud(rf12baud) ' 19200 baud
Locate 1 , 1 : Lcd "Set Tx-Power "
Waitms 100
Call Rf12_setpower(0 , 6) ' 1mW Ausgangangsleistung, 120kHz Frequenzshift


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

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

Do ' Ewigschleife
Empfangen
Toggle Led
Locate 1 , 1 : Lcd "Ready "
Wait 1
Loop

End

' ################################################## ######################
' ####### Tranceiverroutinen
' ################################################## ######################

Sub Empfangen
Locate 1 , 1 : Lcd "Empfange "
Waitms 100
Locate 2 , 1 : Lcd " "
Locate 2 , 1
Call Rf12_rxdata(maxchar)
For Count = 1 To Maxchar
Lcd Chr(rfdata(count)) ;
Waitms 100
Next Count
End Sub

Sub Senden
Locate 1 , 1 : Lcd "Sende "
Waitms 100
Call Rf12_txdata(maxchar)
Waitms 10
End Sub

' ################################################## ######################
' ###### 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 Rf12_txdata(byval Maxchar As Byte)
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 Maxchar
Rf12_ready
Temp = &HB800 + Rfdata(count)
Temp = Rf12_trans(temp)
Next Count
Rf12_ready
Temp = Rf12_trans(&H8208)
End Sub

Sub Rf12_rxdata(byval Maxchar As Byte)
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)
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
Local I As Word
Reset Spi_cs
For I = 1 To 65000
If Spi_sdo = 1 Then Exit For
Next
End Sub


Auf dem Display steht dann immer "Empfange"
Nach einiger Zeit läuft dann die untere Zeile mit wilden Zeichen voll (Das Zeichen gibts im Display-Datenblatt nicht mal, sind grob gesagt 4 waagerechte striche übereinander).
So, an dem Verhalten ändert sich aber absolut nichts, ob ich den sender an hab oder aus. Das verhalten ist immer exakt gleich.

Hm, nun ja. Hoffe das sich jemand diesen Langen Text durchliest.
Wäre echt super dankbar für jede Hilfe.
Komm hier echt absolut nimmer weiter.
Will zumidnest mal ein Paar Zeichen übertragen können.
Ich denke danach würd ich selbst weiter kommen.

Hoffe auf hilfe.
Gruß, euer Robodriver

raggy
26.04.2008, 14:27
Hallo
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=31961&highlight=rfm12
seh dir mal das untere Programm von Knickohr an und die Pinbelegung.
Das Programm funktioniert bei mir auf selbst gebauten Platinen ohne Probleme allerdings habe ich int nicht angeschlossen und FSK mit 10 Kohm gegen 5V+ gelegt.
Desweiteren seh mal bei google und glaube auch hier nach ,mit dem Pollinboard soll es mit dem Optokoppler Probleme geben (behoben von Pollin ?) die haben alle bruecken eingebaut soweit ich gelesen hab.Wollte mir auch eins holen darum habe ich erstmal durchgelesen ob das Board was ist.
Ich hoffe ich konnte dir weiterhelfen
Gruß raggy

robodriver
26.04.2008, 16:58
Danke für deine Antwort,

weiter bringt mich das allerdings nicht.

Das Programm von Knickohr ist ja exakt das was ich hier gepostet habe und auf meinem Controller getestet habe. Hab lediglich die Pins entsprechend angepasst.
FSK mal als Eingang konfiguriert und den Pull-Up Widerstand aktiviert (im geposteten Programm ist der noch aus, habs aber auch mit pull-up schonmal probiert), ergibt ja den gleichen Effekt.
int ist ja bei mir auch als Eingang.
Und beim empfangen läuft wie gesagt alle 1 Sekunde die unter Display Zeile mit einem komischen, nichtidentifizierbarem Zeichen voll (Welches das Display laut Datenblatt gar nicht beinhaltet)

Das Pollinboard hab ich nicht. Das ist eine Schaltung auf Streifenrasterplatinen zusammen gelötet.
[/list]

raggy
26.04.2008, 17:22
Hi
ich vermisse in deiner Pin aufstellung Gnd
AVR und RFM12 oder so sollten gemeinsam Gnd haben
Zum anderen die Baud hat nichts mit der seriellen schnittstelle zu tun,es muß an dem Sender und Empfaenger gleich eingestellt werden durch die Initalisierung am Programm anfang.
Wenn du an dem Programm nichts veraendert hast als nur die Pin dann muß es ansich laufen,wuerde die Hardware noch mal nachsehen ob sich da nicht was eingeschlichen hatBei mir funktioniert das Programm sowohl mit Atmega8 als auch mit Atmega16 /32

robodriver
26.04.2008, 17:35
Also jetzt hab ich auch mal am Sender das Programm von Knickohr rein geladen.

Der Sender arbeitet ja mit einem Mega8, also musste ich da keinerlei Änderungen am Programm machen.

Der Empfänger arbeitet mit einem Mega 32. Desshalb musste ich da ein wenig anpassen.
Aber ich blick in dem Programm net durch. Das ist mir zu verschachtelt.

Warum läuft denn beim Empfänger ständig die untere Zeile mit diesem merkwürdigem Zeichen voll? Obwohl nichts empfangen werden kann.
Muss der Empfänger nicht so lange nichts machen, bis er was empfängt?

Die beiden GND vom Modul liegen auf dem gleichen GND wie der Controller.

Die Hardware hab ich schon mehrfach durchgemessen, aber keine Fehler gefunden.

Die Modul-Initialisierung läuft übrigens bei beiden Modulen scheinbar fehlerfrei duch


^^ Nachtrag:
Ach ja, einwas ist bei mir noch anders als bei Knickohr.
Meine Schaltungen laufen beide auf 8MHz
Hab das im Programm natürlich bei der Taktung umgeschrieben.
Dürfte doch eigentlich nichts aus machen oder?

raggy
27.04.2008, 18:13
Hallo
Wenn Du mich fragst wuerde ich es erstmal genauso machen wie in dem
Programm,dann kanst du es immer noch umaendern und die auswirkungen sehen.
Hat aber den vorteil das mann erstmal sieht ob alles in Ordnung ist,RFM12
und auch die restliche Schaltung.
Wenn da wirres zeug ankommt ist irgendwas verkehrt habe beim ersten mal auch erst rumexperimentiert,bis es lief.Ob der FSK mit geschalteten Pull up vom Atmega das richtige ist ??? der wiederstand ist viel hoeher (Datenblatt)
mehr weiß ich leider auch nicht
Zum Programm das ist fuer mich auch so ein Raetzel aber alle im Internet bauen darauf auf. zumindest Bascom.
Gruß raggy

robodriver
27.04.2008, 18:32
Danke für deine Antwort.

Also um weiter Fehler ausschließen zu können, hat mir ein Freund nun 2 Pollin-Evaluation-Boards zur Verfügung gestellt. Eins mit dem RFM01 Modul und das zweite mit einem RFM02 Modul.

Ist zwar nicht das RFM12-Modul was ich brauch, aber erstmal egal.
WEIL:

Er hat da das Test-Programm von Pollin drauf gespielt. Nun übersetze ich den Quellcode von C in Basic um dann zumindest mal zu sehen ob meine Übersetzung korrekt ist.
Und wie ich bis jetzt feststellen musste, ist meine Übersetzung offensichtlich absolut falsch. Denn mit dem Basic-Code Empfängt das Modul nichts.

Also scheint etwas an der Konfiguration falsch zu sein.
Demm beim Empfangen wird ja nur Konfiguriert und dann auf den IRQ gewartet. Aber nach meiner Konfiguration über Basic kommt kein IRQ.
Daten kommen aber vom anderen Modul 100%ig an. Das beweist ja, wenn ich wieder das C-Programm auf spiele, dann empfängt der Chip was.

Also liegt hier definitiv der Fehler im Basic.
Meine Vermutung ist, der Fehler liegt genau genommen beim SPI.
Mit SPI hab ich noch nie gearbeitet und keinerlei Erfahrung.

Schaut euch den Code bitte mal an, ob ihr das Fehler finden könnt:


' Empfangen von Daten auf dem Evaluation-Board
' Modul: RFM01
' AVR: Mega8

$regfile = "m8def.dat"
$crystal = 8000000

'DDR = &B76543210 ; 0=Eingang ; 1=Ausgang
Ddrb = &B00000000
Ddrc = &B00000000
Ddrd = &B01110000
Portb = &B00000000
Portc = &B00000000
Portd = &B00000000

Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 128 , Noss = 1 ' LED zur Schleifenkontrolle

Declare Function Rf01_trans(byval Wert As Word) As Word

Dim A As Byte
Dim Temp As Word

Led1 Alias Portd.6
Led2 Alias Portd.5
Modul_power Alias Portd.4

' werden benötigt für rf12_ready
Spi_cs Alias Portb.2 ' SS-Pin
Config Spi_cs = Output
Spi_sdo Alias Pinb.4 ' MISO-PIN
Set Spi_cs

Spiinit

Wait 1

Reset Modul_power
For A = 1 To 6
Toggle Led1
Waitms 200
Next A

Reset Led1

Set Modul_power

Waitms 200

Temp = Rf01_trans(&H0000)
Temp = Rf01_trans(&H898a)
Temp = Rf01_trans(&Ha640)
Temp = Rf01_trans(&Hc847)
Temp = Rf01_trans(&Hc69b)
Temp = Rf01_trans(&Hc42a)
Temp = Rf01_trans(&Hc240)
Temp = Rf01_trans(&Hc080)
Temp = Rf01_trans(&Hce88)
Temp = Rf01_trans(&Hce8b)
Temp = Rf01_trans(&Hc081)


Ddrd.7 = 1 'FSK
Ddrd.2 = 0 'nIRQ

Do

Do
Loop Until Pind.2 = 0

Set Led2
Waitms 300
Reset Led2

Loop



Function Rf01_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
Rf01_trans = Temp
End Function

End

(Ist der Code für Mega8 auf den Pollin-Evaluation-Board mit angeschlossendem RFM01 Modul


Bin schon total verzweifelt :(
So schwer kann das doch wohl nicht sein....

raggy
28.04.2008, 17:47
Wenn Du mit Interrupt arbeites muß Du in Config SPI auch interrupt = On
setzen.
$framesize = 40 ist wichtig (Variable)
ansonsten weiß ich wirklich nicht weiter.
Gruß raggy

robodriver
28.04.2008, 19:56
Okay, also ich hab es jetzt nochmal noch feiner umgeschrieben das Programm.
Und hab so weit erstmal etwas hin bekommen, das die Schaltung zumindest reagiert, sobald Daten an kommen.
Irgendwie scheint da das Hardware-SPI nicht so richtig zu funktionieren oder ich bein einfach zu blöd für...
Hab das SPI jetzt raus gelassen und ne komplette Software-SPI Lösung geschrieben. Und damit funktionierts...

Für alle dies Interessiert, hier der code (nur Schade das result beim Empfangen immer 0x00 ist, obwohl beim ersten Byte 0x31 gesendet wird...)



' Empfangen von Daten auf dem Evaluation-Board
' Modul: RFM01
' AVR: Mega8

$regfile = "m8def.dat"
$crystal = 8000000

Declare Function Rf01_trans(byval Wert As Word) As Word
Declare Function Read_fifo() As Byte

Dim A As Byte
Dim B As Byte
Dim Temp As Word
Dim Result As Byte

Led1 Alias Portd.6
Led2 Alias Portd.5
Modul_power Alias Portd.4
Spi_cs Alias Portb.2 ' SS-Pin
Spi_sdo Alias Pinb.4 ' MISO-PIN

Ddrd.4 = 1
Ddrd.5 = 1 'LED 2 Ausgang
Ddrd.6 = 1
Reset Led2
Reset Modul_power

Wait 1

For A = 1 To 6
Toggle Led2
Waitms 200
Next A

Reset Led2
Set Modul_power

Waitms 200

Portb.2 = 1 'Slave inaktiv
Portb.3 = 1 'MOSI auf high
Portb.5 = 0 'Sck Low
Portb.7 = 1 'FSK high
Ddrb.2 = 1
Ddrb.3 = 1
Ddrb.4 = 0 'MISO = Eingang
Ddrb.5 = 1

'Ddrd.2 = 0 'INT0 als Eingang
'Ddrd.7 = 1 'FSK als Ausgang


Temp = Rf01_trans(&H0000)
Temp = Rf01_trans(&H898a)
Temp = Rf01_trans(&Ha640)
Temp = Rf01_trans(&Hc847)
Temp = Rf01_trans(&Hc69b)
Temp = Rf01_trans(&Hc42a)
Temp = Rf01_trans(&Hc240)
Temp = Rf01_trans(&Hc080)
Temp = Rf01_trans(&Hce88)
Temp = Rf01_trans(&Hce8b)
Temp = Rf01_trans(&Hc081)


Ddrd.7 = 1 'FSK
Ddrd.2 = 0 'nIRQ

B = 0
Do

Do
Loop Until Pind.2 = 0
Set Led2
B = B + 1
Result = Read_fifo()
If Result = &H00 Then
Set Led1
Waitms 200
Reset Led1
End If

If B = 18 Then
Temp = Rf01_trans(&Hce88)
Temp = Rf01_trans(&Hce8b)
B = 0
'Set Led2
'Waitms 200
'Reset Led2
End If
Reset Led2
Loop



Function Rf01_trans(byval Wert As Word) As Word
Temp = 0
Portb.5 = 0 'Low SCK
Portb.2 = 0 'Low SS

For A = 15 To 0 Step -1
If Wert.a = 1 Then
Portb.3 = 1
Else
Portb.3 = 0
End If
Portb.5 = 1 'high sck
nop
nop
nop
nop
Portb.5 = 0

Next A
Portb.2 = 1

End Function

Function Read_fifo() As Byte
Portb.5 = 0
Portb.3 = 0
Portb.2 = 0
For A = 0 To 15
Portb.5 = 1
nop
Portb.5 = 0
nop
Next A
For A = 7 To 0 Step -1
If Pinb.4 = 1 Then
Result.a = 1
Else
Result.a = 0
End If

Portb.5 = 1
nop
Portb.5 = 0
nop
Next A
Portb.2 = 1

Read_fifo = Result
End Function

End

stefan_Z
29.04.2008, 03:26
Hallo!

Ich würde mich gerne kurz an das Thema dranhängen...
Hintergrund:
Ein recht kurzfristiges Projekt wo wir Platinen machen lassen und erstmal ein Grundprogramm benutzen.
Später soll dann die Funk-Steuerung nachgerüstet werden.
Also muss ich platz lassen für das RFM01 (nur Empfang).
Controller ist ein Mega32 und noch kann ich Pins belegen wie ich lustig bin.
Daher wollte ich nochmal Rückfrage halten, ob das auch wirklich so richtig ist...

RFM01 <-> Mega32
VCC 5V gemeinsam mit dem AVR
SDI <-> MOSI
SDO <-> MISO
SCK <-> SCK
nSel <-> SS
DATA/nFFS <-> über 1 (10?) kOhm auf VCC

Folgende Pins sind dann am RFM01 noch unbelegt welche brauche ich?
2 - nIRQ - Interrupt Request Output (active low)
4 - DCLK/CFIL/FFIT - Clock Output (AVR hat nen eigenen 16 MHz Schwinger)
5 - CLK - Clock Output for external µC (wie ist das jetzt anders als DCLK?)
6 - nRES - Reset Output (active low) - hier sagt er bescheid vonwegen Neustart?
11 - VDI - Valid Data Indicator - hier eine LED ran?

Besonders wichtig wäre es zu wissen, ob ich irgendwelche externen Interrupts brauche und an welchem Bein vom RFM01.
Der Mega32 soll das Hauptprogramm nur bei Empfang unterbrechen.

Zusatzfrage:
Wäre es ggfs. möglich mit ein und derselben Pinbelegung zum AVR alternativ auch das RFM12 zu benutzen?

Vielen Dank schonmal im Voraus....
Stefan

Grandalf
29.04.2008, 14:45
hallo

also für die pinbelegung an einem Pollin Evaluations board kann ich nur das hier anbieten

da pollin neuerdings das board schon mit integriertem rfm01 bzw rfm02 bzw rfm12 platz anbietet haben die ein datenblatt zur verfügung gestellt wo direkt die pin-verbindungen zu sehen sind

so hab ich das jetzt gerade auch verbunden:
http://www.pollin.de/shop/downloads/D810046B.PDF


meine frage zu dem ist jetzt jedoch....wie sieht das mit registern aus bzw wie initialisiere ich das und wie sende bzw empfange ich.
ich hab 2evaluationsboards mit jeweils einem rfm12 und einem ATmega16
und will einfach nur einen buchstaben von einem zum anderen board schicken

duch die programmcodes die ich bisher gefunden habe find ich mich nicht zurecht da die meist immer nur mit hexzahlen um sich schmeißen.
könnte mir mal einer erklären wie das geht
vllt so ne kleine init-routine oder so

danke schon mal

raggy
29.04.2008, 15:45
hallo Grandalf
Sowei mir bekannt funktioniert die Initalisierung des RFM12 /01 /02
nur in HEX-zahlen ich habe noch keine andere Initalisierung gesehen.

stefan_Z
30.04.2008, 02:01
Jo, das Datenblatt kenn ich auch...
Wollte aber wissen, was wirklich nötig, was überflüssig und was vonwegen Interrupts wichtig ist!

Grandalf
30.04.2008, 07:23
wenn du wissen willst was von den pins notwendig ist und was nicht so kannst du dir das in dem datenblatt zum RFM01/02/12 anschauen
da steht genau drin welcher pin für was steht

interupts zb sind alle auf aktiv low und davon sind es 2 stück ein input interupt und ein output interrupt

ja das mit den hexzahlen weiß ich schon nur kann man ja die ports auch anders einstellen
statt 0xff
kann man ja auch &B11111111
oder PORTx |= (1<<Px0)|(1<<Px1)......|(1<<Px7)
schreiben, wobei ich mit der langen angabe (PORTx |=....) am besten klar komme. da ich bei der methode vorher sagen kann #define MOSI PD5 //SDI
und schon kann ich direkt mit den pinfunktionen arbeiten (1<<MOSI)
ist zwar mehr schreib arbeit aber extrem übersichlicher als nur hexzahlen rein zu kloppen

mfg Grandalf

stefan_Z
30.04.2008, 15:19
Die Datenblätter sind leider Schrott, finde ich. Die Funktion der Pins wird da nicht wirklich brauchbar erklärt.
Die hier habe ich bisher gefunden:
http://www.hoperf.com/pdf/rfm01.pdf
http://www.hoperf.com/pdf/RF01_code.pdf
http://www.hoperf.com/pdf/RF0102TOOLS.pdf
http://www.pollin.de/shop/downloads/D810047D.PDF

Gibts da was brauchbares? Irgendwie bin ich von Linear und Konsorten verwöhnt...

Ich muss wie gesagt nur wissen, ob SDI, SDO, SCK reichen, oder ob ich noch nIRQ auf nen INTx legen muss.
Das würde Sinn machen, weil das Modul nur sporadisch Daten empfangen wird - das aber im Interrupt.
Oder läuftdas über den SPI Interrupt des AVR?

DCLK und CLK brauche ich glaubich nicht - oder täusche ich mich? Der AVR hat nen 16MHz Quarz.
nRES gehört wohl auch zu den CLKs

Und an VDI kann ich ne LED anklemmen, ja?

Grüße
Stefan

raggy
30.04.2008, 20:14
Hallo hier mal die Befehle RFM12 usw
Ich weiß nicht ob ihr das schonmal gelesen habt
http://www.mikrocontroller.net/articles/RFM12
Gruß raggy

Grandalf
02.05.2008, 07:28
Hallo

nein ich habe es vorher noch nicht gesehen...also erstmal danke
nur verstehe ich ehrlich gesagt die angaben dort garnicht

die absätze "RFM empfängt nur müll" und "RFM hängt sich auf" sind zwar noch nachvollziehbar aber was ich wirklich zur zeit brauche steht (wenn ich das gerad richtig interpretiere in dem abschnitt Register)
und genau das versteh ich nicht.
denn: was bitte bedeuten die ganzen abkürzungen
(x0 x1 x2 x3 b0 b1 e1 ef b... x... xx und so weiter)
das ganze sagt mir nichts

ich bin kein profi oder so sondern beschäftige mich erst seit kurzem mit Controllerprogrammierung habe jetzt die RS232 schnittstelle und ein LCD Display am laufen bekommen sowie kleinere spielereien mit taktgebern und LEDs sowie tastern. nun will ich mich halt dem RFM12 zuwenden und hab halt die pinbelegung gefunden (wobei auch dort 2 verschiedene die beide funktionieren sollten wenn man weiß wie).

Ich suche halt nun eine beschreibung wie ich den RFM initialisiere und dann benutzen kann.

Mit register angaben wie
DDRx oder PORTx oder UCSRA kann ich was anfangen aber sowas in der art hab ich noch nicht gefunden


also hier nochmal meine derzeitige pinbelegung
(laut dieser seite im ersten absatz unter Treiber: http://www.mikrocontroller.net/articles/AVR_RFM12 ):
DDRB |= (1<<PB4)|(1<<PB6)|(1<<PB7); //SS; MISO; SCK;
DDRB & ~(1<<PB5); //MOSI
//FSK liegt mit 1kohm auf VCC

Meine zweite Variante für die Pinbelegung ist so wie in diesem Datenblatt:
http://www.pollin.de/shop/downloads/D810046B.PDF

schonmal danke für weitere infos

gruß Grandalf

Sauerbruch
02.05.2008, 14:46
Moin Grandalf,

die Manuals der RF-Serien bieten - um es mal positiv zu formulieren - in der Tat noch Potenzial zur Optimierung ihrer Verständlichkeit.
Dabei ist es eigentlich ziemlich einfach: Um das Modul zu konfigurieren, muss man ihm Steuerkommandos (seriell) zuschicken, die i.d.R. 2 bytes lang sind.

Als Beispiel mal das Power Management Command:

1 0 0 0 0 0 1 0 er ebb et es ex ebew dc

An den ersten 8 bits erkennt der Chip, dass es sich eben um dieses Power-Management-Kommando handelt. Die Sequenz am Anfang ist nämlich bei jedem Kommando unterschiedlich - kannste ja mal überprüfen.

Die dann folgenden, mit Buchstaben bezeichneten Bits legen dann die gewünschten Einstellungen fest. Soll das Teil senden, muss Bit Nr.5 (et = Enable Transmitter) 1 sein, wenn der Empfänger aktiviert werden soll, muss Bit Nr. 7 (er = Enable Receiver) 1 sein usw.

Der kryptische Abschluss "POR" in der oberen Zeile heißt "Power-On-Reset", und die darunter stehende Zahl im Hexadezimal-Code gibt an, wie diese bits gesetzt sind, wenn der Chip "aufwacht" und noch nicht speziell konfiguriert wurde. Für das Power-Management-Kommando wäre das &H8208 oder binär 1000 0010 0000 1000. Also die korrekten 8 Anfangs-bits (klar), und alle Funktionen außer dem Quarzoszillator deaktiviert.

Man muss beileibe nicht alle Kommandos ausführen, wenn ein Chip initialisiert wird. Dafür ist es ganz gut zu sehen, wie die Ausgangskonfiguration bei Power on ist. Je nach Anwendung kann das eine oder andere Steuer-bit genau so bleiben.

Mit dem Befehl Spiout lassen ich diese 2-Byte-Blöcke superbequem an den Chip senden. Details hat auch hier die Bascom-Hilfe parat. Das schwierigste dabei (so ging es zumindesten mir) war in der Tat, das Prinzip der RFM-Chips zu verstehen.

Und ich kann nur empfehlen, mit "leichten" Aufgaben anzufangen, z.B. einen unmodulierten Träger zu senden und zu empfangen, und nicht gleich FIFO-gepufferte Datenpakete zu übertragen oder sowas. Sonst weiß man schon gleich am Anfang nicht, weshalb es klemmt...

Grandalf
05.05.2008, 07:14
@Sauerbruch

Vielen Dank
jetzt komm ich echt weiter, super

werd gleich anfangen

@einfache sachen schicken: ich informiere mich lieber immer erst so weit das ich sofort das programm schreiben kann was ich will so das es sofort läuft (oder nach kleineren Korrekturen)

Nur hatte ich gedacht das der unterschied zwischen senden und register select durch den PIN "nSEL" eingestellt wird und nicht durch ein bit in dem an den rf übergebenen word


Danke!

Grandalf
05.05.2008, 08:33
aehm ok hab mir gerad alles angeschaut

ich verstehe zwar jetzt wie ich den rfm12 einstelle nur merk ich gerad das ich nicht weiß was ich wie einzustellen habe
auf dem pollin datenblatt steht hinten eine beispiel-Initialisierung drauf nur bin ich 1. mir nicht sicher ob die Fehlerfrei ist :-s und 2. glaube ich auch das dort viel mehr eingestellt wird als für mich notwendig ist
da ich nur nSEL CLK SDO und SDI angeschlossen hab und FSK mit 1kohm auf VCC liegt (im gegensatz zu pollin wo fast jeder pin am ATmega16 angeschlossen ist)

desweiteren hab ich noch fragen wie ich die einstellungs-words an den rfm12 sende:
- der CLK wird ja getaktet und muss ich nun ein komplettes word pro takt an den SDI schicken oder nur ein bit? und wie schnell soll ich den CLK takten?
- muss ich nachdem ich das komplette word drin hab noch etwas machen damit er das word ausführt (zb den nSEL = 1 oder ist das automatisch sobald der FIFO voll ist)

sorry wegen der ganzen fragen

Sauerbruch
06.05.2008, 08:09
Also - für die Konfiguration des Chips brauchst Du nichts anderes zu machen als die 16 bit seriell auf den SDI-Pin zu geben. Das macht Bascom sehr komfortabel mit dem Befehl SPIOUT, var, bytes. Dieser Befehl sorgt dafür, dass 1. der SS-Pin (Slave select, verbunden mit nSEL) auf Low gezogen wird. Dadurch weiß der Chip, dass er jetzt gemeint ist und ein Kommando kommt. 2. wird der Clock-Takt aktiviert, und 3. das im Befehl bezeichnete Byte (oder mehrere!!) seriell cock-synchron über DOUT ausgegeben (daher zu verbinden mit SDI). Sind alle bits übertragen, geht SS (=nSEL) wieder auf High und der Chip weiß, dass es das jetzt war.

Die Umsetzung des Kommandos läuft im Chip dann ganz von alleine, man braucht nichts weiter zu tun.

Das FIFO-Register ist was ganz anderes, nämlich so ´ne Art Zwischenspeicher für zu sendende oder empfangene Daten, falls die mal schneller anfallen, als sie abgesendet werden können. Damit habe ich aber noch nie gearbeitet und daher keine Erfahrung. Ich hab meine RFM-Module bisher im einfachen (und unspannenden) FSK-Modus betrieben.

Nochwas zu SPIOUT, var, bytes: Die Bascom-Hilfe schreibt, dass "bytes" die Anzahl der zu sendenden bytes ist. Somit stellt sich die Frage, ob "var" auch immer ein byte sein muss. Für die Übertragung der 16-bit-Kommandos müsste man also immer 2 bytes in Folge übertragen. Hab´ ich auch so gemacht; ein Array definiert, z.B. A(2), und dann mit SPIOUT A(1), 2 beide in Folge gesendet. Ob man "var" gleich als Word senden kann (mit bytes = 2) weiß ich nicht. in Einzelbytes funktioniert´s aber auf jeden Fall.

Gutes Gelingen!

Grandalf
06.05.2008, 10:38
hey ok gut dann hab ich erstanden

aber:
gibt es denn diesen bascombefehl auch in C
(SPIOUT mein ich)???

und was ich mit fifo und den registern meinte ist: WAS muss ich denn einstellen damit das läuft
ich habe keine ahnung was einige einstellmöglichkeiten machen wenn ich sie so oder so konfiguriere und daher müsste ich mal so ne minimal init haben, dazu hier nochmal meine arbeitsgeräte:
Evaluationboard
Addonboard
RFM12
(alles von pollin)
genutzte pins: sck sdi sdo nsel (und fsk ist auf VCC gelegt)


gruß

Sauerbruch
06.05.2008, 11:12
Hmmm... da muss ich auf der ganzen Linie passen.

Mit C habe ich mich noch niemals auch nur in Ansätzen beschäftigt. Und was die genaue Handhabung des FIFO-Registers betrifft, habe ich dieses Kapitel aus Bequemlichkeitsgründen umgangen :-)
Es gibt aber hier und in anderen Mikrocontroller-Foren einige Threads, die glaube ich ganz hilfreich sein könnten. Und ich weiß auch, dass einige Freaks schon RF12-Quellcode in C geschrieben und im Forum gepostet haben.

Viel Erfolg weiterhin!

Grandalf
06.05.2008, 14:12
hi

ja schon ich hab auch einige beispielprogramme gefunden und ich bin die mal durchgegangen aber sehr übersichtlich sind die nich programmiert und kommentare fehlen an den stellen die ich wissen will komplett. daher ist es 1. total verwirrend und 2. seeehr langwierig für mich als "nichtprofi" da durchzusteigen

naja ok ich werd weiter suchen

stefan_Z
08.05.2008, 02:28
Eine Frage hätte ich noch zum RFM01...
Das ist ja über MISO/MOSI/etc angeklemmt - also die Pins, mit denen auch der ISP arbeitet...
- Funktioniert der denn dann überhaupt noch?
- Kann er das RFM-Modul beschädigen?
- Sollte ich einen Jumper für das RFM01 vorsehen, um VCC zu trennen vor dem Proggen?

thewulf00
08.05.2008, 08:32
Hallo Stefan!

Der ISP ist ein Mehrgerätebus, d.h. er ist für mehrere Geräte an den selben Leitungen vorgesehen. Wenn Du den ISP vom Atmel nutzt, kannst Du trotzdem den Atmel programmieren, SOLANGE Du VCC NICHT trennst. Genau dieses Fehler hat Pollin gemacht, mit ihrem Optokoppler, der die Versorgungsspannung der Module für die Programmierung ausschalten können soll.

Durch den Bus wird nichts zerstört. Solange die Leitung nSel auf '1' steht, nimmt das Modul keine Signale vom ISP entgegen, man kann also programmieren.

Sauerbruch
08.05.2008, 13:44
...außerdem musst Du die Kommunikation zwiachen Controller und RFM-Chip nicht über MOSI und MISO laufen lassen. Man kann die SPI-Schnittstelle frei konfigurieren, und die Funktionen DOUT (Data out), DIN Data In), Clock und SS 8Slave select) auf beliebige IO-Ports legen. Zumindestens in Bascom...

stefan_Z
08.05.2008, 14:01
Ok danke für die Infos. Das mit MISO/MOSI passt schon, hardwaremäßig find ich immer bsser als emuliert....

Jaecko
16.05.2008, 10:39
Mal ne Frage zur Antenne: es müsste doch auch gehen, wenn man als Antenne einen Kupferstreifen auf der Platine stehen lässt. Oder brauchts bei dem Modul unbedingt ein Stück Draht o.ä.?

Grandalf
26.05.2008, 13:32
beim pollin board kannste die antenne auch weg lassen nur musst du die boards dann mindestens 30 cm nebeneinander stellen

Jaecko
26.05.2008, 14:33
Hm naja schon,... nur bei 30cm Entfernung isn Kabel wirtschaftlicher.
Dauert eh noch bissl, bis ich die Teile dann mal in Betrieb nehm.

Grandalf
27.05.2008, 08:10
wo issen das problem da nen 17 cm langen draht dranzulöten?

und schon haste ne reichweite von mehreren 10 - 100 metern