Firmware para PIC e dsPIC (MPLAB X + XC + MCC; PICkit / Snap / ICD)
Carregue também a skill embedded-c-cpp para padrões de codificação, arquitetura, testes unitários e depuração geral. Esta skill contém as partes específicas da Microchip. O firmware PIC é escrito em C (XC8 não possui C++).
Primeiro, identifique o projeto
| O que procurar | Onde encontrar | Por que é importante |
|---|---|---|
| Parte exata (PIC16F18877, PIC18F47Q10, PIC24FJ128GA010, dsPIC33CK256MP508, PIC32MX795F512L...) | nbproject/configurations.xml (<targetDevice>), MCC .mc3, usuário | Registradores, periféricos, PPS, modelo de interrupção e memória diferem por parte — no dsPIC33, as famílias F, E, C e A têm módulos PWM/ADC/PLL diferentes |
| Compilador + versão | configurations.xml (<languageToolchain>, <languageToolchainVersion>) | XC8 vs XC16 vs XC-DSC (dsPIC) vs XC32; níveis de otimização e sintaxe diferem |
| Versão do MCC | Estrutura mcc_generated_files/, arquivo .mc3; Melody (mais novo: subpastas system/, timer/, *_Initialize) vs Clássico | Onde residem os bits de configuração e drivers, nomes das APIs |
| Clock | Configurações de clock no MCC / #pragma config (FEXTOSC, RSTOSC / FNOSC / POSCMOD), defines _XTAL_FREQ ou FCY | Atrasos, taxas de baud, períodos de timer |
| Programador/depurador | PICkit 4/5, MPLAB Snap, ICD 4/5 | Capacidade de alimentação e programação de alta tensão |
Quando um nome de registrador ou bit for incerto, indique qual seção do datasheet consultar (ou leia o cabeçalho do dispositivo pic16f18877.h etc. no diretório de includes do compilador) em vez de chutar — os nomes de registradores PIC variam entre subfamílias.
Regras que previnem as falhas clássicas do PIC
- Leitura de entrada digital retorna 0 → ANSEL. Na maioria dos PICs modernos, os pinos iniciam como analógicos. Limpe o bit
ANSELx(no MCC: desmarque "Analógico") para toda entrada digital. - Escreva em
LATx, leia dePORTx. Escrever bits emPORTxfaz leitura-modificação-escrita dos níveis dos pinos e pode alterar outras saídas (cargas pesadas, alternância rápida). Partes sem registradores LAT precisam de uma variável shadow. - TRIS: 1 = entrada, 0 = saída. Fácil de inverter.
- Peripheral Pin Select (PPS) deve mapear sinais UART/SPI/PWM para pinos em dispositivos PPS; com
PPS1WAY = ONsó pode ser destravado uma vez após reset — deixe o MCC gerar isso. - Bits de configuração definem oscilador, watchdog, MCLR, LVP, brown-out, proteção de código. Defina-os no MCC (ou na janela Configuration Bits → Generate Source Code), nunca deixe com defaults que você não verificou. Oscilador errado = nada funciona ou todo timing está incorreto.
_XTAL_FREQ(XC8) /FCY(XC16) deve ser igual ao clock real —__delay_ms()e muitos cálculos dependem disso.- Atomicidade de 8 bits: no PIC16/18, qualquer
uint16_t/uint32_tcompartilhado com uma ISR é lido em várias instruções — desabilite aquela interrupção (ou GIE) durante a leitura. No PIC24/dsPIC o mesmo se aplica a valores de 32 bits. - Pilha de chamadas por hardware é minúscula em PICs de 8 bits (8 níveis em PIC16 antigos, 16 nos PIC16F1 aprimorados, 31 no PIC18) e a ISR também usa níveis. Sem recursão; observe o aviso do XC8 (1393) possível estouro de pilha de hardware e a profundidade estimada na saída da compilação.
- Flags de interrupção: na ISR, verifique tanto o bit de habilitação quanto o de flag (
if (PIEx.xIE && PIRx.xIF)), limpe a flag, mantenha curto. Habilite interrupção periférica + global (MCC:INTERRUPT_GlobalInterruptEnable()). - Regeneração do MCC sobrescreve
mcc_generated_files/. Coloque o código da aplicação em seus próprios arquivos.c/.h; mantenhamain.cenxuto; revise a caixa de diálogo de mesclagem do MCC em vez de aceitar cegamente. - Configurações irreversíveis/arriscadas: proteção de código (CP), proteção contra escrita, desabilitar MCLR junto com LVP desligado, configurações de oscilador que param o chip. Não habilite proteção de código nem altere isso em um dispositivo do usuário sem confirmação explícita; um Snap não consegue recuperar uma parte que precisa de programação de alta tensão.
Sintaxe específica por família (interrupções, atrasos, configuração, memória): references/families.md.
dsPIC33 (controle, DSP, controle de motores, fontes digitais)
O dsPIC33 usa a sintaxe do núcleo PIC24 mais um motor DSP. Regras extras:
- FCY = FOSC/2; a configuração do PLL e a comutação de clock diferem por família (EP vs CK/CH) — gere com o MCC e verifique as frequências reportadas, incluindo o clock auxiliar que aciona PWM/ADC.
- Use ponto fixo Q15 (biblioteca DSP
dsp.h,libq.h, builtins) em vez defloatem loops rápidos; documente a escala de cada variável. - Limite explicitamente integradores e saídas em C — a aritmética C normal wrappa; a saturação do
CORCONsó protege operações do motor DSP. - Loop de controle = interrupção do ADC disparada pelo PWM em alta prioridade; meça seu tempo de execução em um osciloscópio.
- Configure as entradas de falta/limite de corrente do PWM antes de habilitar as saídas em qualquer estágio de potência, e teste o dead time em baixa tensão primeiro — código PWM errado destrói hardware.
- Habilite o trap de estouro catastrófico do acumulador (
COVTE); deixeOVATE/OVBTEdesligado para código MAC normal (os bits de guarda são feitos para serem usados). - Conjuntos alternados de registradores no dsPIC33CK/CH usam
__attribute__((interrupt, context))com prioridade ISR correspondente — nãoshadow. - dsPIC33CH é dual-core: dois projetos, posse de pinos, mailboxes MSI.
Detalhes: references/dspic33.md.
Compilar, programar, depurar
| Ação | Como fazer |
|---|---|
| Compilar no IDE | MPLAB X → Clean and Build (martelo+vassoura). Verifique o Memory Summary e avisos na saída |
| Compilar headless | prjMakefilesGenerator.sh <proj>.X@default depois make -C <proj>.X CONF=default → dist/default/production/<proj>.X.production.hex |
| Programar | MPLAB X "Make and Program Device", MPLAB IPE, ou ipecmd pela linha de comando |
| Depurar | MPLAB X Debug Main Project com PICkit/Snap/ICD (build de depuração), ou o MPLAB X Simulator para lógica/timers puros sem hardware |
Programação altera o dispositivo: confirme a parte e o programador com o usuário antes de executar ipecmd, e nunca apague/proteja sem confirmação. Comandos completos, diferenças entre programadores e solução de problemas de conexão: references/build-program-debug.md.
Quando não funciona
- Nada executa: bits de configuração (fonte do oscilador, WDT, MCLR), alimentação, pull-up do MCLR (10 kΩ), programador liberou o dispositivo do reset (IPE "Release from Reset" /
-OL). - Executa na velocidade errada / baud errado:
RSTOSC/FNOSC, PLL, divisor de clock (CDIV),_XTAL_FREQincompatível. - Reinícios aleatórios: leia os bits de causa de reset na inicialização (PCON/PCON0/RCON —
references/families.md), watchdog não limpo, estouro de pilha (STKOVF), brown-out. - PIC24/dsPIC reinicia ou trava subitamente: instale handlers de trap (
_AddressError,_StackError,_MathError,_OscillatorFail) — erros de endereço geralmente significam acesso de 16 bits desalinhado.
Arquivos de referência
| Arquivo | Leia quando |
|---|---|
references/families.md | Escrevendo/revisando código para uma família específica: sintaxe de interrupção, atrasos, bits de configuração, modelo de memória, atomicidade, causas de reset, traps, cache/DMA do PIC32, dicas de otimização e memória do XC8 |
references/dspic33.md | Qualquer trabalho com dsPIC33: famílias, XC-DSC, comutação PLL/clock, motor DSP e matemática Q15, registradores context/shadow de ISR, traps matemáticos, DMA, loops de controle PWM/ADC de alta velocidade, dual-core CH, ferramentas motorBench/potência, lista de verificação de revisão |
references/mcc-and-project.md | Estrutura do projeto, MCC Melody vs Clássico, regras de regeneração, onde colocar código, drivers de periféricos (UART, I2C, ADC, timers, PWM, NVM/EEPROM), baixo consumo |
references/build-program-debug.md | Instalação de ferramentas, compilações headless, programação com ipecmd, diferenças entre PICkit/Snap/ICD, limites de depuração, solução de problemas "não consegue conectar / ID do dispositivo não corresponde", teste unitário de código PIC no PC |