Code:
$regfile = "m88def.dat" ' specify the used micro ' used crystal frequency
$crystal = 14745600
$baud = 57600 ' use baud rate
$hwstack = 70 ' default use 32 for the hardware stack
$swstack = 70 ' default use 10 for the SW stack
$framesize = 60 ' default use 40 for the frame space
Const Release = "2014.02.13 RGB-On V1.00"
'------------------------------------------------------------------------------- Testvariablen
Dim Tempo As Byte '=> für Print
'------------------------------------------------------------------------------- RS232
Dim Rx_data As Byte , Uart_rxd As Bit
On Urxc Rxd_isr 'Interrupt Empfange String von RXD
Enable Urxc
'------------------------------------------------------------------------------- allg. Variablen
'Ddrc = &B01001111 ' PortC (LED + Relaisausgänge + FSK) auf Ausgang setzen
'Portc = &B10110000 ' PortC pull up Widerstand (Taster) einschalten
Config Pinb.0 = Input : Taster Alias Pinb.0 : Portb.0 = 1 ' Schalter von der Dunstabzugshaube
Config Portb.1 = Output : Led_pwm Alias Portb.1 ' hinterer LED-Strip dieser kann gedimmt werden
Config Portc.1 = Output : Led_vorn Alias Portc.1 ' vorderer LED-String nur für Beleuchtung
Dim Pwm_byte As Byte ' Konstante für hinterer Strip = 100%
Config Timer1 = Pwm , Pwm = 8 , Compare_a_pwm = Clear Up , Prescale = 1
'Dim Rgb_vorn_flag As Bit , Rgb_hinen_flag As Bit
'------------------------------------------------------------------------------- Variablen
'------------------------------------------------------------------------------- RFM12 Variablen & Hardwaresetup = Anschluss
Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 4 , Noss = 0 , Spiin = &HB0
Spiinit
Config Int0 = Rising 'Rising
On Int0 Ffit_isr
Enable Int0
Spi_sdo Alias Pinb.4
Spi_cs Alias Portb.2 : Ddrb.2 = 1
Set Spi_cs
Config Portc.3 = Input
Nirq Alias Pinc.3
Config Portc.2 = Input
Ffit Alias Pinc.2
'-------------------------------------------------------
Declare Sub Rf12_init()
Declare Sub Rf12_txdata(byval Txlen As Byte)
Declare Sub Rf12_ready
Declare Sub Rf_cmd(byval Wert As Word)
Dim Cmd(2) As Byte , Lv As Byte
Declare Sub Sdi_send(byval Sdi_byte As Byte)
Dim Sdi(2) As Byte , Fifo(2) As Byte
Sdi(1) = &HB8
Const Myadress = 40 'Nodeadresse vom Teilnehmer
Const Snap_sync = &H54 'Synczeichen SNAP-Protokoll
Const Hdb2_ = &H50
Const Recive_buffer_size = 15
Dim Slaveadress As Byte
Dim Mem_dummy As Byte , Dummy As Byte ' Variablen für Lösche des Empfangsarray
Dim Rf12_timeout As Word , Rf12_err As Byte , Byteanzahl As Byte
Dim Framelength As Byte , Crc As Byte , Crc_rx As Byte , Rf_sync As Bit , Rf_rxd As Bit , Crclength As Byte
Dim Rf12_data(20) As Byte ' , Rf12_s(12) As Byte At Rf12_data + 4 ' Rx_data(40) As Byte
Dim Temp As Byte , Temp_rfm As Word
Sync Alias Rf12_data(1)
Hdb2 Alias Rf12_data(2)
Hdb1 Alias Rf12_data(3)
Dab1 Alias Rf12_data(4)
Sab1 Alias Rf12_data(5)
'-------------------------------------------------------------------------------
'**************************** Programmstart *********************************
Enable Interrupts
Call Rf12_init()
Print Release
Stop Timer1 ' PWM-Erzeugung gestoppt, wird über RFM12 zugeschalten
'#####################################################################################################
'############################################# MAIN DO ###########################
'#####################################################################################################
Do
Pwm1a = Pwm_byte ' Timervorgaben für Timer => Steuerung Helligkeit
'******************************************************************************* UART-Auswertung
If Uart_rxd = 1 Then
Select Case Rx_data
Case 123 : Goto $c00 'vom MCS-Programmer geschickte "123" empfangen?
Case "1" : Pwm_byte = Pwm_byte - 10
Print " pwm_byte " ; Pwm_byte
Case "2" : Start Timer1
Pwm_byte = 100
Case "3" : Pwm_byte = 0
Stop Timer1
Reset Led_pwm
End Select
Print Pwm_byte
Uart_rxd = 0
End If
'******************************************************************************
Debounce Taster , 0 , Led_an , Sub ' Lichtschalter an Haube
'******************************************************************************* RFM12 abfragen & Empfangsbereit schalten
If Rf_rxd = 1 Then
Rf_rxd = 0
'Gosub Framehandler
'Gosub Rf12_rxd_on
End If '
Loop
End
'+++++++++++++++++++++++++++++++++++++++++++++++Subroutinen+++++++++++++++++++++
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'(********* ISR Timer 1 ***************************************************
25ms_irq: ' 25ms Interrupt für die Tastenentprellung und Zeitzählung Rolladen Hoch/Runter
Timer1 = Timer1vorgabe
Incr Timecount
Return 'and exit isr with RETI
')
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Tasterdebounce
Led_an:
Toggle Led_vorn
Select Case Led_vorn
Case 0 : If Rf12_data(6) = 1 Then
Pwm_byte = 155
Start Timer1
Else
Stop Timer1
Pwm_byte = 0
Reset Led_pwm
End If
Case 1 : Start Timer1
Pwm_byte = 255
End Select
Return
'++++++++++++++++++++++++++++++ Auswertung des RFM12 Frames auf Pausablität & Sende-Empfangsroutinen +++++++++++++++++++++++++++++++++++++++++++
'++++++++++++++++++++++++++++ Einstellen des RFM 12 für 868,35MHz
'Einstellen des RFM 12
Sub Rf12_init()
Waitms 150
Call Rf_cmd(&H0000) 'Read Status
Call Rf_cmd(&Hc0e0) 'low battery, clock 10 MHz
Call Rf_cmd(&H80e7) 'Configuration: 868MHzband, 12pf, enable FIFO
Call Rf_cmd(&H82d8) 'power management: enable receiver, enable clock output
Call Rf_cmd(&Hc2ac) 'data filter command
Call Rf_cmd(&Ha686) 'Frequency: 868,35MHz
'Call Rf_cmd(&Ha74e) 'Frequency: 869,35MHz
Call Rf_cmd(&Hc611) 'Datarate: 19,2 kbit
Call Rf_cmd(&H94a1) 'receiver setting: 134kHz, -97dbm
Call Rf_cmd(&Hc2ac) 'data filter:
Call Rf_cmd(&Hc483) 'AFC:
Call Rf_cmd(&H9850) 'TX control
Call Rf_cmd(&He000) 'wake-up
Call Rf_cmd(&Hc800) 'low duty-cycle
Call Rf_cmd(&Hca81) 'Reset FIFO
Call Rf_cmd(&Hca83) 'enable FIFO
Call Rf_cmd(&H0000) 'read Status
End Sub
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Sende Daten
Sub Rf12_txdata(byval Txlen As Byte)
'
Print "Rf12_txdata(framelength) " ; Framelength
For Tempo = 1 To Framelength
Print "send-data " ; Rf12_data(tempo) ; " " ; Tempo
Next
Print "txdata-end "
Print
Call Rf_cmd(&H8220) : Rf12_ready ' Sender aktivieren
Call Sdi_send(&Haa) : Rf12_ready 'Preamble
Call Sdi_send(&Haa) : Rf12_ready 'Preamble
Call Sdi_send(&H2d) : Rf12_ready 'Startzeichen: 2D für den Empfänger 'Preamble
Call Sdi_send(&Hd4) : Rf12_ready 'Startzeichen: D4 für den Empfänger
For Lv = 1 To Txlen
Rf12_ready
Call Sdi_send(rf12_data(lv))
Next Lv
Call Sdi_send(&Haa) : Rf12_ready 'Dummybyte nachschieben
Call Sdi_send(&Haa) : Rf12_ready
End Sub
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Befehl zum RFM senden z.bsp. Initialisierungen
'
Sub Rf_cmd(byval Wert As Word)
Cmd(2) = Wert And 255
Shift Wert , Right , 8
Cmd(1) = Wert
Spiout Cmd(1) , 2
End Sub
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Daten zum RFM12 senden
Sub Sdi_send(byval Sdi_byte As Byte) 'wait for TX FIFO IRQ
Bitwait Nirq , Reset
Sdi(2) = Sdi_byte
Spiout Sdi(1) , 2
End Sub
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Busy check
' nach jeder SPI-Übertragung wird geprüft, ob Übertragung erfolgreich und neue Daten gesendet werden können
Sub Rf12_ready
Rf12_timeout = 60000 'Timeout Zeit (orig. 50000)
Reset Spi_cs 'SS-Pin--> select RF12
While Spi_sdo = 0 'MISO muss von RF12 auf high gehen 'In der Sim. auf 1 stellen
If Rf12_timeout > 0 Then 'Timeout Loop
Decr Rf12_timeout
Else
Rf12_err = 1 'Flag setzen
Exit While 'Timeout --> Abbruch kein ready vom RF12
End If
Waitus 20
Wend 'Warten bis senden bzw. empfangen fertig
End Sub
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ RFM12 - Empfänger einschalten
Rf12_rxd_on:
Print "rxd on"
'Dummy = Memcopy(mem_dummy , Rf12_data(1) , Framelength , 2)
Lv = 1 ' Empfangsbytezähler zurück setzen
Rf_sync = 0 'Sync-Erkennung zurücksetzen 'sync-Flag
Rf_rxd = 0 ' Empfangserkennung zurücksetzen
Call Rf_cmd(&H0000) 'Status lesen
Call Rf_cmd(&H82d8) ' Empfänger einschalten
Call Rf_cmd(&Hca81) 'FIFO&Reset CMD: sensitiver Reset aus (Brownout)
Call Rf_cmd(&Hca83) 'FIFO&Reset CMD: Synchroner Zeichenemfang (warte auf Startzeichen: 2DD4)
Enable Int1
Enable Interrupts
Return
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ INT1 ISR(Daten vom RFM12)
'Interrupt Routine zum empfangen der bytes aus dem RFM 12
Ffit_isr:
Spiin Fifo(1) , 2 '1 Byte lesen
Temp = Fifo(2)
If Temp = Snap_sync And Rf_sync = 0 Then
Rf_sync = 1
Lv = 1
Framelength = 4
End If
Rf12_data(lv) = Temp
If Lv = 3 Then Framelength = Temp
If Framelength >= Recive_buffer_size Then
Dummy = Memcopy(mem_dummy , Rf12_data(1) , Framelength , 2)
Framelength = Recive_buffer_size
Call Rf_cmd(&H8208)
Disable Int1
Gosub Rf12_rxd_on
End If
If Lv = Framelength And Rf_sync = 1 Then 'alles eingetroffen
Rf_rxd = 1 'Flag setzen und Empfänger zurück setzen
Rf_sync = 0
Call Rf_cmd(&H8208)
Disable Int1
End If
Incr Lv
Return
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Send Frame over RF12
Sendsnapframe:
' Zusammenstellung des Sendepaketes mit SNAP-Protokoll
'Header aufbereiten (SNAP) => 5 Byte-Header
Select Case Byteanzahl '6Byte<=sync+HDB2+HDB1+DAB+SAB+letztes Byte = CRC
'Case 0 To 8 : Framelength = 6 '6-14 (0--8 Datebyte)
Case 5 : Byteanzahl = 11
Case 9 : Byteanzahl = 16 '22 (16 Datenbyte)
Case 10 : Byteanzahl = 4
Case 15 : Byteanzahl = 15 '38 (32 Datenbyte)
End Select
Rf12_data(1) = Snap_sync
Rf12_data(3) = Byteanzahl 'HDB1 0..32DatenByteInfo
Rf12_data(4) = Slaveadress 'Zieladresse
Rf12_data(5) = Myadress 'Senderadresse
'ab 6.Stelle <--0...40 Datenbyte rein
Framelength = Byteanzahl
Crclength = Byteanzahl - 1
Rf12_data(framelength) = Crc8(rf12_data(1) , Crclength) 'CRC an letzter Stelle anhängen und raus senden
Call Rf12_txdata(framelength) ' Datenpaket senden
Return
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Auswertung empfangener Frams
Framehandler:
If Sync = Snap_sync Then 'Check auf richtiger SNAP-Knoten Syncbyte richtig? ' Adressraum = 1 Byte?
If Dab1 = Myadress Then ' Stimmt die Adressierung?
Crc = Framelength - 1 ' CRC-Länge bestimmen
Crc_rx = Crc8(rf12_data(1) , Crc) ' CRC berechnen
Print "CRC " ; Crc ; " " ; Rf12_data(framelength)
If Crc_rx = Rf12_data(framelength) Then ' in letzter Stelle steht der berechnete Sende-CRC => überprüfen
Print "CRC OK! => " ; Crc_rx
Select Case Hdb2
' Case 1 weiter ohne ACK
Case 1 : Print "ohne ACK "
Gosub Rf12_rxd_on
Gosub Funkdaten_handler
'Dummy = Memcopy(mem_dummy , Rf12_data(1) , Framelength , 2)
' Case 2 als Master => Slave hat mit ACK geantwortet
Case 2 : Print "CRC good => "
Hdb2 = &H0
'Dummy = Memcopy(mem_dummy , Rf12_data(1) , Framelength , 2)
' Case 3 als Slave => sende Master ein ACK
Case 3 : Print "Master fordert ACK "
Gosub Rf12_rxd_on
Swap Dab1 , Sab1
Hdb2 = &H2
Rf12_data(framelength) = Crc8(rf12_data(1) , Crc)
Call Rf12_txdata(framelength)
Gosub Funkdaten_handler ' => Hier Dann Aktionen Ausführen
'Dummy = Memcopy(mem_dummy , Rf12_data(1) , Framelength , 2)
End Select
Else
Print "Framehandler-CRC-Bad" ; Crc_rx
'Dummy = Memcopy(mem_dummy , Rf12_data(1) , Framelength , 2)
End If
Else
Print "das war nicht für mich " ; Dab1
End If
End If
Return
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Funkdaten_handler: 'Auswertung der Nutzdaten.... nur als Denkhilfe :)
Select Case Rf12_data(6)
Case 0 : Reset Led_vorn
Stop Timer1
Pwm_byte = 0
Reset Led_pwm
Case 1 : Reset Led_vorn 'Led_vorn = 0
Start Timer1
Pwm_byte = 155
End Select
Return
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ UART ISR
Rxd_isr: '
Rx_data = Udr 'Zeichen aus UART holen
Uart_rxd = 1
Return
Vielen Dank für Eure Hilfe!!!
Lesezeichen