본문 바로가기
정보&팁/전기 & 전자

CAN통신 - Boardcast 형식

by 가능성의 꾸꾸 2025. 3. 11.
728x90
반응형

 

 

1. 설계 개요

📌 각 모터별 개별 메시지 수신
각 모터는 자신만 받아야 하는 메시지가 있음 → 각 모터의 고유 ID 사용

📌 모든 모터가 동일한 메시지를 수신
모든 모터가 동일한 명령을 받아야 하는 경우 → 공통 ID를 추가 사용


2. CAN 메시지 ID 설계

목적  CAN ID 설명
모터 1 전용 메시지 0x101 모터 1만 수신
모터 2 전용 메시지 0x102 모터 2만 수신
모터 3 전용 메시지 0x103 모터 3만 수신
모터 4 전용 메시지 0x104 모터 4만 수신
모든 모터 공통 메시지 0x1FF 모든 모터가 수신

3. 필터 설정 방법

각 모터는 자신의 ID와 공통 ID(0x1FF)를 모두 수신할 수 있도록 필터를 설정해야 합니다.
이를 위해 필터 뱅크 2개를 사용해야 합니다.


🔹 (1) 각 모터가 개별적으로 받을 메시지 설정

  • 각 모터는 자신만의 ID를 가져야 하므로 정확한 ID 매칭이 필요합니다.
  • 필터 마스크 = 0x7FF (모든 비트 체크, 완전 일치)

예제: 모터 1 (ID = 0x101) 설정

CAN_FilterTypeDef canFilterConfig1;

canFilterConfig1.FilterBank = 0;
canFilterConfig1.FilterMode = CAN_FILTERMODE_IDMASK;
canFilterConfig1.FilterScale = CAN_FILTERSCALE_32BIT;

// 모터 1의 ID 설정
canFilterConfig1.FilterIdHigh = (0x101 << 5);
canFilterConfig1.FilterIdLow = 0x0000;

// 정확한 ID만 매칭 (모든 비트 체크)
canFilterConfig1.FilterMaskIdHigh = (0x7FF << 5);
canFilterConfig1.FilterMaskIdLow = 0x0000;

canFilterConfig1.FilterFIFOAssignment = CAN_RX_FIFO0;
canFilterConfig1.FilterActivation = ENABLE;

HAL_CAN_ConfigFilter(&hcan1, &canFilterConfig1);

🔹 (2) 모든 모터가 같은 메시지를 받을 수 있도록 설정

  • 공통 메시지는 0x1FF로 설정
  • 필터 마스크를 활용하여 0x1FF를 특정 패턴으로 설정
  • ID 중 상위 7비트(0x1F0)를 무시하고, 하위 4비트(0x0F)만 비교하도록 설정
CAN_FilterTypeDef canFilterConfig2;

canFilterConfig2.FilterBank = 1;
canFilterConfig2.FilterMode = CAN_FILTERMODE_IDMASK;
canFilterConfig2.FilterScale = CAN_FILTERSCALE_32BIT;

// 공통 ID (0x1FF) 설정
canFilterConfig2.FilterIdHigh = (0x1FF << 5);
canFilterConfig2.FilterIdLow = 0x0000;

// 하위 4비트(0x0F)를 비교하고, 나머지 비트는 무시
canFilterConfig2.FilterMaskIdHigh = (0x1F0 << 5);
canFilterConfig2.FilterMaskIdLow = 0x0000;

canFilterConfig2.FilterFIFOAssignment = CAN_RX_FIFO0;
canFilterConfig2.FilterActivation = ENABLE;

HAL_CAN_ConfigFilter(&hcan1, &canFilterConfig2);

이 설정의 의미

  • FilterId = 0x1FF → 공통 메시지를 받을 CAN ID
  • FilterMask = 0x1F0 → ID의 상위 7비트는 무시하고, 하위 4비트만 체크
  • 결과적으로 모든 모터가 0x1FF 메시지를 수신 가능!

4. 각 모터에서 메시지 처리 방식

각 모터는 개별 메시지 + 공통 메시지를 받게 됩니다.
이를 처리하기 위해 모터는 자신의 ID와 공통 ID를 구분하여 동작하면 됩니다.

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
    CAN_RxHeaderTypeDef RxHeader;
    uint8_t RxData[8];

    if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData) == HAL_OK)
    {
        uint16_t received_id = RxHeader.StdId;

        // 자신의 ID인지 확인
        if (received_id == MY_MOTOR_ID)
        {
            printf("Motor %d received individual command\r\n", MY_MOTOR_ID);
            MotorControl(RxData);
        }
        // 공통 ID 메시지인지 확인
        else if (received_id == 0x1FF)
        {
            printf("Motor %d received global command\r\n", MY_MOTOR_ID);
            MotorControl(RxData);
        }
    }
}

📌 5. 정리: 최적의 필터 활용 방식

목적 CAN ID 필터 설정
각 모터가 자신만의 메시지를 받음 0x101, 0x102, 0x103, 0x104 FilterId = 0x101 (예), FilterMask = 0x7FF
모든 모터가 동일한 메시지를 받음 0x1FF FilterId = 0x1FF, FilterMask = 0x1F0 (하위 4비트만 비교)

이 설정을 적용하면

  • 각 모터는 자신에게 할당된 메시지만 수신
  • 공통 명령(0x1FF)은 모든 모터가 함께 수신 가능
  • 필터를 최소한으로 사용하면서도 효율적인 수신 가능 🚀

 

추후 프로토콜 설계와 데이터 업데이트 예정

 

728x90