AnsweredAssumed Answered

STM32F4 + Arduino Uno Can Bus Comminication Error

Question asked by doganay.serhat on Oct 15, 2015
Latest reply on Oct 15, 2015 by doganay.serhat
Hi everyone,

I have STM32F4 and Arduino uno. I want to communicate each other Stm and arduino. But, can't run its. Both, 125 KBPS.  I communicated between Can1 and Can2 with STM32F4. Thereafter, i communicated between two Arduino Uno. But, I can't communicate between Arduino Uno and STM32F4. I used MCP2551 for STM32F4 and MCP2515 Can Module for Arduino uno.   This, my final year project. Thanks...

// This codes Arduino Uno Can-Bus.. (125KBPS..)
#include <mcp_can.h>
#include <SPI.h>
 
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 10;
 
MCP_CAN CAN(SPI_CS_PIN);                                    // Set CS pin
 
void setup()
{
    Serial.begin(115200);
 
START_INIT:
 
    if(CAN_OK == CAN.begin(CAN_125KBPS))                   // init can bus : baudrate = 500k
    {
        Serial.println("CAN BUS Shield init ok!");
    }
    else
    {
        Serial.println("CAN BUS Shield init fail");
        Serial.println("Init CAN BUS Shield again");
        delay(100);
        goto START_INIT;
    }
}
 
unsigned char stmp[8] = {0, 1, 2, 3, 4, 5, 6, 7};
void loop()
{
    // send data:  id = 0x00, standrad frame, data len = 8, stmp: data buf
    CAN.sendMsgBuf(0x00, 0, 8, stmp);
    delay(100);                       // send data per 100ms
}
 
/*********************************************************************************************************
  END FILE
*********************************************************************************************************/



This Codes STM32F4 CAN1 Transmitter And CAN2 Receiver...

//  CAN1 PB8 (RX), PB9 (TX) //CAN1'den alinan veri CAN2'ye gonderiliyor.
//  CAN2 PB5 (RX), PB6 (TX)  Can2'den herhangi bir veri gönderilmedigi icin logic analyzer'da bos gozukmekte.
//  USART6 PC7 (RX), PC6 (TX)
//En son usart 2 kullan1yoruz PA2 TX, PA3 RX
//usart2 DE YESIL LED DEVAMLI YANIYOR
  
#include "stm32f4xx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h> //
  
//****************************************************************************
  
void RCC_Configuration(void)
{
  /* --------------------------- System Clocks Configuration -----------------*/
 // Enable the APB1 periph clock for USART2
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
  
  /* Enable CAN clocks */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1 | RCC_APB1Periph_CAN2, ENABLE);
  
  /* GPIO[B,D,C,A] clock enable */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOA| RCC_AHB1Periph_GPIOC, ENABLE);
}
  
//****************************************************************************
  
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  
  /*-------------------------- GPIO Configuration ----------------------------*/
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  
  /* Configure USART RX and TX pins */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
  /* Connect USART pins to AF */
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
  
  /* Configure CAN1 RX and TX pins */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  
  /* Connect CAN1 pins to AF */
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_CAN1); // CAN1_RX
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_CAN1); // CAN1_TX
  
  /* Configure CAN2 RX and TX pins */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  
  /* Connect CAN2 pins to AF */
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_CAN2); // CAN2_RX
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_CAN2); // CAN2_TX
}
  
//****************************************************************************
  
void USART6_Configuration(void)
{
  USART_InitTypeDef USART_InitStructure;
  
  /* USARTx configuration ------------------------------------------------------*/
  /* USARTx configured as follow:
        - BaudRate = 115200 baud
        - Word Length = 8 Bits
        - One Stop Bit
        - No parity
        - Hardware flow control disabled (RTS and CTS signals)
        - Receive and transmit enabled
  */
  USART_InitStructure.USART_BaudRate = 9600; // Default 115200 idi.
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  
  USART_Init(USART2, &USART_InitStructure);
  
  USART_Cmd(USART2, ENABLE);
}
  
//****************************************************************************
  
void CAN_Configuration(void)
{
  RCC_ClocksTypeDef     RCC_Clocks;
  CAN_InitTypeDef       CAN_InitStructure;
  CAN_FilterInitTypeDef CAN_FilterInitStructure;
  
  RCC_GetClocksFreq(&RCC_Clocks);
  
  /* CAN register init */
  CAN_DeInit(CAN1);
  CAN_DeInit(CAN2);
  
  CAN_StructInit(&CAN_InitStructure);
  
  /* CAN cell init */
  CAN_InitStructure.CAN_TTCM = DISABLE;
  CAN_InitStructure.CAN_ABOM = DISABLE;
  CAN_InitStructure.CAN_AWUM = DISABLE;
  CAN_InitStructure.CAN_NART = DISABLE;
  CAN_InitStructure.CAN_RFLM = DISABLE;
  CAN_InitStructure.CAN_TXFP = DISABLE;
  CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
  
  /*
 
  quanta 1+6+7 = 14, Bir bitlik sürenin degeri 14 quanta birimidir. SJM=1, BS1=6, BS=7 quanta olarak ayarlanmistir.
  APB2 bus hattinin clock degeri 42 mhz oldugundan,
    buda yaklasik 24 nanosaniye yapar. Yani islemcinin 1 clock darbesi 24*14=336 quanta birimine esit olur.
    (14 * 24 = 336)
     
   
     42000000 / 336 = 125000 */
  /* CAN Baudrate = 125Kbps (CAN clocked at 42 MHz) Prescale = 24 */
     
     
  /* Requires a clock with integer division into APB clock */
  
  CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; // 1+6+7 = 14, 1+14+6 = 21, 1+15+5 = 21
  CAN_InitStructure.CAN_BS1 = CAN_BS1_15tq; //eski degeri 6
  CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;// eski degeri 7
  CAN_InitStructure.CAN_Prescaler = 16;
    //Bu degerler icin logic analyzer'da hatasiz sonuc elde edildi. Hicbir error problemiyle karsilasilmadi.
     
    //
  
  CAN_Init(CAN1, &CAN_InitStructure);
  CAN_Init(CAN2, &CAN_InitStructure);
  
  /* CAN filter init */
  CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; // IdMask or IdList
  CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; // 16 or 32
  
  CAN_FilterInitStructure.CAN_FilterIdHigh      = 0x0000; // Everything, otherwise 11-bit in top bits
  CAN_FilterInitStructure.CAN_FilterIdLow       = 0x0000;
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh  = 0x0000;
  CAN_FilterInitStructure.CAN_FilterMaskIdLow   = 0x0000;
  
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0; // Rx
  CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
  
  CAN_FilterInitStructure.CAN_FilterNumber = 0; // CAN1 [ 0..13]
  
  CAN_FilterInit(&CAN_FilterInitStructure);
  
  CAN_FilterInitStructure.CAN_FilterNumber = 14; // CAN2 [14..27]
  
  CAN_FilterInit(&CAN_FilterInitStructure);
}
  
//****************************************************************************
  
void CAN2RX(void)
{
  CanRxMsg RxMessage;
  
  if (CAN_MessagePending(CAN2, CAN_FIFO0))
  {
    memset(&RxMessage, 0, sizeof(RxMessage));
  
    /* receive */
    CAN_Receive(CAN2, CAN_FIFO0, &RxMessage);
  
    printf("RX %04X - %02X - %02X %02X %02X %02X %02X %02X %02X %02X\n",
      RxMessage.StdId, RxMessage.DLC,
      RxMessage.Data[0],RxMessage.Data[1],RxMessage.Data[2],RxMessage.Data[3],
      RxMessage.Data[4],RxMessage.Data[5],RxMessage.Data[6],RxMessage.Data[7]);
  }
}
  
//****************************************************************************
  
void CAN1TX(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] = 0x02;
  TxMessage.Data[1] = 0x11;
  TxMessage.Data[2] = 0x11;
  TxMessage.Data[3] = 0x11;
  
  while(1) // Do not want to exit
  {
    volatile uint32_t i;
    static int j = 0;
    uint8_t TransmitMailbox = 0;
  
    TxMessage.Data[4] = (j >>  0) & 0xFF; // Cycling
    TxMessage.Data[5] = (j >>  8) & 0xFF;
    TxMessage.Data[6] = (j >> 16) & 0xFF;
    TxMessage.Data[7] = (j >> 24) & 0xFF;
    j++;
  
    TransmitMailbox = CAN_Transmit(CAN1, &TxMessage);
  
    i = 0;
    while((CAN_TransmitStatus(CAN1, TransmitMailbox) != CANTXOK) && (i != 0xFFFFFF)) // Wait on Transmit
    {
      i++;
      CAN2RX(); // Pump RX
    }
  
    CAN2RX();
  }
}
  
//****************************************************************************
  
int main(void)
{
  RCC_Configuration();
  
  GPIO_Configuration();
  
  USART6_Configuration();
  
  CAN_Configuration();
  
  puts("CAN Test");
  
  CAN1TX();
  
  while(1); // Don't want to exit
     
     
}
#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  
  /* Infinite loop */
  while (1)
  {
  }
}
#endif
 
//******************************************************************************
// Hosting of stdio functionality through USART6
//******************************************************************************
   
#include <rt_misc.h>
   
#pragma import(__use_no_semihosting_swi)
   
struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;
FILE __stdin;
   
int fputc(int ch, FILE *f)
{
  while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
   
  USART_SendData(USART2, ch);
   
  return(ch);
}
   
int fgetc(FILE *f)
{
  char ch;
   
  while(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET);
   
  ch = USART_ReceiveData(USART2);
   
  return((int)ch);
}
   
int ferror(FILE *f)
{
  /* Your implementation of ferror */
  return EOF;
}
   
void _ttywrch(int ch)
{
  while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
   
  USART_SendData(USART2, ch);
}
   
void _sys_exit(int return_code)
{
label:  goto label;  /* endless loop */
}

Outcomes