PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] MCP2515 Remoteframe wird nicht gesendet.........



Kampi
30.08.2012, 18:32
Hallo Forum,

ich komme im Moment mit meinen CAN-Controllern nicht weiter.
Ich habe eine CAN-Platine + ein RN-Control mit einem MCP2515. Die Datenübertragung zwischen beiden Systemen funktioniert fehlerfrei.
Jetzt habe ich bei meinem RN-Control das Programm etwas angepasst, damit ich abwechselnd einen Remote oder Data-Frame senden kann.
Das ganze funktioniert auch tadellos, sprich nach dem aufspielen des Programmes tippe ich ein "R" ein und ein Remoteframe wird gesendet. Und das jedes mal wenn ich ein "R" eintippe.
Tippe ich ein "D" ein und einen Wert zwischen 0-255 wird er auch problemlos gesendet. Und das kann ich auch immer wiederholen.
Jetzt komme ich zu meinem Problem....
Wenn ich nach einem Remoteframe einen Datenframe sende funktioniert es problemlos.
Will ich allerdings nach dem Datenframe wieder einen Remoteframe senden, wird das gesendet was vorher mit dem Datenframe übermittelt wurde und KEIN Remoteframe.
Dieses Problem verschwindet auch erst wieder wenn ich den Controller vom RN-Control neu flashe, sprich nach einem Druck auf dem Reset-Taster bleibt das Problem :/.
Hier ein Auszug aus den Terminals:

Das erscheint bei der Eingabe eines "R"


Buffer: 1
Frame: 1
Filter: 0
Nachricht in Buffer 0
Standard Remote Frame
Status: 72
ID Nachricht: 7


Das erscheint beim Eingeben eines "D" mit einem Zahlenwert:


Buffer: 1
Frame: 0
Filter: 0
Nachricht in Buffer 0
Standard Data Frame
Status: 64
ID Nachricht: 7
Länge Nachricht: 8
Daten 1: 10
Daten 2: 4
Daten 3: 9
Daten 4: 16
Daten 5: 25
Daten 6: 36
Daten 7: 49
Daten 8: 64


Und das erscheint wenn ich wieder ein "R" eingebe:


Buffer: 1
Frame: 0
Filter: 0
Nachricht in Buffer 0
Standard Data Frame
Status: 64
ID Nachricht: 7
Länge Nachricht: 8
Daten 1: 10
Daten 2: 4
Daten 3: 9
Daten 4: 16
Daten 5: 25
Daten 6: 36
Daten 7: 49
Daten 8: 64


Das hier ist das Programm auf dem RN-Control:



'Mikrocontroller
$regfile = "m32def.dat"
$crystal = 16000000

'Stacks
$hwstack = 200
$swstack = 200
$framesize = 400

'UART konfigurieren
$baud = 19200

'SPI konfigurieren
Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Noss = 1 , Clockrate = 16
Spiinit

'Unterprogramme
Declare Function Read_rx_status As Byte
Declare Function Read_register(byval Adresse As Byte) As Byte
Declare Sub Register
Declare Sub Recieve_can
Declare Sub Mcp2515_init
Declare Sub Interrupt_occur
Declare Sub Config_filter(byval Filter As Byte , Byval Buffer As Byte , Byval Ex_f_enable As Byte)
Declare Sub Send_can(daten As Byte , Byval Tx_identifier As Long , Byval Ex_id_enable As Byte)
Declare Sub Bitmodify(byval Reg_add As Byte , Byval Reg_mask As Byte , Byval Reg_val As Byte)
Declare Sub Send_remote(byval Tx_identifier As Long , Byval Ex_id_enable As Byte)
Declare Sub Write_register(byval Adresse As Byte , Byval Daten As Byte)

'Befehle
Const Spi_read = &H03
Const Spi_write = &H02
Const Spi_reset = &HC0
Const Spi_rts0 = &H81
Const Spi_bitmodify = &H05
Const Spi_rx_status = &HB0
Const Spi_read_rx = &H90

'Registeradressen
'Controlregister
Const Cnf1 = &H2A
Const Cnf2 = &H29
Const Cnf3 = &H28
Const Canctrl = &H0F 'Control Register vom MCP2515
Const Caninte = &H2B 'Interrupt Enable vom MCP2515
Const Canintf = &H2C 'Interrupfflags vom MCP2515

'Transmit Buffer
Const Txb0ctrl = &H30 'Transmit Buffer 0 Control Register
Const Txb0sidh = &H31 'Transmit Buffer 0 Std Identifier High
Const Txb0sidl = &H32 'Transmit Buffer 0 Std Identifier Low
Const Txb0eid8 = &H33 'Transmit Buffer 0 Ext Identifier High
Const Txb0eid0 = &H34 'Transmit Buffer 0 Ext Identifier Low
Const Txb0dlc = &H35 'Transmit Buffer 0 Data Length Code
Const Txb0d0 = &H36 'Transmit Buffer 0 Data Byte 0
Const Txb0d1 = &H37 'Transmit Buffer 0 Data Byte 1
Const Txb0d2 = &H38 'Transmit Buffer 0 Data Byte 2
Const Txb0d3 = &H39 'Transmit Buffer 0 Data Byte 3
Const Txb0d4 = &H3A 'Transmit Buffer 0 Data Byte 4
Const Txb0d5 = &H3B 'Transmit Buffer 0 Data Byte 5
Const Txb0d6 = &H3C 'Transmit Buffer 0 Data Byte 6
Const Txb0d7 = &H3D 'Transmit Buffer 0 Data Byte 7

'Recieve Buffer
Const Rxm0sidh = &H20 'Receive Buffer 0 Std Identifier High
Const Rxm0sidl = &H21 'Receive Buffer 0 Std Identifier Low
Const Rxm0eid8 = &H22 'Receive Buffer 0 Ext Identifier High
Const Rxm0eid0 = &H23 'Receive Buffer 0 Ext Identifier low
Const Rxm1sidh = &H24 'Receive Buffer 1 Std Identifier High
Const Rxm1sidl = &H25 'Receive Buffer 1 Std Identifier Low
Const Rxm1eid8 = &H26 'Receive Buffer 1 Ext Identifier High
Const Rxm1eid0 = &H27 'Receive Buffer 1 Ext Identifier low
Const Rxb0ctrl = &H60 'Recieve Buffer 0 Control Register
Const Rxb1ctrl = &H70 'Recieve Buffer 1 Control Register
Const Rxb0d0 = &H66 'Revieve Buffer 0 Data Byte 0
Const Rxb0d1 = &H67 'Revieve Buffer 0 Data Byte 1
Const Rxb0d2 = &H68 'Revieve Buffer 0 Data Byte 2
Const Rxb0d3 = &H69 'Revieve Buffer 0 Data Byte 3
Const Rxb0d4 = &H60 'Revieve Buffer 0 Data Byte 4
Const Rxb0d5 = &H6A 'Revieve Buffer 0 Data Byte 5
Const Rxb0d6 = &H6B 'Revieve Buffer 0 Data Byte 6
Const Rxb0d7 = &H6C 'Revieve Buffer 0 Data Byte 7

'Error
Const Eflg = &H2D 'Errorflags
Const Tec = &H1C 'Tx Error Counter
Const Rec = &H1D 'Rx Error Counter

'Acceptance Filter
'RXF0
'Standard Identifier
Const Rxf0sidh = &H00
Const Rxf0sidl = &H01

'Extended Identifier
Const Rxf0eidh = &H02
Const Rxf0eidl = &H03

'RXF1
'Standard Identifier
Const Rxf1sidh = &H04
Const Rxf1sidl = &H05

'Extended Identifier
Const Rxf1eidh = &H06
Const Rxf1eidl = &H07

'RXF2
'Standard Identifier
Const Rxf2sidh = &H08
Const Rxf2sidl = &H09

'Extended Identifier
Const Rxf2eidh = &H0A
Const Rxf2eidl = &H0B

'RXF3
'Standard Identifier
Const Rxf3sidh = &H10
Const Rxf3sidl = &H11

'Extended Identifier
Const Rxf3eidh = &H12
Const Rxf3eidl = &H13

'RXF4
'Standard Identifier
Const Rxf4sidh = &H14
Const Rxf4sidl = &H15

'Extended Identifier
Const Rxf4eidh = &H16
Const Rxf4eidl = &H17

'RXF5
'Standard Identifier
Const Rxf5sidh = &H18
Const Rxf5sidl = &H19

'Extended Identifier
Const Rxf5eidh = &H1A
Const Rxf5eidl = &H1B

'I/O Einstellungen
Config Portb.4 = Output
Config Pind.2 = Input

'Namen vergeben
Cs Alias Portb.4

'Globale Variablen
Dim Status As Byte
Dim Interrupt As Byte
Dim Errorcode As Byte
Dim Statusflag As Byte
Dim Input_uart As Long
Dim Can_message(10) As Byte
Dim Can_remote(2) As Integer
Dim Message_id As Long

Dim Identifier As Long
Dim Test(8) As Byte
Dim A As String * 10

Identifier = 200
Test(1) = 2
Test(2) = 4
Test(3) = 9
Test(4) = 16
Test(5) = 25
Test(6) = 36
Test(7) = 49
Test(8) = 64


'Interrupts einstellen
Enable Interrupts 'Interrupts aktivieren '
Config Int0 = Falling 'INT0 auf fallende Flanke einstellen
On Int0 Mcp2515_int 'Sprungmarke für INT0
'On Urxc Uart_recieved
'Enable Urxc
Enable Int0 'INT0 aktivieren

'Chipselect auf High setzen
Set Cs
Wait 1

'MCP2515 initialisieren
Mcp2515_init

'Filter einstellen
'Config_filter 7 , 0 'Filter einstellen (1. Zahl = Filter, 2. Zahl = Buffer)

'Hauptprogramm
Do

Input "Eingabe: " , A
Select Case A
Case "R" : Print "Remote"
Send_remote 7 , 0
Case "D" : Print "Data
Input "Daten: " , Test(1)
Send_can Test(1) , 7 , 0 'Daten senden (1. Zahl = ID , 2. Zahl = Identifiertyp - 0 = Standard, 1 = Extended)
Incr Test(1)
End Select
A = ""




Loop
End



'Unterprogramme
'-------------------------------------------------------------------------------------------------------------------

Function Read_rx_status() As Byte

Reset Cs 'CS auf Low ziehen

Spdr = Spi_rx_status 'Befehl zum auslesen des Rx Status Register ins Datenregister schreiben
Spiout Spdr , 1 'Inhalt des Datenregisters über SPI senden
Waitus 1 'Kurze Zeit warten
Spiin Read_rx_status , 1 'Antwort des MCP2515 unter "Status" speichern

Set Cs

End Function

'-------------------------------------------------------------------------------------------------------------------

Function Read_register(byval Adresse As Byte ) As Byte

Reset Cs 'Chipselect auf Low ziehen
Spdr = Spi_read 'Inhalt von "SPI_Read" im Datenregister speichern
Spiout Spdr , 1
Spiout Adresse , 1
Waitus 1
Spiin Read_register , 1 'Registerinhalt einlesen
Set Cs 'Chipselect auf High ziehen

End Function

'-------------------------------------------------------------------------------------------------------------------

Sub Mcp2515_init

Reset Cs

Spdr = Spi_reset 'MCP2515 reseten
Do
Loop Until Spsr.spif = 1
Set Cs

'Control Register beschreiben
Write_register Canctrl , &H88 'Device in Configuration Mode versetzen, Nachrichten nur 1x versenden

'Interrupts einstellen
Write_register Caninte , &H05 'Transmit und Recieve Buffer 0 Interrupt aktivieren

'Tx-Konfiguration
Bitmodify Txb0ctrl , &H03 , &H03 'Priorität der Nachrichten auf "Highest" stellen

'Bittiming einstellen
Write_register Cnf1 , &H03 'Baudrate einstellen
Write_register Cnf2 , &HA0 'Phasensegmenteinstellungen
Write_register Cnf3 , &H02

'Rx Buffer einstellen
Write_register Rxb0ctrl , &H20 'Standard Identifier erlauben
Write_register Rxb1ctrl , &H60

Bitmodify Canctrl , &HE0 , &H0 'CAN-Controller in den "Normal Mode" versetzen

'Tx Message Identifier einstellen
Write_register Txb0sidh , &H00
Write_register Txb0sidl , &H00

End Sub

'-------------------------------------------------------------------------------------------------------------------

Sub Write_register(byval Adresse As Byte , Byval Daten As Byte)

Reset Cs 'Chipselect auf Low ziehen
Spdr = Spi_write 'Inhalt von "SPI-Write" ins SPI_Data_Register schieben
Do 'Schleife bis SPI Interrupt Flag gesetzt wurde, also bis
Loop Until Spsr.spif = 1 'die Übertragung abgeschlossen ist

Spdr = Adresse
Do
Loop Until Spsr.spif = 1

Spdr = Daten
Do
Loop Until Spsr.spif = 1
Set Cs 'Chipselect auf High ziehen
End Sub

'-------------------------------------------------------------------------------------------------------------------

Sub Bitmodify(reg_add , Reg_mask , Reg_val)

Reset Cs
Spdr = Spi_bitmodify
Do
Loop Until Spsr.spif = 1
Spdr = Reg_add
Do
Loop Until Spsr.spif = 1
Spdr = Reg_mask
Do
Loop Until Spsr.spif = 1
Spdr = Reg_val
Do
Loop Until Spsr.spif = 1
Set Cs

End Sub

'-------------------------------------------------------------------------------------------------------------------

Sub Interrupt_occur
Local Errorflag As Byte
Local Rx_error As Byte

Interrupt = Read_register(canintf) 'Interruptflags auslesen um zu erfahren welcher Interrupt
'ausgelöst wurde
'Select Case Interrupt
'Case 1 : Recieve_can
'Case 2 : Recieve_can

'Case Else : Print "Error"
'End Select

If Interrupt > 32 Then
Errorflag = Read_register(eflg)
Rx_error = Read_register(rec)
End If


Print "Interruptflag: " ; Interrupt
Print "Error: " ; Errorflag
Print "Errorcounter: " ; Rx_error

End Sub

'-------------------------------------------------------------------------------------------------------------------

Sub Config_filter(byval Filter As Byte , Byval Buffer As Byte , Byval Ex_f_enable As Byte)

Local Filter_low As Integer
Local Filter_high As Integer
Local Id0_high As Byte
Local Id0_low As Byte
Local Id1_high As Byte
Local Id1_low As Byte

Bitmodify Canctrl , &HE0 , &H80, 'CAN-Controller in den "Configuration Mode" versetzen

'Identifier einstellen
Filter_low = Filter 'Speichert den Identifier in zwei Variablen und schiebt
Filter_high = Filter 'den Wert um 5 Stellen nach rechts um die drei
Shift Filter_low , Left , 5 ' niedrigsten Bits zu gewinnen. Dasselbe passiert für
Shift Filter_high , Right , 3 'die acht höchsten Bits. Anschließend werden die Werte
'in die passenden Register geschrieben.
If Buffer = 0 Then
Id0_high = Filter_high
Id0_low = Filter_low
Elseif Buffer = 1 Then
Id1_high = Filter_high
Id1_low = Filter_low
Else
Print "Unbekannter Buffer"
Errorcode = 3
End If

'Maskenbits setzen
Write_register Rxm0sidh , &HFF
Write_register Rxm0sidl , &HFF
Write_register Rxm1sidh , &HFF
Write_register Rxm1sidl , &HFF

'Filter setzen
Write_register Rxf0sidh , Id0_high
Write_register Rxf0sidl , Id0_low
Write_register Rxf1sidh , Id1_high
Write_register Rxf1sidl , Id1_low

Bitmodify Canctrl , &HE0 , &H0 'CAN-Controller in den "Normal Mode" versetzen

End Sub

'-------------------------------------------------------------------------------------------------------------------

Sub Send_remote(byval Tx_identifier As Long , Byval Ex_id_enable As Byte)

Local Tx_low As Integer
Local Tx_high As Integer
Local Id_high As Byte
Local Id_low As Byte

'Prüfen ob die Nachricht mit einem 29-Bit Identifier versendet werden soll oder nicht
If Ex_id_enable = 0 Then

'Prüfen ob der Identifier die richtige Länge hat
If Tx_identifier > 2047 Then

Print "Identifier beträgt " ; Tx_identifier ; " und ist damit zu groß. Maximaler Wert ist 2047!"
Errorcode = 1

Else

'Identifier einstellen
Tx_low = Tx_identifier 'Speichert den Identifier in zwei Variablen und schiebt
Tx_high = Tx_identifier 'den Wert um 5 Stellen nach rechts um die drei
Shift Tx_low , Left , 5 ' niedrigsten Bits zu gewinnen. Dasselbe passiert für
Shift Tx_high , Right , 3 'die acht höchsten Bits. Anschließend werden die Werte
'in die passenden Register geschrieben.
Id_high = Tx_high
Id_low = Tx_low

'ID in die ID-Register schreiben
Write_register Txb0sidh , Id_high
Write_register Txb0sidl , Id_low

'Renotebit setzen
Bitmodify Txb0ctrl , &H08 , &H08

Reset Cs
Spdr = Spi_rts0 'Übertragung auslösen
Do
Loop Until Spsr.spif = 1
Set Cs

End If

Elseif Ex_id_enable = 1 Then

Else

Print "Error. Unbekannter Identifier!"
Errorcode = 2

End If

End Sub

'-------------------------------------------------------------------------------------------------------------------

Sub Send_can(daten(8) As Byte , Byval Tx_identifier As Long , Byval Ex_id_enable As Byte)

Local Tx_low As Integer
Local Tx_high As Integer
Local Id_high As Byte
Local Id_low As Byte

'Prüfen ob die Nachricht mit einem 29-Bit Identifier versendet werden soll oder nicht
If Ex_id_enable = 0 Then

'Prüfen ob der Identifier die richtige Länge hat
If Tx_identifier > 2047 Then

Print "Identifier beträgt " ; Tx_identifier ; " und ist damit zu groß. Maximaler Wert ist 2047!"
Errorcode = 1
Return

Else

'Identifier einstellen
Tx_low = Tx_identifier 'Speichert den Filter in zwei Variablen und schiebt
Tx_high = Tx_identifier 'den Wert um 5 Stellen nach rechts um die drei
Shift Tx_low , Left , 5 ' niedrigsten Bits zu gewinnen. Dasselbe passiert für
Shift Tx_high , Right , 3 'die acht höchsten Bits. Anschließend werden die Werte
'in die passenden Register geschrieben.
Id_high = Tx_high
Id_low = Tx_low

'ID in die ID-Register schreiben
Write_register Txb0sidh , Id_high
Write_register Txb0sidl , Id_low

'Daten in die Datenregister schreiben
Write_register Txb0dlc , 8
Write_register Txb0d0 , Daten(1)
Write_register Txb0d1 , Daten(2)
Write_register Txb0d2 , Daten(3)
Write_register Txb0d3 , Daten(4)
Write_register Txb0d4 , Daten(5)
Write_register Txb0d5 , Daten(6)
Write_register Txb0d6 , Daten(7)
Write_register Txb0d7 , Daten(8)

Reset Cs
Spdr = Spi_rts0 'Übertragung auslösen
Do
Loop Until Spsr.spif = 1
Set Cs

End If

Elseif Ex_id_enable = 1 Then

Else

Print "Error. Unbekannter Identifier!"
Errorcode = 2
Return

End If

End Sub

'-------------------------------------------------------------------------------------------------------------------

Sub Recieve_can

'Variablen für die Empfangsroutine
Local Id_low As Integer 'Buffer für die drei niedrigsten ID-Bits
Local Id_high As Integer 'Buffer für die acht höchsten ID-Bits
Local Laenge As Byte 'Buffer für die vier Längen-Bits
Local Daten As Byte
Local Dummy As Byte
Local Daten_laenge As Byte
Local Zaehler_laenge As Byte

'Variablen löschen
Id_high = 0
Id_low = 0
Laenge = 0

'Status auslesen und analysieren
Status = Read_rx_status()

If Status = 128 Then 'Nachricht in Rx-Buffer 1



Elseif Status = 72 Then 'Standard Remote Anfrage

'Lesen der Buffer auslösen
Reset Cs
Spdr = Spi_read_rx
Spiout Spdr , 1
Waitus 1

'CAN-Nachricht nach und nach empfangen
'ID auslesen
Spiin Id_high , 1
Spiin Id_low , 1

Spiin Dummy , 1 'Beide Bytes des Extended Identifiers einlesen
Spiin Dummy , 1 'und in einem Dummy speichern

'Länge auslesen
Spiin Laenge , 1

'CAN-Nachricht bearbeiten
'Standard Identifier auslesen 'High Identifier erkennen funktioniert!
Shift Id_high , Left , 3 'Verschiebung beim Senden rückgängig machen
Shift Id_low , Right , 5

Can_remote(1) = Id_high 'und Werte logisch miteiander verknüpfen um daraus
Can_remote(1) = Can_remote(1) Or Id_low 'die komplette ID zu gewinnen
Can_remote(2) = Laenge

Elseif Status = 64 Then 'Nachricht in Rx-Buffer 0

'Lesen der Buffer auslösen
Reset Cs
Spdr = Spi_read_rx
Spiout Spdr , 1
Waitus 1

'CAN-Nachricht nach und nach empfangen
'ID auslesen
Spiin Id_high , 1
Spiin Id_low , 1

Spiin Dummy , 1 'Beiden Bytes des Extended Identifiers einlesen
Spiin Dummy , 1

'Länge auslesen
Spiin Laenge , 1
Zaehler_laenge = Laenge + 2
Laenge = Laenge And &H0F

'Daten auslesen
For Daten_laenge = 3 To Zaehler_laenge
Spiin Can_message(daten_laenge) , 1
Next

'CAN-Nachricht bearbeiten
'Standard Identifier auslesen
Shift Id_high , Left , 3 'Verschiebung beim Senden rückgängig machen
Shift Id_low , Right , 5
Laenge = Laenge And &H0F
Can_message(1) = Id_high 'und Werte logisch miteiander verknüpfen um daraus
Can_message(1) = Can_message(1) Or Id_low 'die komplette ID zu gewinnen
Can_message(2) = Laenge

Else
Print "Keine neue Nachricht vorhanden!"

End If

Set Cs
Waitus 1 'Kurz warten

End Sub

'-------------------------------------------------------------------------------------------------------------------

Sub Register

'Terminalausgabe
Print "Registereinstellungen:"
Print "Registerinhalt CNF1: " ; Read_register(cnf1)
Print "Registerinhalt CNF2: " ; Read_register(cnf2)
Print "Registerinhalt CNF3: " ; Read_register(cnf3)
Print "Registerinhalt CAN Control: " ; Read_register(canctrl)
Print "Registerinhalt TXB0 Control: " ; Read_register(txb0ctrl)
Print "Tx Identifier: " ; Identifier
Print "Registerinhalt TXB0 Data Lenght: " ; Read_register(txb0dlc)
Print "Registerinhalt CAN Interrupt Enable: " ; Read_register(caninte)
Print "Registerinhalt CAN Datenregister: " ; Read_register(txb0d0)
Print "----------------------------------------------------------"

End Sub


'ISRs
'-------------------------------------------------------------------------------------------------------------------

'ISR von INT0
Mcp2515_int:

Statusflag = 1 'Interrupt ausgelöst

Return

'-------------------------------------------------------------------------------------------------------------------

'ISR vom UART
'Uart_recieved:

' Input_uart = Udr

'Return

'-------------------------------------------------------------------------------------------------------------------

Kampi
30.08.2012, 18:34
Da der Thread in einem Stück zu lang ist....

Hier das Programm auf meinem CAN-Knoten:



'Mikrocontroller
$regfile = "m32def.dat"
$crystal = 16000000

'Stacks
$hwstack = 200
$swstack = 200
$framesize = 400

'Watchdog konfigurieren
Config Watchdog = 2048

'UART konfigurieren
$baud = 19200

'SPI konfigurieren
Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Noss = 1 , Clockrate = 16
Spiinit

'TWI konfigurieren
Config Sda = Portc.1
Config Scl = Portc.0
Config Twi = 100000 'TWI Frequenz

'Unterprogramme
Declare Function Read_rx_status() As Byte
Declare Function Read_temperature() As Byte
Declare Function Read_register(byval Adress As Byte) As Byte
Declare Function Read_eeprom(byval Adress As Integer) As Byte
Declare Sub Recieve_can
Declare Sub Mcp2515_init
Declare Sub Interrupt_occur
Declare Sub Write_eeprom(byval Data_eeprom As Byte , Byval Adress As Integer)
Declare Sub Config_filter(byval Filter_wert As Byte , Byval Buffer As Byte , Byval Filter As Byte , Byval Ex_f_enable As Byte)
Declare Sub Send_can(daten As Byte , Byval Tx_identifier As Long , Byval Ex_id_enable As Byte , Byval Remote As Byte)
Declare Sub Bitmodify(byval Reg_add As Byte , Byval Reg_mask As Byte , Byval Reg_val As Byte)
Declare Sub Send_remote(byval Tx_identifier As Long , Byval Ex_id_enable As Byte)
Declare Sub Write_register(byval Adresse As Byte , Byval Daten As Byte)

'Befehle
Const Spi_read = &H03
Const Spi_write = &H02
Const Spi_reset = &HC0
Const Spi_rts0 = &H81
Const Spi_bitmodify = &H05
Const Spi_rx_status = &HB0
Const Spi_read_rx0 = &H90
Const Spi_read_rx1 = &H96

'Registeradressen
'Controlregister
Const Cnf1 = &H2A
Const Cnf2 = &H29
Const Cnf3 = &H28
Const Canctrl = &H0F 'Control Register vom MCP2515
Const Caninte = &H2B 'Interrupt Enable vom MCP2515
Const Canintf = &H2C 'Interrupfflags vom MCP2515

'Transmit Buffer
Const Txb0ctrl = &H30 'Transmit Buffer 0 Control Register
Const Txb0sidh = &H31 'Transmit Buffer 0 Std Identifier High
Const Txb0sidl = &H32 'Transmit Buffer 0 Std Identifier Low
Const Txb0eid8 = &H33 'Transmit Buffer 0 Ext Identifier High
Const Txb0eid0 = &H34 'Transmit Buffer 0 Ext Identifier Low
Const Txb0dlc = &H35 'Transmit Buffer 0 Data Length Code
Const Txb0d0 = &H36 'Transmit Buffer 0 Data Byte 0
Const Txb0d1 = &H37 'Transmit Buffer 0 Data Byte 1
Const Txb0d2 = &H38 'Transmit Buffer 0 Data Byte 2
Const Txb0d3 = &H39 'Transmit Buffer 0 Data Byte 3
Const Txb0d4 = &H3A 'Transmit Buffer 0 Data Byte 4
Const Txb0d5 = &H3B 'Transmit Buffer 0 Data Byte 5
Const Txb0d6 = &H3C 'Transmit Buffer 0 Data Byte 6
Const Txb0d7 = &H3D 'Transmit Buffer 0 Data Byte 7

'Recieve Buffer
Const Rxm0sidh = &H20 'Receive Buffer 0 Std Identifier High
Const Rxm0sidl = &H21 'Receive Buffer 0 Std Identifier Low
Const Rxm0eid8 = &H22 'Receive Buffer 0 Ext Identifier High
Const Rxm0eid0 = &H23 'Receive Buffer 0 Ext Identifier low
Const Rxm1sidh = &H24 'Receive Buffer 1 Std Identifier High
Const Rxm1sidl = &H25 'Receive Buffer 1 Std Identifier Low
Const Rxm1eid8 = &H26 'Receive Buffer 1 Ext Identifier High
Const Rxm1eid0 = &H27 'Receive Buffer 1 Ext Identifier low
Const Rxb0ctrl = &H60 'Recieve Buffer 0 Control Register
Const Rxb1ctrl = &H70 'Recieve Buffer 1 Control Register
Const Rxb0d0 = &H66 'Revieve Buffer 0 Data Byte 0
Const Rxb0d1 = &H67 'Revieve Buffer 0 Data Byte 1
Const Rxb0d2 = &H68 'Revieve Buffer 0 Data Byte 2
Const Rxb0d3 = &H69 'Revieve Buffer 0 Data Byte 3
Const Rxb0d4 = &H60 'Revieve Buffer 0 Data Byte 4
Const Rxb0d5 = &H6A 'Revieve Buffer 0 Data Byte 5
Const Rxb0d6 = &H6B 'Revieve Buffer 0 Data Byte 6
Const Rxb0d7 = &H6C 'Revieve Buffer 0 Data Byte 7

'Error
Const Eflg = &H2D 'Errorflags
Const Tec = &H1C 'Tx Error Counter
Const Rec = &H1D 'Rx Error Counter

'Acceptance Filter
'RXF0
'Standard Identifier
Const Rxf0sidh = &H00
Const Rxf0sidl = &H01

'Extended Identifier
Const Rxf0eidh = &H02
Const Rxf0eidl = &H03

'RXF1
'Standard Identifier
Const Rxf1sidh = &H04
Const Rxf1sidl = &H05

'Extended Identifier
Const Rxf1eidh = &H06
Const Rxf1eidl = &H07

'RXF2
'Standard Identifier
Const Rxf2sidh = &H08
Const Rxf2sidl = &H09

'Extended Identifier
Const Rxf2eidh = &H0A
Const Rxf2eidl = &H0B

'RXF3
'Standard Identifier
Const Rxf3sidh = &H10
Const Rxf3sidl = &H11

'Extended Identifier
Const Rxf3eidh = &H12
Const Rxf3eidl = &H13

'RXF4
'Standard Identifier
Const Rxf4sidh = &H14
Const Rxf4sidl = &H15

'Extended Identifier
Const Rxf4eidh = &H16
Const Rxf4eidl = &H17

'RXF5
'Standard Identifier
Const Rxf5sidh = &H18
Const Rxf5sidl = &H19

'Extended Identifier
Const Rxf5eidh = &H1A
Const Rxf5eidl = &H1B

'I²C Adressen
'Adresse des LM75
Const Lm75r = &H9F 'Adresse des Temperatursensors

'Adresse des EEPROM
Const 24lc128w = &HA0
Const 24lc128r = &HA1

'I/O Einstellungen
Config Portb.4 = Output
Config Pind.2 = Input

'Namen vergeben
Cs Alias Portb.4

'Watchdog starten
'Start Watchdog

'I²C starten
I2cinit

'Globale Variablen
'I²C EEPROM
Dim Eeprom_in As Byte
Dim Eeprom As Byte

'LM75
Dim Temperatur As Byte

'CAN
Dim Status As Byte
Dim Interrupt As Byte
Dim Errorcode As Byte
Dim Statusflag As Byte
Dim Can_message(10) As Byte

'UART
Dim Input_string As String * 20
Dim Input_string_overlay(20) As Byte At Input_string Overlay
Dim Bytes_received As Byte

'Variablen setzen
Eeprom = 100
Bytes_received = 0
Can_message(1) = 0
Can_message(2) = 0
Can_message(3) = 0
Can_message(4) = 0
Can_message(5) = 0
Can_message(6) = 0
Can_message(7) = 0
Can_message(8) = 0
Can_message(9) = 0
Can_message(10) = 0

'Interrupts einstellen
Enable Interrupts 'Interrupts aktivieren '
Config Int0 = Falling 'INT0 auf fallende Flanke einstellen
On Int0 Mcp2515_int 'Sprungmarke für INT0
On Urxc Uart_recieved
Enable Urxc
Enable Int0 'INT0 aktivieren

Set Cs 'Chipselect auf High setzen
Wait 1

'MCP2515 initialisieren
Mcp2515_init

'EEPROM beschreiben
'Write_eeprom Eeprom , 2 'EEPROM beschreiben (1. Zahl = Daten, 2. Zahl = Speicheradresse)

'Filter einstellen
Config_filter 7 , 0 , 0 , 0 'Filter einstellen (1. Zahl = Filterwert, 2. Zahl = Buffer, 3. Zahl = Filter, 4. Zahl = Identifiertyp - 0 = Standard, 1 = Extended)

'Hauptprogramm
'-------------------------------------------------------------------------------------------------------------------

Do

'Empfangene Nachricht auswerten
If Statusflag = 1 Then

Interrupt_occur 'Interruptquelle auslesen


End If

Wait 1

Loop
End


'Unterprogramme
'-------------------------------------------------------------------------------------------------------------------

Function Read_rx_status() As Byte

Reset Cs 'CS auf Low ziehen

Spdr = Spi_rx_status 'Befehl zum auslesen des Rx Status Register ins Datenregister schreiben
Spiout Spdr , 1 'Inhalt des Datenregisters über SPI senden
Waitus 1 'Kurze Zeit warten
Spiin Read_rx_status , 1 'Antwort des MCP2515 unter "Status" speichern

Set Cs

End Function

'-------------------------------------------------------------------------------------------------------------------

Function Read_register(byval Adresse As Byte ) As Byte

Reset Cs 'Chipselect auf Low ziehen
Spdr = Spi_read 'Inhalt von "SPI_Read" im Datenregister speichern
Spiout Spdr , 1
Spiout Adress , 1
Waitus 1
Spiin Read_register , 1 'Registerinhalt einlesen
Set Cs 'Chipselect auf High ziehen

End Function

'-------------------------------------------------------------------------------------------------------------------

Sub Mcp2515_init

Reset Cs

Spdr = Spi_reset 'MCP2515 reseten
Do
Loop Until Spsr.spif = 1
Set Cs

'Control Register beschreiben
Write_register Canctrl , &H88 'Device in Configuration Mode versetzen, Nachrichten nur 1x versenden

'Interrupts einstellen
Write_register Caninte , &HFF 'Transmit und Recieve Buffer 0 Interrupt aktivieren

'Tx-Konfiguration
Bitmodify Txb0ctrl , &H03 , &H03 'Priorität der Nachrichten auf "Highest" stellen

'Bittiming einstellen
Write_register Cnf1 , &H03 'Baudrate einstellen
Write_register Cnf2 , &HA0 'Phasensegmenteinstellungen
Write_register Cnf3 , &H02

'Rx Buffer einstellen
Write_register Rxb0ctrl , &H20 'Standard Identifier erlauben
Write_register Rxb1ctrl , &H20

'Maskenbits setzen
Write_register Rxm0sidh , &HFF
Write_register Rxm0sidl , &HFF
Write_register Rxm1sidh , &HFF '
Write_register Rxm1sidl , &HFF

Bitmodify Canctrl , &HE0 , &H0 'CAN-Controller in den "Normal Mode" versetzen

'Tx Message Identifier einstellen
Write_register Txb0sidh , &H00
Write_register Txb0sidl , &H00

End Sub

'-------------------------------------------------------------------------------------------------------------------

Sub Write_register(byval Adress As Byte , Byval Daten As Byte)

Reset Cs 'Chipselect auf Low ziehen
Spdr = Spi_write 'Inhalt von "SPI-Write" ins SPI_Data_Register schieben
Do 'Schleife bis SPI Interrupt Flag gesetzt wurde, also bis
Loop Until Spsr.spif = 1 'die Übertragung abgeschlossen ist

Spdr = Adresse
Do
Loop Until Spsr.spif = 1

Spdr = Daten
Do
Loop Until Spsr.spif = 1
Set Cs 'Chipselect auf High ziehen

End Sub

'-------------------------------------------------------------------------------------------------------------------

Sub Bitmodify(reg_add , Reg_mask , Reg_val)

Reset Cs
Spdr = Spi_bitmodify
Do
Loop Until Spsr.spif = 1
Spdr = Reg_add
Do
Loop Until Spsr.spif = 1
Spdr = Reg_mask
Do
Loop Until Spsr.spif = 1
Spdr = Reg_val
Do
Loop Until Spsr.spif = 1
Set Cs

End Sub

'-------------------------------------------------------------------------------------------------------------------

Sub Interrupt_occur
Local Errorflag As Byte
Local Rx_error As Byte

Interrupt = Read_register(canintf) 'Interruptflags auslesen um zu erfahren welcher Interrupt
'ausgelöst wurde
Recieve_can

If Interrupt > 32 Then
Errorflag = Read_register(eflg)
Rx_error = Read_register(rec)
End If

Print "Interruptflag: " ; Interrupt
Print "Errorflag: " ; Errorflag
Print "------------------------------------------------------------------------"

End Sub

'-------------------------------------------------------------------------------------------------------------------

Sub Config_filter(byval Filter_wert As Byte , Byval Buffer As Byte , Byval Filter As Byte , Byval Ex_f_enable As Byte)

Local Filter_low As Integer
Local Filter_high As Integer
Local Id_high As Byte
Local Id_low As Byte

Bitmodify Canctrl , &HE0 , &H80, 'CAN-Controller in den "Configuration Mode" versetzen

If Ex_f_enable = 0 Then

'Standardidentifier einstellen
Filter_low = Filter_wert 'Speichert den Identifier in zwei Variablen und schiebt
Filter_high = Filter_wert 'den Wert um 5 Stellen nach rechts um die drei
Shift Filter_low , Left , 5 ' niedrigsten Bits zu gewinnen. Dasselbe passiert für
Shift Filter_high , Right , 3 'die acht höchsten Bits. Anschließend werden die Werte
'in die passenden Register geschrieben.
If Buffer = 0 Then

Select Case Filter
Case 0 : Id_high = Filter_high
Id_low = Filter_low
Write_register , Rxf0sidh , Id_high
Write_register , Rxf0sidl , Id_low

Case 1 : Id_high = Filter_high
Id_low = Filter_low
Write_register , Rxf1sidh , Id_high
Write_register , Rxf1sidl , Id_low
End Select

Elseif Buffer = 1 Then

Select Case Filter
Case 5 : Id_high = Filter_high
Id_low = Filter_low
Write_register , Rxf0sidh , Id_high
Write_register , Rxf0sidl , Id_low
End Select

Else

Print "Unbekannter Buffer"
Errorcode = 3

End If

Elseif Ex_f_enable = 1 Then



Else

Print "Error. Unbekannter Identifier!"
Errorcode = 2

End If

Bitmodify Canctrl , &HE0 , &H0 'CAN-Controller in den "Normal Mode" versetzen

End Sub

'-------------------------------------------------------------------------------------------------------------------

Sub Send_remote(byval Tx_identifier As Long , Byval Ex_id_enable As Byte)

Local Tx_low As Integer
Local Tx_high As Integer
Local Id_high As Byte
Local Id_low As Byte

'Prüfen ob die Nachricht mit einem 29-Bit Identifier versendet werden soll oder nicht
If Ex_id_enable = 0 Then

'Prüfen ob der Identifier die richtige Länge hat
If Tx_identifier > 2047 Then

Print "Identifier beträgt " ; Tx_identifier ; " und ist damit zu groß. Maximaler Wert ist 2047!"
Errorcode = 1

Else

'Identifier einstellen
Tx_low = Tx_identifier 'Speichert den Identifier in zwei Variablen und schiebt
Tx_high = Tx_identifier 'den Wert um 5 Stellen nach rechts um die drei
Shift Tx_low , Left , 5 ' niedrigsten Bits zu gewinnen. Dasselbe passiert für
Shift Tx_high , Right , 3 'die acht höchsten Bits. Anschließend werden die Werte
'in die passenden Register geschrieben.
Id_high = Tx_high
Id_low = Tx_low

'ID in die ID-Register schreiben
Write_register Txb0sidh , Id_high
Write_register Txb0sidl , Id_low

'Renotebit setzen
Bitmodify Txb0ctrl , &H08 , &H08

Reset Cs
Spdr = Spi_rts0 'Übertragung auslösen
Do
Loop Until Spsr.spif = 1
Set Cs

End If

Elseif Ex_id_enable = 1 Then

Else

Print "Error. Unbekannter Identifier!"
Errorcode = 2

End If

End Sub

'-------------------------------------------------------------------------------------------------------------------

Sub Send_can(daten(8) As Byte , Byval Tx_identifier As Long , Byval Ex_id_enable As Byte , Byval Remote As Byte)

Local Tx_low As Integer
Local Tx_high As Integer
Local Id_high As Byte
Local Id_low As Byte

'Prüfen ob die Nachricht mit einem 29-Bit Identifier versendet werden soll oder nicht
If Ex_id_enable = 0 Then

'Prüfen ob der Identifier die richtige Länge hat
If Tx_identifier > 2047 Then

Print "Identifier beträgt " ; Tx_identifier ; " und ist damit zu groß. Maximaler Wert ist 2047!"
Errorcode = 1
Return

Else

'Identifier einstellen
Tx_low = Tx_identifier 'Speichert den Filter in zwei Variablen und schiebt
Tx_high = Tx_identifier 'den Wert um 5 Stellen nach rechts um die drei
Shift Tx_low , Left , 5 ' niedrigsten Bits zu gewinnen. Dasselbe passiert für
Shift Tx_high , Right , 3 'die acht höchsten Bits. Anschließend werden die Werte
'in die passenden Register geschrieben.
Id_high = Tx_high
Id_low = Tx_low

'ID in die ID-Register schreiben
Write_register Txb0sidh , Id_high
Write_register Txb0sidl , Id_low

'Daten in die Datenregister schreiben
Write_register Txb0dlc , 8
Write_register Txb0d0 , Daten(1)
Write_register Txb0d1 , Daten(2)
Write_register Txb0d2 , Daten(3)
Write_register Txb0d3 , Daten(4)
Write_register Txb0d4 , Daten(5)
Write_register Txb0d5 , Daten(6)
Write_register Txb0d6 , Daten(7)
Write_register Txb0d7 , Daten(8)

Reset Cs
Spdr = Spi_rts0 'Übertragung auslösen
Do
Loop Until Spsr.spif = 1
Set Cs

End If

Elseif Ex_id_enable = 1 Then

Else

Print "Error. Unbekannter Identifier!"
Errorcode = 2

End If

End Sub

'-------------------------------------------------------------------------------------------------------------------

Sub Recieve_can

'Variablen für die Empfangsroutine
Local Id_low As Integer 'Buffer für die drei niedrigsten ID-Bits
Local Id_high As Integer 'Buffer für die acht höchsten ID-Bits
Local Laenge As Byte 'Buffer für die vier Längen-Bits
Local Daten As Byte
Local Dummy As Byte
Local Daten_laenge As Byte
Local Zaehler_laenge As Byte
Local Buffer As Byte
Local Frame As Byte
Local Filter As Byte

'Variablen löschen
Id_high = 0
Id_low = 0
Laenge = 0

'Status auslesen und analysieren
Status = Read_rx_status()

'Buffer ausfiltern
Buffer = Status
Shift Buffer , Right , 6

'Frame ausfiltern
Frame = Status
Frame = Frame And &H18
Shift Frame , Right , 3

'Filter ausfiltern
Filter = Status
Filter = Filter And &H07

Print "Buffer: " ; Buffer
Print "Frame: " ; Frame
Print "Filter: " ; Filter
Print ""

If Buffer = 2 Then 'Nachricht in Rx-Buffer 1

Print "Nachricht in Buffer 1"


Elseif Buffer = 1 Then 'Nachricht in Rx-Buffer 0

Print "Nachricht in Buffer 0"

If Frame = 0 Then

Print "Standard Data Frame"

'Lesen vom Buffer auslösen
Reset Cs
Spdr = Spi_read_rx0
Spiout Spdr , 1
Waitus 1

'CAN-Nachricht nach und nach empfangen
'ID auslesen
Spiin Id_high , 1
Spiin Id_low , 1

Spiin Dummy , 1 'Beiden Bytes des Extended Identifiers einlesen
Spiin Dummy , 1

'Länge auslesen
Spiin Laenge , 1
Zaehler_laenge = Laenge + 2
Laenge = Laenge And &H0F

'Daten auslesen
For Daten_laenge = 3 To Zaehler_laenge
Spiin Can_message(daten_laenge) , 1
Next

'CAN-Nachricht bearbeiten
'Standard Identifier auslesen
Shift Id_high , Left , 3 'Verschiebung beim Senden rückgängig machen
Shift Id_low , Right , 5
Laenge = Laenge And &H0F
Can_message(1) = Id_high 'und Werte logisch miteiander verknüpfen um daraus
Can_message(1) = Can_message(1) Or Id_low 'die komplette ID zu gewinnen
Can_message(2) = Laenge

'Ausgabe
Print "Status: " ; Status
Print "ID Nachricht: " ; Can_message(1)
Print "Länge Nachricht: " ; Can_message(2)
Print "Daten 1: " ; Can_message(3)
Print "Daten 2: " ; Can_message(4)
Print "Daten 3: " ; Can_message(5)
Print "Daten 4: " ; Can_message(6)
Print "Daten 5: " ; Can_message(7)
Print "Daten 6: " ; Can_message(8)
Print "Daten 7: " ; Can_message(9)
Print "Daten 8: " ; Can_message(10)
Print "------------------------------------------------------------------------"

Elseif Frame = 1 Then

Print "Standard Remote Frame"

'Lesen vom Buffer auslösen
Reset Cs
Spdr = Spi_read_rx0
Spiout Spdr , 1
Waitus 1

'CAN-Nachricht nach und nach empfangen
'ID auslesen
Spiin Id_high , 1
Spiin Id_low , 1

Spiin Dummy , 1 'Beide Bytes des Extended Identifiers einlesen
Spiin Dummy , 1 'und in einem Dummy speichern
Spiin Dummy , 1

'CAN-Nachricht bearbeiten
'Standard Identifier auslesen 'High Identifier erkennen funktioniert!
Shift Id_high , Left , 3 'Verschiebung beim Senden rückgängig machen
Shift Id_low , Right , 5

Can_message(1) = Id_high 'und Werte logisch miteiander verknüpfen um daraus
Can_message(1) = Can_message(1) Or Id_low 'die komplette ID zu gewinnen

'Ausgabe
Print "Status: " ; Status
Print "ID Nachricht: " ; Can_message(1)
Print "------------------------------------------------------------------------"

End If

Else

Print "Keine neue Nachricht vorhanden!"

End If

Set Cs

End Sub

'-------------------------------------------------------------------------------------------------------------------

Function Read_temperature() As Byte
Local Lm75high As Byte
Local Lm75low As Byte

I2cstart 'TWI Startkondition
I2cwbyte Lm75r 'Übergabe der Leseadresse
I2crbyte Lm75high , Ack 'Auslesen des Registers für die Temperatur
I2crbyte Lm75low , Nack 'Auslesen des Registers für die Nachkommastelle
I2cstop 'TWI Stopkondition
If Lm75high > 127 Then
Temperatur = Lm75high And 127
Temperatur = Not Temperatur
Incr Temperatur
Else
Temperatur = Lm75high
End If

End Function

'-------------------------------------------------------------------------------------------------------------------

Function Read_eeprom(byval Adress As Integer) As Byte
Local Adress_high As Byte
Local Adress_low As Byte

Adress_high = High(adress) 'High Byte der Adresse speichern
Adress_low = Low(adress) 'Low Byte der Adresse speichern

I2cstart 'Startkondition
I2cwbyte 24lc128w 'Schreibadresse übertragen
I2cwbyte Adress_high 'High Byte der Adresse schreiben
I2cwbyte Adress_low 'Low Byte der Adresse schreiben

I2cstart 'Startkondition
I2cwbyte 24lc128r 'Leseadresse übertragen
I2crbyte Read_eeprom , Nack 'Daten auslesen
I2cstop 'Stopkondition

End Function

'-------------------------------------------------------------------------------------------------------------------

Sub Write_eeprom(byval Data_eeprom As Byte , Byval Adress As Integer)
Local Data_lenght As Byte
Local Adress_high As Byte
Local Adress_low As Byte

Adress_high = High(adress) 'High Byte der Adresse speichern
Adress_low = Low(adress) 'Low Byte der Adresse speichern

I2cstart 'Startkondition
I2cwbyte 24lc128w 'Schreibadresse übertragen
I2cwbyte Adress_high 'High Byte der Adresse schreiben
I2cwbyte Adress_low 'Low Byte der Adresse schreiben
I2cwbyte Data_eeprom 'Daten schreiben
I2cstop 'Stopkondition
Waitms 10 '10ms warten um den Schreibvorgang abzuschließen

End Sub

'-------------------------------------------------------------------------------------------------------------------

'ISRs
'-------------------------------------------------------------------------------------------------------------------

'ISR von INT0
Mcp2515_int:

Statusflag = 1 'Interrupt ausgelöst

Return

'-------------------------------------------------------------------------------------------------------------------

'ISR vom UART
Uart_recieved:

Bytes_received = Bytes_received + 1
Input_string_overlay(bytes_received) = Udr


Return

'-------------------------------------------------------------------------------------------------------------------


Danke für die Hilfe!

Edit:
Ich habe es nun auf den MCP2515 vom RN-Control eingrenzen können.
Wenn ich den MCP abziehe, wieder anstecke und den Controller resete sodass der MCP neu initialisiert wird, kann ich wieder einen Remoteframe senden.
Aber das oben beschriebene Problem kehrt wieder sobald ich einen Datenframe gesendet habe.
Habe ich irgendwas in der Routine zum senden eines Remoteframes vergessen oder falsch gemacht?

Kampi
30.08.2012, 23:49
Ok das Problem hat sich geklärt. Die Lösung ist mir beim Stöbern des Datenblattes auf der Couch vorm Fernseher ins Gehirn geschossen ^.^
Ich habe das falsche Register beschrieben.
Und zwar habe ich habe folgendes geschrieben:

Bitmodify Txb0ctrl , &H08 , &H08

Aber dieses Bit "TxREQ" signalisiert nur, dass eine Remote Transmission Anfrage eingegangen ist.
Richtig ist allerdings das hier:

Write_register Txb0dlc , &H40

Und laut Datenblatt bestimmt Bit 6 im Datalenght Register was für ein Frame gesendet wird.
Eine 1 ist ein Remoteframe und eine 0 ein Datenframe :)
Nun klappt es problemlos.