PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Bascom - Candip - Anfängerfragen



MichlM
18.05.2007, 11:11
Servus,

ich habe hier zwei Candip`s und programmiere diese mit Bascom. Das versenden und empfangen von Nachrichten anhand der Programmbeispiele funktioniert. Erstaunlicherweise, da ich doch noch ziemlicher Anfänger im Bereich µ-controller bin.
Ich habe eine grundsätzliche Frage zu dem Beispielcode. Der Candip hat einen Mega162 und einen SJA1000. Der SJA1000 hat doch einen Adressbuss Bit 0-7 der irgendwie an den Mega162 angeschlossen ist. Im Bascom Beispiel steht :
' SJA1000 CAN contoller is located at &H4000
Const Can_base = &H4000
Was bedeutet das &H4000? ist das die Adresse eines kompletten Port0-7 an einem Mega. Und wo sind ALE,RD und WR für den SJA1000?
Hier der komplette Beispielcode:

candipio.bas
'
' Purpose: General Test routines for SJA1000 on the CANDIP in BasicCAN mode
'
' Chip: AT90S8515 running at 3.6864MHz
'
' Version: 1.0.0, 25:th of February 2000
'
' Author: Lars Wictorsson
' LAWICEL / SWEDEN
' http://www.lawicel.com lars@lawicel.com
'
' Remarks: This code sample is provided as is and demonstrates
' simple distributed I/O by CAN. The CANDIP is reading
' two push buttons and sends their current status as
' CAN frames when they are changed. The NodeId used is read
' from the CANDIP Activity board jumpers (PD3-PD5) when started.
' When button PB2 and/or PB3 is busshed/released their status
' is sent on the CANbus based on the NodeId read from startup.
' The other node is "listening" for this ID and will display
' the status on the LED's PB0 and PB1 and vice versa.
' This demonstrates the Multi Master functionality of CAN.
' This program is tested with BASCOM-AVR version 1.0.0.8.
'
' Test Setup: Use 2 CANDIP's and 2 Activity boards.
' One one Activity board, set PD3-PD5 open (NodeID=0).
' One the other, set PD3 closed, PD4-PD5 open (NodeID=1).
' Set PB0-PB1 as output and PB2-PB3 as input.
'
' Important: The MakeInt function in BASCOM is wrong in version 1.0.0.8
' and will be fixed later, this means you need to swap
' the msb and lsb (the help file in BASCOM shows it correct
' but compiler is wrong, this is a known bug of BASCOM).
'
' History: 2000-02-25 1.0.0 Created
'
' CANDIP: See CANDIP at http://www.lawicel.com/candip/
'
$crystal = 3686400
$baud = 57600
' SJA1000 CAN contoller is located at &H4000
Const Can_base = &H4000
' Some SJA1000 registers in BasicCAN mode
Const Can_ctrl = &H4000
Const Can_cmd = &H4001
Const Can_status = &H4002
Const Can_int = &H4003
Const Can_ac = &H4004
Const Can_am = &H4005
Const Can_tmg_0 = &H4006
Const Can_tmg_1 = &H4007
Const Can_ocr = &H4008
Const Can_test = &H4009
Const Can_tx_id = &H400A
Const Can_tx_len = &H400B
Const Can_tx_buf0 = &H400C
Const Can_tx_buf1 = &H400D
Const Can_tx_buf2 = &H400E
Const Can_tx_buf3 = &H400F
Const Can_tx_buf4 = &H4010
Const Can_tx_buf5 = &H4011
Const Can_tx_buf6 = &H4012
Const Can_tx_buf7 = &H4013
Const Can_rx_id = &H4014
Const Can_rx_len = &H4015
Const Can_rx_buf0 = &H4016
Const Can_rx_buf1 = &H4017
Const Can_rx_buf2 = &H4018
Const Can_rx_buf3 = &H4019
Const Can_rx_buf4 = &H401A
Const Can_rx_buf5 = &H401B
Const Can_rx_buf6 = &H401C
Const Can_rx_buf7 = &H401D
Const Can_clkdiv = &H401F
' Some key values
Const Own_id = 0 ' Our CAN-ID
Const Acceptmask = &HFF ' Our accept mask
' Some useful bitmasks
Const Resreq = 1 ' Reset Request
Const Rbs = 1 ' Receive Buffer Status
Const Rrb = 4 ' Release Receive Buffer
Const Txreq = 1 ' Transmit Request
Const Tba = 4 ' Transmit Buffer Access
Declare Sub Initsja
Declare Sub Transmitcanio( b as byte)
Declare Sub Checkcan
Dim Always As Byte
Dim Nodeid As Byte
Dim Inpb As Byte
Dim Inpbold As Byte
Always = 1
Inpb = &H0C ' Default button status
Inpbold = &H0C
Mcucr = &HC0 ' Enable External Memory Access With
Wait - state
Ddrb = &H03 ' Set PB0+PB1 as output and PB2+PB3 as
input with pullup
Portb = &H0F ' and turn off LED's
Ddrd = &H00 ' Set PD3+PD4+PD5 as inputs with
pullup
Portd = &H38
Nodeid = Pind ' Read Jumper inputs on Port D and
save as Node ID.
Rotate Nodeid , Right , 3
Nodeid = Nodeid And &H07
Nodeid = 7 - Nodeid ' Invert, how to make it better in
BASCOM?
Initsja
While Always = 1
Inpb = Pinb And &H0C ' Read inputs PB2 & PB3
If Inpb <> Inpbold Then ' Are they different from last check?
Transmitcanio Inpb ' If so, send new state of buttons
Inpbold = Inpb ' and save this state
End If
Checkcan
Wend
End
Sub Initsja ' Initiate CAN controller 125kbit
Local B As Byte
B = Inp(can_ctrl)
B = B And Resreq
While B = 0
out can_ctrl,resreq
B = Inp(can_ctrl)
B = B And Resreq
Wend
out Can_ac, Own_id
out Can_am, Acceptmask
out Can_tmg_0,3
out Can_tmg_1,&H1C
out Can_ocr,&HDE
out Can_clkdiv,7
out Can_ctrl,&H5E
out Can_cmd,&H0C
End Sub
Sub Transmitcanio( b as byte)
Local Id As Word
Local Tmp1 As Word
Local Ln As Byte
Local Tmp2 As Byte
Do ' Loop until transmit buffer is empty
Tmp1 = Inp(can_status)
Tmp1 = Tmp1 And Tba
Loop Until Tmp1 = Tba
Id = &H500 + Nodeid ' Create ID based on NodeId
Ln = 1
Tmp1 = Id
Rotate Tmp1 , Right , 3
Tmp2 = Low(tmp1)
out Can_tx_id, Tmp2
Tmp1 = Id And &H07
Rotate Tmp1 , Left , 5
Tmp1 = Tmp1 + Ln
Tmp2 = Low(tmp1)
out Can_tx_len, Tmp2
out Can_tx_buf0, b
out Can_cmd, Txreq
End Sub
Sub Checkcan
Local Id As Word
Local Tmp1 As Word
Local Ln As Byte
Local Tmp2 As Byte
Tmp2 = Inp(can_status)
Tmp2 = Tmp2 And Rbs
If Tmp2 = Rbs Then
Tmp2 = Inp(can_rx_id)
Id = Makeint(0 , Tmp2)
Rotate Id , Left , 3
Tmp1 = Inp(can_rx_len)
Rotate Tmp1 , Right , 5
Tmp1 = Tmp1 And &H07
Id = Id + Tmp1
Tmp2 = Inp(can_rx_len)
Ln = Tmp2 And &H0F
Tmp2 = Inp(can_rx_buf0)
Rotate Tmp2 , Right , 2
If Nodeid = 0 Then
If Id = &H501 Then
Portb = &H0C + Tmp2
End If
Elseif Nodeid = 1 Then
If Id = &H500 Then
Portb = &H0C + Tmp2
End If
End If
out can_cmd, rrb
End If
End Sub


Vielen Dank

Michl

Ratber
18.05.2007, 11:53
Die Lösung ist recht einfach.

Der SJA1000 hat ja etliche Register die angesprochen werden können (Konfiguration und Transfer).
Damit man Pinne spart ist dieser einen kombinierten Adress/Datenbus (D0-D7 plus Steuerleitungen (7 Stück)) so das nur 15 Leitungen für die komplette Steuerung nötig sind.
Der Rest ist beim SJA ja nur der CAN zum Transreciver und die Versorgungsleitungen sowie der Takt (Quarz).

Der Mega 8515 im Beispiel hat selber auch einen Externen Bus und der Author hat den SJA einfach an den Bus des Atmel gehangen (Steht aber auch groß im Quellcode ganz oben welche Leítung wohin gewandert ist) wobei sich durch die gewählte Verdrahtung die Basisadresse 4000h ergibt.

Die Einzelnen Adressen für die Funktionen sind dann als Constanten definiert (Direkt darunter "Const Can_ctrl = &H4000" bis "Const Can_clkdiv = &H401F") so das man die einzelenen Funktionen bzw. die Puffer direkt über ihren Namen ansprechen kann.

Ist das denn so schwer abzulesen ? (OK,du bist Anfänger wie du sagst da kann man jetzt keine größeren Masstäbe anlegen)
Für mich ist das nach 2 Minuten Studieren eigentlich ein sehr einfaches Beispiel gewesen bis auf den Umstand das der eigentliche Code etwas Spagettihaft geraten ist (Sprichwörtlich ohne Punkt und Komma)

Versuch einfach mal im Code dieeinzelnene Funktionsblöcke etwas räumlich zu trennen (Leerzeilen.Einrücken von Schleifen usw.) dann ergibt sich eine bessere Übersicht .

MichlM
18.05.2007, 12:32
@Ratber:
Danke für die ausführliche Antwort, leider verstehe ich das immer noch nicht ganz.
Du schreibst im Quellcode steht ganz oben welche Leitungen wohin gewandert sind. Wo steht wie der Daten/Steuerbus des SJA auf welche Pins vom µC sind? Ich finde da nix. Da stehen doch nur die Pins womit die Node-ID`s festgelegt werden.
Wie errechnet/ergibt sich die &H4000 zum adressbus auf dem µC?

Vielen Dank

Ratber
18.05.2007, 13:07
Ok,also nochmal einzeln.


Die Adresse 0 am SJA ist wenn ich an seinem Adress/Datenbus alle Bits "0" setze ! (Oder wars jetzt invers auf "1" ?.Egal,speilt jetzt keine Rolle)
Soweit sollte das ja wohl klar sein.

Am Controller (8515) soll das Adresse 4000 hex sein also 16384 Dez
Binär entspricht das 0100000000000000 bin was ich jetzt mal der Übersicht wegen in 4er Gruppen aufteile.
Dann wäre das also 0100 0000 0000 0000
Ab hier werden die 32 Adressen des SJA1000 eingeblendet

16384dez bis 16400dez
oder
4000 hex bis 400F hex
oder
0100 0000 0000 0000 bin bis 0100 0000 0000 1111 bin

Du könntest das Höchste Adressbit des SJA1000 auch an ein anderes Bit als das Adressbit 14 des Controllers hängen um einen anderen Adressraum zu bekommen.
Der Author des Artikels hat sich eben entschieden den SJA1000 über den Externen Bus ab Adresse 4000h einzublenden weil am Bus praktischer ist weil man dort noch unmengen an Geräten anhängen kann.
Wenn du nur den SJA1000 zum Experimentien nutzen willst kannst du ihn natürlich auch über 2 ganz gewöhnliche Ports ansteuern nur das für mehr Hardware dann wenig Raum bleibt (Die 15 Bit sind so oder so weg).



Besser so ?

MichlM
21.05.2007, 09:15
@Ratber:
Danke für Deine ausführliche Antwort. Mein Problem war, ich hatte den externen Adressbus nicht verstanden, dass es sowas überhaupt gibt und wie das so funktioniert. Hab jetzt einiges darüber im Netz gefunden und sehe das jetzt klarer, nur wie man zu der Basisadresse &H4000 kommt verstehe ich nicht. Wenn ich den SJA1000 mit dem Adress/Daten D0-7 an Port A des 8515 hänge und die zugehörigen ALE/RD/WR verbinde ergibt das dann automatisch die Basisadress &H4000 oder muss das irgendwo eingestellt/konfiguriert werden.

Vielen Dank

Michl

Vitis
21.05.2007, 14:45
Bei µC läuft nix mit plug an pray, ist kein PC mit Treiber CD und fertig.
Die Controller und auch oft die Peripherie dazu müssen immer
konfiguriert werden.
Die Register des CANDIP kannst Du Dir in etwa wie die Treibereinstellungen
für Deine Graphikkarte vom PC vorstellen. Um eine schöne Bildschirmdarstellung
zu bekommen musst Du der auch sagen 60Hz Bildwiederholrate
800 x 600 Auflösung etc.
Die entsprechende Wunschkonfiguration musst Du dem Teil
verklickern, sonst weiß es nicht was es tun soll. Zu diesem Zweck
werden Werte in den Registern verändert. Da es aber nicht nur
ein Register ist sondern mehrere haben die alle Namen, sprich
Adressen. So wie Wohnzimmer, Küche, Toilette etc. nicht dass man
sich da mal vertut mit den Tätigkeiten. Eine solche Adresse ist dann
eben die &H4000. Für gewöhnlich gibt es für Bausteine ein
Datenblatt, wo dann drin steht, welche Adresse für was gut ist.

Ratber
22.05.2007, 00:30
@Vitis

Ja,das der TJA1000 seine Register Adressiert (0-31 um genauer zu sein) ist schon klar.

MichLM hat ,so wie ich es jetzt verstanden haben, nur das Problem zu verstehen wie die Adresse 4000h am Controller zustande kommt.



@MichLM

Ich kenne den Candip nur dem Namen nach und habe somit keinen Schaltplan aber wenn du selber mal eines deiner Module in augenschein nimmst und die Adressleitungen des SJA1000 zum Controller verfolgst kannst du ja sehen an welchen Adressbits des Controllers diese angeknüpfelt sind.
Das dürfte vieleicht schneller zum Verständnis führen.

MichlM
25.05.2007, 09:58
Hallo,

irgendwie komme ich mit dem Candip auf keinen grünen Zweig.

Das mit dem externen Bus hab ich jetzt verstanden, nur die addressierung macht mir immer noch Kopfzerbrechen.

Der SJA1000 hat nur einen Adress/Datenbus, d.h. erst werden die Registeradressen (&H00-&H1F) übertragen und danach die Daten auf den gleichen 8 Leitungen, es ist kein extra adressbus am SJA1000. Wie kommt man dann auf die Basisadresse von &H4000. Laut Handbuch müsste man entweder noch EMCUCR verwenden um auf diesen Speicherbereich zu kommen, was aber im Beispielcode (der funktioniert) nicht verwendet wird.

Der SJA1000 und der AVR sind nur über die 8 Datenleitungen AD0-AD7, ALE, WR, RD und CS verbunden. Der SJA hat auch keine Pin`s um seine Adresse einzustellen

Ich glaub` ich seh` den Wald vor lauter Bäumen nicht.

Gruss
Michl

Ratber
25.05.2007, 10:26
Das fürht so zu nix.

Nimm dienen Candip und schau an welche Controllerleitungen der angeschlossen ist.
Dann wirst du auch verstehen wie der "Controlleradressbereich" zustande gekommen ist.