TM4C123 - CAN 통신 테스트

[TI]/TM4C | 2014.08.17 19:00
Posted by nexp

TM4C123 - CAN 통신 테스트




TM4C123 은 2채널의 CAN 듈이 있다. 기존  Stellaris 시리즈와 거의 유사하게 되어 있어 기존 코드 수정없이 사용가능하다.

■ CAN protocol version 2.0 part A/B
■ Bit rates up to 1 Mbps
■ 32 message objects with individual identifier masks
■ Maskable interrupt
■ Disable Automatic Retransmission mode for Time-Triggered CAN (TTCAN) applications
■ Programmable Loopback mode for self-test operation
■ Programmable FIFO mode enables storage of multiple message objects
■ Gluelessly attaches to an external CAN interface through the CANnTX and CANnRX signals



TM4C123 의 CAN통신 핀맵



기존과 조금 다른 점으로 CAN 핀맵을 리맵 할 수 있다는 것인데.. 테스트를 위해 PB4, PB5에 할당해서 테스트 하기로 했다.

CAN0RX -> PB4

CAN0TX -> PB5



EVB_DSP 보드에서 







EXP_SM EVM 보드에서






코드는 기본적으로 LM3S 시리즈의 CAN통신 예제와 동일하다. 


TM4C123 CAN 초기화 함수

기존과 조금 달라진 점은 CAN 통신 속도 설정하는 부분이 좀더 간단히 처리할 수 있도록 되어 있다.

    //포트클럭 설정

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);


    //CAN 포트 설정

    GPIOPinConfigure(GPIO_PB4_CAN0RX);

    GPIOPinConfigure(GPIO_PB5_CAN0TX);

    GPIOPinTypeCAN(GPIO_PORTB_BASE, GPIO_PIN_4 | GPIO_PIN_5);


    // CAN클럭 초기화

    SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);


    // Initialize the CAN controller

    CANInit(CAN0_BASE);


    // CAN통신 속도 설정

    CANBitRateSet(CAN0_BASE, SysCtlClockGet(), 500000);



    // CAN interrupts 설정

    CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);

    IntEnable(INT_CAN0);


    // Enable the CAN for operation.

    CANEnable(CAN0_BASE);



CAN 메세지 전송하기
CAN데이터를 전송하려면 먼저 CAN Message Object를 초기화하고 전송해야 한다.

tCANMsgObject g_MsgObjectRx;

//메세지 오브젝트 초기화
void CANConfigureNetwork(void)
{
    //TX용 CAN 메시제 오프젝트 초기화
    g_MsgObjectTx.ulMsgID = 0x02;   //CAN ID
    g_MsgObjectTx.ulMsgIDMask = 0;

    //인터럽트 설정
    g_MsgObjectTx.ulFlags = MSG_OBJ_TX_INT_ENABLE;

    //메세지 크기
    g_MsgObjectTx.ulMsgLen = MAX_CAN_MSG_SIZE;
    //메시지 버퍼 설정
    g_MsgObjectTx.pucMsgData = g_CanTxMsgBuffer;
}

//CAN 메세지 전송
void SendCanMsg(unsigned char MsgId, unsigned char ucEvent, unsigned char Data)
{
    //MsgId : Message Object의 번호(수신측에서는 의미없는 값이다.)
 
    g_MsgObjectTx.pucMsgData[0] = ucEvent;
    g_MsgObjectTx.pucMsgData[1] = Data;

 /*
    //필요에 따라서 설정
    g_MsgObjectTx.pucMsgData[2] = 0;
    g_MsgObjectTx.pucMsgData[3] = 0;
 
    g_MsgObjectTx.pucMsgData[4] = 0;
    g_MsgObjectTx.pucMsgData[5] = 0;
    g_MsgObjectTx.pucMsgData[6] = 0;
    g_MsgObjectTx.pucMsgData[7] = 0;
 */ 
 
    CANMessageSet(CAN0_BASE, MsgId, &g_MsgObjectTx, MSG_OBJ_TYPE_TX);
}




CAN메세지 수신하기
CAN데이터를 전송하려면 먼저 CAN Message Object를 초기화 해야 수신할 수 있다. 수신하고 싶은 ID를 msg.ulMsgID 에 정의 하고 CANMessageSet()함수로 설정 할 수 있다. 물론 message object개수(1~32)만큼 설정 가능하다.

//메세지 오브젝트 초기화
void CANConfigureNetwork(void)
{
 tCANMsgObject msg;

    //수신할 CAN ID
    msg.ulMsgID = 0x02;
    msg.ulMsgIDMask = 0;//0xFF;

    //인터럽트 사용
    msg.ulFlags = MSG_OBJ_RX_INT_ENABLE;

    //수신할 버퍼와 크기
    msg.ulMsgLen = MAX_CAN_MSG_SIZE;
    msg.pucMsgData = g_CanTxMsgBuffer;

    //수신할 message object 초기화 (message object : 1~32)
    CANMessageSet(CAN0_BASE, 1, &msg, MSG_OBJ_TYPE_RX);
}



CAN 인터럽트 핸들러

void CANHandler(void)
{
    unsigned long rx_id_status;

    //CAN 인터럽트의 상태값을 읽어온다
    rx_id_status = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);
    
     //읽은후 지운다
    CANIntClear(CAN0_BASE, rx_id_status); 
      
 //CAN 인터럽트 처리
 if(rx_id_status)
 {
  //message object 깂을 읽어온다 - 읽어오면 지워진다
  CANMessageGet(CAN0_BASE, rx_id_status, &g_MsgObjectRx, 1);
  
  DebugPrint("[ID%02X %02X:%02x:%02x] : ", 
        rx_id_status,    //message object 번호
     g_MsgObjectRx.ulMsgID,  //수신한 CAN ID
     g_MsgObjectRx.ulMsgIDMask,
     g_MsgObjectRx.ulMsgLen 
     );

  //수신한 데이터 출력
  DebugPrint("%02x %02x %02x %02x | %02x %02x %02x %02x\r\n", 
    g_MsgObjectRx.pucMsgData[0],
    g_MsgObjectRx.pucMsgData[1],
    g_MsgObjectRx.pucMsgData[2],
    g_MsgObjectRx.pucMsgData[3],
    g_MsgObjectRx.pucMsgData[4],
    g_MsgObjectRx.pucMsgData[5],
    g_MsgObjectRx.pucMsgData[6],
    g_MsgObjectRx.pucMsgData[7]    
    ); 
 }
}




OBD-II (J1962) 실드 케이블 - Right Angle 핀맵






차량용 OBD 쉴드 케이블 D-SUB 작업용 컨넥터 핀맵






LPC11Cxx - CAN 드라이버 (CAN transceiver ) 내장 MCU

 

Cortex-M3코어을 가진 CAN지원 MCU중 저렴하고 소형인 STM32F3T4가 좋은데, NXP사에서 출시된 LPC11C 시리즈는 CAN 드라이버(CAN transceiver ) 까지 내장되어 있어 경쟁력 있어 보인다.

 

 

C_CAN controller. On-chip C_CAN and CANopen drivers included. On-chip, high-speed CAN transceiver (parts LPC11C22/C24 only).

 

 

 

쇼핑몰에서 저렴하게 판매하고 있으니 테스트 해볼만할것 같다.

 

[CAN_EVM] ECU Read 2 - TFT LCD에 RPM정보 그래프로 표시하기

 

 

 

 

ECU정보 읽기 두번째로 이번에는 차량 PRM(속도) 정보를 읽어와 그래프로 표시하는 예제를 작성해 보았다.

모드에 따라 숫자로도 표시되고 그래프로 표시되도록 했다.

아무래도 그래프로 표시되면 과거 정보를 볼 수 있기 때문에 적산된 그래프로 운전 패턴이나 운행 상태를 좀더 파악하기 쉽다.

(좀더 보기 좋게 하기 위해 시간축에 대해 타이밍 조절은 좀 필요할것 같다.)

 

 

 

 

 

일단 테스트를 위해 계기판 위쪽으로 잘 보이는 곳에 [CAN_EVM] 보드를 간의로 설치했다.

 

 

 

 

[CAN_EVM] ECU정보를 이용한 RPM(차량속도) TFT LCD 표시 테스트 동영상

테스트는 운행중 촬영에 어려움이 있기때문에 RPM만 표시하도록 했고, 기어 중립상태에서 엑셀을 밝아 RPM변화 상태를 표시해 보았다. 

 

 

 

TAG Can, CAN_EVM, ecu, OBD

[CAN_EVM] ECU Read 1 -  TFT LCD에 기어단수 표시하기

 

  

 

 

 

차량운전 하다 보면 PRM이나 속도등의 정보를 좀더 크고 잘 보이는 위치에 있었으면 좋겠다는 생각을 해 보는데 모처럼 주말에 시간이 나서 작업을 해 보았다.

 

차량 ECU정보를 이용하면 차량 RPM, 속도 및 기어 위치, 브레이크위치 등의 정보를 알 수 있는데  CAN통신으로 읽어올 수 있다. 차량과 CAN통신이 가능한 [CAN_EVM] 보드를 이용하여 차량의 ECU정보를 읽어와 TFT LCD에 표시하는 예제를 작성해 보았다. 

 

 

 

인터페이스는 OBD커넥터를 이용했다.


 

 

우선 테스트를 간단하게 하기 위해 기어 위치를 임의의 숫자로 변환해서 표시 했다. 추후 좀더 디테일한 이미지로 표시하면 좋을것 같다. 

 

ECU정보는 차량마다 다르고 공개도 되어 있지 않기 때문에(나만 못찾나?)..

아무튼 데이터 페킷을 비교해 가면서 기어 위치 정보를 표시하도록 했다.

  if(g_MsgObjectRx.Data[1] ==  0x40)
  {
   //P
   gGearPos = 0; 
  }
  else if(g_MsgObjectRx.Data[1] == 0x46)
  {
   //중립
   gGearPos = 3;
  }
  else if(g_MsgObjectRx.Data[1] == 0x45)
  {
   //D
   gGearPos = 4;
  }  
  else if(g_MsgObjectRx.Data[1] == 0x48)
  {
   if(g_MsgObjectRx.Data[0] == 1)
    gGearPos = 1;
  
   else if(g_MsgObjectRx.Data[0] == 2)
    gGearPos = 2; 
  }
  else if(g_MsgObjectRx.Data[1] == 0x47)
  {
   //R
   gGearPos = 7;
  }

 

 

 

 

ECU정보를 이용한 TFT LCD에 기어위치 표시 테스트 동영상

동영상 상에 후진 표시가 안된다. 코드를 보니 후진과 D를 같은 값으로 설정하게 했다. 수정후 정상 동작한다.

 

 

 

 

TAG Can, CAN_EVM, ecu, OBD

[CANTUSB] 조향각 센서 테스트

[INTERFACE]/CAN | 2012.04.19 23:32
Posted by nexp

[CANTUSB] 조향각 센서 테스트

 

 

자동차용 조향각 센서(Steering Sensor) 는 CAN 인터페이스 방식으로 연결되기 때문에 예전에 LM3S5732로 제작했던  CAN2USB 보드를 이용하여 센서값을 출력해 보았다.

 

조향각 센서는 CAN ID 7C0로 적절히 초기 값을 설정하면 2B0 에서 각도 및 각속도가 출력된다.

[ID 2B0(0):00:05] : ff 7f 00 05 | f2 00 00 00
[ID 2B0(0):00:05] : ff 7f 00 05 | e3 00 00 00

 

 

테스트 동영상

CAN2USB 보드를 이용하여 조향각 센서의 데이터값을 출력하는 테스트

 

OBD테스트중 문제 발생

[INTERFACE]/CAN | 2011.02.22 12:29
Posted by nexp
OBD테스트중 문제 발생
투싼ix 에서는 잘 동작했던 OBD보드가 투싼mx에서는 동작하지 않는 현상이 발생
ID문제일 가능성이 있어 ID체크 하는 부분을 수정했는데 여전히 동작을 하지 않는다.
CAN 인터럽트 조차 발생하지 않는다.
CAN보레이트 문제 인가 싶어 변경해도 역시 동작 하지 않는다.
 
예전 작성했던 문서를 보니 답이 나온다.
CAN ID필터를 걸어두었는데... 투싼ix는 ID가 7E8, 7E9 두개의 응답이 있었는데 7E9이상 받도록 필터 설정을 해 두었던 것이 문제가 된것 같다.

OBD 응답 형식을 보면7E8~7EA까지 있다.



필터 설정을 7E8이 되로록 수정 하니 잘 올라온다. -> 문서 정리 해 두었던 것이 많이 도움이 된것 같다.
투싼mx, 스포티지둘다 체크 했는데 7E8이 올라온다.
 
투싼mx OBD데이터
Velocity Temp
[ID 7E8(0):00:08] : 03 41 0d 00 | 00 00 00 00
Velocity Temp
[ID 7E8(0):00:08] : 03 41 0d 00 | 00 00 00 00
Velocity Temp
[ID 7E8(0):00:08] : 03 41 0d 00 | 00 00 00 00
Velocity
[ID 7E8(0):00:08] : 03 41 0d 00 | 00 00 00 00
스포티지 OBD데이터
[ID 7E8(0):00:08] : 03 41 0d 00 | 00 00 00 00
Velocity Temp
[ID 7E8(0):00:08] : 03 41 0d 00 | 00 00 00 00
Velocity Temp
[ID 7E8(0):00:08] : 03 41 0d 00 | 00 00 00 00
 
TAG Can, OBD
[OBD2W] OBD 데이터 무선 전송 모듈 제작

OBD데이터를 Bluteooth, Zigbee등의 무선통신으로 전송하는 모듈을 제작 했다.



[OBD-II] Connector 제작

[INTERFACE]/CAN | 2010.07.30 11:18
Posted by nexp
[OBD-II] Connector 제작

[OBD2WiFi] 보드 제작 을 위한 커넥터를 제작했다. 일단 CAN통신만 사용하도록 했다.






국내 차량 OBD 커넥터 사양

TAG Can, OBD

Luminary Micro Cortex-M3 CAN 통신

[TI]/LuminaryMicro | 2010.06.17 18:05
Posted by nexp
Luminary Micro Cortex-M3 CAN 통신

■ CAN protocol version 2.0 part A/B
■ Bit rates up to 1 Mbps
32 message objects with individual identifier masks
■ Maskable interrupt
■ Disable Automatic Retransmission mode for Time-Triggered CAN (TTCAN) applications
■ Programmable Loopback mode for self-test operation
■ Programmable FIFO mode enables storage of multiple message objects
■ Gluelessly attaches to an external CAN interface through the CANnTX and CANnRX signals

CAN 블록도



CAN 핀맵
Luminary Micro에서 출시되는 Cortex-M3시리즈는 동일한 핀맵을 가지고 있는것 같다. PD0(CANrx), PD1(CANtx)로 할당되어 있다.
아래 그림은 64핀 패키지의 LM3S5732의 핀맵이다. LM3S2965도 동일하지만 100핀이므로 핀번호는 다르다.



CAN 메세지 전송하기
CAN데이터를 전송하려면 먼저 CAN Message Object를 초기화하고 전송해야 한다.
tCANMsgObject g_MsgObjectRx;

//메세지 오브젝트 초기화
void CANConfigureNetwork(void)
{
    //TX용 CAN 메시제 오프젝트 초기화
    g_MsgObjectTx.ulMsgID = 0x02;   //CAN ID
    g_MsgObjectTx.ulMsgIDMask = 0;

    //인터럽트 설정
    g_MsgObjectTx.ulFlags = MSG_OBJ_TX_INT_ENABLE;

    //메세지 크기
    g_MsgObjectTx.ulMsgLen = MAX_CAN_MSG_SIZE;
    //메시지 버퍼 설정
    g_MsgObjectTx.pucMsgData = g_CanTxMsgBuffer;
}

//CAN 메세지 전송
void SendCanMsg(unsigned char MsgId, unsigned char ucEvent, unsigned char Data)
{
    //MsgId : Message Object의 번호(수신측에서는 의미없는 값이다.)
 
    g_MsgObjectTx.pucMsgData[0] = ucEvent;
    g_MsgObjectTx.pucMsgData[1] = Data;

 /*
    //필요에 따라서 설정
    g_MsgObjectTx.pucMsgData[2] = 0;
    g_MsgObjectTx.pucMsgData[3] = 0;
 
    g_MsgObjectTx.pucMsgData[4] = 0;
    g_MsgObjectTx.pucMsgData[5] = 0;
    g_MsgObjectTx.pucMsgData[6] = 0;
    g_MsgObjectTx.pucMsgData[7] = 0;
 */ 
 
    CANMessageSet(CAN0_BASE, MsgId, &g_MsgObjectTx, MSG_OBJ_TYPE_TX);
}



CAN메세지 수신하기
CAN데이터를 전송하려면 먼저 CAN Message Object를 초기화 해야 수신할 수 있다. 수신하고 싶은 ID를 msg.ulMsgID 에 정의 하고 CANMessageSet()함수로 설정 할 수 있다. 물론 message object개수(1~32)만큼 설정 가능하다.

//메세지 오브젝트 초기화
void CANConfigureNetwork(void)
{
 tCANMsgObject msg;

    //수신할 CAN ID
    msg.ulMsgID = 0x02;
    msg.ulMsgIDMask = 0;//0xFF;

    //인터럽트 사용
    msg.ulFlags = MSG_OBJ_RX_INT_ENABLE;

    //수신할 버퍼와 크기
    msg.ulMsgLen = MAX_CAN_MSG_SIZE;
    msg.pucMsgData = g_CanTxMsgBuffer;

    //수신할 message object 초기화 (message object : 1~32)
    CANMessageSet(CAN0_BASE, 1, &msg, MSG_OBJ_TYPE_RX);
}


CAN 인터럽트 핸들러
void CANHandler(void)
{
    unsigned long rx_id_status;

    //CAN 인터럽트의 상태값을 읽어온다
    rx_id_status = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);
   
     //읽은후 지운다
    CANIntClear(CAN0_BASE, rx_id_status); 
     
 //CAN 인터럽트 처리
 if(rx_id_status)
 {
  //message object 깂을 읽어온다 - 읽어오면 지워진다
  CANMessageGet(CAN0_BASE, rx_id_status, &g_MsgObjectRx, 1);
  
  DebugPrint("[ID%02X %02X:%02x:%02x] : ",
        rx_id_status,    //message object 번호
     g_MsgObjectRx.ulMsgID,  //수신한 CAN ID
     g_MsgObjectRx.ulMsgIDMask,
     g_MsgObjectRx.ulMsgLen 
     );

  //수신한 데이터 출력
  DebugPrint("%02x %02x %02x %02x | %02x %02x %02x %02x\r\n",
    g_MsgObjectRx.pucMsgData[0],
    g_MsgObjectRx.pucMsgData[1],
    g_MsgObjectRx.pucMsgData[2],
    g_MsgObjectRx.pucMsgData[3],
    g_MsgObjectRx.pucMsgData[4],
    g_MsgObjectRx.pucMsgData[5],
    g_MsgObjectRx.pucMsgData[6],
    g_MsgObjectRx.pucMsgData[7]    
    ); 
 }
}


LM3S2965 -> LM3S5732 CAN테스트 결과
message object 번호 1의 내용은 CAN ID 2를 8바이트 수신해서 출력하고 있다.
[ID01 02:00:08] : 01 9d 00 00 | 00 00 00 00
[ID01 02:00:08] : 01 9e 00 00 | 00 00 00 00
[ID01 02:00:08] : 01 9f 00 00 | 00 00 00 00
[ID01 02:00:08] : 01 a0 00 00 | 00 00 00 00

블로그 이미지

nexp

카테고리

분류 전체보기 (1560)
[MyProject] (48)
[TI] (75)
[NXP] (51)
[ST_MICRO] (129)
[FreeScale] (31)
[MSP430] (140)
[Microchip] (131)
Cortex-M (36)
[ATMEL] (29)
[AnalogDevice] (22)
[Embedded] (2)
ARM9 (24)
[AVR] (80)
[DSP] (111)
[8051] (21)
[MCU] (50)
[INTERFACE] (213)
[AppBoard] (23)
[ROBOT] (25)
[MODULE] (129)
[SENSOR] (41)
[DATA] (21)
[FPGA] (32)
[EVB] (1)
[Proramming] (38)
[MyLog] (6)
[IDEA] (0)
[Utility] (19)
[Book] (24)
취미생활 (4)
[Link] (2)