Computer Science
탄탄한 기반 실력을 위한
전공과 이론 지식 모음
Today I Learned!
배웠으면 기록을 해야지
TIL 사진
Flutter 사진
Flutter로 모바일까지
거꾸로캠퍼스 코딩랩 Flutter 앱개발 강사
스파르타코딩클럽 즉문즉답 튜터
카카오테크캠퍼스 3기 학습코치
프로필 사진
박성민
임베디드 세계에
발을 들인 박치기 공룡
임베디드 사진
EMBEDDED SYSTEM
임베디드 SW와 HW, 이론부터 실전까지
ALGORITHM
알고리즘 해결 전략 기록
🎓
중앙대학교 소프트웨어학부
텔레칩스 차량용 임베디드 스쿨 3기
애플 개발자 아카데미 1기
깃허브 사진
GitHub
프로젝트 모아보기
Instagram
인스타그램 사진

Embedded System/MCU

[MCU] MCP2515 SPI2CAN 모듈은 개발보드에 따라 허리를 끊고 별도 Vcc를 인가해줘야한다 (아닐 수 있음)

sm_amoled 2026. 2. 8. 15:32

아주 특이한 트러블슈팅 사례가 있었다.

이 SPI2CAN 모듈을 사용하면 CAN Controller가 없는 보드에서도 SPI 통신을 통해서 모듈에 있는 CAN Controller에 접근하고, Transciver 의 역할까지 수행해서 CAN 버스에 메시지를 보내고 받을 수 있게된다. 우리의 보드에서는 CAN Controller 핀이 있긴 하지만, 내부 드라이버에 CAN이 구현이 되어있지 않아서 (정확히는 수신 과정에서 문제가 있어서) SPI2CAN 모듈을 사용해 개발을 진행하고 있었다. 

그런데 간헐적으로 통신이 되는, 또는 간헐적으로 통신이 안되는 문제가 자주 발생했다. 흠...

 

우선 디버깅 환경을 CAN 메시지를 정상적으로 쏘고 있던 STM32 보드에 현재 개발보드의 SPI2CAN 모듈을 물려 진행하였다. CAN 버스를 Logic Analyzer로 확인해보면, 내부에서 10ms 단위로 보내져야 하는 메시지가 거의 0.1ms 단위로 보내지고 있는 것을 보았다.  

 

 

실제로 안에서는 이 메시지의 마지막 부분이 NACK으로 되어있는 것을 보아, "수신 완료" 메시지를 못보내서 송신측에서 받을 때까지 무한히 해당 메시지를 보내고 있는 것으로 이해했다. 그렇다면 수신측의 문제일 가능성이 매우 BIG.

 

 

그렇게 계속 디버깅을 하다가, 전 기수에서 남겨주고 간 유품들 중에 이 MCP2515 SPI2CAN 모듈이 모두 PCB 뒷판에 뭔가 수술을 한 흔적이 남아있었다. 왜인지는 모르겠는데 뒷판을 까고 납땜을 해둔 모듈들밖에 없었다. 그래서 이게 뭔가 문제의 해결책인가? 싶어서 서치를 돌렸고, 아래 게시글을 찾을 수 있었다. 무려 10년 전의 라즈베리파이2 시절 포럼 게시글.  

 

https://forums.raspberrypi.com/viewtopic.php?t=141052#p933920

 

[quick-guide] CAN bus on raspberry pi with MCP2515 - Raspberry Pi Forums

saper_2 wrote:So, you don't see/can't access can0 from ifconfig/ip ? Looking at your circuit, I see (potential) problem: not translating MOSI & CE from RPi . If you power MC2515 from 5V then it's acceptable logic levels are higher (usually Vin(hi)_min=~3,5

forums.raspberrypi.com

 

여기에서 언급하는 바에 따르면, CAN Controller의 역할을 하는 MCP2515 라는 칩이 있고, CAN Tranceiver의 역할을 하는 TJA1050이라는 칩이 있다. 얘네들의 이름은 이전에 CAN 게시글에서 한 번 본 적이 있는지라 낯이 익었다. 이 중에서, 두 칩이 요구하는 Vcc의 전압이 다르다는 것이 글의 요지이다. 

  • MCP2515 -> 3.3V 전압을 인가해야함
  • TJA1050 -> 5V의 전압을 인가해야함
  • 그런데 같은 Vcc를 공유하는 현재 상태 -> 통신이 안된다.

실제로 회로를 살펴보면 이렇게 Vcc가 공통으로 들어가고 있다. 

 

그러니, 여기에서 회로 중간을 끊어버리고, 따로 TJA1050에서는 Vcc로 5V를 받도록 외부 전원을 넣어줘야 한다는 것. 

 

시키는 대로 뒷 PCB를 까고 여기에 Vcc 5V를 따로 넣어주는 방식으로 변경했다. 

 

그러니 진짜로 기존에 잘 안되던 녀석이랑 CAN으로 통신이 잘 되게되었다!

 

원인이 뭐지?

근데, 실제로 문서를 찾아보면, TJA1050 모듈은 5V를 Vcc로 가지는게 맞는데, MCP2515 컨트롤러는 3.3V와 5V를 모두 받도록 설계가 되어있다. 

 

그래서 MCP2515가 3.3V를 받아야만 정상적으로 동작한다는건 거짓말이라고 생각이 되었다. 아마도 10년 전에는 그럴 수 있겠지만, 지금은 데이터시트 상으로는 3.3V에서도 문제 없이 동작해야한다.

 

그렇다면 의심해볼 수 있는 것은, SPI 신호 선의 세기라고 생각이 들었다.

  • 3.3V를 공급한 경우
    • SPI로 3.3V 레벨로 MCP2515에 초기화를 시도.
    • 근데 5V 전압을 받아야하는 TJA1050은 3.3V로는 깨어나지 못함
    • CAN 초기화 실패
  • 5V를 공급한 경우
    • SPI로 5V 레벨로 MCP2515에 초기화를 시도
    • 이때 5V를 받았으므로 TJA는 초기화가 되고, MCP2515도 응답을 보냄
    • 근데 SPI 신호가 3.3V 수준으로밖에 나오지 못해서 5V를 기준으로 동작하는 컨트롤러가 SPI신호를 무시하여 통신이 이루어지지 않음

 

아직 이 표에서 정확한 의미를 확인하기는 내 전기적인 지식이 부족하긴 하지만, Vdd가 3.3V 또는 5V로 들어왔을 때 요구되는 CS, SCK, Pin의 전압들이 Vdd 값에 따라서 달라지고 있음은 확실해보였다. 이걸 클로드에 넣고, 혹시 어떻게 달라지는지에 대해서 한 번 물어봤는데, 확실히 인식 Voltage 기준이 달라지는 것으로 보인다. 

 

즉, TJA1050 때문에 5V를 연결 → 그러면 MCP2515도 5V로 동작 → 근데 SPI 선들이 나오는 GPIO는 3.3V 수준으로 신호를 보냄 → MCP2515가 이 신호가 수준미달이라 무시함 → 통신 안됨 의 이유로 통신이 안되고 있는 것이다.

 

 

그렇다면 왜 라즈베리파이와 아두이노에서는 이게 잘 동작했는가? 

 

에 대해서는, RPI와 아두이노는 GPIO PIN으로 3.3V와 5V 레벨의 output을 내보낼 수 있게 설계가 되어있지만, 지금 개발을 위해 사용하는 TOPST 보드는 3.3V 만 GPIO PIN을 통해서 출력으로 뱉을 수 있기 때문이 아닐까. 그렇다면 위에서 생각했던 내용들, 간헐적으로만 통신이 가능했던 구질구질한 문제까지 모두 설명이 되는 것 같다. (3.3V 신호를 노이즈로 읽으면 통신이 안되고, 정상 신호로 판별했다면 통신이 잘 되었을지도)

 

마무리 

이 문제의 정확한 이유는 TOPST D3-G 보드의 데이터시트나 Hardware 관련 문서를 찾아보려고 했는데, 여기에서 나오는 전압이 5V를 뱉지 못한다거나 하는 내용은 찾아보지 못했던지라 이게 확실하게 이유라고는 말을 못하겠다.

 

그러나, 위에 있는 포럼에 나와있는 것처럼 MCP2515가 3.3V를 받아야만 동작하기 때문은 아니라고 확신한다. 왜냐? 데이터시트 상으로도 여기에 5V를 넣어줬을 때 문제가 없고, 실제로 5V를 연결해서 CAN 활성화까지는 문제 없이 진행이 되었기 때문. 그리고 TJA1050 을 연결해주기 위해서도 여기에는 원래 무조건 5V를 연결해줘야 했다. 

 

문제는 결국 보드의 GPIO 전압이 3.3V까지인지, 5V까지 낼 수 있는지를 확인하는 것이였다고 생각이 든다. 

 

 

조상님이 짜주신 코드와 트러블슈팅이라고 하더라도 항상 의심을 해. 예외는 없어.

-박성민-
320x100