AnsweredAssumed Answered

NUCLEO-F103RB - CAN bus problem - No TX sent

Question asked by abramo.jacopo on Mar 20, 2015
Latest reply on Mar 20, 2015 by abramo.jacopo
Greetings,

I am currently testing the bxCAN integrated in the STM32F103RBT6 available on the Nucleo I'm using (F103RB). Up until now I used an example which should be able to transmit correctly a message, and also to receive them from an external source provided the presence of a CAN transceiver. But the problem is that, even by checking by using an oscilloscope, CAN_TX does not transfer what I want.

Here is the following code. I'm using the CAN1 peripheral, remapped on the PB8 and PB9 pins of the microcontroller.

#include <stm32f10x.h>
#define LED_pin 5
 
/* GPIO CAN: PD0 E PD1 */
 
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
GPIO_InitTypeDef GPIO_InitStructure, LED_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
 
uint32_t i;
 
CanTxMsg TxMessage;
CanRxMsg RxMessage;
uint8_t TransmitMailbox = 0;
 
void clock_init(void)
{                                                                          
  /*Configure all clocks to max for best performance.                                        
   * If there are EMI, power, or noise problems, try slowing the clocks*/                    
 
  /* First set the flash latency to work with our clock*/                                    
  /*000 Zero wait state, if 0  MHz < SYSCLK <= 24 MHz                                        
    001 One wait state, if  24 MHz < SYSCLK <= 48 MHz                                        
    010 Two wait states, if 48 MHz < SYSCLK <= 72 MHz */                                    
  FLASH_SetLatency(FLASH_Latency_1);                                                        
 
  /* Start with HSI clock (internal 8mhz), divide by 2 and multiply by 9 to                  
   * get maximum allowed frequency: 36Mhz                                                    
   * Enable PLL, wait till it's stable, then select it as system clock*/                    
  RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_9);                                      
  RCC_PLLCmd(ENABLE);                                                                        
  while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);                                      
  RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);                                                
 
  /* Set HCLK, PCLK1, and PCLK2 to SCLK (these are default */                                
  RCC_HCLKConfig(RCC_SYSCLK_Div1);                                                          
  RCC_PCLK1Config(RCC_HCLK_Div1);                                                            
  RCC_PCLK2Config(RCC_HCLK_Div1);                                                            
 
  /* Set ADC clk to 9MHz (14MHz max, 18MHz default)*/                                        
  RCC_ADCCLKConfig(RCC_PCLK2_Div4);                                                          
 
  /*To save power, use below functions to stop the clock to ceratin                          
   * peripherals                                                                            
   * RCC_PeriphClockCmd                                                                  
   */                                                                                                                               
 
}
 
void LED_init(void)
{
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  LED_InitStructure.GPIO_Pin =  GPIO_Pin_5;
  LED_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  LED_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &LED_InitStructure);
 
}
 
void CAN_TX()
{
  TxMessage.StdId=0x11;
  TxMessage.RTR=CAN_RTR_DATA;
  TxMessage.IDE=CAN_ID_STD;
  TxMessage.DLC=2;
  TxMessage.Data[0]=0xCA;
  TxMessage.Data[1]=0xFE;
 
  TransmitMailbox=CAN_Transmit(CAN1, &TxMessage);
  i = 0;
  while((CAN_TransmitStatus(CAN1, TransmitMailbox) != CAN_TxStatus_Ok) && (i != 0xFFFF))
  {
    i++;
  }
 
  i = 0;
  while((CAN_MessagePending(CAN1, CAN_FIFO0) < 1) && (i != 0xFFFF))
  {
    i++;
  }
 
  RxMessage.StdId=0x00;
  RxMessage.IDE=CAN_ID_STD;
  RxMessage.DLC=0;
  RxMessage.Data[0]=0x00;
  RxMessage.Data[1]=0x00;
  CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
}
 
void CAN_init(void)
{
 
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
 
  /* Configure CAN pins: CAN_TX and CAN_RX */
  /* CAN RX */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
 
  /* CAN TX */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
 
  GPIO_PinRemapConfig(GPIO_Remap1_CAN1,ENABLE);
 
//  /* Enable CAN reset state */
//  RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1, ENABLE);
//  /* Release CAN from reset state */
//  RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1, DISABLE);
 
  NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;;
  NVIC_Init(&NVIC_InitStructure);
 
  CAN_DeInit(CAN1);
  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 = ENABLE;
  CAN_InitStructure.CAN_RFLM = DISABLE;
  CAN_InitStructure.CAN_TXFP = DISABLE;
  CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack;
  CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
  CAN_InitStructure.CAN_BS1 = CAN_BS1_12tq;
  CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
  CAN_InitStructure.CAN_Prescaler = 1;
 
//  CAN_FilterInitStructure.CAN_FilterNumber=0;
//  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
//  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
//  CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
//  CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
//  CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
//  CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
//  CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
//  CAN_FilterInitStructure.CAN_FilterActivation=DISABLE;
 
  CAN_Init(CAN1, &CAN_InitStructure);
//  CAN_FilterInit(&CAN_FilterInitStructure);
  CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
 
}
 
void main (void)
{
    clock_init();
    LED_init();
    CAN_init();
    CAN_TX();
    while(1);
}
 
void USB_LP_CAN1_RX0_IRQHandler(void)
{
  if(CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET)
    CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
  CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);
}
 
void assert_failed(u8* file, u32 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)
  {
     for(i=0;i<100000;i++);
  }
}

Outcomes