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