MCU에서 CAN 초기화 및 설정 (ESP32 기준)
1. 개요
ESP32는 다양한 통신 프로토콜을 지원하며, 그중 하나가 CAN(Controller Area Network) 입니다. CAN은 자동차, 산업 자동화, 로봇 공학 등 다양한 분야에서 사용되며, 신뢰성 높은 통신을 제공합니다.
이번 포스팅에서는 ESP32 IDF(ESP-IDF)를 활용한 CAN 초기화 및 설정 방법을 살펴보고, CAN 필터링 및 인터럽트 처리, CAN 통신 속도 설정 및 오류 처리에 대해 자세히 설명하겠습니다. 또한, 예제 코드를 통해 실전에서 활용할 수 있도록 안내하겠습니다.
2. ESP32 IDF를 활용한 CAN 설정
ESP32에서 CAN을 사용하려면 ESP-IDF(ESP32 IoT Development Framework)를 활용해야 합니다. ESP-IDF는 공식적으로 제공되는 개발 프레임워크이며, 다양한 드라이버와 API를 포함하고 있습니다.
2.1 ESP-IDF 설치 및 프로젝트 생성
ESP-IDF를 설치한 후, 새 프로젝트를 생성합니다. 만약 ESP-IDF가 아직 설치되지 않았다면, 공식 문서를 참고하여 설치를 진행하시기 바랍니다.
새로운 프로젝트를 생성하려면 다음 명령어를 사용합니다:
idf.py create-project esp32_can_project
cd esp32_can_project
이제 CAN 드라이버를 설정하겠습니다.
2.2 CAN 드라이버 초기화 및 설정
ESP-IDF에서는 twai
라는 이름으로 CAN 드라이버를 제공합니다. 따라서 헤더 파일을 포함해야 합니다:
#include "driver/twai.h"
그다음, CAN 드라이버를 초기화합니다:
void can_init() {
twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(GPIO_NUM_21, GPIO_NUM_22, TWAI_MODE_NORMAL);
twai_timing_config_t t_config = TWAI_TIMING_CONFIG_500KBITS();
twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
if (twai_driver_install(&g_config, &t_config, &f_config) == ESP_OK) {
printf("CAN Driver Installed Successfully\n");
} else {
printf("Failed to install CAN driver\n");
}
if (twai_start() == ESP_OK) {
printf("CAN Driver Started Successfully\n");
} else {
printf("Failed to start CAN driver\n");
}
}
이 코드는 다음을 수행합니다:
- GPIO 21을 TX, GPIO 22를 RX로 설정합니다.
- CAN 속도를 500Kbps로 설정합니다.
- 모든 메시지를 수락하는 필터 설정을 적용합니다.
- CAN 드라이버를 설치 및 시작합니다.
3. CAN 필터링 및 인터럽트 처리
3.1 필터링 설정
필터링을 통해 특정 ID의 CAN 메시지만 수신할 수 있습니다. 기본적으로 모든 메시지를 수락하지만, 특정 ID만 수신하려면 다음과 같이 설정할 수 있습니다:
twai_filter_config_t filter = {
.acceptance_code = (0x123 << 21),
.acceptance_mask = ~(0xFFF << 21),
.single_filter = true
};
위 코드는 ID가 0x123인 메시지만 수락하도록 설정합니다.
3.2 인터럽트 기반 수신 처리
인터럽트를 사용하여 CAN 메시지를 수신하려면, twai_receive()
를 활용할 수 있습니다:
void can_receive_task(void *arg) {
twai_message_t message;
while (1) {
if (twai_receive(&message, portMAX_DELAY) == ESP_OK) {
printf("Received message ID: 0x%X, Data: ", message.identifier);
for (int i = 0; i < message.data_length_code; i++) {
printf("%02X ", message.data[i]);
}
printf("\n");
}
}
}
이제 FreeRTOS 태스크를 생성하여 백그라운드에서 CAN 메시지를 지속적으로 수신할 수 있습니다.
xTaskCreate(can_receive_task, "CAN_Receive_Task", 4096, NULL, 5, NULL);
4. CAN 통신 속도 설정 및 오류 처리
4.1 속도 설정
CAN 속도는 twai_timing_config_t
를 통해 설정할 수 있습니다.
대표적인 속도 옵션은 다음과 같습니다:
twai_timing_config_t t_config = TWAI_TIMING_CONFIG_1000KBITS(); // 1Mbps
// 또는
// twai_timing_config_t t_config = TWAI_TIMING_CONFIG_250KBITS(); // 250Kbps
속도는 통신 환경과 네트워크 길이에 따라 선택해야 합니다.
4.2 오류 처리
CAN 통신 중 오류가 발생할 경우, twai_status_info_t
구조체를 통해 확인할 수 있습니다:
twai_status_info_t status;
twai_get_status_info(&status);
if (status.state == TWAI_STATE_BUS_OFF) {
printf("CAN Bus Off 상태 발생, 재시작 중...\n");
twai_initiate_recovery();
}
이 코드는 버스 오프(Bus Off) 상태가 발생하면 CAN 드라이버를 재시작하는 로직을 포함합니다.
5. 예제 코드 전체
#include "driver/twai.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <stdio.h>
void can_init() {
twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(GPIO_NUM_21, GPIO_NUM_22, TWAI_MODE_NORMAL);
twai_timing_config_t t_config = TWAI_TIMING_CONFIG_500KBITS();
twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
twai_driver_install(&g_config, &t_config, &f_config);
twai_start();
}
void can_receive_task(void *arg) {
twai_message_t message;
while (1) {
if (twai_receive(&message, portMAX_DELAY) == ESP_OK) {
printf("Received message ID: 0x%X, Data: ", message.identifier);
for (int i = 0; i < message.data_length_code; i++) {
printf("%02X ", message.data[i]);
}
printf("\n");
}
}
}
void app_main() {
can_init();
xTaskCreate(can_receive_task, "CAN_Receive_Task", 4096, NULL, 5, NULL);
}
이 예제 코드를 실행하면 ESP32에서 CAN을 초기화하고 메시지를 수신하는 기능을 구현할 수 있습니다. 이를 활용하여 다양한 CAN 네트워크 프로젝트를 진행할 수 있습니다.
'CAN 통신' 카테고리의 다른 글
CAN 컨트롤러(MCP2515) 사용 방법 [ ESP32 IDF ] (0) | 2025.02.26 |
---|---|
CAN 데이터 송수신 (ESP32 IDF 예제) (0) | 2025.02.25 |
CAN 드라이버 및 소프트웨어 스택 개요 (0) | 2025.02.23 |
CAN 인터페이스 및 주요 하드웨어 (0) | 2025.02.22 |
CAN 통신의 전기적 특성 및 물리 계층 분석 (0) | 2025.02.21 |