CAN 컨트롤러(MCP2515) 사용 방법 ( ESP32 IDF )
1. 개요
ESP32에는 내부 CAN 컨트롤러(TWAI)가 있지만, 일부 프로젝트에서는 외부 CAN 컨트롤러를 사용해야 할 수도 있습니다. 대표적인 외부 CAN 컨트롤러로는 MCP2515가 있으며, SPI 인터페이스를 통해 ESP32와 연결하여 사용할 수 있습니다.
이 글에서는 ESP32 IDF(ESP-IDF) 환경에서 MCP2515를 사용하여 CAN 통신을 설정하는 방법을 자세히 설명합니다.
2. MCP2515 SPI 인터페이스 설정
MCP2515는 SPI(Serial Peripheral Interface) 프로토콜을 통해 마이크로컨트롤러와 통신합니다. SPI는 빠른 데이터 전송 속도를 제공하며, MCP2515를 제어하는 데 필수적인 요소입니다.
2.1 MCP2515 핀 구성
MCP2515는 SPI 인터페이스를 사용하여 ESP32와 연결됩니다. 주요 핀은 다음과 같습니다:
MCP2515 핀 | 설명 | ESP32 핀 예제 |
---|---|---|
VCC | 전원 공급 (5V 또는 3.3V) | 3.3V |
GND | 그라운드 | GND |
CS | SPI 칩 선택 (Chip Select) | GPIO5 |
SCK | SPI 클록 (Serial Clock) | GPIO18 |
SI | SPI 데이터 입력 (MOSI) | GPIO23 |
SO | SPI 데이터 출력 (MISO) | GPIO19 |
INT | 인터럽트 핀 | GPIO4 |
2.2 ESP32 IDF에서 SPI 설정
ESP-IDF에서 SPI 통신을 설정하려면 spi_device_interface_config_t
를 사용하여 SPI 버스를 구성해야 합니다.
#include "driver/spi_master.h"
#include "driver/gpio.h"
#define PIN_NUM_MISO 19
#define PIN_NUM_MOSI 23
#define PIN_NUM_CLK 18
#define PIN_NUM_CS 5
spi_device_handle_t mcp2515_handle;
void spi_init() {
spi_bus_config_t buscfg = {
.miso_io_num = PIN_NUM_MISO,
.mosi_io_num = PIN_NUM_MOSI,
.sclk_io_num = PIN_NUM_CLK,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
};
spi_device_interface_config_t devcfg = {
.command_bits = 0,
.address_bits = 0,
.dummy_bits = 0,
.clock_speed_hz = 1 * 1000 * 1000, // 1MHz
.mode = 0,
.spics_io_num = PIN_NUM_CS,
.queue_size = 1,
};
spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO);
spi_bus_add_device(SPI2_HOST, &devcfg, &mcp2515_handle);
}
3. 라이브러리 활용하여 데이터 송수신
ESP-IDF 환경에서는 직접 MCP2515 레지스터를 제어하거나, 오픈소스 라이브러리를 활용하여 MCP2515를 쉽게 사용할 수 있습니다.
3.1 MCP2515 설정
MCP2515를 사용하려면 먼저 초기화해야 합니다. 아래는 MCP2515를 초기화하는 코드 예제입니다.
#include "mcp2515.h"
#include "driver/spi_master.h"
void mcp2515_init() {
struct mcp2515_config config;
config.spi_handle = mcp2515_handle;
config.cs_pin = PIN_NUM_CS;
mcp2515_initialize(&config);
mcp2515_set_bitrate(MCP_500KBPS, MCP_8MHZ);
mcp2515_set_mode(MCP_NORMAL);
}
int mcp2515_send_message(struct can_frame *frame) {
uint8_t tx_buffer[13];
tx_buffer[0] = (uint8_t)(frame->can_id >> 3);
tx_buffer[1] = (uint8_t)((frame->can_id & 0x07) << 5);
tx_buffer[2] = 0; // Standard frame, no extended ID
tx_buffer[3] = 0; // No RTR
tx_buffer[4] = frame->can_dlc & 0x0F;
memcpy(&tx_buffer[5], frame->data, frame->can_dlc);
spi_transaction_t t;
memset(&t, 0, sizeof(t));
t.length = (5 + frame->can_dlc) * 8;
t.tx_buffer = tx_buffer;
return spi_device_transmit(mcp2515_handle, &t);
}
int mcp2515_receive_message(struct can_frame *frame) {
uint8_t rx_buffer[13];
spi_transaction_t t;
memset(&t, 0, sizeof(t));
t.length = 13 * 8;
t.rx_buffer = rx_buffer;
if (spi_device_transmit(mcp2515_handle, &t) != ESP_OK) {
return -1;
}
frame->can_id = (rx_buffer[0] << 3) | (rx_buffer[1] >> 5);
frame->can_dlc = rx_buffer[4] & 0x0F;
memcpy(frame->data, &rx_buffer[5], frame->can_dlc);
return 0;
}
3.2 데이터 전송 예제
CAN 버스를 통해 데이터를 송신하려면 CAN 메시지를 작성한 후 MCP2515에 전송 요청을 해야 합니다.
void send_can_message() {
struct can_frame frame;
frame.can_id = 0x100;
frame.can_dlc = 2;
frame.data[0] = 0xAB;
frame.data[1] = 0xCD;
mcp2515_send_message(&frame);
}
3.3 데이터 수신 예제
CAN 메시지를 수신하려면 MCP2515의 인터럽트를 사용하거나 폴링 방식으로 데이터를 읽어올 수 있습니다.
void receive_can_message() {
struct can_frame frame;
if (mcp2515_receive_message(&frame) == MCP2515_OK) {
printf("CAN ID: 0x%X\n", frame.can_id);
printf("Data: ");
for (int i = 0; i < frame.can_dlc; i++) {
printf("%02X ", frame.data[i]);
}
printf("\n");
}
}
4. MCP2515 ESP32 IDF 예제 코드
아래는 ESP32 IDF 환경에서 MCP2515를 초기화하고, CAN 메시지를 송수신하는 전체 예제 코드입니다.
#include "driver/spi_master.h"
#include "mcp2515.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#define PIN_NUM_MISO 19
#define PIN_NUM_MOSI 23
#define PIN_NUM_CLK 18
#define PIN_NUM_CS 5
spi_device_handle_t mcp2515_handle;
void app_main() {
// SPI 초기화
spi_init();
// MCP2515 초기화
mcp2515_init();
// CAN 메시지 송신
send_can_message();
// 주기적으로 CAN 메시지 수신
while (1) {
receive_can_message();
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
5. 결론
이 글에서는 ESP32 IDF 환경에서 MCP2515를 SPI를 통해 설정하고, CAN 데이터를 송수신하는 방법을 설명하였습니다.
- SPI 인터페이스 설정: ESP32와 MCP2515 간 SPI 통신을 설정하는 방법을 설명하였습니다.
- 라이브러리 활용: MCP2515를 설정하고 CAN 메시지를 송수신하는 방법을 설명하였습니다.
- 예제 코드 제공: MCP2515를 사용한 전체 코드를 제공하여 실제 프로젝트에서 활용할 수 있도록 하였습니다.
이를 통해 ESP32 IDF 환경에서 외부 CAN 컨트롤러를 활용하여 다양한 프로젝트를 진행할 수 있을 것입니다.
'CAN 통신' 카테고리의 다른 글
CAN 디버깅 및 분석 도구 사용법 (0) | 2025.02.28 |
---|---|
CAN 네트워크 구성 및 다중 노드 통신 실습 (0) | 2025.02.27 |
CAN 데이터 송수신 (ESP32 IDF 예제) (0) | 2025.02.25 |
MCU에서 CAN 초기화 및 설정 (ESP32 기준) (0) | 2025.02.24 |
CAN 드라이버 및 소프트웨어 스택 개요 (0) | 2025.02.23 |