PIC18F4550 em C e Assembly PIC16: o que a bancada MPLAB ensina de verdade
Quem monta painel com CLP acaba lidando com o mesmo tipo de problema que o PIC resolve na bancada: pino, tempo e estado. O relé do quadro não liga porque o bit no registrador “parece” certo; liga porque a lógica de I/O, o debounce e o ciclo de varredura estão consistentes. Este texto é um estudo de mãos no hardware do repositório pic_mcu — C no PIC18F4550 com MPLAB X e XC8, Assembly no PIC12F675, PIC16F84A e PIC16F628A com MPASM — e da interface LCD 16x2 que também está no site da Wilson Tecnologia. Não é release de fabricante e não é firmware de ECU de produção.
O que o repositório de fato contém
A raiz separa duas pastas: C e asm. O README registra as ferramentas usadas na época do estudo:
- C: MPLAB X v3.65 e compilador XC8 v1.45 (modo Free), no PIC18F4550 — e também exercícios em C no PIC12C508A e um driver de relé/timer no PIC16F628A.
- Assembly: MPLAB IDE v8.92 e MPASM v5.51, no caminho das aulas WR Kits, nos PIC12F675, PIC16F84A e PIC16F628A.
No C do PIC18F4550 os projetos MPLAB listados e presentes no disco são: Blink_LED (RB0), LCD_16x2, TIMER1_INTERRUPT_low, TIMER0_INTERRUPT_low, TIMER0_INTERRUPT_high e Butt_SCAN_INT. O README ainda marca SPI e CAN com MCP2515 como “coming soon” — portanto não trato esses dois como implementados. No Assembly, o 16F84A cobre o básico (setar pino, botão+LED, sub-rotina, delay, aritmética, lógica, condicional). O 16F628A vai longe: debounce, multiplicação e divisão, Timer0/Timer1/Timer2, PWM, WDT, comparador, Vref, DAC de 4 bits e display. No 12F675 o exercício registrado é AD.
Isso já define o escopo: família Mid-Range e PIC18 na bancada, não um stack AUTOSAR.
Mapa mental: o que abrir na ordem certa
| Ordem | Projeto / trilha | O que você está treinando |
|---|---|---|
| 1 | Blink_LED |
TRIS/LAT, clock, “grava e roda” |
| 2 | Butt_SCAN_INT |
Entrada, bounce, vetor de IRQ |
| 3 | Timer0/1 low/high | Prioridade, overflow, ISR curta |
| 4 | LCD_16x2 |
Protocolo, timing, HMI de diagnóstico |
| 5 | asm 16F84A | Banco, ciclo, registrador sem anestesia |
| 6 | asm 16F628A | PWM, WDT, timers “de verdade” |
| 7 | 12F675 AD | Pino compartilhado, conversão |
Pular direto para LCD sem LED/timer é o caminho mais curto para achar que “a biblioteca está quebrada” quando o oscilador é que está errado.
C no PIC18F4550: por que essa peça na bancada
O PIC18F4550 é um 40 pinos com USB on-chip, timers, ADC e I/O em quantidade suficiente para protótipo didático. Eu o usei com XC8 em modo Free e _XTAL_FREQ em 48 MHz nos projetos irmãos da Fatec — o PLL de 96 MHz com postscaler /2 é o caminho clássico quando o oscilador primário alimenta o USB e o CPU. No pic_mcu o primeiro exercício é o mais honesto: piscar LED em RB0.
Por que começar pelo LED? Porque no PIC o “pisca” força três decisões que o CLP esconde atrás do ciclo de varredura:
- Direção do pino — TRIS. Sem isso o LAT escreve no vazio.
- Escrita no latch — LAT, não PORT, quando o objetivo é saída. Ler PORT e escrever de volta é a receita clássica de read-modify-write em pino compartilhado.
- Tempo — busy-wait (
__delay_ms) versus timer+interrupção. O primeiro ensina; o segundo é o que sobrevive quando o firmware cresce.
A sequência do repositório — LED, varredura de botão com interrupção, Timer0 em prioridade baixa e alta, Timer1 em prioridade baixa — é o mesmo caminho de um programador de CLP que sai do contato auxiliar e entra em interrupção cíclica e FC (function block) de tempo.
Nota de bancada. No PIC18 a prioridade de interrupção não é enfeite. High e low são vetores diferentes. Se o debounce do botão e o overflow do timer caem no mesmo nível sem disciplina de tempo de ISR, o LED “funciona” até o dia em que o LCD começa a receber nibble pela metade. Isolar ISR curta (setar flag) e trabalho no main é o hábito que depois se traduz em tarefa cíclica de CLP e em watchdog de painel.
Tabela de decisão: busy-wait vs timer vs IRQ
| Necessidade | Busy-wait __delay_ms |
Timer polled | Timer + IRQ |
|---|---|---|---|
| Aula de LED | Adequado | Overkill | Overkill |
| Debounce + outro I/O | Ruim (trava) | Aceitável | Melhor |
| LCD init one-shot | Aceitável | — | — |
| Base de tempo periódica | Não | Frágil sob carga | Sim |
| Convivência com USB/outros | Não | Arriscado | Sim, ISR curta |
O repo ensina a escada. Quem fica no degrau do delay para sempre leva o hábito ruim para o painel.
LCD 16x2: o HMI mais barato que ainda ensina protocolo
O site da Wilson Tecnologia mostra o projeto de interface 16x2 no PIC18F4550 em C. No repositório a pasta C/pic_18f4550/LCD_16x2 guarda o projeto MPLAB e a pasta de datasheet do módulo. Não invento aqui o mapa de pinos nem a biblioteca: o que interessa é o princípio.
O HD44780 (e clones) não é um “print” mágico. É uma máquina de estados com RS, R/W, E e nibble ou byte de dados. Em 4 bits você economiza pino e paga em temporização: o pulso de Enable, o delay de inicialização (os tais milissegundos depois do power-on) e a distinção comando versus dado. Quem já integrou IHM de CLP via RS-485 reconhece o problema: o display não perdoa sequência errada, só que aqui o “telegrama” tem 4 bits e um pino E.
Na bancada eu trato o LCD como IHM de diagnóstico, não como interface de segurança. Mostrar um inteiro, um char e um float em linhas diferentes — como no exercício irmão da Fatec — serve para validar driver e cursor. Não serve para anunciar estado seguro de uma prensa.
Ponte industrial. O LCD 16x2 no embarcado é o primo pobre da IHM 7". O valor pedagógico é o mesmo da IHM barata no retrofit: o operador vê o que o controlador acha que está acontecendo. Se o texto congela e o processo continua, você descobriu que o HMI não é canal de segurança — descoberta que ISO 13849 e NR-12 já pressupõem, e que ASIL também pressupõe.
Pitfalls do HD44780 na bancada
| Sintoma | Causa comum | O que checar |
|---|---|---|
| Quadrados cheios, sem texto | Init cedo demais / nibble errado | Delay pós power-on, sequência 4-bit |
| Caracteres invertidos / lixo | RS/E trocados ou timing de E | Osciloscópio no E; datasheet do clone |
| Linha 2 escreve na 1 | Endereço DDRAM | Comando de cursor / posição |
| Funciona no reset, quebra sob IRQ | ISR longa no meio do nibble | Flag no ISR; escreve no main |
| Contraste “morto” | Vo / pot | Antes de reescrever o driver |
LCD que falha “só com timer ligado” quase nunca é mistério de biblioteca: é reentrância e tempo.
Assembly Mid-Range: o registrador sem anestesia
O MPASM no 16F84A e no 16F628A é o antídoto contra a ilusão de que “C embarcado é C de PC”. Sem banco de registradores, sem OPTION_REG, sem prescaler do Timer0, o overflow não cai no tempo que a conta de serviette prometeu. Os exercícios de WR Kits no README não são um produto; são musculação:
I/O e debounce (o bounce do fim de curso no CLP), aritmética em 8 bits sem float de graça, PWM/duty (primo do analog out do inversor), WDT (se o laço trava, o chip reinicia — em produção isso vira supervisor e janela; no exercício, já basta não deixar o WDT desligado por acidente) e AD no 12F675 (oito pinos, pino compartilhado; serve para 0–5 V de bancada, não para sensor raciométrico com diagnóstico de cabo aberto).
Não trato a lista como feature de produto. São drills. O 16F84A já é peça de museu de linha — e ainda é o melhor professor de banco e de ciclo de instrução que eu usei.
O que o Assembly ensina que o XC8 esconde
- Banco de registradores: esquecer
BANKSELé o “funciona até mexer numa SFR”. - Prescaler compartilhado (Timer0 / WDT no Mid-Range): mudar um afeta o outro.
- Ciclo de instrução vs tempo de pino: delay em Assembly mente se o clock config está errado.
- PWM por hardware no 16F628A: duty e período não são
analogWriteconceitual — são registradores.
Quem só escreveu C Free no XC8 e nunca abriu o .lst ainda não viu o custo real de uma chamada.
Notas de bancada que o README não escreve, mas o ferro cobra
- Gravação e MCLR. LVP ligado no config (padrão em vários templates XC8) muda o papel do PGM. Se o gravador falha “do nada”, olhe config bit antes de trocar cabo.
- Brown-out e WDT. Nos projetos Fatec irmãos o WDT vem OFF e o BOR ON. Em painel industrial eu não entrego comando de potência com WDT desligado. Na bancada didática, desligar WDT evita reset no delay longo — e ensina o trade-off.
- Read-modify-write. LED em PORTBbit e botão no mesmo PORT é a armadilha clássica. LAT no PIC18 existe por isso.
- Oscilador. EC_EC, XT, HS: o bit de config errado produz “grava e não roda”. Antes de duvidar do C, meça clock ou pisque um LED no reset.
- Ferramentas. MPLAB X 3.65 + XC8 1.45 e MPLAB 8.92 + MPASM 5.51 são o ambiente deste repo; reabrir no X atual pede migração.
Troubleshooting rápido (sintoma → ação)
| Sintoma | Ação 1 | Ação 2 |
|---|---|---|
| Grava e não roda | Config de oscilador | LED no reset / medir clock |
| Pino “não liga” | TRIS | LAT vs PORT |
| Timer “errado” | Prescaler + _XTAL_FREQ |
Prioridade / vetor |
| Botão falso | Debounce / pull-up | ISR vs main |
| LCD morto | Init timing | Cabo/RS/E |
| Reset periódico | WDT ligado sem clear | BOR / alimentação |
Ponte com CLP, painel e linha automotiva didática
| Bancada PIC | Analogia no CLP / painel | Limite da analogia |
|---|---|---|
| TRIS / LAT | %QX direção + imagem de saída | CLP isola eletricamente |
| Debounce | Filtro de entrada | Tempo de ciclo vs ISR |
| Timer IRQ | TON / interrupção cíclica | Safety não vive só nisso |
| LCD 16x2 | IHM de diagnóstico | Não é canal seguro |
| WDT | Watchdog de CPU | Em máquina: supervisor externo |
| PWM 16F628A | Analog out / velocidade | Sem STO / torque limit |
A ponte é didática e útil em retrofit barato. Não autoriza declarar conformidade NR-12 ou ISO 26262 a partir de um .X de LED.
O que este repositório ensina — e o que não chega a produção ASIL
| Ensina de verdade | Não é, e não finjo que é |
|---|---|
| TRIS/LAT, timer, vetor de interrupção, prioridade no PIC18 | Software de item de segurança ISO 26262 (ASIL A–D) |
| Driver HD44780 e HMI de diagnóstico | IHM certificada, canal redundante, QM vs ASIL decomposto |
| Debounce, PWM, WDT, AD de bancada | Stack CAN/ISO-TP, UDS, XCP, calibração de ECU |
| XC8 Free e MPASM como ferramenta | Compilador qualificado, MISRA completo, cobertura MC/DC |
| SPI/CAN “coming soon” no README | Transceiver, common-mode, terminação, EMC de veículo |
ISO 26262 pede processo: item definition, HARA, requisitos, partição QM/ASIL, ferramentas classificadas, testes com evidência. Um .X do MPLAB que pisca LED e escreve no LCD é o chão desse edifício, não o último andar. Confundir as duas coisas é o erro que eu mais vejo em portfólio de embarcado: “fiz PWM no 16F628A, logo entendo torque vectoring”.
A ponte honesta é outra: conversar ciclo versus interrupção com quem programa o CLP, montar IHM barato de diagnóstico em retrofit, e não ter medo do datasheet quando o inversor “não responde”. O mesmo músculo aparece depois no cluster e na ECU monoponto da Fatec — ainda laboratório.
O que deliberadamente não fazer
- Não tratar SPI/CAN “coming soon” como código existente.
- Não migrar o projeto antigo no MPLAB X novo sem esperar quebra de toolchain.
- Não usar LCD ou LED como prova de estado seguro de máquina.
- Não entregar comando de potência com WDT off “porque na aula estava assim”.
- Não inflar o repo em tutorial de SaaS, cloud ou “ECU ASIL em 30 dias”.
Fechamento
pic_mcu é o caderno em que o C e o Assembly se encontram no pino. O site mostra o LCD 16x2; o GitHub mostra a escada que chega lá: LED, timer, botão, display. SPI e CAN ficam no README como intenção, não como código. Quem precisa de firmware de veículo com nível ASIL não começa — nem termina — aqui. Quem precisa entender por que o bit não vira, começa exatamente aqui.