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 對比 XC16 對比 XC-DSC (dsPIC) 對比 XC32;最佳化層級與語法有所不同 |
| MCC 版本 | mcc_generated_files/ 佈局、.mc3 檔案;Melody (較新:system/、timer/ 子資料夾、*_Initialize) 對比 Classic | 組態位元與驅動程式的存放位置、API 名稱 |
| 時脈 | MCC 時脈設定 / #pragma config (FEXTOSC、RSTOSC / FNOSC / POSCMOD)、_XTAL_FREQ 或 FCY 定義 | 延遲、鮑率、計時器週期 |
| 燒錄器/除錯器 | PICkit 4/5、MPLAB Snap、ICD 4/5 | 電源與高壓燒錄能力 |
當不確定某個暫存器或位元名稱時,請說明應查閱哪個資料表章節 (或讀取編譯器包含目錄中的裝置標頭檔 pic16f18877.h 等),而不是猜測——PIC 暫存器名稱因子系列而異。
防止經典 PIC 故障的規則
- 數位輸入讀取為 0 → ANSEL。 在大多數現代 PIC 上,引腳預設上電為 類比。清除每個數位輸入的
ANSELx位元 (MCC:取消勾選「Analog」)。 - 寫入
LATx,讀取PORTx。 寫入PORTx位元會對引腳電平進行讀取-修改-寫入,可能翻轉其他輸出 (大負載、快速切換)。沒有 LAT 暫存器的元件需要影子變數。 - TRIS:1 = 輸入,0 = 輸出。 容易搞反。
- 周邊引腳選擇 (PPS) 必須將 UART/SPI/PWM 訊號映射到 PPS 裝置的引腳上;若
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 位元數值。 - 硬體呼叫堆疊非常小:8 位元 PIC 上 (舊 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)、寫入保護、同時關閉 MCLR 與 LVP、可能停止晶片的振盪器設定。未經明確確認,請勿在用戶的裝置上啟用程式碼保護或更改這些設定;Snap 無法復原需要高壓燒錄的元件。
家族特定語法 (中斷、延遲、組態、記憶體):references/families.md。
dsPIC33 (控制、DSP、馬達控制、數位電源)
dsPIC33 使用 PIC24 核心語法加上 DSP 引擎。額外規則:
- FCY = FOSC/2;PLL 設定與時脈切換因家族而異 (EP 對比 CK/CH)——使用 MCC 產生並驗證報告的頻率,包括驅動 PWM/ADC 的輔助時脈。
- 在快速迴圈中使用 Q15 定點數 (DSP 函式庫
dsp.h、libq.h、內建函式) 而非float;記錄每個變數的縮放比例。 - 在 C 中明確限制積分器與輸出——標準 C 算術會繞回;
CORCON飽和僅保護 DSP 引擎操作。 - 控制迴路 = 高優先級的 PWM 觸發 ADC 中斷;在示波器上測量其執行時間。
- 在啟用任何功率級輸出之前,先配置 PWM 故障/電流限制輸入,並先在低電壓下測試死區時間——錯誤的 PWM 程式碼會破壞硬體。
- 啟用災難性累加器溢位陷阱 (
COVTE);對於一般 MAC 程式碼保持OVATE/OVBTE關閉 (保護位元預期會被使用)。 - dsPIC33CK/CH 交替暫存器組使用
__attribute__((interrupt, context))並搭配匹配的 ISR 優先級——而非shadow。 - dsPIC33CH 為雙核心:兩個專案、引腳所有權、MSI 信箱。
詳細資訊:references/dspic33.md。
建置、燒錄、除錯
| 動作 | 方法 |
|---|---|
| 在 IDE 中建置 | MPLAB X → Clean and Build (錘子+掃帚)。檢查輸出中的 Memory Summary 與警告 |
| 無頭建置 | 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 搭配 PICkit/Snap/ICD (除錯建置),或 MPLAB X Simulator 用於純邏輯/計時器 (無需硬體) |
燒錄會變更裝置:在執行 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 context/shadow 暫存器、數學陷阱、DMA、高速 PWM/ADC 控制迴路、雙核心 CH、motorBench/電源工具、審查清單 |
references/mcc-and-project.md | 專案結構、MCC Melody 對比 Classic、重新產生規則、放置程式碼的位置、周邊驅動程式 (UART、I2C、ADC、計時器、PWM、NVM/EEPROM)、低功耗 |
references/build-program-debug.md | 安裝工具、無頭建置、ipecmd 燒錄、PICkit/Snap/ICD 差異、除錯限制、「無法連接 / 裝置 ID 不匹配」故障排除、在 PC 上對 PIC 程式碼進行單元測試 |