Professional Documents
Culture Documents
Conoscere ed usare
Progettare con i microcontrollori PIC in modo facile e veloce
PICmicro
Copyright: 20 INWARE Edizioni S.r.l. Via Giotto, 7 20032 Cormano (MI) Tel: 02-66504755 Fax: 02-66508225 info@inwaredizioni.it - www.inwaredizioni.it
Tutti i diritti sono riservati a norma di legge e a norma delle convenzioni internazionali. vietata la riproduzione di testi e di disegni raccolti in questa opera. Nomi e marchi citati nel testo sono generalmente depositati o registrati dalle rispettive case produttrici.
Indice
1 - Introduzione ai PICmicro ............................................................................. 1 Un po di storia................................................................................................. 1 Introduzione al PICmicro ................................................................................. 2 PIC16F84A Il microcontrollore utilizzato in questo libro.................................. 5
CPU e memoria ....................................................................................................... 5 Periferiche ............................................................................................................... 5 Struttura interna....................................................................................................... 7 Organizzazione della memoria programma ............................................................. 8 Organizzazione della memoria dati ......................................................................... 9
Il software ...................................................................................................... 14
MPLAB: editor e compilatore ................................................................................. 14 Il software per la programmazione ........................................................................ 15
4 - Architettura interna del PIC16F84A.......................................................... 37 La Program Memory...................................................................................... 38 Il Register File................................................................................................ 38 La ALU........................................................................................................... 41 L'Accumulatore o registro W ......................................................................... 42 Il Program Counter (PC)................................................................................ 43 Lo Stack Pointer ............................................................................................ 44 5 - Realizzazione delle "luci in sequenza" .................................................... 47 6 - Le porte di I/O ............................................................................................. 51 Le porte A e B................................................................................................ 51 Stadi di uscita delle linee di I/O ..................................................................... 53
Stadio di uscita delle linee RA0, RA1, RA2 e RA3 ................................................ 53 Funzionamento in ingresso.................................................................................... 53 Funzionamento in uscita........................................................................................ 54 Stadio d'uscita della linea RA4 .............................................................................. 54 Stadio di uscita delle linee RB0, RB1, RB2 ed RB3 .............................................. 56 Stadio di uscita delle linee RB4, RB5, RB6 e RB7 ................................................ 57
8 - Gli interrupt ................................................................................................. 67 Tipi di evento e bit di abilitazione................................................................... 67 Interrupt vector ed Interrupt handler .............................................................. 68 Interrupt flag................................................................................................... 68 Salvataggio del contesto................................................................................ 69 Ritorno da un interrupt handler...................................................................... 70 Esempio pratico di gestione di un interrupt ................................................... 70 Analisi del sorgente INTRB.ASM................................................................... 71
Perch viene generato un interrupt quando premuto un tasto qualsiasi? ...........72
9 - Reset ............................................................................................................ 75 Power-On-Reset (POR)................................................................................. 77 Power-up Timer (PWRT) ............................................................................... 77 Oscillator Start-up Timer (OST)..................................................................... 77 10 - Il Power Down Mode................................................................................. 81 Introduzione ................................................................................................... 81 L'istruzione SLEEP ........................................................................................ 81 Il "risveglio" del PICmicro............................................................................... 82 Esempio di Power Down mode ..................................................................... 82 11 - Il watch dog timer (WDT) ......................................................................... 85 Introduzione ................................................................................................... 85 Assegnazione del PRESCALER al WDT ...................................................... 86 Esempio pratico di uso del Watch Dog Timer ............................................... 87 12 - Scrittura e lettura dati da EEPROM ........................................................ 89 Registri speciali per laccesso alla EEPROM dati ......................................... 89 Scrittura di un dato su EEPROM ................................................................... 89 Lettura di un dato da EEPROM ..................................................................... 91 13 - Esempi ed applicazioni pratiche............................................................. 93 Gestione di un display LCD ........................................................................... 93
Hello World! ...........................................................................................................94 Le linee Enable (E) e Register Select (RS) dell'LCD .............................................95 Multiplex sul bus dati .............................................................................................95 Analizziamo il sorgente LCD1.ASM .......................................................................96 Subroutine di gestione del display LCD .................................................................97
II
Realizzazione del gioco elettronico SIMON.............................................. 111 14 - Set di istruzioni....................................................................................... 113 Le istruzioni semplici ................................................................................... 113
ADDLW ............................................................................................................... 115 ADDWF ............................................................................................................... 116 ANDWF ............................................................................................................... 116 ANDLW ............................................................................................................... 117 BCF ..................................................................................................................... 118 BSF ..................................................................................................................... 118 BTFSC................................................................................................................. 119 BTFSS................................................................................................................. 119 CALL ................................................................................................................... 120 CLRF ................................................................................................................... 121 CLRW .................................................................................................................. 121 CLRWDT ............................................................................................................. 121 COMF.................................................................................................................. 122 DECF................................................................................................................... 122 DECFSZ .............................................................................................................. 123 GOTO.................................................................................................................. 123 INCF .................................................................................................................... 124 INCFSZ ............................................................................................................... 124 IORLW................................................................................................................. 125 IORWF ................................................................................................................ 125 MOVLW ............................................................................................................... 126 MOVF .................................................................................................................. 126 MOVWF............................................................................................................... 127 NOP..................................................................................................................... 127 RETFIE................................................................................................................ 127 RETLW................................................................................................................ 128 RETURN ............................................................................................................. 128 RLF...................................................................................................................... 129 RRF ..................................................................................................................... 130 SLEEP................................................................................................................. 131 SUBLW................................................................................................................ 131 SUBWF ............................................................................................................... 132 SWAPF................................................................................................................ 133 XORLW ............................................................................................................... 133 XORWF ............................................................................................................... 133
III
BZ ........................................................................................................................137 CLRC ................................................................................................................... 137 CLRDC ................................................................................................................ 137 CLRZ ................................................................................................................... 137 MOVFW ............................................................................................................... 138 NEGF................................................................................................................... 138 SETC ................................................................................................................... 138 SETDC................................................................................................................. 138 SETZ.................................................................................................................... 138 SKPC ...................................................................................................................139 SKPDC ................................................................................................................ 139 SKPNC ................................................................................................................ 139 SKPNDC.............................................................................................................. 139 SKPNZ................................................................................................................. 139 SKPZ ...................................................................................................................139 SUBCF................................................................................................................. 140 SUBDCF .............................................................................................................. 140 TSTF.................................................................................................................... 140
15 - Direttive dell'assembler MPASM........................................................... 141 CBLOCK ...................................................................................................... 141 __CONFIG................................................................................................... 141 DT ................................................................................................................ 143 #DEFINE...................................................................................................... 144 EQU ............................................................................................................. 144 ERRORLEVEL............................................................................................. 144 EXTERN ...................................................................................................... 145 GLOBAL ...................................................................................................... 146 IF.................................................................................................................. 146 IFDEF........................................................................................................... 147 INCLUDE ..................................................................................................... 147 ORG............................................................................................................. 148 RES.............................................................................................................. 148 MACRO........................................................................................................ 148 PROCESSOR.............................................................................................. 150 RADIX .......................................................................................................... 150 A - La programmazione ICSP dei PICmicro............................................. 151 B - Tabelle....................................................................................................... 155 Tabella dei caratteri ASCII........................................................................... 156 Tabella di conversione binario/esadecimale................................................ 157 C - Glossario dei termini utilizzati ................................................................ 159 .ASM file ...................................................................................................... 159 .ERR file....................................................................................................... 159 .HEX file ....................................................................................................... 159 .LST file........................................................................................................ 159 CPU ............................................................................................................. 159 ICSP............................................................................................................. 159 Interrupt ....................................................................................................... 159 Macro ........................................................................................................... 159 Microcontroller ............................................................................................. 159 IV
Notazione BINARIA ed ESADECIMALE ..................................................... 160 OPCODE ..................................................................................................... 160 Operazioni booleane ................................................................................... 160
AND..................................................................................................................... 160 OR ....................................................................................................................... 161 XOR..................................................................................................................... 161 NOT..................................................................................................................... 161
RAM............................................................................................................. 161 RESET......................................................................................................... 161 ROM, PROM, EPROM, EEPROM, FLASH................................................. 162
ROM .................................................................................................................... 162 PROM.................................................................................................................. 162 EPROM ............................................................................................................... 162 EEPROM ............................................................................................................. 162 FLASH................................................................................................................. 162
SUBROUTINE ............................................................................................. 162 D - Routine Assembler di varia utilit.......................................................... 163 Conversione da ASCII a binario .................................................................. 163 Conversione da binario a cifre ASCII .......................................................... 164 Conversione da esadecimale a cifre ASCII................................................. 166 Moltiplicazione tra due numeri binari a 16 bit.............................................. 167 Divisione tra un dividendo binario a 48 bit ed un divisore binario a 23 bit .. 168 Gestione di ore, minuti e secondi mediante Timer0.................................... 170 Discriminazione di un interrupt .................................................................... 172 E - Il contenuto del CD .................................................................................. 173 Linterfaccia grafica ..................................................................................... 173 I contenuti .................................................................................................... 174 F - Indice delle figure e delle tabelle............................................................ 175
Prefazione
Era la fine del 1991 quando misi per la prima volta i miei occhi su un data-book della Microchip, si trattava di un PIC17C42 "Preliminary". In quel periodo andava molto di moda stampare i data-book con questa scritta trasversale, forse lo facevano perch dubitavano che questi oggettini pretenziosi potessero mai guadagnarsi lo status di un prodotto maturo. Erano gli anni in cui la famiglia 5x, con il glorioso PIC16C54 rappresentava l'unico paniere di prodotti OTP a buon mercato disponibili (letteralmente) sulla piazza. Molti anni anagrafici (purtroppo) sono passati da allora, ma molti di pi tecnologicamente parlando. Oggi esistono migliaia di prodotti FLASH, la tecnologia che ha sostituito rapidamente quella OTP, di costruttori diversi, ma Microchip sempre l, continua a raccontare una storia cominciata negli anni ottanta. Da allora ha accompagnato i primi passi di milioni di firmwaristi e progettisti in erba, affascinando per la sua compattezza, per le prestazioni inarrivabili ad una semplicit spesso disarmante. Ciononostante, ai nostri giorni, si sentiva ancora il bisogno di un libro che parlasse di PIC "dando del tu" al lettore, non in senso letterale ma permettendo una rapida assimilazione dei concetti apprendendoli in modo molto pratico. Questo libro nasce infatti su un successo: il PIC BY EXAMPLE (noto anche come PBE), che nel 1997 il co-autore Tiziano Galizia scrisse con grande entusiasmo insieme a Sergio Tanzilli e lo pubblic in una esordiente Internet. Il PBE stato riorganizzato e rielaborato con la preziosa esperienza di Maurizio Del Corso che, lavorando a quattro mani con Tiziano Galizia, ha prodotto una trattazione ottimale, esaustiva e di indubbio aiuto per ogni neofita appassionato.
VII
Introduzione
Conoscere a fondo un microcontrollore non significa solo averne compreso le sue funzioni e le sue potenzialit, ma significa soprattutto disporre di uno strumento potentissimo per la realizzazione di sistemi elettronici ottimizzati per la gestione ed il controllo di apparecchiature anche molto complesse. Tuttavia, bench la letteratura in materia sia abbondante, non sempre immediato capire nel dettaglio come utilizzare questi dispositivi per trarne il massimo delle prestazioni. Lintento di questo volume accompagnare il lettore alla scoperta dei microcontrollori PICmicro, seguendo un approccio prevalentemente pratico in modo da realizzare semplici progetti fin dalle prime pagine, rendendo molto semplice la comprensione di questi affascinanti dispositivi. Il testo tratta in maniera esaustiva il microcontrollore PIC16F84A e le sue applicazioni circuitali. Viene analizzata larchitettura interna con riferimento alle porte di I/O ed i relativi stadi di ingresso ed uscita, il timer TMR0 e la sua utilizzazione mediante il prescaler. Vengono illustrate le tecniche di gestione mediante interruzioni, il power-down mode e la gestione dei vari meccanismi di reset nonch luso del watchdog timer e la scrittura/lettura dati della EEPROM interna. Gli argomenti sono trattati attraverso semplici circuiti di esempio il cui codice viene analizzato riga per riga in modo da spiegarne la funzione fin nei minimi dettagli. Tra gli esempi applicativi vengono proposti la gestione di un display LCD, la gestione di una connessione RS232, la gestione di una tastiera ed un esempio di gestione della EEPROM interna mediante la realizzazione dello storico gioco elettronico SIMON. Per rendere il lettore autonomo nella realizzazione dei vari progetti, viene illustrato luso dellambiente MPLAB di Microchip che consente la creazione e modifica dei file sorgenti e la relativa compilazione mediante una interfaccia user friendly. A completamento della trattazione vengono analizzate tutte le istruzioni supportate da PIC16F84A incluse le macro-istruzioni e molte delle direttive dellassemblatore MPASM. A corredo del volume allegato un CDROM contenente tutta la documentazione tecnica relativa ai PICmicro, lambiente di sviluppo MPLAB, i file sorgenti e compilati relativi ai progetti trattati e le versioni dimostrative di vari pacchetti software utili alla realizzazione di progetti con i PICmicro. Le nozioni trattate nel presente volume possono essere facilmente applicate ad altri modelli di PICmicro rendendo il testo non solo un punto di partenza, ma anche un utile manuale da tenere sempre a portata di mano.
IX
Ringraziamenti
Sono doverosi i ringraziamenti a Sergio Tanzilli, amico di vecchia data, per la stesura del corso originale - PIC BY EXAMPLE - nel lontano 1997. Il corso ancora visibile allindirizzo www.tanzilli.com ed stato tradotto in diverse lingue. Possiamo sicuramente affermare che migliaia di utenti hanno iniziato la loro avventura con i PICmicro seguendo proprio questo corso. I nostri ringraziamenti vanno anche ad Antonio Cirella (Direttore Responsabile della rivista Fare Elettronica www.farelettronica.com) per averci convinto a portare avanti questo progetto e per il grande supporto morale e logistico che ci ha accompagnato durante tutto il lavoro di stesura del testo. Infine un ringraziamento a voi lettori che avete deciso di acquistare il libro, con la speranza e, senza peccare di presunzione certezza, che vi torner molto utile per comprendere questi microcontrollori ormai entrati, a pieno diritto, nella storia dellelettronica.
Vorrei dedicare questo mio lavoro alle persone che amo di pi. Mia moglie Angela, che ha avuto tanta pazienza nel sopportare le notti passate al computer, dandomi la tranquillit necessaria a poter completare il libro; il mio piccolo Julian, che con la sua allegria e curiosit ha tentato incessantemente di spegnere il mio computer dopo aver scoperto a cosa serviva quel misterioso pulsante nero; la dolcissima Gaia, che vedendomi lavorare da solo in ufficio, ha voluto tenermi compagnia ogni giorno, guardando incessantemente il DVD di Topo Gigio sullaltro computer. Tiziano Galizia
XI
1 - INTRODUZIONE AI PICMICRO
UN PO DI STORIA
Microchip Technology Incorporated stata fondata da un gruppo di investitori che vide il potenziale di mercato nella linea di semiconduttori della General Instruments che allora produceva diversi componenti elettronici. La General Intruments aveva a catalogo anche una interessante linea di microcontrollori programmabili, chiamata Peripheral Interface Controllers, in pratica PIC (ecco svelato il significato della sigla). Di fatto erano dei microcontrollori molto semplici, costruiti attorno ad unarchitettura RISC (Reduced Instructions Set Code), in grado di eseguire una istruzione per ciclo di clock alla frequenza massima di 20 Mhz (attualmente i PICmicro della famiglia 18 raggiungono la frequenza di 40 MHz). Questo faceva del PIC un microcontrollore a 8 bit relativamente veloce, ma la caratteristica ancora pi interessante era la possibilit di disporre di correnti, in uscita ad ogni pin, di circa 20 mA, quando i prodotti concorrenti difficilmente superavano la decina di milliAmpere. Per ragioni sconosciute, la General Instruments valut che non valesse la pena mantenere la divisione microcontrollori e quindi decise di venderla al gruppo di investitori, insieme alla fabbrica di Chandler in Arizona. Il gruppo dinvestitori fond quello che oggi noto come Microchip Technology e questi microcontrollori diventarono il loro prodotto di punta. Era il 1990. Inizialmente i modelli disponibili erano pochi, non tutti disponevano di alcune caratteristiche comuni come linterrupt e usavano un inconsueto sistema di paginazione della memoria (ancora oggi utilizzato su alcuni modelli). A dispetto di queste limitazioni, il mercato rispose in modo incoraggiante, consentendo a Microchip di sviluppare nuovi modelli con caratteristiche migliori, tra le quali: interrupt, A/D, comparatori, periferiche seriali e parallele ed altro ancora. Molto presto la Microchip introdusse la prima famiglia di microcontrollori con memoria OTP (One Time Programming) che, consentendo la programmazione diretta del chip, permettevano di evitare gli alti costi di mascheratura delle allora comuni memorie di tipo ROM (Read Only Memory). Questo ne aument in maniera considerevole la richiesta soprattutto da parte di piccole aziende. In seguito si aggiunsero le prime famiglie con memoria FLASH, la famiglia a 8 pin (PIC12) ideale per impieghi in prodotti a basso costo, e le famiglie ad alte prestazioni ed alto numero di pin (PIC17/18/dsPIC). La grande offerta di prodotti (alcune centinaia di modelli) e lenorme flessibilit 1 - Introduzione ai PICmicro 1
offerta dai microcontrollori PIC, decret il definitivo successo della Microchip, rendendo questa azienda il primo produttore mondiale di microcontrollori a 8 bit.
INTRODUZIONE AL PICMICRO
I PICmicro, che per semplicit da ora in poi chiameremo PIC, sono circuiti integrati appartenenti alla categoria dei microcontrollori, ovvero componenti che integrano, in un unico dispositivo, tutti i circuiti necessari a realizzare un completo sistema digitale programmabile.
Come si pu notare dalla figura 1.1, i PIC, in questo caso un PIC16F84A, si presentano esternamente come dei normali circuiti integrati TTL o CMOS, ma internamente dispongono di tutti dispositivi tipici di un sistema a microprocessore, ovvero: CPU (Central Processor Unit) La CPU il cervello del microcontrollore in quanto si occupa di interpretare le istruzioni di programma. La potenza di calcolo di una CPU si misura in milioni distruzioni per secondo (MIPS) e, nel caso dei PIC, si ottiene dividendo la frequenza di clock per quattro. Memoria programma (FLASH) Nella memoria programma sono memorizzate le istruzioni da eseguire: il programma. In particolare, nel PIC16F84A, utilizzato nella presente trattazione, questa memoria di tipo FLASH. Questo tipo di memoria pu essere scritta migliaia di volte, rendendola ideale per impieghi hobbistici, per lo sviluppo o per tutte quelle applicazioni che richiedono un aggiornamento frequente del codice. 2 1 - Introduzione ai PICmicro
Memoria RAM (Random Access Memory) La memoria RAM usata per memorizzare le variabili utilizzate dal programma. una memoria di tipo non permanente, quindi, togliendo la tensione di alimentazione al microcontrollore, i dati memorizzati andranno perduti. Memoria EEPROM (Random Access Memory) La memoria EEPROM usata per memorizzare le variabili utilizzate dal programma. una memoria di tipo permanente, quindi, togliendo la tensione di alimentazione al microcontrollore, i dati rimarranno memorizzati. Linee di I/O (Input/Output) Le linee dingresso e uscita. Si utilizzano per pilotare dispositivi esterni o ricevere segnali da sensori, pulsanti, ecc. Una delle particolarit che differenziano i PIC da altri dispositivi analoghi la corrente di uscita disponibile, pi che sufficiente a pilotare piccoli carichi come i LED. Dispositivi ausiliari Una serie di dispositivi ausiliari, quali: generatori di clock, bus, contatori, convertitori AD, porte seriali, eccetera. La presenza di tutti questi dispositivi, in uno spazio veramente contenuto, consente al progettista di avvalersi degli enormi vantaggi derivanti dall'uso di un sistema a microprocessore, anche in quei circuiti che fino a poco tempo fa erano destinati ad essere realizzati con circuiterie tradizionali.
1 - Introduzione ai PICmicro
Nota La potenza di calcolo di un PIC si ottiene dividendo per quattro la frequenza di clock. Ad esempio: 20 MHz / 4 = 5 MIPS. I PIC sono disponibili in un'ampia gamma di modelli per meglio adattarsi alle esigenze di progetto specifiche, differenziandosi per: numero di linee di I/O, quantit e tipo di memoria e per dotazione di dispositivi. Si parte dai modelli pi piccoli, identificati dalla sigla PIC12 e dotati di soli 8 pin, fino ad arrivare ai modelli pi grandi con sigla PIC18 dotati di 40 e pi pin. Una descrizione dettagliata delle tipologie di PICmicro disponibile presso il sito web della Microchip, raggiungibile allindirizzo www.microchip.com contenente una grande quantit di informazioni tecniche, software di supporto, esempi di applicazioni e aggiornamenti disponibili.
Nel CD allegato Nella cartella \Documentazione trovate il file Microchip_Line_Card.pdf che riporta le caratteristiche di tutti i modelli di PICmicro disponibili, i sistemi di sviluppo ed altri componenti prodotti dalla Microchip.
1 - Introduzione ai PICmicro
CPU e memoria
35 istruzioni single word (tutte le istruzioni sono eseguite in un solo ciclomacchina, tranne quelle di salto e confronto che richiedono due cicli) Velocit operativa massima: 20 MHz (5 MIPS) 1 KB di memoria programma (FLASH) 68 bytes di memoria dati (RAM) 64 bytes di memoria dati (EEPROM) Programmazione in-circuit (ICSP) SLEEP mode 4 differenti tipi di oscillatore selezionabili Basso consumo di corrente Alimentazione da 2.0 a 5.5 V (dipende dai modelli)
Periferiche
Timer0: 8-bit timer/counter con prescaler a 8-bit Watch-Dog timer (WDT) con oscillatore RC interno 13 pin di I/O capaci di erogare fino a 25mA di corrente
1 - Introduzione ai PICmicro
# Nome I/O Descrizione 16 15 OSC1 CLKI I I Ingresso per il quarzo delloscillatore Ingresso per un clock esterno In modalit RC su questo pin disponibile un segnale di 1/4 della frequenza di clock che denota un ciclo istruzione Ingresso Master Clear (Reset) - se portato a livello logico basso provoca il reset del dispositivo
4 MCLR 17 18 1 2 3 6 7 8 9 10 11 12 13 5 14 RA0 RA1 RA2 RA3 RA4 T0CKI RB0 INT RB1 RB2 RB3 RB4 RB5 RB6 RB7 VSS VDD
I/O Digital I/O I/O Digital I/O I/O Digital I/O I/O Digital I/O I/O Digital I/O - se configurata come uscita di tipo Open Drain I I Ingresso di clock per Timer0 Interrupt esterno I/O Digital I/O I/O Digital I/O I/O Digital I/O I/O Digital I/O I/O Digital I/O I/O Digital I/O I/O Digital I/O I/O Digital I/O Terminale di riferimento per le tensioni (GND) Terminale positivo di alimentazione Tabella 1.1: Descrizione dei pin del PIC16F84A
1 - Introduzione ai PICmicro
Struttura interna
Nella figura 1.4 riportato lo schema a blocchi della struttura interna del PIC16F84A. Le periferiche presenti sono le seguenti: 13 porte I/O per linterazione col mondo esterno 68 byte di memoria RAM 1024 locazioni di memoria FLASH per i programmi 64 byte di memoria non volatile (EEPROM) Timer TMR0 Watchdog timer Timer per la gestione del dispositivo al reset
Nel corso della trattazione verranno analizzate le funzioni di tutte le periferiche e la loro gestione mediante istruzioni assembler.
1 - Introduzione ai PICmicro
1 - Introduzione ai PICmicro
possibile selezionare uno dei due banchi utilizzando specifici bit del registro STATUS come verr spiegato pi avanti. Larea SFR consente di monitorare e controllare le periferiche ed occupa le 1 - Introduzione ai PICmicro 9
prime 12 locazioni di ciascun banco. Larea GPR costituita invece da 68 locazioni nel banco 0. Le corrispondenti locazioni del banco 1 sono equivalenti a quelle del banco 0 per cui indirizzare la cella 0x0C del banco 0 o la cella 0x8C del banco 1 perfettamente equivalente. Nota Il contenuto degli indirizzi di memoria non implementati (quindi gli indirizzi da 50H a 7FH del banco 0 e da D0H a FFH del banco 1) vengono letti come zero logico.
Nel CD allegato Nella cartella \Documentazione trovate il file PIC16F84A.pdf che il data-sheet del PIC a cui la trattazione fa riferimento.
10
1 - Introduzione ai PICmicro
LHARDWARE
Una scheda di prototipazione
Per eseguire gli esercizi proposti nel testo, necessario realizzare di volta in volta il circuito comprendente il PIC16F84A e gli altri componenti eventualmente necessari. Il lettore pu realizzare i circuiti impiegando una breadboard o una scheda millefori, tuttavia consigliamo luso di una scheda di prototipazione per PICmicro in modo da ridurre al minimo il tempo di realizzazione oltre ad evitare grossolani errori nel montaggio. Vista la grande flessibilit ed il costo decisamente contenuto, verr fatto riferimento alla scheda di prototipazione easyPIC2 prodotta da Mikroelektronika e acquistabile presso il distributore italiano www.elettroshop.com. Ovviamente una scelta diversa, da parte del lettore, non preclude la corretta preparazione ed esecuzione dei vari esperimenti.
11
La scheda easyPIC2 consente lo sviluppo di applicazioni impieganti PICmicro a 8, 14, 18, 28 e 40 pin. Tutti i jumper ed i componenti presenti sulla scheda sono contrassegnati con un identificatore per poter avere un eventuale riferimento diretto con lo schema elettrico. Con riferimento alla figura 2.1, ecco cosa mette a disposizione la scheda: 1. Alimentatore a 5V per i dispositivi presenti sulla scheda, accetta tensioni dingresso da 7V a 15V sia in corrente continua che alternata. 2. Questo jumper permette di selezionare la fonte di alimentazione tra una esterna o direttamente dal bus USB. In questultimo caso non necessario limpiego di un alimentatore esterno. 3. Programmatore USB caratterizzato da alta velocit e flessibilit. Pu essere infatti pilotato da un software che, se mantenuto aggiornato, consente la programmazione dei micro anche pi recenti. 4. Predisposizione per sensore di temperatura DS1820 che consente di misurare temperature con un accuratezza di 0,5C. 5. Sezione di comunicazione RS232: possibile selezionare su quali pin del micro indirizzare i segnali Rx e Tx. 6. I pin RA2 ed RA3 del micro sono collegati a due trimmer in modo da poter disporre di due ingressi analogici variabili da 0V a 5V. 7. La port A connessa ad una rete di resistori mediante il dip switch SW1. Se SW1 non nella posizione ON, alla port A non viene collegato nessun pull-up o pull-down. 8. La funzione di pull-up o pull-down per le varie porte pu essere selezionata mediante questi jumper. 9. Predisposizione per la connessione di un display LCD compatibile con il controller HD44780. 10. Area millefori per utilizzare specifici componenti. 11. Supporto per micro in package DIP8, DIP14, DIP18,DIP28 e DIP40, consentendo lo sviluppo di applicazioni per tutte le famiglie di PICmicro. 12. 32 pulsanti per pilotare gli ingressi del micro. 13. E possibile scegliere se la pressione di un pulsante provochi il livello alto o il livello basso del relativo ingresso. 14. LED connessi ad ogni pin del micro. Questo permette di monitorare i lo stato dei segnali digitali presenti sui pin. 15. Display led a 7 segmenti 4 cifre, pilotato in modalit multiplex in modo da utilizzare il minimo numero di I/O del micro. 16. E possibile selezionare a quali porte saranno connessi i LED. possibile anche selezionare quale delle quattro cifre dovr essere abilitata. Questi dip switch consentono di scollegare fisicamente i led dai pin del micro. 17. E possibile regolare il contrasto del display LCD eventualmente connesso alla scheda. 12 2 - Gli strumenti necessari
Un programmatore
Una volta messo a punto il programma per il micro, si rende necessaria una fase di programmazione in cui tale programma, correttamente compilato (firmware), viene scaricato allinterno del micro. Per questa fase necessario disporre di un programmatore di PIC, un circuito sul quale viene inserito il PIC da programmare e, una volta collegato al PC, consente mediante opportuno software, la programmazione del micro. Nel caso della easyPIC2 il programmatore si trova gi a bordo della scheda che viene collegata ad un PC tramite un cavo USB. Chi ha deciso di realizzare i montaggi su millefori o breadboard, avr necessit di un programmatore e una alternativa allacquisto lautocostruzione. In rete si trovano moltissimi siti che propongono schemi elettrici di programmatori per PIC, consigliamo sicuramente di partire visitando il sito www.ic-prog.com. In alternativa, una ricerca su Google (www.google.com) produrr molti risultati.
La tensione di alimentazione di 5 volt viene inviata al pin Vdd (pin 14) mentre il pin Vss (pin 5) viene collegato al negativo di alimentazione. buona norma collegare un condensatore ceramico da 100 nF tra il Vdd e il Vss, tenendo le piste di collegamento il pi corte possibile, in modo da filtrare eventuali disturbi. 2 - Gli strumenti necessari 13
IL SOFTWARE
MPLAB: editor e compilatore
Per lo sviluppo di applicazioni con PICmicro sono necessari un editor di testi ed il compilatore assembler. Mentre per il primo possibile usare anche il famoso Blocco Note (Notepad) di Windows, il compilatore assembler viene fornito gratuitamente da Microchip. In realt Microchip offre molto di pi di un semplice compilatore, possibile infatti scaricare dal sito www.microchip.com lultima versione di MPLAB. MPLAB un software gratuito che comprende un editor di testi ed un compilatore assembler disponibili in un unico ambiente. Leditor di testi di tipo intelligente ovvero una volta determinato il tipo di file da editare, il programma distingue le istruzioni programma dalle costanti, dalle variabili e dai commenti ed utilizza diversi colori rendendo molto pi leggibile il codice. Struttura ed uso di MPLAB Una applicazione sviluppata in MPLAB costituita da un Progetto allinterno del quale si trovano tutti i file sorgenti e di libreria utilizzati. La prima cosa da fare dunque iniziare un nuovo progetto cliccando sullicona come mostrato in figura 2.3 oppure scegliendo New dal menu Project.
Una volta creato il nuovo progetto dovr essere creato il primo file da inserire nel progetto e questo pu essere fatto scegliendo New dal menu File e salvare con estensione .asm il file cos creato. A questo punto, per inserire il file nel progetto basta cliccare con il tasto destro su Source Files nella finestra di riepilogo del progetto e scegliere Add File (come mostrato nella figura 2.4) quindi selezionare il file precedentemente salvato. La stesura del programma verr affrontata pi avanti. La compilazione dellapplicazione pu essere effettuata scegliendo Build All dal menu Project. A seguito della compilazione si aprir una finestra di output 14 2 - Gli strumenti necessari
in cui verranno elencati gli eventuali errori commessi ed attraverso la quale lutente sar informato circa lesito delloperazione di compilazione.
Nei capitoli successivi sar illustrato dettagliatamente luso di MPLAB analizzando le potenzialit di questo ambiente di programmazione.
Nel CD allegato Nella cartella \Software\MPLAB trovate i file di installazione per MPLAB 7.0 Per lultima versione rilasciata da Microchip consigliamo di visitare il sito www.microchip.com.
15
Come primo esempio di applicazione verr realizzato un circuito molto semplice il cui scopo quello di far lampeggiare un diodo LED, utilizzando il PIC16F84A. In particolare questa applicazione illustrer come scrivere un programma assembler, come compilarlo e come trasferirlo nella memoria flash del micro per essere eseguito.
LO SCHEMA ELETTRICO
Il pin MCLR (pin 4) comanda il reset del PICmicro. Normalmente mantenuto a 5 volt tramite la resistenza di pull-up R1 (10k) e deve essere portato a zero (massa) ogni qualvolta si intende resettare il dispositivo. Grazie alla circuiteria interna di reset di cui il PICmicro dotato, non necessario collegare, al pin MCLR, pulsanti o circuiti RC per ottenere il reset all'accensione. Pi avanti verr mostrato come sia possibile abilitare o disabilitare questa funzione direttamente nel codice sorgente.
17
I pin OSC1/CLKIN (pin 16) e OSC2/CLKOUT (pin 15) sono collegati internamente al circuito per la generazione della frequenza di clock, utilizzata per temporizzare tutti i cicli di funzionamento interni al chip. Da questa frequenza (in letteratura indicata con Fosc) dipende la quasi totalit delle operazioni interne ed, in particolare, la velocit con cui il PICmicro esegue le istruzioni del programma. Nel caso del PIC16F84A-20/P tale frequenza pu raggiungere un massimo di 20 Mhz, da cui si ottiene una velocit di esecuzione delle istruzioni pari a 5 milioni di istruzioni al secondo (Fosc/4). Nello schema di figura 3.1, per la generazione del clock, stato utilizzato un quarzo esterno da 4 MHz e due condensatori da 22 pF. Il pin RB0 (pin 6) una delle linee di I/O (Input/Output) disponibili che, in questo caso, stata collegata al LED tramite una resistenza di limitazione da 470 .
Nelle modalit XT, LP o HS, loscillazione viene generata connettendo ai pin OSC1/CLKIN e OSC2/CLKOUT un risonatore ceramico o a cristallo come indicato nella figura 3.2.
Il design delloscillatore del PIC16F84A richiede lutilizzo di un quarzo ad uscita parallela. Lutilizzo di un quarzo ad uscita seriale potrebbe generare una frequenza al di fuori delle specifiche del costruttore. In modalit XT, LP o HS il 18 3 - Un semplice lampeggiatore a led
dispositivo pu essere pilotato, sul pin OSC1/CLKIN, da una fonte esterna di clock (figura 3.3).
Figura 3.3: Sorgente di clock esterno (modalit HS, XT o LP). Valori testati Modalit XT HS Frequenza 455 kHz 2.0 MHz 4.0 MHz 8.0 MHz 10.0 MHz OSC1/C1 47 100 pF 5 - 33 pF 15 33 pF 15 - 33 pF 15 33 pF OSC2/C2 47 100 pF 5 - 33 pF 15 33 pF 5 - 33 pF 15 33 pF
Nota: Capacit alte migliorano la stabilit delloscillatore, ma aumentano il tempo di start-up. Questi valori sono solo di riferimento e, visto che ogni risonatore ha le proprie caratteristiche, consigliabile consultare il produttore del risonatore per gli appropriati valori dei componenti esterni.
Nota Quando si usa un risonatore con frequenze al di sopra di 3,5 MHz raccomandato lutilizzo della modalit HS invece della XT. La modalit HS pu essere usata a qualsiasi Vdd per la quale il microcontrollore certificato. Per applicazioni in cui la precisione e la stabilit della frequenza di clock non un parametro critico, possibile generare il segnale di cadenza utilizzando una rete RC esterna realizzando quindi un oscillatore RC. Questo comporta un notevole risparmio rispetto allinserimento di un quarzo a scapito della precisione della frequenza ottenuta. La frequenza delloscillatore RC dipende infatti dalla tensione di alimentazione, dai valori di R e C inseriti e dalla temperatura alla quale il dispositivo si trova ad operare. Oltre a questi parametri opportuno tenere in considerazione anche le tolleranze dei componenti esterni utilizzati. La figura 3.4 mostra la connessione di una rete RC ad un PIC per la generazione del clock.
19
Nelle figure seguenti sono riportati gli andamenti della frequenza ottenuta mediante una rete RC esterna al variare della tensione di alimentazione Vdd per diversi valori di REXT e CEXT.
20
21
22
Per scrivere un programma in linguaggio assembler occorre: Conoscere il set distruzioni disponibili sul microcontrollore che sintende utilizzare (in questo caso il PICmicro). Conoscere le regole sintattiche per definire variabili, parametri, ecc. Disporre di un editor di testo con cui digitare il programma. Il file di testo contenente il programma (sotto forma di sequenza di istruzioni mnemoniche) denominato sorgente o sorgente assembler. Il passo successivo consiste nel tradurre il sorgente assembler, nella giusta sequenza distruzioni in formato binario che il PICmicro in grado di capire. Il programma che esegue questa traduzione detto compilatore assembler o assemblatore. Nella figura 3.5 schematizzato il flusso di operazioni ed i file generati, necessari ad ottenere un PICmicro programmato.
Come gi detto precedentemente, la prima operazione da effettuare la scrittura del sorgente e la sua memorizzazione in un file di testo. L'estensione di questo file deve essere .ASM. Per la creazione del file ASM si consiglia luso delleditor di MPLAB, tuttavia possibile generare questo file anche con programmi di elaborazione testi come Notepad o qualunque altro software in 3 - Un semplice lampeggiatore a led 23
grado di salvare i file in formato TXT. Il file sorgente utilizzato in questa prima applicazione il file LED.ASM. Il passo successivo la compilazione del sorgente, ovvero la trasformazione in opcode dei codici mnemonici o istruzioni assembler in esso contenute. Il compilatore assembler MPASM prodotto dalla Microchip ed integrato nellambiente MPLAB. Il compilatore viene richiamato automaticamente quando in MPLAB viene dato il comando Build All per la compilazione. Nota Editando il file sorgente con un word processor avanzato, necessario effettuarne il salvataggio come solo testo per rimuovere tutti i caratteri speciali di controllo della formattazione che il compilatore non in grado di trattare. Com possibile vedere nella figura 3.5, oltre al file sorgente con estensione .ASM necessario fornire al compilatore un secondo file prodotto dalla Microchip con estensione .INC, differente a seconda del tipo di PICmicro utilizzato. In questo caso il file il P16F84A.INC. Questo sorgente contiene alcune definizioni dipendenti dal chip utilizzato che verranno analizzate pi avanti. Durante la fase di compilazione, l'assemblatore genera una serie di files con il nome identico al sorgente da cui derivano, ma con una estensione diversa. In particolare si ottengono files con le seguenti estensioni: .HEX il file contenente gli opcode da inserire nella memoria programma del PICmicro. .LST un file di testo in cui viene riportato l'intero sorgente assembler e la corrispondente traduzione in opcode. Non utilizzabile per la programmazione del PICmicro, ma estremamente utile per verificare i processi di compilazione che ha eseguito l'assemblatore. .ERR contiene la lista degli errori di compilazione riscontrati ed il numero di linea all'interno del sorgente assembler (.ASM) in cui sono stati rilevati. I files .LST e .ERR vengono utilizzati per il controllo di quanto effettuato in fase di compilazione. Solo il file .HEX viene utilizzato realmente per programmare il PICmicro. Il file .HEX non un file in formato binario, bens un file codificato in un formato stabilito da Intel per la descrizione dei file binari in formato ASCII. Senza entrare troppo nei dettagli utile sapere che tale formato direttamente riconoscibile da qualsiasi programmatore di PICmicro il quale provveder a leggere da questo formato gli opcode ed a trasferirli nella memoria del PICmicro. 24 3 - Un semplice lampeggiatore a led
PORTB,LED MainLoop
; Subroutines
25
Delay clrf clrf DelayLoop decfsz goto decfsz goto return END
Nel CD allegato Nella cartella \sorgenti trovate il file LED.ASM utilizzato per lesempio.
PROCESSOR una direttiva del compilatore assembler che consente di definire per quale microprocessore stato scritto il file sorgente. Le direttive non sono delle istruzioni mnemoniche che il compilatore traduce nel rispettivo opcode, ma sono indicazioni rivolte al compilatore per discriminarne il funzionamento durante la compilazione. In questo caso il compilatore viene informato che le istruzioni inserite nel file sorgente sono relative ad un PIC16F84A. RADIX DEC
Con la direttiva RADIX il compilatore viene informato che i numeri riportati senza notazione, sono da intendersi espressi nella notazione specificata dalla direttiva RADIX (DEC sta per decimale). Avendo specificato RADIX DEC, per scrivere ad esempio il numero esadecimale 10 (16 decimale) dovr essere esplicitamente espressa la notazione: 0x10 oppure H10. Scrivendo solamente 10 il compilatore lo interpreter come 10 decimale. ERRORLEVEL -302
La direttiva ERRORLEVEL consente di escludere la segnalazione di alcuni errori di compilazione. Nel caso dellesempio viene utilizzata per evitare che il compilatore visualizzi la segnalazione 302 (la segnalazione 302 ricorda di commutare il banco di memoria qualora si utilizzino registri che non stanno nel banco 0).
26
INCLUDE
"P16F84A.INC"
Ancora un'altra direttiva per informare il compilatore di includere nel sorgente un secondo file denominato P16F84A.INC. Il compilatore si limiter a sostituire la linea contenente la direttiva INCLUDE con il contenuto del file indicato ed effettuare la compilazione come se fosse anch'esso parte del file sorgente. __CONFIG _XT_OSC & _CP_OFF & _WDT_OFF
La direttiva __CONFIG imposta i flag di configurazione che verranno utilizzati dal programmatore in fase di programmazione del micro. Questa direttiva verr esaminata in dettaglio pi avanti in questo capitolo. LED EQU 0
La direttiva EQU molto importante in quanto consente di definire delle costanti simboliche all'interno del file sorgente. In particolare la parola LED da questo punto in poi del sorgente sar equivalente al valore 0. Lo scopo principale dell'esistenza della direttiva EQU quindi rendere i sorgenti pi leggibili e consentire di cambiare i valori costanti in un unico punto del sorgente. importante notare che la parola LED non identifica una variabile, ma semplicemente un nome simbolico valido durante la compilazione. Non sar quindi possibile inserire istruzioni tipo LED = 3 all'interno del sorgente in quanto l'assegnazione dinamica di un valore ad una variabile un'operazione che richiede l'intervento della CPU del PICmicro e che quindi deve essere espressa con istruzioni e non con direttive. Nota Le direttive hanno senso solo durante la compilazione del sorgente, quindi un PIC non potr mai eseguire una direttiva. Proseguendo nellanalisi del sorgente si trova la linea: ORG 0x0C
Anche ORG una direttiva e consente di definire l'indirizzo a partire dal quale il compilatore inizia ad allocare i dati o le istruzioni seguenti. In questo caso viene definita un'area dati all'interno del PICmicro ovvero un'area in cui memorizzare variabili e contatori durante l'esecuzione del programma. Quest'area coincide con l'area RAM del PICmicro definita dalla Microchip come area dei FILE REGISTER (si vedano anche le figure 1.5 ed 1.6). I file register altro non sono che locazioni RAM disponibili per l'utente a partire dall'indirizzo 0x0C. Questo indirizzo di inizio fisso e non pu essere cambiato in quanto le locazioni precedenti sono occupate da altri registri specializzati per uso interno. 3 - Un semplice lampeggiatore a led 27
count
RES 2
In questa linea sono presenti una label: Count e una direttiva: RES. La direttiva RES indica al compilatore di riservare un certo numero di byte o meglio di file register all'interno dell'area dati (in questo caso 2 bytes). La label Count (dove Count un nome scelto dallutente) un marcatore che nel resto del sorgente assumer il valore dell'indirizzo in cui stato inserito. Dato che precedentemente era stato definito l'indirizzo di partenza a 0x0C con la direttiva ORG, Count varr 0x0C. Se ad esempio viene inserita una label anche alla linea successiva essa varr 0x0C + 2 (due sono i byte che sono stati riservati) ovvero 0x0E. I nomi delle label possono essere qualsiasi ad eccezione delle parole riservate al compilatore quali le istruzioni mnemoniche e le direttive). Una label si distingue da una costante simbolica in quanto il suo valore viene calcolato in fase di compilazione e non assegnato staticamente dallutente. ORG 0x00
Questa seconda direttiva ORG fa riferimento ad un indirizzo in area programma (nella FLASH) anzich in area dati. Da questo punto in poi andranno infatti inserite le istruzioni mnemoniche che il compilatore dovr convertire negli opportuni opcode per il PICmicro. Il primo opcode eseguito dal PICmicro dopo il reset quello memorizzato nella locazione 0, da qui il valore 0x00 inserito nella ORG. bsf STATUS,RP0
Ecco la prima istruzione mnemonica completa di parametri. I PICmicro hanno una CPU interna di tipo RISC per cui ogni istruzione occupa una sola locazione di memoria, opcode e parametri inclusi. In questo caso l'istruzione mnemonica bsf sta per BIT SET FILE REGISTER ovvero metti a uno (condizione logica alta) uno dei bit contenuti nella locazione di ram specificata. Il parametro STATUS viene definito nel file P16F84A.INC tramite una direttiva EQU. Il valore assegnato in questo file 0x03 e corrisponde ad un file register (ovvero una locazione ram nell'area dati) riservato (si veda la figura 1.6). Anche il parametro RP0 viene definito nel file P16F84A.INC con valore 0x05H e corrisponde al numero del bit che si vuole mettere a uno. Ogni file register lungo 8 bit e la numerazione di ciascuno inizia da 0 (bit meno significativo) fino ad arrivare a 7 (bit pi significativo) Questa istruzione in pratica mette a 1 il quinto bit del file register STATUS ed necessaria per accedere ai file register del banco 1. movlw B'00011111'
Questa istruzione sta a significare: MOVE LITERAL TO W REGISTER ovvero muovi un valore costante nell'accumulatore W. L'accumulatore un particolare registro utilizzato dalla CPU in tutte quelle situazioni in cui vengono effettuate 28 3 - Un semplice lampeggiatore a led
operazioni tra due valori oppure in operazioni di spostamento tra locazioni di memoria. In pratica un registro di appoggio utilizzato dalla CPU per memorizzare temporaneamente un byte ogni volta che se ne presenta la necessit. Il valore costante da memorizzare nell'accumulatore 00011111 ovvero un valore binario a 8 bit dove, il bit pi a destra, rappresenta il bit 0 o bit meno significativo (si noti come sia stata specificata la notazione binaria utilizzando la lettera B). Nell'istruzione successiva: movwf TRISA
il valore 00011111 che si trova in W viene trasferito nel registro TRISA (come per il registro STATUS anche TRISA definito tramite una direttiva EQU) la cui funzione quella di definire il funzionamento di ogni linea di I/O della porta A. In particolare ogni bit ad uno del registro TRISA determina un ingresso sulla rispettiva linea della porta A mentre ogni 0 determina un'uscita. Nella tabella 3.2 viene riportata la configurazione che assumeranno i pin del PICmicro dopo l'esecuzione di questa istruzione:
Bit registro TRISA Linea porta A Pin Valore 0 1 2 3 4 5 6 7 RA0 RA1 RA2 RA3 RA4 17 18 1 2 3 1 1 1 1 1 0 0 0 Stato Ingresso Ingresso Ingresso Ingresso Ingresso -
Si noti che i bit 5, 6 e 7 non corrispondono a nessuna linea di I/O e quindi il loro valore non significativo. Le due istruzioni successive svolgono le funzioni appena viste, ma operando sulla porta B del PICmicro: movlw movwf B'11111110' TRISB
in questo caso la definizione delle linee sar quella riportata nella tabella 3.3.
29
Bit registro TRISB Linea porta B Pin Valore 0 1 2 3 4 5 6 7 RB0 RB1 RB2 RB3 RB4 RB5 RB6 RB7 6 7 8 9 10 11 12 13 0 1 1 1 1 1 1 1
Notate come il valore 0 nel bit 0 del registro TRISB determini la configurazione in uscita della rispettiva linea del PICmicro. Nella applicazione di esempio infatti questa linea viene utilizzata per pilotare il LED. stato visto come l'istruzione movwf trasferisca il valore contenuto nell'accumulatore W (inizializzato opportunamente con l'istruzione movlw B'11111110') nel registro specificato (ad esempio TRISB). Il significato di movwf infatti MOVE W TO FILE REGISTER. bcf STATUS,RP0
Questa istruzione simile alla bsf vista in precedenza, con la sola differenza che azzera il bit anzich portarlo ad uno. La sigla in questo caso lacronimo di BIT CLEAR FILE REGISTER. Dal punto di vista funzionale questa istruzione stata inserita per consentire l'accesso ai registri interni del banco 0 anzich ai registri interni del banco 1 a cui appartengono TRISA e TRISB. Una descrizione pi dettagliata verr data pi avanti nel testo. bsf PORTB,LED
Con questa istruzione viene effettuata la prima operazione che ha qualche riscontro all'esterno del PICmicro. In particolare viene acceso il LED collegato alla linea RB0. PORTB una costante definita in P16F84A.INC e consente di referenziare il file register corrispondente alle linee di I/O della porta B mentre LED il numero della linea da mettere a 1. All'inizio del sorgente la costante LED era stata definita pari a 0, quindi la linea interessata sar RB0. MainLoop Questa linea contiene una label ovvero un riferimento simbolico ad un indirizzo di memoria. Il valore della label, come detto in precedenza, viene calcolato in fase di compilazione in base al numero di istruzioni, alle direttive ORG e alle altre istruzioni che in qualche modo allocano spazio nella memoria del 30 3 - Un semplice lampeggiatore a led
PICmicro. In questo caso, contando le istruzioni inserite a partire dall'ultima direttiva ORG si ricava il valore che verr assegnato a MainLoop ovvero 0x07. In realt il valore che assumono le label non ha molta importanza in quanto il loro scopo proprio quello di evitare di dover conoscere la posizione precisa degli opcode nella memoria del PICmicro permettendo comunque di referenziare una determinata locazione di memoria. In questo caso la label MainLoop viene utilizzata come punto di ingresso di un ciclo (dall'inglese Loop) di accensione e spegnimento del led, ovvero una parte di codice che verr ripetuta ciclicamente all'infinito. Call Delay
Questa istruzione determina una chiamata (dall'inglese call) ad una subroutine che inizia in corrispondenza della label Delay. Le subroutine sono delle parti di programma specializzate per effettuare una funzione specifica. Ogni qualvolta necessaria quella funzione sufficiente richiamarla con una sola istruzione, anzich ripetere ogni volta tutte le istruzioni necessarie ad effettuarla. In questo caso la subroutine inserisce un ritardo pari al tempo di accensione e spegnimento del led. Le istruzioni che compongono la subroutine Delay sono inserite pi avanti in questo stesso sorgente. btfsc PORTB,LED
Il significato di questa istruzione BIT TEST FLAG, SKIP IF CLEAR ovvero controlla lo stato di un bit all'interno di un registro e salta l'istruzione successiva se il valore di tale bit zero. Il bit da controllare corrisponde alla linea di uscita cui collegato il diodo led e, tramite questo test possibile determinare se il led acceso o spento dunque agire di conseguenza: se il led gi acceso verr spento (saltando alla label SetToZero grazie allistruzione goto), se il led spento verr acceso saltando (skip) listruzione goto. goto SetToZero
Questa istruzione il salto incondizionato (dall'inglese GO TO, vai a) alla label SetToZero dove si troveranno le istruzioni per spegnere il led. Questa istruzione verr saltata se il led gi spento. bsf goto PORTB,LED MainLoop
Queste due istruzioni rispettivamente accendono il led e rimandano il programma all'inizio del ciclo di lampeggiamento. SetToZero bcf PORTB,LED goto MainLoop 3 - Un semplice lampeggiatore a led 31
Queste due istruzioni rispettivamente spengono il led e rimandano il programma all'inizio del ciclo di lampeggiamento.
La subroutine Delay
Come descritto in precedenza questa subroutine inserisce un ritardo di circa un secondo e pu essere chiamata pi volte nel sorgente tramite l'istruzione call Delay. Ecco come funziona: Delay clrf clrf DelayLoop decfsz goto decfsz goto retlw Count Count+1 Count,1 DelayLoop Count+1,1 DelayLoop 0
Delay e DelayLoop sono due label. Delay identifica l'indirizzo di inizio della subroutine e viene utilizzato per le chiamate dal corpo principale del programma. DelayLoop viene chiamato internamente dalla subrountine e serve come punto di ingresso per il ciclo (dall'inglese loop) di ritardo. In pratica il ritardo viene ottenuto eseguendo migliaia di istruzioni che decrementano un contatore interno e non hanno quindi effetti visibili allesterno. Questo tipo di ritardo si chiama ritardo software o ritardo a programma. il tipo di ritardo pi semplice da implementare e pu essere utilizzato quando non richiesto che il PICmicro esegua altri compiti mentre esegue il ritardo. Le istruzioni: clrf clrf Count Count+1
CLEAR FILE REGISTER azzerano le due locazioni di ram riservate precedentemente con l'istruzione: Count RES 2
Queste due locazioni sono adiacenti a partire dall'indirizzo referenziato dalla label Count. decfsz Count,1
L'istruzione significa DECREMENT FILE REGISTER, SKIP IF ZERO ovvero decrementa il contenuto di un registro (in questo caso Count e salta l'istruzione successiva se il valore raggiunto zero). Se il valore raggiunto non zero viene 32 3 - Un semplice lampeggiatore a led
che rimanda l'esecuzione all'inizio del ciclo di ritardo. Una volta raggiunto lo zero con il contatore Count vengono eseguite le istruzioni: decfsz goto Count+1,1 DelayLoop
che decrementano il registro seguente fino a che anche questo raggiunge lo zero. Il registro Count+1 in particolare verr decrementato di uno ogni 256 decrementi di Count. Quando anche Count+1 avr raggiunto lo zero l'istruzione: return il cui significato RETURN FROM SUBROUTINE, determiner l'uscita dalla routine di ritardo ed il proseguimento dell'esecuzione dall'istruzione successiva alla call Delay. Per finire, END una direttiva che indica al compilatore la fine del sorgente assembler.
33
Facendo un doppio click su led.asm verr aperto il file per la visualizzazione e le eventuali modifiche. Si noti come nelleditor vengano utilizzati diversi colori: blu per le parole riservate (direttive, istruzioni), verde scuro per i commenti, 34 3 - Un semplice lampeggiatore a led
viola per le label, blu per i numeri binari. possibile visualizzare ed eventualmente cambiare le impostazioni dei colori mediante il menu Edit, quindi Properties e scegliendo Text: qui oltre al tipo di carattere possibile scegliere i vari colori (Choose Colors) o riportare le impostazioni a quelle predefinite (Default Colors). Prima di compilare il progetto necessario specificare in MPLAB il tipo di PIC utilizzato. Questo pu essere fatto dal menu Configure quindi scegliendo Select Device ed infine selezionando il PIC16F84A nella lista dei PIC disponibili. La compilazione del progetto si avvia dal menu Project scegliendo Build All o con la combinazione si tasti CTRL+F10. A seguito della compilazione viene automaticamente aperta in MPLAB una finestra di output in cui riportato lesito delloperazione. Qualora vengano rilevati errori, questi saranno riportati nella finestra di output completi del numero di riga (relativo al file sorgente) alla quale sono stati rilevati. Un doppio click sulla linea relativa ad un errore porta direttamente allinterno del codice alla linea specifica. Nella directory C:\PIC vi sono ora nuovi file oltre a led.asm: LED.MCP, LED.MCW: files relativi al progetto creato in MPLAB (hanno il nome del progetto); LED.HEX: contiene il codice oggetto da utilizzare per programmare il PICmicro; LED.ERR, LED.LST: file contenenti rispettivamente gli eventuali errori ed il codice assembler come gi spiegato in precedenza. Ora tutto pronto per scaricare nel PIC16F84A il programma appena compilato. Per la programmazione del PICmicro occorre fare riferimento alla documentazione tecnica in dotazione al programmatore utilizzato.
Nel programma di esempio stata inserita la direttiva __CONFIG _XT_OSC & _CP_OFF & _WDT_OFF
Il primo parametro _XT_OSC imposta loscillatore in modalit XT, il secondo, _CP_OFF, disabilita la protezione del codice mentre lultimo, _WDT_OFF disabilita il watchdog timer. Queste impostazioni nel PIC16F84A vengono scritte nella locazione di memoria di indirizzo 0x2007. Tutti i software a corredo di programmatori per PIC consentono di visualizzare ed impostare questi flag. Anche mediante MPLAB possibile agire sulla configuration word attraverso il menu Configure quindi scegliendo Configuration bits. Nella nuova finestra che si apre (figura 3.7) vengono riportati i valori dei bit di configurazione in accordo ala direttiva __CONFIG, se specificata nel sorgente, o nella loro impostazione predefinita. Cliccando poi su ciascuna riga possibile variare limpostazione di ciascun parametro.
36
In questo capitolo verr analizzata la struttura interna di un PICmicro, quali dispositivi contiene e come interagiscono tra loro. Nella figura 4.1 riportato lo schema a blocchi semplificato dell'architettura interna del PIC16F84A. Le parti evidenziate sono le componenti che di volta in volta saranno analizzate, in questo caso la Program Memory ed il Register File.
37
LA PROGRAM MEMORY
La PROGRAM MEMORY una memoria speciale di tipo FLASH ed utilizzata nel PICmicro per memorizzare il programma da eseguire. La sua capacit di memorizzazione di 1024 locazioni ognuna in grado di contenere un opcode a 14 bit ovvero una istruzione base del PICmicro. Il programma pi complesso che potr contenere, non potr essere quindi pi lungo di 1024 istruzioni. Gli indirizzi riservati alla PROGRAM MEMORY vanno da 0x000 a 0x3FF (0x3FF esadecimale = 1023 decimale). Il PICmicro pu solamente eseguire le istruzioni memorizzate in queste locazioni e non pu in alcun modo leggere, scrivere o cancellare quanto in esse contenuto. Questo vale in particolar modo per i PIC16F84A mentre su altri modelli quali i PIC16F87x possibile anche aggiornare la memoria programma mentre il programma in esecuzione. Per scrivere, leggere e cancellare queste locazioni necessario un dispositivo esterno denominato programmatore (si veda il capitolo 2). La prima locazione di memoria, all'indirizzo zero, deve contenere la prima istruzione che il PICmicro dovr eseguire al reset e per questo viene nominata Reset Vector. Nel sorgente LED.ASM presentato nel capitolo precedente era stata inserita la direttiva: ORG 0x00
per segnare l'inizio del programma. Questa direttiva tiene conto del fatto che l'esecuzione del programma al reset parte dall'indirizzo 0x00 dell'area programma. L'istruzione che segue immediatamente la direttiva ORG 0x00: bsf STATUS,RP0
IL REGISTER FILE
Il REGISTER FILE un insieme di locazioni di memoria RAM ovvero memorie con cui possibile leggere e modificare il contenuto senza l'ausilio di programmatori esterni e direttamente dal programma in esecuzione sul PICmicro. Date le sue caratteristiche il REGISTER FILE la memoria normalmente utilizzata per memorizzare le variabili di programma, ovvero tutti quei valori il cui contenuto varia durante l'esecuzione. Contrariamente alla PROGRAM MEMORY, il REGISTER FILE perde il suo contenuto quando il PICmicro viene spento per cui necessario reinizializzare i 38 4 - Architettura interna del PIC16F84A
valori di tutte le sue locazioni prima di poterla usare. In figura 4.2 mostrata la struttura del register file per il PIC16F84A. Nota Mentre le PROGRAM MEMORY una memoria non volatile, il REGISTER FILE deve essere sempre correttamente inizializzato prima di eseguire il programma.
39
Le locazioni di memoria presenti nel REGISTER FILE sono indirizzabili direttamente in uno spazio di memoria che va da 0x00 a 0x4F per un totale di 80 byte, denominato pagina 0 (o bank 0). Un secondo spazio di indirizzamento denominato pagina 1 va da 0x80 a 0xCF. Per accedere a questo secondo spazio necessario ricorrere ai due bit ausiliari RP0 e RP1 secondo le modalit che verranno illustrate pi avanti. Le prime 12 locazioni della pagina 0 (da 0x00 a 0x0B) e della pagina 1 (da 0x80 a 0x8B) sono quelle riservate alle funzioni speciali per il funzionamento del PICmicro e non possono essere utilizzate per altri scopi. Le 68 locazioni in pagina 0 indirizzate da 0x0C a 0x4F possono essere utilizzate liberamente dai programmi per memorizzare variabili, contatori, ecc. Nellesempio LED.ASM la direttiva: ORG 0x0C
indica proprio l'indirizzo di inizio dell'area dati utilizzabile dal programma. La direttiva che segue: Count RES 2
riserva uno spazio di due locazioni, che il programma utilizzer per memorizzare i contatori di ritardo della subroutine Delay. I registri specializzati del PIC vengono utilizzati frequentemente nei programmi. Ad esempio, si ricorre alla coppia di registri specializzati TRISA (0x85) e TRISB (0x86), per definire quali linee di I/O sono in ingresso e quali in uscita. Lo stesso stato logico delle linee di I/O dipende dal valore dei due registri PORTA (0x05) e PORTB (0x06). Alcuni registri riportano lo stato di funzionamento dei dispositivi interni al PICmicro o il risultato di operazioni aritmetiche e logiche. necessario conoscere esattamente quale funzione svolge ciascun registro specializzato e quali effetti si ottengono nel manipolarne il contenuto. Per facilitare le operazioni sui registri specializzati, nel file P16F84A.INC (incluso nel sorgente LED.ASM con la direttiva INCLUDE) Microchip ha inserito una lista di nomi che identificano univocamente ciascun registro specializzato e a cui sono associati gli indirizzi corrispondenti nell'area dei REGISTER FILE. Per configurare, ad esempio, tutte le linee della porta B del PIC come uscite agendo sul registro TRISB, possibile referenziare direttamente il registro con il suo indirizzo: movlw movwf B'00000000' 0x86
oppure, referenziare lo stesso registro con il suo nome simbolico: movlw movwf 40 B'00000000' TRISB 4 - Architettura interna del PIC16F84A
avendo per l'accortezza di inserire la direttiva INCLUDE "P16F84A.INC" nel file sorgente.
LA ALU
La ALU (acronimo di Arithmetic and Logic Unit ovvero unit aritmetica e logica) la componente pi complessa del PICmicro in quanto contiene tutta la circuiteria delegata a svolgere le funzioni di calcolo e manipolazione dei dati durante l'esecuzione di un programma. La ALU una componente presente in tutti i microprocessori e da essa dipende direttamente la potenza di calcolo del micro stesso. La ALU del PIC16F84A in grado di operare su valori ad 8 bit, ovvero valori numerici non pi grandi di 255. Esistono microprocessori con ALU a 16, 32, 64 bit e oltre. La famiglia Intel 80386, 486 e Pentium ad esempio dispone di una ALU a 32 bit. Le potenze di calcolo raggiunte da questi micro sono notevolmente superiori a scapito della complessit della circuiteria interna ed accessoria e conseguentemente dello spazio occupato.
41
L'ACCUMULATORE O REGISTRO W
Direttamente connesso con la ALU c' il registro W denominato anche accumulatore. Questo registro consiste di una semplice locazione di memoria in grado di contenere un solo valore a 8 bit. La differenza sostanziale tra il registro W e le altre locazioni di memoria consiste proprio nel fatto che, per referenziare il registro W, la ALU non deve fornire nessun indirizzo di memoria, ma pu accedervi direttamente. Il registro W viene utilizzato molto spesso nei programmi per PICmicro. Come esempio pratico si supponga di voler inserire nella locazione di memoria 0x0C del REGISTER FILE il valore 0x01. Nel set di istruzioni del PICmicro non esiste un'unica istruzione in grado di effettuare questa operazione quindi si rende necessario ricorrere all'accumulatore ed usare due istruzioni in sequenza. Come gi visto, infatti, l'opcode di una istruzione non pu essere pi grande di 14 bit mentre per loperazione che si intende eseguire ne occorrono: 8 bit per specificare il valore da inserire nella locazione di memoria, 7 bit per specificare in quale locazione di memoria tale valore dovr essere inserito, 6 bit per specificare listruzione da utilizzare. Il totale di 8 + 7 + 6 = 21 bit. necessario dunque ricorrere a due istruzioni, ovvero: movlw movwf 0x01 0x0C
La prima inserisce nel registro W il valore 0x01 con l'istruzione MOVe Literal to W, la seconda sposta il valore contenuto in W nella locazione 0x0C con l'istruzione MOVe W to F. Nota Il registro accumulatore W lunico registro a cui la ALU pu accedere direttamente.
42
Una di queste istruzioni GOTO (dall'inglese GO TO, vai a) che permette di cambiare la sequenza di esecuzione e di "saltare" direttamente ad un qualsiasi punto, all'interno della memoria programma, quindi continuare l'esecuzione a partire da quel punto. Un esempio: ORG Point1 movlw goto 0x00
D10 Point1 43
Al reset il PICmicro eseguir l'istruzione MOVLW 10 memorizzata alla locazione 0x00, la quale inserir nell'accumulatore il valore decimale 10, quindi passer ad eseguire l'istruzione successiva GOTO Point1. Questa istruzione determiner un salto incondizionato alla locazione di memoria puntata dalla label Point1 ovvero di nuovo alla locazione 0x00. Nel suo insieme quindi, questo programma non far altro che eseguire continuamente le due istruzioni elencate. Durante questo ciclo (o loop), per determinare quale sar l'istruzione successiva da eseguire, il PIC utilizza uno speciale registro denominato PROGRAM COUNTER (dall'inglese contatore di programma) la cui funzione proprio quella di mantenere traccia dell'indirizzo che contiene la prossima istruzione da eseguire. Questo registro viene incrementato automaticamente ad ogni istruzione eseguita per determinare il passaggio all'istruzione successiva. Al momento del RESET del PIC il PROGRAM COUNTER viene azzerato, determinando cos l'inizio dell'esecuzione a partire dall'indirizzo 0x00. L'istruzione GOTO consente l'inserimento a programma di un nuovo valore nel PROGRAM COUNTER ed il conseguente salto ad una locazione qualsiasi dell'area programma del PIC.
LO STACK POINTER
Un'altra istruzione molto utile, che influenza il valore del PROGRAM COUNTER la CALL (dall'inglese chiamata) con la quale possibile effettuare delle CHIAMATE A SUBROUTINE. Questa istruzione funziona in maniera molto simile alla GOTO. Come la GOTO infatti permette di scrivere nel PROGRAM COUNTER un nuovo indirizzo di esecuzione del programma. La differenza sostanziale consiste per nel fatto che prima di eseguire il salto, il PIC memorizza, in un altro registro speciale, denominato STACK, l'indirizzo di quella che sarebbe dovuta essere la successiva istruzione da eseguire se non si fosse incontrata la CALL. Ad esempio: ORG Point1 movlw call goto Point2 movlw return 44 0x00
D11
In questo caso il PICmicro, dopo aver eseguito la MOVLW D10 passa ad eseguire listruzione CALL Point2. Prima di saltare per, memorizza nello STACK l'indirizzo 0x02, ovvero l'indirizzo della locazione successiva alla CALL. L'esecuzione passa quindi all'istruzione MOVLW D11 quindi alla istruzione RETURN (dall'inglese ritorno). Questa istruzione, come dice il suo nome, consente di "ritornare", ovvero di riprendere l'esecuzione a partire dall'istruzione successiva alla CALL che aveva determinato l'abbandono del flusso principale del programma utilizzando il valore memorizzato nel registro di STACK. Come detto l'operazione appena effettuata viene denominata CHIAMATA A SUBROUTINE, ovvero una interruzione momentanea del normale flusso di programma per "chiamare" in esecuzione una serie di istruzioni per poi ritornare al normale flusso di esecuzione. La parola STACK in inglese significa "catasta" ed infatti su questa catasta possibile depositare, uno sull'altro, pi indirizzi per recuperarli quando servono. Questo tipo di memorizzazione viene anche denominata LIFO dall'inglese Last In First Out, in cui l'ultimo elemento inserito (last in) deve necessariamente essere il primo ad uscire (last out). Grazie a questa caratteristica possibile effettuare pi CALL annidate una nell'altra e mantenere sempre traccia del punto in cui riprendere il flusso al momento che si incontra una istruzione RETURN. Ecco un altro esempio: ORG Point1 movlw call goto Point2 movlw call return Point3 movlw return 0x00
D11 Point3
D12
In questo caso nella subroutine Point2 viene effettuata un'ulteriore CALL alla subroutine Point3. Al ritorno da quest'ultima il programma dovr rientrare nella subroutine Point2 eseguire la RETURN e quindi tornare nel flusso principale. Gli indirizzi da memorizzare nello stack sono due in quanto viene incontrata una seconda CALL prima ancora di incontrare la RETURN corrispondente alla prima. 4 - Architettura interna del PIC16F84A 45
Il PIC16F84A dispone di uno stack a 8 livelli, ovvero uno stack che consente fino ad 8 chiamate annidate. importante assicurasi, durante la stesura di un programma, che ci sia sempre una istruzione RETURN per ogni CALL per evitare pericolosi disallineamenti dello stack che in esecuzione possono provocare errori difficilmente rilevabili. Nota buona norma, allinizio di una subroutine, salvare il contenuto dei registri che verranno utilizzati in modo da poterli ripristinare prima di ritornare al programma principale.
46
Come esercitazione relativa ai concetti finora esposti, verr rielaborato il sorgente LED.ASM presentato nel capitolo 3 per realizzare un lampeggiatore sequenziale a quattro led. Il nuovo sorgente modificato si chiamer SEQ.ASM. Nella figura 5.1 viene riportato lo schema elettrico del nuovo circuito, sostanzialmente equivalente al circuito presentato nel capitolo 3, con l'unica variante che ora i led collegati sono quattro anzich uno.
47
Le linee di I/O utilizzate sono RB0 per il primo led, RB1 per il secondo, RB2 per il terzo ed RB3 per il quarto. Esse vanno quindi configurate come uscite all'inizio del programma con le istruzioni: movlw movwf B'11110000' TRISB
in cui i quattro bit meno significativi, corrispondenti alle linee RB0RB3 vengono messi a zero per definire tali linee in uscita. Nell'area di memoria del REGISTER FILE (che nel sorgente inizia con la direttiva ORG 0x0C) oltre ai due byte referenziati dalla label Count, viene riservato un ulteriore byte con label Shift che verr utilizzato per determinare la sequenza di accensione dei led. La direttiva da inserire : Shift RES 1
Prima di eseguire il ciclo principale (label MainLoop) viene inizializzato il nuovo registro Shift a 00000001B con le seguenti istruzioni: movlw movwf B'00000001' Shift
A questo punto, nel ciclo principale del programma, il valore memorizzato nel registro Shift verr trasferito sulla Porta B ottenendo quindi l'accensione del primo led. Questo viene fatto con le seguenti istruzioni: movf movwf Shift,W PORTB
Successivamente viene effettuato lo scorrimento a sinistra di un bit, del valore contenuto in Shift, con le seguenti istruzioni: bcf rlf STATUS,C Shift,F
la prima istruzione azzera il bit CARRY del registro di stato STATUS che verr analizzato pi avanti. L'istruzione RLF Rotate Left F through Carry (ruota a sinistra attraverso il bit di carry) sposta di un bit verso sinistra il valore memorizzato nel registro Shift inserendo nella posizione occupata dal bit 0 il valore del bit di Carry. Per far s che il bit inserito sia sempre zero, prima della RLF viene eseguita l'istruzione BCF STATUS,C che azzera appunto il bit Carry. A questo punto il registro Shift varr 00000010, quindi, al ciclo successivo, una volta trasferito tale valore sulla port B si otterr lo spegnimento del LED1 e l'accensione del LED2 e cos via per i cicli successivi. Quando il bit 4 di Shift varr 1, significa che tutti i quattro led sono stati accesi almeno una volta e occorre quindi ripartire dal led 1.
48
Le istruzioni seguenti svolgono questo tipo di controllo: btfsc swapf Shift,4 Shift,F
L'istruzione BTFSC Shift,4 controlla appunto se il bit 4 del registro Shift vale 1. In caso positivo viene eseguita l'istruzione successiva SWAPF Shift,F altrimenti listruzione consecutiva viene saltata. L'istruzione SWAP (dall'inglese "scambia") scambia i quattro bit pi significativi contenuti nel registro Shift con i quattro meno significativi. Dal valore iniziale del registro Shift pari a 00010000 ottenuto dopo alcune ripetizioni del ciclo MainLoop si ottiene il valore 00000001 quindi la riaccensione del primo led.
Nel CD allegato Nella cartella \sorgenti trovate il file SEQ.ASM utilizzato in questo capitolo.
49
6 - LE PORTE DI I/O
LE PORTE A E B
Il PIC16F84A dispone di un totale di 13 linee di I/O organizzate in due porte denominate PORT A e PORT B. La PORT A dispone di 5 linee configurabili sia come ingresso che come uscita identificate dalle sigle RA0, RA1, RA2, RA3 ed RA4. La PORT B dispone di 8 linee anch'esse configurabili come ingresso o come uscita ed identificate dalle sigle RB0, RB1, RB2, RB3, RB4, RB5, RB6 ed RB7.
La suddivisione delle linee in due porte distinte dettata dai vincoli dell'architettura interna del PIC16F84A che prevede la gestione di dati di 6 - Le porte di I/O 51
lunghezza massima pari a 8 bit. Per la gestione delle linee di I/O da programma, il PIC dispone di due registri interni per ogni porta denominati TRISA e PORTA per la porta A, TRISB e PORTB per la porta B. I registri TRIS A e B, permettono di determinare se una singola linea di una porta debba funzionare come ingresso o come uscita. I registri PORTA e PORTB permettono invece di impostare lo stato delle linee di uscita o leggere lo stato delle linee di ingresso. Ognuno dei bit contenuti nei registri menzionati corrisponde univocamente ad una linea di I/O. Ad esempio il bit 0 del registro PORTA e del registro TRIS A corrispondono alla linea RA0, il bit 1 alla linea RA1 e cos via. Se il bit 0 del registro TRISA viene messo a zero, la linea RA0 verr configurata come linea in uscita, quindi il valore a cui verr messo il bit 0 del registro PORTA determiner lo stato logico di tale linea (0 = 0 volt, 1 = 5 volt). Se il bit 0 del registro TRISA viene messo a uno, la linea RA0 verr configurata come linea in ingresso, quindi lo stato logico in cui verr posta la linea RA0 dalla circuiteria esterna, si rifletter sullo stato del bit 0 del registro PORTA. Si supponga, come esempio, di voler collegare un led sulla linea RB0 ed uno switch sulla linea RB4. Il codice da scrivere sar il seguente: movlw movwf 00010000B TRISB
in cui viene messo a zero il bit 0 (linea RB0 in uscita) e ad uno il bit 4 (linea RB4) in ingresso. Si ricorda a tale proposito che nella notazione binaria il bit pi a destra corrisponde con il bit meno significativo (bit 0). La linea di codice per laccensione del led (accensione sul livello alto) sar la seguente: bsf PORTB,0
Per leggere lo stato dello switch collegato alla linea RB4, il codice sar: btfss goto goto PORTB,4 SwitchAMassa SwitchAlPositivo
dove, ovviamente, SwitchAMassa e SwitchAlPositivo sono le etichette alle quali salter il programma nel caso in cui lo switch sia rispettivamente chiuso a massa (0V) al positivo di alimentazione (5V).
52
6 - Le porte di I/O
Funzionamento in ingresso
Come gi accennato, per configurare la linea RA0 in ingresso, necessario portare ad 1 il bit 0 del registro TRISA con l'istruzione: bsf TRISA,0
Questo determina una commutazione ad 1 dello stato logico del flip-flop di tipo D-latch indicato nel blocco con il nome TRIS latch. Per ogni linea di I/O esiste uno di questi flip-flop e lo stato logico in cui si trova dipende strettamente dallo stato logico del relativo bit nel registro TRIS (in particolare ogni bit del registro TRIS fisicamente implementato con un TRIS latch). 6 - Le porte di I/O 53
L'uscita Q del TRIS latch collegata all'ingresso di una porta logica di tipo OR. Ci comporta che, indipendentemente dal valore presente all'altro ingresso, l'uscita della porta OR varr sempre 1 (in quanto uno dei suoi ingressi vale 1). In questa condizione il transistor P non conduce e mantiene la linea RA0 scollegata dal positivo di alimentazione. Allo stesso modo l'uscita negata del TRIS latch collegata all'ingresso di una porta AND quindi l'uscita di questa varr sempre 0 (in quanto uno dei suoi ingressi vale 0). In questa condizione anche il transistor N non conduce mantenendo la linea RA0 scollegata anche dalla massa. Lo stato logico della linea RA0 dipender esclusivamente dalla circuiteria esterna a cui collegata. Lo stato di RA0 pu essere letto sfruttando la circuiteria d'ingresso del blocco rappresentata dal TTL input buffer e dal latch di ingresso.
Funzionamento in uscita
RA0 una uscita se il bit 0 del registro TRISA viene portato a zero con l'istruzione: bcf TRISA,0
Questo determina la commutazione a 0 dell'uscita Q del TRIS latch (ed a 1 dell'uscita Q negata). In questo stato il valore in uscita dalle porte OR e AND dipende esclusivamente dallo stato dell'uscita Q negata del Data Latch. Come per il TRIS latch, anche il Data Latch dipende dallo stato di un bit in un registro, in particolare del registro PORTA. La sua uscita negata viene inviata all'ingresso delle due porte logiche OR e AND e quindi direttamente sulla base dei transistor P ed N. Portando a 0 il bit 0 del registro PORTA con l'istruzione: bcf PORTA,0
il transistor N entra in conduzione portando a 0 della linea RA0. Portando a 1 il bit 0 con l'istruzione: bsf PORTA,0
il transistor P ad entrare in conduzione, portando a +5 volt la linea RA0. In questa condizione sempre possibile rileggere il valore inviato sulla linea tramite la circuiteria d'ingresso.
La logica di commutazione sostanzialmente identica al gruppo di linee RA0-3 ad eccezione dell'assenza della porta OR e del transistor P, ovvero di tutta la catena che consente di collegare al positivo la linea RA4. Questo significa, in termini pratici, che quando la linea RA4 viene configurata come uscita e portata a 1, in realt non viene connessa fisicamente al positivo di alimentazione, ma rimane scollegata. Tale tipo di circuiteria d'uscita viene denominata "open drain" ed utile per applicazioni in cui sia necessario condividere uno stesso collegamento con pi pin d'uscita e vi sia quindi la necessit di mettere in alta impedenza una linea d'uscita senza doverla riprogrammare come linea d'ingresso. Per essere sicuri che la linea RA4 vada a 1 necessario collegare esternamente una resistenza di pull-up, ovvero una resistenza tra RA4 e il positivo di alimentazione. Pi avanti verr analizzato luso della linea indicata sullo schema come TMR0 clock input.
Nota Utilizzando la linea RA4 come uscita, si deve collegare una resistenza di pull-up esterna per garantire il corretto livello logico alto. 6 - Le porte di I/O 55
La sola linea RB0 inoltre, presenta una caratteristica molto particolare. Essa, quando viene configurata come linea di ingresso, pu generare, in corrispondenza di un cambio di stato logico, un interrupt, ovvero una interruzione immediata del programma in esecuzione ed una chiamata ad una subroutine speciale denominata interrupt handler. Il meccanismo dellinterruzione verr trattato nel capitolo 8. 56 6 - Le porte di I/O
6 - Le porte di I/O
57
Ognuno di questi pulsanti, se premuto, collega a massa una linea di ingresso normalmente mantenuta a + 5 volt da una resistenza (da R6 a R9). Si consideri, ad esempio, il pin 10 del PIC16F84A: questa linea verr mantenuta a +5 volt finch non verr premuto il tasto SW1 che provveder a portare la linea ad 0 volt. Il programma di esempio prevede laccensione di ciascuno dei led D1, D2, D3 e D4 in corrispondenza della pressione di uno dei tasti SW1, SW2, SW3 e SW4 rispettivamente. Il sorgente dell'esempio riportato nel file INPUT.ASM. 58 6 - Le porte di I/O
La parte iniziale del programma esegue le stesse funzioni effettuate negli esempi gi visti ed in particolare le istruzioni: bsf movlw movwf STATUS,RP0 11110000B TRISB
configurano le linee da RB0 a RB3 come uscite per il collegamento con i led e le linee da RB4 a RB7 come ingressi per il collegamento con i quattro pulsanti (si noti che prima di accedere al registro TRISB viene impostato il banco di registri 1 portando ad 1 il bit RP0 del registro STATUS). L'istruzione bcf STATUS,RP0
effettua uno swap sul banco di registri 0 in modo da poter accedere direttamente allo stato delle linee di I/O. MainLoop clrf PORTB
Questa istruzione spegne tutti i led collegati sulla PORTA B and ogni ciclo di loop in modo che possano poi essere accesi sulla base dello stato dei pulsanti. btfss bsf PORTB,SW1 PORTB,LED1
Queste due istruzioni vengono eseguite per ogni linea collegata ad un pulsante per verificare se il pulsante premuto e per accendere, eventualmente, il led corrispondente. Pi in dettaglio listruzione btfss PORTB,SW1
solo se il pulsante SW1 rilasciato. In caso contrario la esegue accendendo il led. Il tutto viene eseguito all'interno di un singolo loop tramite l'istruzione: goto MainLoop
Nel CD allegato Nella cartella \sorgenti trovate il file INPUT.ASM utilizzato in questo esempio.
6 - Le porte di I/O
59
In pratica, a differenza di altri registri, il TMR0 non mantiene inalterato il valore che gli viene memorizzato, ma viene incrementato continuamente ad ogni ciclo macchina in modo automatico e del tutto indipendente dallesecuzione del programma. Essendo un registro ad 8 bit, il massimo valore che pu contenere 255 e, una 7 - Il contatore TMR0 ed il PRESCALER 61
volta raggiunto tale valore, TMR0 viene azzerato automaticamente riprendendo quindi il conteggio da zero. La frequenza di conteggio direttamente proporzionale alla frequenza di clock applicata al chip e pu essere modificata programmando opportunamente alcuni bit di configurazione. Nella figura 7.2 viene riportata la catena di blocchi interni al PIC che determinano il funzionamento del registro TMR0.
I blocchi Fosc/4 e T0CKI rappresentano le due possibili sorgenti di segnale per il contatore TMR0. Fosc/4 un segnale generato internamente al PIC dal circuito di clock ed pari alla frequenza di clock divisa per quattro. T0CKI un segnale generato da un eventuale circuito esterno ed applicato al pin T0CKI corrispondente al pin 3 nel PIC16F84A. I blocchi T0CS e PSA sono due commutatori di segnale sulla cui uscita viene presentato uno dei due segnali in ingresso in base al valore dei bit T0CS e PSA del registro OPTION. Il blocco PRESCALER un divisore programmabile il cui funzionamento verr illustrato nel paragrafo successivo. Per analizzare le diverse modalit di conteggio, si supponga di impostare i bit T0CS a 0 e PSA a 1. La catena di blocchi relativa a TMR0 diviene quella di figura 7.3:
62
Le parti in neretto evidenziano il percorso che effettua il segnale prima di arrivare al contatore TMR0. Come gi detto in precedenza, la frequenza Fosc/4 pari ad un quarto della frequenza di clock. Utilizzando un quarzo da 4Mhz si ottiene una Fosc/4 pari ad 1 MHz. Tale frequenza viene inviata direttamente al registro TMR0 senza subire nessun cambiamento, dunque il contenuto di TMR0 viene incrementato un milione di volte al secondo. Impostando lo stato del bit T0CS da 0 a 1 la configurazione diviene quella di figura 7.4.
In questo caso il segnale applicato al pin TOCKI del PIC ad essere inviato direttamente al contatore TMR0 determinandone la frequenza di conteggio. Applicando ad esempio a questo pin una frequenza pari ad 100Hz si ottiene una frequenza di conteggio pari a cento incrementi al secondo. La presenza della porta logica XOR (exclusive OR) all'ingresso TOCKI del PIC consente di determinare tramite il bit T0SE del registro OPTION se il contatore TMR0 deve essere incrementato in corrispondenza del fronte di discesa (T0SE=1) o del fronte di salita (T0SE=0) del segnale applicato dall'esterno. Nella figura 7.5 viene rappresentata la corrispondenza tra l'andamento del segnale esterno ed il valore assunto dal contatore TMR0 in entrambi i casi:
IL PRESCALER
Impostando a zero il bit PSA del registro OPTION il registro TMR0 viene pilotato dal segnale in uscita dal PRESCALER come mostrato nella figura 7.6:
63
Il PRESCALER un divisore programmabile a 8 bit da utilizzare per diminuire la frequenza di conteggio rispetto al segnale Fosc/4 o a quello applicato a T0CKI.
PS2 PS1 PS0 Divisore Frequenza in uscita al prescaler (Hz) 0 0 0 0 1 1 1 1 0 0 1 1 0 0 1 1 0 1 0 1 0 1 0 1 2 4 8 16 32 64 128 256 500.000 250.000 125.000 62.500 31.250 15.625 7.813 3.906
Nella tabella 7.1, riportato il fattore di divisione per ciascuna combinazione dei bit PS0PS3 ed il valore della frequenza in uscita al PRESCALER nellipotesi in cui il segnale applicato abbia frequenza pari a 1MHz.
64
Tali istruzioni impostano il bit T0CS a 0 per selezionare come sorgente del conteggio il clock del PIC, il bit PSA a 0 per assegnare il PRESCALER al registro TRM0 e i bit di configurazione del PRESCALER a 100 per ottenere una divisione di frequenza pari a 32. La frequenza di conteggio ottenuta sul TRM0 sar pari a: F = 1Mhz / 32 = 31.250 Hz La subrountine Delay dovr utilizzare opportunamente il registro TMR0 per ottenere un ritardo pari ad un secondo. Le prime istruzioni che vengono eseguite nella Delay sono: movlw movwf e movlw movwf 125 Count 6 TMR0
Le prime due memorizzano in TMR0 il valore 6 in modo che il registro TMR0 raggiunga lo zero dopo 250 conteggi (256 - 6 = 250) ottenendo cos una frequenza di passaggi per lo zero di TMR0 pari a: 31.250 / 250 = 125 Hz Le istruzioni successive memorizzano in un registro a 8 bit (Count) il valore 125 in modo tale che, decrementando questo registro di uno per ogni passaggio per lo zero di TMR0, si ottenga una frequenza di passaggi per lo zero del registro Count pari a: 125/125 = 1Hz Le istruzioni inserite nel loop DelayLoop si occupano quindi di controllare se TMR0 ha raggiunto lo zero, quindi di reinizializzarlo a 6 e decrementare il valore contenuto in Count. Quando Count raggiunger anch'esso lo zero allora sar trascorso un secondo e la subroutine potr fare ritorno al programma chiamante.
Nel CD allegato Nella cartella \sorgenti trovate il file SEQTMR0.ASM utilizzato in questo esempio.
65
8 - GLI INTERRUPT
L'interrupt una particolare caratteristica dei PICmicro (e dei microprocessori in generale) che consente di intercettare un evento esterno, interrompere momentaneamente il programma in corso, eseguire una porzione di programma specializzata per la gestione dell'evento verificatosi quindi riprendere l'esecuzione del programma principale. Per fare un paragone con il mondo reale, l'interrupt pu essere assimilato alla suoneria del telefono: per poter ricevere telefonate non occorre alzare continuamente la cornetta per sapere se qualcuno intende comunicare, ma, grazie alla suoneria, possibile svolgere altri compiti in quanto, allarrivo di una telefonata, la suoneria stessa provveder a notificare il verificarsi dellevento. Allarrivo dello squillo, possibile decidere di interrompere momentaneamente i compiti in esecuzione, rispondere al telefono e, una volta terminata la conversazione, riprendere dal punto di interruzione. Nellanalogia con il PIC si ha che: I compiti corrispondono al programma in esecuzione. La chiamata da parte di qualcuno corrisponde all'evento da gestire. Lo squillo del telefono corrisponde alla richiesta di interrupt. La risposta al telefono corrisponde alla subroutine di gestione dell'interrupt. evidente quanto sia pi efficiente gestire un evento con un interrupt piuttosto che controllare ciclicamente il verificarsi dello stesso evento attraverso il programma principale. Gran parte degli aspetti legati alla gestione dell'interrupt vengono inoltre trattati direttamente dall'hardware interno del PIC per cui il tempo di risposta all'evento praticamente nullo.
indipendentemente dagli altri agendo sui seguenti bit del registro INTCON: INTE (bit 4) se questo bit viene messo a 1 viene abilitato l'interrupt sul cambiamento di stato sulla linea RB0 T0IE (bit 5) se questo bit viene messo a 1 viene abilitato l'interrupt sulla fine del conteggio del registro TMR0 RBIE (bit 3) se questo bit viene messo a 1 viene abilitato l'interrupt sul cambiamento di stato su una delle linee da RB4 ad RB7 EEIE (bit 6) se questo bit viene messo a 1 viene abilitato l'interrupt sulla fine della scrittura su una locazione EEPROM Esiste inoltre un bit di abilitazione generale degli interrupt che deve essere settato anch'esso ad uno ovvero il bit GIE (Global Interrupt Enable bit) posto sul bit 7 del registro INTCON.
INTERRUPT FLAG
Dato che qualunque interrupt genera una chiamata alla locazione 0x04, nel registro INTCON sono presenti dei flag che indicano quale l'evento che ha generato l'interrupt. In particolare: INTF (bit 1) Se vale 1 l'interrupt stato generato dal cambiamento di stato sulla linea RB0. T0IF (bit 2) Se vale 1 l'interrupt stato generato al termine del conteggio del timer TMR0. RBIF (bit 0) Se vale 1 l'interrupt stato generato dal cambiamento di stato di una delle linee da RB4 a RB7. Come si pu notare, non previsto alcun flag di segnalazione per l'interrupt sul 68 8 - Gli interrupt
fine scrittura in EEPROM dunque l'interrupt handler dovr considerare che l'interrupt stato generato da questo evento quando tutti i tre flag sopra citati valgono 0. Importante: Una volta rilevato quale flag attivo, l'interrupt handler deve provvedere allazzeramento del flag altrimenti non verr pi generato l'interrupt corrispondente. Nota Non esiste un flag per la fine scrittura su EEPROM, per cui tale evento deve essere riconosciuto per esclusione, ovvero si generata una interruzione e tutti i flag sono a zero.
PUSH
ISR
;qui si inserisce il codice relativo alla ;routine di servizio per linterruzione swapf movwf swapf swapf STATUS_TEMP,0 ;Copia STATUS_TEMP in w STATUS ;Ripristino di STATUS W_TEMP,1 W_TEMP,0 ;Ripristino di W
POP
8 - Gli interrupt
69
70
8 - Gli interrupt
LED 1 lampeggia esattamente come avveniva con il programma LED.ASM, ma premendo uno qualsiasi dei tasti da SW1 a SW4 il LED 2 si accende immediatamente e rimane acceso per un tempo pari a 3 lampeggi del LED 1. Quello che accade che mentre il loop principale, derivato dal vecchio LED.ASM, continua a far lampeggiare il LED 1 utilizzando un ritardo software introdotto dalla subroutine Delay, il PIC in grado di accorgersi della pressione di un tasto e di segnalarlo immediatamente sul LED 2 senza influenzare in maniera evidente la frequenza di lampeggio di LED1.
Nel CD allegato Nella cartella \sorgenti trovate il file INTRB.ASM utilizzato in questo esempio.
e quindi dal codice della subroutine di gestione dell'interrupt: bsf movlw movwf bcf retfie Poich l'interrupt handler deve necessariamente essere allocato a partire dall'indirizzo 0x04, per evitare che esso venga eseguito al reset stata inserita listruzione di salto incondizionato. Il codice dell'interrupt handler, in questo caso, molto semplice e si limita ad accendere il LED 2, quindi inserire nel registro utente nTick il numero di lampeggi raggiunto il quale il LED 2 deve spegnersi e quindi azzerare il flag RBIF per consentire alla circuiteria di generazione dell'interrupt di continuare a 8 - Gli interrupt 71 PORTB,LED2 3 nTick INTCON,RBIF
funzionare. L'istruzione RETFIE consente al PIC di tornare ad eseguire il programma interrotto dall'interrupt. La direttiva ORG 0x04 garantisce che linterrupt handler sia posizionato a partire dallindirizzo 0x04. Nota La routine che gestisce linterrupt deve provvedere ad azzerare gli interrupt flag.
Con queste istruzioni viene messo ad uno il bit GIE (bit 7) che abilita in generale la circuiteria di generazione degli interrupt, quindi il bit RBIE (bit 3) che abilita, in particolare, l'interrupt su cambiamento di stato delle linee RB4RB7. Ora, avendo collegato i pulsanti SW1, SW2, SW3 e SW4 proprio sulle linee di I/O RB4, RB5, RB6 ed RB7, con la pressione di uno di questi si impone un cambiamento di stato, quindi un interrupt. Nel loop principale, oltre alle operazioni di accensione e spegnimento del LED 1, viene decrementato il contatore nTick fino al raggiungimento dello zero. In corrispondenza di questo viene spento il LED 2.
72
8 - Gli interrupt
Eseguendo il programma si nota che mentre LED1 lampeggia con la frequenza di un secondo, LED3 lampeggia ad una frequenza pi elevata (125Hz) tanto da apparire sempre acceso. Inoltre premendo un pulsante qualsiasi, LED2 si accende secondo quanto visto in precedenza. L'effetto finale ottenuto l'esecuzione di tre compiti ad una velocit tale da sembrare in esecuzione parallela.
8 - Gli interrupt
73
viene controllato il flag T0IF e RBIF per vedere rispettivamente se l'evento che ha scatenato l'interrupt proviene dal registro TMR0 o dalle porte RB4RB7. Quindi vengono lanciate in esecuzione le relative subroutine di gestione a partire dalle label IntT0IF e IntRBIF. Prima di ridare il controllo al programma principale vengono azzerati i flag T0IF e RBIF per garantire che i successivi eventi possano scaturire nuovamente gli interrupt.
Nel CD allegato Nella cartella \sorgenti trovate il file DBLINT.ASM utilizzato in questo esempio.
74
8 - Gli interrupt
9 - RESET
Il PIC16F84A, come la maggior parte degli altri modelli di PIC, riesce a distinguere diverse tipologie di reset: 1. Power-on Reset (POR) 2. Impulso sul pin /MCLR in condizioni operative normali o nello stato di SLEEP 3. WDT Reset (in condizioni operative normali) 4. WDT Wake-up (nello stato SLEEP)
I vari tipi di reset possono essere riconosciuti a livello software analizzando i flag TO e PD del registro STATUS in accordo alla tabella seguente: 9 - Reset 75
TO PD Condition 1 0 x 0 0 1 1 1 x 0 1 0 1 0 Power-on Reset Non consentito, il TO settato sul POR Non consentito, il PD settato sul POR WDT Reset (during normal operation) WDT Wake-up MCLR durante il normale funzionamento MCLR durante lo SLEEP o interrupt di Wake-up dallo SLEEP
Il pin /MCLR fa capo ad un trigger di Schmitt in modo da ripulire il segnale esterno e renderlo adatto ad essere gestito dalla circuiteria interna. Non tutti i registri sono coinvolti nelloperazione di reset: alcuni registri possono contenere un valore casuale dopo un POR (Power-On-Reset) o il loro contenuto pu restare invariato dopo qualsiasi altro tipo di reset. Per molti altri registri invece previsto un RESET state per ciascun tipo di reset ovvero un valore predefinito che viene caricato automaticamente nel registro dopo una particolare operazione di reset. Nella tabella 9.1 sono riportati gli stati del Program Counter (PC) e del registro STATUS dopo i vari tipi di reset. Nella tabella 9.2 invece riportato lo stato degli altri registri del PIC a seguito delle varie tipologie di reset. Per convenzione con x sono indicati valori casuali, con u i valori che restano invariati durante il reset, con i bit non significativi (letti come 0) e con q i valori dipendenti dalla specifica condizione di reset.
76
9 - Reset
POWER-ON-RESET (POR)
Quando sul pin di alimentazione Vdd si verifica un fronte di salita nel range di 1,21,7V (normalmente questo si verifica nellistante in cui il PIC viene alimentato), viene generato un impulso di reset interno al chip. Per sfruttare tale impulso buona norma mantenere a livello alto il pin /MCLR inserendo un resistore di pull-up (da 10K) connesso tra /MCLR e il positivo di alimentazione. In questo modo non sono necessarie reti RC esterne per garantire il reset allavvio. Se, successivamente allimpulso di POR, il PIC si trova nelle giuste condizioni operative (tensione, frequenza, temperatura, ecc) viene avviata lesecuzione del codice. Viceversa se alcuni parametri non rientrano nelle condizioni ammissibili, il PIC viene mantenuto nello stato di reset ed il codice non viene eseguito. Nota Non vengono generati impulsi di reset durante il fronte di discesa della tensione di alimentazione.
ritardo TPWRT sia il TOST non siano sufficienti a garantire che Vdd abbia raggiunto il valore di regime. In questo caso necessaria una circuiteria di reset esterna come mostrato nella figura 9.3.
Figura 9.3: Circuiteria di reset nel caso di tempi lunghi di stabilizzazione Vdd
Il diodo permette al condensatore di scaricarsi velocemente in fase di spegnimento. Portando infatti Vdd a zero, essendo C carico al valore Vdd, il diodo entra in conduzione provocando la scarica immediata del condensatore. Per R suggerito un valore inferiore a 40K (tipicamente 10K) per garantire un corretto valore 1 allingresso /MCLR. R1 deve avere una valore compreso tra 100 e 1K e la sua funzione quella di limitare la corrente di ingresso al pin /MCLR proveniente dal condensatore nel caso in cui /MCLR venga a trovarsi accidentalmente a livello logico basso.
Condizione Power-on Reset MCLR during normal operation MCLR during SLEEP WDT Reset (during normal operation) WDT Wake-up Interrupt wake-up from SLEEP PC 000h 000h 000h 000h PC + 1 PC + 1 STATUS 0001 1xxx 000u uuuu 0001 0uuu 0000 1uuu uuu0 0uuu uuu1 0uuu
Nota: quando il risveglio (wake-up) dovuto ad una interruzione ed il bit GIE a 1, nel Program Counter viene caricato l interrupt vector (0004h).
78
9 - Reset
Risveglio dallo stato SLEEP mediante interruzione o per WDT Time-out MCLR reset in condizioni operative o nello stato SLEEP. WDT reset in condizioni operative. Registro W INDF TMR0 PCL STATUS FSR PORTA(2) PORTB(3) EEDATA EEADR PCLATH INTCON INDF OPTION_REG PCL STATUS FSR TRISA TRISB EECON1 EECON2 PCLATH INTCON Indirizzo 00h 01h 02h 03h 04h 05h 06h 08h 09h 0Ah 0Bh 80h 81h 82h 83h 84h 85h 86h 88h 89h 8Ah 8Bh POR xxxx xxxx ---- ---xxxx xxxx 0000 0000 0001 1xxx xxxx xxxx ---x xxxx xxxx xxxx xxxx xxxx xxxx xxxx ---0 0000 0000 000x ---- ---1111 1111 0000 0000 0001 1xxx xxxx xxxx ---1 1111 1111 1111 ---0 x000 ---- ------0 0000 0000 000x uuuu uuuu ---- ---uuuu uuuu 0000 0000 000q quuu uuuu uuuu ---u uuuu uuuu uuuu uuuu uuuu uuuu uuuu ---0 0000 0000 000u ---- ---1111 1111 0000 0000 000q quuu uuuu uuuu ---1 1111 1111 1111 ---0 q000 ---- ------0 0000 0000 000u uuuu uuuu ---- ---uuuu uuuu PC + 1(1) uuuq quuu uuuu uuuu ---u uuuu uuuu uuuu uuuu uuuu uuuu uuuu ---u uuuu uuuu uuuu ---- ---uuuu uuuu PC + 1(1) uuuq quuu uuuu uuuu ---u uuuu uuuu uuuu ---0 uuuu ---- ------u uuuu uuuu uuuu(1)
(1): quando il risveglio (wake-up) dovuto ad una interruzione ed il bit GIE a 1, nel Program Counter viene caricato linterrupt vector (0004h). (2): ad ogni reset i pin della PORTA vengono configurati come ingressi. (3): il valore che verr trasferito al latch di uscita.
9 - Reset
79
INTRODUZIONE
Il Power Down Mode o Sleep Mode un particolare stato di funzionamento del PICmicro utilizzato per ridurre il consumo di corrente nei momenti in cui il PICmicro in attesa di un evento esterno. Se ad esempio il PIC gestisce un telecomando per apricancello o per TV, evidente che per la maggior parte del tempo il PICmicro rimane in attesa che qualcuno prema un tasto. Appena premuto, il PICmicro effettua una breve trasmissione per mettersi poi nuovamente in attesa della pressione del prossimo tasto. Il tempo di utilizzo effettivo della CPU del PICmicro risulta quindi limitato ai pochi millisecondi necessari per effettuare la trasmissione, mentre per diverse ore non richiesta nessuna elaborazione particolare. Per evitare linutile dispendio della limitata energia dalla batteria, possibile spegnere buona parte dei circuiti di funzionamento del PICmicro e riaccenderli solo in corrispondenza di un particolare evento esterno.
L'ISTRUZIONE SLEEP
L'istruzione SLEEP viene utilizzata per mettere il PIC in Power Down Mode (modalit a basso consumo) e ridurre di conseguenza la corrente assorbita che passer da circa 2mA (a 5 volt con clock di funzionamento a 4Mhz) a circa 2A, ovvero 1000 volte inferiore. Per entrare in Power Down Mode basta inserire questa istruzione in un punto qualsiasi del programma: SLEEP Qualsiasi istruzione presente dopo la SLEEP non verr eseguita dal PICmicro che terminer in questo punto la sua esecuzione, spegner tutti i circuiti interni, tranne quelli necessari a mantenere lo stato delle porte di I/O (stato logico alto, basso o alta impedenza) ed a rilevare le condizioni di "risveglio" che verranno analizzate in seguito. Per ridurre il consumo di corrente in questo stato, non devono esserci ovviamente circuiti collegati alle linee di uscita del PIC che assorbono corrente. Pi precisamente questi circuiti dovranno essere progettati in modo da limitare il loro assorbimento nelle condizioni di Power Down. Un altro accorgimento 10 - Il Power Down Mode 81
raccomandato da Microchip quello di collegare al positivo (Vdd) o al negativo (Vss) di alimentazione tutte le linee in alta impedenza non utilizzate compresa la linea RA4/T0CKI (pin 3).
82
Nel CD allegato Nella cartella \sorgenti trovate il file PDM.ASM utilizzato in questo esempio.
83
INTRODUZIONE
In questo capitolo verr illustrato il funzionamento del Watch Dog Timer il cui scopo quello di migliorare l'affidabilit dei circuiti basati su PICmicro. Il Watch Dog Timer un oscillatore interno al PICmicro molto simile al TMR0, ma completamente indipendente dal resto della circuiteria, il cui scopo quello di rilevare eventuali blocchi della CPU e resettare il PICmicro per riprendere la normale esecuzione del programma. Per poter rilevare un eventuale blocco della CPU durante l'esecuzione di un programma, viene inserita all'interno del programma principale, una istruzione speciale: CLRWDT (CLeaR Watch Dog Timer) la quale azzera ad intervalli regolari il Watch Dog Timer impedendogli di terminare il suo conteggio. Se la CPU non effettua questa istruzione prima del termine del conteggio, con buona probabilit il programma bloccato quindi viene fatto automaticamente un Reset. Nota Per poter utilizzare il Watch Dog Timer occorre abilitarlo mediante i flag di configurazione del programmatore o mediante la direttiva __CONFIG. Il periodo minimo oltre il quale la CPU viene resettata di circa 18ms (dipende dalla temperatura e dalla tensione di alimentazione). possibile per assegnare il PRESCALER al Watch Dog Timer per ottenere ritardi pi lunghi fino a 2.3 secondi. Per abilitare il Watch Dog Timer occorre abilitare in fase di programmazione il flag WDTE della word di configurazione (utilizzando la direttiva __CONFIG oppure manualmente secondo le modalit relative al programmatore in uso).
85
In caso contrario il prescaler verr assegnato al TIMER 0. Ovviamente assegnando il prescaler al WDT non sar possibile assegnarlo completamente al TIMER 0 e viceversa. Intervenendo sui valori dei bit PS0, PS1 e PS2 dello stesso registro OPTION_REG si possono ottenere diversi intervalli di ritardo. La scelta corretta dovr essere fatta tenendo conto del massimo ritardo ottenibile all'interno del programma tra l'esecuzione di due istruzioni CLRWDT successive. Nella tabella 11.1 riportato la corrispondenza tra i valori di questi bit e gli intervalli ottenuti.
PS2 PS1 PS0 Divisore Periodo di ritardo del WDT 0 0 0 0 1 1 1 1 0 0 1 1 0 0 1 1 0 1 0 1 0 1 0 1 1 2 4 8 16 32 64 128 18 ms 36 ms 72 ms 144 ms 288 ms 576 ms 1.152 s 2.304 s
86
Allentrata in esecuzione del programma il LED 1 inizier a lampeggiare. Durante il lampeggio viene eseguita continuamente l'istruzione CLRWDT per evitare che la CPU venga resettata. Premendo il tasto SW2 la CPU entra in un loop infinito (StopLoop) allinterno del quale non viene mai eseguita la CLRWDT. Trascorsi circa 2.3 secondi, il Watch Dog Timer effettua automaticamente il reset della CPU ed il LED 1 inizia nuovamente a lampeggiare. Come prova del funzionamento del WDT, possibile riprogrammare il 11 - Il watch dog timer (WDT) 87
PIC16F84A con lo stesso programma senza abilitare il WDTE mediante il programmatore (o disabilitandolo manualmente qualora risultasse abilitato). In questo caso premendo il tasto SW2 il lampeggio di LED1 si blocca e non si ripristina in alcun modo.
Nel CD allegato Nella cartella \sorgenti trovate il file WDT.ASM utilizzato in questo esempio.
88
In questo capitolo verr analizzato il funzionamento della EEPROM DATI interna al PIC16F84A. La EEPROM DATI una particolare area di memoria da 64 byte nella quale possono essere scritti valori numerici che rimarranno memorizzati anche in mancanza di tensione di alimentazione. Si intuisce immediatamente quanto possa essere utile questo tipo di memoria. Si pensi, ad esempio, ad un sistema anti intrusione in cui il PIC deve mantenere il codice di accesso anche quando il sistema spento in modo che non sia necessaria una riprogrammazione ad ogni accensione, oppure ad una chiave elettronica realizzata con un PIC che riceve alimentazione solo quando l'utente inserisce la chiave nel lettore. In tutti questi casi la EEPROM DATI integrata nel PIC16F84A garantisce un ottimo livello di sicurezza nella conservazione dei dati, unito ad una relativa facilit d'uso. La memoria EEPROM scrivibile e leggibile in condizioni di normale alimentazione e senza dover ricorrere ad alcun programmatore esterno. Le modalit di accesso sono notevolmente diverse dalla memoria RAM dei REGISTER FILE e devono seguire una serie di procedure particolari atte ad evitare eventuali perdite di dati in condizioni di funzionamento anomale.
Nel registro EEDATA dovr invece essere scritto il valore da inviare alla locazione EEPROM indirizzata con il registro EEADR: movlw movwf D10 EEDATA
Per poter abilitare l'accesso alle successive operazioni di scrittura dovr essere portato ad uno il flag WREN (WRite ENable), contenuto nel registro di controllo EECON1. Dato che il registro EECON1 situato nel banco registri 1, si dovr indirizzare tale banco settando il bit RP0 del registri STATUS prima di accedervi: ;Indirizza il banco 1 bsf STATUS,RP0 ;Abilita la scrittura bsf EECON1,WREN Per evitare scritture accidentali in caso di funzionamento anomalo del PIC dovuto a sbalzi di tensione o errori di programmazione, la scrittura su EEPROM avviene seguendo una precisa sequenza di operazioni di scrittura sul registro EECON2. In particolare nel registro EECON2 dovranno essere scritti in sequenza i due valori esadecimali 0x55 e 0xAA: movlw movwf movlw movwf 0x55 EECON2 0xAA EECON2
Eseguite queste operazioni preliminari possibile avviare la scrittura settando il flag WR (WRite) del registro EECON1 con l'istruzione: bsf EECON1,WR
L'hardware del PIC impiega un certo tempo, a partire da questo momento, per programmare la cella EEPROM con il valore inviato. Al termine dell'operazione viene automaticamente azzerato il flag WR del registri EECON1. Di seguito riportato un ciclo di attesa per sospendere il programma principale fino alla fine delloperazione di scrittura: WriteDoneLoop btfsc EECON1,WR ;Finito di scrivere ? goto WriteDoneLoop ;No, aspetta ;Si, continua con le istruzioni successive 90 12 - Scrittura e lettura dati da EEPROM
Il ciclo di attesa pu essere evitato se si abilita linterrupt relativo alla scrittura dati su EEPROM. Per scrivere un nuovo valore nella stessa cella EEPROM non necessario effettuare operazioni di cancellazione, ma sufficiente ripetere le operazioni di scrittura.
Il dato letto dalla locazione specificata in EEADR viene trasferito nel registro EEDATA dal quale pu essere prelevato con una operazione di MOVF: bcf movf STATUS,RP0 EEDATA,W il ;Indirizza il banco 0 dato letto dalla EEPROM viene trasferito
91
93
Nella tabella 13.1 vengono descritte le funzioni di ogni singola linea disponibile per interfacciare il display.
Pin Nome Funzione 1 2 3 GND Ground. Questo pin deve essere collegato al negativo di alimentazione VDD LCD Power Supply. Questo pin deve essere collegato al positivo di alimentazione (+5V). Liquid Crystal Driving Voltage. A questo pin deve essere applicata una tensione variabile da 0 a 5 volt, tramite un trimmer, per regolare il contrasto del display Register Select. Questo pin una linea di controllo con cui si comunica al display se si sta inviando, sul bus dati (linee DB0DB7), un comando (RS=0) oppure un dato (RS=1) Read/Write. Questo pin una linea di controllo con cui si comunica al display se si intende inviare un dato (R/W=0) oppure leggerlo (R/W=1). Enable. Questo pin una linea di controllo con cui si pu abilitare il display ad accettare dati ed istruzioni dal bus dati (E=1) Data bus line 0 Su queste linee viaggiano i dati tra il PIC e il display Data bus line 1 Data bus line 2 Data bus line 3 Data bus line 4 Data bus line 5 Data bus line 6 Data bus line 7 Tabella 13.1: I pin di un display LCD
4 5 6 7 8 9 10 11 12 13 14
Per ridurre al massimo i collegamenti tra il PIC ed il display LCD, verr utilizzata la modalit di collegamento dati a 4 bit che impiega solo le linee DB4, DB5, DB6 e DB7. Le linee DB0, DB1, DB2 e DB3 non saranno utilizzate, quindi verranno collegate a massa. Anche la linea R/W non verr utilizzata e sar collegata direttamente a massa. In questo modo la modalit di funzionamento viene impostata come sola scrittura e consente di inviare dati all'LCD, ma non di riceverli.
Hello World!
Il file sorgente da utilizzare LCD1.ASM. Una volta programmato il PIC con il file compilato, all'accensione del circuito apparir sul display la schermata riportata in figura 13.2.
94
Se sul display non visibile alcun messaggio o sono visibili solo due righe di rettangoli neri, sar necessario regolare il contrasto del display LCD agendo sul trimmer R2 connesso al pin 3 del display.
Nel CD allegato Nella cartella \sorgenti trovate il file LCD1.ASM utilizzato in questo esempio.
;LCD data line bus LCD_DB4 LCD_DB5 LCD_DB6 LCD_DB7 equ equ equ equ 4 5 6 7 ;LCD ;LCD ;LCD ;LCD data data data data line line line line DB4 DB5 DB6 DB7
Queste costanti definiscono l'associazione tra le linee del PIC (tutte connesse alla PORTA B) e le linee del display. Le singole definizioni verranno usate all'interno delle subroutine di gestione dell'LCD al posto dei singoli numeri di identificazione delle linee di I/O. tmpLcdRegister res 2 msDelayCounter res 2 Queste due istruzioni allocano spazio per due registri: tmpLcdRegister, usato dalle routine di gestione dell'LCD e msDelayCounter usato dalla subroutine msDelay che genera dei ritardi software da 1 ms per il contenuto del registro W. Questa subroutine viene utilizzata sempre dalle subroutine di gestione dell'LCD per generare le temporizzazioni richieste durante la trasmissione di dati e comandi all'LCD. Segue una parte di definizione delle linee di connessione tra il PIC ed il display. La prima chiamata a subroutine : call LcdInit
LcdInit una subroutine che deve essere chiamata solo una volta all'inizio del programma e prima di qualsiasi altra subroutine di gestione dell'LCD. Essa si occupa di effettuare tutte le operazioni necessarie per inizializzare correttamente l'LCD e consentire, alle funzioni successive, di poter operare correttamente. Con le istruzioni seguenti: movlw call 0x00 LcdLocate
viene posizionato il cursore del display sulla prima riga e prima colonna dello 96 13 - Esempi ed applicazioni pratiche
schermo. I caratteri inviati successivamente verranno visualizzati a partire da questa posizione. I quattro bit pi significativi del valore caricato nel registro W con l'istruzione: movlw 0x00
contengono il numero della riga dove si vuole posizionare il cursore, mentre i quattro bit meno significativi contengono il numero della colonna. Cambiando tale valore nel registro W, possibile ottenere posizionamenti diversi. Con il valore 0x10 ad esempio si ottiene il risultato di figura 13.3A mentre con il valore 0x12 il risultato quello di figura 13.3B.
Per visualizzare ogni carattere della scritta vengono utilizzate le seguenti istruzioni: movlw call 'H' LcdSendData
per ciascuna lettera da visualizzare. La prima istruzione carica in w il codice ASCII della lettera da visualizzare (nellesempio la lettera A), la routine LcdSendData preleva il dato dal registro w e lo invia al display. L'incremento della posizione del cursore avviene automaticamente.
97
LcdClear Pulisce il contenuto dello schermo e riposiziona il cursore sulla prima colonna della prima riga. Non richiede alcun passaggio di parametri. LcdLocate Consente di posizionare arbitrariamente il cursore allinterno dellarea visibile del display. Richiede il valore di riga e colonna per il posizionamento del cursore nel registro W. I bit da D0 a D3 contengono il valore di colonna (asse Y) mentre i bit da D4 a D7 il valore di riga (asse X). La numerazione delle righe parte da 0 in alto. La numerazione delle colonne parte da 0 a sinistra. LcdSendData Serve ad inviare un carattere ASCII allLCD da visualizzare nella posizione corrente del cursore. Richiede nel registro W il valore ASCII del carattere da visualizzare. LcdSendCommand Serve ad inviare un comando allLCD. I comandi riconosciuti dallLCD sono riportati sul data-sheet dello stesso. LcdSendByte Questa funzione viene utilizzata internamente alle altre funzioni di gestione dellLCD e si occupa di effettuare lo split di dati e comandi a 8 bit sul bus di dati.
98
99
L'integrato MAX232 prodotto da Maxim, si occupa di convertire i segnali RS232 dai +/-12 volt necessari per trasmettere e ricevere dati sulla porta seriale ai livelli TTL (0/5 volt) gestibili direttamente dalle porte del PIC.
Nel CD allegato Nella cartella \Documentazione trovate il file max232.pdf che il datasheet del circuito integrato MAX232 utilizzato nello schema dellesempio.
Prima di iniziare lanalisi del file sorgente di questa applicazione, opportuno richiamare brevemente il funzionamento della comunicazione seriale RS232.
Per usare la RS232 per collegare tra loro due computer (DTE) senza interporre tra loro alcun dispositivo DCE necessario simulare le connessioni intermedie realizzando un cavo NULL MODEM (o cavo invertente). Nel caso dellapplicazione di esempio, i circuito di figura 13.4 simula un DCE, per cui per 100 13 - Esempi ed applicazioni pratiche
101
Una volta trasmesso l'ottavo bit (bit 7), il PC aggiunge automaticamente un ultimo bit a 1 denominato STOP BIT ad indicare l'avvenuta trasmissione dell'intero byte. La stessa sequenza viene ripetuta per ogni byte trasmesso sulla linea.
In alcuni casi i PC sono dotati di vecchi connettori DB25 anzich DB9 e la tabella seguente riporta i pin sui quali si trovano i segnali di interesse:
Pin 1 Pin 2 Pin 3 Pin 4 Pin 5 Pin 6 Pin 7 Pin 8 Pin 20 Pin 22 Protective Ground Transmit data Received data Request To send Clear To Send Data Set Ready Signal Ground Received Line Signal Detector (Data Carrier Detect) Data terminal Ready Ring Indicator
Il cavo di collegamento tra il PC ed il circuito dovr essere intestato a sua volta con un connettore femmina da un lato per poter essere inserito nella seriale del 102 13 - Esempi ed applicazioni pratiche
PC ed un connettore maschio dall'altro per poter essere inserito nel connettore del circuito di prova. I collegamenti interni al cavo da usare sono riportati nella figura 13.7.
Nota Il livello logico 1 su una linea RS232 corrisponde ad una tensione di +12V, mentre il livello 0 corrisponde ad una tensione di -12V.
Nella figura 13.8 sono riportati i segnali in arrivo dalla seriale ed i segnali che arrivano sul pin 18 del PIC (RA1).
103
Per trasmettere un carattere sulla linea TX basta inserire nel registro W il valore da trasmettere ed effettuare una chiamata alla subroutine TxChar. Ipotizzando di voler trasmettere il carattere 'A' al PC il codice da inserire il seguente: movlw call 'A' TxChar
Per ricevere caratteri l'operazione leggermente pi complessa. Si consideri il file sorgente a partire dalletichetta MainLoop: MainLoop btfsc goto call PORTA,RX MainLoop RxChar
Il programma esegue un loop infinito finch non rileva uno stato logico 0 sulla linea RX. Quando questo avviene significa che molto probabilmente arrivato lo START BIT dal PC e che, secondo quanto detto sopra, arriveranno in sequenza i bit appartenenti al dato trasmesso dal PC. In questo caso viene chiamata la RxChar che si occuper di leggere ogni singolo bit ricevuto, compattarli in un unico byte e restituire il valore del byte cos ricevuto nel registro ShiftReg. Una volta lanciata, la RxChar azzera il registro ShiftReg in cui verranno memorizzati i bit via via che vengono ricevuti RxChar clrf ShiftReg
quindi imposta a 8 il registro BitCount usato per il conteggio del numero di bit in arrivo movlw movwf 8 BitCount
a questo punto attende un periodo pari a circa 1 bit e mezzo in modo da far scorrere il tempo necessario alla trasmissione dello start bit e campionare il valore del BIT 0 circa a met del tempo di durata. DELAY BIT_DELAY+BIT_DELAY/2 ;Wait 1.5 bit Viene ora letto lo stato della linea RX ed il valore letto viene inserito nel flag di CARRY (C) del registro STATUS. Una istruzione di ROTATE RIGHT F TROUGHT CARRY (RRF) con il registro ShiftReg consente di spostare verso destra tutti i bit del registro ShiftReg ed inserire nel bit pi significativo il valore appena letto dalla linea RX come riportato nella figura 13.9.
105
D7 D6 D5 D4 D3 D2 D1 D0
Registro f
Figura 13.9: Operazione di RRF su un registro f
Questa lettura avviene per otto volte ad intervalli di tempo pari alla durata di un bit in modo da campionare il valore della linea RX sempre al centro del bit in ricezione. wDB btfss PORTA,RX goto RxBitL RxBitH nop bsf STATUS,C goto RxShift RxBitL bcf STATUS,C goto RxShift RxShift nop rrf ShiftReg,F ; attende per un periodo di tempo pari ad 1 bit DELAY BIT_DELAY La routine RxChar continua a campionare se non ha ancora letto tutti gli otto bit decfsz goto BitCount,F wDB
e termina dopo aver letto l'ultimo bit return Alluscita della RxChar, nel registro ShiftReg c il byte trasmesso dal PC. Il programma ora in grado di controllare se il byte ricevuto un carattere di controllo oppure un normale carattere da visualizzare su LCD. L'unico carattere di controllo ammesso dal programma il Form Feed (FF) corrispondente al codice ASCII decimale 12. Se il programma riconosce tale codice, provvede a ripulire il contenuto dell'LCD. Il form feed pu essere trasmesso dal PC premendo il tasto CTRL seguito dalla lettera L. Ecco la parte di codice che gestisce la ricezione di un Form Feed: 106 13 - Esempi ed applicazioni pratiche
CheckFormFeed movlw xorwf btfss goto clrf clrf call goto 12 ShiftReg,W STATUS,Z _CheckFormFeed xCurPos yCurPos LcdClear MainLoop
_CheckFormFeed in pratica viene controllato se il valore ricevuto dalla subroutine RxChar pari a 12. In caso affermativo vengono azzerati i registri xCurPos e yCurPos che contengono la posizione corrente del cursore sul display. Quindi viene chiamata la subroutine LcdClear che si occupa di inviare i comandi corretti al display LCD per azzerarne il contenuto. Nel caso non sia stato trasmetto un FF dal PC, il carattere ricevuto viene inviato al display con il seguente codice: movf call ShiftReg,W putchar
Quindi torna ad attendere lo START BIT del prossimo carattere con la seguente istruzione: goto MainLoop
La subroutine putchar invia il valore contenuto nel registro W al display LCD nella posizione in cui si trova il cursore carattere (xCurPos e yCurPos), quindi si occupa di mandare il cursore sulla seconda linea se stato raggiunto il fine riga o di riportarlo alla prima riga se si raggiunto il fine display. In ogni caso i registri xCurPos ed yCurPos vengono aggiornati alla posizione successiva in cui poter scrivere il nuovo carattere ricevuto dal PC.
Nel CD allegato Nella cartella \sorgenti trovate il file LCDTERM.ASM utilizzato in questo esempio.
107
Per valutare la trasmissione seriale sia in ricezione che in trasmissione si consideri il circuito di figura 13.10 che permette di controllare laccensione dei led dal PC nonch leggere lo stato degli switch.
108
Quando il PIC riceve questo comando dalla RS232, legge lo stato dei bit RB4, RB5, RB6 ed RB7 ed invia un unico codice al PC che riflette lo stato dei quattro pulsanti. Di questo codice solo i bit 0,1,2,3 indicano lo stato dei pulsanti secondo la seguente tabella.
Bit 0 Bit 1 Bit 2 Bit 3 0 = SWITCH 1 rilasciato, 1 = SWITCH 1 premuto 0 = SWITCH 2 rilasciato, 1 = SWITCH 2 premuto 0 = SWITCH 3 rilasciato, 1 = SWITCH 3 premuto 0 = SWITCH 4 rilasciato, 1 = SWITCH 4 premuto
Per cui se ad esempio solo lo SWITCH 1 risulta chiuso, il codice di risposta 13 - Esempi ed applicazioni pratiche 109
sar 0x01 (00000001 binario). Se risultano premuti sia lo SWITCH 2 che il 4 il codice di risposta 0x0A (00001010 binario).
Nel CD allegato Nella cartella \sorgenti trovate il file rs232io.asm che il file sorgente per la gestione del circuito illustrato in questo esempio.
Programma di prova
Il programma di prova RS232IO.EXE consente di provare il circuito immediatamente. Il programma funziona in ambiente MS/DOS o prompt MS/DOS sotto Win 95/98. Ipotizzando di aver collegato il circuito alla COM2, per accendere il LED 1 sar sufficiente digitare: RS232IO /COM2 /LED1=ON Per spegnere il LED 1 ed accendere il LED 4 digitare: RS232IO /COM2 /LED1=OFF /LED4=ON Per accendere solo il LED 3 senza modificare lo stato degli altri led: RS232IO /COM2 /LED3=ON Per richiedere lo stato corrente dei singoli switch con un unico comando: RS232IO /COM2 /SWITCH Il programma risponder con qualcosa del tipo: Switch Switch Switch Switch 1: 2: 3: 4: off off ---> Active off
110
Nel CD allegato Nella cartella \sorgenti trovate il file simon.asm che il file sorgente dellapplicazione trattata in questo esempio.
112
14 - SET DI ISTRUZIONI
LE ISTRUZIONI SEMPLICI
In questo capitolo verr descritto dettagliatamente il set di istruzioni del PIC16F84A. Ciascuna istruzione una word di 14 bit ed suddivisa in un opcode che specifica lazione da eseguire ed uno o pi operandi coinvolti nelloperazione. Il formato generale per le istruzioni riportato in figura 14.1. Si noti come le istruzioni che agiscono su un intero byte abbiano un opcode di 6 bit ed un bit d di controllo per stabilire se il risultato delloperazione andr nel registro specificato o nellaccumulatore W. Le istruzioni che agiscono su un solo bit hanno un opcode di quattro bit ed utilizzano un campo b di tre bit per determinare quale bit, allinterno del registro specificato, coinvolto nelloperazione (un campo di tre bit consente di ottenere otto combinazioni ciascuna delle quali identifica un bit allinterno del registro specificato).
14 - Set di istruzioni
113
La maggior parte delle istruzioni viene eseguita in un singolo ciclo-istruzione (1 ciclo-istruzione corrisponde a 4 cicli di clock quindi utilizzando ad esempio un quarzo da 4MHz il ciclo-istruzione ha una durata di 1s). Solo alcune istruzioni come le istruzioni di test (ma solo in caso in cui il risultato sia true) o istruzioni che modificano il valore del program counter, richiedono due cicli-istruzione. Nella descrizione delle varie operazioni, verranno usate le seguenti convenzioni:
f b k x d Indirizzo di un registro (0x00 0x7F) Indirizzo di un bit specifico allinterno di un registro (3 bit) Costante o etichetta Valore non rilevante (pu essere indifferentemente 0 o 1) Campo di selezione del destinatario: se d=0 il risultato va in w altrimenti va in un registro (se non specificato si assume d=1) w Registro accumulatore
Nella tabella seguente sono elencate tutte le istruzioni mnemoniche con il loro comportamento ed il numero di cicli-istruzione richiesti per lesecuzione. Si noti che per le istruzioni di test sono indicati uno o due cicli istruzione: come gi detto, i due cicli sono impiegati solo in caso in cui il risultato del test sia true.
Codice mnemonico ADDLW k ADDWF ANDLW ANDWF BCF BSF BTFSC BTFSS CALL CLRF CLRW CLRWDT COMF DECF DECFSZ f,d f,d f,d f,d k f,d f,b f,b f,b f,b k f Cicliistruzione 1 1 1 1 1 1 1 (2) 1 (2) 2 1 1 1 1 1 1 (2)
Descrizione Somma k con W (w = w + k) Somma il contenuto di w con quello di f AND logico tra w e k (w = w AND k) AND logico tra w ed f Azzera un bit di f Porta ad 1 un bit di f Analizza un bit di f e, se a zero, salta una istruzione Analizza un bit di f e, se ad uno, salta una istruzione Chiama la subroutine all'indirizzo k Azzera il registro f Azzera il registro w Azzera il Watchdog Timer Complementa il contenuto di f Decrementa il contenuto di f Decrementa il contenuto di f e, se il risultato zero, salta una istruzione
114
14 - Set di istruzioni
Codice mnemonico GOTO k INCF INCFSZ IORLW IORWF MOVLW MOVF MOVWF NOP RETFIE RETLW RETURN RLF RRF SLEEP SUBLW SUBWF SWAPF XORLW XORWF k f,d f,d k f,d f,d f,d k f,d f,d k f,d k f,d f
Descrizione Salta all'indirizzo k Incrementa il contenuto di f Incrementa il contenuto di f e, se il risultato zero, salta una istruzione OR logico tra w e k (w = w OR k) OR logico tra w ed f Carica in w il valore k (w = k) Sposta il contenuto di f Sposta il contenuto di w nel registro f Nessuna operazione Ritorna da un interrupt handler Ritorna da una subroutine con w = k Ritorna da una subroutine Scorrimento a sinistra del registro f Scorrimento a destra del registro f Mette in standby il PIC Sottrae da k il valore contenuto in w (w = k-w) Sottrae da f il valore contenuto in w Scambia in f i bit 0123 con i bit 4567 OR esclusivo tra w e k (w = w XOR k) OR esclusivo tra w e f
Cicliistruzione 2 1 1 (2) 1 1 1 1 1 1 2 2 2 1 1 1 1 1 1 1 1
Di seguito riportata una descrizione dettagliata di ogni istruzione con il relativo esempio di utilizzo.
ADDLW
Questa istruzione (ADD Literal and W) somma la costante k al valore memorizzato nell'accumulatore W e mette il risultato nell'accumulatore. Sintassi: addlw k
14 - Set di istruzioni
115
Dopo aver eseguito questo programma l'accumulatore W varr 22. Note: Questa istruzione influenza i bit Z, DC e C del registro STATUS: Z vale 1 se il risultato dell'operazione vale 0. DC vale 1 se il risultato dell'operazione un numero superiore a 15. C vale 1 se il risultato positivo ovvero se il bit 7 del registro contenente il risultato vale 0 e 1 se il risultato negativo ovvero se il bit 7 del registro contenente il risultato vale 1.
ADDWF
Questa istruzione (ADD W and F) somma il valore contenuto nell'accumulatore W con il valore contenuto nel registro indirizzato dal parametro f. In base al valore di d, il risultato memorizzato nell'accumulatore W (se d=0) o nello stesso registro f (se d=1). Sintassi: addlw f,d
Operazione equivalente: d = W + f (dove d pu essere W o f) Esempio: add1 equ add2 equ org movlw movwf movlw movwf movf addwf 0CH 0DH 00H 10 ;Primo addendo = 10 add1 15 ;Secondo addendo = 15 add2 add1,W ;W = add1 add2,0 ;W = W + add2
Note: Questa istruzione influenza i bit Z, DC e C del registro STATUS: Z vale 1 se il risultato dell'operazione vale 0. DC vale 1 se il risultato dell'operazione un numero superiore a 15. C vale 1 se il risultato positivo ovvero se il bit 7 del registro contenente il risultato vale 0 e 1 se il risultato negativo ovvero se il bit 7 del registro contenente il risultato vale 1.
ANDWF
Questa istruzione (AND W with F) effettua l'AND logico tra il valore contenuto nell'accumulatore W ed il valore contenuto nel registro indirizzato dal parametro 116 14 - Set di istruzioni
f. In base al valore di d, il risultato memorizzato nell'accumulatore W (se d=0) o nello stesso registro f (se d=1). Sintassi: andwf f,d
Operazione equivalente: d = W AND f (dove d pu essere W o f) Esempio: Spesso l'AND logico viene utilizzato per mascherare il valore di alcuni bit all'interno di un registro. Ad esempio per estrarre dal numero binario 01010101B i quattro bit meno significativi al fine di ottenere il seguente valore 00000101B, basta preparare una maschera del tipo 00001111B e farne l'AND con il valore di partenza: movlw 01010101B all'indirizzo movwf 0CH mascherare movlw 00001111B andwf 0CH,0 ;Memorizza nel registro ;0CH il valore iniziale da ;Prepara la maschera di bit ;Effettua l'AND e memorizza il ;risultato nell'accumulatore W
Il risultato in W sar 00000101B come richiesto. W = 00001111 AND f = 01010101 = --------------W = 0000010101 Note: Questa istruzione influenza il bit Z del registro STATUS: Z vale 1 se il risultato dell'operazione 0.
ANDLW
Questa istruzione (AND Literal and W) effettua l'AND logico tra k ed il valore memorizzato nell'accumulatore W e mette il risultato nell'accumulatore. Sintassi: andlw k
Operazione equivalente: W = W AND k Esempio: org 00H start movlw 0xF4 14 - Set di istruzioni 117
andlw 0x0F ... Dopo aver eseguito questo programma l'accumulatore W varr 0x04. Note: Questa istruzione influenza i bit Z, che vale 1 se il risultato dell'operazione vale 0.
BCF
Questa istruzione (Bit Clear F) azzera il bit b del registro all'indirizzo f. Sintassi: bcf f,b
Operazione equivalente: f(b) = 0 Esempio: parm1 equ 0CH org 00H movlw 11111111B movwf parm1 bcf parm1,0
Al termine del programma il registro parm1 varr 11111110B. Note: Questa istruzione non influenza alcun bit di stato
BSF
Questa istruzione (Bit Set F) mette a uno il bit b del registro all'indirizzo f. Sintassi: bsf f,b
Operazione equivalente: f(b) = 1 Esempio: parm1 equ 0CH org 00H movlw 00000000B movwf parm1 bsf parm1,0
118
14 - Set di istruzioni
BTFSC
Questa istruzione (Bit Test F, Skip if Clear) controlla il bit b contenuto nel registro all'indirizzo f e salta l'istruzione successiva se questo vale 0. Sintassi: btfsc f,b
Operazione equivalente: f(b) = 0 ? Si, salta una istruzione Esempio: parm1 equ 0CH org 00H movlw 11111111B movwf parm1 loop btfsc parm1,0 goto loop
;Valore iniziale
Questa programma esegue un loop infinito. Lo stesso programma non esegue il loop se l'istruzione: movlw 11111111B ;Valore iniziale
BTFSS
Questa istruzione (Bit Test F, Skip if Set) controlla il bit b contenuto nel registro all'indirizzo f e salta l'istruzione successiva se questo vale 1. Sintassi: btfss f,b
Operazione equivalente: f(b) = 1 ? Si, salta una istruzione Esempio: parm1 equ 0CH org 00H movlw 11111110B movwf parm1 14 - Set di istruzioni
;Valore iniziale
119
parm1,0 loop
Questa programma esegue un loop infinito. Lo stesso programma non esegue il loop se l'istruzione: movlw 11111110B ;Valore iniziale
CALL
Questa istruzione (CALL Subroutine) richiama in esecuzione una subroutine memorizzata all'indirizzo k. Il parametro k pu essere specificato utilizzando direttamente il valore numerico dell'indirizzo oppure la relativa label. Sintassi: call Esempio: org call ... 00H ledOn k
;Subroutine di accensione di un led ledOn bsf PORTB,LED1 return Quando la CPU del PIC incontra una istruzione CALL, memorizza nello STACK il valore del registro PC + 1 in modo da poter riprendere l'esecuzione dall'istruzione successiva alla CALL, quindi scrive nel PC l'indirizzo della subroutine iniziando l'esecuzione di quest'ultima. Il valore originale del PC viene ripristinato all'uscita della subroutine con l'esecuzione dell'istruzione di ritorno RETURN o RETLW. Nel PIC16F84A sono disponibili 8 livelli di stack, per cui il numero massimo di CALL annidate, ovvero di istruzioni CALL all'interno di subroutine che a loro volta contengono altre CALL, limitato ad 8 livelli. Note: Questa istruzione non influenza nessun bit di stato.
120
14 - Set di istruzioni
CLRF
Questa istruzione (CLeaR F register) azzera il valore contenuto nel registro indirizzato dal parametro f. Sintassi: clrf f
Operazione equivalente: f = 0 Esempio: Volendo azzerare il registro TMR0 il cui indirizzo 0x01, l'istruzione da eseguire sar: clrf 0x01
Includendo il file P16F84A.INC all'inizio del sorgente, sar possibile utilizzare il nome simbolico del registro TMR0. clrf TMR0
Note: Dopo l'esecuzione di questa istruzione il bit Z del registro STATUS viene messo a 1.
CLRW
Questa istruzione (CLeaR W register) azzera il valore contenuto nel registro W. Sintassi: clrw Operazione equivalente: W = 0 Note: Dopo l''esecuzione di questa istruzione il bit Z del registro STATUS viene messo a 1.
CLRWDT
Questa istruzione (CLeaR WatchDog Timer) deve essere utilizzata quando il PIC viene programmato con l'opzione Watchdog abilitata (fusibile WDTE). In questa modalit il PIC abilita un timer che, una volta trascorso un determinato tempo, effettua il reset del PIC. Per evitare il reset, il programma dovr eseguire ciclicamente l'istruzione CLRWDT per azzerare il timer prima di detto tempo. Se il timer non viene azzerato in tempo, la circuiteria di watchdog (dall'inglese cane da guardia) interpreter questo come un blocco del programma in esecuzione ed effettuer il reset per sbloccarlo. Sintassi: clrwdt
14 - Set di istruzioni
121
loop
COMF
Questa istruzione (COMplement F) effettua il complemento del valore contenuto nel registro indirizzato dal parametro f. In base al valore di d, il risultato memorizzato nell'accumulatore W (se d=0) o nello stesso registro f (se d=1). Sintassi: comf f,d
Operazione equivalente: d = NOT f (dove d pu essere W o f) Esempio: parm1 equ 0CH org 00H movlw 01010101B movwf parm1 comf parm1,1 ... Al termine dell'esecuzione del programma il valore del registro parm1 sar 10101010B. Note: Questa istruzione influenza il bit Z del registro STATUS: Z vale 1 se il risultato dell'operazione vale 0.
DECF
Questa istruzione (DECrement F register) decrementa il contenuto del registro indirizzato dal parametro f. In base al valore di d, il risultato memorizzato nell'accumulatore W (se d=0) o nello stesso registro f (se d=1). Sintassi: decf f,d
Operazione equivalente: d = f -1 (dove d pu essere W o f) Esempio: Con il seguente programma viene scritto il valore 0x23 nel registro 122 14 - Set di istruzioni
all'indirizzo 0CH quindi decrementato di uno. Al termine dell'esecuzione il registro alla locazione 0CH conterr il valore 0x22. movlw movwf decf 23H 0CH OCH,1 ;Scrive in W il valore 23H ;Copia nel registro 0CH il valore di W ;Decrementa il valore contenuto nel ;registro 0CH
Note: Questa istruzione influenza il bit Z del registro STATUS. Z vale 1 se il risultato dell'operazione vale 0.
DECFSZ
Questa istruzione (DECrement F, Skip if Zero) decrementa il valore del registro all'indirizzo f e se il risultato vale zero salta l'istruzione successiva. In base al valore di d, il risultato memorizzato nell'accumulatore W (se d=0) o nello stesso registro f (se d=1). Sintassi: decfsz f,b
Operazione equivalente: d = f -1 (dove d pu essere W o f) se d = 0 salta Esempio: counter equ 0CH org 00H movlw 10 movwf counter loop decfsz counter,1 ... goto loop
;counter = 10
Questo programma esegue per 10 volte l'istruzione decfsz ed esce quando counter = 0. Note: Questa istruzione non influenza alcun bit di stato.
GOTO
Questa istruzione (GO TO address) determina un salto del programma in esecuzione all'indirizzo k. Il parametro k pu essere specificato utilizzando direttamente il valore numerico dell'indirizzo oppure la relativa label. Sintassi: goto 14 - Set di istruzioni k 123
Questo programma esegue un ciclo (loop) infinito. Note: Questa istruzione non influenza alcun bit di stato.
INCF
Questa istruzione (INCrement F) incrementa il contenuto del registro all'indirizzo f. In base al valore di d, il risultato memorizzato nell'accumulatore W (se d=0) o nello stesso registro f (se d=1). Sintassi: incf f,d
Operazione equivalente: d = f +1 (dove d pu essere W o f) Note: Questa istruzione influenza il bit Z del registro STATUS: Z vale 1 se il risultato dell'operazione vale 0.
INCFSZ
Questa istruzione (INCrement F, Skip if Zero) incrementa il valore del registro all'indirizzo f e se il risultato vale zero salta l'istruzione successiva. In base al valore di d, il risultato memorizzato nell'accumulatore W (se d=0) o nello stesso registro f (se d=1). Sintassi: incfsz f,b
Operazione equivalente: d = f +1 (dove d pu essere W o f) se d = 0 salta Esempio: counter equ 0CH org 00H movlw 250 movwf counter loop incfsz counter,1 ... goto loop
;counter = 250
124
14 - Set di istruzioni
Questo programma carica il valore 250 nel registro counter ed esegue per 6 volte l'istruzione incfsz finch esce per counter = 0. Essendo counter un registro a 8 bit quando vale 255 e viene incrementato, assume nuovamente valore 0. Note: Questa istruzione non influenza alcun bit di stato.
IORLW
Questa istruzione (Inclusive OR Literal with W) effettua l'OR tra il valore contenuto nell'accumulatore W ed il valore costante k. Sintassi: iorlw k
Operazione equivalente: W = W OR k Esempio: org start movlw iorlw ... 00H 00001111B 11110000B
Dopo aver eseguito questo programma l'accumulatore W varr 11111111B. Note: Questa istruzione influenza il bit Z del registro STATUS: Z vale 1 se il risultato dell'operazione vale 0.
IORWF
Questa istruzione (Inclusive OR W with F) effettua l'OR tra il valore contenuto nell'accumulatore W ed il valore contenuto nel registro indirizzato dal parametro f. In base al valore di d, il risultato memorizzato nell'accumulatore W (se d=0) o nello stesso registro f (se d=1). Sintassi: iorwf f,d
Operazione equivalente: d = f OR W (dove d pu essere W o f) Esempio: parm1 equ 0CH org 00H movlw 00001111B 14 - Set di istruzioni 125
Al termine dell'esecuzione il valore del registro parm1 sar 11111111B. Note: Questa istruzione influenza il bit Z del registro STATUS: Z vale 1 se il risultato dell'operazione vale 0.
MOVLW
Questa istruzione (MOVe Literal to W) assegna all'accumulatore W il valore costante k. Sintassi: movlw k
Dopo aver eseguito questo programma l'accumulatore W varr 20. Note: Questa istruzione non influenza nessun bit di stato.
MOVF
Questa istruzione (MOVe F) copia il contenuto del registro indirizzato dal parametro f nell'accumulatore W o nello stesso registro f. Il parametro d determina la destinazione: Per d = 0 il valore viene memorizzato nel registro W. Per d = 1 il valore viene lasciato nel registro f. In questo caso l'utilit dell'istruzione sta nel fatto che viene alterato il bit Z del flag STATUS in base al valore contenuto nel registro f. Sintassi: movf f,d
Operazione equivalente: d = f (dove d pu essere W o f) Esempio: L'esempio seguente copia il valore contenuto nel registro all'indirizzo 126 14 - Set di istruzioni
Note: Questa istruzione influenza il bit Z del registro STATUS: Z vale 1 se il risultato dell'operazione vale 0.
MOVWF
Questa istruzione (MOVe W to F) copia il contenuto del registro W nel registro indirizzato dal parametro f. Sintassi: movwf f
Operazione equivalente: f = W Esempio: Per scrivere il valore 10H (esadecimale) nel registro TMR0 le istruzioni da eseguire sono le seguenti. movlw movwf 10H TMR0 ;Scrive nel registro W il valore 10H ;e lo memorizza nel registro TMR0
NOP
Questa istruzione (No OPeration) non esegue alcuna operazione, ma utile per inserire ritardi pari ad un ciclo-istruzione. Sintassi: nop Esempio: Utilizzando un quarzo da 4MHz possibile ottenere un ritardo pari ad 1s per ogni istruzione NOP inserita nel nostro sorgente. nop ;Esegue un ritardo pari ad 1s
RETFIE
Questa istruzione (RET From Interrupt) deve essere inserita al termine di ogni subroutine di gestione degli interrupt per ridare il controllo al programma principale. Sintassi: retfie Esempio: 14 - Set di istruzioni 127
loop 04H
In questo sorgente il programma principale esegue un loop infinito. Allarrivo di un interrupt il controllo verr dato automaticamente al programma allocato dall'indirizzo 04H (nell'esempio intHandler). Listruzione RETFIE determiner quindi il ritorno al loop principale. Note: Questa istruzione non influenza alcun bit di stato.
RETLW
Questa istruzione (RETurn Literal to W) ritorna il controllo da una subroutine al programma principale. A differenza dell'istruzione RETURN essa consente di passare, tramite l'accumulatore W, il valore costante k al programma principale. Sintassi: retlw Esempio: rtc equ org call movwf ... mySub1 nop retlw 0CH 00H mySub1 rtc k
10
Una volta eseguito, questo programma memorizza nel registro rtc il valore 10 passato dalla subroutine mySub1. Note: Questa istruzione non influenza alcun bit di stato (vedi anche l'istruzione RETURN).
RETURN
Questa istruzione (RETURN from subroutine) deve essere inserita al termine di ogni subroutine per riprendere l'esecuzione del programma principale.
128
14 - Set di istruzioni
Sintassi: return Esempio: org 00H call mySub1 ... mySub1 nop return Note: Nel PIC16F84A possono essere annidate fino ad 8 chiamate a subroutine del tipo: org call ... mySub1 call return mySub2 call return mySub3 return 00H mySub1
mySub2
mySub3
Questa istruzione non influenza alcun bit di stato (vedi anche l'istruzione RETLW).
RLF
Questa istruzione (Rotate Left F through carry) ruota i bit contenuti nel registro all'indirizzo f verso sinistra (ovvero dai bit meno significativi verso quelli pi significativi) passando per il bit CARRY del registro STATUS come illustrato in figura:
Il contenuto del bit CARRY del registro status viene spostato nel bit D0 mentre il valore in uscita dal bit D7 viene spostato nel CARRY. Il valore del parametro d determina la destinazione del risultato ottenuto al 14 - Set di istruzioni 129
termine della rotazione: Per d = 0 il risultato viene memorizzato nel registro W lasciando il registro f invariato. Per d = 1 il risultato viene memorizzato nello stesso registro f Sintassi: rlf f,b
Operazione equivalente: d = f << 1 (dove d pu essere W o f) Esempio: parm1 equ 0CH org 00H clrf C,STATUS movlw 01010101B movwf parm1 rlf parm1,1
Al termine del programma il registro parm1 varr 10101010B mentre il CARRY varr 0. Note: Questa istruzione influenza solo il bit CARRY del registro STATUS.
RRF
Questa istruzione (Rotate Right F through carry) ruota i bit contenuti nel registro all'indirizzo f verso destra (ovvero dai bit pi significativi verso quelli meno significativi) passando per il bit CARRY del registro STATUS, come illustrato in figura:
Il contenuto del bit CARRY del registro status viene spostato nel bit D7 mentre il valore in uscita dal bit D0 viene spostato nel CARRY. Il valore del parametro d determina la destinazione del risultato ottenuto al termine della rotazione: Per d = 0 il risultato viene memorizzato nel registro W lasciando il registro f invariato. Per d = 1 il risultato viene memorizzato nello stesso registro f
130
14 - Set di istruzioni
Sintassi: rrf
f,b
Operazione equivalente: d = f >> 1 (dove d pu essere W o f) Esempio: parm1 equ 0CH org 00H clrf C,STATUS movlw 01010101B movwf parm1 rrf parm1,1
Al termine del programma il registro parm1 varr 00101010B mentre il CARRY varr 1. Note: Questa istruzione influenza solo il bit CARRY del registro STATUS.
SLEEP
Questa istruzione (go into standby mode) blocca l'esecuzione del programma in corso e porta il PIC nello stato di standby (sleep dall'inglese to sleep, dormire). Sintassi: sleep Esempio: org start sleep 00H
SUBLW
Questa istruzione (SUBstract W from Literal) sottrae alla costante k il valore memorizzato nell'accumulatore W. Sintassi: sublw k
14 - Set di istruzioni
131
10 12
Dopo aver eseguito questo programma l'accumulatore W varr 2. Note: Questa istruzione influenza i bit Z, DC e C del registro STATUS: Z vale 1 se il risultato dell'operazione vale 0. DC vale 1 se il risultato dell'operazione un numero superiore a 15. C vale 1 se il risultato positivo ovvero se il bit 7 del registro contenente il risultato vale 0 e 1 se il risultato negativo ovvero se il bit 7 del registro contenente il risultato vale 1.
SUBWF
Questa istruzione (SUBstract W from F) sottrae il valore contenuto nel registro W dal valore contenuto nel registro indirizzato dal parametro f. In base al valore di d, il risultato memorizzato nell'accumulatore W (se d=0) o nello stesso registro f (se d=1). Sintassi: subwf f,d
dove REG1 l'indirizzo di un qualsiasi registro specificato con la direttiva: REG1 RES 1
Per valori iniziali di REG1=3 e W=2, dopo l'esecuzione risulta REG1=1 e C=1 in quanto il risultato positivo. Per valori iniziali di REG1=2 e W=2 dopo l'esecuzione risulta REG1=0 e C=1 perch il risultato sempre positivo. Per valori iniziali di REG1=1 e W=2, risulta REG1=FFH (ovvero -1) quindi C=0 perch il risultato negativo. Note: Questa istruzione influenza i bit Z, DC e C del registro STATUS: Z vale 1 se il risultato dell'operazione vale 0. C vale 1 se il risultato positivo ovvero se il bit 7 del registro contenente il risultato vale 0 e 1 se il risultato negativo ovvero se il bit 7 del registro contenente il risultato vale 1.
132
14 - Set di istruzioni
SWAPF
Questa istruzione (SWAP F) scambia il valore del quattro bit pi significativi (D7-D4) contenuti nel registro all'indirizzo f con i quattro bit meno significativi (D3-D0) dello stesso. In base al valore di d, il risultato memorizzato nell'accumulatore W (se d=0) o nello stesso registro f (se d=1). Sintassi: swap f,d
Operazione equivalente: f = Swap dei bit 0123 con 4567 di f Note: Questa istruzione non influenza alcun bit di stato.
XORLW
Questa istruzione (eXclusive OR Literal with W), effettua l'OR esclusivo (XOR) tra il valore contenuto nell'accumulatore W ed il valore costante k. Sintassi: xorlw k
Operazione equivalente: W = W XOR k Esempio: org start movlw xorlw ... 00H 10000000B 11110000B
Dopo aver eseguito questo programma l'accumulatore W varr 01110000B. Note: Questa istruzione influenza il bit Z del registro STATUS: Z vale 1 se il risultato dell'operazione vale 0.
XORWF
Questa istruzione (eXclusive OR W with F) effettua l'OR esclusivo (XOR) tra il valore contenuto nell'accumulatore W ed il valore contenuto nel registro indirizzato dal parametro f. In base al valore di d, il risultato memorizzato nell'accumulatore W (se d=0) o nello stesso registro f (se d=1). Questa istruzione influenza i bit Z del registro STATUS che varr 1 se il risultato dell'operazione 0. Sintassi: xorwf 14 - Set di istruzioni f,d 133
Operazione equivalente: d = f XOR W (dove d pu essere W o f) Esempio: xorwf xorwf COUNTER,F COUNTER,W ;COUNTER = COUNTER XOR W ;W = COUNTER XOR W
Note: L'OR esclusivo (XOR) un'operazione tra due bit in cui il bit risultante vale 0 se i due bit sono uguali. Spesso lo XOR viene utilizzato nell'assembler del PIC per effettuare la comparazione tra due valori in mancanza di un'istruzione specifica. Si supponga di avere un valore nel registro REG1 e di voler verificare se uguale a 57H. Le istruzioni da eseguire sono le seguenti: movlw xorwf btfss 57H REG1,0 STATUS,Z ;W = Valore da comparare = 57H ;Risultato. W = 57H ;W = W XOR REG1 Effettua lo XOR con ; il valore in REG1 ;Salta l'istruzione seguente se il ; risultato dello XOR vale 0, ovvero ; se il valore di REG1 e' pari a 57H ;Salta se diverso da 57H ;Salta se uguale da 57H
goto goto
diverso uguale
134
14 - Set di istruzioni
LE ISTRUZIONI SPECIALI
Per facilitare la programmazione in assembler sono state previste degli speciali codici mnemonici che consentono di rendere il codice molto pi comprensibile. Di seguito vengono descritte tali istruzioni e per ciascuna riportatala lequivalente sequenza di istruzioni semplici.
ADDCF
Esegue la somma del contenuto di un registro con il bit C (Carry) del registro STATUS. In base al valore di d, il risultato memorizzato nell'accumulatore W (se d=0) o nello stesso registro f (se d=1). Questa istruzione influenza i bit Z del registro STATUS che varr 1 se il risultato dell'operazione 0. Sintassi: addcf f,d
ADDDCF
Esegue la somma del contenuto di un registro con il bit DC (Digit Carry) del registro STATUS. In base al valore di d, il risultato memorizzato nell'accumulatore W (se d=0) o nello stesso registro f (se d=1). Questa istruzione influenza i bit Z del registro STATUS che varr 1 se il risultato dell'operazione 0. Sintassi: adddcf f,d
B
Salto incondizionato ad uno specifico indirizzo k. Sintassi: B k k
14 - Set di istruzioni
135
BC
Salto ad uno specifico indirizzo k se il bit C (Carry) del registro STATUS vale 1. Sintassi: BC k
BDC
Salto ad uno specifico indirizzo k se il bit DC (Digit Carry) del registro STATUS vale 1. Sintassi: BDC k
BNC
Salto ad uno specifico indirizzo k se il bit C (Carry) del registro STATUS vale 0. Sintassi: BNC k
BNDC
Salto ad uno specifico indirizzo k se il bit DC (Digit Carry) del registro STATUS vale 0. Sintassi: BNDC k
BNZ
Salto ad uno specifico indirizzo k se il bit Z (Zero flag) del registro STATUS vale 0. Sintassi: BNZ k
BZ
Salto ad uno specifico indirizzo k se il bit Z (Zero flag) del registro STATUS vale 1. Sintassi: BZ k
CLRC
Azzera il bit C (Carry) del registro STATUS. Sintassi: clrc Sequenza equivalente: bcf STATUS,C
CLRDC
Azzera il bit DC (Digit Carry) del registro STATUS. Sintassi: clrdc Sequenza equivalente: bcf STATUS,DC
CLRZ
Azzera il bit Z (Zero flag) del registro STATUS. Sintassi: clrz Sequenza equivalente: bcf
STATUS,Z
14 - Set di istruzioni
137
MOVFW
Sposta in w il contenuto del registro f. Questa istruzione influenza i bit Z del registro STATUS che varr 1 se il risultato dell'operazione 0. Sintassi: movfw f f,0
NEGF
Esegue loperazione di negazione (NOT) sul registro f. Questa istruzione influenza i bit Z del registro STATUS che varr 1 se il risultato dell'operazione 0. Sintassi: negf f,d
SETC
Mette ad 1 il bit C (Carry) del registro STATUS. Sintassi: setc Sequenza equivalente: bsf STATUS,C
SETDC
Mette ad 1 il bit DC (Digit Carry) del registro STATUS. Sintassi: setdc Sequenza equivalente: bsf STATUS,DC
SETZ
Mette ad 1 il bit Z (Zero flag) del registro STATUS. Sintassi: setz Sequenza equivalente: bsf 138 STATUS,Z 14 - Set di istruzioni
SKPC
Controlla il bit C (Carry) del registro STATUS e se ad 1 salta una istruzione. Sintassi: skpc Sequenza equivalente: btfss STATUS,C
SKPDC
Controlla il bit DC (Digit Carry) del registro STATUS e se ad 1 salta una istruzione. Sintassi: skpdc Sequenza equivalente: btfss STATUS,DC
SKPNC
Controlla il bit C (Carry) del registro STATUS e se a 0 salta una istruzione. Sintassi: skpnc Sequenza equivalente: btfsc STATUS,C
SKPNDC
Controlla il bit DC (Digit Carry) del registro STATUS e se a 0 salta una istruzione. Sintassi: skpndc Sequenza equivalente: btfsc STATUS,DC
SKPNZ
Controlla il bit Z (Zero flag) del registro STATUS e se a 0 salta una istruzione. Sintassi: skpnz Sequenza equivalente: btfsc STATUS,Z
SKPZ
Controlla il bit Z (Zero flag) del registro STATUS e se ad 1 salta una istruzione. 14 - Set di istruzioni 139
SUBCF
Sottrae dal registro f il bit C (Carry) del registro STATUS. In base al valore di d, il risultato memorizzato nell'accumulatore W (se d=0) o nello stesso registro f (se d=1). Questa istruzione influenza i bit Z del registro STATUS che varr 1 se il risultato dell'operazione 0. Sintassi: subcf f,d
SUBDCF
Sottrae dal registro f il bit DC (Digit Carry) del registro STATUS. In base al valore di d, il risultato memorizzato nell'accumulatore W (se d=0) o nello stesso registro f (se d=1). Questa istruzione influenza i bit Z del registro STATUS che varr 1 se il risultato dell'operazione 0. Sintassi: subdcf f,d
TSTF
Controlla il contenuto del registro f e, se zero, mette ad uno il bit Z (Zero flag) del registro STATUS. Sintassi: tstf f f,1
140
14 - Set di istruzioni
Le direttive sono dei particolari comandi, utilizzabili all'interno del file sorgente, finalizzati a condizionare il funzionamento dell'assemblatore durante la compilazione. Contrariamente a quanto avviene per le istruzioni assembler, le direttive non sono tradotte in codici operativi per il micro quindi, nel file compilato, non ne rimane alcuna traccia.
CBLOCK
Questa direttiva consente di definire un blocco di costanti. Ciascuna costante contrassegnata da una label e, se non viene specificato il parametro increment, a ciascuna label assegnato un valore (indirizzo) che si incrementa di uno per ciascuna label specificata. Se viene specificato il parametro increment per una label, la label successiva sar associata ad un indirizzo maggiore della precedente per una differenza pari al valore increment. Un blocco di costanti deve essere chiuso con la direttiva ENDC. Sintassi: cblock [<expr>] <label>[:increment][,<label>[:increment]] endc Esempio: cblock ;alletichetta nome_1 sar assegnato ; il valore 0x20 nome_1, nome_2 ;a nome_2 il valore 21 nome_3:2, nome_4 ;a nome_3 il valore 22 e a nome_4 il ;valore 24 endc 0x20
__CONFIG
Con questa direttiva possibile definire il valore da memorizzare nella word di configurazione. Prima di utilizzare questa direttiva occorre aver specificato nel sorgente con la direttiva LIST quale PICmicro viene utilizzato. Le differenti 15 - Direttive dell'assembler MPASM 141
famiglie di PICmicro hanno la word di configurazione implementate su indirizzi diversi. Nel PIC16F84A l'indirizzo 0x2007. E' necessario inoltre verificare che il programmatore di PICmicro utilizzato sia in grado di leggere il valore della word di configurazione dal file .HEX e di scriverlo correttamente nella giusta locazione del PICmicro. Questa funzione non sempre disponibile specialmente nei programmatori di basso costo, per cui in questi casi perfettamente inutile usare la direttiva __CONFIG all'interno del sorgente, ma occorre agire direttamente sui comandi messi a disposizione dal programmatore specifico. Sintassi: __CONFIG <expr> Esempio: nella figura 15.1 riportata la struttura della word di configurazione del PIC16F84A estratta dal datasheet Microchip.
Si supponga di voler programmare il PICmicro con la protezione del codice disabilitata (CP=1), il Power-up timer abilitato (PWRTE=0), il Watch dog disabilitato (WDTE=0) e l'oscillatore settato in modo XT (FOSC1=0, FOSC0=1). La word di configurazione dovr essere programmata con il seguente valore binario: 11111111110001 per cui la direttiva da utilizzare sar __CONFIG 11111111110001B oppure l'equivalente esadecimale __CONFIG 0x3FF1. Il sorgente al completo sar: PROCESSOR 142 16F84A 15 - Direttive dell'assembler MPASM
__CONFIG
0x3FF1
; Inserire qui il programma END L'assemblatore genera il seguente file .HEX: :02400E00F13F80 :00000001FF dove: :02400E00F13F80 :00000001FF l'indirizzo dove si trova la configuration word nel PIC16F84A pari a 400E / 2 = 2007. L'indirizzo deve essere diviso in due perch il formato .HEX a 8 bit prevede l'uso di indirizzi orientati al byte. :02400E00F13F80 :00000001FF il valore che verr programmato nella locazione 2007 hex. Il valore deve essere letto con i due byte invertiti, ovvero 3FF1 che corrisponde esattamente a quanto stato inserito nel file sorgente.
DT
Questa direttiva consente di definire una tabella di valori. In fase di compilazione viene tradotta in una serie di istruzioni RETLW, una per ciascun parametro <expr> specificato. <expr> deve essere un valore ad 8 bit quindi, se si specifica una stringa di caratteri, si generano tante istruzioni RETLW una per ciascun carattere. Sintassi: [<label>] dt <expr> [,<expr>,,<expr>] Esempio: dt dt pippo,0 0x03, 0xF5
Queste due righe, in fase di compilazione, verranno tradotte nelle seguenti istruzioni: retlw retlw retlw p i p 143
p o 0 0x03 0xF5
#DEFINE
Questa direttiva consente di definire una stringa da sostituire ad un testo specifico durante la fase di compilazione. In particolare, in fase di compilazione, ogni volta che viene incontrata la stringa <nome>, questa verr automaticamente sostituita con <string>. Sintassi: #define <name> [<string>] Esempio: #define bcf uscita0 0x06,0 uscita0
EQU
Definisce una costante assegnando il valore <expr> a <label>. Sintassi: <label> equ <expr> Esempio: sei equ 6
ERRORLEVEL
Consente di impostare i tipi di messaggi che verranno visualizzati nei file .lst e .err prodotti dopo la fase di compilazione. Sintassi: errorlevel {0|1|2|+<msgnum>|-<msgnum>} [, ]
144
Note: I numeri 0,1 e 2 definiscono il tipo di avvisi in accordo alla seguente tabella:
Valore Avvisi abilitati 0 1 2 Messaggi, Warnings ed errori Warnings ed errori Errori
msgnum consente di abilitare (+) o disabilitare (-) un avviso specifico. Ciascun avviso infatti codificato con un numero di tre cifre. Di seguito sono riportati alcuni avvisi con il relativo codice.
Codice Avviso 102 105 113 114 115 128 132 136 203 207 225 302 307 313 Error: Out of Memory Error:Cannot open file Error:Symbol not previously defined Error:Divide by zero Error:Duplicate label Error:Missing arguments Error:Unknow processor Error:Duplicate macro name Warning: Found opcode in column 1 Warning: Found label after column 1 Warning: invalid label in operand Message: Register in operand not in bank 0 Message: Setting page bits Message: CBLOCK constants will starts with value of 0
Si noti che il codice degli errori inizia per 1, quello dei warnings per 2, mentre quello dei messaggi per 3.
Nel CD allegato Nella cartella \Documentazione trovate il file mpasm.pdf. questo il manuale dellassembler Microchip in cui si trova la lista completa dei codici degli avvisi.
EXTERN
una direttiva utilizzata quando un progetto composto da pi file. Consente di usare unetichetta definita in altri file come GLOBAL (si veda la direttiva GLOBAL).
145
[, <label>]
extern funz ;la label funz esterna al file call funz ;riferimento alla label esterna
GLOBAL
una direttiva utilizzata quando un progetto composto da pi file. Consente di definire unetichetta che pu essere utilizzata anche in altri file come EXTERN (si veda la direttiva EXTERN). Sintassi: global <label> Esempio: var1 res 1 var2 res 1 global var1, var2 ;var1 e var2 sono visibili anche ;esternamente al file [, <label>]
IF
una direttiva che consente di decidere se compilare o meno una determinata parte di codice in funzione del valore assunto dallespressione <expr>. In particolare se <expr> vale 0 (false) il codice successivo verr ignorato. Il codice ignorato delimitato da una direttiva ELSE o ENDIF. Se <expr> diversa da zero (true) il codice successivo viene invece regolarmente compilato. Sintassi: if <expr> Esempio: if version==100 movlw 0x01 else movlw 0x0F endif
146
In questo esempio se version vale 100 viene compilata la linea di codice movlw 0x01, altrimenti viene compilata la linea movlw 0x0F. Si noti che con questa direttiva possibile discriminare sezioni di codice a livello di compilazione e non di esecuzione. Nel caso dellesempio se version vale 100 listruzione movlw 0x0F non sar fisicamente presente nel file compilato.
IFDEF
simile alla direttiva IF con lunica differenza che IFDEF permette solamente di controllare se una certa etichetta stata precedentemente definita usando la #DEFINE (o mediante linea di comando allinvocazione del compilatore). Come per la IF, la sezione di codice successiva delimitata da una direttiva ELSE o ENDIF, viene esclusa dalla compilazione se letichetta specificata nella direttiva IFDEF non stata precedentemente definita. Sintassi: ifdef <label>
INCLUDE
Permette di inserire un file sorgente esterno prima di procedere con la compilazione. Sono permesse fino a sei inclusioni annidate (inclusioni di file che a loro volta includono altri file). Il file da includere pu essere specificato tra una coppia di parentesi acute o tra virgolette. Nel primo caso il file sar cercato in percorsi predefiniti nel seguente ordine: cartella di lavoro corrente, cartella in cui si trova il file sorgente, cartella che contiene il file eseguibile del compilatore. Se invece il file viene specificato tra virgolette necessario specificare anche il percorso completo per raggiungere il file. Sintassi: include <<file>> include <file>
Esempio: ;il file pippo.inc verr cercato in C:\PIC\PROVE include C:\PIC\PROVE\pippo.inc ;il file pippo.inc viene cercato nelle directory ;predefinite include <pippo.inc>
147
ORG
Definisce un indirizzo della memoria del PIC a partire dal quale verr allocato il codice successivo. Se viene specificata letichetta <label> il valore dellindirizzo specificato viene associato alletichetta. Sintassi: Esempio: val1 org 0x20 ;il codice inserito in questo punto viene allocato ;a partire dallindirizzo 0x20 val2 org val1+0x10 ;il codice inserito in questo punto viene allocato ;a partire dallindirizzo 0x30 <label> ORG <expr>
RES
Permette di riservare un certo numero di locazioni di memoria a partire dalla locazione corrente che pu essere etichettata con la <label> qualora essa venga specificata. Sintassi: Esempio: buffer res 16 A partire dallindirizzo corrente (associato alletichetta buffer) vengono riservate 16 locazioni di memoria. In altri termini buffer una variabile di 16 byte. [<label>] res <numero_locazioni>
MACRO
La direttiva MACRO una delle pi interessanti messe a disposizione dall'assembler MPASM. Essa consente di associare una label (etichetta) ad una sequenza di istruzioni assembler in modo da poterla inserire, in fase di compilazione, semplicemente specificando la label di riferimento. Sintassi: <label> macro [<arg>, ..., <arg>]
Esempio: Si supponga di dover mettere a zero le linee RB0, RB1 ed RB2 in 148 15 - Direttive dell'assembler MPASM
diversi punti del programma. Ogni volta che necessario compiere questa operazione dovranno essere inserite le seguenti istruzioni all'interno del sorgente: bcf bcf bcf PORTB,0 PORTB,1 PORTB,2
Con la direttiva MACRO possibile definire una "nuova istruzione" (una macro) per definire l'insieme delle tre istruzioni assembler con un'unica etichetta. All'inizio del sorgente sar sufficiente scrivere: AZZERA bcf bcf bcf ENDM MACRO PORTB,0 PORTB,1 PORTB,2
Ogni volta che si presenta la necessit di inserire le tre istruzioni, baster scrivere semplicemente: AZZERA Sar compito dellassemblatore espandere la label AZZERA nelle tre istruzioni corrispondenti. Con le macro possibile anche specificare dei parametri. Si supponga ad esempio che le linee da azzerare non siano sempre le stesse, ma cambino di volta in volta. In questo caso la macro sar la seguente: AZZERA bcf bcf bcf ENDM MACRO LINEA1, LINEA2, LINEA3 PORTB,LINEA1 PORTB,LINEA2 PORTB,LINEA3
quindi ogni volta che la macro viene richiamata, si devono specificare quali linee devono essere azzerate: AZZERA 0,1,2
per azzerare RB3, RB5 ed RB7. Una macro concettualmente diversa dall'istruzione CALL che agisce a livello di esecuzione del codice e che determina il richiamo di un gruppo di istruzioni 15 - Direttive dell'assembler MPASM 149
all'interno dell'area programma del PICmicro. Le chiamate alle MACRO vengono risolte a livello di compilazione ad opera dell'MPASM che si occupa semplicemente di sostituire di volta in volta l'etichetta della MACRO con le istruzioni corrispondenti. Questo comporta una replica nella memoria programma delle istruzioni ogni volta che la macro viene specificata nel sorgente. Per funzioni complesse e nel caso sia necessario ottimizzare lo spazio occupato dal programma, sempre meglio ricorrere alle subroutine (vedi istruzione CALL) piuttosto che alle MACRO.
PROCESSOR
Questa direttiva consente di specificare il tipo di PICmicro utilizzato. Sintassi: processor <processor_type> Esempio: processor 12F675
RADIX
Definisce la radice predefinita per le espressioni numeriche. Se non specificato, la radice predefinita esadecimale. Il parametro <default_radix> pu valere: hex (esadecimale) dec (decimale) oct. (ottale) Sintassi: radix <default_radix> Esempio: radix dec
Nel CD allegato Nella cartella \Documentazione trovate il file mpasm.pdf. questo il manuale dellassembler Microchip in cui si trova la lista completa delle direttive del compilatore.
150
La programmazione ICSP (In-Circuit Serial Programming) implementata da Microchip per la programmazione di alcune famiglie di PIC, consente di programmare i chip direttamente sulla scheda destinazione riducendo i tempi di sviluppo/produzione di schede basate sui PIC. In queste pagine viene data una breve introduzione alla programmazione ICSP per i PIC16x84. Tutta la documentazione necessaria per programmare altre famiglie di PIC disponibile sul CD allegato al testo. La programmazione ICSP viene effettuata tramite tre soli collegamenti (oltre al terminale comune) tra il programmatore ed il PIC da programmare ovvero:
Piedino di master clear (pin 4 su PIC16x84) utilizzato per applicare la tensione di programmazione VPP al chip. Linea 6 della porta B (pin 12 su PIC16x84) utilizzata come linea CLOCK. Linea 7 della porta B (pin 13 su PIC16x84) utilizzata come linea DATA.
La modalit di comunicazione con il PIC di tipo seriale sincrono in cui i bit trasmessi sulla linea DATA (pin RB7) vengono scanditi dal segnale generato sulla linea di CLOCK (pin RB6). Questultimo viene generato dal programmatore mentre il flusso sulla linea DATA bidirezionale a seconda delloperazione in corso. Nella seguente figura viene riportato un esempio di trasmissione di un comando dal programmatore al PIC.
Tutte le operazioni sul PIC da programmare devono essere precedute dallinvio di un comando da parte del programmatore per comunicare al PIC loperazione che si intende eseguire. La lunghezza dei comandi sempre di 6 bit A - La programmazione ICSP dei PICmicro 151
eventualmente seguiti dalla trasmissione di 14 bit contenenti il valore che dovr essere scritto. Nella seguente tabella viene riportato lelenco dei comandi riconosciuti dai PIC16x84:
Comando dal programmatore Load Configuration Load Data for Program Memory Read Data from Program Memory Increment Address Begin Programming Load Data for Data Memory Read Data from Data Memory Bulk Erase Program Memory Bulk Erase Data Memory Codice Descrizione comando 000000 Invia al PIC il prossimo dato da scrivere in memoria programma. Al codice comando segue immediatamente il dato da memorizzare. Invia al PIC il prossimo dato da scrivere in memoria dati. Al codice comando segue immediatamente il dato da memorizzare. Legge dal PIC la locazione corrente dallarea programma. Appena riceve questo comando il PIC trasmette al programmatore il valore letto. Incrementa il puntatore alla locazione corrente nella memoria dati/configurazione/programma. Programma la locazione corrente. Invia al PIC il prossimo valore da scrivere in memoria dati. Al codice comando segue immediatamente il dato da memorizzare. Legge dal PIC la locazione corrente dalla memoria dati. Appena riceve questo comando il PIC trasmette al programmatore il valore letto. Cancella lintera memoria programma Cancella lintera memoria dati
000010
Il PIC16x84 dispone internamente di tre aree di memoria distinte programmabili dallesterno: larea programma (1024 byte), larea dati pari (64 byte) e larea configurazione (8 byte). Tutte le aree di memoria sono implementate su FLASH. Le sole aree di programma e dati possono essere lette dallesterno. Per poter scrivere in una qualsiasi locazione, il programmatore deve inviare al PIC uno dei comandi LOAD seguito da 14 bit contenenti il dato da memorizzare. Volendo ad esempio scrivere nella locazione 0 della memoria programma dovr essere inviata al PIC la sequenza: Load Data for Program Memory + valore a 14 bit Begin Programming Il comando Load Data trasferisce semplicemente il dato a 14 bit in un buffer provvisorio allinterno del PIC, il comando Begin Programming effettua la scrittura vera e propria del dato nella memoria programma. Lindirizzo della locazione di memoria che viene scritta contenuto in un puntatore di scrittura 152 A - La programmazione ICSP dei PICmicro
azzerato automaticamente non appena il PIC viene messo in programmazione (MCLR=12V) ed incrementato tramite il comando: Increment Address Per programmare la locazione successiva baster trasmettere nuovamente i seguenti comandi: Load Data for Program Memory + valore locazione 1 Begin Programming Increment Address e cos via fino alla scrittura completa del programma. Per poter scrivere in una locazione di memoria non necessario effettuare operazioni di cancellazione. Larea dati e larea configurazione vengono programmate con le stesse modalit utilizzando il relativo comando LOAD. Larea dati unarea FLASH visibile anche dal programma in esecuzione sul PIC e la sua programmazione pu essere utile per assegnare dei valori iniziali alle variabili utilizzate dal programma. Larea configurazione contiene dati invisibili al programma su PIC, ma utili per determinare la modalit di funzionamento di alcuni dispositivi interni al PIC quali loscillatore di clock, il watchdog timer, ecc.
Nel CD allegato Nella cartella \ICSP trovate tutta la documentazione relativa alla tecnica ICSP.
153
B - TABELLE
Nelle pagine che seguono sono riportate due tabelle ritenute utili in fase di sviluppo di applicazioni impieganti microcontrollori. In particolare riportata la tabella dei codici ASCII in cui per ciascun carattere illustrata la corrispondente codifica ASCII sia in forma binaria che esadecimale. La tabella successiva, invece, riporta la conversione da decimale a binario ed esadecimale dei numeri da 0 a 127.
B - Tabelle
155
156
B - Tabelle
HEX 72 73 74 75 76
CHAR r s t u v
HEX 77 78 79 7A 7B
HEX 7C 7D 7E 7F
CHAR | } ~ DEL
B - Tabelle
157
HEX 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66
BIN 01011010 01011011 01011100 01011101 01011110 01011111 01100000 01100001 01100010 01100011 01100100 01100101 01100110
HEX 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73
BIN 01100111 01101000 01101001 01101010 01101011 01101100 01101101 01101110 01101111 01110000 01110001 01110010 01110011
DEC 103 104 105 106 107 108 109 110 111 112 113 114 115
HEX 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F -
BIN 01110100 01110101 01110110 01110111 01111000 01111001 01111010 01111011 01111100 01111101 01111110 01111111 -
DEC 116 117 118 119 120 121 122 123 124 125 126 127 -
158
B - Tabelle
.ASM file
File sorgente in formato testo contenente le istruzioni assembler che costituiscono il programma e le direttive del compilatore.
del
Interrupt
Meccanismo che consente linterruzione dellesecuzione del programma principale al verificarsi di particolari eventi, esterni o interni, al micro.
.ERR file
File prodotto dopo la fase di compilazione di un progetto. Questo file contiene eventuali avvisi e messaggi di errore generati in fase di compilazione.
Macro
Un insieme di istruzioni assembler che vengono incluse nel file sorgente prima della compilazione. Ogni macro identificata da una etichetta in corrispondenza della quale il compilatore inserisce le relative istruzioni prima di procedere con la compilazione.
.HEX file
File ottenuto in seguito alla fase di compilazione e pronto per essere scaricato nella memoria programma del micro.
.LST file
File di testo ottenuto dopo la fase di compilazione contenente il codice macchina generato per ciascuna istruzione assembler.
Microcontroller
Chip programmabile dotato dei dispositivi di base per poter memorizzare un programma (memoria EPROM o EEPROM), per poter memorizzare dati e valori (memoria RAM), eseguire funzioni di input/output (linee di I/O, porte seriali, ecc.) e altre funzioni di ausilio (generatore di clock, contatori, ecc.). Il Microcontroller si distingue dal Microprocessore proprio per la presenza di dispositivi ausiliari all'interno dello stesso chip che contiene la CPU.
CPU
Acronimo di Central Process Unit (unit centrale di processo) la componente che in un sistema a microprocessore esegue le istruzioni di programma.
ICSP
Acronimo di Programming. In-Circuit Tecnologia Serial che
159
OPCODE
L'OPerative CODE (dall'inglese codice operativo) il valore numerico che identifica univocamente una istruzione del PIC. La maggior parte delle istruzioni richiede dei parametri per cui lopcode risulta essere una parte della stringa di bit che costituisce il codice dellistruzione. Ad esempio per azzerare il Register File all'indirizzo 0x0C, il codice sar: 00 0001 1000 1100 dove la parte in grassetto lopcode che identifica l'istruzione, mentre i restanti bit costituiscono il parametro da utilizzare con l'istruzione che in questo caso l'indirizzo del registro (000 1100 = 0x0C).
Operazioni booleane
Le booleane sono operazioni logiche tra numeri binari utili in programmazione per lavorare sui bit contenuti nei registri dei PIC. Di seguito sono elencate alcune operazioni elementari.
AND
L'AND tra due bit segue la seguente tavola della verit: 0 0 1 1 AND AND AND AND 0 1 0 1 = = = = 0 0 0 1
Se uno dei due fattori vale 0 anche il risultato sar pari a 0. L'AND tra due registri viene effettuato a coppia tra i bit che occupano la stessa posizione come riportato nell'esempio seguente:
160
NOT
Il NOT consiste nella semplice negazione del valore di un bit. Se un bit vale 0 il suo NOT sar 1 e viceversa. NOT 0 = 1 NOT 1 = 0 Il NOT di un registro viene effettuato negando i singoli bit come riportato nell'esempio seguente: 01010101 NOT = -------------10101010
OR
L'OR, o OR inclusivo, tra due bit segue la seguente tavola della verit: 0 0 1 1 OR OR OR OR 0 1 0 1 = = = = 0 1 1 1
Se uno dei due bit vale 1 anche il risultato sar pari a 1. L'OR tra due registri viene effettuato a coppia tra i bit che occupano la stessa posizione come riportato nell'esempio seguente: 01010101 OR 11110000 = ----------11110101
RAM
un tipo di memoria in grado di mantenere i dati in essa memorizzati finch rimane alimentata. L'accesso all'interno di una memoria RAM pu essere effettuato sia in lettura che scrittura ad una qualsiasi locazione di memoria specificando l'indirizzo della locazione che si desidera raggiungere. Data l'estrema facilit di scrittura e lettura di una RAM essa viene normalmente utilizzata in un sistema a microprocessore per memorizzare i dati di lavoro generati dinamicamente dal programma in esecuzione (variabili, array, ecc.). L'acronimo RAM sta per Random Access Memory ovvero memoria ad accesso casuale.
XOR
Lo XOR (OR esclusivo) tra due bit segue la seguente tavola della verit: 0 0 1 1 XOR XOR XOR XOR 0 1 0 1 = = = = 0 1 1 0
Se i due bit sono uguali il risultato vale 0 in caso contrario vale 1. Lo XOR tra due registri viene effettuato a coppia tra i bit che occupano la stessa posizione come riportato nell'esempio seguente: 01010101 XOR 11110000 = -----------10100101
RESET
Con il termine reset si intende l'operazione di azzeramento e riavvio del programma in esecuzione e di tutti i dispositivi interni al PIC. Al reset il programma in esecuzione viene immediatamente interrotto, tutti i 161
File Register interni reinizializzati e il programma riattivato in esecuzione a partire dal Reset Vector, ovvero dall'istruzione memorizzata nella locazione 0x0000 (nel PIC16F84A).
EEPROM
Electrical Erasable Programmable Read Only Memory (memoria a sola lettura programmabile, cancellabile elettricamente). una memoria EPROM che pu essere cancellata elettricamente senza l'ausilio di lampade UV.
FLASH
Molto simile alla EEPROM, una memoria che pu essere cancellabile e modificabile elettricamente senza l'ausilio di lampade UV.
SUBROUTINE
un insieme di istruzioni chiamate pi volte all'interno di un programma. Tipicamente una subroutine viene inserita in un programma sia per separare logicamente la funzione dal resto del sorgente sia per risparmiare spazio in memoria scrivendo una sola volta il gruppo di istruzioni necessarie. La struttura di base di una subroutine la seguente: Label istruzione 1 istruzione 2 ... istruzione n return Label un nome simbolico da subroutine che potr essere utilizzato all'interno del sorgente per richiamarla tramite una istruzione CALL. L'istruzione return deve essere sempre inserita alla fine di una subroutine in modo tale che la CPU possa riprendere l'esecuzione del programma dall'istruzione successiva alla call. C - Glossario dei termini utilizzati
ROM
Read Only Memory (memoria a sola lettura) una memoria gi programmata che non pu pi essere modificata o cancellata.
PROM
Programmable Read Only Memory (memoria a sola lettura programmabile). una memoria ROM non ancora programmata. La programmazione pu essere effettuata tramite una apparecchiatura specializzata denominata programmatore di PROM.
EPROM
Erasable Programmable Read Only Memory (memoria a sola lettura programmabile, cancellabile). una memoria PROM che pu essere cancellata se esposta alla luce di una lampada ad ultravioletti. Per questo motivo i dispositivi dotati di EPROM hanno una finestra trasparente da cui possibile far raggiungere il chip interno al dispositivo dai raggi UV. 162
In questa sezione sono riportate alcune routine utili che possono essere usate allinterno di programmi pi complessi. Vengono descritti i parametri di ingresso e il registro (o i registri) in cui viene lasciato leventuale risultato senza scendere nellanalisi approfondita del codice. I file sorgente di ciascuna routine presente nel CD allegato.
; moltiplicazione di w per 10 movwf result1 bcf STATUS, C rlf result1, f movf result1, w rlf result1, f rlf result1, f addwf result1, w addwf result0, w return ;vengono aggiunte le unit 163
movlw 10 bin2dec999a addwf Asc0, f decf Asc1, f skpc goto bin2dec999a bin2dec999b addwf Asc1, f 164 D - Routine Assembler di varia utilit
Asc2, f bin2dec999b
bin2dec999c addwf Asc2, f skpc goto bin2dec999c movlw addwf addwf addwf return 0x30 Asc2, f Asc1, f Asc0, f
165
166
f f f f
167
DIVIDE_LOOP_48by23 rlf Dividend + rlf Dividend + rlf Dividend + rlf Dividend + rlf Dividend + 168
5, 4, 3, 2, 1,
rlf rlf rlf rlf movf btfss goto subwf movf skpc incfsz subwf movf skpc incfsz subwf goto
Dividend, f Temp + 2, f Temp + 1, f Temp, f Divisor + 2, w Dividend + 5, 0 Div48by23_add Temp + 2, f Divisor + 1, w Divisor + 1, w Temp + 1, f Divisor, w Divisor, w Temp, f DIVIDE_SKIP_48by23
Div48by23_add addwf Temp + 2, movf Divisor + btfsc STATUS, C incfsz Divisor + addwf Temp + 1, movf btfsc incfsz addwf
f 1, w 1, w f
DIVIDE_SKIP_48by23 decfsz BitCount, f goto DIVIDE_LOOP_48by23 rlf Dividend + 5, f rlf Dividend + 4, f rlf Dividend + 3, f rlf Dividend + 2, f rlf Dividend + 1, f rlf Dividend, f retlw 1 D - Routine Assembler di varia utilit 169
Correctie_af movlw D'60' subwf Secondi, w btfss STATUS, Z goto SecTest_af clrf Secondi incf Minuti, f movlw D'6' movwf TimerL movlw D'60' subwf Minuti, w btfss STATUS, Z goto SecTest_af clrf Minuti incf Ore, f movlw D'24' subwf Ore, w btfss STATUS, Z goto SecTest_af clrf Ore SecTest_af swapf STATUS_TEMP, w movwf STATUS swapf W_TEMP, f swapf W_TEMP, w bsf INTCON, T0IE retfie
171
DISCRIMINAZIONE DI UN INTERRUPT
Questo frammento di codice pu essere inserito in corrispondenza dellinterrupt vector (0x04 per il PIC16F84A) e consente di determinare levento che ha scatenato linterruzione. Viene eseguito prima di tutto un salvataggio del contesto, quindi vengono analizzati i vari flag per capire quale evento ha scatenato linterruzione. Le istruzioni goto rimandano alle varie sezioni di codice atte alla gestione dello specifico evento. ;***************************************************** ;* Riconoscimento Interrupt ;***************************************************** ServiceInterrupt movwf W_TEMP ;Copia W in W_TEMP swapf STATUS, w movwf STATUS_TEMP ;Salva STATUS in STATUS_TEMP btfsc INTCON, RBIF ;Cambio di stato sulla PORTB? goto ServizioRB ;si, gestisci linterruzione btfsc INTCON, T0IF ;Interrupt da Timer0? goto ServizioTimer ;si, gestisci linterruzione btfsc INTCON, INTF ;Interrupt esterno? Goto ServizioExt ;si, gestisci linterruzione Goto ServizioEE ;linterruzione di fine ;scrittura su eeprom
Nel CD allegato Nella cartella \sorgenti\utility trovate i file relativi alle routines illustrate.
172
E - IL CONTENUTO DEL CD
LINTERFACCIA GRAFICA
Il CD allegato al presente volume compatibile con tutti i sistemi operativi Windows e richiede un processore Pentium o superiore con almeno 32Mb di RAM. Se il CD non si avvia automaticamente allinserimento, possibile lanciare il menu di navigazione avviando il file start.exe situato nella directory principale del CD. Allavvio linterfaccia grafica si presenta come in figura e, mediante il menu di navigazione sulla sinistra, possibile accedere alle varie sezioni del CD.
La documentazione in formato pdf e per la sua visualizzazione necessario il software Acrobat Reader che pu essere installato cliccando sulla apposita icona ai piedi del menu di navigazione.
E - Il contenuto del CD
173
I CONTENUTI
Tutta la documentazione situata nella cartella \documentazione e contiene: Il datasheet del PIC16F84A. La guida al compilatore assembler MPASM. Microchip Line Card. Datasheet del MAX232. Il software contenuto nella cartella \software che contiene: MPLAB: la versione 7.00 dellambiente di sviluppo MPLAB di Microchip. Lambiente di sviluppo comprende leditor ed il compilatore assembler. Terminale RS232: il programma usato nella realizzazione del progetto di figura 13.10. sPrint Layout: il programma per il disegno dei circuiti stampati. sPlan: il programma per il disegno degli schemi elettrici. Compilatori: nella sezione dei compilatori possibile trovare tre potentissimi compilatori che permettono la stesure dei file sorgenti sia in Basic, sia in Pascal che in C. I compilatori sono in versione demo e la loro unica limitazione la generazione di un file hex non superiore ai 2K di dimensione. Nella cartella \sorgenti sono contenuti tutti i file sorgente dei progetti trattati nel testo e dei relativi file hex. Le routines di utilit riportate nel testo si trovano nella cartella \sorgenti\utility. Gli schemi elettrici dei progetti sono nella cartella \schemi e sono tutti in formato .spl leggibili e modificabili mediante il software sPlan. La cartella \icsp contiene, infine, il pdf della In Circuit Serial Programming Guide una guida di 250 pagine interamente dedicata alla programmazione InCircuit dei PIC.
174
E - Il contenuto del CD
Figura 1.1: Il PIC16F84A .................................................................................... 2 Figura 1.2: Schema a blocchi di un microcontrollore di nuova generazione...... 3 Figura 1.3: Piedinatura del PIC16F84A.............................................................. 5 Tabella 1.1: Descrizione dei pin del PIC16F84A................................................ 6 Figura 1.4: Schema a blocchi del PIC16F84A ................................................... 7 Figura 1.5: Memoria programma per un PIC16F84A......................................... 8 Figura 1.6: Struttura della memoria dati ............................................................. 9 Figura 2.1: Una panoramica della scheda easyPIC2....................................... 11 Figura 2.2: Schema elettrico della parte di alimentazione ............................... 13 Figura 2.3: Creazione di un nuovo progetto in MPLAB.................................... 14 Figura 2.4: Aggiunta di un file al progetto......................................................... 15 Figura 3.1: Schema elettrico del lampeggiatore a LED.................................... 17 Figura 3.2: Oscillatore al quarzo/ceramico (modalit HS, XT o LP). ............... 18 Figura 3.3: Sorgente di clock esterno (modalit HS, XT o LP). ....................... 19 Tabella 3.1: Selezione delle capacit per i risonatori ceramici......................... 19 Figura 3.4: Oscillatore RC. ............................................................................... 20 Figura 3.5: Le operazioni per la programmazione di un PIC............................ 23 Tabella 3.2: Pin della PORTA dopo il caricamento di 0001111 in TRISA........ 29 Tabella 3.3: Pin della PORTB dopo il caricamento di 11111110 in TRISB...... 30 Figura 3.6: Il progetto in MPLAB. ..................................................................... 34 Figura 3.7: Lo stato della configuration word in MPLAB .................................. 36 Figura 4.1: La Program Memory ed il Register File ......................................... 37 Figura 4.2: Register File del PIC16F84A.......................................................... 39 Figura 4.3: La ALU ed il registro accumulatore W ........................................... 41 Figura 4.4: Il program Counter e lo Stack ........................................................ 43 Figura 5.1: Schema del lampeggiatore sequenziale ........................................ 47 Figura 6.1: Le porte A e B ................................................................................ 51 Figura 6.2: Stadio di uscita per RA0RA3........................................................ 53 Figura 6.3: Stadio di uscita di RA4 ................................................................... 55 Figura 6.4: Stadio di uscita di RB0RB3 .......................................................... 56 Figura 6.5: Stadio di uscita di RB4RB7 .......................................................... 57 Figura 6.6: Input da tastiera.............................................................................. 58 Figura 7.1: Il registro contatore TMR0.............................................................. 61 Figura 7.2: I blocchi correlati al TMR0.............................................................. 62 Figura 7.3: TMR0 regolato dal clock interno .................................................... 62 Figura 7.4: TMR0 regolato dal clock esterno ................................................... 63 F - Indice delle figure e delle tabelle 175
Figura 7.5: Incremento di TMR0 sul fronte di salita o di discesa...................... 63 Figura 7.6: Pilotaggio di TMR0 attraverso il Prescaler ..................................... 64 Tabella 7.1: Fattori di divisione e frequenza ottenuta con un clock di 1MHz ... 64 Figura 8.1: Lampeggiatore gestito mediante interruzioni ................................. 70 Figura 8.2: Gestione di due interruzioni............................................................ 73 Figura 9.1: I blocchi coinvolti al reset ............................................................... 75 Figura 9.2: Schema a blocchi della circuiteria di reset interna al PIC16F84A. 76 Figura 9.3: Circuiteria di reset nel caso di tempi lunghi di stabilizzazione Vdd 78 Tabella 9.1: Valori di reset per il Program Counter ed il registro STATUS....... 78 Tabella 9.2: Valori di reset per i vari registri ..................................................... 79 Figura 10.1: Esempio di Power-Down Mode .................................................... 83 Tabella 11.1: Fattori di divisione impostabili per il WDT ................................... 86 Figura 11.1: Esempio di uso del WDT .............................................................. 87 Figura 13.1: Pilotaggio di un display LCD ........................................................ 93 Tabella 13.1: I pin di un display LCD ................................................................ 94 Figura 13.2: Il risultato dellesecuzione del programma LCD1.ASM ................ 95 Figura 13.3: Il testo pu essere posizionato a partire da qualsiasi punto ........ 97 Figura 13.4: Visualizzazione di caratteri su LCD inviati da un PC su RS232 .. 99 Figura 13.5: Connessione via modem tra due PC remoti .............................. 100 Figura 13.6: Livelli di tensione RS232 per la trasmissione del carattere A.. 101 Figura 13.7: Cavo dritto per la connessione del circuito al PC....................... 103 Figura 13.8: Segnali in arrivo sulla seriale...................................................... 104 Figura 13.9: Operazione di RRF su un registro f............................................ 106 Figura 13.10: Pilotaggio e monitoraggio delle porte I/O via RS232 ............... 108 Figura 13.11: Schema elettrico del SIMON GAME. ..................................... 112 Figura 14.1: Formato delle istruzioni .............................................................. 113 Figura 15.1: Struttura della word di configurazione ........................................ 142
176