cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103 + CAN -> microcontroller does not release the frame from FIFO banks

PLacz
Associate

Hi everyone,

I have a problem with implementation CAN protocol on STM32F103C8. 

I have a blue pill board connected through PA11 (CAN Rx) and PA12 (CAN Tx) to CJMCU-1051 transceiver ( relation between connection: CRX -> PA11, CTX -> PA12). 

The CANL and CANH signals from the transceiver are connected to the CAN bus on which there are already two nodes and they communicate with each other with baudrate = 500kBps (4 frames run on the network):

0693W000005BbAyQAK.pngSo network is working.

And now my code.

Clocks are configuring to max speed - 72MHz (of course PCLK1, according to RM , is sets to 36MHz).

void RCC_Conf(void)
{
  // RCC setting reset
  RCC_DeInit();
 
  // Turn on HSE
  RCC_HSEConfig(RCC_HSE_ON);
 
  // Wait up to HSE will be ready
  HSEStartUpStatus = RCC_WaitForHSEStartUp();
 
  if(HSEStartUpStatus == SUCCESS)
  {
	  /*
	   * the introduction of delays is (waitstate) for higher clock rates
	   * is due to the maximum frequency with which it is performed
	   * communication with Flash memory can be 24 MHz
	   */
	  FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
 
	  // wait for flash memory
	  FLASH_SetLatency(FLASH_Latency_2);
 
	  // HCLK = SYSCLK
	  RCC_HCLKConfig(RCC_SYSCLK_Div1);
 
	  // PCLK2 = HCLK
	  RCC_PCLK2Config(RCC_HCLK_Div1);
 
	  // PCLK1 = HCLK/2
	  RCC_PCLK1Config(RCC_HCLK_Div2);
 
	  // PLLCLK = 8MHz * 9 = 72 MHz
	  RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
 
	  // Turn on PLL
	  RCC_PLLCmd(ENABLE);
 
	  // Wait up to PLL will be ready
	  while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
 
	  // Select PLL as source of clock
	  RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
 
	  // Wait up to PLL will be the source of clock
	  while(RCC_GetSYSCLKSource() != 0x08);
 
	  // Turn on Włączenie clock signal supervision system
	  //RCC_ClockSecuritySystemCmd(ENABLE);
  }
}

Configuration of SysTick

void SysTick_Conf (void)
{
	SysTick_Config(F_PCLK2/8/1000);
	SysTick->CTRL &= ~SysTick_CTRL_CLKSOURCE_Msk;
}

And finally CAN configuration:

void CAN_Config(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;
  uint8_t ststus = 10;
 
  /* Configure CAN1 IOs **********************************************/
  /* GPIOA and AFIO clocks enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);
 
  /* Configure CAN1 RX pin */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(GPIOA, &GPIO_InitStructure)
 
  /* Configure CAN1 TX pin */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
 
  /* Configure CAN1 and CAN2 **************************************************/
  /* CAN1 and Periph clocks enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
 
   /* CAN1 and CAN2 register init */
  CAN_DeInit(CAN1);
//  CAN_DeInit(CAN2);
 
  /* Struct init*/
  CAN_StructInit(&CAN_InitStructure);
 
  /* CAN1 and CAN2  cell init */
  CAN_InitStructure.CAN_TTCM = DISABLE;
  CAN_InitStructure.CAN_ABOM = DISABLE;
  CAN_InitStructure.CAN_AWUM = ENABLE;//DISABLE;
  CAN_InitStructure.CAN_NART = DISABLE;
  CAN_InitStructure.CAN_RFLM = DISABLE;
  CAN_InitStructure.CAN_TXFP = ENABLE;
  CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
  CAN_InitStructure.CAN_SJW = CAN_SJW_4tq;
  CAN_InitStructure.CAN_BS1 = CAN_BS1_8tq;
  CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;
 
/* 500KBps */
  CAN_InitStructure.CAN_Prescaler =12;
 
 
  /*Initializes the CAN1  and CAN2 */
  ststus = CAN_Init(CAN1, &CAN_InitStructure);
//  CAN_Init(CAN2, &CAN_InitStructure);
 
  /* CAN1 filter init */
  CAN_FilterInitStructure.CAN_FilterNumber = 1;
  CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
  CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
  CAN_FilterInitStructure.CAN_FilterIdHigh = 0x1;
  CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
  CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
  CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
  CAN_FilterInit(&CAN_FilterInitStructure);
 
  TxMessage.StdId = 0x10;
  TxMessage.ExtId = 0x00;
  TxMessage.RTR = CAN_RTR_DATA;
  TxMessage.IDE = CAN_ID_STD;
  TxMessage.DLC = 4;
}

As answer from function 

ststus = CAN_Init(CAN1, &CAN_InitStructure);

I got value equal to 1, so CAN protocol is correctly implemented and it is in normal mode. This situation is confirmed by values of registers:

0693W000005BbFAQA0.pngIn main program loop I want to send a frame every 1s, the source_time variable is a variable incremented in the SysTick interrupt and I want to send it by the bus

while (1)
	{
		if(flag_)
		{
			TxMessage.Data[0] = (uint8_t)(source_time >> 24);
			TxMessage.Data[1] = (uint8_t)(source_time >> 16);
			TxMessage.Data[2] = (uint8_t)(source_time >> 8);
			TxMessage.Data[3] = (uint8_t)source_time;
			
			temp1 = CAN_Transmit(CAN1, &TxMessage);
			
			temp2 = CAN_GetLastErrorCode(CAN1);
			
			TransmitStatus[0] = CAN_TransmitStatus(CAN1,0);
			TransmitStatus[1] = CAN_TransmitStatus(CAN1,1);
			TransmitStatus[2] = CAN_TransmitStatus(CAN1,2);
			flag_ = 0;
		}
	}

The result is that transmission status is set to pending (the value is returned by the CAN_TransmitStatus function) for all FIFO banks, what is confirmed by registers:

0693W000005BbJHQA0.png 

After connection oscilloscope between microcontroller and transceiver I can notice that transceiver allow for transferring CRX frames (PA11 pin), o that I conclude that transceiver works properly:

0693W000005BbKtQAK.png 

Summing up, maybe someone has an idea why STM does not send a frame to the transceiver but is in pending mode all the time?

0 REPLIES 0