PIC & dsPIC 펌웨어 (MPLAB X + XC + MCC; PICkit / Snap / ICD)
코딩 표준, 아키텍처, 단위 테스트 및 일반 디버깅을 위해 embedded-c-cpp도 함께 로드하세요. 이 스킬은 Microchip 특화 부분을 다룹니다. PIC 펌웨어는 C로 작성됩니다 (XC8은 C++를 지원하지 않음).
먼저, 프로젝트를 식별하세요
| 찾을 항목 | 위치 | 중요한 이유 |
|---|---|---|
| 정확한 부품 (PIC16F18877, PIC18F47Q10, PIC24FJ128GA010, dsPIC33CK256MP508, PIC32MX795F512L...) | nbproject/configurations.xml (<targetDevice>), MCC .mc3, 사용자 | 레지스터, 주변장치, PPS, 인터럽트 모델, 메모리는 부품마다 다름 — dsPIC33의 경우 F, E, C, A 계열은 PWM/ADC/PLL 모듈이 다름 |
| 컴파일러 + 버전 | configurations.xml (<languageToolchain>, <languageToolchainVersion>) | XC8 vs XC16 vs XC-DSC (dsPIC) vs XC32; 최적화 수준과 구문이 다름 |
| MCC 종류 | mcc_generated_files/ 레이아웃, .mc3 파일; Melody (최신: system/, timer/ 하위 폴더, *_Initialize) vs Classic | 설정 비트와 드라이버의 위치, API 이름이 다름 |
| 클록 | MCC 클록 설정 / #pragma config (FEXTOSC, RSTOSC / FNOSC / POSCMOD), _XTAL_FREQ 또는 FCY 정의 | 지연, 보레이트, 타이머 주기에 영향 |
| 프로그래머/디버거 | PICkit 4/5, MPLAB Snap, ICD 4/5 | 전원 및 고전압 프로그래밍 기능 |
레지스터 또는 비트 이름이 확실하지 않으면, 추측하지 말고 확인할 데이터시트 섹션을 알려주세요 (또는 컴파일러의 include 디렉토리에서 장치 헤더 pic16f18877.h 등을 읽으세요) — PIC 레지스터 이름은 서브-패밀리마다 다릅니다.
고전적인 PIC 실패를 방지하는 규칙
- 디지털 입력이 0으로 읽힘 → ANSEL. 대부분의 최신 PIC에서 핀은 전원 켜질 때 아날로그로 설정됩니다. 모든 디지털 입력에 대해
ANSELx비트를 클리어하세요 (MCC: "Analog" 체크 해제). LATx에 쓰고,PORTx를 읽으세요.PORTx비트에 쓰면 핀 레벨의 읽기-수정-쓰기가 발생하여 다른 출력을 변경할 수 있습니다 (무거운 부하, 빠른 토글). LAT 레지스터가 없는 부품은 섀도우 변수가 필요합니다.- TRIS: 1 = 입력, 0 = 출력. 반대로 하기 쉽습니다.
- 주변장치 핀 선택 (PPS) 은 PPS 장치에서 UART/SPI/PWM 신호를 핀에 매핑해야 합니다.
PPS1WAY = ON인 경우 리셋 후 한 번만 잠금 해제할 수 있으므로 MCC가 생성하도록 하세요. - 설정 비트 는 오실레이터, 워치독, MCLR, LVP, 저전압 감지, 코드 보호를 결정합니다. MCC (또는 Configuration Bits 창 → Generate Source Code)에서 설정하고, 확인하지 않은 기본값으로 절대 남겨두지 마세요. 잘못된 오실레이터 = 아무것도 실행되지 않거나 모든 타이밍이 어긋납니다.
_XTAL_FREQ(XC8) /FCY(XC16)는 실제 클록과 일치해야 합니다 —__delay_ms()및 많은 계산이 이에 의존합니다.- 8비트 원자성: PIC16/18에서 ISR과 공유되는
uint16_t/uint32_t는 여러 명령어에 걸쳐 읽히므로 읽기 주변에서 해당 인터럽트(또는 GIE)를 비활성화하세요. PIC24/dsPIC에서는 32비트 값에도 동일하게 적용됩니다. - 하드웨어 호출 스택이 매우 작습니다 (오래된 PIC16에서 8단계, 향상된 PIC16F1에서 16단계, PIC18에서 31단계) 그리고 ISR도 단계를 사용합니다. 재귀 금지; XC8 경고 (1393) possible hardware stack overflow 와 빌드 출력의 예상 깊이를 주시하세요.
- 인터럽트 플래그: ISR에서 인에이블 비트와 플래그 비트를 모두 확인하고 (
if (PIEx.xIE && PIRx.xIF)), 플래그를 클리어하고, 짧게 유지하세요. 주변장치 + 전역 인터럽트를 활성화하세요 (MCC:INTERRUPT_GlobalInterruptEnable()). - MCC 재생성은
mcc_generated_files/를 덮어씁니다. 애플리케이션 코드는 자신의.c/.h파일에 배치하고,main.c는 얇게 유지하세요. MCC 병합 대화상자를 맹목적으로 수락하지 말고 검토하세요. - 되돌릴 수 없거나 위험한 설정: 코드 보호(CP), 쓰기 보호, LVP 비활성화와 함께 MCLR 비활성화, 칩을 멈추게 하는 오실레이터 설정. 사용자의 장치에서 명시적 확인 없이 코드 보호를 활성화하거나 이러한 설정을 변경하지 마세요. Snap은 고전압 프로그래밍이 필요한 부품을 복구할 수 없습니다.
패밀리별 구문 (인터럽트, 지연, 설정, 메모리): references/families.md.
dsPIC33 (제어, DSP, 모터 제어, 디지털 전원)
dsPIC33은 PIC24 코어 구문에 DSP 엔진을 더한 것입니다. 추가 규칙:
- FCY = FOSC/2; PLL 설정 및 클록 전환은 패밀리(EP vs CK/CH)마다 다릅니다 — MCC로 생성하고 보고된 주파수(PWM/ADC를 구동하는 보조 클록 포함)를 확인하세요.
- 빠른 루프에서는
float대신 Q15 고정소수점 (DSP 라이브러리dsp.h,libq.h, 빌트인)을 사용하고, 모든 변수의 스케일링을 문서화하세요. - C에서 적분기와 출력을 명시적으로 클램프 하세요 — 일반 C 산술은 래핑됩니다.
CORCON포화는 DSP 엔진 연산만 보호합니다. - 제어 루프 = PWM으로 트리거된 고우선순위 ADC 인터럽트; 오실로스코프로 실행 시간을 측정하세요.
- 출력을 활성화하기 전에 PWM 오류/전류 제한 입력을 구성 하고, 먼저 저전압에서 데드 타임을 테스트하세요 — 잘못된 PWM 코드는 하드웨어를 파괴합니다.
- 치명적인 누산기 오버플로우 트랩(
COVTE)을 활성화하세요. 일반 MAC 코드에서는OVATE/OVBTE를 끄세요 (가드 비트는 사용하도록 설계됨). - dsPIC33CK/CH 대체 레지스터 세트는 일치하는 ISR 우선순위와 함께
__attribute__((interrupt, context))를 사용합니다 —shadow가 아닙니다. - dsPIC33CH는 듀얼 코어입니다: 두 개의 프로젝트, 핀 소유권, MSI 메일박스.
자세한 내용: references/dspic33.md.
빌드, 프로그래밍, 디버그
| 동작 | 방법 |
|---|---|
| IDE에서 빌드 | MPLAB X → Clean and Build (망치+빗자루). 출력에서 메모리 요약과 경고를 확인하세요 |
| 헤드리스 빌드 | prjMakefilesGenerator.sh <proj>.X@default 그런 다음 make -C <proj>.X CONF=default → dist/default/production/<proj>.X.production.hex |
| 프로그래밍 | MPLAB X "Make and Program Device", MPLAB IPE, 또는 명령줄에서 ipecmd |
| 디버그 | MPLAB X Debug Main Project with PICkit/Snap/ICD (디버그 빌드), 또는 순수 로직/타이머를 위한 MPLAB X 시뮬레이터 (하드웨어 없이) |
프로그래밍은 장치를 변경합니다: ipecmd를 실행하기 전에 사용자와 부품 및 프로그래머를 확인하고, 확인 없이 절대 지우거나 보호하지 마세요. 전체 명령어, 프로그래머 차이점 및 연결 문제 해결: references/build-program-debug.md.
작동하지 않을 때
- 아무것도 실행되지 않음: 설정 비트 (오실레이터 소스, WDT, MCLR), 전원, MCLR 풀업 (10 kΩ), 프로그래머가 장치를 리셋에서 해제했는지 (IPE "Release from Reset" /
-OL). - 잘못된 속도/잘못된 보레이트로 실행됨:
RSTOSC/FNOSC, PLL, 클록 분주기 (CDIV),_XTAL_FREQ불일치. - 무작위 리셋: 부팅 시 리셋 원인 비트 읽기 (PCON/PCON0/RCON —
references/families.md), 워치독이 클리어되지 않음, 스택 오버플로우 (STKOVF), 저전압 감지. - PIC24/dsPIC 갑작스러운 리셋 또는 정지: 트랩 핸들러 설치 (
_AddressError,_StackError,_MathError,_OscillatorFail) — 주소 오류는 일반적으로 잘못 정렬된 16비트 액세스를 의미합니다.
참조 파일
| 파일 | 다음 경우에 읽으세요 |
|---|---|
references/families.md | 특정 패밀리용 코드 작성/검토 시: 인터럽트 구문, 지연, 설정 비트, 메모리 모델, 원자성, 리셋 원인, 트랩, PIC32 캐시/DMA, XC8 최적화 및 메모리 팁 |
references/dspic33.md | 모든 dsPIC33 작업 시: 패밀리, XC-DSC, PLL/클록 전환, DSP 엔진 및 Q15 수학, ISR 컨텍스트/섀도우 레지스터, 수학 트랩, DMA, 고속 PWM/ADC 제어 루프, 듀얼 코어 CH, motorBench/전원 도구, 검토 체크리스트 |
references/mcc-and-project.md | 프로젝트 구조, MCC Melody vs Classic, 재생성 규칙, 코드 배치 위치, 주변장치 드라이버 (UART, I2C, ADC, 타이머, PWM, NVM/EEPROM), 저전력 |
references/build-program-debug.md | 도구 설치, 헤드리스 빌드, ipecmd 프로그래밍, PICkit/Snap/ICD 차이점, 디버깅 제한, "연결할 수 없음 / 장치 ID 불일치" 문제 해결, PC에서 PIC 코드 단위 테스트 |