STM32F0 CAN Neden bu kadar geç init olur?

Başlatan Mucit23, 24 Kasım 2018, 16:59:09

Mucit23

Selamlar

STM32F042C6 ile CanBus üzerine çalışmalar yapıyorum. Daha önce F103 ile yapmıştım. Ayarlar çok benziyor. Örnek uygulamalara da bakarak bir init kodu hazırladım. CAN Modülünü LoopBack modunda çalıştırıp birşeyler gönderip alıyorum. Can donanımı init edildikten sonra herşey güzel çalışıyor mesaj gönderip mesaj alabiliyorum. Mesaj geldiğinde kesme felan oluşuyor. Fakat sorun şu ki. CAN Donanımının İnit olması ortalama 4-5 sn sürüyor. Neye takıldığını anlayamadım. Init rutinlerim aşağıdaki gibi.

void CAN_Configuration(void){
  CAN_InitTypeDef        CAN_InitStructure;
  CAN_FilterInitTypeDef  CAN_FilterInitStructure;
  GPIO_InitTypeDef  GPIO_InitStructure;
  NVIC_InitTypeDef  NVIC_InitStructure;
	  /* CAN Periph clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
	
  /* Configure CAN RX and TX pins */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
	
  /* Connect CAN pins to AF7 */
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_0);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_0); 
	
  /* CAN register init */
  CAN_DeInit(CAN);
  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_LoopBack;
  CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
	
  /* CAN Baudrate = 125kbps (CAN clocked at 36 MHz) */
  CAN_InitStructure.CAN_BS1 = CAN_BS1_9tq;
  CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
  CAN_InitStructure.CAN_Prescaler = 2;
  CAN_Init(CAN, &CAN_InitStructure);
	
  /* CAN filter init */
  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 = ENABLE;
  CAN_FilterInit(&CAN_FilterInitStructure);
	
  /* NVIC configuration *******************************************************/
  NVIC_InitStructure.NVIC_IRQChannel = CEC_CAN_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPriority = 0x0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
	
  /* Enable FIFO 0 message pending Interrupt */
  CAN_ITConfig(CAN, CAN_IT_FMP0, ENABLE);
}

  CAN_Init(CAN, &CAN_InitStructure);fonksiyonunu çapırdıktan 4-5 sn sonra program geri geliyor. Ve Can Inıt status Fail olarak geri dönüyor. Yani Can donanımı düzgün init olmuyor ama çalışmaya çalışıyor.

CAN_Init Fonksiyonunu incelediğimde aşağıdaki kısımda takıldığını görüyorum.

   /* Wait the acknowledge */
   wait_ack = 0;

   while (((CANx->MSR & CAN_MSR_INAK) == (uint16_t)CAN_MSR_INAK) && (wait_ack != INAK_TIMEOUT))
   {
     wait_ack++;
   }

döngü içinde 5 sn kadar bekleniyor ve zaman aşımı olup döngüden çıkıyor.

Acaba eksik birşeymi yapıyorum? Neden böyle davranıyor? Bilgisi olan varmı? Yukarıdaki döngüden çıktıktan sonra can loopback modunda çalışıyor. Sıkıntı olmaması lazım.



Elektroemre

#1
Bu satıları:
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_0);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_0);

bu şekilde değiştirip bir dene:
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_4);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_4);

https://www.st.com/resource/en/datasheet/stm32f042k6.pdf
Datasheet sayfa 31'de, PA11 ve PA12'nin CANBUS için AF4 olarak konfigüre edilmesi gerektiği yazıyor.

Mucit23

Teşekkürler, düzeldi şimdi. Datasheete bakmamıştım ama GPIO.h içerisinde Alternate Fonksiyonlara bakarken AF0'da CAN'i gördüm. O yüzden AF0 yazmıştım

/** 
  * @brief  AF 0 selection
  */
#define GPIO_AF_0            ((uint8_t)0x00) /* WKUP, EVENTOUT, TIM15, SPI1, TIM17,
                                                MCO, SWDAT, SWCLK, TIM14, BOOT,
                                                USART1, CEC, IR_OUT, SPI2, TS, TIM3,
                                                USART4, CAN, TIM3, USART2, USART3, 
                                                CRS, TIM16, TIM1 */

Aynısı AF4'de de varmış.

Tekrardan Teşekkürler.