cancel
Showing results for 
Search instead for 
Did you mean: 

Bulk data transfer on CAN bus

puneethj
Associate II
Posted on November 13, 2015 at 22:40

Hi guys i have managed to communicate using CAN protocol now i want to send around 200 16 bit values from 1 stm32f4 to another stm32f4 below is the code to transfer 8 values, How can i improve my code to transfer 200 values.. can i use same STDID

void CAN_Txvalues(void) {
CanTxMsg TxMessage;
// transmit */
TxMessage.StdId = 0x150;
TxMessage.ExtId = 0x00;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 8;
TxMessage.Data[0] = (ADCDmaValuesc1[0] >> 8) ;
TxMessage.Data[1] = (ADCDmaValuesc1[0]);
TxMessage.Data[2] = (ADCDmaValuesc1[1] >> 8) ;
TxMessage.Data[3] = (ADCDmaValuesc1[1]);
TxMessage.Data[4] = (ADCDmaValuesc1[2] >> 8) ;
TxMessage.Data[5] = (ADCDmaValuesc1[2]);
TxMessage.Data[6] = (ADCDmaValuesc1[3] >> 8) ;
TxMessage.Data[7] = (ADCDmaValuesc1[3]);
uint8_t TransmitMailbox = 0;
do
{
TransmitMailbox = CAN_Transmit( CAN2, &TxMessage );
}
while( TransmitMailbox == CAN_NO_MB );
CAN_Txvalues2();// next values
}
void CAN_Txvalues2(void) {
CanTxMsg TxMessage;
// STM_EVAL_LEDOn(LED5);
// transmit */
TxMessage.StdId = 0x151;
TxMessage.ExtId = 0x00;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 8;
TxMessage.Data[0] = (ADCDmaValuesc1[4] >> 8) ;
TxMessage.Data[1] = (ADCDmaValuesc1[4]);
TxMessage.Data[2] = (ADCDmaValuesc1[5] >> 8) ;
TxMessage.Data[3] = (ADCDmaValuesc1[5]);
TxMessage.Data[4] = (ADCDmaValuesc1[6] >> 8) ;
TxMessage.Data[5] = (ADCDmaValuesc1[6]);
TxMessage.Data[6] = (ADCDmaValuesc1[7] >> 8) ;
TxMessage.Data[7] = (ADCDmaValuesc1[7]);
uint8_t TransmitMailbox = 0;
do
{
TransmitMailbox = CAN_Transmit( CAN2, &TxMessage );
}
while( TransmitMailbox == CAN_NO_MB );
}
void CANrx(void) {
if(stdid =150)
{
save data in adc values 0 to 3
}
if(stdid = 151)
{
save data in adc values 4 to 7
}
}

But i badly need to improve the way my code works.. Any help is most welcome Thanks guys


#becan #!stm32f4-disco
7 REPLIES 7
Posted on November 13, 2015 at 22:57

But i badly need to improve the way my code works..

Consider using one subroutine, and passing in a pointer, and a message number. And then call that in a loop.

Hard coding everything seems like a very bad habit that you need to break as so as possible.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
jpeacock
Associate II
Posted on November 16, 2015 at 03:20

Assuming you are not using any particular CAN protocol and you don't want to change the message ID then a common method is to use the first two bytes of the data area as the index for the first of three values being sent, followed by three sequential values.  For example, the first message would be: 0x0000  val0  val1  val2.  This would be followed by: 0x0003  val3  val4  val5, and so on.  You can ack each message by sending back just the index.

A more sophisticated method is the SDO transfer used in the CANopen protocol.  This uses variations on the above to send variable types and lengths of data.

  Jack Peacock
puneethj
Associate II
Posted on November 16, 2015 at 12:31

Hey jack, thanks for replying, could you please post an example for SDO transfer, i would like to try that. Thanks

jpeacock
Associate II
Posted on November 16, 2015 at 13:45

SDO (System Data Objects) is part of the open source CANopen network protocol.  Search for the CAN in Automation website and you'll find the specifications for it.  There are some open source CANopen examples, search for CANfestival.

You need quite a bit of infrastructure to use SDO.  It requires a system object dictionary to obtain object metadata (the type and size for an object).  In simple terms you send an object ID and the data (in segments if over 32 bit).

  Jack Peacock

puneethj
Associate II
Posted on November 17, 2015 at 18:18

Hi everyone I read CAN1 has connection to 512 byte SRAM memory  so is there any way to save the received frames in the SRAM , if so how to access those messages, if any one already worked on CAN1  with SRAM please help me thank you.

Posted on November 17, 2015 at 18:52

I suspect it's used for the Filter/FIFO arrangement. Suggest you review the documentation and look at if/where it is mapped into the 32-bit address range. If it is there, then presumably you can access it like any other memory.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
jpeacock
Associate II
Posted on November 17, 2015 at 18:59

That's internal memory, no direct access.  Most of the memory is used for filters and FIFOs anyway.  Short answer, no you can't use the memory for anything.  Incoming messages have to be moved from the two FIFOs (3 deep) and saved somewhere in SRAM.  Same for TX, messages have to be queued into one of the three mailboxes.

The memory is only accessible from CAN1 through setting the filters.  CAN2 uses the same filter area as CAN1, but a register specifies where the CAN2 filters start.  I suppose you could store data in unused filter slots but it would be slow and clumsy, and only save a few bytes of RAM at a cost of many more bytes of flash.

  Jack Peacock