Skocz do zawartości

STM32F103 + CAN -> procek nie wypuszcza ramki z banków FIFO


amilo_pa

Pomocna odpowiedź

Hej wszystkim,

Mam mały problem z zaimplementowaniem protokołu CAN na STM32F103 (tzw bluepillu). Ale po kolei.


Mam Bluepilla podłączonego poprzez PA11 (CAN_Rx) i PA12 (CAN_Tx) do transceivera CJMCU-1051 (wejscia CRX -> PA11 i CTX -> PA12 ). Sygnały CANL oraz CANH wychodzące z transceivera)  mam połączone z magistralą CAN na któej są już dwie nody i komunikują się ze sobą z baudratem =  500kBps  (po sieci biegają 4 ramki):

CAN_BUS.thumb.png.414fb8cef7800af61307dfcbdd555516.png

Więc sieć dzial.
 

I teraz mój kod.
Konfiguracja zegarów na maksymalne taktowanie - 72MHz ( PCLK1 zgodnie z RM ustawone na 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);

  }

}

SysTick skonfigurowany na 1ms:

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

 

No i czas na konfigurację CANa:

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_Mode_IPU//GPIO_Mode_AF_PP;
  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;
}

w odpowiedzi na wywołanie funkcji 

ststus = CAN_Init(CAN1, &CAN_InitStructure);

dostaję wartość1 czyli CAN_InitStatus_Success, co potwierdzają rejestry:

CAN_MCR__MSR.thumb.png.b1b9098a0b39bb5c83fea8b8b60e65fc.png

W głównej pętli programu chcę wysyłać ramkę co 1s, zmienna source_time jest to zmienna inkrementowana w przerwaniu od SysTicka i to ją chcę wysyłać po magostrali

	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;
		}
	}

 

Rezultatem jest ustawienie się statusu transmisji na (wartość zwraca przez funkcję CAN_TransmitStatus) na pending dla wszystkich banków FIFO, co potwierdzają rejestry

TXRQ.thumb.png.d55848831afd2124fe771b3de1ae0599.png

Po podłączeniu sond oscyloskopu pomiędzy uP a transceiver, można zaobserwować, że transceiver przepuszcza ramki biegające po CANie -> więc nie jest uszkodzony

Rx_Tx.thumb.png.4e16f70578a2ffd7cb2ad6d4ef87dc2f.png

 

Reasumując, może ma ktoś pomysł dlaczego STM nie wypuszcza ramki do transcivera tylko jest cały czas w trybie pending? 

Edytowano przez amilo_pa
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.