Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
PIC16F876
Ringraziamento particolare a
Nicola Guercetti
che con i suoi consigli ha permesso
una più veloce stesura
di questo manuale
Tutte le volte che nel Manuale si fa riferimento al datasheet del componente si intende il file DS30292x.PDF (dove x
definisce la versione, che in questo momento risulta essere la B) rintracciabile nel sito www.microchip.com.
Sommario
I
8.1. PREMESSA ............................................................................................................................................... 37
8.2. FUNZIONAMENTO DELLA PERIFERICA ADC ............................................................................................... 38
8.3. IL RISULTATO DELLA CONVERSIONE ......................................................................................................... 40
8.4. LA PROGRAMMAZIONE DELLA CONVERSIONE ............................................................................................ 40
CAPITOLO 9 LA MEMORIA EEPROM ...................................................................................................... 41
9.1. PREMESSA ............................................................................................................................................... 41
9.2. REGISTRI SPECIALI PER L'ACCESSO ALLA EEPROM DATI .......................................................................... 41
9.3. SCRITTURA DI UN DATO SU EEPROM....................................................................................................... 41
9.4. LETTURA DI UN DATO DA EEPROM ......................................................................................................... 42
CAPITOLO 10 COMUNICAZIONE SERIALE.............................................................................................. 43
10.1. PREMESSA ............................................................................................................................................... 43
10.2. COMUNICAZIONE USART........................................................................................................................ 43
10.2.1. Trasmissione Asincrona ................................................................................................................. 44
CAPITOLO 11 ALGORITMI E FUNZIONI ................................................................................................... 45
11.1. PREMESSA ............................................................................................................................................... 45
11.2. RITARDO SOFTWARE PROGRAMMABILE..................................................................................................... 45
11.2.1. Funzioni di supporto alla funzione Delay........................................................................................ 46
11.3. USO DEL DISPLAY LED A 7 SEGMENTI ..................................................................................................... 47
11.3.1. Le costanti ..................................................................................................................................... 47
11.3.2. Aggiornare il display...................................................................................................................... 48
11.3.3. Visualizzare una parola sul display ................................................................................................ 48
11.3.4. Convertire numero decimale per visualizzarlo sul display............................................................... 49
11.4. ALGORITMI DI SOMMA ............................................................................................................................. 50
11.4.1. Somma di due registri a 8 bit.......................................................................................................... 51
11.4.2. Somma di due numeri di 3 Byte ...................................................................................................... 51
11.5. ALGORITMI DI PRODOTTO E DI DIVISIONE .................................................................................................. 52
11.5.1. Prodotto di due numeri da 2 Byte ................................................................................................... 52
11.5.2. Divisione di un numero di 2 Byte per dieci...................................................................................... 54
APPENDICE A ...................................................................................................................................................... 56
P16F876.INC ....................................................................................................................................................... 56
APPENDICE B....................................................................................................................................................... 61
OPERATORI LOGICI E MATEMATICI ........................................................................................................................ 61
APPENDICE C ...................................................................................................................................................... 62
CONFIGURATION WORD ........................................................................................................................................ 62
APPENDICE D ...................................................................................................................................................... 63
STRUTTURA DELLA RAM - F ILE REGISTERS ........................................................................................................... 63
REGISTRO DI S TATO – S TATUS REGISTER ............................................................................................................... 64
APPENDICE E....................................................................................................................................................... 65
SET DI ISTRUZIONI PER I PIC .................................................................................................................................. 65
APPENDICE F....................................................................................................................................................... 66
ADCON0 REGISTER ............................................................................................................................................. 66
ADCON1 REGISTER ............................................................................................................................................. 67
APPENDICE G ...................................................................................................................................................... 68
STANDARD RS232................................................................................................................................................. 68
INDICE ANALITICO............................................................................................................................................. 70
II
Introduzione Alla Programmazione Dei PIC16F876
1.1. Premessa
Lo scopo che ci prefiggiamo scrivendo questo testo è di insegnare il linguaggio assembly
per la programmazione dei microcontrollori PIC16F876 della Microchip per permettere di sfruttare
tutte le potenzialità di questo integrato.
Il testo è stato scritto considerando che il lettore conosca già la tipologia di programmazione
in assembly, quindi non verranno spiegati i significati di parole come Program Counter, Stack,
Opcode, Direttive al compilatore, Istruzioni, Interrupt…
Al lettore digiuno da questo tipo di linguaggio si consiglia di studiare su un testo specifico
all’insegnamento del linguaggio assembly e solo in un secondo momento di affrontare la lettura di
questo, mentre per tutti quelli a cui serva solo un ripasso veloce dei termini di sopra elencati si
consiglia di leggere sul sito www.tanzilli.com il corso introduttivo alla programmazione del
PIC6F84 dove sono rivisti in sufficiente dettaglio i termini principali dell’assembly riferendoli
subito al mondo dei PIC della Microchip.
1.2. Il PIC16F876
Il microcontrollori PIC (Programmable Interface Controller) con la sigle 16F876 si presenta
come un integrato a 28 piedini1 posto in un contenitore DIP-SOIC.
Questo dispositivo oltre ad essere una CPU “in miniatura” possiede delle periferiche
integrate.
L’architettura utilizzata per il set d’istruzioni è di tipo RISC e ogni istruzione viene
identificata da un parola di 14bit: questa caratteristica impone un set limitato di istruzioni (35) e
quindi risulta che mancano istruzioni come moltiplicazione e divisione. Per quanto riguarda i dati
questi sono memorizzati in parole da 8bit.
Altra considerazione di importanza, per quel che riguarda l’architettura, è la presenza di un
solo registro interno che è quello di accumulazione denominato con la lettera ‘W’ (facendo
rferimento al mondo Intel a 16bit si può dire che esite solo il registro AX e mancano registri come
BX, CX, DX, SI, DI…)
La mancanza di questi espliciti registri però è supplita dalla presenza di memoria RAM
integrata sul CHIP (si hanno a disposizione 512 Bytes di memoria RAM di cui 144 Bytes riservati
1
Ci sono PIC anche con un numero diverso di piedini a seconda del numero di periferiche integrate che
possiedono e del tipo di compito a cui sono destinati. Il PIC16F876 fa perte della famiglia PIC16F87x, dove al posto
della x si anno le sigle 3,4,6 o7. Questi PIC, oltre ad essere diversi internamente possiedono anche un diverso numero di
piedini: 28 per i 16F873/6 e 40 per il 16F874/7.
1
Introduzione Alla Programmazione Dei PIC16F876
per la gestione del dispositivo e 368 Bytes liberi per utilizzo generale!!) che possono essere usati
alla stregua di registri! (quindi si può considerare la presenza di 368 registri a 8bit… calma non
esaltatevi: NON sono VERI registri sono locazioni di RAM usate COME registri, quindi ci saranno
degli accorgimenti per poterli usare.)
Le istruzioni del programma sono memorizzate su una memoria FLASH, avente 8k
(8192) locazioni di memoria da 14bit, e sono indirizzate attraverso un PC (Program Counter) da
13bit. La loro memorizzazione, in genere, viene effettuata mediante un Programmatore di Memorie
Flash oppure può essere fatta attraverso un procedimento di In-Circuit Serial Programming (ICSP)
attraverso due pin dell’integrato.
Si vuole ricordare la presenza di un’ulteriore forma di memorizzazione attraverso una
EEPROM (256 Bytes) che permette la memorizzazione di dati che permangono anche con lo
spegnimento del dispositivo.
Il PIC prevede l’interruzione del programma principale attraverso la gestione di Interrupt.
Bisogna fare attenzione perchè le potenzialità di controllo degli Interrupt sono ridotte da diversi
fattori: la non esistenza di una gerarchia di priorità, la gestione di un interrupt disabilita il
riconoscimento di un ulteriore Interrupt e la routine richiamata quando si verifica un Interrupt è
unica e quindi è compito del programmatore riconoscere l’evento che si è determinato.
Altre caratteristiche sono la possibilità di portare il componente in una modalità di risparmio
energetico (Sleep Mode) e di poter scegliere la frequenza di oscillazione, dove le frequenze
ammissibili vanno da 0 a 20 MHz che portano il PIC a funzionare tra 0 e 5 MHz2.
Per fare un rapido elenco delle periferiche integrate nel PIC si possono ricordare:
• 3 porte di Input/Output selezionabili: due con 8 piedini e una con 6 piedini
• 3 contatori: due a 8bit e uno a 16 bit. Possono sia servire per conteggi di tempo che di eventi e
con la possibilità di variare la frequenza di conteggio attraverso dei “prescaler” (Divisore di
frequenza di conteggio)
• 2 moduli che possono funzionare alternativamente come “Catturatori di eventi”,
“Comparatori”, o “Modulatori PWM”
• 5 ingressi facenti capo, attraverso un multiplexer, a un ConvertitorieAnalogico-Digitale a
10bit
• Interfaccia di Comunicazione seriale sia Sincrona che Asincrona
2
Questo è dovuto al fatto che la frequenza a cui vengono eseguite le istruzioni nella CPU risulta essere ¼ della
frequenza scelta per l’oscillatore.
2
Introduzione Alla Programmazione Dei PIC16F876
Capitolo 2 La Programmazione
2.1. Premessa
Il capitolo, attraverso un semplice esempio di programma, introduce la programmazione in
assembly del PIC.
Le sole periferiche considerate sono le porte di I/O, che , per ora, sono viste sotto l’aspetto
di registri logici e non come periferiche hardware: viene seguito questo primo approccio per
focalizzare l’attenzione sul funzionamento del PIC come microprocessore e non come
microcontrollori.
Gli argomenti di seguito trattati sono: direttive al compilatore, principi di programmazione,
gestione della memoria, gestione del processo, stack e gestione delle porte di I/O.
PROCESSOR 16F876
RADIX DEC
INCLUDE "P16F876.INC"
ERRORLEVEL -302
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _WRT_ENABLE_ON & _LVP_OFF
LED EQU 0
ORG 0x20
Count RES 3
3
Introduzione Alla Programmazione Dei PIC16F876
;Reset Vector
;Start point at CPU reset
ORG 0x00
bsf STATUS,RP0
movlw B'00011111'
movwf TRISA
movlw B'11111110'
movwf TRISB
movlw B'00111100'
movwf TRISC
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
;Software delay
Delay
clrf Count
clrf Count+1
clrf Count+2
DelayLoop
decfsz Count,1
goto DelayLoop
decfsz Count+1,1
goto DelayLoop
decfsz Count+2,1
goto DelayLoop
return
END
F IL E 1 . A S M – P R IM O P R O G R A M M A
Per prima cosa vediamo la direttiva PROCESSOR che seleziona il tipo di microprocessore
utilizzato, quindi si trova radix che setta la notazione numerica di default alla quale il compilatore
associa tutti i numeri che nel programma sono indicati senza una notazione esplicita. Le alternative
sono hex, dec o oct.
Durante la programmazione i numeri possono essere immessi con notazioni differenti da
quella scelta per default; le notazioni accettate sono:
4
Introduzione Alla Programmazione Dei PIC16F876
F IG . 2 .2 -1 – N O TAZ IO N I N U M ER IC H E D E L C O M P IL ATO R E
Ritornando alla spiegazione del nostro file, la direttiva che si incontra in questo momento,
__CONFIG, è forse una delle più importanti in quanto il buon funzionamento del circuito dipende dal
giusto settaggio delle ‘Caratteristiche speciali della CPU’. Per i nostri scopi la configurazione, così
come è settata va più che bene. Per maggiori chiarimenti fare riferimento all’Appendice C (in cui è
riportata la Configuration Word) oppure al datasheet del componente a pag. 121.
Come per l’assembly usato per i processori Intel, la direttiva che ora i ncontriamo
LED EQU 0
serve per definire una costante, in questo caso di nome LED e avente il valore, in decimale,
pari a 0.
3
La spiegazione degli operatori &, != ecc. si può trovare nell’Appendice B.
5
Introduzione Alla Programmazione Dei PIC16F876
F IG . 2 .2 -2 – S TR U TTU R A D E L L A P R O G R AM M E M O R Y E S TAC K
La direttiva ORG serve al compilatore per capire in quale indirizzo di memoria porre il codice
che la segue. Nel nostro caso ci interessa prima definire la posizione della memoria RAM in cui
vogliamo allocare (o riservare) delle celle di memoria e poi definire la posizione di inizio del nostro
programma sulla FLASH. Si vuole far notare che la direttiva ORG usata per riservare memoria sulla
RAM e per scrivere il programma sulla flash è identica: è quindi compito del compilatore capire a
quale memoria si sta facendo riferimento.
Al programma è riservata l’indirizzo 0x00 (vedi figura 2.2 -2) mentre, come vedremo più in
dettaglio, alla routine di interrupt è riservato l’indirizzo 0x04.
Come si può vedere nell’Appendice D la memoria libera , cioè non riservata a speciali
funzioni del PIC, risulta essere indicata con la dicitura ‘General Purpose Register’ ed è
complessivamente pari a 368 Bytes. Ogni cella di memoria è di 8bit e gli indirizzi di partenza dai
quali si può allocare memoria sono: 0x20, 0xA0, 0x110 e 0x190.
F IG . 2 .2 -3 – I N D IR IZZ AM E N TO D E L L E M E M O R IE F L ASH E R AM
6
Introduzione Alla Programmazione Dei PIC16F876
dedicati (chiamati RP1 e RP0) che si trovano nel registro STATUS (Appendice D). Si osservi, nella
struttura del File Register (Appendice D), che questo registro è presente in ogni banco di memoria a
causa della sua importanza. Nel registro STATUS, infatti, sono elencati i seguenti bit di stato:
• RP1 e RP0 che servono per indirizzare i 4 banchi di memoria
Per selezionare i banchi si devono rispettare queste combinazioni:
RP1:RP0 Bank
00 0
01 1
10 2
11 3
• IRP è un bit che viene abilitato quando si esegue un indirizzamento indiretto della
memoria
• TO e PO utilizzati da istruzioni quali SLEEP oppure dal Watchdog
• Z che viene settato a uno se il risultato di un' operazione logica o aritmetica è nullo
• DC il bit dove viene registrato il riporto dovuto al quarto bit
• C è il bit dove viene registrato il riporto
Ritornando al programma …
L' istruzioneORG 0x20 risulta essere la direttiva che comunica al compilatore che ciò che
segue è codice che si trova nella memoria RAM! Nel nostro caso la linea seguente del programma
permette di allocare 3 Byte di memoria indicandola attraverso una etichetta mnemonica COUNT.
Dopo aver riservato 3 Byte di memoria la nuava direttiva org 0x00 comunica al compilatore
che da questo punto incomincia il programma principale.
4
Fate riferimento all' Appendice E per avere una visione ompleta
c delle istruzioni o al datasheet del
componente a pag.139 per avere la spiegazione di ogni singola istruzione.
5
In realtà il valore logico 1 è relativo alla tensione +5V mentre lo 0 ai 0V. Sapendo questo si può pensare di
collegare opportunatamente ai piedini di output un led che si accenderà quando ai piedini arriva un 1 logico, oppure un
interruttore ai piedini di input che comunicheranno un 0 logico quando si chiuderà il contatto.
7
Introduzione Alla Programmazione Dei PIC16F876
F IG . 2 .3 -1 – P O S IZ IO N E D E L L E P O R TE N EL L ’ IN TE G R ATO A 2 8 P IN
Ogni porta è provvista/assistita da due registri a 8 bit: uno che serve per tenere le
informazioni sullo stato di utilizzo della porta, cioè se i singoli piedini sono usati come Input
(indicati nel registro attraverso un 1) o come Output (indicati con uno 0), e denominato con TRISx,
mentre l' altro mantiene traccia del dato presente nella porta (stato logico 1 o 0) e denominato con
PORTx (Attenzione stesso nome duplice significato!).
Ad ogni bit dei registri PORTx e TRISx corrisponde un piedino I/O del PIC.
Esempio.
- se il dato presente nel registro TRISB risulta essere B' 00001111' avremo che i piedini
della porta B saranno settati metà come Output (0) e metà come Input (1): nel caso in
esame i piedini RB4, RB5, RB6, RB7 saranno output mentre RB0, RB1, RB2, RB3
saranno Input.
- Considerando la stessa porta si può vedere che se il dato presente nel registro PORTB
fosse B' 00001111' avremo che il PIC sta ricevendo, dai piedini d' ingres
so, degli 1 e sta
trasmettendo degli 0.
…riprendiamo il FILE1.ASM
L' istruzione
BSF STATUS, RPO
Serve per settare la coppia di bit RP1:RP0=01 in modo da abilitare il BANK1 di memoria
RAM.
BSF, letteralmente ' Bit Set File register' , permette di settare a 1 il bit nella posizione RPO
contenuto nella locazione di RAM indirizzata da STATUS6.
Una vola abilitato il BANK1 si può aggiornare il funzionamento I/O delle porte7 A , B e C
andando ad impostare il valore dei registri TRISA, TRISB e TRISC.
6
STATUS, come RP0, W ecc.. sono costanti, che si riferiscono a registri o a bit, che sono definite all’interno
del file P16F876.INC, per questo motivo devono essere scritte in maiuscolo. Queste costanti permettono una più
semplice programmazione in assembly liberando il programmatore dall’onere della conoscenza dell’ind irizzo numerico
di ogni singolo registro o posizione dei bit all’interno dei registri.(vedere Appendice A)
8
Introduzione Alla Programmazione Dei PIC16F876
movlw B'11111110'
movwf TRISB
movlw B'00111100'
movwf TRISC
dove MOVLW permette di portare la costante B' 000111111' (in gergo detta LITERAL, e da
questo nome deriva la L presente in MOVLW) nell' accumulatore W (da qui la W in MOVLW). In
un secondo momento MOVWF permette di spostare il dato dall' accumulatore allaRAM (che in
gergo viene chiamata File Register, e da qui la F in MOVWF) nella posizione indirizzata dalla
costante TRISA.
Una volta aggiornati i Registri TRISx si deve riselezionare il BANK0 per poter abilitare
l' utilizzo del registri PORTx. Per far quest
o è usata l' istruzione BCF(Bit Clear File register) che
permette di ripristinare nel registro STATUS RP1:RP0=00.
Il programma ora porta a 1 il piedino 0 della porta B, che precedentemente si era abilitato
come output, attraverso:
bsf PORTB,LED
E' significativo notare come una istruzione del genere possa permettere l’accensione di un
led se questo fosse connesso al pin 0 della porta B: la costante LED=0 assume il significato di
indicatore del piedino a cui è connesso il led.
Nel nostro programma, all' interno del MainLoop, troviamo una chiamata alla subroutin
Delay tramite l’istruz ione call. Delay è una subroutine che esegue un ritardo software.
Le istruzioni usate in questa subroutine, oltre alle istruzioni goto e return, sono:
- CLRF che permette di azzerare il registro indirizzato
- DECFSZ che decrementa un registro in memoria e nel momento in cui questo venga
azzerato, il programma esce dal DelayLoop saltando l’operazione GOTO.
7
L' aggiornamento dello stato delle porte è una delle operazioni che per prime devono essere fatte durante la
programmazione. Durante questo aggiornamento si deve tener in considerazione le tipologia di circuito dove il PIC sarà
inserito.
9
Introduzione Alla Programmazione Dei PIC16F876
ci sono due problemi da non sottovalutare per queste istruzioni: la dimensione massima dello Stack
e la paginazione della Flash.
Come si può vedere dalla figura 2.2-2 la paginazione suddivide la FLASH in quattro parti.
Questa suddivisione comporta un problema sia per l' istruzione CALL che per la GOTO (che per la
RETURN). C' è da dire, innanzitutto che per programmi di piccole dimensioni la memoria occupata
dal codice rimane confinata nella pagina 0, solo per grandi programmi si deve considerare la
gestione delle pagine.(Nel caso si debbano scrivere programmi di grandi dimensioni si consiglia di
vedere pag. 26 del datasheet del componente)
Il problema dello Stack riguarda, invece, la sola istruzione CALL. Lo Stack ha una
dimensione massima di 8 livelli che permettono un' annidamento di 8 chiamate. Caratteristica dello
Stack è di essere un buffer circolare (se lo stack è stato riempito per 8 volte la nona volta viene
riscritto il valore che era stato accantonato per primo!) senza nessun controllo sulle condizioni di
Overflow e Underflow, e senza la possibilità di utilizzare istruzioni dirette, come potrebbero essere
PUSH e POP, per la gestione dello Stack in quanto sono assenti. MORALE: ATTENZIONE
durante la programmazione a non superare le 8 chiamate!!
L' uni
ca volta in cui potrebbe essere utile o ininfluente la caratteristica ciclica dello Stack
rigurda quei programmi aventi più MainLoop e che quindi possono spostarsi da uno ' stato stabile' ad
un altro anche eseguendo durante questi spostamenti più di 8 chiamate annidiate!(vedi figura)
10
Introduzione Alla Programmazione Dei PIC16F876
......
Si possono fare due osservazioni: la prima è che con questo tipo di programmazione non ci
interessa sapere a priori la posizione dei registro in memoria, quindi si semplifica molto la
programmazione, la seconda è che questo metodo provoca un maggior dispendio di memoria per la
programmazione in quanto alcune istruzioni sono superflue.
Un esempio di questo tipo di programmazione si trova nel “file2.asm” dove si è riscritto il
“file1.asm” con le nuove direttive8.
;
; File002.asm
;
PROCESSOR 16F876
RADIX DEC
INCLUDE "P16F876.INC"
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _WRT_ENABLE_ON & _LVP_OFF
LED EQU 0
ORG 0x20
Count RES 3
;Reset Vector
;Start point at CPU reset
ORG 0x00
banksel TRISA
movlw B'00011111'
movwf TRISA & 7FH
movlw B'11111110'
movwf TRISB & 7FH
movlw B'00111100'
movwf TRISC & 7FH
Banksel PORTB
bsf PORTB,LED
MainLoop
call Delay
8
Si ricorda che durante la compilazione il software della Microchip darà sempre il messaggio di “errore” per
tutti i registri che si trovano sul bank1. Questo messaggio , come prima detto, non deve essere considerato, oppure si
può risolvere con la direttiva errorlevel o aggiungendovi al nome del registro & 7FH.
11
Introduzione Alla Programmazione Dei PIC16F876
btfsc PORTB,LED
goto SetToZero
bsf PORTB,LED
goto MainLoop
SetToZero
bcf PORTB,LED
goto MainLoop
;Subroutines
;Software delay
Delay
clrf Count
clrf Count+1
clrf Count+2
DelayLoop
decfsz Count,1
goto DelayLoop
decfsz Count+1,1
goto DelayLoop
decfsz Count+2,1
goto DelayLoop
return
END
F IL E 2 . A S M – P R IM O P R O G R A M M A C O N B A N K S E L
2.6. Conclusioni
Il programma FILE1.ASM non si limita, quindi, a variare lo stato logico dei bit di un
registro , ma permette di portare ad 1, con una certa frequenza determinata della routine di ritardo
software,un pin di uscita de PIC; inoltre se pensassimo di connettere a questo piedino un led, un
programma del genere farebbe in modo che il led possa lampeggiare aritmicamente.
12
Introduzione Alla Programmazione Dei PIC16F876
3.1. Premessa
Nel capitolo precedente si era accennato ad un oscillatore a 20 MHz, in questo si imparerà
ad ottenerne uno facendo uso di un solo quarzo e due capacità sfruttando le caratteristiche circuitali
dell’integrato. Il PIC, come detto nell’introduzione, può funzionare con diverse frequenze, quindi si
parlerà pure di come ottenere diversi valori di frequenze o come utilizzare un generatore di clock
esterno.
Importante è però capire che vi è una differenza tra la frequenza dell’oscillatore esterno e la
frequenza del clock interno con cui vengono eseguite le istruzioni del PIC, questo a causa del fatto
che la frequenza del clock interno risulta da una divisione per 4 della frequenza dell’oscillatore
esterno.
13
Introduzione Alla Programmazione Dei PIC16F876
F IG . 3 .2 -1
Le modalità vengono scelte per mezzo della direttiva al compilatore __CONFIG (vedi
capitolo 2)
Se si vuole si può, inoltre, collegare il PIC ad una sorgente esterna di clock, ad esempio
quando si devono pilotare più microcontrollori che lavorino in modo sincronizzato, in questo caso
le configurazioni da usare sono LP, XT e HS.
14
Introduzione Alla Programmazione Dei PIC16F876
Capitolo 4 Interrupt
4.1. Premessa
Il PIC 16F876 possiede vari tipi di Interrupt. Si parla di 14 differenti sorgenti di interrupt,
ma molto facilmente nella programmazione se ne terranno in considerazione ben pochi: due o, più
frequentemente, uno. Questo vuol dire, da una parte, che durante la programmazione ci si dovrà
preoccupare di selezionare i tipi di interrupt di nostro interesse e dall' altra che si dovrà programmare
le routine ad hoc che ci permettano di gestire gli interrupt. Per fare questo si devono conoscere tre
aspetti: il primo è che per ogni interrupt che si verifica la chiamata a sottoprogramma che il PIC
esegue è unica per tutti gli interrupt e avviene all' indirizzo0x04 della memoria Flash (vedi figura
2.2-2),il secondo è che ci sono ben 5 registri dedicati alla gestione degli interrupt e il terzo è che sta
al programmatore verificare il tipo di interrupt che si è verificato andando a testare i registri
dedicati.
...
...
retfie ;Ritorna al programma principale nella
;posizione in cui si è generato l'interrupt
15
Introduzione Alla Programmazione Dei PIC16F876
Dall’esempio si nota che subito dopo aver dato origine al programma si deve fare un salto
incondizionato in modo tale che il compilatore riservi il posto alla routine di interrupt nella
memoria FLASH. Per riservare il posto alla routine di interrupt basta dichiarare la sua posizione con
la direttiva ORG 04H e quindi scrivere il suo codice.
Per poter programmare bene una routine di gestione degli interrupt è bene conoscere in che
modo le interruzioni vengono gestite.
Quando si verifica un' interrupt il PIC esegue alcune operazioni: disabilita il bit GIE del
registro INTCON in modo tale che non vengano gestiti altri interrupt contemporaneamente9, viene
abilitato il bit relativo all' interrupt che si è verificato, detto FLAG BIT, viene registrato nello stack
il PC e chiamata la locazione di memoria 0x04.
Quindi, sapendo questo, durante la programmazione di questa routine si deve:
- Fare attenzione alla posizione dove si colloca la sequenza iniziale della routine che deve
essere la 0x04 in modo che possa essere chiamata. (Questo viene fatto, come da
esempio, dalla direttiva ORG 04H)
- Salvare i dati10 del registro di stato STATUS e il registro accumulatore W (e altri
registri che si pensa possano essere modificati durante l' interruzione). Questa è una delle
classiche operazioni fatte nella gestione degli interrupt, essendo queste chiamate in
momenti sconosciuti dell’esecuzione del programma.
- Identificare l' interrupt testando i bit di interesse dei registri: INTCON, PIR1,PIR2
- Chiamare la subroutine di gestione appropriata
- Cancellare il bit che identifica l' interrupt
- Ripristinare gli eventuali registri precedentemente salvati
- Uscire dalla subroutine attraverso l' istruzioneretfie che oltre a ricaricare dallo stack il
PC riporta a 1 il bit GIE per poter rilevare altri eventuali interrupt
corpo_routine_interrupt_inizio
....
....
....
corpo_routine_interrupt_fine
banksel status_temp ;
movf status_temp,W ;
movwf STATUS ;
swapf w_temp,F ; Recupero i registri
swapf w_temp,W ; W e STATUS salvati.
retfie ; Fine routine di Interrupt
9
Attenzione: questo potrebbe essere un problema! Nel PIC, infatti, non esiste una gerarchia di interrupt, quindi
l' interrupt che viene gestito è quello che si verifica per primo: è questo il perché è consigliabile implementare pochi
interrupt nel programma, in modo da evitare che se ne verifichi uno mentre ne viene gestito un altro perdendo così la
possibilità di osservarlo!
10
Non è necessario se questi non vengono modificati, mentre è di grande importanza se si ha la possibilità che
invece lo siano.
16
Introduzione Alla Programmazione Dei PIC16F876
....
....
NOTA: È molto probabile che una routine di questo tipo possa dare dei problemi durante il
salvataggio del registro STATUS. Infatti nella seconda riga si può vedere che la direttiva Banksel
prende il posto di una istruzione tipo BSF STATUS,RP0 che presuppone una variazione del registro
STATUS prima ancora che si sia fatta una sua copia. Da notare che però anche se tecnicamente non
corretta, una routine di questo tipo da problemi solo se viene chiamata, da un interrupt, in un punto
del programma dove il banco di memoria selezionato risulta essere diverso da quello in cui si trova
STATUS_TEMP, mentre non provoca nessun problema se ad esempio viene richiamata all' interno
di un loop infinito in cui si era già preselezionato il banco di memoria di STATUS_TEMP. Nello
stesso tempo, però una routine di questo tipo permette una gestione più veloce dell' interrupt rispetto
ad una routine che invece non presenta questo tipo di errore. Morale: state attenti quando usate una
routine di questo tipo e valutate se il risparmio di tempo è essenziale o se è meglio evitare possibili
problemi durante la chiamata di interrupt.
Una possibile gestione alternativa dell' interrupt che ene
ti conto del banco di memoria può
essere:
ORG 0x20
....
....
status_temp RES 1
w_temp RES 1
....
....
banco_0o1
btsfsc STATUS, RP0
goto banco_1
banco_0 ; RP1:RP0= 00
banksel status_temp ;
movwf w_temp ; Salvo lo stato dei registri
movf STATUS,W ; W e STATUS.
movwf status_temp ;
bcf status_temp, RP1
bcf status_temp, RP0
goto corpo_routine_interrupt_inizio
banco_1 ; RP1:RP0= 01
banksel status_temp ;
movwf w_temp ; Salvo lo stato dei registri
movf STATUS,W ; W e STATUS.
movwf status_temp ;
bcf status_temp, RP1
bsf status_temp, RP0
goto corpo_routine_interrupt_inizio
banco_2o3
btsfsc STATUS, RP0
goto banco_3
banco_2 ; RP1:RP0= 10
banksel status_temp ;
movwf w_temp ; Salvo lo stato dei registri
movf STATUS,W ; W e STATUS.
movwf status_temp ;
bsf status_temp, RP1
bcf status_temp, RP0
goto corpo_routine_interrupt_inizio
banco_3 ; RP1:RP0= 11
banksel status_temp ;
17
Introduzione Alla Programmazione Dei PIC16F876
corpo_routine_interrupt_inizio
....
....
....
corpo_routine_interrupt_fine
banksel status_temp ;
movf status_temp,W ;
movwf STATUS ;
swapf w_temp,F ; Recupero i registri
swapf w_temp,W ; W e STATUS salvati.
retfie0x04 ; Fine routine di Interrupt
....
....
Una semplice osservazione che si vuole fare è che il salvataggio di W e STATUS non è
sempre essenziale. Per suffragare questa affermazione si consideri questo semplice esempio
(file3.asm) in cui non è presente alcun accorgimento per il salvataggio dei dati del registro STATUS
e W.
;
; file0003.asm
;
; Programma che fa lampeggiare il led sull'uscita 0 della porta B
; Viene abilitato un'interrupt che segnala il cambiamento di stato delle linee RB4, RB5,RB6,RB7
; della porta B facendo accendere il led dell'uscita 1 della porta B
; Il led che si è acceso con l'interrupt si spegnerà dopo tre lampeggi del diodo intermittente
PROCESSOR 16F876
RADIX DEC
INCLUDE "P16F876.INC"
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _WRT_ENABLE_ON & _LVP_OFF
LED1 EQU 0
LED2 EQU 1
LED3 EQU 2
LED4 EQU 3
ORG 0x20
Count RES 3
nTick RES 1 ;Registro utilizzato per contare il numero di
;lampeggi del LED 1
;Reset Vector
;Punto di inizio del programma al reset della CPU
ORG 00H
18
Introduzione Alla Programmazione Dei PIC16F876
;interrupt.
goto Start
;Interrupt vector
;Punto di inizio per tutte le subroutine di gestione degli interrupt
ORG 04H
;**********************************************************************
; Interrupt handler
;**********************************************************************
;**********************************************************************
; Corpo del programma
;**********************************************************************
Start:
;Commuta sul secondo banco dei registri per accedere ai registri TRISA e TRISB
banksel TRISA
movlw 00011111B
movwf TRISA & 7FH
movlw 11110000B
movwf TRISB & 7FH
banksel LED1
;**********************************************************************
; Loop principale
;**********************************************************************
MainLoop
19
Introduzione Alla Programmazione Dei PIC16F876
TurnOnLed1
bsf PORTB,LED1
;Spegnimento led
TurnOffLed1
;**********************************************************************
; Subroutine
;**********************************************************************
Delay
clrf Count
clrf Count+1
clrf Count+2
DelayLoop
decfsz Count,1
goto DelayLoop
decfsz Count+1,1
goto DelayLoop
decfsz Count+2,1
goto DelayLoop
return
END
F IL E 3 . A S M – G E S T IO N E I N T E R R U P T
20
Introduzione Alla Programmazione Dei PIC16F876
F IG . 4 .3 -1
Ogni bit di questi registri ha una sua funzione particolare ed esclusiva nella gestione degli
interrupt. Si può però fare una distinzione dei bit in 3 classi:
1. Il bit GIE e PEIE di INTCON
2. I bit, esclusi GIE e PEIE, il cui no,e finisce con E, cioè i bit TOIE, INTE, RBIE di
INTCON e tutti i bit di PIE1 e PIE2.
3. I bit il cui nome finisce con F, cioè i bit TOIF, INTF, RBIF di INCON e tutti i bit di
PIR1 e PIR2.
Nella prima classe si è posto il bit GIE che è il bit di abilitazione di tutti gli interrupt che
possono essere segnalati. Come si può osservare dalla figura 4.3-2 la segnalazione degli interrupt è
fatta attraverso una rete logica e la comunicazione alla CPU dell’interrupt è vincolata dal settag gio a
uno di GIE.
F IG . 4 .3 -2
11
Si veda il datasheet del PIC per maggiori dettagli: pag 20 e seguenti
21
Introduzione Alla Programmazione Dei PIC16F876
Allo stesso modo il bit PEIE possiede una grande importanza in quanto blocca la
comunicazione di un interrupt da tutta una serie di sorgenti. Questo tipo di interruzioni vengono
chiamate Interruzioni di periferica (Peripheral Interrupt).
Senza addentrarci nella gestione di ogni singola sorgente di interruzione, possiamo dire che
il registro INTCON permette la gestione degli INTERRUPT provenienti dal TIMER0, dal pin
RB0/INT della porta B, e dai piedini RB4:RB7 sempre della porta B, mentre tutte gli altri interrupt
sono generati dalle periferiche e quindi sono trattati in modo a se stante attraverso i registri PIEx e
PIRx.
La seconda classe si compone dei bit, detti ENABLE BIT, che permettono l’abilitazione o la
disabilitazione della segnalazione del singolo interrupt.
Nell’ultima classe si hanno i cosiddetti FLAG BIT che segnalano l’avvenuto interrupt.
Molto importante è sapere che anche quando una sorgente di interrupt non viene abilitata per mezzo
del suo ENABLE BIT, se si verifica un interrupt questo viene segnalato sul FLAG BIT, e la
comunicazione alla CPU dell’interruzione è ostacolata dall’AND logico con l’ENABLE BIT.
Si vuole far presente che all’uscita della routine di getione dell’interrupt è compito del
programma il ritorno a zero del FLAG BIT che ha generato l’interrupt, pena la nuova richiamata
della stessa interruzione.
22
Introduzione Alla Programmazione Dei PIC16F876
5.1. Premessa
In questo capitolo si parla delle periferiche del PIC usate come contatori ti tempo e di eventi.
5.2. Il Timer 0
Questo modulo è un contatore di tempo, o di eventi, a 8 bit. Il registro usato per il conteggio
è detto TMR0.
In questa periferica si possono vedere 4 sezioni distinte:
1. l' ingresso del clock del contatore
2. il prescaler a 8 bit
3. il modulo del watchdog
4. il registro a 8 bit TMR0
F IG . 5 .2 -1 - T IM E R 0
23
Introduzione Alla Programmazione Dei PIC16F876
F IG . 5 .2 -2
Partendo dalla sezione d' ingresso del clock possiamo vedere che il bit T0CS quando è a 0
seleziona come clock del timer il clock di sistema, mentre se è a 1 abilita il clock esterno presente
sul piedino 6 (denominato RA4/T0CKI)13. Il bit T0SE permette di selezionare il fronte di salita, del
clock esterno, con cui fare procedere il conteggio. Osserviamo che questo dispositivo si presta sia
per un conteggio di tempo (sia quando si abilita il clock interno, sia quando si abilita un clock
esterno), sia per un conteggio di eventi, quando al piedino 6 fa capo un segnale che commuta per
segnalare un evento.
Il prescaler è invece un dispositivo che permette di "dividere" la frequenza di clock
(attraverso la scelta opportuna dei bit PS2:PS0, vedi figura 4.2-3) e quindi permette di incremetare
il contatore come se avessimo a disposizione frequenze di clock differenti. Questo modulo è
comune sia al TIMER0 che al Watchdog, quindi la selezione, attraverso il bit PSA, dell' utilizzo per
uno ne esclude l' uso da parte dell' altro. (vedi figura 4.2
-1)
F IG . 5 .2 -3
Il watchdog è una periferica a se stante rispetto al TIMER0 che ha in comune con esso
l' utilizzo del solo Prescaler. Il Watch Dog Timer è un oscillatore interno al PIC, ma completamente
indipendente dal resto della circuiteria, il cui scopo è quello di rilevare eventuali blocchi del flusso
normale del programma e attraverso un reset del microcontrollori di ripristinare la normale
esecuzione. (Per maggiori chiarimenti sul watchdog fare riferimento al datasheet)
Infine è nel registro TMR0 che è contenuto il dato del conteggio. Questo registro è
accessibile sia in scrittura che in lettura, questo comporta sia la possibilità di fare partire il
conteggio da un valore desiderato, sia la possibilità di osservare lo stato del conteggio. Essendo a 8
12
Si veda pag. 48 del datasheet per maggiori informazioni
13
Ricordiamo che il piedino 6 si trova sulla porta A e quindi per abilitare il suo uso come clock esterno si deve
abilitare il piedino come ingresso segnalandolo nel registro TRISA. Bisogna poi provvedere ad un' adeguata elettronica
esterna.
24
Introduzione Alla Programmazione Dei PIC16F876
bit, una volta raggiunto il valore 255 all’incremento successivo il contatore si azzera andando in
overflow. L’overflow del timer 0 genera un interrupt segnalato dal bit T0IF del registro INTCON.
5.3. Timer 1
Questo modulo è un contatore di tempo o di eventi a 16 bit. Il registro a 16bit è detto TMR1
ed è formato da due registri a 8 bit (TMR1H:TMR1L) che possono essere letti o scritti. Dopo
l’accensione del PIC il valore presente in questi registri è sconosciuto e quindi si deve pensare di
aggiornarli se si intende usare il timer1. Questo modulo permette la generazione di un interrupt
quando si verifica l’overflow del registro TMR1 con la segnalazione nel flag TMR1IF nel registro
PIR1.
F IG . 5 .3 .2 -5 .3 -1 – T IM E R 1
Il timer1 è assistito dal registro T1CON (vedi pag 51 del datasheet) che permette: la scelta
della divisione del prescaler, l’abilitazione o la disabilitazione dell’incremento del registro TMR1 e
la scelta del tipo di clock da usare. Caratteristica peculiare di questo timer è la possibilità di
collegare un circuito oscillatore dedicato e permettere, quindi, un conteggio sia sincrono che
asincrono, alla frequenza desiderata.
Questa periferica può essere usata da sola oppure insieme alle funzioni Capture e Compare
delle periferiche CCP. (Si faccia riferimento al capitolo dedicato)
5.4. Timer2
Questo modulo è un contatore a 8 bit esclusivamente alimentato dal clock di sistema: può
essere quindi solo un contatore di tempo. Il registro dove viene memorizzato il conteggio è il
TMR2.
25
Introduzione Alla Programmazione Dei PIC16F876
F IG . 5 .4 .3 -5 .4 -1 – T IM E R 2
26
Introduzione Alla Programmazione Dei PIC16F876
6.1. Premessa
Tutti funzioni eseguite dal PIC devono poter comunicare con la circuiteria elettronica
esterna. Questa comunicazione viene fatta attraverso le 3 porte del PIC.
Nel capitolo 2 si è parlato di queste porte a livello logico: da allora si è appreso che per la
configurazione in ingresso o in uscita i singoli piedini di una porta si deve configurare i registro
TRIx a lei relativo, mentre per leggere o scrivere si usa il registro PORTX.
Nella realtà le porte del PIC risultano essere dispositivi hardware abbastanza complessi,
dove ogni singolo piedino può avere caratteristiche a se stanti e che quindi merita esso stesso la
definizione di dispositivo.
In questo capitolo saranno discusse nel dettaglio le caratteristiche di queste periferiche.
6.2. Porta A
Questa porta è contraddistinta da 6 piedini di I/O che, sull' integrato DIP
-SOIC a 28 piedini,
si posizionano dal numero 2 al numero 7. I nomi e le funzioni di queste linee sono:
- RA0/AN0 : piedino I/O – ingresso analogico
- RA1/AN1 : piedino I/O – ingresso analogico
- RA2/AN2/VREF- : piedino I/O – ingresso analogico
- RA3/AN3/VREF+ : piedino I/O – ingresso analogico
- RA4/TOCKI : piedino I/O – ingresso clock esterno per Timer0
- RA5/AN4/SS : piedino I/O – ingresso analogico – ingresso per trasmissioni seriali
Il funzionamento di queste linee, come si può vedere dal nome che portano, può essere
diverso, tuttavia si può osservare come la configurazione dello stadio di uscita sia lo stesso (ad
esclusione della porta RA0/TOCKI)
6.2.1. Stadio di uscita delle linee RA0, RA1, RA2 ,RA3 e RA5
Iniziamo dal gruppo di linee RA0, RA1, RA2 ,RA3 e RA5 per le quali è riportato lo schema
di uscita nella figura 5.2-1.
Prendiamo come esempio la linea RA0 ed analizziamo il funzionamento dello stadio d' uscita
sia quando la linea funziona in ingresso, che quando funziona in uscita.
27
Introduzione Alla Programmazione Dei PIC16F876
F IG . 6 .2 -1
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 la collegheremo.
Applicando 0 o 5 volt al pin RA0, sarà possibile leggerne lo stato sfruttando la circuiteria
d' ingresso del blocco rappresentata dal TTL input buffer e dal latch d' ingresso.
Questi cinque ingressi possono essere utilizzati come ingressi analogici da inviare al
convertitore D/A. Per questo motivo vi è un ulteriore registro ADCON1 (vedi il capitolo dedicato)
che permette di selezionare l’entrata come analogica e disabilitare quindi l’ingresso digitale.
28
Introduzione Alla Programmazione Dei PIC16F876
F IG . 6 .2 -2
collegare al positivo la linea RA4. Questo significa, in termini pratici, che quando la linea RA4
viene programmata in uscita e messa a 1 in realtà non viene connessa al positivo ma rimane
scollegata. Tale tipo di circuiteria d' uscita viene denominata a "collettore aperto”.
Se vogliamo che la linea RA4 vada a 1 dovremo collegare esternamente una resistenza di
pull-up, ovvero una resistenza collegata al positivo di alimentazione.
Le caratteristiche salienti di questo pin risultano essere la presenza di un trigger di Smith in
ingresso e l’uscita a collettore (o drain) aperto.
6.3. Porta B
Questa porta è contraddistinta da 8 piedini di I/O che, sull' integrato DIP (o SOIC), si
posizionano dal numero 21 al numero 28. I nomi e le funzioni di queste linee sono:
- RB0/INT : piedino I/O – ingresso interrupt esterno
- RB1 : piedino I/O
- RB2 : piedino I/O
- RB3/PGM : piedino I/O – Piedino usato per la programmazione del CHIP
- RB4 : piedino I/O con generazione di interrupt alla sua variazione di stato
- RB5 : piedino I/O con generazione di interrupt alla sua variazione di stato
- RB6/PGC : piedino I/O con generazione di interrupt alla sua variazione di stato – Piedino
usato per la programmazione del CHIP
- RB7/PGD : piedino I/O con generazione di interrupt alla sua variazione di stato – Piedino
usato per la programmazione del CHIP
F IG . 6 .3 -1
30
Introduzione Alla Programmazione Dei PIC16F876
6.4. Porta C
Questa porta è contraddistinta da 8 piedini di I/O che, sull' integrato DIP -SOIC a 28 pin, si
posizionano dal numero 11 al numero 18. I nomi e le funzioni di queste linee sono:
- RC0/T1OSO/T1CKI : piedino I/O – Uscita oscillatore Timer1 – Ingresso clock Timer1
- RC1/T1OSI/CCP2 : piedino I/O – Ingresso oscillatore Timer1 – Ingresso Capture2 o Uscita
Compare2 o Uscita PWM2
- RC2/CCP1 : piedino I/O – Ingresso Capture1 o Uscita Compare1 o Uscita PWM1
- RC3/SCK/SCL : piedino I/O – piedino usato per trasmissioni seriali sincrone
- RC4/SDI/SDA : piedino I/O – piedino usato per trasmissioni seriali sincrone
31
Introduzione Alla Programmazione Dei PIC16F876
F IG . 6 .4 -1
32
Introduzione Alla Programmazione Dei PIC16F876
7.1. Premessa
Il PIC possiede 3 funzioni particolari che permettono di catturare il tempo presente nel
Timer 1 quando si verifica un evento esterno (funzione CAPTURE), di generare un evento quando
il conteggio del Timer1 è uguale ad un valore prefissato (funzione COMPARE) e ancora una
funzione per la generazione di una modulazione a larghezza d’impulsi (funzioni PWM – pulse wide
modulation).
Le funzioni di CAPTURE, COMPARE e PWM sono integrate in due moduli detti CCP1 e
CCP2. Quando si decide una funzione per un modulo se ne disabilita l’utilizzo delle altre due.
I due moduli sono indipendenti, e questo ci permette di scegliere per entrambi la funzione
che vogliamo. Le funzioni si appoggiano ai timer 1 e 2 in questo modo: la funzione Capture e la
funzione Compare usano il timer1, mentre la PWM il timer 2. Questo sfruttamento dei timer
comporta delle interazioni tra le funzioni che bisogna tener presente. Nella configurazione:
- PWM/Capture o Pwm/Compare: non ci sono problemi
- Capture/Capture: il Timer 1 è usato per entrambe le funzioni
- Capture/Compare: la funzione Capture può triggerare su un determinato evento
cancellando il registro TMR1
- Compare/Compare: ci sono due funzioni che portano a zero il registro TMR1
- PWM/PWM: entrambe, basandosi sul Timer 2, operano alla stessa
frequenza.
Ogni modulo CCP possiede un registro a 16 bit che assume un significato diverso a seconda
della funzione selezionata, e hanno le seguenti caratteristiche:
CCP1 Module possiede:
- Un registro CCPR1 a 16 bit formato da due registri a 8 bit: CCPR1L (byte meno significativo) e
CCPR1H (byte più significativo)
- Un registro per il controllo del modulo detto CCP1CON
- La generazione di un evento durante la comparazione che resetta il Timer1
33
Introduzione Alla Programmazione Dei PIC16F876
I registri di configurazione dei moduli CCP (CCP1CON e CCP2CON) sono così fatti:
F IG . 7 .1 -1 – R E G IS TR I C C P 1 C O N E C C P 2 C O N
F IG . 7 .2 .1 - F U N Z IO N E C APTU R E
Oss: quando si cambiano le impostazioni della funzione Capture viene generato un falso
interrupt di Capture, per evitare questo si deve disabilitare l’acquisizione dell’interrupt di cattura
(bit CCPxIE del registro PIE1) e, una volta modificata la funzione, cancellare il flag d’interrupt
CCPxIF dal registro PIR1 e riabilitare l’acquisizione in PIE1.
34
Introduzione Alla Programmazione Dei PIC16F876
F IG . 7 .3 .2 – F U N Z IO N E C O M P AR E
14
In questo caso il trmine Duty Cycle è usato erroneamente e si deve intendere come la durata in cui il segnale
rimane alto.
35
Introduzione Alla Programmazione Dei PIC16F876
F IG . 7 .4 .3 - F U N Z IO N E P W M
Le operazioni che la funzione PWM compie si possono così riassumere: quando il registro
TMR2 è uguale al registro PR2 la funzione identifica la fine di un periodo e annullando il registro
TMR2 dà origine al nuovo periodo. Nel nuovo periodo il pin CCPx è settato al livello alto per tutta
la durata del “duty cycle”. La durata del “duty cycle” è ottenuta comparando il registro CCPRxH
più due bit “accessori” con il timer2, quando si ha l’uguaglianza viene posto il pin al valore basso.
Ogni volta che si arriva alla fine del periodo viene ricaricato il registro CCPRxH più due bit
“accessori” dal registro CCPRxL:CCPxCON<5:4>. Si può quindi aggiornare il duty cycle in ogni
momento andando a cambiare il suo valore nel registro CCPRxL:CCPxCON<5:4>, però il suo
aggiornamento sarà visto nella forma d’onda di uscita solo al nuovo periodo. Durante la modalità
PWM il registro CCPRxH risulta essere di sola lettura.
36
Introduzione Alla Programmazione Dei PIC16F876
8.1. Premessa
Il PIC16F876 è internamente dotato di un convertitore A/D, che è classificato come una
periferica del PIC stesso. Qui abbiamo uno schema a blocchi del convertitore:
F IG . 8 .1 -1 – C O N V ER ITO R E A /D
Come possiamo notare il convertitore è unico mentre a monte di esso è presente un MUX
analogico necessario per settare gli ingressi analogici opportuni ( 5 ingressi per il PIC a 28 pin 8
ingressi per il PIC a 44 pin). Di default le tensioni di riferimento sono quelle di alimentazione (0-
37
Introduzione Alla Programmazione Dei PIC16F876
5V), ma con la possibilità di operare anche con riferimenti esterni Vref+ e Vref-15. I registri dove
viene letto il risultato della conversione sono ADRESH e ADRESL, mentre i registri che
permettono la configurazione del convertitore sono ADCON0, che controlla le operazioni del
modulo, e ADCON1, che permette la configurazioni delle porte in ingresso.
F IG . 8 .1 -2
F IG . 8 .2 -1
15
Che comunque devono essere sempre compresi tra 0 e 5 V.
38
Introduzione Alla Programmazione Dei PIC16F876
Affinché la conversione sia fatta correttamente bisogna attendere che la capacità venga
caricata fino al valore di tensione in ingresso. Questo tempo che si aggira intorno ai 20 µsec,
dipende sia dalla resistenza Rss del carico (meglio se <10K), sia dalla resistenza interna dello
switch elettronico (funzione della temperatura).
Una volta memorizzata analogicamente il valore di tensione può iniziare la conversione vera
e propria che richiede un tempo di circa Tad = 1.6 µsec per ogni bit di conversione (ossia 12Tad per
i 10 bit complessivi), questo tempo può assumere solo quattro valori: 2Tosc, 8Tosc, 32Tosc e
tempo dell’oscillatore RC interno (2 -6 µsec). Ne segue che Tosc, e quindi la massima frequenza del
clock del PIC, sia vincolato a valori precisi. Ecco qui visualizzato un ciclo di conversione:
F IG . 8 .2 -2
La conversione avviene settando il bit GO/DONE (si deve porlo ad 1, altrimenti se posto a 0
viene interrotta la conversione) dopodiché bisogna aspettare un tempo pari a 2Tad necessario per
l’acquisizione del valore analogico in ingresso all’ ADC.
I cinque ingressi analogici possono essere disponibili contemporaneamente o secondo
particolari combinazioni a seconda dei settagli del registro ADCON1.(Si veda l’Appendice F)
OSS: gli ingressi usati come analogici vanno settati come ingressi nel registro TRISA.
F IG . 8 .2 -3
39
Introduzione Alla Programmazione Dei PIC16F876
F IG . 8 .3 -1
Quando viene resettato il PIC il contenuto dei due registri del convertitore A/D ADRESL
ADRSH viene cancellato ed lo stesso convertitore viene forzato ad abortire la conversione.
16
In realtà questi registri sono entrambi da 8 bit, però sono interpretati dal ADC come un unico registro da 16
40
Introduzione Alla Programmazione Dei PIC16F876
9.1. Premessa
La EEPROM DATI è una particolare area di memoria da 256 byte nella quale possiamo
scrivere i valori numerici che vogliamo che non vengano persi in caso di mancanza di tensione di
alimentazione.
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.
Nota: Si può leggere e scrivere anche nella memoria FLASH in modo simile a come si fa
con la EEPROM. Per questo tipo di operazione si rimanda al datasheet a pag 41 e seguenti.
41
Introduzione Alla Programmazione Dei PIC16F876
Nel registro EEDATA dobbiamo ora scrivere il valore che intendiamo inviare alla locazione
EEPROM indirizzata con il registro EEADR:
banksel EEDATA
movlw 10
movwf EEDATA
A questo punto dobbiamo settare il flag WREN (WRite ENable) contenuto nel registro di
controllo EECON1 per poter abilitare l' accesso alle successive operazioni di scrittura.
banksel EECON1
bsf EECON1,WREN ;Enable Write
Ora dobbiamo eseguire una sequenza di scritture sul registro EECON2 per comunicare al
PIC che abbiamo intenzione di scrivere sulla EEPROM. Questa sequenza rappresenta una specie di
codice di accesso alla EEPROM e serve ad evitare scritture accidentali in caso di funzionamento
anomalo del PIC dovuto a sbalzi di tensione, errori si programmazione. In pratica dobbiamo
scrivere i due valori esadecimali 55h e AAh in sequenza nel registro EECON2:
banksel EECON2
movlw 55h ;Write 55h to EECON2
movwf EECON2
movlw AAh ;Write AAh to EECON2
movwf EECON2
Arrivati a questo punto abbiamo effettuato tutte le operazioni preliminari per scrivere sulla
EEPROM e ci rimane solo di avviare la scrittura settando il flag WR (WRite) del registro EECON1
con l' istruzione:
bsf EECON1,WR ;Begin write
L' hardwaredel PIC impiega un certo tempo a partire da questo momento per programmare
la cella EEPROM con il valore da noi inviato. Quando l' operazione ha avuto termine, l' hardware del
PIC ci avverte azzerando nuovamente il flag WR del registri EECON1.
Se nel nostro programma decidiamo di aspettare che la cella sia stata programmata prima di
proseguire dovremo inserire il seguente loop di attesa:
WriteDoneLoop
btfsc EECON1,WR ;Writing done ?
goto WriteDoneLoop ;No, wait
... ;Yes, continue ..
Per evitare questa attesa è possibile richiedere all' hardware del PIC di generare un interrupt
di avvenuta programmazione.
Per scrivere un nuovo valore nella stessa cella EEPROM non è necessario effettuare
operazioni di cancellazioni della cella ma semplicemente ripetere le stesse operazioni di scrittura..
42
Introduzione Alla Programmazione Dei PIC16F876
10.1. Premessa
Gli standard di comunicazione seriale che possono essere usati col PIC 16F876 sono17:
• USART o SCI: Universal Synchronous Asynchronous Receiver Trasmitter
anche conosciuto col termine Serial Communications
Interface
• SSP: Synchronous Serial Port
17
Si veda i capitoli 9 e 10 del datasheet del PIC
18
Interfaccia seriale standard usata dai PC. Si veda l’Appendice G dove sono riportate alcune informazioni
relative a questo standard.
43
Introduzione Alla Programmazione Dei PIC16F876
F IG . 1 0 .2 -1
Si può vedere come il cuore del trasmettitore sia il registro a scorrimento TSR: questo
registro non è mappato in memoria e per poterlo alimentare si deve usare il registro TXREG.
Il funzionamento del registro TSR è regolato dal bit TXEN di TXSTA, infatti se questo bit
viene posto a uno si ha lo scorrimento del dato in TSR, mentre se viene posto a zero la trasmissione
s’interrompe e TSR viene cancellato.
Lo stato di TSR, cioè l’indicazione se il registro è pieno o è vuoto, è descritto nel bit TRMT
di TXSTA.
44
Introduzione Alla Programmazione Dei PIC16F876
11.1. Premessa
Questo capitolo vuole essere una raccolta di algoritmi e funzioni per sveltire e agevolare la
programmazione del PIC.
movf VALUE_DELAY_0, W
movwf DELAY_TEMPORANEO_0
REDO0
movf VALUE_DELAY_1, W
movwf DELAY_TEMPORANEO_1
REDO1
movf VALUE_DELAY_2, W
movwf DELAY_TEMPORANEO_2
REDO2
NOP
decfsz DELAY_TEMPORANEO_2, F
goto REDO2
FINE_REDO2
decfsz DELAY_TEMPORANEO_1, F
45
Introduzione Alla Programmazione Dei PIC16F876
goto REDO1
FINE_REDO1
decfsz DELAY_TEMPORANEO_0, F
goto REDO0
FINE_REDO0
return
Per poter calcolare la giusta temporizzazione in secondi si deve usare la seguente formula:
VALUE _ DELAY _ 0 ⋅VALUE _ DELAY _ 1 ⋅VALUE _ DELAY _ 2
delay =
fosc / 20 − VALUE _ DELAY _ 0 ⋅VALUE _ DELAY _ 1 − VALUE _ DELAY _ 0 − 1
Nel caso in cui si usi un oscillatore alla frequenza di 20MHz si possono usare i seguenti
valori per i registri:
Tempo [sec] Frequenza [Hz] VALUE_DELAY_0 VALUE_DELAY_1 VALUE_DELAY_2
2 0,5 63 127 248
1 1 104 209 45
0,5 2,0 62 125 64
0,1 10,0 14 28 255
0,01 100,0 10 20 50
0,000104 9600,0 2 4 13
;****************************************************************
; DELAY_1sec
; Funzione di ritardo di supporto
;****************************************************************
DELAY_1sec
movlw 104
movwf VALUE_DELAY_0
movlw 209
movwf VALUE_DELAY_1
movlw 45
movwf VALUE_DELAY_2
goto DELAY
;****************************************************************
; DELAY_500msec
; Funzione di ritardo di supporto
;****************************************************************
DELAY_500msec
movlw 62
movwf VALUE_DELAY_0
movlw 125
movwf VALUE_DELAY_1
movlw 64
movwf VALUE_DELAY_2
goto DELAY
;****************************************************************
; DELAY_100msec
; Funzione di ritardo di supporto
;****************************************************************
DELAY_100msec
movlw 14
movwf VALUE_DELAY_0
movlw 28
movwf VALUE_DELAY_1
46
Introduzione Alla Programmazione Dei PIC16F876
movlw 255
movwf VALUE_DELAY_2
goto DELAY
;****************************************************************
; DELAY_10msec
; Funzione di ritardo di supporto
;****************************************************************
DELAY_10msec
movlw 10
movwf VALUE_DELAY_0
movlw 20
movwf VALUE_DELAY_1
movlw 50
movwf VALUE_DELAY_2
goto DELAY
F IG . 1 1 .3 -1 – D IS PL AY L E D A 7 S EG M E TI AD AN O D O C O M U N E
11.3.1. Le costanti
47
Introduzione Alla Programmazione Dei PIC16F876
;*****************************************************************************
; Funzione che aggiorna il display col carattere contenuto in CHAR_TO_DISPLAY
;
;*****************************************************************************
AGGIORNA_DISPLAY
movf CHAR_TO_DISPLAY, W
movwf PORTB
return
;**********************************************************************
; Funzione che visualizza la parola CIAO
;**********************************************************************
FUNZIONE_CIAO
movlw _DISPLAY_SPENTO
movwf CHAR_TO_DISPLAY
call AGGIORNA_DISPLAY
call DELAY_500msec
movlw _DISPLAY_LED_CHAR_C
movwf CHAR_TO_DISPLAY
call AGGIORNA_DISPLAY
call DELAY_500msec
movlw _DISPLAY_LED_CHAR_I
48
Introduzione Alla Programmazione Dei PIC16F876
movwf CHAR_TO_DISPLAY
call AGGIORNA_DISPLAY
call DELAY_500msec
movlw _DISPLAY_LED_CHAR_A
movwf CHAR_TO_DISPLAY
call AGGIORNA_DISPLAY
call DELAY_500msec
movlw _DISPLAY_LED_CHAR_O
movwf CHAR_TO_DISPLAY
call AGGIORNA_DISPLAY
call DELAY_500msec
movlw _DISPLAY_SPENTO
movwf CHAR_TO_DISPLAY
call AGGIORNA_DISPLAY
return
;**************************************************************************
; Converti Numero decimale binario in un numero decimale per display
;**************************************************************************
CONVERTI_NUM_CHAR_DISPLAY
bcf STATUS, Z
movf CHAR_TO_DISPLAY, W
sublw 0
btfsc STATUS, Z
goto CHAR_DISPLAY_0
movf CHAR_TO_DISPLAY, W
sublw 1
btfsc STATUS, Z
goto CHAR_DISPLAY_1
movf CHAR_TO_DISPLAY, W
sublw 2
btfsc STATUS, Z
goto CHAR_DISPLAY_2
movf CHAR_TO_DISPLAY, W
sublw 3
btfsc STATUS, Z
goto CHAR_DISPLAY_3
movf CHAR_TO_DISPLAY, W
sublw 4
btfsc STATUS, Z
goto CHAR_DISPLAY_4
movf CHAR_TO_DISPLAY, W
sublw 5
btfsc STATUS, Z
goto CHAR_DISPLAY_5
movf CHAR_TO_DISPLAY, W
sublw 6
btfsc STATUS, Z
goto CHAR_DISPLAY_6
movf CHAR_TO_DISPLAY, W
sublw 7
btfsc STATUS, Z
goto CHAR_DISPLAY_7
49
Introduzione Alla Programmazione Dei PIC16F876
movf CHAR_TO_DISPLAY, W
sublw 8
btfsc STATUS, Z
goto CHAR_DISPLAY_8
movf CHAR_TO_DISPLAY, W
sublw 9
btfsc STATUS, Z
goto CHAR_DISPLAY_9
CHAR_DISPLAY_9
movlw _DISPLAY_LED_NUM_9
movwf CHAR_TO_DISPLAY
return
CHAR_DISPLAY_8
movlw _DISPLAY_LED_NUM_8
movwf CHAR_TO_DISPLAY
return
CHAR_DISPLAY_7
movlw _DISPLAY_LED_NUM_7
movwf CHAR_TO_DISPLAY
return
CHAR_DISPLAY_6
movlw _DISPLAY_LED_NUM_6
movwf CHAR_TO_DISPLAY
return
CHAR_DISPLAY_5
movlw _DISPLAY_LED_NUM_5
movwf CHAR_TO_DISPLAY
return
CHAR_DISPLAY_4
movlw _DISPLAY_LED_NUM_4
movwf CHAR_TO_DISPLAY
return
CHAR_DISPLAY_3
movlw _DISPLAY_LED_NUM_3
movwf CHAR_TO_DISPLAY
return
CHAR_DISPLAY_2
movlw _DISPLAY_LED_NUM_2
movwf CHAR_TO_DISPLAY
return
CHAR_DISPLAY_1
movlw _DISPLAY_LED_NUM_1
movwf CHAR_TO_DISPLAY
return
CHAR_DISPLAY_0
movlw _DISPLAY_LED_NUM_0
movwf CHAR_TO_DISPLAY
return
50
Introduzione Alla Programmazione Dei PIC16F876
banksel RIPORTO
movf RIPORTO, W
bcf RIPORTO, 0
bcf STATUS, C
addwf PRIMO_ADDENDO, W
btfss STATUS, C
goto SOMMA_SENZA_RIPORTO
bsf RIPORTO, 0 ;C'è il riporto
;quindi sicuramente non c'è ora!
addwf SECONDO_ADDENDO, W
movwf RISULTATO_SOMMA
return
SOMMA_SENZA_RIPORTO
addwf SECONDO_ADDENDO, W
btfsc STATUS, C
bsf RIPORTO, 0 ;ora c'è il riporto!
movwf RISULTATO_SOMMA
return
RIPORTO
;****************************************************************
; Somma 3 Byte
;
; T S F
; ADDENDO1_3B OOOO OOOO OOOO
; ADDENDO2_3B OOOO OOOO OOOO
; --------------
; RISULTATO_3B OOOO OOOO OOOO
;
51
Introduzione Alla Programmazione Dei PIC16F876
; RIPORTO OOOO
;
;****************************************************************
SOMMA_3BYTE
movf ADDENDO1_3B_F, W
movwf PRIMO_ADDENDO
movf ADDENDO2_3B_F, W
movwf SECONDO_ADDENDO
call SOMMA_8bit
movf RISULTATO_SOMMA, W
movwf RISULTATO_3B_F
movf ADDENDO1_3B_S, W
movwf PRIMO_ADDENDO
movf ADDENDO2_3B_S, W
movwf SECONDO_ADDENDO
call SOMMA_8bit
movf RISULTATO_SOMMA, W
movwf RISULTATO_3B_S
movf ADDENDO1_3B_T, W
movwf PRIMO_ADDENDO
movf ADDENDO2_3B_T, W
movwf SECONDO_ADDENDO
call SOMMA_8bit
movf RISULTATO_SOMMA, W
movwf RISULTATO_3B_T
return
ITERAZIONI
;****************************************************************
; Moltiplica due numeri da 2 BYTE
;
;
; H L
; NUMERO1 0000 0000
; NUMER02 0000 0000
;
; 3 2 1 0
; RISULT_MOLT 0000 0000 0000 0000
;
; TEMP_REG_4B 0000 0000 0000 0000
;
;****************************************************************
MOLTIPLICA_2B_2B
clrf RISULT_MOLT_0
clrf RISULT_MOLT_1
clrf RISULT_MOLT_2
clrf RISULT_MOLT_3
52
Introduzione Alla Programmazione Dei PIC16F876
clrf TEMP_REG_4B_0
clrf TEMP_REG_4B_1
clrf TEMP_REG_4B_2
clrf TEMP_REG_4B_3
movf NUMERO1_L, W
movwf TEMP_REG_4B_0
movf NUMERO1_H, W
movwf TEMP_REG_4B_1
movlw 16
movwf ITERAZIONI
LOOP_ITERAZIONI
bcf STATUS, C
rrf NUMERO2_H, F
rrf NUMERO2_L, F
call SOMMA_8bit
movf RISULTATO_SOMMA, W
movwf RISULT_MOLT_0
movf RISULT_MOLT_1, W
movwf PRIMO_ADDENDO
movf TEMP_REG_4B_1, W
movwf SECONDO_ADDENDO
call SOMMA_8bit
movf RISULTATO_SOMMA, W
movwf RISULT_MOLT_1
movf RISULT_MOLT_2, W
movwf PRIMO_ADDENDO
movf TEMP_REG_4B_2, W
movwf SECONDO_ADDENDO
call SOMMA_8bit
movf RISULTATO_SOMMA, W
movwf RISULT_MOLT_2
movf RISULT_MOLT_3, W
movwf PRIMO_ADDENDO
movf TEMP_REG_4B_3, W
movwf SECONDO_ADDENDO
call SOMMA_8bit
movf RISULTATO_SOMMA, W
movwf RISULT_MOLT_3
TROVATO_ZERO
nop
bcf STATUS, C
rlf TEMP_REG_4B_0, F
rlf TEMP_REG_4B_1, F
rlf TEMP_REG_4B_2, F
rlf TEMP_REG_4B_3, F
decfsz ITERAZIONI, F
goto LOOP_ITERAZIONI
return
53
Introduzione Alla Programmazione Dei PIC16F876
ITERAZIONI
;****************************************************************
; Dividi per Dieci
;
; |
; DIVIDENDO | 10
; ---------------------
; SOTTRATTORE | RISULTATO_DIV
; |
; RESTO |
;
; H L
; DIVIDENDO 0000 0000
; SOTTRATTORE 0000 0000
; RESTO 0000 0000
; RISULTATO_DIV 0000 0000
;
;
;****************************************************************
DIVIDI_PER_DIECI
banksel SOTTRATTORE_H
clrf SOTTRATTORE_H
clrf SOTTRATTORE_L
clrf RISULTATO_DIV_H
clrf RISULTATO_DIV_L
movlw B'10100000'
movwf SOTTRATTORE_H
movlw 13
movwf ITERAZIONI
LOOP_DIVIDI
clrf RESTO_H
clrf RESTO_L
bcf STATUS, C
movf SOTTRATTORE_L, W
subwF DIVIDENDO_L, W
movwf RESTO_L
btfsc STATUS, C ; Se c'è riporto salta
goto NON_C_E_RIPORTO
; C'è riporto
movf DIVIDENDO_H, F
btfsc STATUS, Z ; Se il sottrattore è zero allora il numero è minore
goto ZERO_TO_RISULTATO ;DIVIDENDO < SOTTRATTORE
decf DIVIDENDO_H, F ;C'è il riporto
NON_C_E_RIPORTO
movf SOTTRATTORE_H, W
subwF DIVIDENDO_H, W
movwf RESTO_H
54
Introduzione Alla Programmazione Dei PIC16F876
bsf STATUS, C
rlf RISULTATO_DIV_L, F
rlf RISULTATO_DIV_H, F
goto FINE_DIVIDI
FINE_DIVIDI
bcf STATUS, C
rrf SOTTRATTORE_H, F
rrf SOTTRATTORE_L, F
decfsz ITERAZIONI, F
goto LOOP_DIVIDI
return
55
Appendice A
Appendice A
P 1 6 F 8 7 6 .IN C
LIST
; P16F876.INC Standard Header File, Version 1.00 Microchip Technology, Inc.
NOLIST
; This header file defines configurations, registers, and other useful bits of
; information for the PIC16F876 microcontroller. These names are taken to match
; the data sheets as closely as possible.
;==========================================================================
;
; Revision History
;
;==========================================================================
;1.12 01/12/00 Changed some bit names, a register name, configuration bits
; to match datasheet (DS30292B)
;1.00 08/07/98 Initial Release
;==========================================================================
;
; Verify Processor
;
;==========================================================================
IFNDEF __16F876
MESSG "Processor-header file mismatch. Verify selected processor."
ENDIF
;==========================================================================
;
; Register Definitions
;
;==========================================================================
W EQU H'0000'
F EQU H'0001'
56
Appendice A
57
Appendice A
58
Appendice A
59
Appendice A
;==========================================================================
;
; RAM Definition
;
;==========================================================================
__MAXRAM H'1FF'
__BADRAM H'08'-H'09'
__BADRAM H'88'-H'89', H'8F'-H'90', H'95'-H'97', H'9A'-H'9D'
__BADRAM H'105', H'107'-H'109'
__BADRAM H'185', H'187'-H'189', H'18E'-H'18F'
;==========================================================================
;
; Configuration Bits
;
;==========================================================================
LIST
60
Appendice B
Appendice B
O P E R A T O R I L O G IC I E M A T E M A T IC I
61
Appendice C
Appendice C
C O N F IG U R A T IO N W O R D
62
Appendice D
Appendice D
S T R U T T U R A D E L L A R A M - F IL E R E G IS T E R S
63
Appendice D
R E G IS T R O D I S T A TO – S T A TU S R E G IS T E R
64
Appendice E
Appendice E
S E T D I I S T R U Z IO N I P E R I P IC
OSS: La descrizione approfondita delle singole istruzioni a pag. 139 del datasheet del PIC16F87x
65
Appendice F
Appendice F
A D C O N 0 R E G IS T E R
66
Appendice F
A D C O N 1 R E G IS T E R
67
Appendice G
Appendice G
S TA N D A R D R S 2 3 2
Per usare la RS232 per collegare tra loro due computer vicini senza interporre tra loro alcun modem dobbiamo
simulare in qualche modo le connessioni intermedie realizzando un cavo NULL MODEM o cavo invertente, ovvero un
cavo in grado di far scambiare direttamente tra loro i segnali dai due DTE come se tra loro ci fossero effettivamente i
DCE.
La linea Transmit Data (TXD) presente sul pin 3 del connettore DB9 maschio di cui il vostro PC è dotato è
connessa alla linea Receive Data (RXD) presente sul pin 2 del secondo PC. Le masse (GND) presenti sul pin 5 di
entrambe i PC sono connesse tra loro.
Per osservare i segnali generati dal PC trasmittente durante la trasmissione seriale colleghiamo tra la linea
TXD e la linea GND un oscilloscopio e lanciamo in esecuzione su entrambe i PC un programma di emulazione
terminale (tipo Hyperterminal o simili).
68
Appendice G
Configuriamo le porte seriali di entrambe i PC a 9600 baud, 8 data bit, 1 stop bit, no parity e disabilitiamo il
controllo di flusso (handshake) sia hardware che xon/xoff. In questo stato qualsiasi cosa digiteremo sul PC trasmittente
verrà inviata immediatamente sulla porta seriale. Assicuriamoci inoltre che il programma di emulazione terminale scelto
sia opportunamente configurato per usare la porta seriale su cui siamo connessi (COM1 o COM2).
Proviamo a digitare la lettera A maiuscola e verifichiamo se è stata correttamente ricevuta sul PC ricevente.
Fatto questo controllo andiamo a vedere sull' oscilloscopio che tipo di segnali sono stati generati per effettuare la
trasmissione.
Quando non c' é 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 all' inverso della frequenza di trasmissione ovvero al tempo di trasmissione di un singolo bit.
Nel nostro caso, avendo scelto di trasmettere a 9600 bit per secondo, la tensione di alimentazione rimarà a +12
volt per: 1/9600=0.104 mS.
Questo segnale viene denominato START BIT ed è sempre presente all' inizio di 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 nostro caso la lettera A maiuscola corrisponde al valore binario 01000001 per
cui la sequenza di trasmissione sarà la seguente:
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.
Aggiungendo al nostro cavo seriale una connessione tra il pin TXD (pin 3) del PC ricevente con il pin RXD
(pin 2) del PC trasmittente, potremo effettuare una trasmissione RS232 bidirezionale. Il cavo che abbiamo ottenuto è il
più semplice cavo NULL MODEM in grado di mettere in collegamento tra loro due DTE.
69
Indice Analitico
Indice Analitico
A F
ADC........................... Vedi Convertitore A/D File Registers..............................................61
assembly, linguaggio ....................................1 FILE1.ASM..................................................3
file2.asm.....................................................11
B file3.asm.....................................................18
banchi di memoria ........................................6 FLAG BIT..................................................20
Banchi di memoria, Abilitare i......................8 frequenza del clock interno .........................13
banksel .......................................................10 frequenza dell’oscillatore e sterno................13
BCF..............................................................9 frequenza di oscillazione ..............................2
BSF ..............................................................8
G
C General Purpose Register..............................6
goto ...............................................................9
C bit.............................................................7
GOTO ...............................................................9
call ...............................................................9
CALL ...............................................................9
Capture.......................................................20 H
CCP............................................................20 HS ..............................................................13
clock, sorgente esterna................................14
Compare.....................................................20 I
Comunicazione Seriale ...............................20 include ..........................................................5
CONFIG......................................................5; 14
INTCON ....................................................20
Configuration Word................................5; 60 interrupt......................................................15
contatori ti tempo e di eventi.......................20 Interrupt .......................................................2
convertitore A/D.........................................20 Interrupt, gestione degli ..............................16
convertitore per approssimazioni successive istruzioni ......................................................7
...............................................................20
L
D
loop ..............................................................9
datasheet .........................................................b LP ..............................................................13
direttive al compilatore .................................3
Display LED a 7 segmenti ..........................20 M
divisione, Algoritmi di................................48
DS30292x.PDF ................................................b
MainLoop.....................................................9
DS33014F.pdf ............................................10 MAX232 ..............................................20; 67
memoria EEPROM ..............................2; 20
E memoria FLASH ........................................2
memoria FLASH, paginazione....................10
ENABLE BIT.............................................20 memoria libera .............................................6
EQU.............................................................5 memoria RAM............................................1
errorlevel .....................................................5
messaggi di errore ........................................5
microchip ........................................................b
MOVLW......................................................9
70
Indice Analitico
71