Lezione 3 di 43

Lezione 02

🎓 PIC16 — From Zero to Hero · Lezione 02

Il PIC16F84A — Il nostro dispositivo 🔧

Pinout, registri speciali, banchi di memoria e valori di reset.
Tutto quello che devi sapere prima di scrivere la prima istruzione I/O.

🎯 Cosa impari in questa lezione

  • Il pinout completo del PIC16F84A — cosa fa ogni pin
  • Cos’è il registro TRIS e come configura la direzione dei pin
  • Tutti i SFR con indirizzo, valore di reset e funzione
  • Come funziona la selezione dei banchi con RP0/RP1
  • Il registro STATUS bit per bit
  • Il registro OPTION_REG e a cosa serve

📋 Scheda lezione

Modulo0 — Il Laboratorio
Lezione02 di 42
Livello⭐ Principiante
Tempo~30 minuti
DevicePIC16F84A
CodiceSolo esempi, nessun esercizio lungo

📦 Il package — 18 pin in un chip

Il PIC16F84A è disponibile in package PDIP-18 (dual in-line, 18 pin) e SOIC-18. Nel simulatore useremo sempre il modello PDIP-18, che è il più facile da visualizzare e da usare su breadboard.

18 pin sembrano pochi — e lo sono — ma sono sufficienti per imparare tutto quello che serve. Ecco la mappa completa:

PIC16F84A 18-pin PDIP 4MHz · 1K Flash · 68B RAM RA2 I/O digitale 1 RA3 I/O digitale 2 RA4 / T0CKI I/O · Clock TMR0 3 MCLR̄ / VPP Reset (attivo basso) 4 VSS GND — 0V 5 RB0 / INT I/O · Interrupt esterno 6 RB1 I/O digitale 7 RB2 I/O digitale 8 RB3 I/O digitale 9 RA1 I/O digitale 18 RA0 I/O digitale 17 OSC2/CLKOUT Uscita clock ÷4 16 OSC1/CLKIN Ingresso clock/quarzo 15 VDD Alimentazione +5V 14 RB7 I/O · IOC · PGD 13 RB6 I/O · IOC · PGC 12 RB5 I/O · IOC 11 RB4 I/O · IOC 10 1 2 3 4 5 6 7 8 9 18 17 16 15 14 13 12 11 10 PORTA (5 pin) PORTB (8 pin) Clock/Oscillatore Reset Alimentazione GND
Figura 1 — Pinout PIC16F84A PDIP-18 (dati da datasheet DS35007C)

Pin speciali — da non dimenticare mai

Pin 4 — MCLR̄

Master Clear Reset, attivo basso. Se questo pin va a 0V, il PIC si resetta immediatamente. Nel circuito reale deve sempre essere collegato a VDD (tramite resistenza pull-up) per evitare reset accidentali. Nel simulatore è gestito automaticamente.

Pin 15/16 — OSC1/OSC2

L’ingresso e l’uscita del circuito oscillatore. Tipicamente collegati a un quarzo da 4 MHz con due condensatori da 22 pF. La frequenza del quarzo determina la velocità di esecuzione. Nel simulatore è configurabile come parametro del progetto.

Pin 3 — RA4/T0CKI

Pin I/O a drain aperto — a differenza degli altri, in uscita non può fornire corrente (solo assorbirla). Come ingresso alternativo, è il clock esterno del Timer0. Da ricordare se ci si chiede perché un LED non si accende su RA4.


🔀 TRIS — il registro che decide la direzione

Ogni pin I/O del PIC può essere configurato come ingresso o uscita. La direzione si imposta scrivendo nei registri TRISA (banco 1, indirizzo 0x85) e TRISB (banco 1, indirizzo 0x86).

Regola TRIS

0 = Output (zero = uscita)
1 = Input (uno = ingresso)

Un trucco mnemonico: 0 = Output, 1 = Input. O forse preferisci: TRIState Input — quando un bit TRIS è 1, il pin è in alta impedenza (input).

Valori di reset

Dopo il reset, tutti i pin sono input per default:
TRISA = 0x1F (tutti e 5 i bit a 1)
TRISB = 0xFF (tutti gli 8 bit a 1)

Questo è un comportamento di sicurezza: un pin configurato erroneamente come output potrebbe danneggiare il circuito esterno.

Esempio pratico: voglio RB0–RB3 come output (LED) e RB4–RB7 come input (pulsanti):

; Per accedere al banco 1 devo settare RP0 nel registro STATUS
BSF STATUS, RP0 ; banco 0 → banco 1

; TRISB = 1111 0000 = 0xF0
; ^^^^ ^^^^
; RB7..4 RB3..0
; input output
MOVLW 0xF0
MOVWF TRISB

; Torno al banco 0 per usare PORTB
BCF STATUS, RP0 ; banco 1 → banco 0

⚠️ Nota: TRISB sta nel banco 1, PORTB sta nel banco 0. Ogni volta che devi configurare i TRIS devi prima passare al banco 1, poi tornare al banco 0. Lo vedremo in dettaglio nella prossima sezione.


🗂️ I due banchi di memoria — e come si cambia

La RAM del PIC16F84A è divisa in due banchi da 128 byte. In ogni momento la CPU lavora su un solo banco, selezionato dal bit RP0 nel registro STATUS.

Mappa RAM — PIC16F84A (valori reali) BANCO 0 (RP0 = 0) 0x00 INDF — Indirizzamento indiretto 0x01 TMR0 — Timer 0 (reset: 0xFF) 0x02 PCL — Program Counter (byte basso) 0x03 STATUS — Flag Z,C,DC,RP0,RP1… 0x04 FSR — Puntatore indiretto 0x05 / 0x06 PORTA / PORTB 0x08 / 0x09 EEDATA / EEADR — EEPROM 0x0C–0x4F GPR — 68 byte liberi per variabili BANCO 1 (RP0 = 1) 0x80 INDF — mirror di 0x00 0x81 OPTION_REG — prescaler, pullup, clock 0x82 / 0x83 PCL / STATUS — mirror banco 0 0x84 FSR — mirror di 0x04 0x85 / 0x86 TRISA / TRISB — direzione I/O 0x88 / 0x89 EECON1 / EECON2 — ctrl EEPROM 0x0A / 0x0B PCLATH / INTCON — mirror 0x8C–0xCF GPR — mirror banco 0 (stesso dato!) ⇄ RP0
Figura 2 — Mappa completa della RAM con indirizzi reali

I registri con indirizzi 0x00, 0x02, 0x03, 0x04, 0x0A, 0x0B sono accessibili da entrambi i banchi senza dover cambiare RP0 — sono mappati fisicamente una sola volta. Le GPR (0x0C–0x4F) sono ugualmente accessibili da entrambi i banchi.


🚦 Il registro STATUS — ogni bit conta

Il registro STATUS (0x03) è uno dei più importanti. Contiene i flag dell’ALU (risultati delle operazioni) e i bit di controllo della banca. Vale la pena conoscerlo bit per bit.

STATUS Register — 0x03 (reset: 0x18 = 0001 1000) bit 7 IRP Bank ind. bit 6 RP1 Sel. banco bit 5 RP0 Sel. banco ★ bit 4 T̄O̅ Timeout WDT bit 3 P̄D̅ Power Down bit 2 Z Zero flag ★ bit 1 DC Digit Carry bit 0 C Carry flag ★ 0=banco0 / 1=banco1 1 se risultato = 0 1 se overflow ★ = bit usati frequentemente nel codice · TO e PD si leggono dopo reset/SLEEP, non si scrivono normalmente Valore di reset: 0x18 = bit TO e PD = 1 (power-on normale), tutti gli altri = 0
Figura 3 — Registro STATUS bit per bit (indirizzo 0x03, reset 0x18)

🟣 Flag Z — Zero

Si mette a 1 quando il risultato di un’operazione è esattamente zero. È il flag più usato: serve per implementare confronti, contatori e condizioni di uscita dai loop. Istruzioni come DECFSZ si basano su di esso internamente.

🟠 Flag C — Carry

Si mette a 1 quando un’addizione supera 255 (overflow a 8 bit) oppure quando in una sottrazione il risultato è negativo. Indispensabile per l’aritmetica multi-byte (numeri a 16 o 32 bit).

🔵 Bit RP0 — Bank Select

Con BSF STATUS, RP0 vai al banco 1 (dove stanno TRIS e OPTION_REG). Con BCF STATUS, RP0 torni al banco 0. Ricordati sempre di tornare al banco 0 dopo aver configurato i TRIS — è uno degli errori più comuni.


⚙️ OPTION_REG — il registro delle opzioni

Il registro OPTION_REG (banco 1, indirizzo 0x81, reset 0xFF) controlla il comportamento del Timer0, dei pull-up su PORTB e del fronte attivo sull’interrupt esterno. Nelle prossime lezioni lo useremo spesso.

BitNome01Default
7RBPU̅Pull-up PORTB attiviPull-up PORTB disabilitati1
6INTEDGFronte di discesa (↓)Fronte di salita (↑)1
5T0CSClock interno (Fosc/4)Clock esterno su RA4/T0CKI1
4T0SEFronte di salita su RA4Fronte di discesa su RA41
3PSAPrescaler assegnato a TMR0Prescaler assegnato al WDT1
2–0PS2:PS0Valore prescaler (000=1:2 … 111=1:256)111

💡 Dato che tutti i bit di reset sono 1 (0xFF), al power-on: pull-up PORTB disabilitati, clock TMR0 esterno, prescaler al WDT. Prima di usare il Timer0 bisogna configurare OPTION_REG — lo faremo nella Lezione 17.

🏋️ Prova tu!

Carica questo codice nel simulatore ed eseguilo con Step. Osserva il pannello dei registri.

LIST p=16F84A
#include <p16f84a.inc>
ORG 0x00

; Vado al banco 1
BSF STATUS, RP0

; Configuro PORTB: tutti output
CLRF TRISB

; Torno al banco 0
BCF STATUS, RP0

; Accendo tutti i pin di PORTB
MOVLW 0xFF
MOVWF PORTB

FINE GOTO FINE
END

  1. Dopo BSF STATUS, RP0: guarda il registro STATUS nel simulatore. Il bit 5 è andato a 1?
  2. Dopo CLRF TRISB: guarda l’indirizzo 0x86 nella mappa RAM. È diventato 0x00?
  3. Dopo BCF STATUS, RP0: il bit 5 di STATUS è tornato a 0?
  4. Dopo MOVWF PORTB: guarda l’indirizzo 0x06. Vedi 0xFF? E nel pannello I/O, tutti i pin RB0–RB7 sono alti?

❓ Quiz rapido

1. Voglio RB0 come output e RB1–RB7 come input. Che valore scrivo in TRISB?

Mostra risposta

TRISB = 0xFE → binario 1111 1110. Il bit 0 è 0 (output), tutti gli altri sono 1 (input).


2. Sto scrivendo su TRISB ma nel simulatore vedo che PORTB non cambia. Qual è l’errore più probabile?

Mostra risposta

Stai scrivendo su PORTB invece di TRISB, oppure hai dimenticato di passare al banco 1 prima (BSF STATUS, RP0). TRISB è nel banco 1, PORTB è nel banco 0.


3. Dopo un reset, il registro STATUS vale 0x18. Quali bit sono a 1?

Mostra risposta

0x18 = 0001 1000 → bit 4 (T̄O̅) e bit 3 (P̄D̅) sono a 1. Indicano che il reset è avvenuto per power-on normale (non per WDT né per SLEEP). RP0, Z, C, DC sono tutti a 0 → banco 0 selezionato, nessun flag attivo.


4. Perché RA4 non può pilotare un LED direttamente come fanno RA0–RA3?

Mostra risposta

Perché RA4 è un pin a drain aperto: in uscita può solo portare il pin a 0V (assorbire corrente), non a VDD (fornire corrente). Per pilotare un LED su RA4 serve una resistenza pull-up esterna verso VDD.

Prossima lezione →

Lezione 03 — Il registro W e le prime istruzioni
MOVLW, MOVWF, MOVF, CLRW, CLRF: le cinque istruzioni fondamentali
per spostare dati tra W, costanti e registri RAM.

© Prof. D. Bertolino · PIC16 From Zero to Hero · WebPicSimulator · Lezione 02