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:

  1. Direção do pino — TRIS. Sem isso o LAT escreve no vazio.
  2. 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.
  3. 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 analogWrite conceitual — 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.