Pic Micro

193

Transcript of Pic Micro

Page 1: Pic Micro
Page 2: Pic Micro

Maurizio Del Corso Tiziano Galizia

Conoscere ed usare PPIICCmmiiccrroo

Progettare con i microcontrollori PIC in modo facile e veloce

Page 3: Pic Micro

Copyright:

© 2011 – INWARE Edizioni S.r.l.

Via Giotto, 7 20032 Cormano (MI) Tel: 02-66504755 Fax: 02-66508225 [email protected] - 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.

Page 4: Pic Micro

I

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

2 - Gli strumenti necessari.............................................................................. 11 L’hardware..................................................................................................... 11

Una scheda di prototipazione ................................................................................ 11 Un programmatore ................................................................................................ 13 Alimentazione dei circuiti ....................................................................................... 13

Il software ...................................................................................................... 14 MPLAB: editor e compilatore ................................................................................. 14 Il software per la programmazione ........................................................................ 15

3 - Un semplice lampeggiatore a led ............................................................. 17 Lo schema elettrico ....................................................................................... 17

La generazione del segnale di clock...................................................................... 18 Scrittura e compilazione di un programma assembler .................................. 22 Analisi di un sorgente Assembler .................................................................. 25

La subroutine Delay............................................................................................... 32 La compilazione di un sorgente assembler................................................... 34

I flag di configurazione dei PICmicro ..................................................................... 35 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

Uso delle porte di I/O: Input da tastiera......................................................... 58

Page 5: Pic Micro

II

7 - Il contatore TMR0 ed il PRESCALER........................................................ 61 Il registro contatore TMR0 ............................................................................. 61 Il Prescaler..................................................................................................... 63

Esempio di uso del prescaler.................................................................................64 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 Esempio pratico di gestione di più interrupt................................................... 73

Analisi del sorgente DBLINT.ASM .........................................................................74 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 l’accesso 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

Gestione di una connessione RS232 ............................................................ 99 Introduzione ...........................................................................................................99 Cos'é e a cosa serve l'RS232 ..............................................................................100 La comunicazione seriale asincrona....................................................................101 Come collegare il circuito d'esempio....................................................................102 Funzionamento del MAX232................................................................................103 Analisi del file sorgente........................................................................................104

Page 6: Pic Micro

III

Un altro esempio con l'interfaccia RS232 ................................................... 108 Protocollo di comunicazione con il PC................................................................. 109 Comandi di accensione LED ............................................................................... 109 Comandi di spegnimento LED............................................................................. 109 Lettura stato pulsanti ........................................................................................... 109 Programma di prova ............................................................................................ 110

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

Le istruzioni speciali .................................................................................... 135 ADDCF ................................................................................................................ 135 ADDDCF ............................................................................................................. 135 B.......................................................................................................................... 135 BC ....................................................................................................................... 136 BDC..................................................................................................................... 136 BNC..................................................................................................................... 136 BNDC .................................................................................................................. 136 BNZ ..................................................................................................................... 137

Page 7: Pic Micro

IV

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

Page 8: Pic Micro

V

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 L’interfaccia grafica ..................................................................................... 173 I contenuti .................................................................................................... 174

F - Indice delle figure e delle tabelle............................................................ 175

Page 10: Pic Micro

VII

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.

Antonio Cirella Editore

Page 11: Pic Micro
Page 12: Pic Micro

IX

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. L’intento 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 l’architettura 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é l’uso 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 l’uso dell’ambiente 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 dell’assemblatore MPASM. A corredo del volume è allegato un CDROM contenente tutta la documentazione tecnica relativa ai PICmicro, l’ambiente 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.

Page 13: Pic Micro
Page 14: Pic Micro

XI

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 all’indirizzo www.tanzilli.com ed è stato tradotto in di-verse lingue. Possiamo sicuramente affermare che migliaia di utenti hanno ini-ziato 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 dell’elettronica. Ai miei amici.

Maurizio Del Corso 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” sull’altro computer.

Tiziano Galizia

Page 15: Pic Micro
Page 16: Pic Micro

1 - Introduzione ai PICmicro 1

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 un’architettura 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 d’investitori 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 l’interrupt 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 l’enorme flessibilità

Page 17: Pic Micro

2 1 - Introduzione ai PICmicro

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.

Figura 1.1: Il PIC16F84A

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 d’istruzioni 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.

Page 18: Pic Micro

1 - Introduzione ai PICmicro 3

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 d’ingresso 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.

Figura 1.2: Schema a blocchi di un microcontrollore di nuova generazione.

Page 19: Pic Micro

4 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 all’indirizzo 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.

Page 20: Pic Micro

1 - Introduzione ai PICmicro 5

PIC16F84A IL MICROCONTROLLORE UTILIZZATO IN QUESTO LIBRO Prima di entrare nel vivo della sperimentazione, è necessario analizzare in dettaglio il microcontrollore che verrà utilizzato: il PIC16F84A. Questo modello di PICmicro, oramai storico, è uno dei più economici e facilmente reperibili anche per l’hobbista, oltre ad essere particolarmente adatto per scopi didattici.

CPU e memoria • 35 istruzioni single word (tutte le istruzioni sono eseguite in un solo ciclo-

macchina, 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

Figura 1.3: Piedinatura del PIC16F84A

Page 21: Pic Micro

6 1 - Introduzione ai PICmicro

# Nome I/O Descrizione OSC1 I Ingresso per il quarzo dell’oscillatore 16 CLKI I Ingresso per un clock esterno OSC2 O Uscita per il quarzo dell’oscillatore

15 CLKO O In modalità RC su questo pin è disponibile un segnale di 1/4 della

frequenza di clock che denota un ciclo istruzione

4 MCLR I Ingresso Master Clear (Reset) - se portato a livello logico basso provoca il reset del dispositivo

17 RA0 I/O Digital I/O 18 RA1 I/O Digital I/O 1 RA2 I/O Digital I/O 2 RA3 I/O Digital I/O

RA4 I/O Digital I/O - se configurata come uscita è di tipo Open Drain 3 T0CKI I Ingresso di clock per Timer0 RB0 I/O Digital I/O 6 INT I Interrupt esterno

7 RB1 I/O Digital I/O 8 RB2 I/O Digital I/O 9 RB3 I/O Digital I/O 10 RB4 I/O Digital I/O 11 RB5 I/O Digital I/O 12 RB6 I/O Digital I/O 13 RB7 I/O Digital I/O 5 VSS - Terminale di riferimento per le tensioni (GND) 14 VDD - Terminale positivo di alimentazione

Tabella 1.1: Descrizione dei pin del PIC16F84A

Page 22: Pic Micro

1 - Introduzione ai PICmicro 7

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 l’interazione 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

Figura 1.4: Schema a blocchi del PIC16F84A

Nel corso della trattazione verranno analizzate le funzioni di tutte le periferiche e la loro gestione mediante istruzioni assembler.

Page 23: Pic Micro

8 1 - Introduzione ai PICmicro

Organizzazione della memoria programma Il PIC16F84A è provvisto di due blocchi di memoria: memoria programma (program memory) e memoria dati (data memory). I due blocchi hanno un bus dedicato pertanto l’accesso a ciascun blocco può avvenire durante lo stesso ciclo di clock. La memoria programma per il PIC16F84A è composta da 1024 locazioni di 14 bit ciascuna ed indirizzate da 0x0000 a 0x03FF. L’indirizzamento è ciclico per cui riferendosi ad esempio all’indirizzo 0x0400 (il primo successivo a 0x03FF) equivale a riferirsi all’indirizzo 0x0000. L’indirizzo 0x0000 è noto anche come Reset Vector ed è l’indirizzo caricato nel Program Counter al reset. Nella figura 1.5 è riportata la struttura della memoria programma per il PIC16F84A.

Figura 1.5: Memoria programma per un PIC16F84A

Page 24: Pic Micro

1 - Introduzione ai PICmicro 9

Organizzazione della memoria dati La memoria dati è suddivisa in due banchi denominati Bank0 e Bank1. Ciascun banco è a sua volta suddiviso in due aree dette SFR (Specific Function Register) e GPS (General Purpose Register).

Figura 1.6: Struttura della memoria dati

È possibile selezionare uno dei due banchi utilizzando specifici bit del registro STATUS come verrà spiegato più avanti. L’area SFR consente di monitorare e controllare le periferiche ed occupa le

Page 25: Pic Micro

10 1 - Introduzione ai PICmicro

prime 12 locazioni di ciascun banco. L’area 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.

Page 26: Pic Micro

2 - Gli strumenti necessari 11

2 - GLI STRUMENTI NECESSARI

L’HARDWARE 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 l’uso 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.

Figura 2.1: Una panoramica della scheda easyPIC2.

Page 27: Pic Micro

12 2 - Gli strumenti necessari

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 d’ingresso 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 quest’ultimo caso non è necessario l’impiego 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,5°C.

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.

Page 28: Pic Micro

2 - Gli strumenti necessari 13

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 all’interno 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 all’acquisto è l’autocostruzione. 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.

Alimentazione dei circuiti Ovviamente tutti i circuiti presentati nel testo necessitano di una tensione di alimentazione di 5V per il corretto funzionamento. Se per gli esperimenti viene usata una qualsiasi scheda di prototipazione (come ad esempio la easyPIC2) il problema non si pone in quanto tali schede prevedono un circuito di alimentazione. Al contrario, se il circuito viene realizzato su una breadboard o su una scheda millefori, sarà necessario costruire, una volta per tutte, il circuito di alimentazione a 5V. Per semplicità in figura 2.2 è riportato lo schema elettrico di un alimentatore stabilizzato a 5 V, realizzato con il comunissimo LM7805.

Figura 2.2: Schema elettrico della parte di alimentazione

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.

Page 29: Pic Micro

14 2 - Gli strumenti necessari

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 l’ultima versione di MPLAB. MPLAB è un software gratuito che comprende un editor di testi ed un compilatore assembler disponibili in un unico ambiente. L’editor 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 all’interno del quale si trovano tutti i file sorgenti e di libreria utilizzati. La prima cosa da fare è dunque iniziare un nuovo progetto cliccando sull’icona come mostrato in figura 2.3 oppure scegliendo “New” dal menu “Project”.

Figura 2.3: Creazione di un nuovo progetto in MPLAB

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 dell’applicazione può essere effettuata scegliendo “Build All” dal menu “Project”. A seguito della compilazione si aprirà una finestra di output

Page 30: Pic Micro

2 - Gli strumenti necessari 15

in cui verranno elencati gli eventuali errori commessi ed attraverso la quale l’utente sarà informato circa l’esito dell’operazione di compilazione.

Figura 2.4: Aggiunta di un file al progetto

Nei capitoli successivi sarà illustrato dettagliatamente l’uso 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 l’ultima versione rilasciata da Microchip consigliamo di visitare il sito www.microchip.com.

Il software per la programmazione Una volta creato il file eseguibile, questo dovrà essere caricato nel micro tramite il programmatore come già accennato in precedenza. Il programmatore viene gestito da PC mediante un opportuno software che generalmente viene fornito con il programmatore stesso, ma che potrebbe risultare un ostacolo in caso di programmatori autocostruiti. Se si sta usando un programmatore “fatto in casa”, si consiglia di usare il software gratuito icprog scaricabile dal sito www.ic-prog.com. Icprog supporta molti micro e molti programmatori oltre a disporre dei driver necessari per il funzionamento sotto windows2000 e XP. Il problema non si pone se si usa un programmatore di tipo commerciale o si è optato per l’uso della easyPIC2.

Page 31: Pic Micro
Page 32: Pic Micro

3 - Un semplice lampeggiatore a led 17

3 - UN SEMPLICE LAMPEGGIATORE A LED

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.

Figura 3.1: Schema elettrico del lampeggiatore a LED.

Page 33: Pic Micro

18 3 - Un semplice lampeggiatore a led

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 Ω.

La generazione del segnale di clock Come già osservato in precedenza, nel circuito di figura 3.1 il segnale di clock è ottenuto utilizzando un quarzo esterno da 4MHz, tuttavia questo non è l’unico modo per generare il segnale di cadenza. Il PIC16F84A può operare in quattro differenti modalità di oscillatore ed è possibile agire su due bit di configurazione (FOSC1 e FOSC2) per selezionare una di queste quattro modalità.

• LP Low Power Crystal • XT Crystal/Resonator • HS High Speed Crystal/Resonator • RC Resistor/Capacitor

Nelle modalità XT, LP o HS, l’oscillazione viene generata connettendo ai pin OSC1/CLKIN e OSC2/CLKOUT un risonatore ceramico o a cristallo come indicato nella figura 3.2.

Figura 3.2: Oscillatore al quarzo/ceramico (modalità HS, XT o LP).

Il design dell’oscillatore del PIC16F84A richiede l’utilizzo di un quarzo ad uscita parallela. L’utilizzo di un quarzo ad uscita seriale potrebbe generare una frequenza al di fuori delle specifiche del costruttore. In modalità XT, LP o HS il

Page 34: Pic Micro

3 - Un semplice lampeggiatore a led 19

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à Frequenza OSC1/C1 OSC2/C2

XT 455 kHz 2.0 MHz 4.0 MHz

47 – 100 pF 5 - 33 pF

15 – 33 pF

47 – 100 pF 5 - 33 pF

15 – 33 pF

HS 8.0 MHz 10.0 MHz

15 - 33 pF 15 – 33 pF

5 - 33 pF 15 – 33 pF

Nota: Capacità alte migliorano la stabilità dell’oscillatore, 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.

Tabella 3.1: Selezione delle capacità per i risonatori ceramici.

Nota Quando si usa un risonatore con frequenze al di sopra di 3,5 MHz è raccomandato l’utilizzo 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 all’inserimento di un quarzo a scapito della precisione della frequenza ottenuta. La frequenza dell’oscillatore 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.

Page 35: Pic Micro

20 3 - Un semplice lampeggiatore a led

Figura 3.4: Oscillatore RC.

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.

Page 36: Pic Micro

3 - Un semplice lampeggiatore a led 21

Page 37: Pic Micro

22 3 - Un semplice lampeggiatore a led

SCRITTURA E COMPILAZIONE DI UN PROGRAMMA ASSEMBLER Come per qualsiasi sistema a microprocessore, anche per il PICmicro è necessario preparare un programma per farlo funzionare. Un programma è costituito da una sequenza di istruzioni, ognuna delle quali identifica univocamente una funzione che il PICmicro deve svolgere. Ogni istruzione è rappresentata da una stringa di 14 bit ed è memorizzata in una locazione di memoria dell'area programma. Tale memoria nel PIC16F84A è di tipo FLASH e dispone di 1024 locazioni ognuna delle quali è in grado di contenere una sola istruzione oppure una coppia istruzione/dato. Un esempio di istruzione in notazione binaria è riportato di seguito:

00 0001 0000 0000

ovvero una sequenza di 14 cifre binarie (0 o 1). Generalmente, per questioni di compattezza di scrittura, la stringa di 14 bit viene rappresentata in notazione esadecimale. La stringa dell’esempio precedente espressa in notazione esadecimale diviene:

0x0100

Questo rappresenta esattamente lo stesso valore ma in forma più compatta (una cifra esadecimale corrisponde infatti a 4 cifre binarie). La 0x in testa al valore indica che il numero che segue è da interpretarsi espresso in notazione esadecimale. Lo stesso valore può essere rappresentato in assembler con la notazione H'0100'. Questi codici, completamente privi di senso per un essere umano, sono gli unici che il PICmicro è in grado di comprendere. Per fortuna esistono alcuni strumenti che consentono di facilitare il compito al programmatore rendendo le istruzioni decisamente più comprensibili. Per convenzione, ad ogni operazione è stata associata una breve sigla detta mnemonica, che aiuta a ricordare la funzione svolta da ciascuna istruzione. La stringa 0x0100 dell'esempio precedente, effettua l'azzeramento del registro W (operazione che verrà analizzata più in dettaglio più avanti). In inglese questa azione è espressa con la frase CLEAR W REGISTER, ovvero "AZZERA IL REGISTRO W" che nella forma abbreviata diventa CLRW, la forma mnemonica dell’operazione 0x0100. Altre sigle mnemoniche consentono di definire non solo tutte le istruzioni che il PICmicro è in grado di eseguire, ma anche variabili, costanti ed etichette (label). L'insieme di queste sigle e le regole con cui usarle per formare un programma completo è chiamato LINGUAGGIO ASSEMBLER.

Page 38: Pic Micro

3 - Un semplice lampeggiatore a led 23

Per scrivere un programma in linguaggio assembler occorre:

• Conoscere il set d’istruzioni disponibili sul microcontrollore che s’intende 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 d’istruzioni 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.

Figura 3.5: Le operazioni per la programmazione di un PIC.

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 l’uso dell’editor di MPLAB, tuttavia è possibile generare questo file anche con programmi di elaborazione testi come Notepad o qualunque altro software in

Page 39: Pic Micro

24 3 - Un semplice lampeggiatore a led

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 nell’ambiente 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.

Page 40: Pic Micro

3 - Un semplice lampeggiatore a led 25

ANALISI DI UN SORGENTE ASSEMBLER In questo paragrafo verrà analizzato linea per linea il contenuto del sorgente LED.ASM. Per facilitarne la comprensione, il contenuto del file è stato riportato integralmente di seguito.

;************************************************** ; Conoscere ed usare i PICmicro(R) ; LED.ASM: Lampeggiatore ad un led ; (c) 2005, Maurizio Del Corso - Tiziano Galizia ;************************************************** PROCESSOR 16F84A RADIX DEC ERRORLEVEL -302 INCLUDE "P16F84A.INC" LED EQU 0 ORG 0CH Count RES 2 ;Reset Vector ;Punto d’inizio del programma al reset della CPU ORG 00H bsf STATUS,RP0 movlw 00011111B movwf TRISA movlw 11111110B movwf TRISB bcf STATUS,RP0 bsf PORTB,LED MainLoop call Delay btfsc PORTB,LED goto SetToZero bsf PORTB,LED goto MainLoop SetToZero bcf PORTB,LED goto MainLoop ; Subroutines

Page 41: Pic Micro

26 3 - Un semplice lampeggiatore a led

Delay clrf Count clrf Count+1 DelayLoop decfsz Count,1 goto DelayLoop decfsz Count+1,1 goto DelayLoop return END

Nel CD allegato Nella cartella \sorgenti trovate il file LED.ASM utilizzato per l’esempio.

Nella prima linea di codice è riportato:

PROCESSOR 16F84A

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 H’10’. 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 dell’esempio 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).

Page 42: Pic Micro

3 - Un semplice lampeggiatore a led 27

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 nell’analisi 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.

Page 43: Pic Micro

28 3 - Un semplice lampeggiatore a led

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 dall’utente) è 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 dall’utente.

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

Page 44: Pic Micro

3 - Un semplice lampeggiatore a led 29

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 Stato 0 RA0 17 1 Ingresso1 RA1 18 1 Ingresso2 RA2 1 1 Ingresso3 RA3 2 1 Ingresso4 RA4 3 1 Ingresso5 - - 0 - 6 - - 0 - 7 - - 0 -

Tabella 3.2: Pin della PORTA dopo il caricamento di 0001111 in TRISA.

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 B'11111110' movwf TRISB

in questo caso la definizione delle linee sarà quella riportata nella tabella 3.3.

Page 45: Pic Micro

30 3 - Un semplice lampeggiatore a led

Bit registro TRISB Linea porta B Pin Valore Stato 0 RB0 6 0 Uscita 1 RB1 7 1 Ingresso2 RB2 8 1 Ingresso3 RB3 9 1 Ingresso4 RB4 10 1 Ingresso5 RB5 11 1 Ingresso6 RB6 12 1 Ingresso7 RB7 13 1 Ingresso

Tabella 3.3: Pin della PORTB dopo il caricamento di 11111110 in TRISB.

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 è l’acronimo 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

Page 46: Pic Micro

3 - Un semplice lampeggiatore a led 31

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 all’istruzione goto), se il led è spento verrà acceso saltando (skip) l’istruzione 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 PORTB,LED goto MainLoop

Queste due istruzioni rispettivamente accendono il led e rimandano il programma all'inizio del ciclo di lampeggiamento.

SetToZero bcf PORTB,LED goto MainLoop

Page 47: Pic Micro

32 3 - Un semplice lampeggiatore a led

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 Count clrf Count+1 DelayLoop decfsz Count,1 goto DelayLoop decfsz Count+1,1 goto DelayLoop retlw 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 all’esterno. 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 Count clrf 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

Page 48: Pic Micro

3 - Un semplice lampeggiatore a led 33

eseguita l'istruzione successiva:

goto DelayLoop

che rimanda l'esecuzione all'inizio del ciclo di ritardo. Una volta raggiunto lo zero con il contatore Count vengono eseguite le istruzioni:

decfsz Count+1,1 goto 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.

Page 49: Pic Micro

34 3 - Un semplice lampeggiatore a led

LA COMPILAZIONE DI UN SORGENTE ASSEMBLER In questo paragrafo verrà illustrato come effettuare la compilazione di un sorgente assembler usando l’ambiente MPLAB. Per prima cosa è opportuno creare sul disco fisso una directory di lavoro in cui da ora in poi verranno memorizzati tutti i file sorgenti utilizzati nel testo. Si scelga ad esempio un nome quale C:\PIC (Qualsiasi altro nome di directory o drive è ovviamente valido. Basterà sostituire nel resto della trattazione tutti i riferimenti a C:\PIC con il nome del drive e della directory scelti). Copiare ora nella directory di lavoro C:\PIC il file LED.ASM. Se non è stato fatto prima, è ora il momento di installare l’ambiente MPLAB contenuto nel CD oppure reperire l’ultima versione disponibile direttamente dal sito Microchip (www.microchip.com). Una volta avviato MPLAB, dovrà essere creato un nuovo progetto (come indicato nel capitolo 2) nella directory C:\PIC (sia LED il nome del nuovo progetto creato). Facendo click col tasto destro sulla voce “Source Files” e scegliendo “Add Files…” si inserisce il file led.asm nel progetto appena creato. Se il tutto è stato eseguito correttamente, il file led.asm dovrebbe comparire come sottogruppo di “Source Files” come mostrato in figura 3.6.

Figura 3.6: Il progetto in MPLAB.

Facendo un doppio click su led.asm verrà aperto il file per la visualizzazione e le eventuali modifiche. Si noti come nell’editor vengano utilizzati diversi colori: blu per le parole riservate (direttive, istruzioni), verde scuro per i commenti,

Page 50: Pic Micro

3 - Un semplice lampeggiatore a led 35

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 l’esito dell’operazione. 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 all’interno 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.

I flag di configurazione dei PICmicro Il PICmicro dispone di una serie di flag di configurazione contenuti nella cosiddetta configuration word. Questi flag determinano alcune modalità di funzionamento del PICmicro quando esso esegue un programma. La configurazione dei flag è indicata nei sorgente d'esempio con la direttiva __CONFIG e dovrebbe essere letta correttamente da quasi tutti i programmatori di PICmicro. Alcuni di questi però non lo fanno, per cui i flag andranno impostati manualmente prima di iniziare la programmazione. Tutti gli esercizi riportati in questo testo, salvo quando esplicitamente indicato, utilizzano la seguente configurazione:

1. Oscillatore in modalità XT - In questa modalità il PICmicro funziona correttamente con un quarzo collegato ai pin OSC1 e OSC2 come indicato negli schemi d'esempio.

2. Watch Dog Timer Disabilitato - La funzione del Watch Dog Timer verrà illustrata più avanti.

Page 51: Pic Micro

36 3 - Un semplice lampeggiatore a led

Nel programma di esempio è stata inserita la direttiva

__CONFIG _XT_OSC & _CP_OFF & _WDT_OFF

Il primo parametro _XT_OSC imposta l’oscillatore in modalità XT, il secondo, _CP_OFF, disabilita la protezione del codice mentre l’ultimo, _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 l’impostazione di ciascun parametro.

Figura 3.7: Lo stato della configuration word in MPLAB

Page 52: Pic Micro

4 - Architettura interna del PIC16F84A 37

4 - ARCHITETTURA INTERNA DEL PIC16F84A

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.

Figura 4.1: La Program Memory ed il Register File

Page 53: Pic Micro

38 4 - Architettura interna del PIC16F84A

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

sarà quindi la prima istruzione ad essere eseguita.

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

Page 54: Pic Micro

4 - Architettura interna del PIC16F84A 39

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.

Figura 4.2: Register File del PIC16F84A

Page 55: Pic Micro

40 4 - Architettura interna del PIC16F84A

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. Nell’esempio 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 B'00000000' movwf 0x86

oppure, referenziare lo stesso registro con il suo nome simbolico:

movlw B'00000000' movwf TRISB

Page 56: Pic Micro

4 - Architettura interna del PIC16F84A 41

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.

Figura 4.3: La ALU ed il registro accumulatore W

Page 57: Pic Micro

42 4 - Architettura interna del PIC16F84A

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 l’operazione 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 l’istruzione da utilizzare. Il totale è di 8 + 7 + 6 = 21 bit. È necessario dunque ricorrere a due istruzioni, ovvero:

movlw 0x01 movwf 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 è l’unico registro a cui la ALU può accedere direttamente.

Page 58: Pic Micro

4 - Architettura interna del PIC16F84A 43

IL PROGRAM COUNTER (PC) Qualsiasi linguaggio di programmazione prevede le istruzioni di salto, ovvero istruzioni in grado di modificare il flusso di esecuzione del programma in base alle esigenze del programmatore.

Figura 4.4: Il program Counter e lo Stack

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 0x00 Point1 movlw D’10’ goto Point1

Page 59: Pic Micro

44 4 - Architettura interna del PIC16F84A

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 0x00 Point1 movlw D’10’ call Point2 goto Point1 Point2 movlw D’11’ return

Page 60: Pic Micro

4 - Architettura interna del PIC16F84A 45

In questo caso il PICmicro, dopo aver eseguito la MOVLW D’10’ passa ad eseguire l’istruzione 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 D’11’ 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 0x00 Point1 movlw D’10’ call Point2 goto Point1 Point2 movlw D’11’ call Point3 return Point3 movlw D’12’ return

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.

Page 61: Pic Micro

46 4 - Architettura interna del PIC16F84A

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, all’inizio di una subroutine, salvare il contenuto dei registri che verranno utilizzati in modo da poterli ripristinare prima di ritornare al programma principale.

Page 62: Pic Micro

5 - Realizzazione delle "luci in sequenza" 47

5 - REALIZZAZIONE DELLE "LUCI IN SEQUENZA"

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.

Figura 5.1: Schema del lampeggiatore sequenziale

Page 63: Pic Micro

48 5 - Realizzazione delle "luci in sequenza"

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 B'11110000' movwf TRISB

in cui i quattro bit meno significativi, corrispondenti alle linee RB0÷RB3 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 B'00000001' movwf 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 Shift,W movwf PORTB

Successivamente viene effettuato lo scorrimento a sinistra di un bit, del valore contenuto in Shift, con le seguenti istruzioni:

bcf STATUS,C rlf 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.

Page 64: Pic Micro

5 - Realizzazione delle "luci in sequenza" 49

Le istruzioni seguenti svolgono questo tipo di controllo:

btfsc Shift,4 swapf 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 l’istruzione 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.

Page 65: Pic Micro
Page 66: Pic Micro

6 - Le porte di I/O 51

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.

Figura 6.1: Le porte A e B

La suddivisione delle linee in due porte distinte è dettata dai vincoli dell'architettura interna del PIC16F84A che prevede la gestione di dati di

Page 67: Pic Micro

52 6 - Le porte di I/O

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 00010000B movwf 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 l’accensione del led (accensione sul livello alto) sarà la seguente:

bsf PORTB,0

Per spegnerlo:

bcf PORTB,0

Per leggere lo stato dello switch collegato alla linea RB4, il codice sarà:

btfss PORTB,4 goto SwitchAMassa goto 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).

Page 68: Pic Micro

6 - Le porte di I/O 53

STADI DI USCITA DELLE LINEE DI I/O Per rendere più adattabili i PICmicro alle diverse esigenze di utilizzo, Microchip ha implementato diverse tipologie di stadi di uscita per le linee di I/O. Esistono quindi dei gruppi di pin il cui comportamento è leggermente differenziato da altri gruppi. Conoscendo meglio il funzionamento dei diversi stadi d'uscita sarà possibile sfruttare al meglio le loro caratteristiche ed ottimizzare il loro uso nei progetti.

Stadio di uscita delle linee RA0, RA1, RA2 e RA3 In figura 6.2 è riportato lo schema dello stadio di uscita relativo alle linee RA0, RA1, RA2 ed RA3.

Figura 6.2: Stadio di uscita per RA0÷RA3

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).

Page 69: Pic Micro

54 6 - Le porte di I/O

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.

Stadio d'uscita della linea RA4 Lo stadio di uscita della linea RA4 si differenzia da tutte le altre linee di I/O in quanto condivide lo stesso pin con il TOCKI. Nella figura 6.3 viene riprodotto lo schema a blocchi dello stadio d'uscita estratto dal data sheet Microchip:

Page 70: Pic Micro

6 - Le porte di I/O 55

Figura 6.3: Stadio di uscita di RA4

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 l’uso 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.

Page 71: Pic Micro

56 6 - Le porte di I/O

Stadio di uscita delle linee RB0, RB1, RB2 ed RB3 Anche per questo gruppo di linee rimane sostanzialmente invariata la logica di commutazione. Esse dispongono in aggiunta una circuiteria di weak pull-up attivabile quando le linee sono programmate in ingresso. In ingresso infatti, come spiegato precedentemente, le linee vengono completamente scollegate dal PIC in quanto sia il transitor P che il transistor N sono aperti. Lo stato delle linee dipende quindi esclusivamente dalla circuiteria esterna. Se tale circuiteria è costituita, ad esempio, da un semplice pulsante che, quando premuto, collega a massa la linea di I/O, è necessario inserire una resistenza di pull-up verso il positivo per essere sicuri che quando il pulsante è rilasciato vi sia una condizione logica a 1 stabile sulla linea d'ingresso. La circuiteria di weak pull-up consente di evitare l'uso di resistenze di pull-up e può essere attivata o disattivata agendo sul bit RBPU del registro OPTION. Nella figura 6.4 viene riprodotto lo schema a blocchi dello stadio d'uscita estratto dal data sheet Microchip:

Figura 6.4: Stadio di uscita di RB0÷RB3

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 dell’interruzione verrà trattato nel capitolo 8.

Page 72: Pic Micro

6 - Le porte di I/O 57

Stadio di uscita delle linee RB4, RB5, RB6 e RB7 La circuiteria di commutazione di questo gruppo di linee è identica al gruppo RB0÷RB3. Queste linee dispongono anche della circuiteria di weak pull-up. Rispetto alle linee RB0÷RB3 hanno uno stadio in grado di rilevare variazioni di stato su una qualsiasi linea e di generare un interrupt. Nella figura 6.5 viene riprodotto lo schema a blocchi dello stadio d'uscita estratto dal data sheet Microchip:

Figura 6.5: Stadio di uscita di RB4÷RB7

Page 73: Pic Micro

58 6 - Le porte di I/O

USO DELLE PORTE DI I/O: INPUT DA TASTIERA Come esempio pratico di uso delle porte di I/O verrà illustrato come collegare una tastiera di quattro pulsanti al PICmicro, configurando le linee da RB4 a RB7 come linee di input. Lo schema elettrico utilizzato è riportato nella figura 6.6 ed impiega quattro pulsanti, normalmente aperti, denominati SW1, SW2, SW3 ed SW4.

Figura 6.6: Input da tastiera

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 l’accensione 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.

Page 74: Pic Micro

6 - Le porte di I/O 59

La parte iniziale del programma esegue le stesse funzioni effettuate negli esempi già visti ed in particolare le istruzioni:

bsf STATUS,RP0 movlw 11110000B movwf 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 PORTB,SW1 bsf 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 l’istruzione

btfss PORTB,SW1

salta la successiva:

bsf PORTB,LED1

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.

Page 75: Pic Micro
Page 76: Pic Micro

7 - Il contatore TMR0 ed il PRESCALER 61

7 - IL CONTATORE TMR0 ED IL PRESCALER

IL REGISTRO CONTATORE TMR0 Il registro TMR0 è un contatore, ovvero un particolare tipo di registro il cui contenuto viene incrementato con cadenza regolare e programmabile direttamente dall'hardware del PIC.

Figura 7.1: Il registro contatore TMR0

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 dall’esecuzione del programma. Essendo un registro ad 8 bit, il massimo valore che può contenere è 255 e, una

Page 77: Pic Micro

62 7 - Il contatore TMR0 ed il PRESCALER

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.

Figura 7.2: I blocchi correlati al 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:

Figura 7.3: TMR0 regolato dal clock interno

Page 78: Pic Micro

7 - Il contatore TMR0 ed il PRESCALER 63

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.

Figura 7.4: TMR0 regolato dal clock esterno

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:

Figura 7.5: Incremento di TMR0 sul fronte di salita o di discesa

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:

Page 79: Pic Micro

64 7 - Il contatore TMR0 ed il PRESCALER

Figura 7.6: Pilotaggio di TMR0 attraverso il Prescaler

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 2 500.000 0 0 1 4 250.000 0 1 0 8 125.000 0 1 1 16 62.500 1 0 0 32 31.250 1 0 1 64 15.625 1 1 0 128 7.813 1 1 1 256 3.906

Tabella 7.1: Fattori di divisione e frequenza ottenuta con un clock di 1MHz

Nella tabella 7.1, è riportato il fattore di divisione per ciascuna combinazione dei bit PS0÷PS3 ed il valore della frequenza in uscita al PRESCALER nell’ipotesi in cui il segnale applicato abbia frequenza pari a 1MHz.

Esempio di uso del prescaler Come esempio di uso del TMR0 con prescaler, verrà modificato il sorgente del lampeggiatore sequenziale a led (SEQ.ASM) visto nel capitolo 5 per ottenere intervalli di accensione/spegnimento dei led di 1 secondo utilizzando TMR0. Le modifiche sono state riportate nel file SEQTMR0.ASM. Le prime istruzioni hanno la funzione di programmare il PRESCALER per ottenere una frequenza di conteggio conveniente:

movlw 00000100B movwf OPTION_REG

Page 80: Pic Micro

7 - Il contatore TMR0 ed il PRESCALER 65

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 6 movwf TMR0

e

movlw 125 movwf Count

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.

Page 81: Pic Micro
Page 82: Pic Micro

8 - Gli interrupt 67

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, all’arrivo di una telefonata, la suoneria stessa provvederà a notificare il verificarsi dell’evento. All’arrivo 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. Nell’analogia 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.

TIPI DI EVENTO E BIT DI ABILITAZIONE Il PIC16F84A è in grado di gestire in interrupt quattro eventi diversi:

1. Il cambiamento di stato sulla linea RB0 (External interrupt RB0/INT pin). 2. La fine del conteggio del registro TMR0 (TMR0 overflow interrupt). 3. Il cambiamento di stato su una delle linee da RB4 ad RB7 (PORTB

change interrupts). 4. La fine della scrittura su una locazione EEPROM (EEPROM write

complete interrupt). L'interrupt su ognuno di questi eventi può essere abilitato o disabilitato

Page 83: Pic Micro

68 8 - Gli interrupt

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 VECTOR ED INTERRUPT HANDLER Qualunque sia l'evento abilitato, al suo manifestarsi il PIC interrompe l'esecuzione del programma in corso, memorizza automaticamente nello STACK il valore corrente del PROGRAM COUNTER e salta all'istruzione presente nella locazione di memoria 0x04 denominata Interrupt Vector (vettore di interrupt). A partire da questa locazione dovrà essere inserita la subroutine di gestione dell'interrupt denominata Interrupt Handler (gestore di interrupt). Potendo abilitare più interrupt, il primo compito dell'interrupt handler è la verifica di quale, tra gli eventi abilitati, ha generato l'interrupt e l'esecuzione della relativa parte di programma. Questo controllo può essere effettuato utilizzando gli Interrupt flag.

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

Page 84: Pic Micro

8 - Gli interrupt 69

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 all’azzeramento 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.

SALVATAGGIO DEL CONTESTO Durante un evento di interruzione è il solo Program Counter che viene salvato automaticamente nello STACK. È compito dell’utente provvedere al salvataggio del contenuto di altri registri prima di eseguire la routine di interruzione, per poi ripristinarli alla fine. Normalmente è buona norma provvedere al salvataggio del contenuto dell’accumulatore W e del registro STATUS. L’operazione di salvataggio dei registri è nota come PUSH, mentre quella di ripristino del contenuto dei registri salvati è nota come POP. Di seguito è riportato un esempio di codice che provvede ad eseguire le seguenti azioni:

• Salvataggio del contenuto di W nella variabile W_TEMP • Salvataggio del registro STATUS nella variabile STATUS_TEMP • Esecuzione della routine di interruzione (ISR) • Ripristino del contenuto di W • Ripristino del contenuto del registro STATUS

PUSH movwf W_TEMP ;Copia W in W_TEMP swapf STATUS, w movwf STATUS_TEMP ;Salva STATUS in STATUS_TEMP ISR ;qui si inserisce il codice relativo alla ;routine di servizio per l’interruzione POP swapf STATUS_TEMP,0 ;Copia STATUS_TEMP in w movwf STATUS ;Ripristino di STATUS swapf W_TEMP,1 swapf W_TEMP,0 ;Ripristino di W

Page 85: Pic Micro

70 8 - Gli interrupt

RITORNO DA UN INTERRUPT HANDLER Quando viene generato un interrupt il PIC disabilita automaticamente il bit GIE (Global Interrupt Enable) del registro INTCON in modo da disabilitare tutti gli interrupt mentre è già in esecuzione un interrupt handler. Per poter ritornare al programma principale e riportare ad uno questo bit, occorre utilizzare l'istruzione:

RETFIE

ESEMPIO PRATICO DI GESTIONE DI UN INTERRUPT Come esempio di applicazione degli interrupt, verrà modificato il sorgente del lampeggiatore ad un led (LED.ASM) visto nel capitolo 3, per poter accendere un secondo led (LED 2) alla pressione di un pulsante. Il sorgente d'esempio è disponibile nel file INTRB.ASM, mentre lo schema elettrico è riportato nella figura 8.1.

Figura 8.1: Lampeggiatore gestito mediante interruzioni

Page 86: Pic Micro

8 - Gli interrupt 71

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.

ANALISI DEL SORGENTE INTRB.ASM In corrispondenza della direttiva ORG 00H che, come ripetuto più volte, posiziona il programma a partire dalla locazione di indirizzo 0, è presente una istruzione di salto incondizionato alla label Start:

ORG 0x00 goto Start

seguito da un'altra direttiva:

ORG 0x04

e quindi dal codice della subroutine di gestione dell'interrupt:

bsf PORTB,LED2 movlw 3 movwf nTick bcf INTCON,RBIF retfie

Poiché l'interrupt handler deve necessariamente essere allocato a partire dall'indirizzo 0x04, per evitare che esso venga eseguito al reset è stata inserita l’istruzione 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

Page 87: Pic Micro

72 8 - Gli interrupt

funzionare. L'istruzione RETFIE consente al PIC di tornare ad eseguire il programma interrotto dall'interrupt. La direttiva ORG 0x04 garantisce che l’interrupt handler sia posizionato a partire dall’indirizzo 0x04.

Nota La routine che gestisce l’interrupt deve provvedere ad azzerare gli interrupt flag.

Perchè viene generato un interrupt quando è premuto un tasto qualsiasi? Tra le prime istruzioni che esegue il PIC al reset si trovano le seguenti:

movlw 10001000B movwf INTCON

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 RB4÷RB7. 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.

Page 88: Pic Micro

8 - Gli interrupt 73

ESEMPIO PRATICO DI GESTIONE DI PIÙ INTERRUPT In questo paragrafo verrà mostrato come gestire più interrupt contemporaneamente, modificando il file INTRB.ASM. Con le modifiche che verranno apportate, il nuovo sorgente rinominato DBLINT.ASM, sarà in grado di gestire anche l’interruzione sulla fine conteggio del registro TMR0, facendo lampeggiare il LED 3 in corrispondenza di ogni fine conteggio di TMR0. Il sorgente da utilizzare è dunque DBLINT.ASM ed il circuito da utilizzare è riportato nella figura 8.2.

Figura 8.2: Gestione di due interruzioni

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.

Page 89: Pic Micro

74 8 - Gli interrupt

Analisi del sorgente DBLINT.ASM Le modifiche maggiori riguardano l'interrupt handler all'inizio del quale viene effettuato un controllo su quale evento abbia generato l'interrupt. Con le istruzioni:

btfsc INTCON,T0IF goto IntT0IF btfsc INTCON,RBIF goto IntRBIF

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 RB4÷RB7. 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.

Page 90: Pic Micro

9 - Reset 75

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)

Figura 9.1: I blocchi coinvolti al reset

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:

Page 91: Pic Micro

76 9 - Reset

TO PD Condition 1 1 Power-on Reset 0 x Non consentito, il TO è settato sul POR x 0 Non consentito, il PD è settato sul POR 0 1 WDT Reset (during normal operation) 0 0 WDT Wake-up 1 1 MCLR durante il normale funzionamento

1 0 MCLR durante lo SLEEP o interrupt di Wake-up dallo SLEEP

Figura 9.2: Schema a blocchi della circuiteria di reset interna al PIC16F84A.

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 nell’operazione 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.

Page 92: Pic Micro

9 - Reset 77

POWER-ON-RESET (POR) Quando sul pin di alimentazione Vdd si verifica un fronte di salita nel range di 1,2÷1,7V (normalmente questo si verifica nell’istante 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 all’avvio. Se, successivamente all’impulso di POR, il PIC si trova nelle giuste condizioni operative (tensione, frequenza, temperatura, ecc…) viene avviata l’esecuzione 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.

POWER-UP TIMER (PWRT) Il Power-Up Timer (PWRT) funziona con l’oscillatore RC interno ed inserisce automaticamente un ritardo di 72ms (TPWRT) a partire dall’evento POR. Durante questo tempo il PIC viene mantenuto nella condizione di reset e questo consente alla tensione Vdd di raggiungere il valore nominale necessario alla corretta alimentazione del micro. Il PWRT può essere abilitato/disabilitato attraverso un bit di configurazione (come avviene per il WDT) in fase di programmazione del PIC. Il valore assoluto del ritardo TPWRT vale 72ms per il PIC16F84A e varia a seconda del tipo di micro impiegato.

OSCILLATOR START-UP TIMER (OST) L’Oscillator Start-Up Timer (OST) impone un ritardo di 1024 cicli di clock (riferiti all’ingresso OSC1) alla fine del ritardo imposto dal PWRT. Questo assicura che, prima dell’esecuzione del codice, l’oscillatore che regola il clock sia regolarmente avviato e stabilizzato sulla giusta frequenza. Il ritardo di 1024 cicli, noto anche come TOST, viene imposto solamente se l’oscillatore è in modalità XT, LP o HS e solamente in corrispondenza di un evento di Power-On-Reset o risveglio dallo stato SLEEP. Nel caso in cui il fronte di salita di Vdd sia piuttosto lento, può capitare che sia il

Page 93: Pic Micro

78 9 - Reset

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” all’ingresso /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 PC STATUS Power-on Reset 000h 0001 1xxx

MCLR during normal operation 000h 000u uuuu

MCLR during SLEEP 000h 0001 0uuu

WDT Reset (during normal operation) 000h 0000 1uuu

WDT Wake-up PC + 1 uuu0 0uuu

Interrupt wake-up from SLEEP PC + 1 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).

Tabella 9.1: Valori di reset per il Program Counter ed il registro STATUS

Page 94: Pic Micro

9 - Reset 79

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 Indirizzo POR

W - xxxx xxxx uuuu uuuu uuuu uuuu

INDF 00h ---- ---- ---- ---- ---- ----

TMR0 01h xxxx xxxx uuuu uuuu uuuu uuuu

PCL 02h 0000 0000 0000 0000 PC + 1(1)

STATUS 03h 0001 1xxx 000q quuu uuuq quuu

FSR 04h xxxx xxxx uuuu uuuu uuuu uuuu

PORTA(2) 05h ---x xxxx ---u uuuu ---u uuuu

PORTB(3) 06h xxxx xxxx uuuu uuuu uuuu uuuu

EEDATA 08h xxxx xxxx uuuu uuuu uuuu uuuu

EEADR 09h xxxx xxxx uuuu uuuu uuuu uuuu

PCLATH 0Ah ---0 0000 ---0 0000 ---u uuuu

INTCON 0Bh 0000 000x 0000 000u uuuu uuuu

INDF 80h ---- ---- ---- ---- ---- ----

OPTION_REG 81h 1111 1111 1111 1111 uuuu uuuu

PCL 82h 0000 0000 0000 0000 PC + 1(1)

STATUS 83h 0001 1xxx 000q quuu uuuq quuu

FSR 84h xxxx xxxx uuuu uuuu uuuu uuuu

TRISA 85h ---1 1111 ---1 1111 ---u uuuu

TRISB 86h 1111 1111 1111 1111 uuuu uuuu

EECON1 88h ---0 x000 ---0 q000 ---0 uuuu

EECON2 89h ---- ---- ---- ---- ---- ----

PCLATH 8Ah ---0 0000 ---0 0000 ---u uuuu

INTCON 8Bh 0000 000x 0000 000u uuuu uuuu(1)

(1): quando il risveglio (wake-up) è dovuto ad una interruzione ed il bit GIE è a 1, nel Program Counter viene caricato l’interrupt vector (0004h). (2): ad ogni reset i pin della PORTA vengono configurati come ingressi. (3): è il valore che verrà trasferito al latch di uscita.

Tabella 9.2: Valori di reset per i vari registri

Page 95: Pic Micro
Page 96: Pic Micro

10 - Il Power Down Mode 81

10 - IL POWER DOWN MODE

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 l’inutile 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 2µA, 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

Page 97: Pic Micro

82 10 - Il Power Down Mode

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).

IL "RISVEGLIO" DEL PICMICRO Per risvegliare il PICmicro dallo stato di basso consumo, possono essere utilizzate diverse tecniche:

1. Reset del PICmicro mettendo a 0 il pin MCLR (pin 4) 2. Timeout del Watchdog Timer (se abilitato) 3. Verificarsi di una situazione di interrupt (interrupt dal pin RB0/INT,

cambio di stato sulla porta B, termine delle operazioni di scrittura su EEPROM)

Nei casi 1 e 2 il PICmicro viene resettato e l'esecuzione ripresa dalla locazione 0. Nel caso 3 il PICmicro si comporta come nella normale gestione di un interrupt eseguendo per primo l'interrupt handler e quindi riprendendo l'esecuzione dall'istruzione successiva alla SLEEP. Perché il PICmicro venga risvegliato da un interrupt devono essere abilitati opportunamente i flag del registro INTCON.

ESEMPIO DI POWER DOWN MODE In questo esempio il PICmicro entra in Power Down Mode alla pressione di un pulsante ed, in particolare, in corrispondenza di un interrupt sul fronte di discesa applicato al pin RB0/INT. Il sorgente utilizzato è PDM.ASM e lo schema è riportato nella figura 10.1. In pratica il LED 1 collegato alla linea RB2 lampeggerà ad indicare l'esecuzione del programma in corso. Premendo il tasto SW2 il programma eseguirà l'istruzione:

SLEEP

portando il PICmicro in Power Down Mode. Il LED 1 rimarrà acceso o spento in base al momento scelto per premere SW2. Per effettuare l'uscita dal Power Down Mode del PICmicro, basterà premere SW1 per generare un interrupt e far riprendere l'esecuzione del programma. Si noti che l’Interrupt Handler in questo caso non compie alcuna azione specifica, ma si limita ad azzerare i flag e restituire il controllo al programma principale.

Page 98: Pic Micro

10 - Il Power Down Mode 83

Figura 10.1: Esempio di Power-Down Mode

Nel CD allegato Nella cartella \sorgenti trovate il file PDM.ASM utilizzato in questo esempio.

Page 99: Pic Micro
Page 100: Pic Micro

11 - Il watch dog timer (WDT) 85

11 - IL WATCH DOG TIMER (WDT)

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).

Page 101: Pic Micro

86 11 - Il watch dog timer (WDT)

ASSEGNAZIONE DEL PRESCALER AL WDT Agendo sul bit PSA del registro OPTION_REG è possibile assegnare il prescaler al Watch Dog Timer per ottenere dei tempi di ritardo di intervento maggiori. Il bit PSA deve essere impostato ad uno con l'istruzione:

BSF OPTION_REG,PSA

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 WDT0 0 0 1 18 ms 0 0 1 2 36 ms 0 1 0 4 72 ms 0 1 1 8 144 ms 1 0 0 16 288 ms 1 0 1 32 576 ms 1 1 0 64 1.152 s 1 1 1 128 2.304 s

Tabella 11.1: Fattori di divisione impostabili per il WDT

Page 102: Pic Micro

11 - Il watch dog timer (WDT) 87

ESEMPIO PRATICO DI USO DEL WATCH DOG TIMER Come esempio pratico di uso del Watch Dog Timer, si consideri lo schema di figura 11.1 ed il file sorgente WDT.ASM. Durante la fase di programmazione è necessario abilitare il Watch Dog Timer impostando il relativo flag qualora il programmatore non riconoscesse l’impostazione dei flag di configurazione settati con la direttiva __CONFIG.

Figura 11.1: Esempio di uso del WDT

All’entrata 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) all’interno 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

Page 103: Pic Micro

88 11 - Il watch dog timer (WDT)

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.

Page 104: Pic Micro

12 - Scrittura e lettura dati da EEPROM 89

12 - SCRITTURA E LETTURA DATI DA EEPROM

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.

REGISTRI SPECIALI PER L’ACCESSO ALLA EEPROM DATI Per accedere alla EEPROM DATI vengono utilizzati i seguenti registri speciali:

• EEADR è il registro utilizzato per indirizzare una delle 64 locazioni di memoria EEPROM in cui si desidera effettuare una lettura o scrittura di un dato.

• EEDATA è il registro che viene usato per inviare un byte alla EEPROM in scrittura oppure per ricevere un byte dalla EEPROM in lettura.

• EECON1 ed EECON2 sono due registri di controllo utilizzati nelle operazioni di lettura e scrittura come descritto in seguito.

SCRITTURA DI UN DATO SU EEPROM Vediamo ora come sia possibile scrivere un dato su una locazione EEPROM. Si supponga di voler scrivere il valore decimale 10 nella locazione 0 della EEPROM dati. La prima operazione da compiere è scrivere nel registro EEADR l'indirizzo della locazione di memoria che sarà oggetto di scrittura, utilizzando le

Page 105: Pic Micro

90 12 - Scrittura e lettura dati da EEPROM

seguenti istruzioni:

movlw 0 movwf EEADR

Nel registro EEDATA dovrà invece essere scritto il valore da inviare alla locazione EEPROM indirizzata con il registro EEADR:

movlw D’10’ movwf 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 0x55 movwf EECON2 movlw 0xAA movwf 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 dell’operazione di scrittura:

WriteDoneLoop btfsc EECON1,WR ;Finito di scrivere ? goto WriteDoneLoop ;No, aspetta ;Si, continua con le istruzioni successive

Page 106: Pic Micro

12 - Scrittura e lettura dati da EEPROM 91

Il ciclo di attesa può essere evitato se si abilita l’interrupt 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.

LETTURA DI UN DATO DA EEPROM Per leggere un dato da una locazione della memoria EEPROM dovrà essere dapprima selezionato l’indirizzo della locazione da leggere scrivendolo nel registro EEADR (tale registro è nel banco 0 per cui dovrà essere selezionato tale banco prima dall’accesso al registro):

bcf STATUS,RP0 ;Indirizza il banco 0 movlw 0 movwf EEADR

La lettura vera e propria avviene portando ad uno il flag RD (ReaD) del registro di controllo EECON1 (registro del banco 1):

bsf STATUS,RP0 ;Indirizza il banco 1 bsf EECON1,RD

Il dato letto dalla locazione specificata in EEADR viene trasferito nel registro EEDATA dal quale può essere prelevato con una operazione di MOVF:

bcf STATUS,RP0 ;Indirizza il banco 0 movf EEDATA,W

Con queste istruzioni il dato letto dalla EEPROM viene trasferito nell’accumulatore W.

Page 107: Pic Micro
Page 108: Pic Micro

13 - Esempi ed applicazioni pratiche 93

13 - ESEMPI ED APPLICAZIONI PRATICHE

GESTIONE DI UN DISPLAY LCD Come esempio di applicazione pratica di un microcontrollore, verrà illustrata la gestione di un display a cristalli liquidi o LCD (dall'inglese Liquid Crystal Display) dotato di 2 linee di 16 caratteri ciascuna. I display LCD più comuni reperibili in commercio, dispongono di una un'interfaccia ideata da Hitachi che nel tempo è divenuta uno standard industriale utilizzato anche da altre case produttrici. Questo tipo di interfaccia prevede che il display sia collegato al micro tramite un bus dati da 4 o 8 linee più 3 linee di controllo e le linee di alimentazione. Per approfondire le conoscenze sui display LCD alfanumerici e grafici, si rimanda al testo “Display LCD” della collana “Conoscere ed Usare” di Inware Edizioni. Lo schema elettrico del circuito è riportato in figura 13.1.

Figura 13.1: Pilotaggio di un display LCD

Page 109: Pic Micro

94 13 - Esempi ed applicazioni pratiche

Nella tabella 13.1 vengono descritte le funzioni di ogni singola linea disponibile per interfacciare il display.

Pin Nome Funzione

1 GND Ground. Questo pin deve essere collegato al negativo di alimentazione

2 VDD Power Supply. Questo pin deve essere collegato al positivo di alimentazione (+5V).

3 LCD 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

4 RS Register Select. Questo pin è una linea di controllo con cui si comunica al display se si sta inviando, sul bus dati (linee DB0÷DB7), un comando (RS=0) oppure un dato (RS=1)

5 R/W 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).

6 E Enable. Questo pin è una linea di controllo con cui si può abilitare il display ad accettare dati ed istruzioni dal bus dati (E=1)

7 DB0 Data bus line 0 –Su queste linee viaggiano i dati tra il PIC e il display 8 DB1 Data bus line 1 9 DB2 Data bus line 2 10 DB3 Data bus line 3 11 DB4 Data bus line 4 12 DB5 Data bus line 5 13 DB6 Data bus line 6 14 DB7 Data bus line 7

Tabella 13.1: I pin di un display LCD

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.

Page 110: Pic Micro

13 - Esempi ed applicazioni pratiche 95

Figura 13.2: Il risultato dell’esecuzione del programma LCD1.ASM

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.

Le linee Enable (E) e Register Select (RS) dell'LCD Per poter visualizzare una scritta sul display, il PIC deve inviare una serie di comandi tramite le linee del bus dati (linee da DB4 a DB7). Per far questo utilizza due linee di controllo con cui comunica al display l'operazione di trasferimento che intende effettuare. Le due linee di controllo sono la linea Enable (pin 6 dell'LCD) e Register Select (pin 4 dell'LCD). Con la linea Register Select (RS) il PIC segnala al display che il dato presente sul bus è un comando (RS=0) o un dato da visualizzare (RS=1). Tramite i comandi il PIC può segnalare al display il tipo di operazione da compiere, come ad esempio spostare il cursore o pulire lo schermo. Come dati il PIC può inviare al display direttamente i caratteri ASCII da visualizzare. La linea Enable abilita il display a leggere il comando (o il dato) inviato sul bus dal PIC. Il PIC, a sua volta, deve preoccuparsi di aver già inviato sul bus il comando o il dato corretto prima di portare a livello alto il segnale Enable.

Multiplex sul bus dati Sia i comandi che i dati sono rappresentati da numeri a 8 bit dunque, per pilotare il display utilizzando solo quattro linee dati, viene fatta una operazione di "multiplex", ovvero ogni byte viene scomposto in due gruppi di 4 bit, quindi trasmessi sul bus in sequenza. Vengono inviati prima i quattro bit più significativi seguiti dai quattro bit meno significativi. Nel sorgente di esempio, tutte le operazioni di trasmissione di dati e comandi verso il display vengono eseguite da una serie di subroutine presenti nel file LCD1.ASM semplificando così al massimo la complessità del programma.

Page 111: Pic Micro

96 13 - Esempi ed applicazioni pratiche

Analizziamo il sorgente LCD1.ASM Nella prima parte del file sorgente vengono definite alcune costanti:

;LCD Control lines LCD_RS equ 2 ;Register Select LCD_E equ 3 ;Enable ;LCD data line bus LCD_DB4 equ 4 ;LCD data line DB4 LCD_DB5 equ 5 ;LCD data line DB5 LCD_DB6 equ 6 ;LCD data line DB6 LCD_DB7 equ 7 ;LCD data line 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 0x00 call LcdLocate

viene posizionato il cursore del display sulla prima riga e prima colonna dello

Page 112: Pic Micro

13 - Esempi ed applicazioni pratiche 97

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.

Figura 13.3: Il testo può essere posizionato a partire da qualsiasi punto

Per visualizzare ogni carattere della scritta vengono utilizzate le seguenti istruzioni:

movlw 'H' call LcdSendData

per ciascuna lettera da visualizzare. La prima istruzione carica in w il codice ASCII della lettera da visualizzare (nell’esempio 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.

Subroutine di gestione del display LCD Di seguito sono riportate le funzioni svolte dalle subroutine di gestione del display LCD fornite con il sorgente LCD1.ASM.

LcdInit Questa subroutine si occupa di inizializzare il display LCD e di pulire lo schermo. Deve essere chiamata una sola volta e prima di qualsiasi subroutine di gestione dell’LCD. Non richiede alcun passaggio di parametri.

Page 113: Pic Micro

98 13 - Esempi ed applicazioni pratiche

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 all’interno dell’area 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 all’LCD da visualizzare nella posizione corrente del cursore. Richiede nel registro W il valore ASCII del carattere da visualizzare. LcdSendCommand Serve ad inviare un comando all’LCD. I comandi riconosciuti dall’LCD sono riportati sul data-sheet dello stesso. LcdSendByte Questa funzione viene utilizzata internamente alle altre funzioni di gestione dell’LCD e si occupa di effettuare lo split di dati e comandi a 8 bit sul bus di dati.

Page 114: Pic Micro

13 - Esempi ed applicazioni pratiche 99

GESTIONE DI UNA CONNESSIONE RS232 Introduzione Questa applicazione mostra come sia possibile dotare il PIC16F84A di una interfaccia RS232 per il collegamento alla porta seriale di un PC. Il circuito permette di visualizzare sul display LCD i caratteri ASCII trasmessi da un PC attraverso una porta seriale tramite un normale emulatore di terminale come Hyperterminal (su Windows 95/98/ME/2000/XP), Telix (su MS/DOS) o Minicom (su Linux). Lo schema elettrico da utilizzare è riportato nella figura 13.4.

Figura 13.4: Visualizzazione di caratteri su LCD inviati da un PC su RS232

Page 115: Pic Micro

100 13 - Esempi ed applicazioni pratiche

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 dell’esempio.

Prima di iniziare l’analisi del file sorgente di questa applicazione, è opportuno richiamare brevemente il funzionamento della comunicazione seriale RS232.

Cos'é e a cosa serve l'RS232 Lo standard RS232 definisce una serie di specifiche per la trasmissione seriale di dati tra due dispositivi denominati DTE (Data Terminal Equipment) e DCE (Data Communication Equipment). Il Data Communication Equipment è un dispositivo che si occupa di gestire una comunicazione dati, mentre il Data Terminal Equipment è un dispositivo che si occupa di generare o ricevere dati. Lo standard RS232 è stato creato per connettere tra loro un terminale dati (in questo caso un computer) con un modem, per la trasmissione di dati a distanza. Per avere una connessione tra due computer remoti è quindi necessario disporre di quattro dispositivi come visibile in figura 13.5: un computer (DTE) collegato al modem (DCE) ed un altro modem remoto (DCE) collegato al computer (DTE). In questo modo qualsiasi dato generato dal primo computer e trasmesso tramite RS232 al relativo modem, verrà inviato da quest’ultimo al modem remoto che, a sua volta, provvederà ad inviarlo al computer connesso tramite RS232. Ovviamente è valido anche il processo inverso.

Figura 13.5: Connessione via modem tra due PC remoti

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 dell’applicazione di esempio, i circuito di figura 13.4 simula un DCE, per cui per

Page 116: Pic Micro

13 - Esempi ed applicazioni pratiche 101

il collegamento con il PC, sarà necessario un cavo dritto e non invertente.

La comunicazione seriale asincrona Per consentire la trasmissione di dati tra il PC ed il modem, lo standard RS232 definisce una serie di specifiche elettriche e meccaniche. Una di queste riguarda il tipo di comunicazione seriale che può essere sincrona o asincrona. Nella presente trattazione verrà analizzata solo la comunicazione seriale asincrona rimandando ai testi specializzati chi volesse approfondire la comunicazione seriale sincrona. Una comunicazione seriale consiste nella trasmissione e ricezione di dati da un punto ad un altro usando una sola linea di comunicazione. Dovendo trasmettere un intero byte sarà necessario inviare in sequenza ogni singolo bit in esso contenuto. Si supponga, ad esempio, di voler trasmettere il carattere A usando il protocollo RS232. La connessione RS232 più semplice prevede una linea di trasmissione (TXD) ed una di ricezione (RXD) per cui collegare in seriale due PC significa collegare la linea di trasmissione del primo con quella di ricezione del secondo e viceversa. Collegando un oscilloscopio sulla linea TXD del PC trasmettitore durante la trasmissione del carattere A si rileva il segnale di figura 13.6. Quando nessuna trasmissione è in corso la tensione sulla linea TXD è di -12 volt corrispondente alla condizione logica 1. Per indicare al PC ricevente che la trasmissione ha inizio, il PC trasmittente porta a +12 volt la linea TXD per un tempo pari al tempo di trasmissione di un singolo bit (corrispondente all’inverso della frequenza di trasmissione). Se, ad esempio, la velocità di trasmissione è 9600 bit per secondo (baud), la tensione della linea TXD rimarrà a +12 volt per: 1/9600=0.104 ms. Questo segnale viene denominato START BIT ed è sempre presente all'inizio della trasmissione di ogni singolo byte. Dopo lo start bit vengono trasmessi in sequenza gli otto bit componenti il codice ASCII del carattere trasmesso partendo dal bit meno significativo. Nel caso della lettera A (maiuscola) il valore del byte da trasmettere è 01000001.

Figura 13.6: Livelli di tensione RS232 per la trasmissione del carattere “A”

Page 117: Pic Micro

102 13 - Esempi ed applicazioni pratiche

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.

Come collegare il circuito d'esempio Come accennato il circuito d'esempio simula un dispositivo DCE ciò significa che il cavo da realizzare non dovrà essere di tipo NULL MODEM o INVERTENTE, ma DRITTO ovvero con i pin numerati allo stesso modo connessi tra loro. Questo tipo di cavo è identico a quelli che vengono usati per connettere al PC un modem esterno. Dato che i dispositivi DTE sono sempre dotati di connettore DB9 maschio, il nostro circuito, essendo un DCE, avrà un connettore DB9 femmina la cui pedinatura è riportata nella seguente tabella:

Pin 1 Received Line Signal Detector (Data Carrier Detect)Pin 2 Received Data Pin 3 Transmit Data Pin 4 Data terminal Ready Pin 5 Signal Ground Pin 6 Data set ready Pin 7 Request To Send Pin 8 Clear To Send Pin 9 Ring Indicator

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 Protective Ground Pin 2 Transmit data Pin 3 Received data Pin 4 Request To send Pin 5 Clear To Send Pin 6 Data Set Ready Pin 7 Signal Ground Pin 8 Received Line Signal Detector (Data Carrier Detect)Pin 20 Data terminal Ready Pin 22 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

Page 118: Pic Micro

13 - Esempi ed applicazioni pratiche 103

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.

Figura 13.7: Cavo dritto per la connessione del circuito al PC

Funzionamento del MAX232 Come già anticipato, nel circuito d'esempio viene usato un transceiver RS232, ovvero un integrato in grado di convertire i segnali a +/- 12 volt tipici della RS232 in segnali a 0/5 volt gestibili dalle porte del PIC. Dallo schema di figura 13.4 si nota che il segnale di trasmissione proveniente dal PC entra dal pin 3 del connettore DB9 femmina sul pin 13 del MAX232. Sul pin 12 del MAX232 sarà presente un segnale a 0 volt quando sul pin 13 ci saranno +12 volt e 5 volt quando sul pin 13 ci saranno -12 volt. Il segnale presente sul pin 12 del MAX232 viene quindi inviato alla linea RA1 della porta A del PIC che in questo caso farà da linea di ricezione. Viceversa sul pin 17 (RA0) il PIC genera i segnali TTL da inviare al PC che vengono convertiti in segnali RS232 dal MAX232 tramite i pin 11 (ingresso TTL) e 14 (uscita RS232) quindi inviati al PC tramite il pin 2 del connettore J2.

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).

Page 119: Pic Micro

104 13 - Esempi ed applicazioni pratiche

Figura 13.8: Segnali in arrivo sulla seriale

Analisi del file sorgente Il file sorgente per questa applicazione è LCDTERM.ASM. Una volta compilato il sorgente e programmato correttamente il PIC16F84A è possibile collegare al PC il circuito e fornire alimentazione. Sul display apparirà il cursore lampeggiante in alto a sinistra. Per comunicare con il circuito, è necessario lanciare in esecuzione un programma qualsiasi di emulazione terminale e configurato per usare la porta seriale a cui è collegato il circuito ed impostando i parametri a 9600 baud, 8 data bit, 1 stop bit e no parità senza alcun controllo di flusso. Premendo qualche tasto sulla tastiera del PC si osserva come i caratteri digitati vengano visualizzati anche sul display LCD del circuito. La combinazione di tasti CTRL+L consente di pulire lo schermo dell'LCD per visualizzare nuove scritte. Alla linea 24 del file sorgente si trovano le seguenti direttive:

TX equ 0 ;Tx data RX equ 1 ;Rx data

in cui vengono assegnate alle costanti TX e RX rispettivamente le linee di trasmissione (TX) e ricezione (RX) del PIC. In questa applicazione in realtà non viene ancora usata la linea di trasmissione in quanto il circuito miniterminale è in grado per ora solo di ricevere caratteri. Queste due costanti vengono utilizzate rispettivamente dalle subroutine di trasmissione e ricezione di caratteri via RS232: TxChar ed RxChar. Queste due subroutine consentono di trasmettere e ricevere byte in modalità seriale asincrona a 9600 bps, 8 bit dati, 1 stop bit e nessuna parità.

Page 120: Pic Micro

13 - Esempi ed applicazioni pratiche 105

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 'A' call TxChar

Per ricevere caratteri l'operazione è leggermente più complessa. Si consideri il file sorgente a partire dall’etichetta MainLoop:

MainLoop btfsc PORTA,RX goto MainLoop call 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 8 movwf 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.

Page 121: Pic Micro

106 13 - Esempi ed applicazioni pratiche

D0D1D2D3D4D5D6D7C

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 BitCount,F goto wDB

e termina dopo aver letto l'ultimo bit

return

All’uscita 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:

Page 122: Pic Micro

13 - Esempi ed applicazioni pratiche 107

CheckFormFeed movlw 12 xorwf ShiftReg,W btfss STATUS,Z goto _CheckFormFeed clrf xCurPos clrf yCurPos call LcdClear goto 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 ShiftReg,W call 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.

Page 123: Pic Micro

108 13 - Esempi ed applicazioni pratiche

UN ALTRO ESEMPIO CON L'INTERFACCIA RS232

Figura 13.10: Pilotaggio e monitoraggio delle porte I/O via RS232

Per valutare la trasmissione seriale sia in ricezione che in trasmissione si consideri il circuito di figura 13.10 che permette di controllare l’accensione dei led dal PC nonché leggere lo stato degli switch.

Page 124: Pic Micro

13 - Esempi ed applicazioni pratiche 109

Protocollo di comunicazione con il PC Il circuito è dotato di quattro LED denominati LED1, LED2, LED3 e LED4 e quattro pulsanti denominati SWITCH1, SWITCH2, SWITCH3 e SWITCH4. Tramite un semplice protocollo è possibile decidere quale dei quattro led dovrà accendersi oppure leggere lo stato di uno qualsiasi dei quattro pulsanti. Il protocollo consiste in una serie di codici di controllo che il PC può trasmettere al circuito tramite comunicazione seriale. La velocità di trasferimento è ancora 9600 baud, 8 data bit, 1 stop bit, no parity.

Comandi di accensione LED I comandi per l’accensione dei LED sono i seguenti:

00h Accensione LED 101h Accensione LED 202h Accensione LED 303h Accensione LED 4

Comandi di spegnimento LED I comandi per lo spegnimento dei LED sono i seguenti:

10h Spegnimento LED 111h Spegnimento LED 212h Spegnimento LED 313h Spegnimento LED 4

Lettura stato pulsanti Per leggere lo stato di tutti i quattro pulsanti basta inviare un unico comando:

20h Lettura stato pulsanti 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 0 = SWITCH 1 rilasciato, 1 = SWITCH 1 premutoBit 1 0 = SWITCH 2 rilasciato, 1 = SWITCH 2 premutoBit 2 0 = SWITCH 3 rilasciato, 1 = SWITCH 3 premutoBit 3 0 = SWITCH 4 rilasciato, 1 = SWITCH 4 premuto

Per cui se ad esempio solo lo SWITCH 1 risulta chiuso, il codice di risposta

Page 125: Pic Micro

110 13 - Esempi ed applicazioni pratiche

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 1: off Switch 2: off Switch 3: ---> Active Switch 4: off

Ad indicare, in questo caso, che solo lo SWITCH 3 risulta premuto.

Nel CD allegato Nella cartella \software trovate il file rs232io.exe che è il programma DOS visto in questo esempio.

Page 126: Pic Micro

13 - Esempi ed applicazioni pratiche 111

REALIZZAZIONE DEL GIOCO ELETTRONICO “SIMON” Questo esempio di applicazione, realizza il vecchio gioco elettronico “SIMON”. Il gioco prevede l’accensione di quattro LED in particolari sequenze sempre più difficoltose e il giocatore deve premere i pulsanti relativi ai LED che via via vengono illuminati. L’accensione di ciascun LED è accompagnata da uno specifico tono audio. Sono previste un massimo di 63 mosse e, una volta completate correttamente, il dispositivo notifica il successo ottenuto mediante l’emissione di una serie di toni. Nel caso in cui si verifichi una mossa errata, verrà mostrata la mossa corretta, verrà emesso un tono a notificare l’errore e, attraverso una serie di toni, verrà notificato il massimo numero di mosse corrette eseguite. La convenzione è la seguente: i primi toni indicano le “decine”, i toni successivi (di frequenza più alta) indicano le unità. Quindi se le mosse giuste sono state 23, verranno emessi due toni a frequenza bassa e tre toni a frequenza più alta. Ciascuna mossa è memorizzata nella EEPROM ed occupa una locazione di memoria (quindi si hanno 63 mosse possibili). Il giocatore ha 5 secondi a disposizione per replicare la sequenza, altrimenti verrà notificato un time-out e la mossa sarà ritenuta errata. Il time-out viene gestito attraverso il Timer0. Il circuito è in grado di riconoscere quali tasti sono premuti all’accensione, in modo da poter scegliere alcune opzioni di gioco:

• SW5 permette il reset del PIC quindi l’avvio di un nuovo gioco. • SW6 imposta il livello di difficoltà del gioco (velocità). • Mantenendo premuto SW1 (rosso) durante l’accensione, si entra in

modalità demo, visualizzando le mosse, ma non accettando input esterni.

• Mantenendo premuto SW2 (giallo) durante l’accensione, le mosse vengono proposte in ordine inverso.

• Mantenendo premuto SW3 (verde) durante l’accensione, il gioco si avvia in modalità MUTE, ovvero non vengono emessi i suoni.

• Mantenendo premuto SW4 (blu) durante l’accensione, il gioco si avvia in “double mode” in cui le mosse vengono proposte in coppia.

Lo schema elettrico è riportato nella figura 13.11 e si consiglia di installare i diodi LED vicino ai relativi pulsanti per facilitare la comprensione della sequenza. L’alimentazione è a 5V che possono essere ottenuti mediante un regolatore integrato come già illustrato nei primi capitoli del testo. Per l’emissione dei toni audio è stato impiegato un buzzer piezoelettrico a pilotaggio esterno. Questo significa che il buzzer dovrà essere pilotato con una onda quadra, la cui frequenza determina l’altezza del suono emesso.

Page 127: Pic Micro

112 13 - Esempi ed applicazioni pratiche

Figura 13.11: Schema elettrico del “SIMON GAME”.

Nel CD allegato

Nella cartella \sorgenti trovate il file simon.asm che è il file sorgente dell’applicazione trattata in questo esempio.

Page 128: Pic Micro

14 - Set di istruzioni 113

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 l’azione da eseguire ed uno o più operandi coinvolti nell’operazione. 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 dell’operazione andrà nel registro specificato o nell’accumulatore 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, all’interno del registro specificato, è coinvolto nell’operazione (un campo di tre bit consente di ottenere otto combinazioni ciascuna delle quali identifica un bit all’interno del registro specificato).

Figura 14.1: Formato delle istruzioni

Page 129: Pic Micro

114 14 - Set di istruzioni

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 1µs). 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 Indirizzo di un registro (0x00 ÷ 0x7F) w Registro accumulatore b Indirizzo di un bit specifico all’interno di un registro (3 bit) k Costante o etichetta x Valore non rilevante (può essere indifferentemente 0 o 1)

d 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)

PC Program Counter TO Bit di time-out PD bit di Power-Down

Nella tabella seguente sono elencate tutte le istruzioni mnemoniche con il loro comportamento ed il numero di cicli-istruzione richiesti per l’esecuzione. 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 Descrizione Cicli-

istruzione ADDLW k Somma k con W (w = w + k) 1 ADDWF f,d Somma il contenuto di w con quello di f 1 ANDLW k AND logico tra w e k (w = w AND k) 1 ANDWF f,d AND logico tra w ed f 1 BCF f,b Azzera un bit di f 1 BSF f,b Porta ad 1 un bit di f 1 BTFSC f,b Analizza un bit di f e, se a zero, salta una istruzione 1 (2) BTFSS f,b Analizza un bit di f e, se ad uno, salta una istruzione 1 (2) CALL k Chiama la subroutine all'indirizzo k 2 CLRF f Azzera il registro f 1 CLRW Azzera il registro w 1 CLRWDT Azzera il Watchdog Timer 1 COMF f,d Complementa il contenuto di f 1 DECF f,d Decrementa il contenuto di f 1

DECFSZ f,d Decrementa il contenuto di f e, se il risultato è zero, salta una istruzione 1 (2)

Page 130: Pic Micro

14 - Set di istruzioni 115

Codice mnemonico Descrizione Cicli-

istruzione GOTO k Salta all'indirizzo k 2 INCF f,d Incrementa il contenuto di f 1

INCFSZ f,d Incrementa il contenuto di f e, se il risultato è zero, salta una istruzione 1 (2)

IORLW k OR logico tra w e k (w = w OR k) 1 IORWF f,d OR logico tra w ed f 1 MOVLW k Carica in w il valore k (w = k) 1 MOVF f,d Sposta il contenuto di f 1 MOVWF f Sposta il contenuto di w nel registro f 1 NOP Nessuna operazione 1 RETFIE Ritorna da un interrupt handler 2 RETLW k Ritorna da una subroutine con w = k 2 RETURN Ritorna da una subroutine 2 RLF f,d Scorrimento a sinistra del registro f 1 RRF f,d Scorrimento a destra del registro f 1 SLEEP Mette in standby il PIC 1 SUBLW k Sottrae da k il valore contenuto in w (w = k-w) 1 SUBWF f,d Sottrae da f il valore contenuto in w 1 SWAPF f,d Scambia in f i bit 0123 con i bit 4567 1 XORLW k OR esclusivo tra w e k (w = w XOR k) 1 XORWF f,d OR esclusivo tra w e f 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 Operazione equivalente: W = W + k Esempio:

org 00H start movlw 10 addlw 12 ...

Page 131: Pic Micro

116 14 - Set di istruzioni

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 0CH add2 equ 0DH org 00H movlw 10 ;Primo addendo = 10 movwf add1 movlw 15 ;Secondo addendo = 15 movwf add2 movf add1,W ;W = add1 addwf 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

Page 132: Pic Micro

14 - Set di istruzioni 117

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 ;Memorizza nel registro all'indirizzo movwf 0CH ;0CH il valore iniziale da mascherare movlw 00001111B ;Prepara la maschera di bit andwf 0CH,0 ;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

Page 133: Pic Micro

118 14 - Set di istruzioni

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 ;Valore iniziale movwf parm1 bcf parm1,0 ;D0=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 ;Valore iniziale movwf parm1 bsf parm1,0 ;D0=1

Al termine del programma il registro parm1 varrà 00000001B.

Page 134: Pic Micro

14 - Set di istruzioni 119

Note: Questa istruzione non influenza alcun bit di stato

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 ;Valore iniziale movwf parm1 loop btfsc parm1,0 ;D0 = 0 ? Si, esce goto loop ;No, esegue il loop

Questa programma esegue un loop infinito. Lo stesso programma non esegue il loop se l'istruzione:

movlw 11111111B ;Valore iniziale

viene sostituita con l'istruzione

movlw 11111110B ;Valore iniziale

Note: Questa istruzione non influenza alcun bit di stato

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 ;Valore iniziale movwf parm1

Page 135: Pic Micro

120 14 - Set di istruzioni

loop btfss parm1,0 ;D0 = 1 ? Si, esce goto loop ;No, esegue il loop

Questa programma esegue un loop infinito. Lo stesso programma non esegue il loop se l'istruzione:

movlw 11111110B ;Valore iniziale

viene sostituita con l'istruzione:

movlw 11111111B ;Valore iniziale

Note: Questa istruzione non influenza alcun bit di stato

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 k Esempio:

org 00H call ledOn ... ;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.

Page 136: Pic Micro

14 - Set di istruzioni 121

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

Page 137: Pic Micro

122 14 - Set di istruzioni

Esempio:

org 00H loop clrwdt goto loop

Note: Questa istruzione non influenza alcun bit di stato.

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

Page 138: Pic Micro

14 - Set di istruzioni 123

all'indirizzo 0CH quindi decrementato di uno. Al termine dell'esecuzione il registro alla locazione 0CH conterrà il valore 0x22.

movlw 23H ;Scrive in W il valore 23H movwf 0CH ;Copia nel registro 0CH il valore di W decf OCH,1 ;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 ;counter = 10 movwf counter loop decfsz counter,1 ;counter = counter -1 ... ;counter = 0? Si esce goto loop ;No, continua

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 k

Page 139: Pic Micro

124 14 - Set di istruzioni

Esempio:

org 00H loop goto loop

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 ;counter = 250 movwf counter loop incfsz counter,1 ;counter = counter + 1 ... ;counter = 0 ? Si esce goto loop ;No, continua

Page 140: Pic Micro

14 - Set di istruzioni 125

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 00H start movlw 00001111B iorlw 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

Page 141: Pic Micro

126 14 - Set di istruzioni

movwf parm1 movlw 11111111B iorwf parm1,F

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 Operazione equivalente: W = k Esempio:

org 00H start movlw 20 ...

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

Page 142: Pic Micro

14 - Set di istruzioni 127

0CH nell'accumulatore W:

movf 0CH,W

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 10H ;Scrive nel registro W il valore 10H movwf TMR0 ;e lo memorizza nel registro TMR0

Note: L'esecuzione della MOVWF non influenza nessun bit di stato.

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 1µs per ogni istruzione NOP inserita nel nostro sorgente.

nop ;Esegue un ritardo pari ad 1µs

Note: La NOP non influenza alcun bit di stato.

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:

Page 143: Pic Micro

128 14 - Set di istruzioni

org 00H loop goto loop ;Loop infinito org 04H ;Interrupt vector intHandler retfie ;Ritorna dall'interrupt

In questo sorgente il programma principale esegue un loop infinito. All’arrivo di un interrupt il controllo verrà dato automaticamente al programma allocato dall'indirizzo 04H (nell'esempio intHandler). L’istruzione 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 k Esempio:

rtc equ 0CH org 00H call mySub1 movwf rtc ... mySub1 nop retlw 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.

Page 144: Pic Micro

14 - Set di istruzioni 129

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 00H call mySub1 ... mySub1 call mySub2 return mySub2 call mySub3 return mySub3 return

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

Page 145: Pic Micro

130 14 - Set di istruzioni

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 ;Azzera il CARRY movlw 01010101B ;Valore iniziale 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

Page 146: Pic Micro

14 - Set di istruzioni 131

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 ;Azzera il CARRY movlw 01010101B ;Valore iniziale 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 00H start sleep

Note: Questa istruzione non influenza alcun bit di stato.

SUBLW Questa istruzione (SUBstract W from Literal) sottrae alla costante k il valore memorizzato nell'accumulatore W. Sintassi: sublw k Operazione equivalente: W = k - W Esempio:

org 00H start

Page 147: Pic Micro

132 14 - Set di istruzioni

movlw 10 sublw 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 Operazione equivalente: d = f - W (dove d può essere W o f) Esempio: Si consideri l'istruzione:

subwf REG1,1

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.

Page 148: Pic Micro

14 - Set di istruzioni 133

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 00H start movlw 10000000B xorlw 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 f,d

Page 149: Pic Micro

134 14 - Set di istruzioni

Operazione equivalente: d = f XOR W (dove d può essere W o f) Esempio:

xorwf COUNTER,F ;COUNTER = COUNTER XOR W xorwf COUNTER,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 57H ;W = Valore da comparare = 57H ;Risultato. W = 57H xorwf REG1,0 ;W = W XOR REG1 Effettua lo XOR con ; il valore in REG1 btfss STATUS,Z ;Salta l'istruzione seguente se il ; risultato dello XOR vale 0, ovvero ; se il valore di REG1 e' pari a 57H goto diverso ;Salta se diverso da 57H goto uguale ;Salta se uguale da 57H

Page 150: Pic Micro

14 - Set di istruzioni 135

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 l’equivalente 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 Sequenza equivalente:

btfsc STATUS,C incf 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 Sequenza equivalente:

btfsc STATUS,DC incf f,d

B Salto incondizionato ad uno specifico indirizzo k. Sintassi: B k Sequenza equivalente: goto k

Page 151: Pic Micro

136 14 - Set di istruzioni

BC Salto ad uno specifico indirizzo k se il bit C (Carry) del registro STATUS vale 1. Sintassi: BC k Sequenza equivalente:

btfsc STATUS,C goto k

BDC Salto ad uno specifico indirizzo k se il bit DC (Digit Carry) del registro STATUS vale 1. Sintassi: BDC k Sequenza equivalente:

btfsc STATUS,DC goto k

BNC Salto ad uno specifico indirizzo k se il bit C (Carry) del registro STATUS vale 0. Sintassi: BNC k Sequenza equivalente:

btfss STATUS,C goto k

BNDC Salto ad uno specifico indirizzo k se il bit DC (Digit Carry) del registro STATUS vale 0. Sintassi: BNDC k Sequenza equivalente:

btfss STATUS,DC goto k

Page 152: Pic Micro

14 - Set di istruzioni 137

BNZ Salto ad uno specifico indirizzo k se il bit Z (Zero flag) del registro STATUS vale 0. Sintassi: BNZ k Sequenza equivalente:

btfss STATUS,Z goto k

BZ Salto ad uno specifico indirizzo k se il bit Z (Zero flag) del registro STATUS vale 1. Sintassi: BZ k Sequenza equivalente:

btfsc STATUS,Z goto 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

Page 153: Pic Micro

138 14 - Set di istruzioni

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 Sequenza equivalente: movf f,0

NEGF Esegue l’operazione 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 Sequenza equivalente:

comf f,1 incf 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 STATUS,Z

Page 154: Pic Micro

14 - Set di istruzioni 139

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.

Page 155: Pic Micro

140 14 - Set di istruzioni

Sintassi: skpz Sequenza equivalente: btfss STATUS,Z

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 Sequenza equivalente:

btfsc STATUS,C decf 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 Sequenza equivalente:

btfsc STATUS,DC decf 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 Sequenza equivalente: movf f,1

Page 156: Pic Micro

15 - Direttive dell'assembler MPASM 141

15 - DIRETTIVE DELL'ASSEMBLER MPASM

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 0x20 ;all’etichetta 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

__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

Page 157: Pic Micro

142 15 - Direttive dell'assembler MPASM

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.

Figura 15.1: Struttura della word di configurazione

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 16F84A

Page 158: Pic Micro

15 - Direttive dell'assembler MPASM 143

__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 “pippo”,0 dt 0x03, 0xF5

Queste due righe, in fase di compilazione, verranno tradotte nelle seguenti istruzioni:

retlw ‘p’ retlw ‘i’ retlw ‘p’

Page 159: Pic Micro

144 15 - Direttive dell'assembler MPASM

retlw ‘p’ retlw ‘o’ retlw 0 retlw 0x03 retlw 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 uscita0 0x06,0 bcf uscita0

In fase di compilazione verrà generata la seguente istruzione

bcf 0x06,0

che azzera il bit 0 della PORTB (0x06 è infatti l’indirizzo di PORTB).

EQU Definisce una costante assegnando il valore <expr> a <label>. Sintassi: <label> equ <expr> Esempio:

sei equ 6

assegna il valore 6 all’etichetta sei.

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> [, …]

Page 160: Pic Micro

15 - Direttive dell'assembler MPASM 145

Note: I numeri 0,1 e 2 definiscono il tipo di avvisi in accordo alla seguente tabella:

Valore Avvisi abilitati 0 Messaggi, Warnings ed errori1 Warnings ed errori 2 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 Error: Out of Memory 105 Error:Cannot open file 113 Error:Symbol not previously defined 114 Error:Divide by zero 115 Error:Duplicate label 128 Error:Missing arguments 132 Error:Unknow processor 136 Error:Duplicate macro name 203 Warning: Found opcode in column 1 207 Warning: Found label after column 1 225 Warning: invalid label in operand 302 Message: Register in operand not in bank 0 307 Message: Setting page bits 313 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 dell’assembler 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 un’etichetta definita in altri file come GLOBAL (si veda la direttiva GLOBAL).

Page 161: Pic Micro

146 15 - Direttive dell'assembler MPASM

Sintassi: extern <label> [, <label>] Esempio:

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 un’etichetta che può essere utilizzata anche in altri file come EXTERN (si veda la direttiva EXTERN). Sintassi: global <label> [, <label>] Esempio:

var1 res 1 var2 res 1 global var1, var2 ;var1 e var2 sono visibili anche ;esternamente al file

IF È una direttiva che consente di decidere se compilare o meno una determinata parte di codice in funzione del valore assunto dall’espressione <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

Page 162: Pic Micro

15 - Direttive dell'assembler MPASM 147

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 dell’esempio se version vale 100 l’istruzione movlw 0x0F non sarà fisicamente presente nel file compilato.

IFDEF È simile alla direttiva IF con l’unica differenza che IFDEF permette solamente di controllare se una certa etichetta è stata precedentemente definita usando la #DEFINE (o mediante linea di comando all’invocazione del compilatore). Come per la IF, la sezione di codice successiva delimitata da una direttiva ELSE o ENDIF, viene esclusa dalla compilazione se l’etichetta 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>

Page 163: Pic Micro

148 15 - Direttive dell'assembler MPASM

ORG Definisce un indirizzo della memoria del PIC a partire dal quale verrà allocato il codice successivo. Se viene specificata l’etichetta <label> il valore dell’indirizzo specificato viene associato all’etichetta. Sintassi: <label> ORG <expr> Esempio:

val1 org 0x20 ;il codice inserito in questo punto viene allocato ;a partire dall’indirizzo 0x20 val2 org val1+0x10 ;il codice inserito in questo punto viene allocato ;a partire dall’indirizzo 0x30

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: [<label>] res <numero_locazioni> Esempio:

buffer res 16

A partire dall’indirizzo corrente (associato all’etichetta buffer) vengono riservate 16 locazioni di memoria. In altri termini buffer è una variabile di 16 byte.

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

Page 164: Pic Micro

15 - Direttive dell'assembler MPASM 149

diversi punti del programma. Ogni volta che è necessario compiere questa operazione dovranno essere inserite le seguenti istruzioni all'interno del sorgente:

bcf PORTB,0 bcf PORTB,1 bcf 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 MACRO bcf PORTB,0 bcf PORTB,1 bcf PORTB,2 ENDM

Ogni volta che si presenta la necessità di inserire le tre istruzioni, basterà scrivere semplicemente:

AZZERA

Sarà compito dell’assemblatore 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 MACRO LINEA1, LINEA2, LINEA3 bcf PORTB,LINEA1 bcf PORTB,LINEA2 bcf PORTB,LINEA3 ENDM

quindi ogni volta che la macro viene richiamata, si devono specificare quali linee devono essere azzerate:

AZZERA 0,1,2

per azzerare RB0, RB1 ed RB2, oppure:

AZZERA 3,5,7

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

Page 165: Pic Micro

150 15 - Direttive dell'assembler MPASM

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 dell’assembler Microchip in cui si trova la lista completa delle direttive del compilatore.

Page 166: Pic Micro

A - La programmazione ICSP™ dei PICmicro 151

A - LA PROGRAMMAZIONE ICSP™ DEI PICMICRO

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:

MCLR Piedino di master clear (pin 4 su PIC16x84) utilizzato per applicare la tensione di programmazione VPP al chip.

RB6 Linea 6 della porta B (pin 12 su PIC16x84) utilizzata come linea CLOCK. RB7 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). Quest’ultimo viene generato dal programmatore mentre il flusso sulla linea DATA è bidirezionale a seconda dell’operazione 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 dall’invio di un comando da parte del programmatore per comunicare al PIC l’operazione che si intende eseguire. La lunghezza dei comandi è sempre di 6 bit

Page 167: Pic Micro

152 A - La programmazione ICSP™ dei PICmicro

eventualmente seguiti dalla trasmissione di 14 bit contenenti il valore che dovrà essere scritto. Nella seguente tabella viene riportato l’elenco dei comandi riconosciuti dai PIC16x84:

Comando dal programmatore

Codice comando Descrizione

Load Configuration 000000

Invia al PIC il prossimo dato da scrivere in memoria programma. Al codice comando segue immediatamente il dato da memorizzare.

Load Data for Program Memory 000010

Invia al PIC il prossimo dato da scrivere in memoria dati. Al codice comando segue immediatamente il dato da memorizzare.

Read Data from Program Memory 000100

Legge dal PIC la locazione corrente dall’area programma. Appena riceve questo comando il PIC trasmette al programmatore il valore letto.

Increment Address 000110 Incrementa il puntatore alla locazione corrente nella memoria dati/configurazione/programma.

Begin Programming 001000 Programma la locazione corrente.

Load Data for Data Memory 000011

Invia al PIC il prossimo valore da scrivere in memoria dati. Al codice comando segue immediatamente il dato da memorizzare.

Read Data from Data Memory 000101

Legge dal PIC la locazione corrente dalla memoria dati. Appena riceve questo comando il PIC trasmette al programmatore il valore letto.

Bulk Erase Program Memory 001001 Cancella l’intera memoria programma Bulk Erase Data Memory 001011 Cancella l’intera memoria dati

Il PIC16x84 dispone internamente di tre aree di memoria distinte programmabili dall’esterno: l’area programma (1024 byte), l’area dati pari (64 byte) e l’area configurazione (8 byte). Tutte le aree di memoria sono implementate su FLASH. Le sole aree di programma e dati possono essere lette dall’esterno. 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 all’interno del PIC, il comando Begin Programming effettua la scrittura vera e propria del dato nella memoria programma. L’indirizzo della locazione di memoria che viene scritta è contenuto in un puntatore di scrittura

Page 168: Pic Micro

A - La programmazione ICSP™ dei PICmicro 153

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. L’area dati e l’area configurazione vengono programmate con le stesse modalità utilizzando il relativo comando LOAD. L’area dati è un’area 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. L’area configurazione contiene dati invisibili al programma su PIC, ma utili per determinare la modalità di funzionamento di alcuni dispositivi interni al PIC quali l’oscillatore di clock, il watchdog timer, ecc.

Nel CD allegato Nella cartella \ICSP trovate tutta la documentazione relativa alla tecnica ICSP.

Page 169: Pic Micro
Page 170: Pic Micro

B - Tabelle 155

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.

Page 171: Pic Micro

156 B - Tabelle

TABELLA DEI CARATTERI ASCII HEX BIN CHAR HEX BIN CHAR HEX BIN CHAR 00 00000000 NUL 26 00100110 & 4C 01001100 L 01 00000001 SOH 27 00100111 ‘ 4D 01001101 M 02 00000010 STX 28 00101000 ( 4E 01001110 N 03 00000011 ETX 29 00101001 ) 4F 01001111 O 04 00000100 EOT 2A 00101010 * 50 01010000 P 05 00000101 ENQ 2B 00101011 + 51 01010001 Q 06 00000110 ACK 2C 00101100 , 52 01010010 R 07 00000111 Bell 2D 00101101 - 53 01010011 S 08 00001000 BS 2E 00101110 . 54 01010100 T 09 00001001 HT 2F 00101111 / 55 01010101 U 0A 00001010 LF 30 00110000 0 56 01010110 V 0B 00001011 VT 31 00110001 1 57 01010111 W 0C 00001100 FF 32 00110010 2 58 01011000 X 0D 00001101 CR 33 00110011 3 59 01011001 Y 0E 00001110 SO 34 00110100 4 5A 01011010 Z 0F 00001111 SI 35 00110101 5 5B 01011011 [ 10 00010000 DLE 36 00110110 6 5C 01011100 \ 11 00010001 DC1 37 00110111 7 5D 01011101 ] 12 00010010 DC2 38 00111000 8 5E 01011110 ^ 13 00010011 DC3 39 00111001 9 5F 01011111 _ 14 00010100 DC4 3A 00111010 : 60 01100000 ‘ 15 00010101 NAK 3B 00111011 ; 61 01100001 a 16 00010110 SYN 3C 00111100 < 62 01100010 b 17 00010111 ETB 3D 00111101 = 63 01100011 c 18 00011000 CAN 3E 00111110 > 64 01100100 d 19 00011001 EM 3F 00111111 ? 65 01100101 e 1A 00011010 SUB 40 01000000 @ 66 01100110 f 1B 00011011 ESC 41 01000001 A 67 01100111 g 1C 00011100 FS 42 01000010 B 68 01101000 h 1D 00011101 GS 43 01000011 C 69 01101001 i 1E 00011110 RS 44 01000100 D 6A 01101010 j 1F 00011111 US 45 01000101 E 6B 01101011 k 20 00100000 Space 46 01000110 F 6C 01101100 l 21 00100001 ! 47 01000111 G 6D 01101101 m 22 00100010 “ 48 01001000 H 6E 01101110 n 23 00100011 # 49 01001001 I 6F 01101111 o 24 00100100 $ 4A 01001010 J 70 01110000 p 25 00100101 % 4B 01001011 K 71 01110001 q

Page 172: Pic Micro

B - Tabelle 157

HEX BIN CHAR HEX BIN CHAR HEX BIN CHAR 72 01110010 r 77 01110111 w 7C 01111100 | 73 01110011 s 78 01111000 x 7D 01111101 74 01110100 t 79 01111001 y 7E 01111110 ~ 75 01110101 u 7A 01111010 z 7F 01111111 DEL 76 01110110 v 7B 01111011

TABELLA DI CONVERSIONE BINARIO/ESADECIMALE HEX BIN DEC HEX BIN DEC HEX BIN DEC 00 00000000 0 1E 00011110 30 3C 00111100 60 01 00000001 1 1F 00011111 31 3D 00111101 61 02 00000010 2 20 00100000 32 3E 00111110 62 03 00000011 3 21 00100001 33 3F 00111111 63 04 00000100 4 22 00100010 34 40 01000000 64 05 00000101 5 23 00100011 35 41 01000001 65 06 00000110 6 24 00100100 36 42 01000010 66 07 00000111 7 25 00100101 37 43 01000011 67 08 00001000 8 26 00100110 38 44 01000100 68 09 00001001 9 27 00100111 39 45 01000101 69 0A 00001010 10 28 00101000 40 46 01000110 70 0B 00001011 11 29 00101001 41 47 01000111 71 0C 00001100 12 2A 00101010 42 48 01001000 72 0D 00001101 13 2B 00101011 43 49 01001001 73 0E 00001110 14 2C 00101100 44 4A 01001010 74 0F 00001111 15 2D 00101101 45 4B 01001011 75 10 00010000 16 2E 00101110 46 4C 01001100 76 11 00010001 17 2F 00101111 47 4D 01001101 77 12 00010010 18 30 00110000 48 4E 01001110 78 13 00010011 19 31 00110001 49 4F 01001111 79 14 00010100 20 32 00110010 50 50 01010000 80 15 00010101 21 33 00110011 51 51 01010001 81 16 00010110 22 34 00110100 52 52 01010010 82 17 00010111 23 35 00110101 53 53 01010011 83 18 00011000 24 36 00110110 54 54 01010100 84 19 00011001 25 37 00110111 55 55 01010101 85 1A 00011010 26 38 00111000 56 56 01010110 86 1B 00011011 27 39 00111001 57 57 01010111 87 1C 00011100 28 3A 00111010 58 58 01011000 88 1D 00011101 29 3B 00111011 59 59 01011001 89

Page 173: Pic Micro

158 B - Tabelle

HEX BIN DEC HEX BIN DEC HEX BIN DEC 5A 01011010 90 67 01100111 103 74 01110100 116 5B 01011011 91 68 01101000 104 75 01110101 117 5C 01011100 92 69 01101001 105 76 01110110 118 5D 01011101 93 6A 01101010 106 77 01110111 119 5E 01011110 94 6B 01101011 107 78 01111000 120 5F 01011111 95 6C 01101100 108 79 01111001 121 60 01100000 96 6D 01101101 109 7A 01111010 122 61 01100001 97 6E 01101110 110 7B 01111011 123 62 01100010 98 6F 01101111 111 7C 01111100 124 63 01100011 99 70 01110000 112 7D 01111101 125 64 01100100 100 71 01110001 113 7E 01111110 126 65 01100101 101 72 01110010 114 7F 01111111 127 66 01100110 102 73 01110011 115 - - -

Page 174: Pic Micro

C - Glossario dei termini utilizzati 159

C - GLOSSARIO DEI TERMINI UTILIZZATI

.ASM file File sorgente in formato testo contenente le istruzioni assembler che costituiscono il programma e le direttive del compilatore.

.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.

.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.

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 In-Circuit Serial Programming. Tecnologia che

permette la programmazione del micro direttamente on-board.

Interrupt Meccanismo che consente l’interruzione dell’esecuzione del programma principale al verificarsi di particolari eventi, esterni o interni, al micro.

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.

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.

Page 175: Pic Micro

160 C - Glossario dei termini utilizzati

Notazione BINARIA ed ESADECIMALE Notazioni utilizzate in programmazione per indicare valori numerici in alternativa alla notazione decimale. La notazione Binaria o notazione in base 2, rappresenta bit che possono assumere solo 2 valori 0 o 1 e rispecchia direttamente la modalità di memorizzazione dei numeri di un microprocessore. La notazione Esadecimale o notazione in base 16, rappresenta i numeri tramite cifre esadecimali che possono assumere 16 valori. Nel linguaggio assembler dei PICmicro la notazione esadecimale può essere rappresentata in tre differenti forme:

H'<hex_digit>' 0x<hex_digit> <hex_digit>H

Quindi, ad esempio, lo stesso numero esadecimale 1A viene riconosciuto nelle seguenti forme:

H'1A' 0x1A 1AH

La notazione binaria viene riconosciuta in due forme:

B'<binary_digit>' <binary_digit>B

quindi lo stesso numero binario 01101100 viene riconosciuto nelle seguenti forme:

B'01101100' 01101100B

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 l’opcode risulta essere una parte della stringa di bit che costituisce il codice dell’istruzione. Ad esempio per azzerare il Register File all'indirizzo 0x0C, il codice sarà:

00 0001 1000 1100

dove la parte in grassetto è l’opcode 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 AND 0 = 0 0 AND 1 = 0 1 AND 0 = 0 1 AND 1 = 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:

Page 176: Pic Micro

C - Glossario dei termini utilizzati 161

01010101 AND 11110000 = ---------- 01010000

OR L'OR, o OR inclusivo, tra due bit segue la seguente tavola della verità:

0 OR 0 = 0 0 OR 1 = 1 1 OR 0 = 1 1 OR 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

XOR Lo XOR (OR esclusivo) tra due bit segue la seguente tavola della verità:

0 XOR 0 = 0 0 XOR 1 = 1 1 XOR 0 = 1 1 XOR 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

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

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.

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

Page 177: Pic Micro

162 C - Glossario dei termini utilizzati

File Register interni reinizializzati e il programma riattivato in esecuzione a partire dal Reset Vector, ovvero dall'istruzione memorizzata nella locazione 0x0000 (nel PIC16F84A).

ROM, PROM, EPROM, EEPROM, FLASH Sono memorie che non perdono il loro contenuto in caso di mancanza di alimentazione. Per questo motivo vengono normalmente utilizzate nei sistemi a microprocessore per contenere il programma da eseguire e, in alcuni casi, i dati qualora debbano essere permanenti.

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 program-mabile). È una memoria ROM non ancora programmata. La program-mazione 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.

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.

Page 178: Pic Micro

D - Routine Assembler di varia utilità 163

D - ROUTINE ASSEMBLER DI VARIA UTILITÀ

In questa sezione sono riportate alcune routine utili che possono essere usate all’interno di programmi più complessi. Vengono descritti i parametri di ingresso e il registro (o i registri) in cui viene lasciato l’eventuale risultato senza scendere nell’analisi approfondita del codice. I file sorgente di ciascuna routine è presente nel CD allegato.

CONVERSIONE DA ASCII A BINARIO La seguente routine consente di convertire il carattere ASCII di una coppia di cifre numeriche nel relativo codice binario. Ad esempio il codice ASCII 00111001 (corrispondente alla cifra “9”) verrà convertito in 00001001 ovvero l’espressione binaria del numero 9. Le due cifre in formato ASCII dovranno trovarsi nei registri Asc1:Asc0 ed il risultato verrà lasciato in w. Per il corretto uso della routine dovranno essere dichiarati i registri result0, result1, Asc0 ed Asc1.

;**************************************************** ;* Ascii2Bin ;**************************************************** Ascii2Bin movlw 0x30 ;Si inizia col byte meno significativo subwf Asc0, w movwf result0 ;memorizzaz.del risultato in result0 movlw 0x30 ;elaboraz. del byte più significativo subwf Asc1, w ;memorizzaz.del risultato in W ; 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 ;vengono aggiunte le unità return

Page 179: Pic Micro

164 D - Routine Assembler di varia utilità

CONVERSIONE DA BINARIO A CIFRE ASCII La seguente routine interpreta il contenuto di W come un numero binario (compreso tra 0 e 255) e lo converte nelle relative cifre ASCII che vengono lasciate nei registri Asc2:Asc1:Asc0 (Asc0 è la cifra meno significativa). La routine, oltre ai registri Asc2, Asc1ed Asc0, usa anche il registro TempByte in cui vengono memorizzati i risultati intermedi.

;**************************************************** ;* ByteToDec ;**************************************************** ByteToDec movwf TempByte clrw addlw 241 movwf Asc2 addwf Asc2, w addwf Asc2, w addlw 253 movwf Asc1 swapf TempByte, w andlw 0x0F addwf Asc1, f addwf Asc1, f sublw 251 movwf Asc0 addwf Asc0, f addwf Asc0, f addwf Asc0, f movf TempByte, w andlw 0x0F addwf Asc0, f movlw 10 bin2dec999a addwf Asc0, f decf Asc1, f skpc goto bin2dec999a bin2dec999b addwf Asc1, f

Page 180: Pic Micro

D - Routine Assembler di varia utilità 165

decf Asc2, f skpc goto bin2dec999b bin2dec999c addwf Asc2, f skpc goto bin2dec999c movlw 0x30 addwf Asc2, f addwf Asc1, f addwf Asc0, f return

Page 181: Pic Micro

166 D - Routine Assembler di varia utilità

CONVERSIONE DA ESADECIMALE A CIFRE ASCII La seguente routine interpreta il contenuto di W come un numero intero espresso in esadecimale e lo converte nelle rispettive cifre ASCII. Il risultato viene memorizzato nei registri HtA_L e HtA_H (L e H indicano rispettivamente la cifra meno significativa e quella più significativa del risultato). La routine si appoggia al registro HexTemp che dovrà essere dichiarato.

;**************************************************** ;* HexToAscii ;**************************************************** HexToAscii movwf HexTemp andlw 0x0f sublw 0x09 movf HexTemp, w andlw 0x0f btfss STATUS, C addlw 7 addlw 0x30 movwf HtA_L swapf HexTemp, w andlw 0x0f sublw 0x09 swapf HexTemp, w andlw 0x0f btfss STATUS, C addlw 7 addlw 0x30 movwf HtA_H return

Page 182: Pic Micro

D - Routine Assembler di varia utilità 167

MOLTIPLICAZIONE TRA DUE NUMERI BINARI A 16 BIT I due fattori sono a 16 bit e devono trovarsi nei registri n_2 ed n_1 rispettivamente per il byte più significativo e meno significativo del primo fattore e in n_4 e n_3 rispettivamente per il byte più significativo e meno significativo del secondo fattore. Il risultato, di 32 bit, viene lasciato nei registri q_4, q_3, q_2 e q_1 dove q_1 è il byte meno significativo.

;******************************************************* ;* Mul1616 ;* (n_2:n_1)*(n_4:n_3)=(q_4:q_3:q_2:q_1) ;******************************************************* Mul1616 clrf q_4 clrf q_3 clrf q_2 clrf q_1 bsf q_2, 7 m1 rrf n_2, f rrf n_1, f skpc goto m2 movf n_3, w addwf q_3, f movf n_4, w skpnc incfsz n_4, w addwf q_4, f m2 rrf q_4, f rrf q_3, f rrf q_2, f rrf q_1, f skpc goto m1 return

Page 183: Pic Micro

168 D - Routine Assembler di varia utilità

DIVISIONE TRA UN DIVIDENDO BINARIO A 48 BIT ED UN DIVISORE BINARIO A 23 BIT Il dividendo deve trovarsi nel registro Dividend che deve essere a 48 bit quindi dichiarato con la direttiva RES 6 in modo da riservare 6 locazioni di 8 bit ciascuna. Il divisore deve trovarsi invece nel registro Divisor che deve essere di 23 bit quindi dichiarato con la direttiva RES 3 in modo da riservare tre byte (il bit più significativo viene ignorato). La routine utilizza anche i registri di appoggio BitCount e Temp in cui vengono memorizzati i risultati intermedi. Nel caso in cui il divisore sia nullo, la routine viene interrotta lasciando in W il valore zero. Nel caso in cui la divisione sia avvenuta correttamente, la routine esce lasciando il risultato nel registro Dividend ed il valore ‘1’ in W.

;***************************************************** ;* Div4823 ;***************************************************** Div4823 DIVIDE_48by23 ;Controllo se il divisore è nullo movf Divisor, w iorwf Divisor + 1, w iorwf Divisor + 2, w btfsc STATUS, Z retlw 0 ;Divisor = zero, esce lasciando 0 in w. clrf Temp clrf Temp + 1 clrf Temp + 2 clrf Temp2 movlw D'48' movwf BitCount setc DIVIDE_LOOP_48by23 rlf Dividend + 5, f rlf Dividend + 4, f rlf Dividend + 3, f rlf Dividend + 2, f rlf Dividend + 1, f

Page 184: Pic Micro

D - Routine Assembler di varia utilità 169

rlf Dividend, f rlf Temp + 2, f rlf Temp + 1, f rlf Temp, f movf Divisor + 2, w btfss Dividend + 5, 0 goto Div48by23_add subwf Temp + 2, f movf Divisor + 1, w skpc incfsz Divisor + 1, w subwf Temp + 1, f movf Divisor, w skpc incfsz Divisor, w subwf Temp, f goto DIVIDE_SKIP_48by23 Div48by23_add addwf Temp + 2, f movf Divisor + 1, w btfsc STATUS, C incfsz Divisor + 1, w addwf Temp + 1, f movf Divisor, w btfsc STATUS, C incfsz Divisor, w addwf Temp, 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

Page 185: Pic Micro

170 D - Routine Assembler di varia utilità

GESTIONE DI ORE, MINUTI E SECONDI MEDIANTE TIMER0 Questa routine deve essere usata come routine di servizio per una interruzione causata dal Timer0. La routine incrementa il valore dei registri Ore, Minuti e Secondi in funzione del tempo trascorso dall’inizio dell’esecuzione del programma. Per il corretto funzionamento Timer0 deve essere abilitato senza prescaler ed il PIC deve essere pilotato con un quarzo a 4MHz. Con il quarzo a 4MHz il ciclo istruzione è di 1µs e, poiché il timer provoca una interruzione ogni 256 cicli istruzione, si avranno 3906,25 interruzioni ogni secondo. Ad ogni interruzione la routine di servizio incrementa le variabili di conteggio TimerL e TimerH (TimerL è la meno significativa) per cui quando il conteggio raggiunge il valore 3906,25 è trascorso precisamente un secondo. Non potendo gestire i decimali, la routine controlla quando il conteggio raggiunge il valore 3907 provvedendo ad incrementare il contatore ogni 4 secondi. 3907 in esadecimale corrisponde a 0x0F43 per cui la routine controlla se TimerL ha raggiunto il valore esadecimale 0x43 e, in caso affermativo, controlla che TimerH sia 0x0F. Se TimerH=0x0F e TimerL=0x43 viene incrementato il registro Secondi, quindi aggiornati eventualmente i registri Minuti e Ore. La routine prevede il ripristino del contesto che si presume sia stato salvato secondo quanto indicato nel capitolo relativo alle interruzioni

;***************************************************** ;* TIMER interrupt ;***************************************************** TimerService bcf INTCON, T0IE bcf INTCON, T0IF incf TimerL, f btfsc STATUS, Z incf TimerH, f movlw 0x43 subwf TimerL, w btfss STATUS, Z goto SecTest_af movlw 0x0f subwf TimerH, w btfss STATUS, Z goto SecTest_af clrf TimerL clrf TimerH

Page 186: Pic Micro

D - Routine Assembler di varia utilità 171

incf Secondi, f btfsc Secondi, 0 goto Correctie_af btfsc Secondi, 1 goto Correctie_af movlw 2 addwf TimerL, f 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

Page 187: Pic Micro

172 D - Routine Assembler di varia utilità

DISCRIMINAZIONE DI UN INTERRUPT Questo frammento di codice può essere inserito in corrispondenza dell’interrupt vector (0x04 per il PIC16F84A) e consente di determinare l’evento che ha scatenato l’interruzione. Viene eseguito prima di tutto un salvataggio del contesto, quindi vengono analizzati i vari flag per capire quale evento ha scatenato l’interruzione. 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 l’interruzione btfsc INTCON, T0IF ;Interrupt da Timer0? goto ServizioTimer ;si, gestisci l’interruzione btfsc INTCON, INTF ;Interrupt esterno? Goto ServizioExt ;si, gestisci l’interruzione Goto ServizioEE ;l’interruzione è di fine

;scrittura su eeprom

Nel CD allegato Nella cartella \sorgenti\utility trovate i file relativi alle routines illustrate.

Page 188: Pic Micro

E - Il contenuto del CD 173

E - IL CONTENUTO DEL CD

L’INTERFACCIA 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 all’inserimento, è possibile lanciare il menu di navigazione avviando il file start.exe situato nella directory principale del CD. All’avvio l’interfaccia 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.

Page 189: Pic Micro

174 E - Il contenuto del CD

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 dell’ambiente di sviluppo MPLAB di Microchip. L’ambiente di sviluppo comprende l’editor 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 In-Circuit dei PIC.

Page 190: Pic Micro

F - Indice delle figure e delle tabelle 175

F - INDICE DELLE FIGURE E DELLE TABELLE

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 RA0÷RA3........................................................ 53 Figura 6.3: Stadio di uscita di RA4 ................................................................... 55 Figura 6.4: Stadio di uscita di RB0÷RB3.......................................................... 56 Figura 6.5: Stadio di uscita di RB4÷RB7.......................................................... 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

Page 191: Pic Micro

176 F - Indice delle figure e delle tabelle

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 dell’esecuzione 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

Page 193: Pic Micro