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"
Code:
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:
Code:
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:
Code:
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:

Code:
'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

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