AnsweredAssumed Answered

STM32F103VET6 CAN Normal mode issue

Question asked by afzal.uzair on Apr 22, 2013
Latest reply on Apr 25, 2013 by afzal.uzair
STM32F103 has one CAN only. I want to send and receive data using the same CAN in normal mode(For testing purpose, CAN sends and receives message itself ). I have tried loopback mode and it worked fine. But when I configure CAN to normal mode it does not send or receive message at all over CAN. The CAN Tx pin is not showing CAN transmitted message on oscillioscope(In  loopback it shows message correctly). Firstly I have used method described at  www.mikrocontroller.net/attachment/28831/siemens_AP2921.pdf  
which tells a method to use CAN without transceiver using diodes. Then I thought may be this method is not working so I used a transceiver but I was unable to solve the problem. I am sure that it is not the software problem. What am I doing wrong?

int main(void)
{
     USART2_Config();
     USART2_SendData_s("Main Start:\n\r");
     CAN_Config();
     
     transmit_message();
  while (1)
     {
     }
}

void CAN_Config(void)
{
     // Enable GPIOA clock                                                   
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO , ENABLE);
     
     // CAN Periph clock enable 
     RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1 , ENABLE);
     // GPIO CAN_RX Configuration 
     GPIO_InitStructureCAN_RX.GPIO_Pin = GPIO_Pin_11;
     GPIO_InitStructureCAN_RX.GPIO_Mode = GPIO_Mode_IPU;
     GPIO_InitStructureCAN_RX.GPIO_Speed = GPIO_Speed_10MHz;
     GPIO_Init(GPIOA, &GPIO_InitStructureCAN_RX);

     // GPIO CAN_TX  Configuration 
     GPIO_InitStructureCAN_TX.GPIO_Pin = GPIO_Pin_12;
     GPIO_InitStructureCAN_TX.GPIO_Mode = GPIO_Mode_AF_PP;
     GPIO_InitStructureCAN_TX.GPIO_Speed = GPIO_Speed_10MHz;
     GPIO_Init(GPIOA, &GPIO_InitStructureCAN_TX);
     
     // CAN1 Filter,FIFO and Baudrate settings 
     CAN_Struct_Init();
     
     // CAN1 NVIC settings for FIFO 0 
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
     
  NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;     
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x05;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);


     // IT Configuration for CAN1 FIFO 0 message received interrupt
     CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);


     // Receive message initialized
     RxMessage.StdId = 0x00;
     RxMessage.ExtId = 0x00;
     RxMessage.IDE = CAN_ID_STD;
     RxMessage.DLC = 0;
  RxMessage.FMI = 0;
  for (i = 0; i < 8; i++)
  {
    RxMessage.Data[i] = 0;
  }
}

void CAN_Struct_Init(void)
{
  // CAN1 register init 
  CAN_DeInit(CAN1);
     
     CAN_StructInit(&CAN_InitStructure); 
  // CAN1 cell init 
     CAN_InitStructure.CAN_TTCM = DISABLE; // time-triggered communication mode = DISABLED
     CAN_InitStructure.CAN_ABOM = DISABLE; // automatic bus-off management mode = DISABLED
     CAN_InitStructure.CAN_AWUM = DISABLE; // automatic wake-up mode = DISABLED
     CAN_InitStructure.CAN_NART = DISABLE; // non-automatic retransmission mode = DISABLED
     CAN_InitStructure.CAN_RFLM = DISABLE; // receive FIFO locked mode = DISABLED
     CAN_InitStructure.CAN_TXFP = DISABLE; // transmit FIFO priority = DISABLED
  CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
     
  CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
     CAN_InitStructure.CAN_BS1 = CAN_BS1_2tq;
  CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;
  // CAN1 Baudrate = 250kbps (System clock and CAN clock is 24MHz)
     // CAN_Prescaler value= CAN_clock/(required_Baudrate*total_number_of_tq)
     // In present case, total_number_of_tq=CAN_SJW_1tq+CAN_BS1_2tq+CAN_BS2_3tq=6*tq
     // so CAN_Prescaler= 24MHz/(250kbps*6)=16
  
  CAN_InitStructure.CAN_Prescaler = 16;
  if(CAN_Init(CAN1, &CAN_InitStructure)==CANINITOK)
          USART2_SendData_s("Init OK:\n\r");
     else
          USART2_SendData_s("Init Fail:\n\r");


  // CAN filter init 
  CAN_FilterInitStructure.CAN_FilterNumber = 2;
  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 = CAN_FilterFIFO0;
  CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
  CAN_FilterInit(&CAN_FilterInitStructure);     
}

void transmit_message(void)
{
     Delay(0xffff);
     // Transmit message initialized
  TxMessage.StdId=0x00;
     TxMessage.ExtId=0x00;
  TxMessage.RTR=CAN_RTR_DATA;
  TxMessage.IDE=CAN_ID_STD;
  TxMessage.DLC=5;
  TxMessage.Data[0]=0xA1;
  TxMessage.Data[1]=0xB2;
     TxMessage.Data[2]=0xC3;
     TxMessage.Data[3]=0xD4;
     TxMessage.Data[4]=0xE5;
  TransmitMailbox=CAN_Transmit(CAN1, &TxMessage);
  i = 0;
  while((CAN_TransmitStatus(CAN1, TransmitMailbox) != CANTXOK) && (i != 0xFFFF))
  {
    i++;
  }
     USART2_SendData_s("Succeed:\n\r");
}

void USB_LP_CAN1_RX0_IRQHandler(void)
{
     if(CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET)
     {
          USART2_SendData_s("CAN FIFO 0 IRQ:\n\r");
          CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
  }
}

Outcomes