|
|
View previous topic :: View next topic |
Author |
Message |
carlosma
Joined: 24 Mar 2004 Posts: 53 Location: Portugal
|
CAN bus with data 16 bits |
Posted: Fri Apr 28, 2006 5:19 am |
|
|
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: 1909
|
|
Posted: Fri Apr 28, 2006 11:18 am |
|
|
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
|
|
Posted: Fri Apr 28, 2006 11:34 am |
|
|
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
|
|
Posted: Fri Apr 28, 2006 11:46 am |
|
|
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
|
|
Posted: Fri Apr 28, 2006 4:19 pm |
|
|
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. |
|
|
|
|
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
|