ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • C 미니프로그램에서 CAN 메시지 송수신하기
    design 2026. 3. 19. 12:32

    시작하기 전에 

    0x700 메시지를 수시하면 0x701, 0x702, 0x703, 0x704 메시지를 전송하는 기능이 필요하다. TSMaster의 미니프로그램을 이용하면 이 기능을 구현할 수 있다. 미니프로그램의 언어로 Python 혹은 C를 사용할 수 있다. 나는 C를 모른다. 하지만 C로 도전한다.

     

     

    개요

    • 프로젝트 설계
    • 미니프로그램
    • 나머지 설정
    • 힌트를 얻은 곳
    • 실행 결과

     

     

    프로젝트 설계

    • 2 채널 CAN 인터페이스 하드웨어를 사용한다. 채널 1과 채널 2를 직접 연결하여 버스를 구성한다.

    • 채널 1에서 0x700 메시지를 1000msec 주기로 전송한다. (채널 2에서 수신한다.) 트랜스밋창에서 0x700 메시지 송신을 설정한다.
    • 미니프로그램은 0x700 메시지를 수신하면 (On CAN Rx)
      • 메시지가 채널 2에서 수신된 경우 실행한다.
      • 채널 2에서 0x701, 0x702, 0x703, 0x704 메시지를 송신한다.
      • 각 메시지의 첫 바이트를 카운터하여 메시지가 업데이트되어 송신되는 것을 확인할 수 있도록 한다.
    • 미니프로그램 작동을 Trace 창에서 확인한다.
      • 송신과 수신 메시지를 구분하기 위해서
        • 채널 1번과 채널 2번용 트레이스창을 각각 생성한다.
        • 각 트레이스창에 채널 필터를 적용한다.

     

    미니프로그램

    • 메인 메뉴/ Design/ C Mini Program 버튼을 클릭하여 Add C Code Editor를 한다.

    • Symbols 탭의 이벤트 목록에서 "On CAN Rx" 항목을 마우스 우클릭으로 선택한다. "Add On Rx - CAN Message"를 선택한다. (CAN-FD의 경우 Add On Rx - CAN FD Message를)

    • id에 700을 입력한다. 0x700 메시지를 수신할 때 실행할 함수를 정의할 것이니까. Name에 함수 이름에 사용한 문구를 입력한다. 나는 m700으로 하였다. 0x700 메시지(m)를 수신할 때 실행할 함수니까. 

    • 함수의 뼈대가 만들어 진다. 함수 원형이 아래와 같이 생성된다. m700는 함수 이름에 사용하기 위해 입력한 문구이다.
    void on_can_rx_m700(const TCAN* ACN)
    • 코드를 입력한다. 코드의  작용은 커멘트로 설명하였다.

     

    더보기
    // 0x700 message를 수신하면 
    // 0x701, 0x702, 0x703, 0x704 메시지를 전송한다.
    // 송신 메시지의 첫 바이트를 카운터로 정의한다. 송신할 때마다 
    // 데이터가 변경되는 것을 확인하기 이한 목적이다. 
    
    // 수신 채널이 2번일 경우에만 실행한다.
    if (ACAN->FIdxChn != CH2) return; 
    
    
    // 메시지 송신에 사용할 변수를 선언한다.
    TCAN m_tx;   
    
    // 송신 메시지의 아이디들
    static u16 m_tx_ids[4] = {0x701, 0x702, 0x703, 0x704};  
    
    // 메시지를 전송할 때마다 카운터 바이트를 변경하기 위해
    static u8 m_tx_counters[4] = {0x01, 0x02, 0x03, 0x04}; 
    
    // for 루프를 위한 인덱스
    u8 i;
    
    for (i=0; i<4; i++) {
        m_tx = {1,0x1,8,0,m_tx_ids[i],0,{m_tx_counters[i], 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0}};
        // 데이터의 맨 앞에 1이 채널 2를 의미한다. 채널 0은 채널 1이다.
        m_tx_counters[i] += 1;
    
        if (0 != com.transmit_can_async(&m_tx)){
          log("ERROR: Tx 0x%03x", m_tx.FIdentifier);
        }
    }
    
    return;

     

     

    나머지 설정

    트랜스밋창

    • 트랜스밋창을 생성한다. (아래 그림에서 "[1] CAN / CAN FD Transmit"는 창이 이미 존재하기 때문에 표시된다.)

    • 메시지를 추가한다. 트랜스밋창 상단의 두번째 버튼을 클릭하면 임의의 메시지를 생성할 수 있다.

    • 메시지를 정의한다. Trigger 셀을 클릭하여 Period 을 선택한다. Period에 주기를 1000 msec로 하였다. Id는 700으로, Chn(채널)은 1로 하였다. D0 ... D7은 임의의 데이터를 넣었다.

     

    트레이스창들

    • 트레이스창을 두 개 생성한다. (아래 그림에서 "[1] CAN / CAN FD Trace", "[2] CAN / CAN FD Trace [#2]"는 창들이 이미 존재하기 때문에 표시된다.)

     

    • 두 창들에 각각 채널 1, 채널 2의 메시지들만 표시되도록 필터를 설정한다. 필터를 설정하기 위해서 Measurement Setup 창을 연다.

    • 필터를 적용할 CAN / CAN FD Trace 창을 마우스 우클릭으로 선택한다. 메뉴에서 Insert Filter를 선택한다. 필터가 추가된다. 

    • Measurement Filter를 더블클릭한다. Pass를 선택한다. CAN 1(채널 1)을 선택한다. Add를 선택하여 Add Any Frame을 선택한다. 채널 1의 모든 프레임이 통과되어 트레이스창에 표시된다.

    • 같은 방법으로 다른 트레이스창 앞에 Measurement Filter를 추가하고, 채널 2의 메시지들만 표시되도록 설정한다.

     

     

    힌트를 얻은 곳

    • C에서 메시지를 다루는 방법은 트랜스밋창에서 힌트를 얻었다.
    • 트랜스밋창에서 메시지를 마우스 우클릭으로 선택하고, Copy as C Script를 선택하면, 해당 메시지를 전송하는 C 코드를 알 수 있다. 

     

     

     

    실행 결과

    • 실행 결과는 아래 비디오와 같다. 
    • 미니프로그램을 실행한다. 
    • Start 버튼을 클릭하여 버스를 연결한다. 
    • 트랜스밋창에서 0x700 메시지를 전송한다.
    • 채널 1을 표시하는 위쪽 트레이스창에서 0x700 메시지가 송신(Tx)되는 것을 확인한다.
    • 채널 2를 표시하는 아래쪽 트레이스창에서 0x700 메시지가 수신(Rx)되는 것을 확인한다.
    • 아래쪽 트레이스창에서 0x701, 0x702, 0x702, 0x703 메시지들이 송신되는 것을 확인한다.
    • 위쪽 트레이스창에서 0x701, 0x702, 0x702, 0x703 메시지들이 수신되는 것을 확인한다.  
    • 0x701, 0x702, 0x702, 0x703의 카운터들이 업데이트되는 것을 확인한다.

    https://www.youtube.com/watch?v=-qR8ElcMC_Y 

     

     

     

    결론

    • TSMaster의 C 미니프로램을 이용하여 메시지를 수신하고 메시지들을 송신하는 예제를 작성하였다.
    • 생각보다 쉽다.