Forums

CAN Programming

Started by kuinton January 20, 2004
Does anyone have any sample code to transmit and receive messages
through the CAN port for the DP256 model of HC12? Please let me
know... i tried to program it, but it ended up that i was using the
wrong version... and the registers were all in a different place, and
confusion ensued... please let me know ASAP guys. Thanks.




From Oliver Thamm's site some time ago http://hc12web.de/ coutesy of Andreas Dannenberg Name: CAN_A4.A
; Ver.: 1.0
; Func: CAN-Bus demo for HC12compact-Board (C)MCT Lange & Thamm
; receives data from the SC0 (serial interface) of the HC12,
; sends them out via the CAN-Bus and vice versa
; Auth: Andreas Dannenberg, eMail:
; Student of electrical engineering/telecommunications at
; Leipzig University of Applied Sciences (HTWK)
; Date: Sept 28 1999
; Rem.: Translate with "A12 CAN_A4"
;============================================================================= ; Chip-Select addresses of the CAN-Controller on the HC12compact-board

CAN_ADDR equ $0301 ; select CAN-controller register
CAN_DATA equ $0201 ; access to CAN-controller register

; Registers of SJA1000 in BasicCAN-mode

CR equ 0 ; Control Register
CMR equ 1 ; Command Register
SR equ 2 ; Status Register
ACR equ 4 ; Acceptance Code Register
AMR equ 5 ; Acceptance Mask Register
BTR0 equ 6 ; Bus Timing Register 0
BTR1 equ 7 ; Bus Timing Register 1
OCR equ 8 ; Output Control Register
TXBUF equ 10 ; Transmit Buffer
RXBUF equ 20 ; Receive Buffer
CDR equ 31 ; Clock Divider Register cpu 68hc12 ; pseudo instructions to
padding off ; build HC12-code

include "reghc12.inc" ; include HC12-standard registers

org $0800 ; program runs in RAM ; ***** CAN controller SJA1000 init *****
;
; physical layer interface: PCA82C250 transceiver from Philips Semiconductors
; connected to pins RX0 and TX0 of the CAN controller
; (pins 45 and 47 of ST4 of the HC12compact board)
;
; Bus timing values for a bit rate of 100 kbit/s, oscillator frequency is 16 MHz:
; Pay attention while selecting Time-Segment values to meet the CAN-Standard!
; (refer to SJA1000-Datasheet for more detailed information about CAN-timing)
;
; baudrate prescaler: 5 -> tSCL = 2 * 1/16 MHz * (4+1) = 625 ns (CAN System Clock Period)
; sync segment: tSYNCSEG = 1 * tSCL
; time segment 1: 11 -> tSEG1 = tSCL * (10+1) = 6.875 us
; time segment 2: 4 -> tSEG2 = tSCL * (3+1) = 2.5 us
;
; bit time: tBIT = tSYNCSEG + tSEG1 + tSEG2 = 10 us
; bit rate: fBIT = 1 / tBIT = 100 kbit/s
;
; The CAN-Bus address of the SJA1000-controller will be set to %10000000000
; (11 bits, CAN2.0A).
; Rem.: In BasicCAN-Mode, the SJA1000 only has 8-bit wide acceptance mask
; and code registers. That's why the last three bits of the identifiers of incoming
; messages are ignored and all messages beginning with %10000000 will be received.

Start ldx #CR ; enter Reset-Mode in order to configure the
ldaa #$01 ; SJA1000 CAN parameters
jsr writeSJA1000 ; write to CAN-Controller register

ldx #CDR ; bypass input comperator, BasicCAN mode
ldaa #$48 ; external clock output off
jsr writeSJA1000

ldx #OCR ; set output control register for using CAN-
ldaa #%00011010 ; transceiver: normal Mode, TX0 push pull, TX1 float
jsr writeSJA1000

ldx #BTR0
ldaa #%00000100 ; baudrate prescaler 5, synchron jump width 1
jsr writeSJA1000

ldx #BTR1
ldaa #%00111010 ; 1 samplepoint, tSEG2: 4 cycles, tSEG1: 11 cycles
bsr writeSJA1000

ldx #AMR
ldaa #$00 ; don't mask identifiers of received messages
jsr writeSJA1000

ldx #ACR ; accept only messages with identifier
ldaa #$80 ; starting %1000 0000 (other 3 bits don't care)
jsr writeSJA1000

ldx #CR ; leave reset-mode, disable CAN-interrupts
ldaa #$00 ; and switch to normal operation
jsr writeSJA1000

; ***** Prepare the transmit buffer to send out a byte *****
;
; Transmit buffer layout (in BasicCAN-Mode):
; (the RXBUF receive buffer layout is similar)
;
; TXBUF : Identifier Byte 1 (ID.10 .. ID.3)
; TXBUF+1 : Identifier Byte 2 (ID.2 .. ID.0, RTR, DLC.3 .. DLC.0)
; TXBUF+2..9 : Transmit Data Bytes 1..8
;
; ID.10 .. ID.0 : Identifier bits of the message
; RTR : Remote Transmission Request (1=request transmission, 0a frame)
; DLC.3 .. DLC.0 : Data Length Code (0 to 8)

ldx #TXBUF ; Set up Identifier Byte 1
ldaa #$81 ; send data to CAN-adress %1000 0001
bsr writeSJA1000

ldx #TXBUF+1 ; Set up Identifier Byte 2
ldaa #$01 ; the rest of 11-bit identifier: %000
bsr writeSJA1000 ; and 1 byte to send (DLC.3 .. DLC.0) bsr initSC0 ; Set up the Serial Interface 0

; ***** Main program loop *****
;
; Checks if new serial data is avaiable and transfers them via CAN-bus
; with the identifier %10010000000 and
; redirect messages from the CAN-Bus with identifiers starting with
; %10000000 to the host PC.
; The programm can be terminated by sending a 27 (ASCII-ESC) to the
; serial interface of the HC12compact board.

Send brclr SC0SR1,$20,Rec ; if SC0 receive buffer=empty, check for CAN data
bsr getSC0 ; fetch new data from SC0
cmpa #27 ; <ESC>-key pressed?
beq End ; yes -> terminate program

bsr putSC0 ; local echo of serial data
psha ; save byte onto Stack

Sloop ldx #SR ; read out SJA1000 Status Register
bsr readSJA1000
anda #%00000100 ; mask the Transmit Buffer Status Bit (TBS)
beq Sloop ; wait until the Transmit Buffer is released

pula ; get byte back from Stack
ldx #TXBUF+2 ; write new data into the CAN-
bsr writeSJA1000 ; transmitt buffer

ldx #CMR ; set transmission request bit
ldaa #$01 ; (transmit data via CAN)
bsr writeSJA1000

Rec ldx #SR ; read out the SJA1000 status register
bsr readSJA1000

anda #%00000001 ; isolate receive buffer status bit
beq Send ; if CAN receive buffer=empty, check for serial data
ldx #RXBUF+2 ; read new byte from receive buffer
bsr readSJA1000

bsr putSC0 ; transmit the byte to host PC

ldx #CMR
ldaa #%00000100 ; release the receive buffer
bsr writeSJA1000

bra Send ; check for new serial data

End rts ; back to monitor ; Func: returns the contents of a given register from SJA1000-CAN-Controller
; Args: X = register address
; Retn: A = data
; Dest: -

readSJA1000 stx CAN_ADDR-1
ldaa CAN_DATA
rts

; Func: writes a byte to a given SJA1000-CAN-Controller address
; Args: X = register address, A = new contents
; Retn: -
; Dest: -

writeSJA1000 stx CAN_ADDR-1
staa CAN_DATA
rts

; Func: Initialize serial communication interface SC0 (19200 baud, 8N1)
; Args: -
; Retn: -
; Dest: -

initSC0 clr SC0BDH
movb #$1A,SC0BDL ; set baud rate to 19200
clr SC0CR1 ; 8 data bits, 1 stop bit, no parity
movb #$0C,SC0CR2 ; enable receiver and transmitter
rts

; Func: Gets a byte from SC0
; Args: -
; Retn: A = byte
; Dest: -

getSC0 brclr SC0SR1,$20,getSC0 ; wait for receive data register full
ldaa SC0DRL ; read out data register
rts

; Func: Sends out a byte via SC0
; Args: A = byte
; Retn: -
; Dest: -

putSC0 brclr SC0SR1,$80,putSC0 ; wait until transmit data register=empty
staa SC0DRL ; send new data
rts

-----Original Message-----
From: kuinton [mailto:]
Sent: Tuesday, January 20, 2004 2:36 PM
To:
Subject: [68HC12] CAN Programming Does anyone have any sample code to transmit and receive messages
through the CAN port for the DP256 model of HC12? Please let me
know... i tried to program it, but it ended up that i was using the
wrong version... and the registers were all in a different place, and
confusion ensued... please let me know ASAP guys. Thanks. --------------------To learn more about Motorola Microcontrollers, please visit
http://www.motorola.com/mcu
o learn more about Motorola Microcontrollers, please visit
http://www.motorola.com/mcu


I wrote all this CAN stuff for the D60A which conforms to MSCAN. The D60A
has an RXFG and RXBG buffer system and you will work from the RXFG buffer.
The sending of messages is done with a triple buffer scheme. If this is the
same as the dp256 then I can tell you that there are application notes
showing the algorithm for sending using a linked list. Also there is a
great source of information on this very subject in Prof. Han-way Huang's
book on the 68HC12 with a lot of very good example code for the CAN module.
On RXing a frame, I stuff the frame into a FIFO queue and access the
messages in the main program code with another pointer. I use a separate
data buffer that I use to access messages to be sent from the TX routine.
After all this, I also discovered that there were critical sections in the
code that needed to be made atomic - the old sink and source at different
rates problem! If you need information at that particular subject there is
a professor Valvano at UTexas which gives more information on his book. To
be truthful the CAN site at vector-informatik.de did not really offer any
appreciable amount of help because these people seem to all be working at
upper levels of CAN protocols and not very many people there seem to know
much about MSCAN. Then again I did find the port.de site from the CAN site
and it helped me solve a rather nasty little bug that was driving me crazy
when I accessed their calculator to get the bit rate constants that I needed
but was calculating in error.
Sydney
----- Original Message -----
From: kuinton
To:
Sent: Tuesday, January 20, 2004 4:36 PM
Subject: [68HC12] CAN Programming Does anyone have any sample code to transmit and receive messages
through the CAN port for the DP256 model of HC12? Please let me
know... i tried to program it, but it ended up that i was using the
wrong version... and the registers were all in a different place, and
confusion ensued... please let me know ASAP guys. Thanks.
--------------------To learn more
about Motorola Microcontrollers, please visit
http://www.motorola.com/mcu
o learn more about Motorola Microcontrollers, please visit
http://www.motorola.com/mcu

----
--
Yahoo! Groups Links

a.. To