Come passare un programma
Assembly scritto per 16F84 al 16F1827
|
Note
Ricordiamo che:
-
Una comodità è data dal fatto che 16F1827 può lavorare senza quarzo da 31 kHz
a 32 MHz, utilizzando un circuito interno, come peraltro in modo più limitato
può fare anche 16F628.
Questo non è preciso come il cristallo
esterno, ma per applicazioni in cui il tempo di clock non è determinante
(ovvero la maggior parte...),
permette di risparmiare componenti.
-
Gli Enhanced Mid-range hanno come tools di sviluppo e programmazione indicati PICkit3,
ICD3 e REAL-ICE. Se usate altri tools o tools di terze parti, verificate che il
PIC16F1827 sia supportato.
- Dato che 16F1827 dispone della
possibilità di debug attraverso ISCP/ICD,
il tools Microchip scelto avrà anche la possibilità di effettuare il debug in
circuit. 16F84 e 16F628 non hanno questa possibilità.
- 16F1826 è la stessa cosa di 16F1827, ma con una quantità di
memoria
inferiore
- Le versioni LF sono previste per funzionare in un range di alimentazione
tra 1.8 V e 3.6 V. Quindi attenzione alla tensione di alimentazione.
"Accendi il LED"
Vediamo come il programma minimale "accendi il LED",
scritto per il vecchio 16F84, possa essere passato al 16F1827 senza modifiche
sensazionali, se non quelle relative alle diverse prestazioni dell' ambiente.
Per i test abbiamo usato la nostra 18-pini
Mini Demo Board, che è estremamente pratica e comoda per questo
genere di esercitazioni, anche per la possibilità di funzionare sia stand
alone, sia inserita su una breadboard. Si potrà utilizzare anche una 18-pin
Demo Board DM164120-4 di Microchip che è offerta proprio con il
16F1827 o qualsiasi altra soluzione. Anche perchè lo schema elettrico è
minimale.
Sono necessari solo pochissimi componenti:
L' oscillatore è composto dal classico quarzo a 4MHz (limite del
16F84) e dai condensatori C1 e C2.
Una resistenza R2 è il pull-up del MCLR (sempre per i limiti del
16F84).
Il LED è collegato tra RA1 e la massa con una resistenza di
limitazione R1.
Non dimenticare un condensatore sull' alimentazione (C3) vicino ai pin
del chip.
La presa ISCP/ICD è necessaria per la programmazione on board.
Inoltre l' intero circuito è alimentabile direttamente dal
PICkit3.
- C1-C2 18-27 pF
- C3 100 nF
- R1 330 ohm
- R2 10 k
- Q1 4 MHz
|
|
"Accendi il LED" - ver. 16F84
Per curiosità, iniziamo con una versione extra-skyfo del sorgente, giusto
per avere ben chiaro quello che NON bisogna seguire come esempio:
list p=16F84
_CONFIG=3FF2H
org 0x00
bsf 0x03, 05
movlw
0x00
movwf TRISA
bcf
0x03, 05
bsf 0x03, 1
goto $
end
;--------------------------------------------
; al momento della programmazione scegliere:
; memory unprotected
; watchdog timer disabled
; standard crystal (4 MHz)
; power-up timer on
Davanti ad un aborto del genere, il consiglio è quello dantesco:"non
ti curar di lor, ma guarda e passa...".
Però possiamo vedere i dettagli della versione "infernale" e come si trasforma in
versione "paradisiaca".
|
manca completamente una testata di commento
che spieghi, almeno superficialmente, cosa si voglia fare |
list p=16F84
|
definizione del processore |
|
|
org 0x00 |
locazione di partenza del programma (vettore di reset) |
bsf 0x03, 05
movlw
0x00
movwf
0X85
bcf
0x03, 05
bsf 0x05,
1
|
essendo utilizzati valori assoluti, il senso
delle operazioni è remoto, anche perchè non c'è alcun commento
esplicativo |
goto $ |
l' uso del $ ha
forti limitazioni sulla portabilità |
end
|
fine programma |
;--------------------------------------------
; sul programmatore scegliere:
; memory uprotected
; watchdog timer disabled
; standard crystal (4 MHz)
; power-up timer on
|
non ha alcun senso demandare ad una azione
manuale sul programmatore quello che la linea __CONFIG
farebbe automaticamente |
Una scrittura minimale, ma più sensata, rende le cosa ben più semplici:
;---------------------------------------------------------------------
; FILE: helloLed84.asm
; AUTH: afg
; DATE: 04/05/20129
; DESC: Accendi un LED con 16F84
; NOTE: Verificato con PIC16F84-04/P su 18-pin Demo Board di Microchip.
;
;----------------------------------------------------------------------
; definizione del processore
list p=16F84
#include "P16F84.inc"
;----------------------------------------------------------------------
; CONFIGURAZIONE
; memoria non protetta
; watchdog timer disabled
; power-up timer abilitato
; standard crystal (4 MHz)
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC
;----------------------------------------------------------------------
; uso dell' I/O
; definizione per il LED per utilizzarla nel sorgente
#define LED PORTA, 1 ; LED collegato tra PA0
e massa.
; Si accende con PA0=1
;----------------------------------------------------------------------
; inizio programma
org 0x00
; vettore di reset
; al POR è puntato il Banco 0
start clrf
PORTA ; azzera il latch di PORTA (banco 0)
banksel
TRISA
;
va al banco di TRISA (banco 1)
movlw
0x00
movwf
TRISA ; PORTA come uscita
banksel PORTA
; va al banco di PORTA (banco 0)
bsf LED
; accendi LED
lock goto
lock ; blocco
end
;----------------------------------------------------------------------
Adesso le cose sono più chiare e, come vedremo, la scrittura è portabile
facilmente, anche veramente minimale (d' altronde anche il programma lo è...).
"Accendi il LED" - ver. 16F628
Vediamo cosa dobbiamo fare per il 16F628.
;---------------------------------------------------------------------
; FILE: helloLed628.asm
; AUT : afg
; DATE: 04/05/20129
; DESC: Accendi un LED con 16F628
; NOTE: Verificato con PIC16F628 su 18-pin Demo Board di Microchip.
;
;----------------------------------------------------------------------
; definizione del processore
list p=16F628
#include "P16F628.inc"
;----------------------------------------------------------------------
; CONFIGURAZIONE
; memoria non protetta
; watchdog timer disabled
; power-up timer abilitato
; standard crystal (4 MHz)
__CONFIG, _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC
; LVP disabilitato
; MCLR abilitato
__CONFIG, _LVP_OFF & _MCLRE_ON
;----------------------------------------------------------------------
; uso dell' I/O
; definizione per il LED per utilizzarla nel sorgente
#define LED PORTA, 1 ; LED collegato tra PB0
e massa.
; Si accende con PB0=1
;----------------------------------------------------------------------
; inizio programma
org 0x00
start
; la prima linea non è necessaria perchè al
POR è puntato il Banco 0
;banksel CMCON ; va
al banco di CMCON (banco 0)
movlw
0x07 ; disabilita i comparatori da
PORTA
movwf
CMCON ; CMCON è in Banco 0
; anche PORTA è in Banco 0
clrf
PORTA ; azzera il latch di PORTA
(banco 0)
banksel
TRISA ;
va al banco di TRISA (banco
1)
movlw
0x00
movwf
TRISA ; PORTA come uscita
banksel
PORTA ;
va al banco di PORTA (banco 0)
bsf LED
; accendi LED
lock goto
lock ; blocco
end
;----------------------------------------------------------------------
E' stato necessario aggiungere solo due righe per disabilitare i comparatori
che, al default del POR, si trovano abilitati ed impedirebbero l' uso del
PORTA 0 in modo digitale.
Ovviamente il _CONFIG sarà differente, visto che si tratta di un chip con
diverse prestazioni.
Le linee di configurazione, che solitamente sono una sola, qui sono scritte in
due blocchi per rendere evidente come una serie di opzioni sia comune con il
PIC16F84, mentre un' altra serie sia relativa solo al PIC più recente.
"Accendi il LED" - ver. 16F1827
Veniamo ora all' Enhanced Mid-range.
;---------------------------------------------------------------------
; FILE: helloLed1827.asm
; AUT: afg
; DATE: 04/05/20129
; DESC: Accendi un LED con 16F1827
; NOTE: Verificato con PIC16F1827 su 18-pin Demo Board di Microchip.
;
;----------------------------------------------------------------------
; definizione del processore
list p=16F1827
#include "16F1827.inc"
;----------------------------------------------------------------------
; CONFIGURAZIONE
; memoria non protetta
; watchdog timer disabled
; power-up timer abilitato
; standard crystal (4 MHz)
__CONFIG _CONFIG1, _CP_OFF & _CPD_OFF & _WDTE_OFF & _PWRTE_ON
& _FOSC_HS
; LVP disabilitato
; MCLR abilitato
; BOR disabilitato
; CLOCKOUT, IESO, FCMEN, PLL, STVREN, WRT disabilitati
;
__CONFIG _CONFIG1, _LVP_OFF
& _MCLRE_ON & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF
;----------------------------------------------------------------------
; uso dell' I/O
; definizione per il LED per utilizzarla nel sorgente
#define LED PORTA, 1 ; LED collegato tra PB0
e massa.
; Si accende con PB0=1
;----------------------------------------------------------------------
; inizio programma
org 0x00
start banksel ANSELA ;
va al banco di ANSELA (banco3)
clrf
ANSELA ; disabilita la funzione analogica da PORTA
banksel
PORTA ;
va al banco di PORTA (banco 0)
clrf
PORTA ; azzera il latch di PORTA
banksel
TRISA
; va al banco di TRISA (banco 1)
movlw
0x00
movwf
TRISA ; PORTA come uscita
banksel
PORTA ;
va al banco di PORTA (banco 0)
bsf LED
; accendi LED
lock goto lock
; blocco
end
;----------------------------------------------------------------------
E' stato necessario aggiungere solo due righe per disabilitare la
funzione di ingresso dell' ADC che, al default del POR, si trova abilitata ed
impedirebbe l' uso del PORTA 0 in modo digitale.
Disponendo il microcontroller di modo sleep, potrebbe essere elegante
arrestarlo in questa condizione, che ha un consumo minore del loop chiuso.
Ovviamente pure questo _CONFIG sarà differente, visto che si tratta di un chip
con diverse prestazioni e, come possiamo vedere, si sviluppa su due blocchi
(CONFIG1 e CONFIG2). Anche qui le linee sono state divise per rendere evidente
le parti comuni e quelle specifiche del chip.
CVD...
Vediamo comparate sole le parti principali del programma:
16F84 |
16F628 |
16F1827 |
Note |
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC
org 0x00
start
|
__CONFIG, _CP_OFF &
_WDT_OFF & _PWRTE_ON & _LVP_OFF & _HS_OSC & _MCLRE_ON
org 0x00
start movlw 0x07
movwf
CMCON
|
__CONFIG _CONFIG1, _FOSC_HS & _WDTE_OFF &
_PWRTE_ON & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF
& _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF
& _LVP_OFF
org 0x00
start banksel ANSELA
clrf ANSELA
banksel
PORTA
|
Area istruzioni necessarie ad adeguare l' hardware
specifico del processore |
clrf
PORTA
banksel
TRISA
movlw
0x00
movwf
TRISA
banksel
PORTA
bsf LED
lock goto
lock
end |
clrf
PORTA
banksel
TRISA
movlw
0x00
movwf
TRISA
banksel
PORTA
bsf LED
lock goto
lock
end |
clrf
PORTA
banksel
TRISA
movlw
0x00
movwf
TRISA
banksel
PORTA
bsf LED
lock goto
lock
end |
Area istruzioni necessarie ad accendere il LED |
Osserviamo che il "core" del programma è identico nelle tre
versioni; quello che cambia è l' aggiunta iniziale di istruzioni per adeguare
l' hardware specifico di ciascun processore. 16F84, che ha l' hardware con
la minore complessità (meno funzioni, meno memoria, meno registri) sarà
quello che richiede meno adeguamenti; ma il problema della programmazione
sta solo relativamente negli adeguamenti della base hardware, che, una volta
conosciuti, valgono per tutte le situazioni di compatibilità all' indietro e
vengono riportati pari pari. La programmazione vera e propria sta da un' altra
parte. Così, qualsiasi programma o attività didattica si
svolgerà molto più proficuamente sul chip più recente che su quello
precedente e ancor più sensibile differenza si avrà utilizzando un C.
Come Volevasi Dimostrare, non esiste alcuna pregiudizale logica
e sensata per non
partire con il prodotto più recente piuttosto che con uno precedente, se non
addirittura più
"antico". |
Questo perchè:
- la struttura del programma è identica: basta quel minimo
di adeguamento all' ambiente diverso, che, peraltro, deve essere applicato
anche per il passaggio dal nonno 16F84 al nipote 16F628, dato che ogni
chip ha le sue particolarità.
- ovvero, è possibile esercitare sul PIC più recente qualunque cosa
funziona su quello più datato
- ma, per contro, utilizzando il PIC più recente si avrà la
possibilità di sperimentare un gran numero di funzioni, prestazioni e
situazioni non possibili col suo predecessore
- per di più spendendo meno !
E' evidente che chi sostiene la necessità per il principiante di
partire dal "Momento della Creazione del Silicio" non ha minimamente le idee chiare.
Il concetto guida per l' uso di chip complessi e con data sheet di
centinaia di pagine non è quello di ritenere più accessibili i componenti
meno dotati, ma bensì quello di approcciare il componente complesso col l'
idea della "Libreria".
Nella "Libreria" complessa e vasta del componente "dotato"
inizierò a scegliere quali "libri" leggere, ovvero quali
periferiche e funzioni utilizzare: le altre resteranno lì, inutilizzate, fino
a che non mi serviranno. Le le pagine del foglio dati relative a queste parti
non saranno neppure sfogliate.
Così il componente complesso, affrontato per gradi, non sarà niente di più
che l' utilizzare gradualmente le possibilità della famiglia di
microcontroller, potendo per di più scegliere quali parti considerare e quali
no.
Nota:
Va però detto onestamente che ci sono da considerare alcuni presupposti:
- è necessario, sopratutto per il principiante assoluto, l' appoggio
di un tutor adeguato.
Questo, ovviamente, è valido per qualsiasi approccio, dato che chi fa da
sè fa per tre, ma chi parte con un valido aiuto arriva molto prima e
molto più proficuamente, dato che l' apprendimento non sta nel procedere
per errori e correzioni, ma nell' evitare di ripetere errori inutili con
un adeguato studio o aiuto e concentrare gli sforzi sul risultato.
Ovvero, con questo mini tutorial avete ora ben chiaro che accendere un LED
sull' arcaico 16F84 o sul super performante 16F1827 è la stessa cosa; ma
questo perchè avete seguito appunto un tutorial (che dovrebbe essere un
mezzo per rendere l' apprendimento più efficace). Senza il tutorial, per
i più arrivare alle stesse conclusione avrebbe richiesto un tempo ben
più lungo che la lettura di queste pagine.
- la struttura di base è analoga tra il chip obsoleto e quello ultima
generazione, e questo permette di utilizzare con ragionevole semplicità
le vecchie applicazioni o corsi o tutorial.
Occorre però che queste esercitazioni e tutorial siano aggiornati:
finchè si tiene buono quanto scritto 10 anni fa, il progresso
difficilmente progredisce...
- Però, la conoscenza delle prestazioni addizionali del nuovo prodotto,
delle sue caratteristiche specifiche, dell' uso delle periferiche enhanced
è un lavoro del tutto nuovo e va affrontato di nuovo per ogni chip
che appartenga ad una diversa famiglia rispetto a quello fino ad ora
usato.
- E, fatto chiave, i microcontroller di una stessa area (PIC16, PIC18,
PIC24) sono omologhi, ma NON sono tutti esattamente uguali. Questo
è evidenziato dalle "trappole" in cui si cade passando
da un chip ad un' altro, dove il cambio di una funzione o di un bit o di
una modalità operativa arrestano lo sviluppatore per ore nel tentativo di
venirne a capo. Fa storia il comparatore attivo al POR che impedisce su
alcune porte l' uso digitale o la diversa gestione dei banchi o il pin
open drain, ecc.
Qui, il punto 1 può essere sostituito, con meno efficienza, solo
dall' accurata lettura del foglio dati (406 pagine in inglese...) e dalla
consultazione di forum o documentazione varia.
- Si potrà giustamente sostenere che l' uso di linguaggi evoluti e di
librerie
adeguate rendono i sorgenti molto meno dipendenti dall' hardware di quanto
sia possibile con il "semplice" Assembly, anche se questo è
ineguagliabile in alcune situazioni.
Una nota extra.
Per chi rimane impressionato dall' estensione del __CONFIG
completo del 16F1827, va detto che l'impostazione di tutte le opzioni
possibili non è strettamente necessaria; da un punto di vista funzionale
basterebbe accertarsi di avere fissato le opzioni indispensabili al
funzionamento del programma, trascurando completamente le altre. Se, negli
esempi precedenti, ci limitassimo alle opzioni minime, il CONFIG avrebbe lo
stesso aspetto.
All' atto pratico, però, è buona cosa inserire una versione completa:
- una volta scritta, copia e incolla; non si perde tempo. Al
massimo si varieranno quelle opzioni necessarie al nuovo progetto
- in ogni caso, scrivendo alcune opzioni nei registri di CONFIG, questi
registri vengono modificati. Tanto vale essere sicuri di avere una base
di configurazione ben definita piuttosto che ritrovarsi con qualche
spiacevole bit fuori posto.
- infine, dal punto di vista didattico, e non solo, conoscere
tutte le possibilità del componente che si sta usando è l' unico modo
per usarlo al meglio.
Per ultimo, la configurazione va fatta attraverso il sorgente e non
manualmente sul dispositivo di programmazione: questa pratica è inutilmente
astrusa, fonte di errori e non portabile.
L' uso delle direttive di configurazione è chiaro, portabile e il risultato
è automatico.
|