전자회로 실무 / 펌웨어·회로

MCU(Microcontroller Unit) 모델을 바꾸면 클록(clock) 회로와 퓨즈 비트(fuse bits)·개발 환경 설정도 새 모델에 맞게 변경합니다

기능이 더 많은 MCU(Microcontroller Unit)로 바꿔도 기존 회로와 프로그램(program) 설정을 그대로 쓸 수 있는 것은 아닙니다. 새 모델의 핀(pin) 기능과 클록(clock) 방식을 확인한 뒤 전원부터 프로그래밍(programming), 통신 순서로 점검합니다.

먼저 알아둘 용어

수정 소자·능동 발진기 — 수정 소자는 MCU 내부 발진 회로와 함께 클록을 만들고, 능동 발진기는 외부 부품 자체가 클록 신호를 출력합니다. 연결 핀과 선택 모드가 다릅니다.

퓨즈 비트(fuse bits)·CKSEL·XTAL1 — 퓨즈 비트는 전원이 꺼져도 유지되는 MCU의 설정값입니다. 클록 등의 동작 조건을 정하며, 과전류를 차단하는 보호용 퓨즈(fuse)와는 다른 뜻입니다. CKSEL은 해당 AVR의 클록 선택 설정, XTAL1은 외부 클록 입력 등에 쓰는 핀입니다. MCU 모델에 따라 같은 설정 이름의 의미가 달라질 수 있으므로 사용할 모델의 설명을 확인합니다.

핀 매핑(pin mapping)·USB(Universal Serial Bus) 직렬 변환 — 핀 매핑은 소프트웨어의 기능과 실제 단자를 대응시키는 설정입니다. USB 직렬 변환부는 컴퓨터 연결을 맡는 별도 회로여서 그 인식만으로 목표 MCU의 실행이 증명되지는 않습니다.

MCU 모델을 바꾸면 클록 회로와 퓨즈 비트·개발 환경 설정도 새 모델에 맞게 변경합니다 — 설명용 도해
MCU 모델을 바꾸면 클록 회로와 퓨즈 비트·개발 환경 설정도 새 모델에 맞게 변경합니다 — 설명용 도해 · 클릭하면 확대됩니다.

클록을 만드는 위치와 선택 모드를 맞춥니다

ATmega328PB로 바꿀 때는 이전 모델의 클록 설정을 그대로 복사하지 말고, 새 모델에서 지원하는 발진 모드를 먼저 확인합니다. PB에는 full-swing 수정 발진 모드가 없으므로 지원되는 다른 모드를 선택하고, 선택한 모드에 맞게 클록 회로와 설정을 변경합니다. 기능이 추가된 모델이라고 해서 기존 회로에 그대로 꽂아 쓸 수 있다고 판단하지 않습니다.

full-swing 모드가 없다고 수정 소자를 전혀 사용할 수 없는 것은 아닙니다. PB의 저전력 수정 발진 모드와 외부 클록 입력 등 실제 지원 옵션을 구분합니다. 16 MHz 능동 발진기는 선택 가능한 한 구성이지 모든 PB 설계에 반드시 필요한 공통 부품이 아닙니다.

수정 소자를 쓰는 회로는 MCU 내부 발진 회로와 함께 동작합니다. 능동 발진기는 외부에서 만든 신호를 XTAL1에 입력하는 구성으로, CKSEL도 외부 클록 항목에 맞아야 합니다. 부품만 바꾸고 설정을 그대로 두지 않습니다. 출력 전압·주파수·시작 조건과 MCU의 클록 입력·전원 조건을 대조합니다.

보드 크기가 같아도 핀 기능과 전압은 따로 확인합니다

같은 크기와 헤더(header) 간격은 기계적 호환의 일부일 뿐입니다. 각 헤더 핀의 실제 배선, 전압, 주변장치 기능과 부팅 역할을 하나씩 비교합니다. 개발 환경이 정확한 MCU의 세부 모델을 지원하는지, 실제 클록과 설정이 일치하는지, 추가 주변장치의 핀 매핑이 맞는지 확인합니다.

복사하기 쉬운 항목다시 확인할 내용
클록 부품과 퓨즈지원 모드·입력 핀·실제 발진기·설정
MCU 이름과 보드(board) 크기정확한 모델명·핀 기능·헤더 배선
개발 도구의 보드 선택기기 식별·클록·추가 주변장치 매핑(mapping)
USB 장치 인식변환기 경로와 목표 MCU 실행을 각각 검증

ATmega328PB 보드에서는 개발 환경·기록 경로·추가 통신 핀을 따로 맞춥니다

ATmega328PB처럼 비슷한 이름의 MCU로 보드를 만들었다면, 추가 주변장치를 사용할 수 있다는 설명만으로 기존 프로그램의 핀 번호를 그대로 쓰지 않습니다. 이 모델에는 두 번째 TWI(Two-Wire Interface, I²C 방식의 두 선 통신), SPI(Serial Peripheral Interface, 동기식 직렬 통신), USART(Universal Synchronous and Asynchronous Receiver and Transmitter, 직렬 송수신기)가 있습니다. 추가 GPIO(General-Purpose Input/Output, 범용 입출력)와 ADC(Analog-to-Digital Converter, 아날로그 전압을 수치로 읽는 회로) 입력도 패키지와 핀 설정에 따라 사용할 수 있습니다. 그러나 한 물리 핀에 여러 기능이 겹치는 핀 다중화(pin multiplexing)가 있으므로 추가 통신 두 개와 모든 입출력을 동시에 쓸 수 있다는 뜻은 아닙니다. 회로도의 실제 핀 번호, MCU 데이터시트의 기능 표와 코드에서 고른 포트를 나란히 놓고 확인합니다.

Arduino 계열 개발 환경이라면 MiniCore처럼 ATmega328PB를 지원하는 보드 패키지를 선택할 수 있습니다. 이 경우에도 단순히 ‘328’ 계열을 고르는 데서 끝내지 않고 대상 변형 모델, 클록 소스·주파수, 부트로더 사용 여부와 직렬 업로드 포트를 실제 기판에 맞춥니다. UART(Universal Asynchronous Receiver/Transmitter)는 비동기 직렬 통신을 주고받는 회로입니다. MiniCore의 기본 직렬 업로드 포트는 UART0이고 PB에서는 UART1도 선택할 수 있으므로, 프로그램을 올릴 때 쓰는 TX·RX 핀이 실제 배선과 일치해야 합니다. 보드 패키지 버전에 따라 메뉴와 부트로더 구현이 달라질 수 있어 적용 당시의 선택값을 기록합니다.

FT232RL은 USB와 UART 사이에서 신호를 바꾸는 IC입니다. 컴퓨터에 FT232RL 포트가 보이더라도 새 MCU의 클록·퓨즈·부트로더가 준비됐다는 뜻은 아닙니다. 새 소자에 직렬 부트로더를 쓰려면 먼저 대상 PB의 전압과 클록에 맞춰 별도의 ISP 기록 경로에서 부트로더와 퓨즈를 설정합니다. 그런 다음 FT232RL 쪽 TX를 대상의 선택한 UART RX에, RX를 대상 TX에 연결하고 공통 접지, 신호 전압, 자동 리셋 경로의 실제 회로를 확인합니다. 직렬 업로드가 실패하면 USB 포트 인식만 반복 확인하지 말고 대상 소자 식별값, 클록과 퓨즈, 부트로더 포트, TX·RX 방향과 리셋 타이밍을 순서대로 점검합니다. ISP로 직접 프로그램을 기록하는 방식이라면 직렬 부트로더 경로가 필수는 아닙니다.

예시 코드의 클록 숫자와 실제 MCU 클록을 따로 맞춥니다

MCU를 교체하지 않고 다른 프로젝트의 코드를 가져올 때도 같은 확인이 필요합니다. 예를 들어 WS2812 계열 주소 지정 LED(addressable LED)는 데이터 신호를 받아 개별 LED의 색을 정합니다. 소프트웨어로 데이터 펄스의 길이를 만드는 방식에서는 MCU가 실제로 얼마나 빠르게 실행되는지가 신호의 시간에 영향을 줍니다.

F_CPU는 코드를 기계어로 바꾸는 컴파일러(compiler)에 알려 주는 중앙처리장치(Central Processing Unit, CPU)의 클록 주파수입니다. 단위는 Hz이며, 9.6 MHz를 가정한 코드에서는 9,600,000 Hz에 해당합니다. 이 숫자를 바꾼다고 MCU의 발진기나 분주 설정이 자동으로 바뀌지는 않습니다. 분주(prescaling)는 기준 클록을 일정한 비율로 나누어 더 느린 클록을 만드는 기능입니다. 코드가 가정한 속도와 실제 실행 속도가 다르면 계산한 대기 시간과 출력 펄스 길이도 달라질 수 있습니다.

실제 MCU 클록을 정하는 설정과 컴파일할 때 사용하는 주파수 값은 서로 다른 경로로 적용됩니다. 두 값의 일치를 확인한 다음 출력 신호를 검사합니다.
실제 MCU 클록을 정하는 설정과 컴파일할 때 사용하는 주파수 값은 서로 다른 경로로 적용됩니다. 두 값의 일치를 확인한 다음 출력 신호를 검사합니다. · 클릭하면 확대됩니다.

다음 순서로 설정을 맞춥니다.

  1. 예시 코드가 대상으로 삼은 MCU, 개발 환경의 보드 패키지와 버전, 필요한 라이브러리를 확인합니다. 보드 패키지(board package)는 해당 MCU를 빌드하고 기록하는 방법을 개발 환경에 추가하는 구성입니다. 같은 메뉴 이름이라도 패키지가 다르면 적용 내용이 달라질 수 있습니다.
  2. 회로에서 실제로 사용할 클록 소스와 분주 조건을 정하고, 그 결과의 주파수에 맞춰 빌드 설정을 선택합니다. 예시 코드에 9.6 MHz라고 적혀 있다고 모든 MCU에 그 값을 적용하지 않습니다.
  3. MCU의 퓨즈 설정을 바꿔야 한다면 그 설정을 기록하는 절차를 먼저 수행합니다. 일부 Arduino용 보드 패키지는 Burn Bootloader 명령으로 퓨즈도 기록합니다. 부트로더(bootloader)는 새 프로그램을 받아 기록하는 작은 프로그램이지만, 이 메뉴의 실제 동작은 선택한 패키지와 부트로더 사용 옵션에 따라 달라집니다. 일반 코드 업로드만으로 클록 관련 퓨즈까지 바뀌었다고 판단하지 않습니다.
  4. 확정한 설정으로 다시 컴파일한 뒤 프로그램을 기록하고 검증합니다. 설정을 바꾸기 전에 만든 파일을 그대로 쓰지 않습니다. 기록 성공 후에도 실제 출력 펄스나 통신 결과를 확인해야 합니다.

예시 코드에서 millis()나 tone() 사용을 끄도록 요구하면 그 조건도 확인합니다. millis()는 경과 시간을 밀리초 단위로 읽는 함수이고, tone()은 지정한 주파수의 신호를 출력하는 함수입니다. 작은 MCU에서는 이런 기능과 사용자 코드가 같은 타이머(timer, 시간 간격을 세거나 신호를 만드는 내부 회로)를 필요로 할 수 있습니다. 다만 사용하는 내부 자원과 설정 방식은 보드 패키지·버전에 따라 다릅니다. 예전의 ‘No Millis, No Tone’ 항목을 찾을 수 없다고 비슷한 이름의 기능을 임의로 끄지 말고, 현재 코드가 필요로 하는 함수와 타이머를 확인합니다.

LED가 한 번 켜졌다는 결과만으로 시간 조건이 맞았다고 보지는 않습니다. 이상이 생기면 우선 MCU 종류·실제 클록·빌드 주파수가 일치하는지 확인하고, 그다음 신호를 측정합니다. 설정값과 사용한 패키지·라이브러리 버전을 함께 남기면 다른 기판에서 같은 프로그램을 재현할 때도 원인을 찾기 쉽습니다.

새 AVR에 부트로더를 넣을 때는 기록용 보드와 대상 보드를 구분합니다

USB 직렬 변환부까지 납땜한 기판이 컴퓨터에 나타나도, 새 MCU 안에 부트로더가 들어 있다는 뜻은 아닙니다. 부트로더를 사용하는 설계라면 최초 기록에는 별도의 기록 경로가 필요할 수 있습니다. 인시스템 프로그래밍(In-System Programming, ISP)은 소자를 기판에 둔 채 기록하는 방식이며, ICSP(In-Circuit Serial Programming)는 직렬 기록 신호를 연결하는 인터페이스를 가리킵니다. 여기서는 해당 직렬 ISP 방식을 지원하는 AVR을 대상으로 설명합니다.

예를 들어 Uno R3에 ArduinoISP 예제 프로그램을 넣으면 다른 AVR을 기록하는 도구로 사용할 수 있습니다. 이때 Uno R3는 ‘프로그래머’, 새 기판의 AVR은 ‘대상 소자’입니다. Uno R4나 다른 계열 MCU에 같은 배선과 절차를 그대로 적용하지 않습니다. 기존 프로그램·설정이 들어 있는 기판에서는 기록과 지우기 동작이 무엇을 변경하는지도 먼저 확인합니다.

Uno R3를 기록 도구로 쓸 때의 신호 연결과 개발 환경에서 선택하는 대상을 구분했습니다. 대상 기판의 실제 커넥터 핀 순서는 회로도에서 확인해야 합니다.
Uno R3를 기록 도구로 쓸 때의 신호 연결과 개발 환경에서 선택하는 대상을 구분했습니다. 대상 기판의 실제 커넥터 핀 순서는 회로도에서 확인해야 합니다. · 클릭하면 확대됩니다.
  1. 먼저 기록용 Uno R3만 컴퓨터에 연결합니다. 통합 개발 환경(Integrated Development Environment, IDE)에서 이 보드와 연결 포트를 선택하고 ArduinoISP 예제를 일반 업로드로 기록합니다. 이 단계에서는 아직 새 대상 기판에 부트로더를 넣지 않습니다.
  2. 전원을 분리하고 대상의 정확한 소자명, 동작 전압, 클록 회로와 기록용 신호를 확인합니다. 대상이 5 V 신호를 허용하는지 먼저 판단합니다. 3.3 V 전용 회로에 Uno R3의 신호를 곧바로 연결하지 않습니다.
  3. 사용하는 ArduinoISP 설정에 따라 신호를 연결합니다. 기본 Uno R3 구성에서는 D11을 대상 MOSI, D12를 MISO, D13을 SCK, D10을 대상 RESET에 연결합니다. MOSI(Master Out Slave In)는 기록 도구에서 대상으로 보내는 데이터, MISO(Master In Slave Out)는 돌아오는 데이터, SCK(Serial Clock)는 전송 타이밍을 정하는 클록입니다. 최신 표기에서는 각각 COPI(Controller Out Peripheral In), CIPO(Controller In Peripheral Out)라고도 합니다.
  4. 접지는 공통으로 연결하고, 전원을 어느 쪽에서 공급할지 정합니다. 5 V로 동작하는 소전력 대상에 Uno의 5 V를 공급하는 구성이라면 실제 전류와 전압을 확인합니다. 대상 자체 전원을 쓴다면 전원 출력끼리 무조건 묶지 않습니다. 여섯 핀 ICSP 헤더를 이용해도 대상 RESET은 기록용 Uno의 기본 D10에서 구동하며, 두 보드의 RESET끼리 잇지 않습니다.
  5. 다시 연결한 뒤 IDE의 보드·프로세서·클록 항목은 기록할 대상에 맞춥니다. 포트는 컴퓨터에 연결한 기록용 Uno의 포트를 유지하고, 프로그래머 항목은 Arduino as ISP로 선택합니다. 예제 이름인 ArduinoISP와 프로그래머 메뉴의 이름을 혼동하지 않습니다.
  6. 대상에 맞는 부트로더와 퓨즈 설정을 확인한 뒤 Burn Bootloader를 실행합니다. 완료·검증 결과와 오류 내용을 확인하고 기록 중 연결을 유지합니다. 끝나면 전원을 분리해 기록 배선을 정리한 뒤, 실제 사용 전원과 업로드 경로에서 다시 시험합니다.

외부 수정 진동자(crystal)를 빼고 ATmega328P-AU의 내부 RC 발진기(internal RC oscillator, 칩 안에서 기준 클록을 만드는 회로)를 쓰는 소형 기판이라면, 조립을 마친 뒤에도 프로그램을 기록할 길을 남겨야 합니다. 최초 설정에 필요한 MOSI·MISO·SCK·RESET·전원·접지를 ISP 패드로 빼고, 나중에 직렬 부트로더로 코드를 바꿀 계획이라면 TX·RX·접지와 자동 리셋에 활용할 DTR(Data Terminal Ready, 직렬 변환기의 제어 신호) 접점도 마련합니다. 패드의 위치와 방향을 회로도에 표시하고, 배터리 홀더나 케이스를 조립한 상태에서도 기록 도구가 닿는지 확인합니다. 기록 도구와 배터리 중 어디서 전원을 공급할지도 먼저 정합니다.

ATmega328P의 출하 기본 설정은 내부 발진기 자체가 약 8 MHz로 진동하더라도 CKDIV8 퓨즈가 그 클록을 8분주하므로 실제 시스템 클록은 약 1 MHz입니다. 개발 환경에서 ‘내부 8 MHz’ 보드를 고르는 것만으로 대상 칩의 퓨즈가 바뀌지는 않습니다. 선택한 보드 패키지의 퓨즈 값과 부트로더가 이 소자·클록 설정에 맞는지 확인하고, 앞 절차의 ISP 기록으로 설정을 적용한 뒤 출력 펄스의 주기와 직렬 업로드를 시험합니다. 출하 상태처럼 대상 클록이 느릴 때 ISP가 응답하지 않으면 전원·배선과 함께 기록 도구의 SCK 속도가 대상 클록에 비해 너무 빠르지 않은지도 확인합니다.

이후 DTR 출력을 제공하는 USB-UART 변환기로 직렬 업로드할 경우, 이 사례의 회로처럼 DTR과 대상 RESET 사이에 100 nF(나노패럿) 커패시터(capacitor)를 직렬로 넣을 수 있습니다. 이 커패시터는 DTR 전압이 바뀌는 순간의 신호를 RESET에 전달해 짧은 리셋 펄스를 만듭니다. RESET을 평소 높은 전압으로 유지하는 풀업 저항(pull-up resistor)과 변환기의 출력 전압도 실제 회로에 맞춰 확인합니다. 이 펄스로 대상이 리셋되어 부트로더가 업로드를 기다리는 방식이므로, 커패시터를 RESET과 접지 사이에 붙이는 회로와 혼동하지 않습니다. 업로드가 되지 않으면 ISP 기록 성공 여부, TX·RX 방향, 공통 접지, DTR·RESET 연결, 보드 패키지의 업로드 속도를 차례로 확인합니다. 내부 RC 발진기의 주파수는 전압과 온도에 따라 달라지므로, 긴 시간 간격이나 직렬 통신의 정확도가 중요하면 실제 사용 전압·온도에서 따로 검증합니다.

처음 ISP 기록에 쓰는 MOSI·MISO·SCK·RESET 패드와 이후 UART 업로드에 쓰는 TX·RX·DTR 패드는 다른 경로입니다. DTR은 100 nF 커패시터를 거쳐 RESET으로 이어지고 RESET은 풀업 저항을 통해 대상 전원에 연결됩니다.
처음 ISP 기록에 쓰는 MOSI·MISO·SCK·RESET 패드와 이후 UART 업로드에 쓰는 TX·RX·DTR 패드는 다른 경로입니다. DTR은 100 nF 커패시터를 거쳐 RESET으로 이어지고 RESET은 풀업 저항을 통해 대상 전원에 연결됩니다. · 클릭하면 확대됩니다.

클록 퓨즈가 외부 수정 소자나 외부 클록을 요구하도록 바뀌었다면 그 클록이 실제로 동작해야 후속 통신도 됩니다. 대상 소자 식별 정보가 다르게 읽히거나 기록에 실패하면 소자 선택, 전원, 공통 접지, RESET, 신호 배선과 클록을 차례로 확인합니다. 오류 검사를 강제로 무시해서 기록을 진행하지 않습니다. 기록용 Uno에 넣은 프로그램, 대상 설정과 최종 검증 결과를 구분해 남겨야 다음 기판에서도 같은 순서를 재현할 수 있습니다.

통신 성공을 확인하기 전 기초 조건을 점검합니다

설계와 실장 MCU 번호를 맞추고 지원하지 않는 설정이 남지 않았는지 확인합니다. 전원·리셋(reset)·클록의 허용 상태를 검증한 뒤 프로그래밍과 필요한 직렬 통신을 시험합니다. USB 변환기가 컴퓨터에 보인다고 해서 목표 MCU가 원하는 클록으로 실행 중이라고 판단하지 않습니다. 회로 버전(version), 실장 부품, 퓨즈 비트와 개발 환경 설정, 각 통신 시험의 결과를 함께 기록합니다.

기판 여러 장을 USB 허브(USB hub)에 한꺼번에 연결해 시험할 때에는 터미널(terminal, 컴퓨터의 실행 메시지 창)에 성공 표시와 연결 오류가 섞여 나올 수 있습니다. 성공 문구 한 줄로 모든 기판이 정상이라고 판단하지 말고, 포트 번호와 기판 식별자별로 메시지를 나눠 기록한 뒤 문제가 난 기판을 단독으로 다시 시험합니다. 최초 ISP 기록이 완료됐다고 해서 나중에 실행한 프로그램의 통신까지 성공한 것은 아닙니다. 어느 단계의 어느 기판에서 실패했는지를 구분해야 전원·클록·펌웨어·연결 문제를 좁힐 수 있습니다.

핀 이름을 바꾸면 실제 읽기 호출도 같은 이름을 사용합니다

센서 입력을 한 곳에서 정의해도 호출에 옛 숫자가 남아 있으면 다른 핀을 읽을 수 있습니다. 예를 들어 sensorPin을 바꿔 놓고 analogRead(4)를 그대로 두지 말고 analogRead(sensorPin)처럼 같은 정의를 참조합니다. 핀 이름은 회로도와 실제 보드의 ADC 기능표에 대응시킵니다.

// Arduino Uno R3: select a verified analog input.
const int sensorPin = A0;
void loop() {
  int sample = analogRead(sensorPin);
  // Process this sample before the next read.
}

Arduino의 analogRead 참조는 지정한 아날로그 입력을 읽는 호출과 보드별 사용 가능 핀을 구분합니다. 위는 Uno R3의 A0를 사용하는 코드 조각이며 모든 보드의 핀 0 또는 핀 4가 ADC라는 뜻이 아닙니다. 이식할 때는 새 보드의 전압·기준전압·해상도와 핀 다중화를 확인하고, 코드 전체에 남은 숫자 핀과 읽기 호출을 찾아 수정한 뒤 알려진 입력으로 값을 재검사합니다. 이름을 일치시켰다는 사실만으로 배선·변환값이 정확하다고 판단하지 않습니다.

English summary. A named ADC pin must also be used at the read call. The Uno R3 A0 fragment is not a portable numeric-pin mapping. On migration, verify actual ADC capability, input/reference voltage and resolution, search for stale literal pin numbers, and retest with a known input.

게임 내용을 바꾸는 기판도 기록 경로를 남깁니다

게임처럼 펌웨어를 자주 바꾸는 소형 기판도 MCU가 지원하는 기록 포트를 남기면 소자를 빼지 않고 내용을 갱신할 수 있습니다. 실제 MCU 품번에 맞는 프로그래머, 핀 배치·신호 전압·RESET 연결과 기록 후 검증을 별도로 확인합니다. 포트가 보이는 사진만으로 특정 펌웨어의 기록 성공이나 호환성을 판단하지 않습니다.

펌웨어를 바꿀 수 있는지와 전원·충전 회로가 적합한지는 따로 확인해야 합니다. 충전 IC와 코인형 셀이 함께 보이더라도 충전 전류·종지 전압·셀 보호 조건을 확인하지 않은 조합을 안전한 충전 예시로 사용하지 않습니다.