PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Funktionierendes CAN Bus Projekt entwickeln unter Bascom



Michael_avr
17.10.2006, 21:10
Hallo zusammen,
ich möchte gemeinsam mit mehreren (und Euch) enlich mal das Problem des CAN Busses unter Bascom lösen.
Ich habe mich zu der Version mit dem MCP 2115 Controller und einem Mega 8 entschieden. Der MCP 2515 ist ein CAN Bustreiber auf SPI Basis, somit kann man sinnvoll die Programmierports nutzen.

Ich weiß, diese Kombination gibt es schon in diesem Forum - und das auch noch funktionstätig - jedoch nur unter C!
ich habe viel im Netz gesucht und bin leider immer nur unter C fündig geworden und ein nicht vollendetes Bascomprogramm.

Ich denke das kann man auch unter Bascom lösen, vielleicht gemeinsam.

Ich habe mal in einem Forum einen Quelltext unter Bascom gefunden, der schafft auch irgendeine Kommunikation mit dem Chip, aber senden tut das Ding nix. Man muss nur zwischen den SPI Befehlen einen 21ms wait Befehl einfügen.



Zum Verständniss des Chips MCP 2515 und die Funktion um senden zu können:

1. Slave Select auf Masse und das Manuel
2. Register 1 anwählen und mit Daten beschreiben
3. Register 2 anwählen und mit Daten beschreiben
4. Register 3 anwählen und mit Daten beschreiben
5. Slave Select wieder manuell auf Potential

...... und die Kiste müsste senden.

Kann mir das jemand bestätigen? Mal abgesehen das vorher ein Reset und der Takt eingestellt werden müssen.

Besten Dank

avr57
17.10.2006, 22:54
Hi Michael_avr,

vielleicht hilft Dir dieses Buch?

Programmieren der AVR RISC Mikrocontroller mit BASCOM-AVR
von Claus Kühnel

2. Auflage - 2004

ISBN: 3-907857-04-6

Dort ist u. a. der CAN-Bus inkl Softwarebeispiel beschrieben - evtl. als Anregung.

CAN´sche Gruesse

Karl

_Alex
18.10.2006, 09:45
Hallo,

warum denn nicht ein AVR mit einbebauten CAN like 90CAN32?

An den werde ich mich bei gelegenheit machen, Atmel war so freundlich mir ein paar Muster zur Verfügung zu stellen ;-)

Gruß

Michael_avr
18.10.2006, 12:39
Danke für Eure Antworten.
Ich bin selber Besitzer des Bascom Buches- wie ich finde ein sehr gutes Buch, hier ist auch ein Programm für den Can Baustein von Atmel mit drin.
Danke an Karl, dich empfehle auch gerne jedem dieses Buch.

Jedoch möchte ich bei diesem Projekt nicht auf nur einen speziellen AVR angewiesen sein, der noch dazu mit 13,15€ sehr teuer ist. Weiterer Nachteil ist das TQFP Gehäuse mit 64 Pins.

Meine Testboards haben an Bauteilen ca. 10€ gekostet, inklusive der CAN Komponenten und einem Mega8. Dies Board kann noch weitere 8 Ein/ Ausgänge verwalten und hat eine Anschluss für ein LCD, wahlweise somit auch freie Ports.
Als modulares System denke ich ganz gut – Steuerplatine dran und schon sind Hausbuskomponenten für unter 20€ fertig!

Also MCP 2515 ist für eine vernünftige Kombination mit anderen Chips schon sehr sinnvoll!

Und wie gesagt eine Kommunikation steht mit dem oberen Programm.
Gruß

Vitis
30.05.2007, 12:38
hier mal ein Beispielcode von mir:




$regfile = "m16def.dat" ' ATMega16
$crystal = 14745600 ' Baudratenquarz
$hwstack = 40 ' default use 32 for the hardware stack
$swstack = 80 ' default use 10 for the SW stack
$framesize = 90

Declare Sub Can_init()
Declare Sub Mcp2515_write(byval Reg_add As Byte , Byval Reg_val As Byte)
Declare Sub Mcp2515_bitmodify(byval Reg_add As Byte , Byval Reg_mask As Byte , Byval Reg_val As Byte)
Declare Function Mcp2515_read(byval Reg_add As Byte) As Byte

Mcp2515cs Alias Portb.4
Config Mcp2515cs = Output

Const Cmd_read = &H03 ' Read Command
Const Cmd_write = &H02 ' Write Command
Const Cmd_bitmodify = &H05 ' Bit-modify Command
Const Cmd_readstatus = &HA0 ' Read Status Command (poll)
Const Cmd_read_rx_status = &HB0
Const Cmd_reset = &HC0 ' Reset Command
Const Cmd_rts0 = &H81
Const Cmd_rts1 = &H82


Const Caninte = &H2B
Const Canctrl = &H0F
Const Canstat = &H0E ' Statusregister
Const Eflg = &H2D ' Error Flag Register
Const Cnf3 = &H28 ' Configuration Register 3
Const Cnf2 = &H29 ' Configuration Register 2
Const Cnf1 = &H2A ' Configuration Register 1
Const Txb0ctrl = &B00110000 ' Transmit Buffer 0 Control Register
Const Txb0sidh = &B00110001 ' Transmit Buffer 0 Std Identifier High
Const Txb0sidl = &B00110010 ' Transmit Buffer 0 Std Identifier Low
Const Txb0eid8 = &B00110011 ' Transmit Buffer 0 Ext Identifier High
Const Txb0eid0 = &B00110100 ' Transmit Buffer 0 Ext Identifier Low
Const Txb0dlc = &B00110101 ' Transmit Buffer 0 Data Length Code
Const Txb0d0 = &B00110110 ' Transmit Buffer 0 Data Byte 0
Const Txb0d1 = &B00110111 ' Transmit Buffer 0 Data Byte 1
Const Txb0d2 = &B00111000 ' Transmit Buffer 0 Data Byte 2
Const Txb0d3 = &B00111001 ' Transmit Buffer 0 Data Byte 3
Const Txb0d4 = &B00111010 ' Transmit Buffer 0 Data Byte 4
Const Txb0d5 = &B00111011 ' Transmit Buffer 0 Data Byte 5
Const Txb0d6 = &B00111100 ' Transmit Buffer 0 Data Byte 6
Const Txb0d7 = &B00111101 ' Transmit Buffer 0 Data Byte 7
Const Rxm0sidh = &B00100000 ' Receive Buffer 0 Std Identifier High
Const Rxm0sidl = &B00100001 ' Receive Buffer 0 Std Identifier Low
Const Rxm0eid8 = &B00100010 ' Receive Buffer 0 Ext Identifier High
Const Rxm0eid0 = &B00100011 ' Receive Buffer 0 Ext Identifier low
Const Rxm1sidh = &B00100100 ' Receive Buffer 1 Std Identifier High
Const Rxm1sidl = &B00100101 ' Receive Buffer 1 Std Identifier Low
Const Rxm1eid8 = &B00100110 ' Receive Buffer 1 Ext Identifier High
Const Rxm1eid0 = &B00100111 ' Receive Buffer 1 Ext Identifier low

Const Rxb0ctrl = &H60
Const Rxb1ctrl = &H70


' Hardware SPI-Schnittstelle konfigurieren
Config Portb.6 = Input
Config Portb.5 = Output
Config Portb.7 = Output
Spcr = &B01010010

Config Pind.2 = Input
Config Int0 = Falling
On Int0 Int_canint
Enable Int0
Enable Interrupts

Call Can_init()

Do
' Zu übertragende Daten setzen:
Mcp2515_bitmodify Txb0ctrl , &B00000011 , &B00000011 ' TX-Konfiguration
Mcp2515_write Txb0sidh , &B01010101 ' Empfängeradresse setzen
Mcp2515_write Txb0sidl , &B01010101 ' Empfängeradresse setzen
Mcp2515_write Txb0dlc , &H04 ' Paketlänge festlegen
Mcp2515_write Txb0d0 , &B01010101 ' Zu übertragende Daten setzen
Mcp2515_write Txb0d1 , &B01010101 ' Zu übertragende Daten setzen

' Übertragung auslösen
Reset Mcp2515cs
Waitus 10
Spdr = Cmd_rts0
Do
Loop Until Spsr.spif = 1
Waitus 10
Set Mcp2515cs

Loop

Sub Can_init()
Local Can_tmp As Byte

Reset Mcp2515cs

' Reset MCP2515
Can_tmp = Cmd_reset
Spdr = Can_tmp
Do
Loop Until Spsr.spif = 1
Set Mcp2515cs

Waitms 2000
Mcp2515_write Canctrl , &B10001000 ' low nibble: 3=OSM 2=CLK-Pin 1-0=CLK Divider
Print "speed change done"

' F MCP2515 = 16MHz
Can_tmp = Eram_param_baudrate
Select Case Can_tmp
Case 0:
' CAN 31,25 KHz
Mcp2515_write Cnf1 , &B00001111
Case 1:
' CAN 62,5 KHz
Mcp2515_write Cnf1 , &B00000111
Case 2:
' CAN 125 KHz
Mcp2515_write Cnf1 , &B00000011
Case 3:
' CAN 250 KHz
Mcp2515_write Cnf1 , &B00000001
Case 4:
' CAN 500 KHz
Mcp2515_write Cnf1 , &B00000000
Case Else :
Mcp2515_write Cnf1 , &B00001111
End Select
Mcp2515_write Cnf2 , &B10010000 ' Cnf2 = &H29
Mcp2515_write Cnf3 , &B00000010 ' Cnf3 = &H28
Mcp2515_write Caninte , &B00000011
Mcp2515_write Rxb0ctrl , &B01100000
Mcp2515_write Rxb1ctrl , &B01100000
Mcp2515_write Rxm0sidh , 0 ' Empfängeradressen auf 0, Filter aus
Mcp2515_write Rxm0sidl , 0
Mcp2515_write Rxm0eid8 , 0
Mcp2515_write Rxm0eid0 , 0
Mcp2515_write Rxm1sidh , 0
Mcp2515_write Rxm1sidl , 0
Mcp2515_write Rxm1eid8 , 0
Mcp2515_write Rxm1eid0 , 0
Mcp2515_bitmodify Canctrl , &B11100000 , &B00000000
'Mcp2515_write Canctrl , &B00000000 ' low nibble: 3=OSM 2=CLK-Pin 1-0=CLK Divider
'Mcp2515_write Canctrl , &HE0
End Sub

Sub Mcp2515_bitmodify(reg_add , Reg_mask , Reg_val)
Local Can_tmp2 As Byte
Mcp2515cs = 0
Can_tmp2 = Cmd_bitmodify
Spdr = Can_tmp2
Do
Loop Until Spsr.spif = 1
Waitms 2
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
Mcp2515cs = 1
End Sub

Sub Mcp2515_write(reg_add , Reg_val)
Local Can_tmp2 As Byte
Mcp2515cs = 0
Can_tmp2 = Cmd_write
Spdr = Can_tmp2
Do
Loop Until Spsr.spif = 1
Waitms 2
Spdr = Reg_add
Do
Loop Until Spsr.spif = 1
Spdr = Reg_val
Do
Loop Until Spsr.spif = 1
Mcp2515cs = 1
End Sub


Function Mcp2515_read(reg_add)
Local Can_tmp2 As Byte
Mcp2515cs = 0
Can_tmp2 = Cmd_read
Spdr = Can_tmp2
Do
Loop Until Spsr.spif = 1
Spdr = Reg_add
Do
Loop Until Spsr.spif = 1
Spdr = 0
Do
Loop Until Spsr.spif = 1
Mcp2515_read = Spdr
Mcp2515cs = 1
End Function

Stromi
30.05.2007, 14:12
Hallo Vitis,

wo hast du die Variable "Eram_param_baudrate" her?
Hast du so'ne Art Haus-Automation damit programmiert?
MfG
Stromi

Vitis
30.05.2007, 22:46
Der Code ist nur n Schnipsel von nem ziemlich großen Projekt.
Sie wird von Randbedingungen festgelegt und dient zur Festlegung
der Baudrate, die in meinem Projekt halt variabel ist, daher die
select-case.

elkokiller
25.09.2007, 07:40
Hallo zusammen,

ich möchte mal auf den Grundgedanken von Michael_avr zurück kommen.
Ein gewöhlicher AVR Chip mit MCP 2515 auf der einen und ein paar Ein- und Ausgängen auf der anderen Seite sowie ggf ein LCD Display.
Das alles für einen verträglichen Preis mit dem auch ein Hobbyelektroniker ein paar Chrashs wegstecken kann.

Ich sitze jetzt schon eine lange Zeit an diesem Thema und gebe immer wieder vor Verzweiflung auf. Ich denke nach den unzähligen Forenbeiträgen über dieses Thema, dass es bisher keinem gelungen ist, ein solches Projekt in Bascom in die Praxis umzusetzen.

Fangen wir doch einmal einfach an.
Über den CAN Bus soll eine LED mit einem Taster ein und aus geschaltet werden. Wie kann man das machen?
Wie sieht die Hardware und die Software aus?

Es wäre schön wenn sich an dieser Stelle viele beteiligen würden, so dass wir in kleinen Schritten zu einem Ergebnis kommen können.

Tobias

nikolaus10
25.09.2007, 08:21
Hallo

Ist auch daran gedacht/erweitert werden den CAN Bus im Automobil abzufragen? Also sowohl das OBD, der CANbus als auch die Programmierung etwas transparenter zu machen ?

MFG

Vitis
25.09.2007, 13:33
Ob Du in Bascom oder C oder ASM oder sonstwas programmierst ist im
Prinzip Wurst. Ich hab mit meinem Projekt die Übertragung von
Daten soweit geregelt bekommen, war gar nicht so knifflig.
Poste doch einfach Dein Problemkind, evtl. fällt mir ja was dazu ein.

Ne LED per CAN und MCP schalten ist im Prionzip kein
Thema, Du musst nur den MCP passend konfigurieren und wenn Du
das dann hinbekommen hast ists egal ob Du ne LED schaltest oder
Gigabyte an Daten überträgst, das Prinzip ist das Gleiche.

Ach so, ich empfehle auch den Einsatz eines PCA82C250 als Buskoppler

elkokiller
25.09.2007, 13:40
Hallo Vitis,

du bist offenbar ganz schön Fit was die Programmierung in Bascom und dem CAN-Bus angeht.
Könntest du nichtmal eine Schaltung aus AVR, einem CAN Chip und einem Beispiel Code ins Forum einstelle?
Ich denke du würdest damit einigen eine große Freude bereiten!

Tobias

Skragan
26.09.2007, 13:57
Da ich gerade eine ähnliche Anforderung habe, würde ich mich auch sehr darüber freuen !

Grüße !

elkokiller
27.09.2007, 07:40
Hallo,

ich habe vor einiger Zeit eine Schaltung gefunden mit der ein Atmega8 am Can Bus zu betreiben ist. Leider war dort keine Bascom sondern nur C-Software vorhanden. http://www.kreatives-chaos.com/artikel/can-testboard

Kann jemand sagen ob der hier beschriebene Schaltungsaufbau auch mit Bascom funktioniert?

Kjion
27.09.2007, 11:49
Hi,

klar tut er das, wie Vitis schon sagte: warum sollte eine Schaltung mit einem Compiler funktionieren, mit einem anderen aber nicht (mal von extrem Timing-kritischen Sachen abgesehen)?

Direkt mit einem Bascom Beispiel kann ich nicht dienen, dafür kenne ich den Compiler zu wenig, ich könnte höchstens anbieten eventuellen Code zu testen bzw. mal zu schauen ob mir logische Fehler auffallen. Den MCP2515 kenne ich mittlerweile fast auswendig ;-)

Grüße
Fabian (der die Schaltung erstellt hat :-b)

nikolaus10
27.09.2007, 12:30
Hallo Fabian

Dann schreibe doch mal ein kleines Tutorial im WIKI.
Unser Dank wird dir ewig hinterherhinken. :-)

MFG

Vitis
28.09.2007, 01:01
klar könnte man n wiki schreiben, ich find das aber nicht so den Brüller für n Forum. Ich persönlich bevorzuge die Methode: Hilfe zur Selbsthilfe. Die Copy & Paste-Variante find ich nicht so doll. Es geht doch auch ums Lernen und Verstehen, oder?

elkokiller
28.09.2007, 04:10
Hi Vitis,

bin grundsätzlich deiner Meinung. Für meinen teil muss ich allerdings sagen dass ich entweder zu doof bin oder das Thema zu komplex ist.
Offensichtlich geht es sehr vielen so da es eigentlich noch gar keinen Bascom Code gibt der nur sich nur annähernd damit beschäftigt! Ich weis wovon ich rede da ich schon mind. 2 Jahre auf der Suche bin.

Eine Einstig wärde daher sicher angebracht. Fabian hat einen sehr guten Beitrag auf seiner Seite geleistet. Allerdings nur in C.
Wenn es in Bascom tatsächlich möglich ist, ist jetzt die beste Möglichkeit es nach zu machen!

Tobias

Skragan
28.09.2007, 08:00
Ich sehe es wie Tobias: Grundsätzlich stimmt das, aber wenn man ständig gefrustet aufgeben muss, weil man bestimmte Kniffe nicht vorher gezeigt bekommt, resigniert man eben. Eine kleine Vorlage, auf die man dan aufbauen und an der man lernen kann, macht sicher Sinn. In der Grundschule wird einem zuerst auch gezeigt, wie man addiert bevor man es selber muss...

Vitis
29.09.2007, 01:11
Also ich versteh nicht ganz wo Ihr die Probleme seht.
In einem vorangegangenen Posting hab ich doch die Grundzüger der
Kommunikation mit dem MCP geschrieben.
Senderoutine, Konfiguration etc. Gut, die Empfangsroutine fehlt,
aber die ist dann auch nicht mehr schwer daraus abzuleiten.
Dann hackt Ihr noch Euer Programm drumherum und fertig ist die
Laube.
Zu der Geschichte Grundschule ... es macht auch andersrum wenig
Sinn sich mit Differentialrechnung zu beschäftigen, wenn die
Grundrechenarten nicht sitzen O:)

elkokiller
29.09.2007, 09:14
o.k.
ich mache noch einmal einen versuch mit deinem Programm zurecht zu kommen.
Könntest du aber bitte auch noch einmal das Empfangen beschreiben!

Wenns funktioniert werde ich es hier für alle veröffentlichen so dass damit eines der letzten großen Rätsel gelöst ist ;-)

elkokiller
29.09.2007, 11:21
Hallo Vitis,

ich habe jetzt eine Schaltung, analog zu der des CanTestBoard aufgebaut.
Die dort genutzten Pins musste ich etwas anpassen.

Den Code habe ich wie folgt angepasst:

$regfile = "m8def.dat" ' ATMega8
$crystal = 7372800 ' Baudratenquarz der AVR (MCP2515 mit 16MHz)
$hwstack = 40 ' default use 32 for the hardware stack
$swstack = 80 ' default use 10 for the SW stack
$framesize = 90

Declare Sub Can_init()
Declare Sub Mcp2515_write(byval Reg_add As Byte , Byval Reg_val As Byte)
Declare Sub Mcp2515_bitmodify(byval Reg_add As Byte , Byval Reg_mask As Byte , Byval Reg_val As Byte)
Declare Function Mcp2515_read(byval Reg_add As Byte) As Byte

Mcp2515cs Alias Portb.4 'MISO
Config Mcp2515cs = Output

Const Cmd_read = &H03 ' Read Command
Const Cmd_write = &H02 ' Write Command
Const Cmd_bitmodify = &H05 ' Bit-modify Command
Const Cmd_readstatus = &HA0 ' Read Status Command (poll)
Const Cmd_read_rx_status = &HB0
Const Cmd_reset = &HC0 ' Reset Command
Const Cmd_rts0 = &H81
Const Cmd_rts1 = &H82


Const Caninte = &H2B
Const Canctrl = &H0F
Const Canstat = &H0E ' Statusregister
Const Eflg = &H2D ' Error Flag Register
Const Cnf3 = &H28 ' Configuration Register 3
Const Cnf2 = &H29 ' Configuration Register 2
Const Cnf1 = &H2A ' Configuration Register 1
Const Txb0ctrl = &B00110000 ' Transmit Buffer 0 Control Register
Const Txb0sidh = &B00110001 ' Transmit Buffer 0 Std Identifier High
Const Txb0sidl = &B00110010 ' Transmit Buffer 0 Std Identifier Low
Const Txb0eid8 = &B00110011 ' Transmit Buffer 0 Ext Identifier High
Const Txb0eid0 = &B00110100 ' Transmit Buffer 0 Ext Identifier Low
Const Txb0dlc = &B00110101 ' Transmit Buffer 0 Data Length Code
Const Txb0d0 = &B00110110 ' Transmit Buffer 0 Data Byte 0
Const Txb0d1 = &B00110111 ' Transmit Buffer 0 Data Byte 1
Const Txb0d2 = &B00111000 ' Transmit Buffer 0 Data Byte 2
Const Txb0d3 = &B00111001 ' Transmit Buffer 0 Data Byte 3
Const Txb0d4 = &B00111010 ' Transmit Buffer 0 Data Byte 4
Const Txb0d5 = &B00111011 ' Transmit Buffer 0 Data Byte 5
Const Txb0d6 = &B00111100 ' Transmit Buffer 0 Data Byte 6
Const Txb0d7 = &B00111101 ' Transmit Buffer 0 Data Byte 7
Const Rxm0sidh = &B00100000 ' Receive Buffer 0 Std Identifier High
Const Rxm0sidl = &B00100001 ' Receive Buffer 0 Std Identifier Low
Const Rxm0eid8 = &B00100010 ' Receive Buffer 0 Ext Identifier High
Const Rxm0eid0 = &B00100011 ' Receive Buffer 0 Ext Identifier low
Const Rxm1sidh = &B00100100 ' Receive Buffer 1 Std Identifier High
Const Rxm1sidl = &B00100101 ' Receive Buffer 1 Std Identifier Low
Const Rxm1eid8 = &B00100110 ' Receive Buffer 1 Ext Identifier High
Const Rxm1eid0 = &B00100111 ' Receive Buffer 1 Ext Identifier low

Const Rxb0ctrl = &H60
Const Rxb1ctrl = &H70


' Hardware SPI-Schnittstelle konfigurieren
'Config Portb.6 = Input 'Vitis
'Config Portb.5 = Output 'Vitis
'Config Portb.7 = Output 'Vitis

Config Portb.4 = Input
Config Portb.3 = Output
Config Portb.5 = Output
Spcr = &B01010010

'Config Pind.2 = Input 'Vitis
Config Pind.3 = Input
Config Int0 = Falling
On Int0 Int_canint
Enable Int0
Enable Interrupts

Call Can_init()

Do
' Zu übertragende Daten setzen:
Mcp2515_bitmodify Txb0ctrl , &B00000011 , &B00000011 ' TX-Konfiguration
Mcp2515_write Txb0sidh , &B01010101 ' Empfängeradresse setzen
Mcp2515_write Txb0sidl , &B01010101 ' Empfängeradresse setzen
Mcp2515_write Txb0dlc , &H04 ' Paketlänge festlegen
Mcp2515_write Txb0d0 , &B01010101 ' Zu übertragende Daten setzen
Mcp2515_write Txb0d1 , &B01010101 ' Zu übertragende Daten setzen

' Übertragung auslösen
Reset Mcp2515cs
Waitus 10
Spdr = Cmd_rts0
Do
Loop Until Spsr.spif = 1
Waitus 10
Set Mcp2515cs

Loop

Sub Can_init()
Local Can_tmp As Byte

Reset Mcp2515cs

' Reset MCP2515
Can_tmp = Cmd_reset
Spdr = Can_tmp
Do
Loop Until Spsr.spif = 1
Set Mcp2515cs

Waitms 2000
Mcp2515_write Canctrl , &B10001000 ' low nibble: 3=OSM 2=CLK-Pin 1-0=CLK Divider
Print "speed change done"

' F MCP2515 = 16MHz
Can_tmp = Eram_param_baudrate
Select Case Can_tmp
Case 0:
' CAN 31,25 KHz
Mcp2515_write Cnf1 , &B00001111
Case 1:
' CAN 62,5 KHz
Mcp2515_write Cnf1 , &B00000111
Case 2:
' CAN 125 KHz
Mcp2515_write Cnf1 , &B00000011
Case 3:
' CAN 250 KHz
Mcp2515_write Cnf1 , &B00000001
Case 4:
' CAN 500 KHz
Mcp2515_write Cnf1 , &B00000000
Case Else :
Mcp2515_write Cnf1 , &B00001111
End Select
Mcp2515_write Cnf2 , &B10010000 ' Cnf2 = &H29
Mcp2515_write Cnf3 , &B00000010 ' Cnf3 = &H28
Mcp2515_write Caninte , &B00000011
Mcp2515_write Rxb0ctrl , &B01100000
Mcp2515_write Rxb1ctrl , &B01100000
Mcp2515_write Rxm0sidh , 0 ' Empfängeradressen auf 0, Filter aus
Mcp2515_write Rxm0sidl , 0
Mcp2515_write Rxm0eid8 , 0
Mcp2515_write Rxm0eid0 , 0
Mcp2515_write Rxm1sidh , 0
Mcp2515_write Rxm1sidl , 0
Mcp2515_write Rxm1eid8 , 0
Mcp2515_write Rxm1eid0 , 0
Mcp2515_bitmodify Canctrl , &B11100000 , &B00000000
'Mcp2515_write Canctrl , &B00000000 ' low nibble: 3=OSM 2=CLK-Pin 1-0=CLK Divider
'Mcp2515_write Canctrl , &HE0
End Sub

Sub Mcp2515_bitmodify(reg_add , Reg_mask , Reg_val)
Local Can_tmp2 As Byte
Mcp2515cs = 0
Can_tmp2 = Cmd_bitmodify
Spdr = Can_tmp2
Do
Loop Until Spsr.spif = 1
Waitms 2
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
Mcp2515cs = 1
End Sub

Sub Mcp2515_write(reg_add , Reg_val)
Local Can_tmp2 As Byte
Mcp2515cs = 0
Can_tmp2 = Cmd_write
Spdr = Can_tmp2
Do
Loop Until Spsr.spif = 1
Waitms 2
Spdr = Reg_add
Do
Loop Until Spsr.spif = 1
Spdr = Reg_val
Do
Loop Until Spsr.spif = 1
Mcp2515cs = 1
End Sub


Function Mcp2515_read(reg_add)
Local Can_tmp2 As Byte
Mcp2515cs = 0
Can_tmp2 = Cmd_read
Spdr = Can_tmp2
Do
Loop Until Spsr.spif = 1
Spdr = Reg_add
Do
Loop Until Spsr.spif = 1
Spdr = 0
Do
Loop Until Spsr.spif = 1
Mcp2515_read = Spdr
Mcp2515cs = 1
End Function

Und jetzt gleich ein paar Fragen:
1. Die Adressierung der einzelnen Knoten spielt eine wichtige Rolle.
Wo ist die Adresse dieses Konoten festgelegt?
2. Verstehe ich es richtig dass der Empfängerknoten unter &B01010101 zu erreichen ist
3. Woraus leitest du die Peketlänge "&H04" ab?


Tobias

Michael_avr
01.10.2007, 20:46
Na ich freue mich, dass hier ein wenig schwung wieder rein gekommen ist.

Ich kann mich nur oben anschließen; Ich habe ca. 2Jahre versucht mir selber c beizubringen und wurde leider nur von Francis Büchern unterstützt.

Ich habe aufgegeben und Bascom entdeckt - ich war nach zwei Tagen soweit LCD Displays einwandfrei zu programmieren.....
Jedoch glaube ich in Bezug auf MCP das ich die Grundrechenarten NICHT verstanden habe. Das Mistding kommuniziert einfach nicht mit mir!

Zum übersetzen von C ins viel leichtere Bascom reichts bei mir leider auch nicht....

Ich habe aber mal etwas gelernt und mich mit dem I2C Bus beschäftigt, vielleicht kann ich ja ein wenig Wissen transferieren....
Habe zumindest den I2C zu laufen bekommen (externe Uhr und Porterweiterung als zusätzliche Ausgänge!)

Werde mich nochmals an den MCP machen

Grüße und witer forschen, irgendwann kriegen wir das hin!

Michael

Vitis
02.10.2007, 02:24
Die Adresse des Senderknotens ist die ID, im vorliegenden Codeschnipsel hier 0. Ist aber unerheblich, weil der Absender nicht mit übertragen wird im CAN-Bus-Frame.

Als Empfänger ist richtig der &B01010101 &B01010101 genannt. Die Zeichenfolge verwend ich gern, weil sie im Oszi schön angesehen werden kann und so das Bittiming für die Übertragungsrate schön nachgemesen werden kann.

Die Paketlänge ist falsch, sollte hier 2 sein weil zwei Bytes gesendet werden, das hast du richtig erkannt. Die übrigen 2 Bytes wurden in meinem Beispiel einfach als 0 gesendet, da kein weiteres Byte geschrieben wurde

Skragan
02.10.2007, 08:17
@Vitis: Na klar, die Grundrechenarten lerne ich ja auch immernoch. Ist halt alles nicht so einfach, aber ich muss schnell mit meinen Aufgaben wachsen. :)

Stromi
03.10.2007, 16:54
Teste das mal, vorher noch die Standartwerte für den Prozessor einsetzen
Kommt aus dem Bascom-Forum

$sim
Config Spi = Soft , Din = Pinb.2 , Dout = Portb.1 , Ss = None , Clock = Portb.0
Dim C1 As Byte
Dim A(3) As Byte
Declare Sub Spi_write(byval Reg_add As Byte , Byval Reg_val As Byte)



Const Cmd_read = &H03 ' Read Command
Const Cmd_write = &H02 ' Write Command
Const Cmd_bitmodify = &H05 ' Bit-modify Command
Const Cmd_readstatus = &HA0 ' Read Status Command (poll)
Const Cmd_reset = &HC0 ' Reset Command
Const Canctrl = &H0F

Const Cnf3 = &H28 ' Configuration Register 3
Const Cnf2 = &H29 ' Configuration Register 2
Const Cnf1 = &H2A ' Configuration Register 1

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


Const Rts0 = &H81

Print "Welcome!"

Config Pinb.3 = Output
Config Pinb.4 = Output
Csn Alias Portb.3
Can_reset Alias Portb.4



Spiinit
Can_reset = 1

Print "Reset Done!"


'RESET
Csn = 0
A(1) = Cmd_reset
Spiout A(1) , 1
Csn = 1

Wait 2


'Controls
Spi_write Canctrl , &B00000100
Print "speed change done"

Spi_write Cnf1 , &H07 '03
Spi_write Cnf2 , &H90 '90
Spi_write Cnf3 , &H02 '02



'Do

'Spi_write Txb0d0 , 55 'send motor speed

'Csn = 0
'A(1) = &B10000001
'Spiout A(1) , 1
'Csn = 1

Wait 1
Print "here we go"


Wait 1

Print "senden"


Spi_write Txb0sidh , &HFF
Spi_write Txb0sidl , &H00
Spi_write Txb0dlc , &H3


Csn = 0
A(1) = Rts0
Spiout A(1) , 1
Csn = 1


' Loop



End


Sub Spi_write(byval Reg_add As Byte , Byval Reg_val As Byte)

Print "Reg: " ; Reg_add ; " Val: " ; Reg_val

A(1) = Cmd_write
A(2) = Reg_add
A(3) = Reg_val
Csn = 0
Spiout A(1) , 3
Csn = 1

End Sub

Duesentrieb
03.10.2007, 17:47
Hey Super,
so langsam kommt ja wirklich was zusammen. Vielleicht bekomme ich meinen Can-Bus so jetzt doch noch zum laufen.

Stromi: Passt dein Programm jetzt zu dem Schaltplan den Elkokiller eingestellt hat.
Ich vermisse bei die die Tasterabfrage.
Wenn ich dein Programm richtig verstehe, dann überträgst du doch einfach nur ein telegram über den Bus?!

Daniel

Stromi
03.10.2007, 18:40
Hallo Daniel,
ist nicht von mir. Schaltplan kannst du ja mal vergleichen Das kreative Chaos hat ihn ja online. Hatte es mal aufgebaut, hab' es auch nicht mehr, weil "GEFRUSTET" demontiert :-)
Aber im Simulator geht es.
Gibt ja auch einige schlaue Leute hier, ev. schauen die sich das an.

Hoffentlich keine Erinnerungen an einen Mathelehrer, der pflegte immer zu sagen:
Wenn ihr was nicht verstanden habt, fragt mich.
Wenn man ihn dann gefragt hatte sagte er:
SOLL ICH EUCH DAS EIN MAL EINS ERKLÄREN?
spart "Erklärzeit" und man bleibt immer der Schlaue!

Vitis
03.10.2007, 23:51
Man kann die Software-SPI verwenden, geht fast genauso gut wie die Hardware, aber halt nur fast. Sie hat den Nachteil, dass sie deutlich langsamer ist und die Codegröße in die Höhe schnellt. Der AVR hat ne Hardware-SPI und die würde ich auch raten zu verwenden, wenn die Datenübertragung auch hurtig vonstatten gehen soll ;)

@Michael_avr
Wenns mit C nicht klappt und mit Bascom schon, dann verlässt Du dich scheinbar voll auf die Bascominternen Funktionen. Das ist so auch ganz ok, knifflig wirds bei Peripheriebausteinen, die nicht den Bascomfunktionen entsprechen. LCDs sind da n schönes Beispiel. Dann stehst Du nämlich genau da wo du mit C hingekommen bist. Wichtig bei der Programmierung egal welcher Sprache oder Syntax ist das Verstehen der zugrundeliegenden Logik. Sitzt die einmal ist der Rest drum herum nur Fassade. Ob die Sytax dann
if x=y then
endif

oder

if (x==y) {
}

ist ist Dir dann sowas von egal. Im Grunde unterscheiden sich die Programmiersprachen nur in ihrer Syntax und was halt der Interpreter oder Compiler daraus wurstelt. Obs dann C, C++, Bascom, Java, VBasic oder PHP ist macht Dir dann echt keinen Kummer mehr.
Mit C hättest Du halt den deutlichen Vorteil auch auf anderen Bausteinen wie ARM oder AVR32 zu werkeln. Für die Bascom-Fraktion wirds dann schon eng.

@nikolaus10
Ich für meinen Teil lass liber die Finger weg vom KFz-Bus, das kann (!) mächtig ins Auge gehen. Hab schon genug Blech verbogen und auch verbogen bekommen, mein Bedarf daran ist gedeckt.

Zum geposteten Code, also ich kann da auf den ersten Blick nix verkehrtes dran finden ... achso, doch evtl. Du setzt:

Spi_write Canctrl , &B00000100 also CLK-Pin aktiv, ok. Aber den REQUOP2 lässt Du 0. Das ist Bit 7, und ist zuständig dafür das der MCP in den Configuration-Mode geht und nur dann ist CNF1 - CNF3, Filter und Maskenregister änderbar.
Spi_write Cnf1 , &H07 '03
Spi_write Cnf2 , &H90 '90
Spi_write Cnf3 , &H02 '02
geht dann nicht. (Datenblatt Seite 55-56)

Stromi
04.10.2007, 13:16
Na, das ist ja schonmal ein Prima Hinweis.
Vielleicht hole ich ja doch nochmal die Bauteile und baue das CAN-Teil wieder auf. Damit aus den "Nicht-CAN" ein "CAN-Do" wird. :-)
Danke Vitis

Skragan
04.10.2007, 13:18
Ich habe auch gerade nochmal neue Teile bestellt und werde sofort nächste Woche loslegen.

Alex20q90
05.10.2007, 18:13
Hallo,

ich hab mich auch ein wenig mit CAN-Bus befasst und dem MCP. Jetzt mal ne doofe Frage :

Wie mach ich es das ich zwei CAN-Bus-Controller (als Übersetzter) an einen AVR häng?

Es geht darum :

Ich hab ein Bordcomputer welcher an den CAN-Bus gehängt werden kann um Daten wie Drehzahl etc abzufragen. Da aber im BUS keine Aussentemperatur mitübertragen wird (aber der Bordcomputer sie anzeigen kann) wollte ich ein Zwischenmodul basteln welches einen A-Tempsensor abfrägt und und in den CAN-Bus (richtung BC) einschleift.

Wie müsste ich soetwas anstellen?

Grüße
Alex

Stromi
05.10.2007, 18:51
@Alex
hast du diesen Bordcomputer in Bascom programmiert?
Gehe mal davon aus, sonst würdest du ja nicht im Bascom-Forum landen, kannst du den Code mal hier reinstellen?

Alex20q90
05.10.2007, 23:26
Hi Stromi,

nein hab ich nicht. Ich hab den von nem Bekannten. Sonst würde ich den Code so anpassen das ein TempSensor abgefragt werden kann.
Den Adapter würde ich aber gerne in Bascom schreiben.

Duesentrieb
06.10.2007, 06:18
Hallo,

ich habe mal ein paar grundsätzliche Frage zum Anschluss des MCP2515!
Wenn ich über den ISP auf den CAN zugreife und damit eine eigene Beschaltung vornehme, wie kann ich diesen dann in Zukunft zum Programmieren nehmen?
Der AVR wertet doch ständig die Informationen des Busses aus. Dadurch kann es doch zu erheblichen Verzögerungen im Programm kommen!?
Ist es richtig dass der Atmega 8 über einen Interrupt vom MCP2515 angesprochen wird?

Ich bin echt froh dass wir diesmal offensichtlich eine funktionierende Schaltung hinbekommen!
Daniel =D>

Vitis
08.10.2007, 08:11
@Duesentrieb:
Der ISP ist ja nur in Funktion wenn der Reset low gezogen wird (vom Programmierdongle). Ansonsten ist der AVR im normalen Arbeitsmodus und dann ist die ISP ne SPI-Schnittstelle. kommt sich also nicht direkt ins Gehege ... mal abgesehen vom Verify. Da kommts dann tatsächlich zu Differenzen beim Flashen. Nicht darüber wundern, einfach ignorieren :)

@Alex20q90
Mehr als einen MCP? ... naja, Du kannst natürlich x MCP anhängen, indem Du diese über Software-SPI benutzt. Dann kannst Du soviele anhängen wie Du Port-Pins zur Verfügung hast. Bascom unterstützt zwar meines Wissens nach nur eine Software SPI, aber die kannst Du recht einfach zu Fuß über Bitschupserei und Pingewackel emulieren.

Duesentrieb
14.10.2007, 07:15
Danke Vitis! D.h. der CAN-Controller wertet das Protokoll aus und gibt bei Bedarf einen Interrupt an den AVR.
Welche Empfängeradresse muss ich setzen um alle Nachrichten des Busses an den AVR weitergeleitet zu bekommen?
Damit würde ich doch dann testen können ob und was über den Bus geht (ein Oszi habe ich leider noch nicht)

Übrigens, programmieren kann ich nach der Schaltung, die hier auf der ersten Seite vorgestellt wurde, nur noch wenn ich den CAN Controller rausziehe!

Vitis
14.10.2007, 07:23
Ja, habs schon gesehen, der Reset in der Schaltung geht auf den Reset vom ISP. Ist nicht gut. Den Reset vom MCP würd ich entweder per Pullup fest
legen oder auf nem Pin vom AVR, aber auch da nen Pullup mit dran.
Alle Nachrichten bekommst du mit ID 0 (sprich Null)

EDIT: Für solche Geschichten rate ich dringend zur Anschaffung eines Oszilloskopes !!! Das erspart zig Stunden Debuggen.
N Speicheroszi währ optimal, aber auch mit nem analogen kann man
schon sehr viel sehen. Beispielsweise ob der Oszillator schwingt, oder
auf dem CLK-Pin was kommt etc.

elkokiller
17.10.2007, 21:08
Hallo zusammen,

ich habe mich zwischenzeitlich mal an die Hardware gemacht und das hier beschriebene CAN-MEGA8 Modul nach dem Entwurf aus "kreatives-chaos.com" nachgebaut.
Nach regem Kontakt mit Vitis habe ich das folgende Programm in so weit angepasst dass es zumindes möglich sein sollte, eine Nachricht (welcher Taster gedückt wurde) über den CAN Bus zu senden.


'Testprogramm CAN Sender und Empfänger

$regfile = "m8def.dat" ' ATMega8
$crystal = 7372800 ' Baudratenquarz der AVR (MCP2515 mit 16MHz)
$hwstack = 40 ' default use 32 for the hardware stack
$swstack = 80 ' default use 10 for the SW stack
$framesize = 90
$baud = 9600

' Allgemeine Config ************************************************** **********

Const Keys = 5 '5 angeschlossene Taster

Config Pinc.0 = Input 'Eingang 1 bis 5
Config Pinc.1 = Input
Config Pinc.2 = Input
Config Pinc.3 = Input
Config Pinc.4 = Input
Config Pinc.5 = Input

Config Portb.0 = Output 'Relaisausgang 1 bis 5
Config Portb.1 = Output
Config Portb.2 = Output
Config Portd.7 = Output
Config Portd.6 = Output


Dim I As Byte
Dim Key As Byte

Dim T1 As Bit 'Variable für Tasterzustand
Dim T2 As Bit
Dim T3 As Bit
Dim T4 As Bit
Dim T5 As Bit

Dim Taster As Byte

Portb.0 = 0 'Grunsstellung fixieren
Portb.1 = 0
Portb.2 = 0
Portd.7 = 0
Portd.6 = 0


'CAN relevante Config ************************************************** ********


Declare Sub Mcp2515_write(byval Reg_add As Byte , Byval Reg_val As Byte)
Declare Sub Mcp2515_bitmodify(byval Reg_add As Byte , Byval Reg_mask As Byte , Byval Reg_val As Byte)
Declare Function Mcp2515_read(byval Reg_add As Byte) As Byte

Mcp2515cs Alias Portd.4 'CS am 2515
Config Mcp2515cs = Output

Const Cmd_read = &H03 ' Read Command
Const Cmd_write = &H02 ' Write Command
Const Cmd_bitmodify = &H05 ' Bit-modify Command
Const Cmd_readstatus = &HA0 ' Read Status Command (poll)
Const Cmd_read_rx_status = &HB0
Const Cmd_reset = &HC0 ' Reset Command
Const Cmd_rts0 = &H81
Const Cmd_rts1 = &H82
Const Caninte = &H2B
Const Canctrl = &H0F
Const Canstat = &H0E ' Statusregister
Const Eflg = &H2D ' Error Flag Register
Const Cnf3 = &H28 ' Configuration Register 3
Const Cnf2 = &H29 ' Configuration Register 2
Const Cnf1 = &H2A ' Configuration Register 1
Const Txb0ctrl = &B00110000 ' Transmit Buffer 0 Control Register
Const Txb0sidh = &B00110001 ' Transmit Buffer 0 Std Identifier High
Const Txb0sidl = &B00110010 ' Transmit Buffer 0 Std Identifier Low
Const Txb0eid8 = &B00110011 ' Transmit Buffer 0 Ext Identifier High
Const Txb0eid0 = &B00110100 ' Transmit Buffer 0 Ext Identifier Low
Const Txb0dlc = &B00110101 ' Transmit Buffer 0 Data Length Code
Const Txb0d0 = &B00110110 ' Transmit Buffer 0 Data Byte 0
Const Txb0d1 = &B00110111 ' Transmit Buffer 0 Data Byte 1
Const Txb0d2 = &B00111000 ' Transmit Buffer 0 Data Byte 2
Const Txb0d3 = &B00111001 ' Transmit Buffer 0 Data Byte 3
Const Txb0d4 = &B00111010 ' Transmit Buffer 0 Data Byte 4
Const Txb0d5 = &B00111011 ' Transmit Buffer 0 Data Byte 5
Const Txb0d6 = &B00111100 ' Transmit Buffer 0 Data Byte 6
Const Txb0d7 = &B00111101 ' Transmit Buffer 0 Data Byte 7
Const Rxm0sidh = &B00100000 ' Receive Buffer 0 Std Identifier High
Const Rxm0sidl = &B00100001 ' Receive Buffer 0 Std Identifier Low
Const Rxm0eid8 = &B00100010 ' Receive Buffer 0 Ext Identifier High
Const Rxm0eid0 = &B00100011 ' Receive Buffer 0 Ext Identifier low
Const Rxm1sidh = &B00100100 ' Receive Buffer 1 Std Identifier High
Const Rxm1sidl = &B00100101 ' Receive Buffer 1 Std Identifier Low
Const Rxm1eid8 = &B00100110 ' Receive Buffer 1 Ext Identifier High
Const Rxm1eid0 = &B00100111 ' Receive Buffer 1 Ext Identifier low

Const Rxb0ctrl = &H60
Const Rxb1ctrl = &H70


' Hardware SPI-Schnittstelle konfigurieren

Config Portb.4 = Input 'MISO von 2515
Config Portb.3 = Output 'MOSI von 2515
Config Portb.5 = Output 'SCK
Spcr = &B01010001 'Bit7=0:IntAus, Bit6=1:SPIAn, Bit5=0:MSBfirst,
'Bit4=1:Masterfunktion, Bit3=0:SCK=0wennIdle,
'Bit2=0:L-H-Flanke, Bit1+0=01:AVRClock/16

'Config Pind.3 = Input 'INT1 am AVR und MCP2515

Config Int1 = Falling
On Int1 Int_canint 'Interrupt zum empfangen
Enable Int1
Enable Interrupts


'Programm Start********************************************* ********************
Print "Start Programm"
Gosub Can_init


Do

For I = 1 To Keys
Key = I
Select Case Key
Case 1 : Debounce Pinc.0 , 0 , Key_o1 , Sub 'Port 1.
Case 2 : Debounce Pinc.1 , 0 , Key_o2 , Sub 'Port 2
Case 3 : Debounce Pinc.2 , 0 , Key_o3 , Sub 'Port 3
Case 4 : Debounce Pinc.3 , 0 , Key_o4 , Sub 'Port 4
Case 5 : Debounce Pinc.4 , 0 , Key_o5 , Sub 'Port 5


End Select
Next

Loop



' Zustandsänderung Ausgänge
Key_o1:
Toggle Portb.0
Print "Portb.0" 'Buchse 1
If T2 = 0 Then
T2 = 1
Else
T2 = 0
End If
Gosub Data_send 'Statusänderung per CAN übertragen
Return

Key_o2:
Toggle Portb.1
Print "Portb.1" 'Buchse 2
If T5 = 0 Then
T5 = 1
Else
T5 = 0
End If
Gosub Data_send 'Statusänderung per CAN übertragen
Return

Key_o3:
Toggle Portb.2 'Buchse 3
Print "Portb.2"
If T3 = 0 Then
T3 = 1
Else
T3 = 0
End If
Gosub Data_send 'Statusänderung per CAN übertragen
Return

Key_o5:
Toggle Portd.6 'Buchse 4
Print "Portd.6"
If T1 = 0 Then
T1 = 1
Else
T1 = 0
End If
Gosub Data_send 'Statusänderung per CAN übertragen
Return

Key_o4:
Toggle Portd.7 'Buchse 5
Print "Portd.7"
If T4 = 0 Then
T4 = 1
Else
T4 = 0
End If
Gosub Data_send 'Statusänderung per CAN übertragen
Return


End


'CAN Initialisieren *****************************

Can_init:

Reset Mcp2515cs ' Reset MCP2515

Spdr = &HC0
Do
Loop Until Spsr.spif = 1
Set Mcp2515cs

Waitms 2000
'Mcp2515_write Canctrl , &B10001000 ' low nibble: 3=OSM 2=CLK-Pin 1-0=CLK Divider &B10001000

Print "speed change done"


' CAN 31,25 KHz
Mcp2515_write Cnf1 , &B00001111
Mcp2515_write Cnf2 , &B10010000 ' Cnf2 = &H29
Mcp2515_write Cnf3 , &B00000010 ' Cnf3 = &H28
Mcp2515_write Caninte , &B00000011
Mcp2515_write Rxb0ctrl , &B01100000
Mcp2515_write Rxb1ctrl , &B01100000
Mcp2515_write Rxm0sidh , 0 ' Eigene Empfängeradressen auf 00000000 setzen, kein Filter
Mcp2515_write Rxm0sidl , 0
Mcp2515_write Rxm0eid8 , 0
Mcp2515_write Rxm0eid0 , 0
Mcp2515_write Rxm1sidh , 0
Mcp2515_write Rxm1sidl , 0
Mcp2515_write Rxm1eid8 , 0
Mcp2515_write Rxm1eid0 , 0
Mcp2515_bitmodify Canctrl , &B11100000 , &B00000000
Mcp2515_write Canctrl , &B00000000 ' low nibble: 3=OSM 2=CLK-Pin 1-0=CLK Divider
Mcp2515_write Canctrl , &HE0


Return


'Daten übertargen ****************************
Data_send:

Mcp2515_bitmodify Txb0ctrl , &B00000011 , &B00000011 ' TX-Konfiguration
Mcp2515_write Txb0sidh , &B01010101 ' Empfängeradresse setzen
Mcp2515_write Txb0sidl , &B01010101 ' Empfängeradresse setzen
Mcp2515_write Txb0dlc , &H01 ' Paketlänge festlegen für ein Byte

'Hier soll der Status abgefragt werden: T1, T2, T3, T4, T5
Taster = Pinc
Taster = Taster And &B00011111

Mcp2515_write Txb0d0 , Taster ' Zu übertragende Daten setzen

' Übertragung auslösen
Print "Datenuebertragung"
Reset Mcp2515cs
Waitus 20
Spdr = Cmd_rts0


Do
Loop Until Spsr.spif = 1
Waitus 20
Set Mcp2515cs
Print "Datenuebertragung end"

Return


Int_canint:

Print "Datenempfang - Prüfung"

'Prüfung der ankommenden Daten


Print "Daten:"


Return

Sub Mcp2515_bitmodify(reg_add , Reg_mask , Reg_val)
Local Can_tmp2 As Byte
Mcp2515cs = 0
Can_tmp2 = Cmd_bitmodify
Spdr = Can_tmp2
Do
Loop Until Spsr.spif = 1
Waitms 2
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
Mcp2515cs = 1
End Sub

Sub Mcp2515_write(reg_add , Reg_val)
Local Can_tmp2 As Byte
Mcp2515cs = 0
Can_tmp2 = Cmd_write
Spdr = Can_tmp2
Do
Loop Until Spsr.spif = 1
Waitms 2
Spdr = Reg_add
Do
Loop Until Spsr.spif = 1
Spdr = Reg_val
Do
Loop Until Spsr.spif = 1
Mcp2515cs = 1
End Sub


Function Mcp2515_read(reg_add)
Local Can_tmp2 As Byte
Mcp2515cs = 0
Can_tmp2 = Cmd_read
Spdr = Can_tmp2
Do
Loop Until Spsr.spif = 1
Spdr = Reg_add
Do
Loop Until Spsr.spif = 1
Spdr = 0
Do
Loop Until Spsr.spif = 1
Mcp2515_read = Spdr
Mcp2515cs = 1
End Function


Beim Empfänger der 1:1 in der Hardware ist, sollte zumindest ein Interrupt ausgelöst werden und dies per Print Befehl ausgeben.

Leider funktioniert dies bei mir noch nicht. Den Fehler konnte ich bisher nicht feststellen.
Aber ich denke dass dies schon mal ein Anfang ist um vielleicht gemeinsam etwas weiter zu kommen.

Mein Vorschlag wäre, dass ihr euch die Schaltung anseht und vielleicht auch nachbaut. Irgent wo hat sich ein (Hardware-)Fehler eingeschlichen. Ich kann ihn einfach nicht finden. Vermutlich sehe ich den Wald vor lauter Bäumen nichtmehr.

Wer macht mit?

Tobias

Stromi
17.10.2007, 22:18
Hast du denn den Toogle und Print effekt?`
In der Schaltung würde ich den Reset vom CAN-Controller noch mit einem Pullup versehen.
Ich sollte mir doch mal die Hardware bestellen, es geht ja hier doch weiter :-)

Vitis
18.10.2007, 00:22
der Reset vom ISP geht laut Schaltung nicht auf den Reset vom AVR.
Dafür in den MCP, entweder stimmt Dein Plan nicht mit Deinem
Aufbau überein oder Du drückst beim Proggen jedesmal den Reset-Button?
Ist nicht so elegant, aber das hab ich ja schonmal geschrieben.

elkokiller
20.10.2007, 11:03
Hallo,

am Anschluss des Reset liegt es nicht. habe beide Varianten versucht.
Das Problem muss eine andere Ursache haben.

Hat jemand mal die Schaltung nachgebaut aus ausprobiert? Alternativ würde auch eine andere, funktionierende Variante sicher viele Forenteilnehmer sehr freuen.

feitzi
24.10.2007, 18:01
Hallo Ihr Tüftler
Ich habe ein sehr gut funktionierendes Programm in BASCOM zum Thema CAN mit dem MCP2515.
Da ich euch helfen will könnt Ihr es euch runterladen. (Ich habe auch ein halbes Jahr daran gebastelt)

Gruß
feitzi :-b

Stromi
24.10.2007, 22:30
Danke für den Code !!
Hat es eine Bedeutung, dass du den Quarz geändert hast?
So wie ich das kurz überflogen habe, passt das zu der " Kreativen Schaltung".
Hast du die Resetleitungen zusammen geführt?

Vitis
25.10.2007, 00:04
@feitzi,
schaut soweit lauffähig aus, gut gemacht. n paar kleine "Verbesserungen"
stechen mir jedoch gleich ins Auge. Die Struktur ist nicht besonders
elegant.

z.B. hier:
Hilf1 = Id / 8
Idh = Hilf1
Hilf1 = Idh * 8
Hilf1 = Id - Hilf1
Hilf1 = Hilf1 * 32
Idl = Hilf1

ich würde eher:
idh=high(id)
Idl=low(id)

oder gleich als overlayvariable:
Dim Id As Word At &HA0 , Idl As Byte At &HA0 Overlay , Idh As Byte At &HA1 Overlay



@Stromi,
meinst Du das $crystal = ? Das hat nur mit dem µC zu tun und halt
der RS232-Verbindung. Elkokiller verwendet nen Baudratenquarz und feitzi
nen Quarz mit "runder" Taktung. Letzterer kann bei der UART-Verbindung
mit dem PC u.U. schlechtere Übertragungsqualität verursachen.

feitzi
26.10.2007, 09:43
Hallo

Auch ich hab mich ein halbes Jahr mit dem CAN und MCP2515 rumgeschlagen bis es endlich funktionirt hat. Weiter oben ist ein Schaltplan von elkokiller (Can Testboard). meine Schaltung siet gleich aus, und ich habe ein funktionierendes Programm in Bascom dazu.

Gruß feitzi

Stromi
26.10.2007, 09:51
Du hast doch schon ein Programm gepostet, ist es nicht das Gleiche?

Duesentrieb
26.10.2007, 20:48
Hallo feitzi,

vielen Dank für deinen Programmentwurf. Hast du ihn schon einmal mit dem Testboard ausprobiert. In der Schaltung von Elkokiller ist offensichtlich die CS Pin des 2515 von PB2 auf PD4 verschoben.
Trotz dieser Änderung im Programm bekomme ich es, wie zuvor dias Programm von Elkokiller nicht zum laufen.
Ich habe mittlerweile sämtliche Verbindungen mind. 3 mal überprüft. Die Schaltungen stimmen 1:1. Auch die IC's habe ich mehrfach ausgetauscht.
Funzt das Programm wirklich bei dir?

Kann man die CAN Übertragung eigentlich irgentwie testen?
Ich habe sie quasi 2 mal aufgebaut, so wie sie auf der "Kreativen Seite" beschrieben ist. Oszi ist bei mir leider nicht vorhanden.

Kann jemand helfen?

Ach so, hätte ich fast vergessen. Elkokiller hat am RX1BF Pin eine LED angeschlossen. Die tuts bei mir auch nicht. Würde man deren Funktion überhaupt sehen bei den Geschwindigkeiten?

Daniel

T.J.
26.10.2007, 22:06
ohne Oszilloskop ist das recht schwierig. ich hab mal ne can msg mit m laptop aufgenommen, da konnte man die Bits zählen! aber ganz ohne oszi....kannst du nur testen ob dein empfänger anhand der msg was tut

Duesentrieb
27.10.2007, 09:09
wie sieht das mit der LED aus, würde mann da eine Aktivität sehen?

T.J.
27.10.2007, 09:37
welche geschwindigkeit hast du? Ab 30Hz sieht man die kaum noch blinken...daher will ich das mal bezweifeln. Man könnte evtl. ein kleines blitzen sehen.

Duesentrieb
27.10.2007, 11:34
o.k. dann hat sich das auch erledigt.

Gibt es denn hier irgent jemanden der den Code von Elkokiller oder Feitzi mal ausprobiert hat?
Wäre ganz nett, bevor ich mir jetzt extra ein Oszi zulege, jemanden zu haben der mal einen Kommentar dazu abgeben kann

elkokiller
27.10.2007, 15:02
Hallo zusammen,

ich habe das Programm von Feitzi auf meine Testschaltung afgespielt. Ergebnis: keine Funktion!
Die Frequenz meines Atmega Quarz ist 7,372 Mhz, die des MCP2515 ist 16 Mhz. Das sollte so o.k. sein.
Hier mal die Ausgabe über die RS232 Schnittstelle:

CANINTE: 255
CANINTF: 255
let's GO
T=1 MCP Pinb.3:1
CANINTF: 255
T=2 MCP Pinb.3:1
CANINTF: 255
T=3 MCP Pinb.3:1
CANINTF: 255
T=4 MCP Pinb.3:1
CANINTF: 255
T=5 MCP Pinb.3:1
CANINTF: 255
T=6 MCP Pinb.3:1
.
.
.
T=22 MCP Pinb.3:1
CANINTF: 255
T=23 MCP Pinb.3:1
CANINTF: 255
T=24 MCP Pinb.3:1
CANINTF: 255
T=25 MCP Pinb.3:1
SPI_read_Status0: 255
SPI_read_Status1: 255
SPI_read_Status2: 255
CANINTF: 255
T=26 MCP Pinb.3:1
CANINTF: 255
T=27 MCP Pinb.3:1
CANINTF: 255
T=28 MCP Pinb.3:1
CANINTF: 255
T=29 MCP Pinb.3:1
.
.
.

Das Programm läuft auf zwei CAN-Knoten so dass beim Senden des jeweils anderen eigentlich etwas ankommen müsste!

Tobias

Vitis
27.10.2007, 17:34
schon mal versucht die Anderen Register des MCP auszulesen?
Wenn auf den anderen Registern auch die 255 kommt läuft Der MCP nicht.

elkokiller
27.10.2007, 18:27
Hi vitis,

ich denke daran liegt es nicht. Hier die Abfrage:
CANINTE: 255
CANINTF: 255
Canstat: 0
CANCTRL: 15
CNF1: 42
CNF2: 41
CNF3: 40
TXB0CTRL: 48
TXB1CTRL: 64
TXB2CTRL: 80
RXB0CTRL: 96
RXB1CTRL: 112
BFPCTRL: 12
TXRTSCTRL: 13

Kannst du daraus etwas ablesen?

Tobias

elkokiller
27.10.2007, 19:44
--- das ist mir jetzt aber peinlich ---


Ich habe meinen Fehler gefunden, ich habe die Portsauf meiner Roboternetz-Platine verwechselt. Da konnte garnichts gehen

Jetzt läufts und ich mache mich mals ans Programmstudium =D>

Duesentrieb
27.10.2007, 21:55
Hi Elkokiller,
was läuft denn jetzt bei dir?
Kannst du jetzt Daten übertragen?

Ich habe die Adressierung noch nicht verstanden.
Im Programm von vitis und Elkokiller wird die Adresse durch diese 8 Bits festgelegt
Mcp2515_write Rxm0sidh , 0 ' Eigene Empfängeradressen auf 00000000 setzen, kein Filter
Mcp2515_write Rxm0sidl , 0
Mcp2515_write Rxm0eid8 , 0
Mcp2515_write Rxm0eid0 , 0
Mcp2515_write Rxm1sidh , 0
Mcp2515_write Rxm1sidl , 0
Mcp2515_write Rxm1eid8 , 0
Mcp2515_write Rxm1eid0 , 0

Mit dieser Einstellung sollte der CAN Knoten jede Nachricht empfangen - richtig?!
Um die Adresse zu ändern, muss ich da einfach eines der 8 bits auf 1 setzen?

elkokiller
28.10.2007, 09:46
Hallo zusammen,

ich glaube kaum was ich sehe!
Die Übertragung über CAN funktioniert. Offensichtlich hat es nur nicht funktioniert weil ich immer meinen ISP-Stecker parallel drann hängen hatte.

Jetzt geht die Übertragung!

ich danke allen für ihre Unterstützung!!!!!

Tobias

Stromi
28.10.2007, 13:28
Na, das ist doch erfreulich.
Hatten wir den Reset nicht schon einmal in Verdacht? :-)
Also geht der letzte veröffentlichte Code von Fetzi oder sogar beide Codes

elkokiller
28.10.2007, 15:27
In der Tat. Allerdings ist der Reset mit dem Atmega verbunden!
Mein Problem war die Verbindung zwischen der ISPSchnitstelle und dem PC. Offensichtlich hat die die Funktion zum CAN Prozessor beeinflusst.

Vitis
28.10.2007, 16:49
Jo, wenn der SPI durch den ISP-Stecker blockiert ist geht nicht viel.
Bei dem Bustakt reichen schon u.U. die reinen Leitungen vom ISP,
dass die Flanken verlaufen und das Timing nicht mehr stimmt.

Skragan
05.11.2007, 14:02
Na, da bin ich ja mal gespannt - meine neuen PCB´s sind jetzt auch fertig und bestückt, nun muss ich nur noch Zeit finden zum programmieren, dann geht´s los :)

hanshals
17.11.2007, 15:10
Wollt ihr vielleicht nochmal hier rein schauen? https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=35621
Ich mache nicht gerne Werbung für meine Threads, aber da ich sehr unzufrieden bin mit der Forenstruktur (ich denke, dass die oberen Foren am meisten frequentiert sind, aber wer schaut denn unten nach?! Fast alles lässt sich doch in Elektronik posten...) muss das mal sein...
MFG

Duesentrieb
17.11.2007, 20:41
Hallo,

ich habe das jetzt alles mal so nachgebaut und programmiert wie oben beschrieben.
Funktioniert so weit auch ganz gut.
Allerdings habe ich offensichtlich einen Fehler gemacht!

Ich habe einen Sender und einen Empfänger.
Sobald ich am Sender eine Information auf den Bus gebe, geht diese offensichtlich in eine Endlosschleife.
Allerdings liegt das nicht an meinem Programm sondern offensichtlich am MCP2515.
Kann mir jemand sagen wie ich das Senden wieder stoppen kann?

Noch etwas konkreter:
Das Register canintf bringt mir nach dem Senden immer eine 27 und müsste eigentlich 0 sein.
Die Nachricht wurde aber richtig übertragen!

Vitis
18.11.2007, 11:54
die Endlosschleifer kommt denk ich durch das OSM-Bit.
Die 27 = binär 00011011
Beim Canintf bedeutet dies, das ausser den error-flags nur der tx0 flag
fehlt.
stellt sich die frage ob vor dem senden die flags alle gelöscht waren.
dies macht der mcp nicht alleine, sondern muss vom mcu aktiv getan
werden.
die nächste frage ist dann, ob du über tx0 sendest und ob dein
empfänger den empfang quitiert. wenn du nicht im osm sendest und
es kommt keine quittierung, dann macht der sender immer so weiter.

Abbfrechen kannst Du auch manuell über:
Clearing the TxBnCTRL.TXREQ bit
while it is set, or setting the CANCTRL.
ABAT bit before the message
has started transmission, will abort
the message.

Duesentrieb
18.11.2007, 13:05
o.k. so etwas habe ich mir gedacht.

wo müsste ich das tx0 einbauen?


Mcp2515_read_register Txb0ctrl '&HA0
'Print "SPI_read_Status0: " ; Canin
If Canin.3 = 0 Then Gosub Send_buffer0
Mcp2515_read_register Txb1ctrl '&HA0
'Print "SPI_read_Status1: " ; Canin
If Canin.3 = 0 Then Gosub Send_buffer1
Mcp2515_read_register Txb2ctrl '&HA0
'Print "SPI_read_Status2: " ; Canin
If Canin.3 = 0 Then Gosub Send_buffer2

dann springt er in die einzelen buffer

z.B.

'--------- senden mit Buffer 0
Send_buffer0:
Hilf1 = Id / 8
Idh = Hilf1
Hilf1 = Idh * 8
Hilf1 = Id - Hilf1
Hilf1 = Hilf1 * 32
Idl = Hilf1
'Priorität einstellen bit 1-0 11=>höchste / 10=>hoch
' 01=>niedrig / 00=> niedrigste
Mcp2515_bitmodify Txb0ctrl , &B00000011 , &B00000011
'Standard ID einstellen
Mcp2515_write_register Txb0sidh , Idh
Mcp2515_write_register Txb0sidl , Idl
'Nachrichtenlänge einstellen (DFL)
Mcp2515_write_register Txb0dlc , Dfl
'Daten
Mcp2515_write_register Txb0d0 , Db0(1)
Mcp2515_write_register Txb0d1 , Db0(2)
Mcp2515_write_register Txb0d2 , Db0(3)
Mcp2515_write_register Txb0d3 , Db0(4)
Mcp2515_write_register Txb0d4 , Db0(5)
Mcp2515_write_register Txb0d5 , Db0(6)
Mcp2515_write_register Txb0d6 , Db0(7)
Mcp2515_write_register Txb0d7 , Db0(8)
'nachricht versenden
Reset Css
Waitus 10
Mcphilf = Spi_rts0
Spdr = Mcphilf
Do
Loop Until Spsr.spif = 1
Waitus 10
Set Css
'Print "gesendet Buffer-0"
Waitms 50


Return

wieso sind das eigentlich 3 Buffer?

Duesentrieb
19.11.2007, 16:59
ist keiner da der mir sagen kann wie ich das Flag löschen kann

müsste doch normal mit

Mcp2515_read_register Txb0ctrl.txreq = 0

gehen. - Tuts aber nicht!

Genügt es eigentlich wenn ich das bit am Anfang lösche oder muss ich es nach jedem Senden löshen?

Duesentrieb
22.11.2007, 06:24
Hallo,

ist keiner da der mir bei meinem Problem helfen kann?
Ich ahbe doch nur den Code von feitzi bei mir eingebaut.

Läuft des Programm bei allen anderen auch ohne Quittung und ohne dieses Flag?

Vitis
23.11.2007, 20:42
lies Dir doch mal genau Deine Anweisung durch:

Mcp2515_read_register Txb0ctrl.txreq = 0

Du willst doch ein Bit schreiben, oder nicht?
Es würde sich da die Methode Bit modify anbieten, oder?

Und genau deshalb halt ich nicht viel davon
fertigen Code zu publizieren ;)

Duesentrieb
23.11.2007, 21:03
ja, hast ja recht. Andererseits möchte ich ja mein Geld nicht mit Programmieren verdienen sondern nur die ein oder andere Idee umsetzen.
Wenn ich mich in jedes Programm so tief rein hängen müsste, könnte ich es auch gleich bleiben lassen.

Aber genau aus diesem Grund gibt es ja solche Foren in denen die Profis die Leien unterstützen

Vitis
24.11.2007, 13:27
Also zum Unterbrechen einer Übertragung schreibt das Datenblatt:
3.6 Aborting Transmission
The MCU can request to abort a message in a specific
message buffer by clearing the associated
TXBnCTRL.TXREQ bit.
In addition, all pending messages can be requested to
be aborted by setting the CANCTRL.ABAT bit. This bit
MUST be reset (typically after the TXREQ bits have
been verified to be cleared) to continue transmitting
messages. The CANCTRL.ABTF flag will only be set if
the abort was requested via the CANCTRL.ABAT bit.
Aborting a message by resetting the TXREQ bit does
NOT cause the ABTF bit to be set.

also, um alle Übertragungen zu unterbrechen
erstmal TXREQ auf 0 setzen, anschließend
den ABAT bit auch auf 1 schreiben.
Um wieder zu senden dann wieder den ABAT auf
0 setzen.
Das sollte es schon gewesen sein.

edit:
Eine weitere Schwäche des Codes ist dann noch hier:
Mcpempfang:
Print "Empfangen"
Mcp2515_read_register Canintf 'Spi_rx_status
Canstat = Canin
Print "CANINTF: " ; Canstat
If Canstat.0 = 1 Then Gosub Mcp_read_buffer0
If Canstat.1 = 1 Then Gosub Mcp_read_buffer1
Return

Es wird als Intquelle nur der Buffer0 und der Buffer1 ausgewertet,
wenn ein Fehler auftritt wird der glatt ignoriert.
Kann zwar gut gehen, aber bei größeren Projekten wirds dann
bei debuggen schon "interessant"

ich schlage folgende Ergänzug vor:

if Canstat.7 = 1 then
print "MERRF-Error"
endif
if Canstat.5 = 1 then
print "ERRIF-Error"
endif
sinnvoll währ dann klaro auch die Ints zu enablen:
Mcp2515_write_register Caninte , &B10100011

Dann hat der Code noch n kleines Problemchen.
Hier wird zwar:
'Device zurück in den normalen Modus versetzen
Mcp2515_bitmodify Canctrl , &B11100000 , &B00000000

aber in den Modify-Modus wird der Canctrl zu Anfang nicht gebracht:
Mcp2515_bitmodify Canctrl , &B11100000 , &B10000000 ' = Set Configuration mode
Ausserdem hat man in diesem Register auch den OSM auf Bit 3,
wenn man den aktiviert wird jede Message nur einmal gesendet, also dann:

'Device zurück in den normalen Modus versetzen
Mcp2515_bitmodify Canctrl , &B11101000 , &B00001000

PS:
>Wenn ich mich in jedes Programm so tief rein hängen müsste, könnte ich es auch gleich bleiben lassen.
Nein, Du sparst Zeit, indem Du Dich selbst in den Code einarbeitest, weil Du dann kapiert hast was läuft und dies in anderen Projekten dann übertragen kannst. Du hast ergo was gelernt.

Duesentrieb
25.11.2007, 11:19
Hey Vitis, das nenn ich doch mal Unterstützung!
Nimms und nicht übel, wenn wir so doofe Fragen stellen aber jeder fängt doch mal klein an ;-)

Jetzt würde mich aber auch mal interessieren wie eine Rückmeldung des Empfängers aussieht. Es ist ja wesentlich besser wenn der Sender die Info bekommt das sein Senden erfolgreich war.
Wie muss die Nachricht an den Sender aussehen?

Könntest du mir dazu einen Code basteln? (würde die anderen sicher auch interessieren)

Vitis
25.11.2007, 21:51
Zunächst mal solltest Du Dir mal genau überlegen
wie Dein Bus laufen soll.
Du kannst Deine Kommunikation so aufbauen, dass alle
Busteilnehmer ihre Werte beliebig auf den Bus senden
und die Anderen Busteilnehmer eben nur wenn sie
Werte von einem Anderen benötigen diese dann annehmen,
oder Du kannst Deinen Bus bauen, dass Busteilnehmer
andere anrufen, damit diese dann ihre Werte schicken,
also auf Polling.
Für letztere Kommunikation stellt der MCP ne besondere
automatische Funktion bereit, das RTR (siehe Datenblatt),
mit welchem die Anwesenheit des angesprochenen
Busteilnehmers erstmal erfragt werden kann.

Bei den Kommunikationsformen bist Du dann eben
schon im Protokoll. Hier bietet sich dann schon die
Verwendung von standardisierten Protokollen an,
such mal im Netz unter CANOpen.

PS: ich könnte nen Code basteln, tu dies aber nicht. Ich gebe nur Hilfe zur Selbsthilfe und Tips.

Duesentrieb
30.12.2007, 23:06
Hallo zusammen,

der letzte Beitrag zu diesem Thema ist ja schon einige Zeit her. Zeit genug um ihn wieder zu erwecken =D>

Ich habe nochmal ein paar grundsätzliche Fragen:

1. Wieso werden die Register immer hintereinander beschrieben z.B.
z.B. Mcp2515_bitmodify Canctrl , &B11101000 , &B00001000
Die zweite hebt doch die erste Anweisung auf?!

2. Die Idee von Vits, das Bit 3 (OSM) auf 1 zu setzen und damit eine fortlaufende Übertragung zu stoppen hat leider nichts gebracht!

Müsste man das Problem nicht eigentlich in den Buffern suchen?
Wenn diese ihre Meldung gesendet haben, also Buffer0, 1 und 2 durchlaufen wurden, könnte die Nachricht darin wieder gelöscht werden.


Im Code erfolgt dies doch auch jeweils am Ende der jeweiligen Bufferanweisung durch ein Reset, oder?




Send_buffer2:
Hilf1 = Id / 8
Idh = Hilf1
Hilf1 = Idh * 8
Hilf1 = Id - Hilf1
Hilf1 = Hilf1 * 32
Idl = Hilf1

Mcp2515_bitmodify Txb2ctrl , &B00000011 , &B00000011
'Standard ID einstellen

Mcp2515_write_register Txb2sidh , Idh
Mcp2515_write_register Txb2sidl , Idl
'Nachrichtenlänge einstellen (DFL)
Mcp2515_write_register Txb2dlc , Dfl
'Daten
Mcp2515_write_register Txb2d0 , Db0(1)
Mcp2515_write_register Txb2d1 , Db0(2)
Mcp2515_write_register Txb2d2 , Db0(3)
Mcp2515_write_register Txb2d3 , Db0(4)
Mcp2515_write_register Txb2d4 , Db0(5)
Mcp2515_write_register Txb2d5 , Db0(6)
Mcp2515_write_register Txb2d6 , Db0(7)
Mcp2515_write_register Txb2d7 , Db0(8)
'nachricht versenden
Reset Css
Waitus 10
Mcphilf = Spi_rts2
Spdr = Mcphilf
Do
Loop Until Spsr.spif = 1
Waitus 10
Set Css
' Print "gesendet Buffer-2"
Waitms 50


Return

Außerdem wird das Register vor der eigentlichen Übertragung beschrieben
Mcp2515_bitmodify Txb2ctrl , &B00000011 , &B00000011

Wieso wird das Bit 6 nach Abschluss der Übertragung nicht nachträglich gesetzt? Oder liege ich jetzt völlig falsch?


Edit: Hätte ich fast vergessen! Die Fortlaufende Übertragung erfolgt immer aus dem letzten Buffer. Die beiden ersten senden nur einmal.
Ich habs mit zwei versucht, der Effekt ist der selbe.
D.h. der Inhalt des Vorgängers wurde doch mit der Übertragung des aktuellen Buffers gelöscht, oder?

klaus1973
31.12.2007, 13:18
Hallo Düsentrieb,

ich habe das Programm ebenfalls übernommen und der Tip von Vitis hat bei mir geholfen.
Schau noch malgenau nach, sicher hast du nur einen Zahlendreher!

Leider habe ich ein anderes Problem.
Ich habe 3 Knoten am Bus hängen.
Einer Empfängt alle Nachrichten und gibt sie auf einem Display aus.
Die beiden anderen senden nur.

Nun ist es so dass wenn einer der beiden sendet, der andere keine Nachrichtem mehr senden kann.
Die Kommunikation ist nur noch zwischen dem ersten Sender zum Empfänger möglich.
Woran kann das liegen?

Klaus

klaus1973
31.12.2007, 13:48
Habe den Fehler gefunden.
Natürlich müssen alle Meldungen in jedem Knoten ausgewertet werden bzw. jeder Knoten muss nach dem Empfang wieder in eine Grundstellung gebracht werden.
Das habe ich nicht gemach.... ](*,)

Aber ich habe mal ne andere Frage an die Experten.
Im hier mehrfach beschriebenen Code wird die ID des Senders neu berechnet:

Hilf1 = ID/8
IDH = Hilf1
Hilf1 = IDH *8
Hilf1 = ID - Hilf1
Hilf1 = Hilf1 *32
Idl = Hilf1

wieso macht man das?

Duesentrieb
01.01.2008, 09:54
\:D/ Prost Neujahr!

Hallo Klaus1973,
bin mein Programm noch mal durchgegangen und habe tatsächlich den Fehler gefunden!
Noch ungeklärt ist allerdings meine Frage

1. Wieso werden die Register immer hintereinander beschrieben z.B.
z.B. Mcp2515_bitmodify Canctrl , &B11101000 , &B00001000
Die zweite hebt doch die erste Anweisung auf?

Weis darauf keiner einen Rat?

Ich versuche mich jetzt mal an der Adressierung.
Wenn ich es richtig verstehe, dann müsste doch mit der folgende Initialisierungssequenz eines Empfängers, jede Nachricht mit der Sender-ID zur Auswertung kommen:


Mcp2515_init:
Mcphilf = Spi_reset
Reset Css
Waitus 10
Spdr = Mcphilf
Do
Loop Until Spsr.spif = 1
Waitus 10
Set Css
Mcp2515_write_register Cnf1 , &H13
Mcp2515_write_register Cnf2 , &H90
Mcp2515_write_register Cnf3 , &H02

'Interrupt einstellen
Mcp2515_write_register Caninte , &B00000011

'Buffer 0: Empfangen aller Nachrichten mit ID 255
Mcp2515_write_register Rxb0ctrl , &B00100000

'Buffer 1: Empfangen aller Nachrichten mit ID 255
Mcp2515_write_register Rxb1ctrl , &B00100000

Mcp2515_write_register Rxm0sidh , &B11111111
Mcp2515_write_register Rxm0sidl , &B11111111
Mcp2515_write_register Rxm0eid8 , 0
Mcp2515_write_register Rxm0eid0 , 0
Mcp2515_write_register Rxm1sidh , &B11111111
Mcp2515_write_register Rxm1sidl , &B11111111
Mcp2515_write_register Rxm1eid8 , 0
Mcp2515_write_register Rxm1eid0 , 0

'Einstellen der Pin Funktionen
'Deaktivieren der Pins RXnBF Pins (High Impedance State)
Mcp2515_write_register Bfpctrl , 0

'TXnRTS Bits als Input schalten
Mcp2515_write_register Txrtsctrl , 0

'Device zurück in den normalen Modus versetzen
Mcp2515_bitmodify Canctrl , &B11100000 , &B00000000

'ende MCP2515_init
Return


Leider reagiert der Empfänger darauf überhaupt nicht.
Wo habe ich den Fehler gemacht?[/code]

elkokiller
03.01.2008, 18:02
@Klaus1973:
Die Rechenoperation ist erforderlich um die Hight und Low-Bits so zu befüllen dass sie richtig übertragen werden <32 im IDH >31 im IDL

@Duesentrieb:
Ich habe bisher nur 2 Teilnehmer am Bus hängen und den Ursprungscode beibehalten.
Damit wird alles Empfangen was gesendet wird.
Ich werde mich aber bald auch mit dem Thema beschäftigen so dass mir eine Antwort auf deine Frage sicher auch helfen würde.
Bist du schon weiter gekommen?

T.J.
30.01.2008, 16:12
Hi,

ich benötige auch mal eure hilfe.
Ich habe ein CAN aufgebaut mit 2 Teilnehmern. Ein Empfänger, der läuft mit 8MHz und gibt die Daten auf ein Display aus. Der hat die Config:



Cnf1, H04
Cnf2, H00
Cnf3, H00


Der funktioniert Tadellos mit einem Sender, der gleichen Art. Das ist ein PIC mit CAN controller integriert.

Jetzt habe ich aber als Sender einen Mega32 mit einem 2510 als Controller (eigentlich 16MHz, nun aber einen 8MHz Quarz geholt), der nun mit der gleichen Taktfrequenz läuft. Auf diesem läuft das angehangene Programm. Ich habe die gleiche Config eingestellt, trotzdem empfange ich nur falsche Daten. Aber es kommt was (Inhalt ist 00000000).

Kann mir jemand helfen was ich bei den 3 Cnf registern einstellen sollte??? Ich habe den RS Pin des 2551 auf GND. Und kann mir bitte jemand sagen, ob mein Bascom prog soweit korrekt ist so dass ich sicher sein kann dass es an der config liegt?

Das wäre sehr nett!

Skragan
18.02.2008, 16:01
Hi,

ich habe nun auch mal endlich angefangen und mir hier und da ein paar Codeschnipsel angeschaut und endlose Mengen Unterlagen gewälzt. Nun läuft das prinzipiell auch schon, nur plötzlich ging es nicht mehr und ich stehe auf dem Schlauch. Hat jemand eine Idee ? Sobald MCPinit aufgerufen wird, geht das Programm beim ersten canwrite in den Watchdog...

Skragan
21.02.2008, 07:37
Haben alle Urlaub ? :)

Skragan
21.02.2008, 09:43
Ha ! So, den Fehler habe ich schonmal gefunden. Die /SS Leitung vom Mega8 hing in der Luft und war nicht als Eingang geschaltet. Somit wurde immer das MSTR Bit gelöscht und der SPI wollte nicht senden. Das tut er jetzt.

Hat es eigentlich irgendeinen Vorteil, das SPDR Register manuell zu laden und eine Zeitschleife zu programmieren, die auf das SPIF Bit wartet ? Man kann doch sicherlich genauso den Bascom Befehl SPIout nutzen, oder ?

Jetzt kann ich dann als nächstes den MCP wieder anklemmen. Noch eine Frage, eher Hardware: So ganz habe ich den Zusammenhang mit der /SS Leitung noch nicht erfasst - wozu ist die denn gut, wenn man die nur auf high klemmt ? Oder kann man damit noch etwas anfangen ?

Und noch eine prinzipielle Frage zum SPI Bus: Das muss doch eigentlich auch ohne die /CS Leitung gehen, oder wie klemmt man mehrere Slaves an einen Bus ? Im Bascom Buch von Kühnel sind wir Slaves mit 4 einzelnen /CS Leitungen angeschlossen, aber das kann doch nicht Sinn und Zweck eines Bussystems sein ? (Hat sich erledigt - weiß Bescheid:) )

Skragan
21.02.2008, 10:39
Hier nochmal der aktuelle Code. Jetzt läuft die SPI, allerdings ist auf dem CAN noch Ruhe (Skop) - offenbar sendet der MCP nichts. Hat jemand eine Idee ? Sieht jemand auf Anhieb einen Fehler ?

Skragan
21.02.2008, 12:20
Ein weiterer Fehler war schonmal die falsche Nachrichtenlänge 0x04h, die muss natürlich 0x02h sein. Trotzdem bislang kein Erfolg :(

T.J.
21.02.2008, 13:42
Die routine zum Senden sieht nicht falsch aus. Aber überprüf mal deine CNF config des MCP. Eine Gültige Config muss mind. 6 X TQ haben laut Datenblatt. Ich bin nicht sicher ob du das eingehalten hast.

Skragan
21.02.2008, 14:15
6*TQ ? Gib mir doch mal einen Tip, auf welcher Seite ich dazu was finde :) Ich suche hektisch...

Skragan
21.02.2008, 14:33
Ah, OK... Seite 37ff - die Bit Timings meinst Du, ja ? Das habe ich jetzt zumindest nach einmaligem Lesen noch nicht komplett verstanden. Ich hatte gedacht, man stellt nur die gewünschte Bitrate ein uns gut ist ?

Da hätten die auch gut mal ein Beispiel reinpacken können, denn das erschließt sich mir irgendwie nicht....

Ich werde nochmal weitergrübeln, danke einstweilen für den Hinweis !

Skragan
22.02.2008, 07:22
Ich bekomme es einfach nicht hingefummelt.... die Beschreibung im Datenblatt finde ich einfach nur kryptisch. Ist BRP gleich NBR ? Könnte mir das nicht mal jemand in einfachen Worten erklären, wie ich mit meinem Takt von 16MHz diese Forderung für die Konfiguration erfülle ? Die Details kann ich mir dann sicherlich rückwärts erarbeiten... :(

/edit/

Nach knappen zwei Stunden habe ich einige Fortschritte erzielt, denke ich. Ein paar Dinge konnte ich jetzt begreifen:

Bei einer Fosc von 16MHz und einer gewünschten Bitrate von 125kbit/s berechne ich also TQ wie folgt: (2*125)/62,5ns=4

Das SyncSegment muss 1TQ sein, PropSeg setze ich mit 2TQ, PS1 auf 4TQ (BTLMode auf 0) und um die unter 5.3 gelisteten Regeln zu erfüllen also PS2 auf 3. Dann sähe das so aus:

CNF1 = &B00000100
CNF2 = &B01100010
CNF3 = &B00000011

Aber: Was ist Tdelay unter Punkt 5.3 ? Und wie kommen die bei Punkt 5.3 auf folgende Aussage: "Tosc=50ns, choose BRP<5:0>=04H, then TQ=500ns. To obtain 125kHz, the bit time must be 16TQ" ?? Wäre super, wenn mir das jemand erklären könnte...

Skragan
22.02.2008, 09:05
Trotz der Änderungen schreibt er wie es aussieht nichts in den MCP.

Dieser Part:


Print "Call mcpinit..."

Call Mcpinit()

Print "done!"

Post = Canread(caninte)
Print "CANINTE:" ; Post

Post = Canread(canintf)

Print "CANINTF:" ; Post

Post = Canread(cnf1)
Print "CNF1=" ; Post
Post = Canread(cnf2)
Print "CNF2=" ; Post
Post = Canread(cnf3)
Print "CNF3=" ; Post

mit MCPinit wie folgt:


Sub Mcpinit()
Local Can_tmp As Byte 'Lokale Variable
Reset Mcp_cs 'MCP Chip select an (aktiv)
Waitus 10 'Warten bis Pegel stabil
Can_tmp = Cmd_reset
Spdr = Can_tmp '&HC0 ins SPI Data Register laden
Do 'Warte bis
Loop Until Spsr.spif = 1 'SPI Interrupt cleared (Transfer abgeschlossen)
Waitus 10 'Warten bis Pegel stabil
Set Mcp_cs 'Chip select wieder an (inaktiv)
Led_gelb = 1
Waitms 500
' Canwrite Canctrl , &B10001000
Canwrite Cnf1 , &B00000100 'Timing &H13=50kbit/s, &H07=125kb/s, &H01=250kb/s
Canwrite Cnf2 , &B01100010 '&H90
Canwrite Cnf3 , &B00000011 '&H02
Canwrite Caninte , &B00000011 'Interrupt einstellen
Canwrite Rxb0ctrl , &B01100000 'Buffer 0: Empfangen aller Nachrichten
Canwrite Rxb1ctrl , &B01100000 'Buffer 1: Empfang aller Nachrichten

Canwrite Rxm0sidh , 0 'Kein Filter, Empfängeradresse Null
Canwrite Rxm0sidl , 0
Canwrite Rxm0eid8 , 0
Canwrite Rxm0eid0 , 0
Canwrite Rxm1sidh , 0
Canwrite Rxm1sidl , 0
Canwrite Rxm1eid8 , 0
Canwrite Rxm1eid0 , 0

Canwrite Bfpctrl , 0 'Deaktivieren der RXnBF Pins (High Impedance)
Canwrite Txrtsctrl , 0 'TXnRTS Bits als Inputs schalten
Canmod Canctrl , &B11100000 , &B00000000 'Device zurück in den normalen Modus versetzen
Led_gelb = 0
End Sub

bringt dieses Ergebnis:

Call mcpinit...
done!
CANINTE:0
CANINTF:0
CNF1=0
CNF2=0
CNF3=0

Skragan
22.02.2008, 13:46
Ich bin sicher, daß die Initialisierung des SPI ansich noch fehlerhaft ist. Zwar wird etwas gesendet, aber der MCP scheint einfach nichts zu empfangen / verstehen. Könnte darauf nochmal jemand einen Blick werfen ? Am Montag werde ich mir nochmal genau die Timings der SPI Schnittstelle anschauen...

Skragan
25.02.2008, 08:45
Also ich finde einfach nichts, es ist zum Mäusemelken - die SCK Leitung taktet sauber und auf MOSI gehen auch sinnvolle Datenpakete raus. Trotzdem reagiert der MCP auf nichts. Ich würde mich wirklich sehr über Hilfe freuen !

Testhalber habe ich das Programm von feitzi mal angepasst, das scheint zu laufen, auch wenn ich mit den Ausgaben (noch) nicht wirklich etwas anfangen kann. Vielleicht war der SPI bei mir zu langsam oder zu schnell, keine Ahnung. Oder es liegt einfach an der Ein- und Ausgaberoutine...

T.J.
25.02.2008, 10:15
Ich bekomme es einfach nicht hingefummelt.... die Beschreibung im Datenblatt finde ich einfach nur kryptisch. Ist BRP gleich NBR ? Könnte mir das nicht mal jemand in einfachen Worten erklären, wie ich mit meinem Takt von 16MHz diese Forderung für die Konfiguration erfülle ? Die Details kann ich mir dann sicherlich rückwärts erarbeiten... :(

/edit/

Nach knappen zwei Stunden habe ich einige Fortschritte erzielt, denke ich. Ein paar Dinge konnte ich jetzt begreifen:

Bei einer Fosc von 16MHz und einer gewünschten Bitrate von 125kbit/s berechne ich also TQ wie folgt: (2*125)/62,5ns=4

Das SyncSegment muss 1TQ sein, PropSeg setze ich mit 2TQ, PS1 auf 4TQ (BTLMode auf 0) und um die unter 5.3 gelisteten Regeln zu erfüllen also PS2 auf 3. Dann sähe das so aus:

CNF1 = &B00000100
CNF2 = &B01100010
CNF3 = &B00000011

Aber: Was ist Tdelay unter Punkt 5.3 ? Und wie kommen die bei Punkt 5.3 auf folgende Aussage: "Tosc=50ns, choose BRP<5:0>=04H, then TQ=500ns. To obtain 125kHz, the bit time must be 16TQ" ?? Wäre super, wenn mir das jemand erklären könnte...

DU wirst es nicht glauben, aber ich habe es 3Tage lang mehrmals lesen müssen um da einigermaßen durchzusteigen. Die Formel in Kombination mit den Beispielen ist einfach nur seltsam..und schlecht erklärt.

Folgende Sachen sind mir noch aufgefallen:
- Dein Widerstand RS des 2551 gegen Masse ist 10K, für low speed nimmt man eigentlich 3,3k. Ich habe sogar direkt an Masse gelötet. Musst nur auf beiden Platinen gleich machen.
- bekommt dein 2515 wirklich ordentliche 16MHz ?
- " Canmod Canctrl , &B11100000 , &B00000000 'Device zurück in den normalen Modus versetzen" -> funktioniert das Wikrlich? warum nicht einfach "Canwrite Canctrl , &B00000000" ?

Skragan
25.02.2008, 12:08
Danke für die Hinweise, aber ist meine CNF Konfiguration denn nu richtig ? ;)

Bezüglich des Widerstandes: Direkt auf Masse soll er doch für Highspeed liegen, damit die Flanken steiler werden ? So sagt es zumindest Punkt 1.4.1 im Datenblatt. Ich werde es trotzdem mal probieren, auf EMV achte ich ja zur Zeit eh nicht :)

Der Canmod Canctrl , &B11100000 , &B00000000 setzt Bit 7, 6 und 5 im Canctrl auf Null, und das ist doch normal operation mode ? Wobei ich nicht abstreiten möchte, das canwrite cancontrol,0 nicht auch geht. Es könnte aber sein, daß dann die restlichen Bits noch geklappert werden, bevor der Chip im normal mode ist - deshalb die Maskierung.

Takt ist genau 16MHz, die kommen auch beim MCP richtig an. AufPin 3 kommt ein Rechteck mit 2MHz wieder raus - sieht alles gut aus.

Ich wühle mich gerade noch weiter in das MCP Datenblatt, vielleicht habe ich ja auch nur noch etwas nicht verstanden...

T.J.
25.02.2008, 12:23
Das klingt soweit schonmal ganz gut. Aber du musst mindestens noch Bit 7 in CNF2 setzten, sonst wird deine Einstellung in CNF3 nicht verwendet.

SPI comm kannst du ganz einfach testen in dem du per SPI den clock prescaler mal änderst, so dass dann statt der 2MHz z.B. 4Mhz rauskommen sollen. Wenn das funzt liegt es schon mal nicht mehr an SPI ;)

Skragan
25.02.2008, 13:56
Nene, es klappt immernoch nicht. Ich lasse also gerade die ganze Kommunikationssuppe weg und versuche, nur den MCP zu schreiben und zu lesen, aber es klappt nicht. Eine Änderung des Prescalers nimmt er nicht an. Hier mal der letzte Stand:

Teil 1



'**** Deklarationen ************************************************** **********
$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 8 'default use 10 for the SW stack
$framesize = 24 'default use 40 for the frame space
$regfile = "m8def.dat" 'Chipdefinition
$crystal = 16000000 'Ext. crystal Osc. Speed 16Mhz
$baud = 2400 'Speed COM1

Declare Sub Mcpinit()
Declare Sub Canwrite(byval Reg_add As Byte , Byval Reg_val As Byte)
Declare Sub Canmod(byval Reg_add As Byte , Byval Reg_mask As Byte , Byval Reg_val As Byte)
Declare Function Canread(byval Reg_add As Byte ) As Byte

'**** Portinitialisierung ************************************************** ****
Portb = &H00 'Port B hochohmig schalten
Portc = &H00 'Port C hochohmig schalten
Portd = &H00 'Port D hochohmig schalten

Config Portb.0 = Output 'LED gelb
Led_gelb Alias Portb.0
Led_gelb = 0
Config Portb.1 = Output 'LED rot
Led_rot Alias Portb.1
Led_rot = 0
Config Portb.2 = Input '/SS Eingang
Config Portc = Output 'Aux
Config Pind.2 = Input 'MCP Interrupt MCP2515 /INT
Config Portd.4 = Output 'MCP /CS Chip Select
Mcp_cs Alias Portd.4
Config Portd.6 = Input 'Taster S1
Portd.6 = 1 'Pullup für S1
S1 Alias Pind.6
Config Portd.7 = Input 'Taster S2
Portd.7 = 1 'Pullup für S2
S2 Alias Pind.7

Led_rot = 1 'Resetmerker und Zeit zum ISP Stecker abziehen ;)
Wait 3
Led_rot = 0


'**** Interupts einschalten ************************************************** **
Config Int0 = Falling 'INT MCP ist low aktiv
On Int0 Int_mcp 'Wenn INT, dann Routine INT_mcp aufrufen
Enable Int0 'INT0 einschalten
Enable Interrupts 'Globale Interrupts einschalten

'**** Watchdog einrichten ************************************************** ****
Config Watchdog = 2048 'WD Timer 2 sek
Start Watchdog

'**** Variablen deklarieren ************************************************** **
Const Cmd_read = &H03 'Read Command
Const Cmd_write = &H02 'Write Command
Const Cmd_bitmodify = &H05 'Bit-modify Command
Const Cmd_readstatus = &HA0 'Read Status Command (poll)
'Const Cmd_read_rx_status = &HB0 '?
Const Cmd_reset = &HC0 'Reset Command
Const Cmd_rts0 = &H81 'Sendekommando RTS Buffer 0
Const Cmd_rts1 = &H82 'Sendekommando RTS Buffer 1
Const Cmd_rts2 = &H84 'Sendekommando RTS Buffer 2

Const Bfpctrl = &H0C 'RXnBF Pins
Const Txrtsctrl = &H0D 'TXnRTS Pins
Const Caninte = &H2B 'Interrupt enable
Const Canintf = &H2C 'Interrupt flag
Const Canctrl = &H0F 'Control Register
Const Canstat = &H0E 'Statusregister
Const Eflg = &H2D 'Error Flag Register
Const Cnf3 = &H28 'MCP 2515 Configuration Register 3
Const Cnf2 = &H29 'MCP 2515 Configuration Register 2
Const Cnf1 = &H2A 'MCP 2515 Configuration Register 1
Const Tec = &H1C 'Transmit Error Counter
Const Rec = &H1D 'Receive Error counter

Const Rxm0sidh = &H20 'Receive Buffer Mask 0 Std Identifier High
Const Rxm0sidl = &H21 'Receive Buffer Mask 0 Std Identifier Low
Const Rxm0eid8 = &H22 'Receive Buffer Mask 0 Ext Identifier High
Const Rxm0eid0 = &H23 'Receive Buffer Mask 0 Ext Identifier low
Const Rxm1sidh = &H24 'Receive Buffer Mask 1 Std Identifier High
Const Rxm1sidl = &H25 'Receive Buffer Mask 1 Std Identifier Low
Const Rxm1eid8 = &H26 'Receive Buffer Mask 1 Ext Identifier High
Const Rxm1eid0 = &H27 'Receive Buffer Mask 1 Ext Identifier low

Const Rxb0ctrl = &H60 'Receive Buffer 0 Control Register
Const Rxb0sidh = &H61 'Receive Buffer 0 Std Identifier High
Const Rxb0sidl = &H62 'Receive Buffer 0 Std Identifier Low
Const Rxb0eid8 = &H63 'Receive Buffer 0 ext Identifier High
Const Rxb0eid0 = &H64 'Receive Buffer 0 ext Identifier Low
Const Rxb0dlc = &H65 'Receive Buffer 0 Data Length Code
Const Rxb0d0 = &H66 'Receive Buffer 0 Data Byte 0
Const Rxb0d1 = &H67 'Receive Buffer 0 Data Byte 1
Const Rxb0d2 = &H68 'Receive Buffer 0 Data Byte 2
Const Rxb0d3 = &H69 'Receive Buffer 0 Data Byte 3
Const Rxb0d4 = &H6A 'Receive Buffer 0 Data Byte 4
Const Rxb0d5 = &H6B 'Receive Buffer 0 Data Byte 5
Const Rxb0d6 = &H6C 'Receive Buffer 0 Data Byte 6
Const Rxb0d7 = &H6D 'Receive Buffer 0 Data Byte 7

Const Rxb1ctrl = &H70 'Receive Buffer 1 Control Register
Const Rxb1sidh = &H71 'Receive Buffer 1 Std Identifier High
Const Rxb1sidl = &H72 'Receive Buffer 1 Std Identifier Low
Const Rxb1eid8 = &H73 'Receive Buffer 1 ext Identifier High
Const Rxb1eid0 = &H74 'Receive Buffer 1 ext Identifier Low
Const Rxb1dlc = &H75 'Receive Buffer 1 Data Length Code
Const Rxb1d0 = &H76 'Receive Buffer 1 Data Byte 0
Const Rxb1d1 = &H77 'Receive Buffer 1 Data Byte 1
Const Rxb1d2 = &H78 'Receive Buffer 1 Data Byte 2
Const Rxb1d3 = &H79 'Receive Buffer 1 Data Byte 3
Const Rxb1d4 = &H7A 'Receive Buffer 1 Data Byte 4
Const Rxb1d5 = &H7B 'Receive Buffer 1 Data Byte 5
Const Rxb1d6 = &H7C 'Receive Buffer 1 Data Byte 6
Const Rxb1d7 = &H7D 'Receive Buffer 1 Data Byte 7

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

Const Txb1ctrl = &H40 'Transmit Buffer 1 Control Register
Const Txb1sidh = &H41 'Transmit Buffer 1 Std Identifier High
Const Txb1sidl = &H42 'Transmit Buffer 1 Std Identifier Low
Const Txb1dlc = &H45 'Transmit Buffer 1 Data Length Code
Const Txb1d0 = &H46 'Transmit Buffer 1 Data Byte 0
Const Txb1d1 = &H47 'Transmit Buffer 1 Data Byte 1
Const Txb1d2 = &H48 'Transmit Buffer 1 Data Byte 2
Const Txb1d3 = &H49 'Transmit Buffer 1 Data Byte 3
Const Txb1d4 = &H4A 'Transmit Buffer 1 Data Byte 4
Const Txb1d5 = &H4B 'Transmit Buffer 1 Data Byte 5
Const Txb1d6 = &H4C 'Transmit Buffer 1 Data Byte 6
Const Txb1d7 = &H4D 'Transmit Buffer 1 Data Byte 7

Const Txb2ctrl = &H50 'Transmit Buffer 2 Control Register
Const Txb2sidh = &H51 'Transmit Buffer 2 Std Identifier High
Const Txb2sidl = &H52 'Transmit Buffer 2 Std Identifier Low
Const Txb2dlc = &H55 'Transmit Buffer 2 Data Length Code
Const Txb2d0 = &H56 'Transmit Buffer 2 Data Byte 0
Const Txb2d1 = &H57 'Transmit Buffer 2 Data Byte 1
Const Txb2d2 = &H58 'Transmit Buffer 2 Data Byte 2
Const Txb2d3 = &H59 'Transmit Buffer 2 Data Byte 3
Const Txb2d4 = &H5A 'Transmit Buffer 2 Data Byte 4
Const Txb2d5 = &H5B 'Transmit Buffer 2 Data Byte 5
Const Txb2d6 = &H5C 'Transmit Buffer 2 Data Byte 6
Const Txb2d7 = &H5D 'Transmit Buffer 2 Data Byte 7


Dim Can_post_holen As Bit 'Merker für MCP Interrupt (Post ist da)
Can_post_holen = 0 'Merker auf Null
Dim Data_tmp As Byte 'Temp Datenbyte
Dim Can_rxd_post(8) As Byte 'Datenarray für empfangene Daten
Dim Can_txd_post(8) As Byte 'Datenarray für zu sendende Daten
Dim Canstatus As Byte 'Statuswort



Ich bin echt unglücklich ;)

Skragan
25.02.2008, 13:59
Teil 2


'**** Schnittstellen konfigurieren *********************************************

'SPI
'Config Portb.4 = Input 'MISO Input
'Config Portb.3 = Output 'MOSI Output
'Config Portb.5 = Output 'SCK Output

'Spcr = &B01010011 'HardwareSPI AN, SPI Int off, MSB, Master, Low, Phase 0, Clock 16MHZ/8 = 2MHz
'Spsr = &B00000000 'SPI2X=0

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

Print " "
Print "Neustart !"
Print " "
Print "Call mcpinit..."

Call Mcpinit()

Print "done!"

Data_tmp = Canread(caninte)
Print "CANINTE:" ; Data_tmp

Data_tmp = Canread(canintf)

Print "CANINTF:" ; Data_tmp

Data_tmp = Canread(canctrl)
Print "Canctrl=" ; Data_tmp

Data_tmp = Canread(cnf1)
Print "CNF1=" ; Data_tmp
Data_tmp = Canread(cnf2)
Print "CNF2=" ; Data_tmp
Data_tmp = Canread(cnf3)
Print "CNF3=" ; Data_tmp

'************************************************* ******************************
'* Hauptprogramm *
'************************************************* ******************************
Do
Reset Watchdog

If S1 = 0 Then
Led_rot = 1
Waitms 500
'Prescaler auf clock/1 stellen
Reset Mcp_cs 'MCP Chip select an (aktiv)
Waitus 10 'Warten bis Pegel stabil
Data_tmp = Cmd_reset
Spdr = Data_tmp '&HC0 ins SPI Data Register laden
Do 'Warte bis
Loop Until Spsr.spif = 1 'SPI Interrupt cleared (Transfer abgeschlossen)
Waitus 10 'Warten bis Pegel stabil
Set Mcp_cs 'Chip select wieder an (inaktiv)
Led_gelb = 1
Waitms 500
Canmod Canctrl , &B00000011 , &B00000000 'Device zurück in den normalen Modus versetzen
Canmod Canctrl , &B11100000 , &B00000000 'Device zurück in den normalen Modus versetzen
Led_gelb = 0

Led_rot = 0
End If

If S2 = 0 Then
Led_rot = 1
Waitms 500
Led_rot = 0
End If

'If Can_post_holen = 1 Then
' Print "Empfangen"
' Data_tmp = Canread(canintf)
' Print "CANINTF: " ; Data_tmp
' Can_post_holen = 0
' Led_gelb = 0
'End If

Loop

'************************************************* ******************************
'************************************************* ******************************

Sub Mcpinit()
Local Can_tmp As Byte 'Lokale Variable
Reset Mcp_cs 'MCP Chip select an (aktiv)
Waitus 10 'Warten bis Pegel stabil
Can_tmp = Cmd_reset
Spdr = Can_tmp '&HC0 ins SPI Data Register laden
Do 'Warte bis
Loop Until Spsr.spif = 1 'SPI Interrupt cleared (Transfer abgeschlossen)
Waitus 10 'Warten bis Pegel stabil
Set Mcp_cs 'Chip select wieder an (inaktiv)
Led_gelb = 1
Waitms 500
Canwrite Cnf1 , &B00000100 'forum &B00010011 'selbst:&B00000100
Canwrite Cnf2 , &B11100010 'forum &B10010000 'selbst:&B11100010 '
Canwrite Cnf3 , &B00000011 '&B00000010 'selbst: &B00000011 '
Canwrite Caninte , &B00000011 'Interrupt einstellen
Canwrite Rxb0ctrl , &B01100000 'Buffer 0: Empfangen aller Nachrichten
Canwrite Rxb1ctrl , &B01100000 'Buffer 1: Empfang aller Nachrichten

Canwrite Rxm0sidh , 0 'Kein Filter, Empfängeradresse Null
Canwrite Rxm0sidl , 0
Canwrite Rxm0eid8 , 0
Canwrite Rxm0eid0 , 0
Canwrite Rxm1sidh , 0
Canwrite Rxm1sidl , 0
Canwrite Rxm1eid8 , 0
Canwrite Rxm1eid0 , 0

Canwrite Bfpctrl , 0 'Deaktivieren der RXnBF Pins (High Impedance)
Canwrite Txrtsctrl , 0 'TXnRTS Bits als Inputs schalten
Canmod Canctrl , &B11100000 , &B00000000 'Device zurück in den normalen Modus versetzen
Led_gelb = 0
End Sub

Sub Canwrite(reg_add , Reg_val)
Local Can_tmp2 As Byte
Reset Mcp_cs 'MCP Chip select an (aktiv)
Waitus 10
Can_tmp2 = Cmd_write

' In Bascom:
' Spiout Can_tmp2 , 1
' Spiout Reg_add , 1
' Spiout Reg_val , 1

Spdr = Can_tmp2 '&H02 ins SPI Data Register laden
Do 'Warte bis
Loop Until Spsr.spif = 1 'SPI Interrupt cleared (Transfer abgeschlossen)
Spdr = Reg_add
Do 'Warte bis
Loop Until Spsr.spif = 1 'SPI Interrupt cleared (Transfer abgeschlossen)
Spdr = Reg_val
Do 'Warte bis
Loop Until Spsr.spif = 1 'SPI Interrupt cleared (Transfer abgeschlossen)
Waitus 10
Set Mcp_cs 'Chip select wieder an (inaktiv)
End Sub

Sub Canmod(reg_add , Reg_mask , Reg_val )
Local Can_tmp2 As Byte
Reset Mcp_cs
Waitus 10
Can_tmp2 = Cmd_bitmodify '&H05

' In Bascom:
' Spiout Can_tmp2 , 1
' Spiout Reg_add , 1
' Spiout Reg_mask , 1
' Spiout Reg_val , 1

Spdr = Can_tmp2 'ins SPI Data Register laden
Do 'Warte bis
Loop Until Spsr.spif = 1 'SPI Interrupt cleared (Transfer abgeschlossen)
Spdr = Reg_add
Do 'Warte bis
Loop Until Spsr.spif = 1 'SPI Interrupt cleared (Transfer abgeschlossen)
Spdr = Reg_mask
Do 'Warte bis
Loop Until Spsr.spif = 1 'SPI Interrupt cleared (Transfer abgeschlossen)
Spdr = Reg_val
Do 'Warte bis
Loop Until Spsr.spif = 1 'SPI Interrupt cleared (Transfer abgeschlossen)
Waitus 10
Set Mcp_cs
End Sub

Function Canread(reg_add )
Local Can_tmp2 As Byte
Reset Mcp_cs
Waitus 10
Can_tmp2 = Cmd_read '&H03

' In Bascom:
' Spiout Can_tmp2 , 1
' Spiout Reg_add , 1
' Spiin canread , 1

Spdr = Can_tmp2 'ins SPI Data Register laden
Do 'Warte bis
Loop Until Spsr.spif = 1 'SPI Interrupt cleared (Transfer abgeschlossen)
Spdr = Reg_add
Do 'Warte bis
Loop Until Spsr.spif = 1 'SPI Interrupt cleared (Transfer abgeschlossen)
Canread = Spdr 'Datenübernahme
Spdr = 0
Do 'Warte bis
Loop Until Spsr.spif = 1 'SPI Interrupt cleared (Transfer abgeschlossen)
Waitus 10
Set Mcp_cs
End Function

End

'*** ISR ************************************************** *********************
Int_mcp: 'ISR für Empfang

Led_gelb = 1

Can_post_holen = 1

Return


Bit 7 in CNF2 habe ich geändert, ich hatte das so verstanden, das bei Null die Länge von PS2 > PS1 und IPT ist. Aber naja, ist halt mies beschrieben :)

Die Ausgabe im Terminal ist bei allen Abfragen 255...

Skragan
26.02.2008, 12:36
Also ich bin hilflos - ich finde einfach nicht heraus, warum es nicht läuft.

T.J.
26.02.2008, 12:48
Ja, ist manchmal nicht so vertändlich geschrieben, aber manchmal fehlts auch einfach an genügend englischerfahrung ;)

Bleib mal ganz ruhig, wenn du den prescaler nicht ändern kannst ist CNF eh egal! Dann funzt SPI nicht. Wenn aber ein Takt aus dem Pin 3 kommt, läuft er bekommt nur kein brauchbaren SPI befehl von deinem µC.

Daran musst du nun ansetzen. SPI config prüfen, Hardware prüfen. Hast du z.B. auch die SS Leitung angeschlossen und NOSS entsprechend konfiguriert? bzw. wenn nicht musst du den CS des MCP manuell reseten wenn du senden willst ;)

Check das mal, ich seh da nicht so richtig durch das ist kein Bascom oder? Worin programmierst du da?

Skragan
26.02.2008, 13:08
Aber klar ist das Bascom :)

Die /SS Leitung vom 128er liegt über Pullup als Eingang geschaltet auf 5V, dadurch soll SPI immer senden können. Der /CS vom MCP liegt auf PortD.4 des 128ers und wird vor jeder Übertragung gelöscht bzw. nach jeder Übertragung wieder gesetzt.

Ich habe mir gerade die Leitungen auf dem Skop angeschaut, das passt soweit. Ich hole mir gleich mal ein 4 Kanal, dann mache ich mal einen Screenie von /CS, MOSI und SCK - vielleicht werde ich daraus schlauer...

Skragan
26.02.2008, 13:44
Also, folgenden Code habe ich auf eine Taste gelegt:



Data_tmp = &B01011010 'Cmd_reset
Reset Mcp_cs 'MCP Chip select an (aktiv)
Waitus 10 'Warten bis Pegel stabil
Spiout Data_tmp , 1
Waitus 10 'Warten bis Pegel stabil
Set Mcp_cs 'Chip select wieder an (inaktiv)


Dann sieht man auf dem Skop folgendes (was eigentlich alles perfekt ist):

Chan1: /CS
Chan2: MOSI
Chan3: SCK

Skragan
28.02.2008, 08:44
Falls jemand noch irgendeine Idee hat - ich such mir einen Wolf. Keine Ahnung, warum ich nicht mit Ihm reden kann. Der gleiche Effekt bei beiden Boards, an einem defekten Baustein kann es ja nicht liegen, zumal der Code von feitzi ja irgendetwas sendet. Ein genauer Vergleich brachte mir aber keine Erkenntnisse. :(

T.J.
28.02.2008, 09:59
Das sieht ja eigentlich gut aus. /CS hab ich bei mir halt mit /SS verbunden und den Rest Bascom machen lassen. Aber wenn es so auch funzt, ok.

Ist an der Takteinstellung des SPI irgendwas zu änden? Oder vielleicht was in den Fuses? Ich versuch mich mal zu erinnern, dass ich dir heute nachmittag mein Code schicke.

Skragan
28.02.2008, 10:18
/SS könnte ich natürlich dann mal testhalber umlöten - kein Thema. Das teste ich, sobald ich Deinen Code habe - danke schonmal vorab ;) Das ermuntert einen wieder...

T.J.
28.02.2008, 15:05
Jo, wenn du ein paar Seiten vorher guckst wirst du auch meine verzweifelten Versuche finden :D
Ist immer schön wenn man Antworten bekommt, aber wenn das Thema sehr speziell ist gibt es kaum Leute die was sinnvolles antworten können. Außer eben welche wie ich, die genau das gemacht haben was du vor hast.

Schau mal rein. Quarz ist am MCP (16MHz) und Pin 3 geht zum takteingang des Mega8

Skragan
28.02.2008, 15:16
Danke, schaue ich mir an ! :)

Skragan
29.02.2008, 13:14
HA !

et löppt ! :)

Nach langem Vergleichen der Unterschiede, umlöten der /CS Leitung (um sich erstmal irrerweise auf BASCOM zu verlassen) und genauer Timinganalyse habe ich es nun geschafft, den Prescaler zu ändern.

Ich habe also die /CS mit /SS verbunden und die manuellen Befehle alle gegen spiout ersetzt. Dann ersteinmal nur einen Resetbefehl gefolgt von der Änderung des CANCTRL gesendet. Dabei fiel mir auf, daß nach dem Resetbefehl tatsächlich der Taktausgang des MCP 10µs aufhörte, d.h. der Befehl wurde verstanden. Fehler 1): Mein nächster Befehl wurde schon gesendet, während der MCP noch im Reset hing. Nach Einbau einer 20µs langen Pause sendete ich dann nacheinander die Bytes für modify, canctrl, mask und Wert - es änderte sich nichts. Dann fiel mir auf, daß Du ein ganzes Array rausschiebst und da kam es mir. Fehler 2) zwischen den einzelnen Bytes, welche zu einem Kommando gehören, wurde /CS immer wieder angehoben. Nachdem ich nun auch mit einem Array alle drei Byte hintereinander rausschiebe, bleibt /CS während der Übertragung unten und siehe da, nach dem letzten Bit ändert sich der Takt von 2 auf 16MHz !

An dieser Stelle ersteinmal recht herzlichen Dank - nun kann ich erstmal mit der restlichen Struktur weitermachen, die Initialisierung korrekt durchführen und dann kommen sicherlich weitere Fragen. Die nächsten Tage werde ich aber wohl genug zu tun haben... :)

Hier noch der entscheidende Codeschnipsel:




'SPI
Config Portb.3 = Output 'MOSI
Config Portb.4 = Input 'MISO
Config Portb.5 = Output 'SCK
Config Portb.2 = Output '/SS - /CS

Config Spi = Hard , Data Order = Msb , Master = Yes , Noss = 0 , Clockrate = 4
Spiinit

'************************************************* ******************************

Print " "
Print "Neustart !"
Print " "
Print "Reset 2515..."
Data_tmp = Cmd_reset
Spiout Data_tmp , 1
Waitus 20
Spi_write_buff(1) = Cmd_write
Spi_write_buff(2) = Canctrl
Spi_write_buff(3) = &B00000100

Spiout Spi_write_buff(1) , 3

Print "done!"
End


Ich muss auch nochmal Vitis Recht geben, der ja zu Anfang dieses Threads sagte, man müsse selber durchblicken. Hätte ein kopierter Code auf Anhieb funktioniert, wüsste ich immernoch nicht, wie der Kram wirklich läuft. Jetzt habe ich deutlich mehr Durchblick und habe ganz sicher (mal wieder) was gelernt.

Skragan
03.03.2008, 09:37
Sodele, also schreiben klappt jetzt ganz hervorragend, ich habe den code erstmal auf das nötigste reduziert. Nachdem ich nun den Prescaler geändert habe, wollte ich das Register CANCTRL auslesen - das klappt irgendwie nicht. Muss ich dann noch irgendwie Nullen senden ? In der Help von SPIIN steht irgendwie so etwas, aber das verstehe ich nun überhaupt nicht. Jedenfalls bleibt die MISO Leitung high. Wenn ich da nochmal um einen Tip bitten dürfte ?



'************************************************* ******************************
'*
'*
'* Projekt: CAN Testboard
'* Zielhardware: CAN Testboard V1.0
'* Stand: 03.03.2008
'*
'* CAN Test10.bas
'*
'************************************************* ******************************

'Inspirationsliste
'
'

'**** Deklarationen ************************************************** **********
$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 8 'default use 10 for the SW stack
$framesize = 24 'default use 40 for the frame space
$regfile = "m8def.dat" 'Chipdefinition
$crystal = 16000000 'Ext. crystal Osc. Speed 16Mhz
$baud = 2400 'Speed COM1

Declare Sub Mcpinit()
Declare Sub Canwrite(byval Reg_add As Byte , Byval Reg_val As Byte)
Declare Sub Canmod(byval Reg_add As Byte , Byval Reg_mask As Byte , Byval Reg_val As Byte)
Declare Function Canread(byval Reg_add As Byte ) As Byte

'**** Portinitialisierung ************************************************** ****
Portb = &H00 'Port B hochohmig schalten
Portc = &H00 'Port C hochohmig schalten
Portd = &H00 'Port D hochohmig schalten

Config Portb.0 = Output 'LED gelb
Led_gelb Alias Portb.0
Led_gelb = 0
Config Portb.1 = Output 'LED rot
Led_rot Alias Portb.1
Led_rot = 0
Config Portb.2 = Input '/SS Eingang
Config Portc = Output 'Aux
Config Pind.2 = Input 'MCP Interrupt MCP2515 /INT
Config Portd.4 = Output 'MCP_CS
Mcp_cs Alias Portd.4
Set Mcp_cs 'low aktiv

Config Portd.6 = Input 'Taster S1
Portd.6 = 1 'Pullup für S1
S1 Alias Pind.6
Config Portd.7 = Input 'Taster S2
Portd.7 = 1 'Pullup für S2
S2 Alias Pind.7

Led_rot = 1 'Resetmerker und Zeit zum ISP Stecker abziehen ;)
Wait 3
Led_rot = 0



'**** Variablen deklarieren ************************************************** **
Const Cmd_read = &H03 'Read Command
Const Cmd_write = &H02 'Write Command
Const Cmd_bitmodify = &H05 'Bit-modify Command
Const Cmd_reset = &HC0 'Reset Command
Const Canctrl = &H0F 'Control Register


Dim Data_tmp As Byte 'Temp Datenbyte
Dim Canstatus As Byte 'Statuswort

Dim Spi_write_buff(3) As Byte 'Sendebuffer
Dim Spi_mod_buff(4) As Byte 'Modbuffer
Dim Spi_read_buff(2) As Byte 'empfangsbuffer


'**** Schnittstellen konfigurieren *********************************************

'SPI
Config Portb.3 = Output 'MOSI
Config Portb.4 = Input 'MISO
Config Portb.5 = Output 'SCK
Config Portb.2 = Output '/SS - /CS

Config Spi = Hard , Data Order = Msb , Master = Yes , Noss = 0 , Clockrate = 4
Spiinit

'************************************************* ******************************

Print " "
Print "Neustart !"
Print " "

Print "Call mcpinit..."

Call Mcpinit()

Print "MCP init done!"

Data_tmp = Canread(canctrl)
Print "Canctrl=" ; Bin(data_tmp)

'************************************************* ******************************
'* Hauptprogramm *
'************************************************* ******************************
Do

If S1 = 0 Then
Led_rot = 1
Waitms 500
Led_rot = 0
End If

If S2 = 0 Then
Led_rot = 1
Waitms 500
Led_rot = 0
End If


Loop

'************************************************* ******************************

Sub Mcpinit()
Local Can_tmp As Byte 'Lokale Variable

Print "Reset 2515..." 'MCP Resetten
Can_tmp = Cmd_reset
Reset Mcp_cs
Waitus 1
Spiout Data_tmp , 1
Waitus 1
Set Mcp_cs
Waitus 20 'Warten bis Reset erledigt, evtl. Abfrage MCP einbauen ?
Print "done!"

Print "change prescaler..."
Spi_write_buff(1) = Cmd_write
Spi_write_buff(2) = Canctrl
Spi_write_buff(3) = &B00000100 'Prescaler auf Takt/1
Reset Mcp_cs
Waitus 1
Spiout Spi_write_buff(1) , 3
Waitus 1
Set Mcp_cs
Print "done!"
End Sub

Sub Canwrite(reg_add , Reg_val) 'Subroutine "schreiben"
Spi_write_buff(1) = Cmd_write
Spi_write_buff(2) = Reg_add
Spi_write_buff(3) = Reg_val
Spiout Spi_write_buff(1) , 3
End Sub

Sub Canmod(reg_add , Reg_mask , Reg_val)
Spi_mod_buff(1) = Cmd_bitmodify
Spi_mod_buff(2) = Reg_add
Spi_mod_buff(3) = Reg_mask
Spi_mod_buff(4) = Reg_val
Spiout Spi_mod_buff(1) , 4
End Sub

Function Canread(reg_add)
Spi_read_buff(1) = Cmd_read
Spi_read_buff(2) = Reg_add
Spiout Spi_read_buff(1) , 2
Spiin Canread , 1
End Function

End

sato
03.03.2008, 11:24
Hallo Leute

Habe immer RS485 benutzt, möchte auch zukünftig CAN benutzen doch habe überhaupt keine Kentnisse darüber, was muss ich zuerst lernen und wo kann ich Tutorials, einfache Bascom Beispielcode herkriegen, am liebsten auf deutsch

Danke

Gruss

Sato

Vitis
03.03.2008, 22:38
Basic gibts nicht auf deutsch ... gibt nur englische Syntax (Schreibweise)

Prog (mit enlischer Basic-Syntax) siehe hier:
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=24234&postdays=0&postorder=asc&start=44

Skragan
04.03.2008, 07:53
Aber zu meinem Problem weiß niemand was ? :)

Skragan
04.03.2008, 08:45
Sendet der Befehl SPIIN auch automatisch das notwendige Taktsignal ? Oder ist es dann besser, mit SPIMOVE zu arbeiten ?

Sub Canread(reg_add)
Spi_read_buff(1) = Cmd_read
Spi_read_buff(2) = Reg_add
Spiout Spi_read_buff(1) , 2

Spi_input(1) = Spimove(data_spare) 'Spiin Spi_input(1) , 2

End Sub

Aber es läuft trotzdem nicht, ich empfange einfach nichts...

Vitis
04.03.2008, 08:57
Beim Highlevelbefehl von Bascom kann ich keine Auskunft geben,
da ich die Hardwarenahe Programmierung bevorzuge,
sprich ich schreibe direkt ins SPDR Register.
Dabei ist es so, dass ich dieses abwechselnd lese und schreibe.
Der Hintergrund ist, dass nur wenn die SPI sendet der Takt
über CLK geht und die angehängte Hardware nur dann
ihre Daten senden kann.
Das läuft dann so ab, dass ich ne 0 (Null) ins SPDR schreibe,
warte bis die Übertragung beendet ist und das empfangene
Byte dann im SPDR steht. dieses dann herauskopiere und
die nächste 0 schreibe usw. usw. bis die gewünschte zahl
an Bytes rüber ist.
Sorry, aber Dein Problem scheint mir entweder

a) in der Initialisierung der SPI oder
b) in der Hardware zu liegen.

Haste die Bausteine mal getauscht um zu sehen ob nicht der MCP oder der
ATMega ne Macke haben?

Beim SPIIN scheint bascom nullen zu senden und die emfangenen werte
dann in Variablen zu speichern, beim SPIMOVE kann man gleichzeitig
Daten senden und die Rückgabewerte auslesen.

Ach so, ich initialisiere die SPI über:
config pin_mcp_reset = output
config pin_mcp_select = output
config SPI_mosi = output
config SPI_clk = output
config SPI_miso = input
SPCR=&B01010010

Skragan
04.03.2008, 14:40
Ich bin ja so bescheuert... ich hatte natürlich die Verbindung von /CS zu /SS wieder gelöscht und meine originale Portverbindung wieder erstellt. Und das manuelle setzen von MCP_CS hatte ich natürlich vergessen. Nevermind.... -.-

Nun muss ich nur noch die Timings etc. in den Griff bekommen, er antworter jetzt und schickt mir beim auslesen von CANCTRL eine &04, welche ich ja auch hineingeschrieben habe. Jetzt muss ich erstmal wieder weiter rumprobieren, aber ich denke, ich bekomme es in den Griff...

Skragan
04.03.2008, 16:39
Nun, die Fragen werden ja immer detailiierter... ich kann nun korrekt Register auslesen und beschreiben, zumindest das Register CANCTRL. Mit diesen Subs:


Sub Mcpinit()
Local Can_tmp As Byte 'Lokale Variable

Print "Reset 2515..." 'MCP Resetten
Can_tmp = Cmd_reset
Reset Mcp_cs
Waitus 1
Spiout Data_tmp , 1
Waitus 1
Set Mcp_cs
Waitus 20 'Warten bis Reset erledigt, evtl. Abfrage MCP einbauen ?
Print "done!"

'( Print "change prescaler..."
Spi_write_buff(1) = Cmd_write
Spi_write_buff(2) = Canctrl
Spi_write_buff(3) = &B00000100 'Prescaler CLKOUT auf Takt/1
Reset Mcp_cs
Waitus 1
Spiout Spi_write_buff(1) , 3
Waitus 1
Set Mcp_cs
Print "done!"
')
Set Trigger
Canwrite Cnf1 , &B00000100 'forum &B00010011 'selbst:&B00000100
Reset Trigger
Canwrite Cnf2 , &B11100010 'forum &B10010000 'selbst:&B11100010 '
Canwrite Cnf3 , &B00000011 '&B00000010 'selbst: &B00000011 '
Canwrite Caninte , &B00000011 'Interrupt einstellen
Canwrite Rxb0ctrl , &B01100000 'Buffer 0: Empfangen aller Nachrichten
Canwrite Rxb1ctrl , &B01100000 'Buffer 1: Empfang aller Nachrichten

Canwrite Rxm0sidh , 0 'Kein Filter, Empfängeradresse Null
Canwrite Rxm0sidl , 0
Canwrite Rxm0eid8 , 0
Canwrite Rxm0eid0 , 0
Canwrite Rxm1sidh , 0
Canwrite Rxm1sidl , 0
Canwrite Rxm1eid8 , 0
Canwrite Rxm1eid0 , 0

Canwrite Bfpctrl , 0 'Deaktivieren der RXnBF Pins (High Impedance)
Canwrite Txrtsctrl , 0 'TXnRTS Bits als Inputs schalten
Canmod Canctrl , &B11100000 , &B00000000 'Device zurück in den normalen Modus versetzen
End Sub

Sub Canwrite(reg_add , Reg_val) 'Subroutine "schreiben"
Print Cmd_write
Print Reg_add
Print Reg_val
Spi_write_buff(1) = Cmd_write
Spi_write_buff(2) = Reg_add
Spi_write_buff(3) = Reg_val
Reset Mcp_cs
Waitus 1
Spiout Spi_write_buff(1) , 3
Waitus 1
Set Mcp_cs
End Sub

Mit dem ausgeklammerten Teil ändere ich den Prescaler. Nun soll ja auch der Rest der Konfiguration gemacht werden, dort schreibt er aber immer Nullen in die Register. Ich habe daraufhin in der Sub Canwrite die übergebenen Variablen ausgeben lassen, Reg_val wird immer mit Null ausgegeben, also offenbar nicht richtig an die Subroutine übergeben - woran kann das liegen ? Die anderen Variablen (Reg_add etc.) kommen richtig an...

Vitis
04.03.2008, 18:13
solche Dinge kommen vor wenn Stack und Frame zu klein
sind ... probiers mal mit größeren Werten dafür

ääääääääähhhhhhmmmmmm ... falscher Fehler.
Es wird wohl daran liegen, dass Du den CANCTRL nicht
in den Konfigurationsmodus versetzt.
Dann frisst er nämlich keine Konfigurationsänderung ;)

Skragan
05.03.2008, 07:40
Ist er denn nicht nach dem Reset automatisch im Configmodus ? So stand es doch unter Punkt 10, oder ? Ich schaue mir das gleich mal an !

Pascal
05.03.2008, 07:57
Das stimmt, nach dem Reset ist der Chip erstmal im Konfigurationsmodus.

Vitis
05.03.2008, 08:58
das mag wohl sein, wenn du aber bit 7 bis 5 von canctral auf 0 setzt
bist du aus dem config-mode raus

edit: sorry, hab die Klammer übersehen ...

ich würds dennoch mal mit dem config Mode probieren.

Skragan
05.03.2008, 09:07
:) ja, ich setze mich gleich nochmal dran... kann eigentlich nur noch eine Kleinigkeit sein.

Skragan
05.03.2008, 09:13
Also, wenn ich die Register manuell schreibe, läufts. Aber sobald ich die Sub CANWRITE benutze, ist Reg_val immer null ?! Die Variable wird nicht übergeben...

/edit/

Ich habe es nochmals getestet. Schreibe ich CNF1 manuell, d.h. ohne nutzen der Subroutine, funktioniert es bestens, ich lese den geschriebenen Wert wieder aus. Sobald ich die Subroutine verwende, ist immer Reg_val &H00, egal, welchen Wert ich übergebe. Nach mehrfachem durchlesen und vergleichen checke ich einfach nicht, warum das so ist. Die anderen Variablen werden korrekt übergeben ....

Skragan
05.03.2008, 09:40
Ja, Problem gefunden. HWStack und Framesize zu klein, wie Du sagtest...

Skragan
05.03.2008, 14:25
Goil ! Nun kann ich bereits zwischen zwei Boards Nachrichten hin- und herschicken und sie empfangen sogar das richtige Byte *froi* ganz automatisch mit ISR.

Nun fehlt eigentlich nur noch die Ausmaskierung und Identifier, die sind zur Zeit noch alle disabled.

Mit
Canwrite Bfpctrl , &B00001111 'RXnBF Pins Buffer Full Anzeige

müsste man doch eigentliche eine Anzeige an D4 (mein Schaltplan) bekommen, wenn ein Buffer voll ist, oder ?

Ansonsten hier mal der aktuelle Stand, wie er testhalber läuft. Allen nochmals herzlichen Dank soweit !

Vitis
05.03.2008, 14:53
Bei ID und Maske ist zu beachten, welche Bits als ID-Bits verwendet werden.
Das sind mitnichten bit 0-7 usw. die sind lustig übers Register verteilt ...

Nur mal noch n Einwurf ... ist n häufiger Stolperstein.
Also der Befehl "shift left" ist Dein Freund dabei.

Das mit dem Flag setzen in der ISR haste schön gemacht ...

"Sie haben Post ..." :)

Skragan
05.03.2008, 16:46
Falls Feitzi noch mitliest: Deine Leseroutine kannst Du vielleicht etwas optimieren, so wie hier:



Dlc0 = Canread(rxb0dlc)
Print "RxB0DLC=" ; Bin(canread(rxb0dlc))
Print "RxB0CTRL=" ; Bin(canread(rxb0ctrl))
Spi_read_buff(1) = Cmd_read
Spi_read_buff(2) = Rxb0d0
Reset Mcp_cs
Waitus 1
Spiout Spi_read_buff(1) , 2
Spiin Can_rxd_data(1) , Dlc0
Waitus 1
Set Mcp_cs
For N = 1 To Dlc0
M = N - 1
Print "0D" ; M ; "=" ; Can_rxd_data(n) ; "-"
Next N
Canmod Canintf , &B00000001 , &B00000000
Canmod Eflg , &B01000000 , &B00000000


natürlich noch ohne Fehlerauswertung, aber deutlich übersichtlicher. Diese Routine liest so lange Register aus, wie der DLC lang ist und legt sie automatisch in einem maximal 8 Byte langen Array ab. Braucht deutlich weniger Hilfsvariablen (eine nur zur Anzeige) und eine deutlich kleinere Schleife - und diese auch nur zum Anzeigen.

Skragan
06.03.2008, 08:54
Nun habe ich eine Senderoutine, die abwechselnd eine Nachricht mit sidl=00100000 und sidl=00000000 sendet. Der Empfänger soll nur die Nachrichten mit sidl=00100000 empfangen. Boh - aber er empfängt noch beide Nachrichten:


Canwrite Caninte , &B00000011 'Interrupt einstellen
Canwrite Rxb0ctrl , &B00100100 'Buffer 0: Empfangen aller Nachrichten
Canwrite Rxb1ctrl , &B00100000 'Buffer 1: Empfang aller Nachrichten

Canwrite Rxm0sidh , 0 'Kein Filter, Empfängeradresse Null
Canwrite Rxm0sidl , &B00100000
Canwrite Rxm0eid8 , 0
Canwrite Rxm0eid0 , 0
Canwrite Rxm1sidh , 0
Canwrite Rxm1sidl , &B00100000
Canwrite Rxm1eid8 , 0
Canwrite Rxm1eid0 , 0

Canwrite Rxf0sidl , &B00100000
Canwrite Rxf1sidl , &B00100000
Canwrite Rxf2sidl , &B00100000
Canwrite Rxf3sidl , &B00100000
Canwrite Rxf4sidl , &B00100000


Mit dieser Config sollte die Maske und auch alle Filter nur durchlassen, was sidl=00100000 hat, oder was habe ich da nicht geblickt ? Kommt jetzt genau das, was Du meintest ?

Skragan
10.03.2008, 14:26
Vitis,

kannst Du mir nochmal sagen, wo ich dazu etwas finde ? Ich habe nun Sender und Empfänger, wenn ich per Dipschalter z.B. SIDL=00001111 einstelle, zeigt der Empfänger an, daß die SIDL 00001011 ist ? Ich bin verwirrt....

Skragan
12.03.2008, 11:48
arghs... Nun, ich hatte auch die völlig falschen Bits in SIDL eingestellt, nun überträgt er immer richtig. Jetzt muss ich es nur noch hinbekommen, daß er nur eine bestimmte Nachricht empfängt, aber irgendwie habe ich die Filter noch nicht richtig eingestellt:

mit radress=00100000

Canwrite Rxb0sidl , Radress
Canwrite Rxf0sidl , Radress
Canwrite Rxm0sidl , Radress

sollte jetzt ein so konfigurierter client nur Nachrichten mit SIDL 00100000 empfangen, oder nicht ? Jedenfalls werden noch alle Nachrichten empfangen, rollover ist ausgeschaltet.

Stromi
14.03.2008, 11:34
Auszug aus einer CAN-Bus-Beschreibung ( http://www.me-systeme.de/canbus.html ):

Prinzip des Datenaustausches im CAN Netzwerk

Bei der Datenübertragung in einem CAN Bus werden keine Knoten adressiert, sondern der Inhalt einer Nachricht (z.B. Drehzahl oder Motortemperatur) wird durch einen eindeutigen Identifier gekennzeichnet.

Neben der Inhaltskennzeichnung legt der Identifier auch die Priorität der Nachricht fest.

Mit der dann folgenden Akzeptanzprüfung stellen alle Stationen nach korrektem Empfang der Nachricht anhand des Identifiers fest, ob die empfangenen Daten für sie relevant sind oder nicht. Durch die inhaltsbezogene Adressierung wird eine hohe Flexibilität erreicht: Es lassen sich sehr einfach Stationen zum bestehenden CAN-Netz hinzufügen.

Außerdem ergibt sich die Möglichkeit des Multicasting: Eine Nachricht kann von mehreren Teilnehmern gleichzeitig empfangen und ausgewertet werden. Messgrößen, die von mehreren Steuergeräten als Information benötigt werden, können über das CAN-Netz so verteilt werden, dass nicht jedes Steuergerät einen eigenen Sensor benötigt.

Ev kannst du die Lesung nicht selektieren?
Geht sonst alles?

Skragan
19.03.2008, 13:24
Ansonsten geht alles. Der Identifier wird ja auch korrekt gesendet, nur habe ich offenbar noch ein Problem mit der Erkennung, ob die Nachricht nun für den Empfänger wichtig war und somit empfangen wird... Ich lese mich da gerade noch tiefer rein, aber noch checke ich das nicht...

Stromi
19.03.2008, 14:27
Hallo Alex,
wenn alles soweit funktioniert, würdest du den Code hier reinstellen? Interessiert nicht nur mich wie es scheint.
Manche gute Programmmierer könnten eine Lib draus machen.
Ich bin schon aus Frust auf MBasic bei CAN umgestiegen, da gibt es eine Lib. Und Diese ist easy zu handeln.
Ev. könntest du den Code bei Mscelec abgeben, vielleicht macht er was draus, wäre doch für alle Bascom-Anwender gut.
Vielen Dank

Skragan
19.03.2008, 14:43
Kann ich machen, das ist ja nur ein Testboard und somit nicht schlimm. Ich poste dann Schaltplan etc.

Ich muss halt nur noch die "Adressierung" bzw. Nachrichtenselektion richtig hinbekommen und den Code verschönern...

Stromi
19.03.2008, 15:11
Kann ich machen, das ist ja nur ein Testboard und somit nicht schlimm. Ich poste dann Schaltplan etc.

Ich muss halt nur noch die "Adressierung" bzw. Nachrichtenselektion richtig hinbekommen und den Code verschönern...

Nun, lass dir doch helfen.
Wenn der Code da ist, wird der eine oder andere es sehen können, wo man was selektieren kann.
Verschönern kann man ihn wenn er fertig ist.
Guß nach Oldenburg, BFE-Stadt, Niedersachsen ?

Skragan
19.03.2008, 16:18
Aber klar - dann halt schon "unfertig" :)

Ja, Oldenburg - eher Rastede :)

feitzi
23.03.2008, 05:52
Hallo
Ja feitzi liest immer wiedermal mit
Die Sende und empfangsrutiene hab ich optimiert (schon vor längerer Zeit)
Ein Tip für die Identiferzuortnung:
Ich vergebe jeder Platiene eine "Knotennummer" zum Beispiel gibt es bei mir Knoten 1, 2, 3, 4, und 40. und dann noch genau deffinierte Identifer für Digitale bzw Analoge Informationen.
Siehe Anhang (die ID´s sind in HEX). Sobald ich Zeit habe, werde ich mein derzeitiges CAN Programm dokumentieren, und hier in´s Forum stellen.

Gruß feitzi

Skragan
25.03.2008, 07:39
Hi feitzi,

es wäre super, wenn Du das nochmal etwas ausführlicher erklären könntest - das verstehe ich noch absolut nicht.

Gruß Alex

feitzi
25.03.2008, 14:37
Hallo

Ich hab mein derzeitiges Programm angehängt.
Das Programm "MegaCAN-V76" ist ein Standardprogramm, ich verwende dieses Modul zur Erweiterung eines Industiellen Heizungsreglers.
Im Programm "CAN Mega16" hab ich auf das wichtigste Abgespekt. Da ist auch eine Erklärung zu der ID Verteilung.

hoffe ich konnte helfen

Gruß feitzi

elkokiller
06.07.2008, 08:09
Hallo,

jetzt wo die CAN Programme über Bascom so langsam zum laufen kommen möchte ich mal eine Frage zu den verschiedenen Konfigurationsmöglichkeiten stellen.

Wie muss die Konfig aussehen wenn der Sender auf eine Bestätigung des Empfängers bekommen soll?

Duesentrieb
12.07.2008, 19:13
Hallo,

ich habe ein Problem mit meinem CAN-Bus-Experiment.

Ich habe drei Knoten an meinem Bus.
Sendet einer der Knoten, so kommt die Nachricht richtig bei beiden Empfängern an.
Sendet ein weiterer Knoten, so kommt dessen Nachricht nur noch bei dem an, der bisher noch nichts gesendet hat.
Hat jeder einmal eine Nachricht versendet, so bemerken jeweils die beiden verbleibenden Empfänger dass was auf dem Bus ist, sie geben aber nur noch ihren eigen Speicher aus.

Offensichtlich wirde der eigene Speicher nach dem Senden nicht gelöscht.

Kann mir jemand sagen was ich falsch gemacht habe?


Hier mal die wichtigsten Ausschnitte meines Codes:


********MCP2515 Initialisieren************************************ ****

Mcp2515_init:

'MCP2515 per Software Reset zurücksetzen
Mcphilf = Spi_reset
Reset Css
Waitus 10
Spdr = Mcphilf
Do
Loop Until Spsr.spif = 1
Waitus 10
Set Css

'einstellen des Bit Timings
'CNF1 &H07==>125 kbit/s &H13==>50 kbit/s
Mcp2515_write_register Cnf1 , &H13
Mcp2515_write_register Cnf2 , &H90
Mcp2515_write_register Cnf3 , &H02


'Interrupt einstellen
Mcp2515_write_register Caninte , &B00000011

Mcp2515_write_register Rxb0ctrl , &B01100000

Mcp2515_write_register Rxb1ctrl , &B01100000



'************************************************* ***************************
'****************** Filter und Maske einstellen ********************
'************************************************* ***************************

'Maske setzen - alle Bits auf "1" führen zu einem eindeutigen Filtern einer ID
Mcp2515_write_register Rxm0sidh , &B00111111 '
Mcp2515_write_register Rxm0sidl , &B11100000 '
Mcp2515_write_register Rxm1sidh , &B00111111 '
Mcp2515_write_register Rxm1sidl , &B11100000 '

'Filter setzen "25"
Mcp2515_write_register Rxf0sidh , &B00000011
Mcp2515_write_register Rxf0sidl , &B00100000
Mcp2515_write_register Rxf1sidh , &B00000011
Mcp2515_write_register Rxf1sidl , &B00100000

'************************************************* ***************************
'************************************************* ***************************
'************************************************* ***************************



'Einstellen der Pin Funktionen
'Deaktivieren der Pins RXnBF Pins (High Impedance State)
Mcp2515_write_register Bfpctrl , 0

'TXnRTS Bits als Input schalten
Mcp2515_write_register Txrtsctrl , 0


'Device zurück in den normalen Modus versetzen
Mcp2515_bitmodify Canctrl , &B11100000 , &B00000000


Return



'*************************************************

Send_buffer0:

'Priorität einstellen
Mcp2515_bitmodify Txb0ctrl , &B00000011 , &B00000011

' Bit 7 Unimplemented: Lesen als'0 '
' Bit 6 ABTF: Nachricht Aborted Flag Bit -
' 1 = Nachricht wurde abgebrochen
' 0 = Nachricht erfolgreich abgeschlossene Übertragung
' Bit 5 MLOA: Nachricht Lost Arbitration Bit -
' 1 = Nachricht verloren, Schiedsverfahren gleichzeitig gesendet
' 0 = Nachricht nicht verloren, während Schiedsverfahren gesendet
' Bit 4 TXERR: Übermittlung Bit-Fehler erkannt
' 1 = Ein Bus-Fehler ist aufgetreten, während die Nachricht übermittelt wurde,
' 0 = es ist keine Bus-Fehler aufgetreten, während die Nachricht übermittelt wurde,
' Bit 3 TXREQ: Nachricht Transmit Request-Bit -
' 1 = Buffer ist derzeit zur Übertragung anhängig
' (MCU setzt dieses Bit auf Anfrage Nachricht übertragen werden - Bit wird automatisch gelöscht, wenn
' Wird die Nachricht gesendet)
' 0 = Buffer ist derzeit nicht zur Übertragung anhängig
' (MCU kann dieses Bit klar um eine Nachricht abbrechen)
' Unimplemented
' Bit 2: Lesen als'0 '
' Bit 1-0 TXP: Sendepuffer Priority
' 11 = Höchste Priorität
' 10 = High Intermediate Priority
' 11 = Low Intermediate Priority
' 00 = Tiefste Message Priority

'Standard ID einstellen
Mcp2515_write_register Txb0sidh , Idh ' Absenderadresse setzen
Mcp2515_write_register Txb0sidl , Idl ' Absenderadresse setzen
'Nachrichtenlänge einstellen (DFL)
Mcp2515_write_register Txb0dlc , Dfl
'Daten
Mcp2515_write_register Txb0d0 , Db0(1)
Mcp2515_write_register Txb0d1 , Db0(2)
Mcp2515_write_register Txb0d2 , Db0(3)
Mcp2515_write_register Txb0d3 , Db0(4)
Mcp2515_write_register Txb0d4 , Db0(5)
Mcp2515_write_register Txb0d5 , Db0(6)
Mcp2515_write_register Txb0d6 , Db0(7)
Mcp2515_write_register Txb0d7 , Db0(8)
'nachricht versenden
Reset Css
Waitus 10
Mcphilf = Spi_rts0
Spdr = Mcphilf
Do
Loop Until Spsr.spif = 1
Waitus 10
Set Css
' Print "gesendet Buffer-0"
Waitms 50
Return


Wäre klasse wenn mir jemand was sagen kann. Vielleicht hilft es ja auch anderen

cni
03.12.2008, 21:53
Ist auch daran gedacht/erweitert werden den CAN Bus im Automobil abzufragen?


Ja, das würde mich auch interessieren!

T.J.
04.12.2008, 10:46
In den bisherigen sachen kann ich kein Fehler finden. Wo ist die routine des Empfangens?

Den CAN im KFZ abzufragen habe ich auch irgendwann mal vor. Ist ja soweit kein Problem nur man kennt die IDs und die Nachrichtendefinitionen nicht ;)

patti16
04.12.2008, 19:16
Die Protokolle müsste man finden da diese genormt sind. Wenn du es testen willst mach die aber an ältern Can Fahrzeugen da die neuen Quasi Abschalten wenn jemand den Bus abhört.

T.J.
04.12.2008, 19:49
welche Protokolle sind denn genormt? Davon wüsste ich! Und wer schaltet denn ab, wenn du mit listen ans Gateway gehst?
An Diag CAN kannst natürlich net gehen, da musst du ja die ganze Kommunikation aufbauen. Da geht eh nur die Hälfte im Stand!

Aber jetzt :-#

elkokiller
13.01.2009, 17:47
Hallo,

hat schon mal jemand einen Mega32 an den MCP2515 angeschlossen und zum Laufen gebracht?

patti16
13.01.2009, 20:12
hallo t.j.,

ich weiß es nicht genau die lehrer sagen das in der Schule mehr Infos habe ich auch nicht darüber.

Im Stand geht alles ... ausserdem musste schon schauen welchen Can du nimmst es gibt ja verschiedene.

cni
15.01.2009, 22:20
Welche verschiedene CAN Busse gibt es denn im Auto?

patti16
15.01.2009, 22:27
z.b Can Bus Antrieb, Can Bus Comfort,

jedoch bezieht sich das ganze nur auf die Geschwindigkeit des Bussystems und auf die Proritäten.

Duesentrieb
16.01.2009, 14:39
Hi,

die Sache mit dem Mega 32 am CAN interessiert mich auch. Bisher habe ich alles mit nem einfachen Mega 8 gemacht.
An den Fuse kann es doch nicht hängen!

Liegt es vielleicht an der Programmierung der Register?

patti16
16.01.2009, 14:55
Sorry diskutieren oder streiten möchte ich mich nicht wollte es nur gesagt haben.


intressieren tut mich das thema auch.

elkokiller
16.01.2009, 18:10
Habt ihr eure Can Busse alle mit nur mit Mega8 gebaut?
Ist hier keiner mal nen Schritt weiter gegangen?

T.J.
16.01.2009, 18:50
wie weit meinst du? Ich habe PIC18F2685, Mega8, AT90CAN64/32/128 erfolgreich in Betrieb. Im KFZ gibt es 4 wichtige. Was die Prioritäten angeht liegt das nur an den Definitionen.

elkokiller
16.01.2009, 19:18
na ja, ich meine auf Basis der Mega's. Beim 8er läufts super. nur bei meinem 32er geht nichts.
Den Pic kann ich nicht einschätzen und dass es beim AT90CAN.. läuft ist auch klar.

Aber wie so geht es beim 32er nicht?
Ich ahbe eine, zum Mega8 identtische Schaltung aufgebaut und das selbe Programm eingespielt. Aber es geht nichts!

Vitis
17.01.2009, 09:42
ob M8 oder M32 ist dem MCP herzlich wurst,
kann nur auf Fehler beim Transfer oder
falsche Fuses oder Beschaltungsfehler beruhen
wenn der Dingsda nix macht.

elkokiller
17.01.2009, 11:25
kannst du mir sagen welche Fuse damit was zu tun haben?!
Wenn ich sie doch so eingestellt habe wie beim Mega8 muss es doch gehen, oder?

T.J.
17.01.2009, 15:08
na ja, ich meine auf Basis der Mega's. Beim 8er läufts super. nur bei meinem 32er geht nichts.
Den Pic kann ich nicht einschätzen und dass es beim AT90CAN.. läuft ist auch klar.

Aber wie so geht es beim 32er nicht?
Ich ahbe eine, zum Mega8 identtische Schaltung aufgebaut und das selbe Programm eingespielt. Aber es geht nichts!

das macht keinen Unterschied. Ich habe meine Schaltung generell mit nem 32er getestet und dann einen 8er auf die Platine gelötet. Da hast du irgendwo n fehler oder einen HW Unterschied der beiden Megas nicht beachtet.

elkokiller
17.01.2009, 21:03
Hallo T.J.,

dann muss es bei mir an der HW liegen (das Programm läuft sonst ja).
Liegt es vielleicht an den genutzen Anschlüssen?
Fällt dir im Schaltplan etwas auf? Ich habe ihn auf das Wesentliche gekürzt:

elkokiller
17.01.2009, 22:54
ist es möglich dass es an meiner Resetschaltung liegt?
Ich habe die Resets beider IC's verbunden und über einen Widerstand auf +5V gelegt.
Der Taster, im Schaltplan nicht mehr enthalten, geht auf Masse.

Ich habe nähmich festgestellt, dass die Schaltung doch geht wenn ich die Spannung kompl. wegnehme und wieder anlege.
Über den Resetschalter hängt sich das Programm bei Neustart auf!

T.J.
18.01.2009, 11:47
Hm, nein da fällt mir nix auf. Miso Mosi und SCk eben. Mehr brauchts ja nicht! Ist ja sehr seltsam. gerade da und beim CS sollte es zum mega32 ja keinen Unterschied machen :)

elkokiller
08.04.2009, 08:07
Hallo zusammen,

nachdem ich das Programm noch mal von grund auf neu geschrieben habe bin ich mehr oder weniger zufällig auf die Ursache für mein Problem (M32 und MCP2515) gestoßen!

So ganz nachvollziehen kann ich es nicht und hoffe auf eure Unterstützung:
Ich habe neben dem CAN Controller auch ein LCD Display in der 4 Bit Variante angeschlossen (separate Ports am M32).
Ohne die Displaykonfig läuft das Programm, in dem neben dem MCP2515 auch weitere I/O's beschaltet sind problemlos.
Nehme ich die Display Konfig hinzu, hängt sich das Programm beim Initialisieren des MCP auf!

Jetz bin ich der Verzweiflung nahe. Die beiden Bausteine und ihre Ports haben nichts miteinander zu tun und trotzdem geht entweder das eine oder das andere.

Was kann ich jetzt noch tun?

Vitis
09.04.2009, 06:55
seltsam, sollte normal nicht sein, ist wohl mal wieder n Baascom Bug ...
oder ein Initialisierungsfehler im Programm ... müsste man aber das Listing
sehen dafür.
Im Extremfall müsstest Du dann halt die Init vom LCD von Hand
machen oder gar die LCD Ausgaberoutinen manuell machen.

elkokiller
09.04.2009, 22:44
ich bin selbst noch am zweifeln ob es daran liegen kann!

Ich habe jetzt so viel an dem Programm rumgebastelt dass es selbst ohne LCD nicht mehr läuft.
Bisher starte die Initialisierung wenigstens, jetzt hängt selbst sie sich auf und ich muss die Spannung kompl. wegnehmen.

Ich habe meinen Code jetzt mal auf das wesentliche gekürzt.
Hat jemand ne Idee wo hier der Fehler steckt?



$regfile = "m32def.dat"
$crystal = 7372800
$baud = 9600


$hwstack = 32
$swstack = 8
$framesize = 24


Config Spi = Hard , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Noss = 1 , Clockrate = 16
Spiinit



Dim Mcphilf As Byte

Dim Id As Integer
Dim Idh As Byte
Dim Idl As Byte
Dim Dfl As Byte
Dim Idi As Byte
Dim Canin As Byte
Dim Db0(8) As Byte
Dim Canstat As Byte

Dim T As Integer
Dim L As Byte

Dim Verify As Byte
Verify = 10

Dim Hilf1 As Word
Dim Hilf2 As Word
Dim Absender As Byte


Const Spi_reset = &HC0
Const Spi_write = &H02
Const Spi_read = &H03
Const Spi_rts0 = &H81
Const Spi_rts1 = &H82
Const Spi_rts2 = &H84
Const Spi_read_status = &HA0
Const Spi_bit_modify = &H05

Const Rxb0ctrl = &H60
Const Rxb1ctrl = &H70

Const Rxm0sidh = &H20
Const Rxm0sidl = &H21
Const Rxm1sidh = &H24
Const Rxm1sidl = &H25

Const Rxf0sidh = &H00
Const Rxf0sidl = &H01
Const Rxf1sidh = &H04
Const Rxf1sidl = &H05


Const Bfpctrl = &H0C
Const Txrtsctrl = &H0D
Const Canctrl = &H0F

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 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

Const Txb1ctrl = &H40 ' Transmit Buffer 1 Control Register
Const Txb1sidh = &H41 ' Transmit Buffer 1 Std Identifier High
Const Txb1sidl = &H42 ' Transmit Buffer 1 Std Identifier Low
Const Txb1dlc = &H45 ' Transmit Buffer 1 Data Length Code
Const Txb1d0 = &H46 ' Transmit Buffer 1 Data Byte 0
Const Txb1d1 = &H47 ' Transmit Buffer 1 Data Byte 1
Const Txb1d2 = &H48 ' Transmit Buffer 1 Data Byte 2
Const Txb1d3 = &H49 ' Transmit Buffer 1 Data Byte 3
Const Txb1d4 = &H4A ' Transmit Buffer 1 Data Byte 4
Const Txb1d5 = &H4B ' Transmit Buffer 1 Data Byte 5
Const Txb1d6 = &H4C ' Transmit Buffer 1 Data Byte 6
Const Txb1d7 = &H4D ' Transmit Buffer 1 Data Byte 7

Const Txb2ctrl = &H50 ' Transmit Buffer 2 Control Register
Const Txb2sidh = &H51 ' Transmit Buffer 2 Std Identifier High
Const Txb2sidl = &H52 ' Transmit Buffer 2 Std Identifier Low
Const Txb2dlc = &H55 ' Transmit Buffer 2 Data Length Code
Const Txb2d0 = &H56 ' Transmit Buffer 2 Data Byte 0
Const Txb2d1 = &H57 ' Transmit Buffer 2 Data Byte 1
Const Txb2d2 = &H58 ' Transmit Buffer 2 Data Byte 2
Const Txb2d3 = &H59 ' Transmit Buffer 2 Data Byte 3
Const Txb2d4 = &H5A ' Transmit Buffer 2 Data Byte 4
Const Txb2d5 = &H5B ' Transmit Buffer 2 Data Byte 5
Const Txb2d6 = &H5C ' Transmit Buffer 2 Data Byte 6
Const Txb2d7 = &H5D ' Transmit Buffer 2 Data Byte 7

Const Rxb0sidh = &H61
Const Rxb0sidl = &H62
Const Rxb0dlc = &H65
Const Rxb1sidh = &H71
Const Rxb1sidl = &H72
Const Rxb1dlc = &H75


Const Cnf1 = &H2A
Const Cnf2 = &H29
Const Cnf3 = &H28
Const Caninte = &H2B
Const Canintf = &H2C


Declare Sub Mcp2515_write_register(byval Adress As Byte , Byval Daten As Byte)
Declare Sub Mcp2515_read_register(byval Adress As Byte )
Declare Sub Mcp2515_bitmodify(byval Reg_add As Byte , Byval Reg_mask As Byte , Byval Reg_val As Byte)



Config Pind.3 = Input
Mcpint Alias Pind.3 ' Mcpint Alias Pind.3
Css Alias Portd.4
Config Css = Output


Set Css
Wait 1

Absender = 106
Id = 105


Gosub Mcp2515_init
Print "init o.k."

Idi = 10



'Aktivmeldung an CAN Bus

Gosub Status
Gosub Senden


Do

If Mcpint = 0 Then Gosub Mcpempfang


Loop


'************************************************* ****************************************
'********* $include "Can_config_V1_beschriftet.bas" **************************************
'************************************************* ****************************************

Status:

Print "Status: Senden - " ; Mcpint

If Mcpint = 1 Then



Gosub Senden


Else

Print "MCP Pin=0"

End If



Mcp2515_read_register Canintf 'Spi_rx_status

Canstat = Canin

Print "CANINTF: " ; Canstat


Mcp2515_bitmodify Canctrl , &B11101000 , &B00001000



Waitms 500
Return


Senden:

Print "Senden: Mcp2515_read_register Txb0ctrl "
Mcp2515_read_register Txb0ctrl '&HA0
Print "Senden: Mcp2515_read_register Txb0ctrl o.k. "

'ID auf SIDL und SIDH "verteilen"

Hilf1 = Id / 8
Idh = Hilf1
Hilf1 = Idh * 8
Hilf1 = Id - Hilf1
Hilf1 = Hilf1 * 32
Idl = Hilf1

Print Id

Print "SPI_read_Status0: " ; Canin
If Canin.3 = 0 Then Gosub Send_buffer0
Mcp2515_read_register Txb1ctrl '&HA0
Print "SPI_read_Status1: " ; Canin



Print "Senden-Ende"

Return

'********senden mit Buffer 0****************************************

Send_buffer0:

Print "Send_buffer0:"
'Priorität einstellen
Mcp2515_bitmodify Txb0ctrl , &B00000011 , &B00000011


'Standard ID einstellen
Mcp2515_write_register Txb0sidh , Idh ' Absenderadresse setzen
Mcp2515_write_register Txb0sidl , Idl ' Absenderadresse setzen
'Nachrichtenlänge einstellen (DFL)
Mcp2515_write_register Txb0dlc , Dfl
'Daten
Mcp2515_write_register Txb0d0 , Db0(1)
Mcp2515_write_register Txb0d1 , Db0(2)
Mcp2515_write_register Txb0d2 , Db0(3)
Mcp2515_write_register Txb0d3 , Db0(4)
Mcp2515_write_register Txb0d4 , Db0(5)
Mcp2515_write_register Txb0d5 , Db0(6)
Mcp2515_write_register Txb0d6 , Db0(7)
Mcp2515_write_register Txb0d7 , Db0(8)
'nachricht versenden
Reset Css
Waitus 10
Mcphilf = Spi_rts0
Spdr = Mcphilf
Do
Loop Until Spsr.spif = 1
Waitus 10
Set Css
Print "gesendet Buffer-0"
Waitms 50
Return

'********senden mit Buffer 1****************************************
Send_buffer1:

Mcp2515_bitmodify Txb1ctrl , &B00000011 , &B00000011


'Standard ID einstellen
Mcp2515_write_register Txb1sidh , Idh
Mcp2515_write_register Txb1sidl , Idl
'Nachrichtenlänge einstellen (DFL)
Mcp2515_write_register Txb1dlc , Dfl
'Daten
Mcp2515_write_register Txb1d0 , Db0(1)
Mcp2515_write_register Txb1d1 , Db0(2)
Mcp2515_write_register Txb1d2 , Db0(3)
Mcp2515_write_register Txb1d3 , Db0(4)
Mcp2515_write_register Txb1d4 , Db0(5)
Mcp2515_write_register Txb1d5 , Db0(6)
Mcp2515_write_register Txb1d6 , Db0(7)
Mcp2515_write_register Txb1d7 , Db0(8)
'nachricht versenden
Reset Css
Waitus 10
Mcphilf = Spi_rts1
Spdr = Mcphilf
Do
Loop Until Spsr.spif = 1
Waitus 10
Set Css
Waitms 50
Return



Send_buffer2:

Return


'********MCP2515 Initialisieren************************************ ****

Mcp2515_init:

'ID auf SIDL und SIDH "verteilen"


Hilf1 = Id / 8
Idh = Hilf1
Hilf1 = Idh * 8
Hilf1 = Id - Hilf1
Hilf1 = Hilf1 * 32
Idl = Hilf1



'MCP2515 per Software Reset zurücksetzen
Mcphilf = Spi_reset
Print "Mcphilf = Spi_reset "
Reset Css
Print "Reset CSS"
Waitus 10
Spdr = Mcphilf
Do
Loop Until Spsr.spif = 1
Waitus 10
Set Css
Print "Set Css1"
'einstellen des Bit Timings
'CNF1 &H07==>125 kbit/s &H13==>50 kbit/s

Mcp2515_write_register Cnf1 , &H13
Mcp2515_write_register Cnf2 , &H90
Mcp2515_write_register Cnf3 , &H02

Print "Timing o.k."

'Interrupt einstellen
Mcp2515_write_register Caninte , &B00000011


'Einstellen der Filter
Mcp2515_write_register Rxb0ctrl , &B01100000

'Buffer 1: Empfang aller Nachrichten
Mcp2515_write_register Rxb1ctrl , &B01100000
' **



'************************************************* ***************************
'****************** Filter und Maske einstellen ********************
'************************************************* ***************************

'Maske setzen - alle Bits auf "1" führen zu einem eindeutigen Filtern einer ID
Mcp2515_write_register Rxm0sidh , &B00111111 '
Mcp2515_write_register Rxm0sidl , &B11100000 '
Mcp2515_write_register Rxm1sidh , &B00111111 '
Mcp2515_write_register Rxm1sidl , &B11100000 '

'Filter setzen "25"
Mcp2515_write_register Rxf0sidh , &B00000011
Mcp2515_write_register Rxf0sidl , &B00100000
Mcp2515_write_register Rxf1sidh , &B00000011
Mcp2515_write_register Rxf1sidl , &B00100000

'************************************************* ***************************
'************************************************* ***************************
'************************************************* ***************************



'Einstellen der Pin Funktionen
'Deaktivieren der Pins RXnBF Pins (High Impedance State)
Mcp2515_write_register Bfpctrl , 0

'TXnRTS Bits als Input schalten
Mcp2515_write_register Txrtsctrl , 0


'Device zurück in den normalen Modus versetzen
Mcp2515_bitmodify Canctrl , &B11100000 , &B00000000

' Bit 7 Unimplemented: Lesen als'0 '
' Bit 6 ABTF: Nachricht Aborted Flag Bit -
' 1 = Nachricht wurde abgebrochen
' 0 = Nachricht erfolgreich abgeschlossene Übertragung
' Bit 5 MLOA: Nachricht Lost Arbitration Bit -
' 1 = Nachricht verloren, Schiedsverfahren gleichzeitig gesendet
' 0 = Nachricht nicht verloren, während Schiedsverfahren gesendet
' Bit 4 TXERR: Übermittlung Bit-Fehler erkannt
' 1 = Ein Bus-Fehler ist aufgetreten, während die Nachricht übermittelt wurde,
' 0 = es ist keine Bus-Fehler aufgetreten, während die Nachricht übermittelt wurde,
' Bit 3 TXREQ: Nachricht Transmit Request-Bit -
' 1 = Buffer ist derzeit zur Übertragung anhängig
' (MCU setzt dieses Bit auf Anfrage Nachricht übertragen werden - Bit wird automatisch gelöscht, wenn
' Wird die Nachricht gesendet)
' 0 = Buffer ist derzeit nicht zur Übertragung anhängig
' (MCU kann dieses Bit klar um eine Nachricht abbrechen)
' Unimplemented
' Bit 2: Lesen als'0 '
' Bit 1-0 TXP: Sendepuffer Priority
' 11 = Höchste Priorität
' 10 = High Intermediate Priority
' 11 = Low Intermediate Priority
' 00 = Tiefste Message Priority


Mcp2515_read_register Caninte
Print "CANINTE: " ; Canin
Mcp2515_read_register Canintf
Print "CANINTF: " ; Canintf
Mcp2515_read_register Canstat
Print "Canstat: " ; Canstat
Mcp2515_read_register Canctrl
Print "CANCTRL: " ; Canctrl
Mcp2515_read_register Cnf1
Print "CNF1: " ; Cnf1
Mcp2515_read_register Cnf2
Print "CNF2: " ; Cnf2
Mcp2515_read_register Cnf3
Print "CNF3: " ; Cnf3
Mcp2515_read_register Txb0ctrl
Print "TXB0CTRL: " ; Txb0ctrl
Mcp2515_read_register Txb1ctrl
Print "TXB1CTRL: " ; Txb1ctrl
' Mcp2515_read_register Txb2ctrl
' Print "TXB2CTRL: " ; Txb2ctrl
Mcp2515_read_register Rxb0ctrl
Print "RXB0CTRL: " ; Rxb0ctrl
Mcp2515_read_register Rxb1ctrl
Print "RXB1CTRL: " ; Rxb1ctrl
Mcp2515_read_register Bfpctrl
Print "BFPCTRL: " ; Bfpctrl
Mcp2515_read_register Txrtsctrl
Print "TXRTSCTRL: " ; Txrtsctrl




Return


'********MCP2515 schreiben****************************************

Sub Mcp2515_write_register(byval Adress As Byte , Byval Daten As Byte)
'Print "Reg: " ; Adress ; " Val: " ; Daten
Mcphilf = Spi_write
Reset Css
Spdr = Mcphilf
Do
Loop Until Spsr.spif = 1
Waitms 2
Spdr = Adress
Do
Loop Until Spsr.spif = 1
Spdr = Daten
Do
Loop Until Spsr.spif = 1
Set Css
End Sub



'********MCP2515 lesen****************************************

Sub Mcp2515_read_register(byval Adress As Byte )
Mcphilf = Spi_read
Reset Css
Spdr = Mcphilf
Do
Loop Until Spsr.spif = 1
Waitms 2
Spdr = Adress
Do
Loop Until Spsr.spif = 1
Spdr = 0
Do
Loop Until Spsr.spif = 1
Canin = Spdr
Set Css
End Sub



'********MCP2515 bitmodify****************************************

Sub Mcp2515_bitmodify(reg_add , Reg_mask , Reg_val)
'Local Can_tmp2 As Byte
Reset Css
Mcphilf = Spi_bit_modify
Spdr = Mcphilf 'Can_tmp2
Do
Loop Until Spsr.spif = 1
Waitms 2
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 Css
End Sub



'******** Datenempfang ********************************************

Mcpempfang:
Print "Empfangen"
Mcp2515_read_register Canintf 'Spi_rx_status
Canstat = Canin
Print "CANINTF: " ; Canstat
If Canstat.0 = 1 Then Gosub Mcp_read_buffer0
If Canstat.1 = 1 Then Gosub Mcp_read_buffer1
Return

'-------- lesen vom Buffer 0
Mcp_read_buffer0:
Print "Mcp_read_buffer0:"
Mcp2515_read_register Rxb0sidh
Idh = Canin
Mcp2515_read_register Rxb0sidl
Idl = Canin
Mcp2515_read_register Rxb0dlc

Dfl = Canin
Id = Idh * 8
Hilf1 = Idl / 32
Id = Id + Hilf1

'Print "ID-0=" ; Id ; " DFL-0=" ; Dfl
'Daten
For L = 1 To 8
If L = 1 Then Mcp2515_read_register &H66
If L = 2 Then Mcp2515_read_register &H67
If L = 3 Then Mcp2515_read_register &H68
If L = 4 Then Mcp2515_read_register &H69
If L = 5 Then Mcp2515_read_register &H6A
If L = 6 Then Mcp2515_read_register &H6B
If L = 7 Then Mcp2515_read_register &H6C
If L = 8 Then Mcp2515_read_register &H6D
Db0(l) = Canin
Next L
Mcp2515_bitmodify Canintf , &B00000001 , &B00000000
Print "Daten Buffer-0:" ; Db0(1) ; "-" ; Db0(2) ; "-" ; Db0(3) ; "-" ; Db0(4) ; "-" ; Db0(5) ; "-" ; Db0(6) ; "-" ; Db0(7) ; "-" ; Db0(8)

Gosub Auswertung

Return

'-------- lesen vom Buffer 1 ---------- falls erforderlich
Mcp_read_buffer1:
Print "Mcp_read_buffer1:"
Mcp2515_read_register Rxb1sidh
Idh = Canin
Mcp2515_read_register Rxb1sidl
Idl = Canin
Mcp2515_read_register Rxb1dlc
Dfl = Canin
Id = Idh * 8 : Hilf1 = Idl / 32 : Id = Id + Hilf1
' Print "ID-1=" ; Id ; " DFL-1=" ; Dfl
'Daten
For L = 1 To 8
If L = 1 Then Mcp2515_read_register &H76
If L = 2 Then Mcp2515_read_register &H77
If L = 3 Then Mcp2515_read_register &H78
If L = 4 Then Mcp2515_read_register &H79
If L = 5 Then Mcp2515_read_register &H7A
If L = 6 Then Mcp2515_read_register &H7B
If L = 7 Then Mcp2515_read_register &H7C
If L = 8 Then Mcp2515_read_register &H7D
Db0(l) = Canin
Next L
Mcp2515_bitmodify Canintf , &B00000010 , &B00000000
Print "Daten Buffer-1:" ; Db0(1) ; "-" ; Db0(2) ; "-" ; Db0(3) ; "-" ; Db0(4) ; "-" ; Db0(5) ; "-" ; Db0(6) ; "-" ; Db0(7) ; "-" ; Db0(8)
Return








'************************************************* ****************************************
'************************************************* ****************************************
'*********** Auswertung *****************************************
Auswertung:
Print "Auswerten Daten Buffer-1:" ; Db0(1) ; "-" ; Db0(2) ; "-" ; Db0(3) ; "-" ; Db0(4) ; "-" ; Db0(5) ; "-" ; Db0(6) ; "-" ; Db0(7) ; "-" ; Db0(8)

If Db0(2) = 140 Then

Select Case Db0(1)
Case 101 To 105 : Gosub Schreiben 'In Knoten schreiben
Case 150 To 155 : Gosub Lesen 'aus Knoten lesen
Case 201 To 208 : Gosub Befehl 'in Knoten ausführen

End Select

Else
If Db0(2) = 255 Then Gosub Status 'kann zu Problemen führen wenn alle Knoten gleichzeitig ihren Status senden!!!!!


End If

Return


'*********** neue Zeit programmieren *****************************************

Schreiben: 'In Knoten schreiben



Return

'*********** Lesen ausführen ********************************************

Lesen: 'aus Knoten lesen



Return


'*********** Lesebefehl ausführen ********************************************

Befehl: 'in Knoten ausführen




Print "Befehl Daten Buffer-1:" ; Db0(1) ; "-" ; Db0(2) ; "-" ; Db0(3) ; "-" ; Db0(4) ; "-" ; Db0(5) ; "-" ; Db0(6) ; "-" ; Db0(7) ; "-" ; Db0(8)
Return

Tefi
02.10.2009, 23:19
Hollo

Jetzt habe ich mich auch einmal an die CAN Schaltung gewagt, was anhand der hier vorliegenende Informationen gut nachvollziehbar ist. Ich kann eine Message von einem Node mittels Schalter auslösen und diese im zweiten Node empfangen. Drücke ich aber ein zweites Mal auf den Schalter so funktioniert es nicht mehr und ich bekomme folgende Werte:

Empfangen...
eflg=11111111
canintf=11111111
Reading RxB 0
RxB0CTRL=11111111
RxB0SIDL=11111111
RxB0SIDH=11111111
RxB0DLC=11111111
RxB0CTRL=11111111
RxB0d0=11111111
Reading RxB 1
RxB1CTRL=11111111
RxB1SIDL=11111111
RxB1SIDH=11111111
RxB1DLC=11111111
RxB1CTRL=11111111
RxB1d0=11111111

Woran kann das liegen?
Hat schonmal jemand das gleiche Verhalten erlebt?

Gruss, Tefi

Tefi
12.10.2009, 09:24
Hab's gefunden. Der Reset eines MCP2515's hing in der Luft und nicht via Widerstand an VDD.

a4b68e
28.07.2010, 20:16
Hallo!
ich versuche mich gerade damit auch auseinander zu setzen.
kann mal Jemand, bitte, den Schaltplan angucken?
ich habe die RS232 und ISPL von Atmega weggelassen, weil ich die Schaltung möglichst klein haben möchte. Der Atmega8 wird auf dem STK500 geflasht und einfach in den Sockel auf der Platine eingesetzt.
Sieht da Jemand Fehler im Schaltplan?

Wenn der Taster gedrückt wird, möchte ich eine CAN-Bootschaft absenden.

Passt das so?
Gruss

Duesentrieb
28.07.2010, 21:28
Hallo a4b68e,

die Schaltung passt! Jett mal ans Programmieren ;-)

a4b68e
30.07.2010, 21:34
So, die Schaltung habe ich vor 3 Tagen fertiggelötet.

Nun habe ich mich gestern an das Programmieren gesetzt und wusste nicht, wie ich anfangen soll.

Ich will KEINE fertige Lösung. ich bin so ein Mensch, der ein Beispiel braucht, um Etwas zu verstehen.
Könnt Ihr mir sagen welches Quellcode von oben geposteten ich am besten nehmen soll?
Dann werde ich mich mal hinsetzen und das Studieren.
Trocken Datenblatt (MCP2515) zu lesen bringt bei mir leider nicht viel.
Durchgelesen habe ich es aber schon (nur nicht VIEL schlauer geworden).

Wie ich oben schon geschrieben habe, ich möchte nichts empfangen, sondern erst mal nur senden.

das Programm wollte ich so aufbauen (ganz grob):

1. µC configuration
2. Dim xxx as xxx
3. CAN configuration
4. ABFRAGE:
do
if Taster=0 then
goto SENDEN
5. Senden
Goto ABFRAGE
6. End

Warum nehmen die meisten die 7,3728 MHz Quarze?
Kann ich auch die 8,000 Mhz nehmen, oder gar den internen 1 Mhz Oszillator verwenden?

Gruss Alex

a4b68e
02.08.2010, 17:41
Hallo!
Kann mit jemand was zum Quarz sagen?
Frage ist oben.
Gruss

a4b68e
19.08.2010, 19:45
Hallo!
habe mich mal wieder an das Projekt hingesetzt.
Die Hardware ist fertig.
Wie soll ich mit der Software anfangen?
Gruss Alex

Duesentrieb
20.08.2010, 05:59
Hallo,

wenn du ganz neu mit dem CAN anfängst würde ich dir empfehlen die den Code aus diesem Beitrag zu nehmen, mit vielen "Print"-Kommentaren zu versehen und einfach mal zu verfolgen was da im Programm so alles passiert.
Ganz ohne Datenblatt wirst du nicht auskommen da es sehr viele Konfigurationsmöglichkeiten gibt.

Fang einfach mal klein an und frag wenn du etwas nicht verstehst!

a4b68e
20.08.2010, 19:21
ja, ich fange so zu sagen von 0 mit dem Can-Bus an.
Mit den µC habe ich aber schon Erfahrung.
Welchen Code sollte ich genau als Beispiel nehmen?
Meistens sind es doch spezielle Sachen, die mich "ablenken" und für den Anfang zu kompliziert sind.
Danke
Gruss Alex

a4b68e
08.09.2010, 23:52
Hallo!
ich kenne mein Code schon fast auswendig, aber ich habe das programm immer noch nicht zum Laufen bekommen.
Ich habe schon alles probiert, was mir nur einfallen konnte.
Habe jetzt den gesammten Code so weit gekürzt wie es nur geht.
Ich hoffe ich habe nichts "falsches" weggekürzt.

für mich scheint das Programm logisch zu sein, und müsste laufen. Tut es aber nicht.
ich habe am TX vom MCP2515 kein Signal.

Falls Jemand Zeit hat, BITTE durchgucken. Ich bin schon Ratlos.



$regfile = "m8def.dat" ' ATMega8
$crystal = 16000000 ' Baudratenquarz der AVR (mega8 mit 16MHz)
$hwstack = 40 ' default use 32 for the hardware stack
$swstack = 80 ' default use 10 for the SW stack
$framesize = 90
$baud = 9600


' Allgemeine Config ************************************************** **********

Config Pind.2 = Input 'Taster
Config Portb.0 = Output 'LED
Taster Alias Pind.2
Led Alias Portb.0

Led = 0 'Grundstellung



'CAN relevante Config ************************************************** ********

Declare Sub Mcp2515_write(byval Reg_add As Byte , Byval Reg_val As Word)
Declare Sub Mcp2515_bitmodify(byval Reg_add As Byte , Byval Reg_mask As Byte , Byval Reg_val As Byte)


Mcp2515cs Alias Portb.2 'CS am Mega8
Config Mcp2515cs = Output


Const Cmd_write = &H02 ' Write Command
Const Cmd_bitmodify = &H05 ' Bit-modify Command
Const Cmd_reset = &HC0 ' Reset Command
Const Cmd_rts0 = &H81
Const Cmd_rts1 = &H82
Const Caninte = &H2B
Const Canctrl = &H0F
Const Canstat = &H0E ' Statusregister
Const Eflg = &H2D ' Error Flag Register

Const Cnf3 = &H28 ' Configuration Register 3
Const Cnf2 = &H29 ' Configuration Register 2
Const Cnf1 = &H2A ' Configuration Register 1


Const Txb0ctrl = &B00110000 ' Transmit Buffer 0 Control Register
Const Txb0sidh = &B00110001 ' Transmit Buffer 0 Std Identifier High
Const Txb0sidl = &B00110010 ' Transmit Buffer 0 Std Identifier Low
Const Txb0dlc = &B00110101 ' Transmit Buffer 0 Data Length Code
Const Txb0d0 = &B00110110 ' Transmit Buffer 0 Data Byte 0


' Hardware SPI-Schnittstelle konfigurieren************************************* *

Config Portb.4 = Input 'MISO von 2515
Config Portb.3 = Output 'MOSI von 2515
Config Portb.5 = Output 'SCK
Spcr = &B01010001 'Bit7=0:IntAus, Bit6=1:SPIAn, Bit5=0:MSBfirst,
'Bit4=1:Masterfunktion, Bit3=0:SCK=0wennIdle,
'Bit2=0:L-H-Flanke, Bit1+0=01:AVRClock/16


'Programm Start********************************************* ********************
Gosub Can_init

Abfrage:
Do
If Taster = 0 Then
Set Led
Wait 1
Reset Led
Waitms 500
Gosub Data_send
Else
Goto Abfrage
Loop
End If

End

'CAN Initialisieren *****************************

Can_init:

Reset Mcp2515cs ' Reset MCP2515

Spdr = &HC0 ' IC reset
Do
Loop Until Spsr.spif = 1
Set Mcp2515cs

Waitms 2000
Mcp2515_write Canctrl , &B10001101 ' set configuration mode, osm=1, clkout enabled, prescaler /2

' CAN 100 kbit/s
Mcp2515_write Cnf1 , &B00000001 ' Can Geschwindigkeit einstellen (Cnf1-Cnf3)
Mcp2515_write Cnf2 , &B10111010 ' Cnf2 = &H29
Mcp2515_write Cnf3 , &B00000111 ' Cnf3 = &H28
Mcp2515_write Caninte , &B00000000 'Can interrupt disabled
Mcp2515_write Canctrl , &B00001101 ' set normal operation mode, osm=1, clkout enabled, prescaler /2

Return


'Daten ubertargen ************************************************** *********
Data_send:

Mcp2515_bitmodify Txb0ctrl , &B00000011 , &B00000011 ' TX-Konfiguration
Mcp2515_write Txb0sidh , &B10101010 ' Empfangeradresse setzen
Mcp2515_write Txb0sidl , &B10101010 ' Empfangeradresse setzen
Mcp2515_write Txb0dlc , &B00000001 ' Paketlange festlegen fur ein Byte


'Daten zur Uebertragung************************
Mcp2515_write Txb0d0 , &B01011101 ' Zu ubertragende Daten setzen


' Ubertragung auslosen
Reset Mcp2515cs
Waitms 20
Spdr = Cmd_rts0 '!!!!! DIESE STELLE IST MIR UNKLAR

Do
Loop Until Spsr.spif = 1
Waitus 20
Set Mcp2515cs

Waitms 2
Set Led 'LED als Anzeige "Gesendet"
Waitms 200
Reset Led
Waitms 100

Goto Abfrage 'Zurück zur Abfrage





Sub Mcp2515_bitmodify(reg_add , Reg_mask , Reg_val)
Local Can_tmp2 As Byte
Mcp2515cs = 0
Can_tmp2 = Cmd_bitmodify
Spdr = Can_tmp2
Do
Loop Until Spsr.spif = 1
Waitms 2
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
Mcp2515cs = 1
End Sub

Sub Mcp2515_write(reg_add , Reg_val)
Local Can_tmp2 As Byte
Mcp2515cs = 0
Can_tmp2 = Cmd_write
Spdr = Can_tmp2
Do
Loop Until Spsr.spif = 1
Waitms 2
Spdr = Reg_add
Do
Loop Until Spsr.spif = 1
Spdr = Reg_val
Do
Loop Until Spsr.spif = 1
Mcp2515cs = 1
End Sub


Im Anhang ist der Schaltplan.
Danke schön
Gruss Alexander

olli1986
05.08.2013, 17:51
Hi @ all,
ich heiße Oliver bin 27 Jahre jung.
Immer wenn ich mal Zeit habe beschäftige ich mich mit Elektronik und co.

So dann wollen wir mal :-)

Ich weiß das dieses Thema schon älter ist, aber wie man sieht immer noch nicht abgeschoben ;-)

Beschäftige mich schon länger mit dem CAN-BUS, wie gesagt wenn zeit war.
Habe jetzt ein par Schaltpläne erstellt die ich später mal selber Ätzen möchte usw.
Wollte jetzt gerne eure meinung zu den Schaltplänen hören, vom Grund her sind sie alle gleich
es sollen nur verschiedene Knoten sein.

CAN Atmega USB soll als verbindung zum PC dienen
CAN Mini Knoten soll nachher in ein Unterputz gehäuse passen
CAN Uni Knoten soll ein Universal Knoten sein für alles wo ich ein wenig mehr platz habe als in einer Unterputzdose.

Anstat des Atmega 168 soll ein Atmega 328P-AU in gleicher Form zum einsatz kommen.

Gruß Olli

Kampi
05.08.2013, 19:28
Hey,

schau mal.....ich habe auch mal sowas gemacht (bin auch ab und an noch dabei):

http://kampis-elektroecke.de/index.php/nggallery/slideshow?page_id=453

Vielleicht hilft dir das ja auch weiter (auch vom Code her).

olli1986
05.08.2013, 20:58
Hi @Kampi

manchmal sieht man den Wald vor lauter Bäumen nicht mehr.
Bin vor ca. eine Woche über diese Seite gestolpert aber völlig vergessen (ich werd alt *husthust* ;-))
Werde die Seite mal studieren :-).

Was meinst du sonnst so zu meinen Schaltplänen?

Gruß Olli

Kampi
06.08.2013, 05:58
Hi @Kampi

manchmal sieht man den Wald vor lauter Bäumen nicht mehr.
Bin vor ca. eine Woche über diese Seite gestolpert aber völlig vergessen (ich werd alt *husthust* ;-))
Werde die Seite mal studieren :-).

Was meinst du sonnst so zu meinen Schaltplänen?

Gruß Olli

Hey,

die Pläne muss ich mir heute Mittag mal anschauen.
Wenn du den Code verwenden willst, erwarte aber keine Wunder....der ist noch nicht fertig (ich glaube Masken und Filter setzen ist noch gar nicht implementiert).....senden und empfangen klappt aber 1a!

olli1986
12.08.2013, 17:50
Hi Kampi,

habe mir jetzt mal deine Homepage angeschaut und ich muss sagen, ich habe wieder was dazu gelernt.
Die Idee hatte ich auch schon gehabt bloß nicht verwirklicht :-).

Ich hatte den Code irgend wo hier aus diesem Thema wo mit ich die ersten nachrichten verschickt und empfangen habe,
aber das von dir schein ein wenig besser Organisiert zu sein.

Mit den Filtern und Masken habe ich auch noch nicht so ganz verstanden, das ist doch im Grunde so wie eine IP Adresse,
oder bin ich da völlig aufm falschen weg?

Gruß Olli

Kampi
12.08.2013, 18:06
Hi Kampi,

habe mir jetzt mal deine Homepage angeschaut und ich muss sagen, ich habe wieder was dazu gelernt.
Die Idee hatte ich auch schon gehabt bloß nicht verwirklicht :-).

Ich hatte den Code irgend wo hier aus diesem Thema wo mit ich die ersten nachrichten verschickt und empfangen habe,
aber das von dir schein ein wenig besser Organisiert zu sein.

Mit den Filtern und Masken habe ich auch noch nicht so ganz verstanden, das ist doch im Grunde so wie eine IP Adresse,
oder bin ich da völlig aufm falschen weg?

Gruß Olli

Hey,

im Grunde ja.
Mit den Maskenbits legst du fest, welche der Filterbits beachtet werden. Setzt du alle auf High, beachtet der Controller alle 8 Filterbits.
Die Filterbits hingegen sind die Adressbits eines jeden Controllers.
Das ist jetzt nur einfach ausgedrückt :)
Für genauere Infos solltest du dir das Kapitel mal genauer durchlesen.

olli1986
13.08.2013, 11:48
Hi Kampi,

habe noch ein wenig bei Google gesucht, jetzt habe ich es verstanden mit den Masken und filtern.

In nach folgenden Link ist es sehr gut beschrieben.
http://www.daedalus.ei.tum.de/index.php/de/dokumentation/projekte/komm-struktur/funktionsweise-des-can-bus

meinolf
01.12.2013, 13:28
Hallo
ich möchte mehrere Tempsensoren analog oder i2c auf den can-bus bringen.
sowas ist doch bestimmt schonmal gebaut worden


meinolf