본문 바로가기

[ST_MICRO]/STM32F1

[myUSB] STM32 EVM CAN Interrupt Test

[myUSB] STM32 EVM CAN Interrupt Test
STM32 (myUSB EVM)보드와 LM3S5732 EVM보드를 이용하여 CAN통신 테스트를 해 보았다. CAN인터럽트를 이용하여 데이터를 수신하도록 했다.
지난번에 폴링으로 테스트 하긴 했는데... 새롭게 하려니 또 시간이 많이 소비되는것 같다. 서로 다른 보드의 환경설정 하는데 시간이 많이 걸렸다. 정리만 잘 해두었어도 시간을 많이 줄일 수 있었는데... 다시한번 정리해 보도록 한다.



모터 제어 확장 보드의 LM3S5732에서 SW7를 누르면  CAN데이터가 전송되도록 했다.



STM32 CAN인터럽트
인터럽트 소스는 여러가지 있지만 가장 많이 사용하게 될 소스는 CAN_RF0R, CAN_RF1R 이다. CAN 데이터가 Mailbox에 정상적으로 저장되면 이벤트를 발생하게 된다.



물론 초기화시에 CAN->IER 레지스터에 CAN_RF0R_FMP0로 사용 여부를 설정해야 된다.
ST에서 제공하는 함수로 CAN_ITConfig()를 사용하면 쉽게 설정 가능하다.

  /* CAN FIFO0 message pending interrupt enable */
  CAN_ITConfig(CAN_IT_FMP0, ENABLE);


/*******************  Bit definition for CAN_RF0R register  *******************/
#define  CAN_RF0R_FMP0                       ((u8)0x03)               /* FIFO 0 Message Pending */
#define  CAN_RF0R_FULL0                      ((u8)0x08)               /* FIFO 0 Full */
#define  CAN_RF0R_FOVR0                      ((u8)0x10)               /* FIFO 0 Overrun */
#define  CAN_RF0R_RFOM0                      ((u8)0x20)               /* Release FIFO 0 Output Mailbox */

#define CAN_IT_FMP0                 ((u32)0x00000002) /* FIFO 0 message pending */

USB와 CAN을 동시에 사용할 경우 인터럽트 소스를 구분할 필요가 있는데 FIFO pending를 알아내려면 ST제공 예제의 CAN_GetITStatus() 함수 에서는 추가가 되어 있이 않아서 추가했다.

[stm32f10x_can.c]
ITStatus CAN_GetITStatus(u32 CAN_IT)
{
          :
  case CAN_IT_FMP0:
      pendingbitstatus = CheckITStatus(CAN->RF0R, CAN_RF0R_FMP0);  
   break;
  
    default :
      pendingbitstatus = RESET;
      break;
}
 


소스코드
//CAN Interrupt
void USB_LP_CAN_RX0_IRQHandler(void)
{
  if(CAN_GetITStatus(CAN_IT_FMP0) == SET)
  {
    CAN_Receive(CAN_FIFO0, &gRxMessage);
  
   gFlagCanInt = 1;  
  }
}



//-----------------------------------------------------------------------------
int main(void)
{
 unsigned char flag_sw1 = 0;
    //System Init
 SystemInit();
 
    //LED Init
 Led1Init();
 Led1On();

 Led2Init();
 Led2Off(); 
 
 Sw1Init(); 
 
 //Serial Init
 DebugInit(BAUD_115200);
 DebugPrint("STM32 CAN Test Program..\r\n");

 //CAN Init
 CAN_initial();

 while (1)
 {
  if(gFlagCanInt)
  {
   DebugPrint("[ID %02X:%02x:%02x] : ",
      g_MsgObjectRx.StdId,  //수신한 CAN ID
      g_MsgObjectRx.IDE,
      g_MsgObjectRx.DLC
      );
 
   //수신한 데이터 출력
   DebugPrint("%02x %02x %02x %02x | %02x %02x %02x %02x\r\n",
     g_MsgObjectRx.Data[0],
     g_MsgObjectRx.Data[1],
     g_MsgObjectRx.Data[2],
     g_MsgObjectRx.Data[3],
     g_MsgObjectRx.Data[4],
     g_MsgObjectRx.Data[5],
     g_MsgObjectRx.Data[6],
     g_MsgObjectRx.Data[7]    
     ); 
  
   gFlagCanInt = 0;
  }
  
  :
 }



테스트 결과 시리얼포트 출력 화면
STM32 CAN Test Program..
[ID 04:00:08] : 01 09 00 00 | 00 00 00 00
[ID 04:00:08] : 01 0a 00 00 | 00 00 00 00
[ID 04:00:08] : 01 0b 00 00 | 00 00 00 00
[ID 04:00:08] : 01 0c 00 00 | 00 00 00 00
[ID 04:00:08] : 01 0d 00 00 | 00 00 00 00
[ID 04:00:08] : 01 0e 00 00 | 00 00 00 00
[ID 04:00:08] : 01 0f 00 00 | 00 00 00 00
[ID 04:00:08] : 01 10 00 00 | 00 00 00 00


CAN통신 보레이트 설정

   #ifdef  CAM_BAUD_125KB
   CAN_InitStructure.CAN_Prescaler = 16;
   CAN_InitStructure.CAN_BS1       = 8;
   CAN_InitStructure.CAN_BS2       = 7;
   #endif
   #ifdef  CAM_BAUD_250KB
   CAN_InitStructure.CAN_Prescaler = 8;
   CAN_InitStructure.CAN_BS1       = 8;
   CAN_InitStructure.CAN_BS2       = 7;
   #endif
   #ifdef  CAM_BAUD_500KB
   CAN_InitStructure.CAN_Prescaler = 4;
   CAN_InitStructure.CAN_BS1       = 8;
   CAN_InitStructure.CAN_BS2       = 7;
   #endif
   #ifdef  CAM_BAUD_1000KB
   CAN_InitStructure.CAN_Prescaler = 2;
   CAN_InitStructure.CAN_BS1       = 8;
   CAN_InitStructure.CAN_BS2       = 7;
   #endif


반응형