cancel
Showing results for 
Search instead for 
Did you mean: 

CAN protocol between 2 or more devices

puneethj
Associate II
Posted on September 08, 2015 at 14:59

Hi every one I want to establish a connection using CAN between two STM32F407 boards, my CAN configuration is working on same board, CAN1 to CAN2 is successful, But i am not able to send the same frame to different board, The problem is i am not able to debug 2 devices at the same time using my laptop, Please guide me on this

void CAN_Configuration(void) {
CAN_InitTypeDef CAN_InitStructure;
/* CAN register init */
CAN_DeInit(CAN1);
CAN_DeInit(CAN2);
/* CAN2 configuration */
CAN_InitStructure.CAN_TTCM = DISABLE; // Time-triggered communication mode = DISABLED
CAN_InitStructure.CAN_ABOM = DISABLE; // Automatic bus-off management mode = DISABLED
CAN_InitStructure.CAN_AWUM = DISABLE; // Automatic wake-up mode = DISABLED
CAN_InitStructure.CAN_NART = DISABLE; // Non-automatic retransmission mode = DISABLED
CAN_InitStructure.CAN_RFLM = DISABLE; // Receive FIFO locked mode = DISABLED
CAN_InitStructure.CAN_TXFP = DISABLE; // Transmit FIFO priority = DISABLED
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; // Normal CAN mode
/* quanta 1+6+7 = 14, 14 * 24 = 336, 42000000 / 336 = 125000 */
/* CAN Baudrate = 125Kbps (CAN clocked at 42 MHz) Prescale = 24 */
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; // Synchronization jump width = 1
CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq; //6
CAN_InitStructure.CAN_BS2 = CAN_BS2_7tq; //7
CAN_InitStructure.CAN_Prescaler = 24; // baudrate 1Mbps
CAN_Init(CAN1, &CAN_InitStructure);
CAN_Init(CAN2, &CAN_InitStructure);
}
void CAN_FilterConfiguration(void) {
CAN_FilterInitTypeDef CAN_FilterInitStructure;
/* CAN filter configuration */
CAN_FilterInitStructure.CAN_FilterNumber = 0; // CAN 1
CAN_FilterInitStructure.CAN_FilterNumber = 14; // CAN 2
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0; // FIFO = 0
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; // Filter mode = identifier mask based filtering
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_16bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
}
void CAN_TxMessage(void) {
CanTxMsg TxMessage;
// transmit */
TxMessage.StdId = 0x123;
TxMessage.ExtId = 0x00;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 8;
TxMessage.Data[0] = * ((unsigned char *)&ADC1->DR);
TxMessage.Data[1] = ((uint32_t)&ADC1->DR >> 8);
TxMessage.Data[2] = 0xff;
TxMessage.Data[3] = 0x07;
uint8_t TransmitMailbox = 0;
volatile uint32_t i;
static int j = 0;
TxMessage.Data[4] = ADCDmaValuesc1[1];
TxMessage.Data[5] = 0x01;
TxMessage.Data[6] = 0x02;
TxMessage.Data[7] = 0x03;
j++;
TransmitMailbox = CAN_Transmit(CAN1, &TxMessage);
i = 0;
while((CAN_TransmitStatus(CAN1, TransmitMailbox) != CANTXOK) && (i != 0xFFFFFF)) // Wait on Transmit
{
i++;
}
CAN2RX(); // Pump RX
}
void CAN2RX(void)
{
CanRxMsg RxMessage;
if (CAN_MessagePending(CAN2, CAN_FIFO0))
{
/* receive */
CAN_Receive(CAN2, CAN_FIFO0, &RxMessage);
datarx[0] = RxMessage.StdId;
datarx[1] = RxMessage.DLC;
datarx[2] = RxMessage.Data[0];
datarx[3] = RxMessage.Data[1];
datarx[4] = RxMessage.Data[2];
datarx[5] = RxMessage.Data[3];
datarx[6] = RxMessage.Data[4];
datarx[7] = RxMessage.Data[5];
datarx[8] = RxMessage.Data[6];
datarx[9] = RxMessage.Data[7];
ADC_Val2 = datarx[2] | (datarx[3] << 8);
}
}

#timer #stm32f4 #bxcan
7 REPLIES 7
Posted on September 08, 2015 at 17:12

I guess you're going to have to figure out how to debug things, and how your code flows/behaves without a single-step debugger. Perhaps you can instrument your code better, and use a serial port, along with serial dongles and terminal applications to allow you to watch what's going on. Create a little monitor application so you can interact with your devices.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
jpeacock
Associate III
Posted on September 08, 2015 at 19:23

Are both boards identical, do they both have the same code, and are both using an internal oscillator or external crystal?  What do the error registers show on the CAN interface?

  Jack Peacock

LMI2
Lead
Posted on September 08, 2015 at 20:34

And are grounds from both of the card connected together?

puneethj
Associate II
Posted on September 09, 2015 at 10:05

@Community member, Yes identical boards, Yes same code CAN1 transmits and CAN2 Receives, External Oscillator at max speed 168 MHz. I dont know what exactly this means Error Registers on CAN interface, If it is about flag status, I receive nothing, everything is at reset.

@Lei Mich, I actually missed this point, I will connect the ground and try again as soon as i get back to work. Thanks

jpeacock
Associate III
Posted on September 09, 2015 at 13:56

If the CAN registers are at reset it is likely you have not enabled the CAN peripheral clock with an RCC call:

RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); 
CAN_DBGFreeze(Iob->Info.CANx, DISABLE); // do not freeze CAN bus while debugging

I don't see in your code where the clock is enabled. If the clock is off registers will not change and the peripheral won't run. Jack Peacock
jpeacock
Associate III
Posted on September 09, 2015 at 13:58

Ignore that second line, part of my own driver infrastructure.

puneethj
Associate II
Posted on September 10, 2015 at 11:43

I have enabled the clock in a separate function, As i said Communication between CAN1 and CAN2 is successful on the same board, The problem is when i try to communicate with 2 different boards,