Was macht Snap / ICD)?
Lade ebenfalls embedded-c-cpp für Codierungsstandards, Architektur, Unit-Tests und allgemeines Debugging. Dieser Skill enthält die Microchip-spezifischen Teile. PIC-Firmware wird in C geschrieben (XC8 hat kein C++).
Zuerst: Projekt identifizieren
| Finden | Wo | Warum es wichtig ist |
|---|---|---|
| Exaktes Bauteil (PIC16F18877, PIC18F47Q10, PIC24FJ128GA010, dsPIC33CK256MP508, PIC32MX795F512L...) | nbproject/configurations.xml (<targetDevice>), MCC .mc3, Benutzer | Register, Peripherie, PPS, Interrupt-Modell, Speicher unterscheiden sich pro Bauteil – bei dsPIC33 haben die Familien F, E, C und A unterschiedliche PWM/ADC/PLL-Module |
| Compiler + Version | configurations.xml (<languageToolchain>, <languageToolchainVersion>) | XC8 vs. XC16 vs. XC-DSC (dsPIC) vs. XC32; Optimierungsstufen und Syntax unterscheiden sich |
| MCC-Variante | mcc_generated_files/ Layout, .mc3 Datei; Melody (neuer: system/, timer/ Unterordner, *_Initialize) vs. Classic | Wo Konfigurationsbits und Treiber leben, API-Namen |
| Takt | MCC-Takteinstellungen / #pragma config (FEXTOSC, RSTOSC / FNOSC / POSCMOD), _XTAL_FREQ oder FCY define | Verzögerungen, Baudraten, Timer-Perioden |
| Programmierer/Debugger | PICkit 4/5, MPLAB Snap, ICD 4/5 | Spannungsversorgung und Hochspannungs-Programmierfähigkeit |
Wenn ein Register- oder Bit-Name unsicher ist, nenne den Datenblattabschnitt zum Nachschlagen (oder lies den Device-Header pic16f18877.h usw. im Compiler-Include-Verzeichnis), anstatt zu raten – PIC-Registernamen variieren zwischen Unterfamilien.
Regeln, die die klassischen PIC-Fehler verhindern
- Digitaler Eingang liest 0 → ANSEL. Bei den meisten modernen PICs sind Pins nach dem Einschalten analog. Lösche das
ANSELx-Bit (MCC: "Analog" abwählen) für jeden digitalen Eingang. - Schreibe
LATx, lesePORTx. Das Schreiben vonPORTx-Bits führt einen Read-Modify-Write der Pin-Pegel durch und kann andere Ausgänge umkippen lassen (starke Lasten, schnelles Toggeln). Teile ohne LAT-Register benötigen eine Schattenvariable. - TRIS: 1 = Eingang, 0 = Ausgang. Leicht zu invertieren.
- Peripheral Pin Select (PPS) muss UART/SPI/PWM-Signale auf Pins bei PPS-Geräten mappen; mit
PPS1WAY = ONkann es nur einmal nach dem Reset entsperrt werden – lasse es von MCC generieren. - Config-Bits bestimmen Oszillator, Watchdog, MCLR, LVP, Brown-out, Code-Schutz. Setze sie in MCC (oder im Config-Bits-Fenster → Quellcode generieren), verlasse dich nie auf nicht überprüfte Standardeinstellungen. Falscher Oszillator = nichts läuft oder jede Zeitsteuerung ist falsch.
_XTAL_FREQ(XC8) /FCY(XC16) muss dem echten Takt entsprechen –__delay_ms()und viele Berechnungen hängen davon ab.- 8-Bit-Atomizität: Bei PIC16/18 wird jeder
uint16_t/uint32_t, der mit einer ISR geteilt wird, in mehreren Instruktionen gelesen – deaktiviere diesen Interrupt (oder GIE) um das Lesen herum. Bei PIC24/dsPIC gilt das Gleiche für 32-Bit-Werte. - Hardware-Callstack ist winzig bei 8-Bit-PICs (8 Ebenen bei alten PIC16, 16 bei enhanced PIC16F1, 31 bei PIC18) und die ISR verbraucht auch Ebenen. Keine Rekursion; achte auf die XC8-Warnung (1393) possible hardware stack overflow und die geschätzte Tiefe in der Build-Ausgabe.
- Interrupt-Flags: Überprüfe in der ISR sowohl Enable- als auch Flag-Bits (
if (PIEx.xIE && PIRx.xIF)), lösche das Flag, halte sie kurz. Aktiviere periphere + globale Interrupts (MCC:INTERRUPT_GlobalInterruptEnable()). - MCC-Regeneration überschreibt
mcc_generated_files/. Lege Anwendungscode in eigenen.c/.h-Dateien ab; haltemain.cschlank; überprüfe den MCC-Merge-Dialog, anstatt blind zu akzeptieren. - Irreversible / riskante Einstellungen: Code-Schutz (CP), Write-Schutz, Deaktivieren von MCLR zusammen mit LVP aus, Oszillatoreinstellungen, die den Chip stoppen. Aktiviere keinen Code-Schutz oder ändere diese Einstellungen ohne explizite Bestätigung am Gerät des Benutzers; ein Snap kann ein Teil, das Hochspannungsprogrammierung benötigt, nicht wiederherstellen.
Familien-spezifische Syntax (Interrupts, Verzögerungen, Config, Speicher): references/families.md.
dsPIC33 (Regelung, DSP, Motorregelung, Digital Power)
dsPIC33 verwendet die PIC24-Core-Syntax plus eine DSP-Engine. Zusätzliche Regeln:
- FCY = FOSC/2; PLL-Setup und Taktumschaltung unterscheiden sich pro Familie (EP vs. CK/CH) – generiere mit MCC und überprüfe die gemeldeten Frequenzen, einschließlich des Hilfstakts, der PWM/ADC antreibt.
- Verwende Q15-Festkomma (DSP-Bibliothek
dsp.h,libq.h, Builtins) anstelle vonfloatin schnellen Schleifen; dokumentiere die Skalierung jeder Variable. - Begrenze Integratoren und Ausgänge explizit in C – normale C-Arithmetik läuft über; die
CORCON-Sättigung schützt nur DSP-Engine-Operationen. - Regelkreis = PWM-getriggerter ADC-Interrupt mit hoher Priorität; messe seine Ausführungszeit auf einem Oszilloskop.
- Konfiguriere PWM-Fehler-/Strombegrenzungseingänge vor dem Aktivieren der Ausgänge an jeder Leistungsstufe, und teste die Totzeit zuerst bei niedriger Spannung – falscher PWM-Code zerstört Hardware.
- Aktiviere die katastrophale Akkumulator-Überlauf-Falle (
COVTE); lasseOVATE/OVBTEfür normalen MAC-Code aus (Guard-Bits sind zur Nutzung vorgesehen). - dsPIC33CK/CH alternative Registersätze verwenden
__attribute__((interrupt, context))mit passender ISR-Priorität – nichtshadow. - dsPIC33CH ist Dual-Core: zwei Projekte, Pin-Besitz, MSI-Mailboxen.
Details: references/dspic33.md.
Bauen, Programmieren, Debuggen
| Aktion | Wie |
|---|---|
| Bauen in der IDE | MPLAB X → Clean and Build (Hammer+Besen). Überprüfe die Memory Summary und Warnungen in der Ausgabe |
| Headless-Build | prjMakefilesGenerator.sh <proj>.X@default dann make -C <proj>.X CONF=default → dist/default/production/<proj>.X.production.hex |
| Programmieren | MPLAB X "Make and Program Device", MPLAB IPE, oder ipecmd von der Kommandozeile |
| Debuggen | MPLAB X Debug Main Project mit PICkit/Snap/ICD (Debug-Build), oder der MPLAB X Simulator für reine Logik/Timer ohne Hardware |
Programmieren verändert das Gerät: bestätige das Bauteil und den Programmierer mit dem Benutzer, bevor du ipecmd ausführst, und lösche/schütze niemals ohne Bestätigung. Vollständige Befehle, Programmierer-Unterschiede und Verbindungs-Fehlerbehebung: references/build-program-debug.md.
Wenn es nicht funktioniert
- Nichts läuft: Config-Bits (Oszillatorquelle, WDT, MCLR), Spannung, MCLR-Pull-up (10 kΩ), Programmierer hat das Gerät aus dem Reset entlassen (IPE "Release from Reset" /
-OL). - Läuft mit falscher Geschwindigkeit / falschem Baud:
RSTOSC/FNOSC, PLL, Taktteiler (CDIV),_XTAL_FREQ-Missmatch. - Zufällige Resets: lies die Reset-Ursachen-Bits beim Booten (PCON/PCON0/RCON –
references/families.md), Watchdog nicht gelöscht, Stack-Überlauf (STKOVF), Brown-out. - PIC24/dsPIC plötzlicher Reset oder Hänger: installiere Trap-Handler (
_AddressError,_StackError,_MathError,_OscillatorFail) – Adressfehler bedeuten meist einen nicht ausgerichteten 16-Bit-Zugriff.
Referenzdateien
| Datei | Lesen, wenn |
|---|---|
references/families.md | Code für eine bestimmte Familie schreiben/überprüfen: Interrupt-Syntax, Verzögerungen, Config-Bits, Speichermodell, Atomizität, Reset-Ursachen, Traps, PIC32-Cache/DMA, XC8-Optimierung und Speicher-Tipps |
references/dspic33.md | Jede dsPIC33-Arbeit: Familien, XC-DSC, PLL/Taktumschaltung, DSP-Engine und Q15-Mathe, ISR-Context/Shadow-Register, Math-Traps, DMA, High-Speed-PWM/ADC-Regelkreise, Dual-Core CH, motorBench/Power-Tools, Review-Checkliste |
references/mcc-and-project.md | Projektstruktur, MCC Melody vs. Classic, Regenerierungsregeln, wo Code abgelegt wird, Peripherietreiber (UART, I2C, ADC, Timer, PWM, NVM/EEPROM), Low Power |
references/build-program-debug.md | Tools installieren, Headless-Builds, ipecmd-Programmierung, PICkit/Snap/ICD-Unterschiede, Debugging-Grenzen, "cannot connect / device ID mismatch"-Fehlerbehebung, Unit-Tests von PIC-Code auf dem PC |