- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 9 von 9

Thema: Bascom - Candip - Anfängerfragen

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    09.08.2006
    Beiträge
    12

    Bascom - Candip - Anfängerfragen

    Anzeige

    Praxistest und DIY Projekte
    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:
    Code:
    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

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.09.2004
    Ort
    Düsseldorf
    Beiträge
    3.948
    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 .
    Gruß
    Ratber

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    09.08.2006
    Beiträge
    12
    @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

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.09.2004
    Ort
    Düsseldorf
    Beiträge
    3.948
    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 ?
    Gruß
    Ratber

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    09.08.2006
    Beiträge
    12
    @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

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von Vitis
    Registriert seit
    06.01.2005
    Ort
    Südpfalz
    Alter
    50
    Beiträge
    2.253
    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.
    Vor den Erfolg haben die Götter den Schweiß gesetzt

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.09.2004
    Ort
    Düsseldorf
    Beiträge
    3.948
    @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.
    Gruß
    Ratber

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    09.08.2006
    Beiträge
    12
    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

  9. #9
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.09.2004
    Ort
    Düsseldorf
    Beiträge
    3.948
    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.
    Gruß
    Ratber

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiFePO4 Speicher Test