CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

CAN bus with data 16 bits

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
carlosma



Joined: 24 Mar 2004
Posts: 53
Location: Portugal

View user's profile Send private message Send e-mail MSN Messenger

CAN bus with data 16 bits
PostPosted: Fri Apr 28, 2006 5:19 am     Reply with quote

Hello,
I need send and receive data CAN BUS with data 16bits.
I change the driver can-18xxx8.C to int16 in the DATA variable, but have Error.

With 8 bits using the standard can-18xxx8.c and 18F458 works fine.
I am beginning in CAN BUS protocol. Somebody will be able to help me or has experience in data 16 or 32 bits.

Thanks
Carlos
newguy



Joined: 24 Jun 2004
Posts: 1903

View user's profile Send private message

PostPosted: Fri Apr 28, 2006 11:18 am     Reply with quote

The CAN protocol sends packets of 8 bits only. Up to 8 bytes can be transfered in a single transaction. The data to be transmitted is loaded into out_data[0...7], and the can_putd() function transmits this data. One of the arguments of the can_putd() function is the length of data (i.e. the number of bytes of out_data[]) you want to send.

If you want to transfer 16 bits, you would load out_data[0] with half the data, and out_data[1] with the other half. Then you would call can_putd() with the data length argument set to 2. Easy.
iso9001



Joined: 02 Dec 2003
Posts: 262

View user's profile Send private message

PostPosted: Fri Apr 28, 2006 11:34 am     Reply with quote

Like newguy said,

CAN is set up to send 8 bytes each of 8 bits, the id, crc, and dlc. Of course you could make your data mean anything you wanted. Ie: You still send 64bits but to you, 4 int16's were sent.

Now, if you mean make the module send 8 blocks of 16 bits... Even if you could somehow manage to trick the unit into sending 128bits, you would have two major problems: The CRC would be corrupted and usless, then no other node would accpet the message except your own.

You can make 8x8 4x16 2x32, always limited to 64bits. Unless you load the id frame with some data, but thats pretty messy
jma_1



Joined: 08 Feb 2005
Posts: 147
Location: Wisconsin

View user's profile Send private message

PostPosted: Fri Apr 28, 2006 11:46 am     Reply with quote

Greetings,
The CAN message format specifies the number of data bits. A strict message structure is followed. Each data field is 0 to 8 bytes.

One approach around modifying the data field would be to create proprietary messages, following the standard CAN message structure, but specific meaning for your identifiers (source address, destination adress, message type, multiple packet, etc).

Message Structure:
(IFS)
Start of Frame
Arbitration Field (11 or 29 bit)
Control Field
Data Field (0 to 8 bytes)
CRC Field
Acknowledge Field
End of Frame
Interframe Space (IFS)

Cheers,
JMA
sjbaxter



Joined: 26 Jan 2006
Posts: 141
Location: Cheshire, UK

View user's profile Send private message Visit poster's website

PostPosted: Fri Apr 28, 2006 4:19 pm     Reply with quote

Just to clarify JMA's comments and reinforce newguys post ...

The CAN message has a dedicated data payload area (maximum of 8 bytes). The rest of the message structure shown in JMA's post is handled at the hardware level by the controller and its format cannot be altered (apart from changing the id length from 11 to 29 bits ... or standard/extended id's).

Depending on the number of payload data bytes you want to send, you set the 'dlc' to reflect the number of bytes of 'useful data'. i.e

to send a message with:

no data, set dlc = 0;
1 data byte, set dlc = 1;
2 data bytes, set dlc = 2;
3 data bytes, set dlc = 3;
4 data bytes, set dlc = 4;
5 data bytes, set dlc = 5;
6 data bytes, set dlc = 6;
7 data bytes, set dlc = 7;
8 data bytes, set dlc = 8;

if you want to send more than 8 bytes, you need to implement a transport protocol, whereby you may send 6 bytes of data and 2 bytes indicating the packet or sequence number. (Real protocols are a bit more involved than this and involve handshaking and packet checking, etc).

For your problem (just sending 16 bits of data)

Code:
void main ()
{
    // CAN message info
    int32 id;
    int8 data[8];
    int8 dlc;
    int8 priority;
    int1 ext;
    int1 rtr;

    // data to send
    int16 value;

    value = 0xFE68;    // example 16 bits of data to send

    // create message
    id = 100;    // example message id
    data[0] = (int8)(value >> 8);    // bits 8 to 15
    data[1] = (int8)(value);    // bits 0 to 7
    dlc = 2;    // 2 bytes in data payload
    priority = 3;
    ext = false;   // 11 bit identifier
    rtr = false;    // data frame

    // send message (when tx buffer is free)
    while (!can_tbe());
        can_putd(id, &data[0], dlc, priority, ext, rtr);

    // main program loop
    for(;;)
    {
    }

}


In this example, the CAN node receiveing the data would need to 're-assemble' the two bytes into an int16 to complete the transfer of 'value' from one node to another.

Note: You can set dlc to 8 and only fill 2 bytes with real data. This is acceptable, but the CAN bus will have 6 extra bytes of data per message sent being thrown around that don't really mean anything, but just waste bus space (bandwidth).

For 32 bits of data :

Code:
    // data to send
    int32 value;

    value = 0xFE684610;    // example 32 bits of data to send

    // create message
    id = 100;    // example message id
    data[0] = (int8)(value >> 24);    // bits 24 to 31
    data[1] = (int8)(value >> 16);    // bits 16 to 23
    data[2] = (int8)(value >> 8);    // bits 8 to 15
    data[3] = (int8)(value);    // bits 0 to 7
    dlc = 4;    // 4 bytes in data payload
    priority = 3;
    ext = false;   // 11 bit identifier
    rtr = false;    // data frame

_________________
Regards,
Simon.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group