CAFE

한국직업능력교육원

[스크랩] [ARM 실습 48] CAN1 LoopBack 모드

작성자송명규|작성시간26.06.18|조회수20 목록 댓글 0

드디어 CAN 통신을 하는군요

CAN은 다른 통신과는 다르게 이론적인 백그라운 지식이 많이 필요로 합니다.

특히 개요라든지 시스템 구성 등 전반적인 기초 지식이 있었야만 창의적 코딩이 가능합니다.

그래서 공부를 많이해야되는 파트중에 하나입니다.

 

CAN통신 셀프 자체 테스트용으로 CAN1 LoopBack Test 프로그램으로 가볍게 시작해 보겠습니다.

LoopBack 모드는 CAN 통신 모드중에 하나로 TX 메시지가 RX로 TX메시지가 루프백 된다.

 

CAN 통신 설정및 개요파악 3가지 중요한 사항이 있는데

1.  전송속도  == 최대 1M Bit

2.  Bit 프레임 이해  = 1패킷 이해

3. 수신 ID 필터 설정 및 마스크 이해

 상기 3가지를 이해하는게 중요하다.

 

Bit Rate :  250K 

 

아래링크는 Bit 전송속도를 자동으로 계싼해준다

http://www.bittiming.can-wiki.info/

 

1.  전체 소스코드

2. 중요코드

CAN_TxHeaderTypeDef TxHeader;

CAN_RxHeaderTypeDef RxHeader;

uint8_t TxData[8] = {'0', '1', '2', '3', '4', '5', '6', '7'}; // 전송 Data

uint8_t RxData[8]; // 수신버퍼

HAL_StatusTypeDef TxStatus;

 

void CAN1_Tx(void){

char msg[50];

// create TxHeader variable

CAN_TxHeaderTypeDef TxHeader;

 

uint32_t TxMailbox;

 

uint8_t our_message[5] = {'H','E','L','L','O'};

 

TxHeader.DLC = 5; // 5byte(we will send "HELLO")

// use standard ID

TxHeader.StdId = 0x65D;

TxHeader.IDE = CAN_ID_STD;

TxHeader.RTR = CAN_RTR_DATA;

 

if(HAL_CAN_AddTxMessage(&hcan1, &TxHeader, our_message, &TxMailbox) != HAL_OK){

// here, variable TxMailbox is updated by HAL_CAN_AddTxMessage API!

Error_Handler();

}

 

// use a while loop in order to wait until the message is transmitted successfully.

while(HAL_CAN_IsTxMessagePending(&hcan1,TxMailbox));

// if HAL_CAN_IsTxMessagePending return 1, there is a pending transmission request

 

// After while loop, i will just print that message got transmitted successfully.

sprintf(msg,"Message Transmitted\r\n");

HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);

}

 

void CAN1_Rx(void){

char msg[50];

CAN_RxHeaderTypeDef RxHeader;

uint8_t rcvd_msg[5];// to save received data

 

// wait until some message comes to the FIFO( not euqal to 0)

while(!HAL_CAN_GetRxFifoFillLevel(&hcan1,CAN_RX_FIFO0));

 

if(HAL_CAN_GetRxMessage(&hcan1,CAN_RX_FIFO0

,&RxHeader,rcvd_msg) != HAL_OK)

{

Error_Handler();

}

sprintf(msg,"Message Received : %s\r\n",rcvd_msg);

HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);

}

 

// 메시지 송신 함수
void CAN_Transmit(void)
{
    TxHeader.DLC = 8;  // 데이터 길이
    TxHeader.IDE = CAN_ID_STD;  // 표준 ID
    TxHeader.StdId = 0x321;  // 메시지 ID

    // 송신
    if (HAL_CAN_AddTxMessage(&hcan1, &TxHeader, TxData, (uint32_t*)CAN_TX_MAILBOX0) != HAL_OK)
    {
        // 송신 실패 처리
        Error_Handler();
    }
}

// 메시지 수신 함수
void CAN_Receive(void)
{
    if (HAL_CAN_GetRxFifoFillLevel(&hcan1, CAN_RX_FIFO0) > 0)
    {
        // 수신된 메시지 가져오기
        if (HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &RxHeader, RxData) == HAL_OK)
        {
            // 수신된 데이터 처리
            // 예: RxData를 출력하거나 다른 작업 수행
        }
    }
}

// 오류 처리 함수
void Error_Handler(void)
{
    while(1)
    {
        // 오류 발생 시 무한 루프
    }
}

 

MX_GPIO_Init();

MX_CAN1_Init();

MX_USART2_UART_Init();

/* USER CODE BEGIN 2 */

CAN_Filter_Config();

 

if(HAL_CAN_Start(&hcan1) != HAL_OK){

Error_Handler();

}

 

CAN1_Tx();

CAN1_Rx();

/* USER CODE END 2 */

 

/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

{

CAN_Transmit(); // 메시지 송신

CAN_Receive(); // 메시수신

HAL_Delay(1000);

/* USER CODE END WHILE */

 

/* USER CODE BEGIN 3 */

}

/* USER CODE END 3 */

}

 

3. CUbeMX 설정

4. 실행결과

 

 

다음검색
현재 게시글 추가 기능 열기

댓글

댓글 리스트
맨위로

카페 검색

카페 검색어 입력폼