Sei sulla pagina 1di 18

ipia F. MARAZZI lab. di elettronica a.s.

2012/2013
26013 CREMA giancarlo.livraga@istruzione.it

IL MICROCONTROLLORE PIC16F690
NOTA: questo fascicolo vuole solo essere un manualetto di rapida consultazione durante la scrittura ed il debugging di programmi per il
PIC16F690 sotto la guida di un docente o per chi, in qualche misura, abbia conoscenze precedenti su microprocessori e periferiche.

Il PIC12F690 è un microcontrollore RISC a 8bit con architettura HARVARD (area programmi separata
dall‟area dati), ed è una sostanziale espansione dei suoi fratelli più piccoli come il PIC12F675. Di questi ha le
medesime prestazioni generali (istruzioni, frequenza di clock etc.) ma un maggior numero di linee di I/O e
alcune potenti funzioni hardware in più.
La figura a lato mostra il layout dell‟integrato dove
sono utilizzati nomi multipli sui pin per indicare le
diverse funzioni che ciascuno di essi può svolgere.
NOTA: In questa dispensa, salvo errori o dimenticanze, si
useranno solo i nomi associati ai port (RA, RB e RC) an-
che se i pin sono configurati per altre funzioni.

LA MEMORIA DEL PIC16F690


La memoria è separata tra l‟area di programma (4K di memoria di tipo flash, garantiti 100.000 cicli di scrittu-
ra, 40 anni di ritenuta dati), l‟area RAM organizzata in 4 banchi da 128 byte. Come nel più piccolo
PIC12F675 non tutte le locazioni RAM sono fisicamente esistenti e quelle mancanti, se indirizzate in lettura
ritornano 0x00. Nei primi 32 byte di ogni banco RAM sono allocati gli SFR (Special Function Register) cioè i
registri di configurazione e di funzionamento delli dispositivi interni del microcontrollore. I restanti byte sono
dei GPR (General Pourpose Register), quindi liberi per la memorizzazione dei dati.
Gli ultimi 16 indirizzi di ogni banco, gli intervalli [070h,07Fh] [0F0h,0FFh], [170h,17Fh], [1F0h,1FFh]) puntano
sempre agli indirizzi di banco 0 cioè all‟intervallo [070h,07Fh]. Questo permette di condividere velocemente
dati tra diverse parti del programma indipendentemente dal banco RAM attivo in quel momento.

Elenco dei registri dell‟area RAM (per nome, descrizione e indirizzo RAM)
NOTA: il valore dell’indirizzo specifica solo i 7 bit bassi dell’indirizzo effettivo (9bit), i restanti due bit definiscono il banco RAM
e sono forniti dai bit STATUS,RP<1,0>. Alcuni registri sono indifferentemente accessibili da più banchi RAM.
registri del PIC16F690 banco RAM
(nelle colonne a lato è indicato esplicitamente solo il primo indirizzo –quello del banco RAM più basso. indirizzo 0 1 2 3
Le x segnano le ulteriori posizioni nelle quali il registro è raggiungibile)
INDF (usato per indirizzamento indiretto, non è un registro reale) 00h x x x x
TMR0 (timer 0) registro contatore a 8 bit 01h x x
OPTION_REG controlla TMR0, WPU e GP2 interrupt 81h x x
PCL contatore di programma, parte bassa 02h x x x x
STATUS flag vari e controlla banco RAM attivo 03h x x x x
FSR indice per l’indirizzamento indiretto 04h x x x x
PORTA 6 bit di I/O chiamati RA<5:0> equivalente al registro GPIO del PIC12F675 05h x x
TRISA 6 bit corrispondenti a PORTA per definire il verso dei pin in/out come TRISIO 85h x x
WPUA 5 bit corrispondenti a PORTA per definire se attivare le singole Resistenze di pull-up 95h x
IOCA 6 bit corrispondenti a PORTA per abilitare o meno interrupt su cambiamento di stato 96h x
PORTB 4 bit di I/O chiamati RB<7:4> 06h x x
TRISB 4 bit corrispondenti a PORTB per definire il verso dei pin in/out 86h x x
WPUB 4 bit corrispondenti a PORTB per definire se attivare le singole Resistenze di pull-up 115h x
IOCB 4 bit corrispondenti a PORTB per abilitare o meno interrupt su cambiamento di stato 116h x
PORTC 8 bit di I/O chiamati RC<7:0> 07h x x
TRISC 8 bit corrispondenti a PORTC PORTB per definire il verso dei pin in/out 87h x x
PCLATH Il program counter ha 13 bit e le istruzioni che hanno PCL come destinazione (ad esempio ADDWF PCL,d) 0AH x x x x
forniscono solo 8 bit di indirizzo –parte bassa- ; i restanti 5 bit –parte alta- sono forniti da PCLATH<4:0>.
Le istruzioni GOTO e CALL utilizzano un op.code ridotto e forniscono 11 bit di indirizzamenti –parte bassa-;
i restanti 2 bit sono forniti da PCLATH<4:3>.
INTCON Abilitazioni varie di interrupt e alcuni flag (flag= bit di segnalazione) 0Bh x x x x
PIR1 Insieme di flag vari 0Ch x
PIR2 Insieme di flag vari 0Dh x
PIE1 Insieme di bit di abilitazione interrupt 8Ch x
PIE2 Insieme di bit di abilitazione interrupt 8Dh x
EEDAT port dati da e verso EEROM 10Ch x
EECON1 18Ch x

File: PIC16F690.DOC –rev.8 pag. 1/18


ipia F. MARAZZI lab. di elettronica a.s. 2012/2013
26013 CREMA giancarlo.livraga@istruzione.it

EEADR 10Dh x
EECON2 18Dh x
EEDATH 10Eh x
EEADRH 10Fh x
EEADRH 10Fh x
T1CON 10Fh x
TMR1L 8 bit bassi (dei 16 totali) del contatore/timer 1 0Eh x
TMR1H 8 bit alti (dei 16 totali) del contatore/timer 1 0Fh x
PCON 8Eh x
OSCCON 8Fh x
OSCTUNE 90h x
TMR2 8 bit del contatore/timer 2 11h x
T2CON 12h x
PR2 registro RW costantemente comparato con il valore del timer 2. La condizione di uguaglianza, postscalata dal 92h x
rapporto definito in T2CON setta il flag TMR2IF che, se abilitato, genera una richiesta di interrupt.
CCPR1L registro RW utilizzato per catturare il valore del timer1 in modo CAPTURE o per contenere gli 8 bit più significativi 15h x
(di 10) da utilizzare per determinare il duty cycle in modo PWM
CCPR1H registro RW utilizzato per catturare il valore del timer1 in modo CAPTURE o per caricare gli 8 bit da CCPR1L che 16h x
verranno poi comparati con il valore di TMR2 per determinare il duty cycle in modo PWM
CCP1CON 17h x
PWM1CON 1Ch x
PSTRCON 19Dh x
ECCPAS 1Dh x
CM1CON0 119h x
CM2CON0 11Ah x
CM2CON1 11Bh x
SRCON 19Eh x
VRCON 118h x
ANSEL 11Eh x
ANSELH 11Fh x
ADCON0 1Fh x
ADCON1 9Fh x
T1CON
ADRESH Risultato della conversione AD –parte alta- 1Eh x
ADRESL Risultato della conversione AD –parte bassa- 9Eh x

LE ISTRUZIONI DEL PIC16F690


L‟ACCUMULATORE è il registro principale di ogni microprocessore ed è coinvolto in quasi tutte le istruzioni.
Nel PIC l‟accumulatore si chiama W e non è esplicitamente indirizzabile. Le istruzioni di questo microcontrol-
lore sono costituite da un unico byte di 14 bit strutturati come segue:
13 12 11 10 9 8 7 6 5 4 3 2 1 0
codice operativo d Indirizzamento (del registro)

Il bit<7> (d) specifica la destinazione del risultato dell’operazione (d=0 il risultato è nell’accumulatore W, d=1 il risultato è nel registro
indirizzato).
I 9 bit necessari a coprire lo spazio indirizzabile della RAM (da 000h…1FFh) sono costruiti automaticamente
unendo i bit RP1,RP0 del registro di STATUS con i 7 bit per l‟indirizzamento disponibili nelle istruzioni.
L‟area RAM appare quindi divisa in quattro banchi (convenzionalmente banco 0, 1, 2 e 3) corrispondenti allo
stato di questi due bit. Nella scrittura di un programma si deve quindi fare attenzione e tenere traccia del
banco attivo commutando RP0,RP1 quando necessario.
NOTA: nella maggior parte degli assemblatori si può usare la direttiva
banksel <registro|0|1|2|3>
per generare automaticamente le due istruzioni che settano correttamente i bit RP1 e RP0 del registro di STATUS.

File: PIC16F690.DOC –rev.8 pag. 2/18


ipia F. MARAZZI lab. di elettronica a.s. 2012/2013
26013 CREMA giancarlo.livraga@istruzione.it

Nella tabella che segue sono riportate le istruzioni del PIC con le seguenti convenzioni
destinazione del risultato (0=accumulatore, 1=registro).
f indirizzo del registro (o nome simbolico se dichiarato) d Vale 0 per default (se non esplicitamente scritta)
k costante numerica, label b posizione del bit nel registro (7…0)
La colonna dello Status flag mostra quali bit del registro di STATUS siano influenzati dalla istruzione.
OPERAZIONI SUI BYTE
Codice mne-
Status flag commento
monico
CLRF f Z (clear file: azzera il registro f)
CLRW Z (clear w: azzera l‟accumulatore)
MOVF f,d Z (mov f: il contenuto di f è ricopiato in d)
MOVWF f (mov w f: il contenuto dell‟accumulatore è ricopiato in f)
ADDWF f,d C, DC, Z (add w f: somma algebrica W+f)  d
SUBWF f,d C, DC, Z (sub w f: sottrazione algebrica f-W) d
ANDWF f,d Z (and w f: funzione AND bit con bit tra W ed f)  d
IORWF f,d Z (inclusive or w f: funzione OR bit con bit tra W ed f)  d
XORWF f,d Z (xor w f: funzione XOR bit a bit tra W ed f)  d
COMF f,d Z (complement f: complementa tutti I bit di f)  d
DECF f,d Z (decrement f: decrementa f)  d
DECFSZ f,d (decrement f skip zero: decrementa f, scavalca prossima istruzione se risultato =0)  d
INCF f,d Z (increment f: incrementa f)  d
INCFSZ f,d (increment f skip zero: incrementa f, scavalca prossima istruzione se risultato =0)  d
RLF f,d C (rotate left: rotazione sinistra di f attraverso il carry)  d
RRF f,d C (rotate right: rotazione destra di f attraverso il carry)  d
SWAPF f,d (swap file: scambia tra loro i 4 bit bassi/alti di f)  d
OPERAZIONI SUI BIT
Codice mnemonico commento
BCF f,b (Bit clear file: azzera il bit specificato)
BSF f,b (Bit set file: porta allo stato 1 il bit specificato)
BTFSS f,b (bit test file skip set: se il bit specificato vale 1 salta la prossima istruzione)
BTFSC f,b (bit test file skip clear: se il bit specificato vale zero salta la prossima istruzione)

OPERAZIONI CON COSTANTI


Codice mnemonico Status flag commento
ADDLW k C, DC, Z (add literal w: somma k all‟accumulatore, W+kW)
SUBLW k C, DC, Z (subtract literal w: sottrae l‟accumulatore da k, k-WW)
MOVLW k (move literal w: carica il valore k nell‟accumulatore)
IORLW k (inclusive or literal w: funzione OR bit a bit tra k e W, risultato in W)
ANDLW k (and literal w: funzione AND bit a bit tra k e W, risultato in W)
XORLW k (xor literal w: funzione XOR bit a bit tra k e W, risultato in W)
GOTO k (salto di programma alla posizione k che può essere una label)
CALL k (chiamata di subroutine di indirizzo k)
OPERAZIONI DI CONTROLLO DEL FLUSSO DI PROGRAMMA
RETURN (istruzione di ritorno alla chiamata da un subroutine)
RETLW k (return literal w: ritorno da subroutine con il valore k nell‟accumulatore)
RETFIE (return from interrupt enable: ritorno da subroutine chiamata da interrupt)
SLEEP va in stato sleep, verrà svegliato da WDT (watch dog timer)
CLRWDT (clear watch dog timer: azzera il timer specificato)
NOP (no operation: operazione nulla per inserire ritardi i sincronizzazioni)

File: PIC16F690.DOC –rev.8 pag. 3/18


ipia F. MARAZZI lab. di elettronica a.s. 2012/2013
26013 CREMA giancarlo.livraga@istruzione.it

I REGISTRI DEL PIC16F690


Come si è detto all‟inizio il PIC dispone di diverse periferiche integrate: port di I/O, counter/timer, AD conver-
ter etc, Tutte queste periferiche sono configurabili in modo da rendere flessibile il loro uso per adattarlo ai va-
ri scopi richiesti e la loro configurazione è ottenuta scrivendo opportuni zeri e uno nei singoli bit degli special
function register (SFR).
La figura a fianco, tratta dal manuale del
PIC16F690, illustra come esempio la rete lo-
gica che controlla il timer TMR0.
Il segnale di clock connesso al timer0 (TMR0)
è selezionato dalla catena di multiplexer
(T0CS, PSA, PSxx e WDTPSxx) che in fun-
zione dello stato (0/1) dei rispettivi bit di con-
trollo selezionano il percorso (frecce rosse punti-
nate) attivo e quindi la sorgente di segnale uti-
lizzato da TMR0.
Tutti questi bit di controllo risiedono negli SFR
(Special Function Register) e devono essere
quindi programmati opportunamente per otte-
nere la configurazione richiesta.
Qui di seguito l‟elenco degli SFR del PIC16F690 con le funzioni dei rispettivi bit.
STATUS (03H) selezione banco RAM attivo e flag vari
7 IRP Selezione banco RAM per indirizzamento indiretto. 0=banchi 0 e 1, 1=banchi 2 e 3
6 RP1 RW Selezione banco di memoria:
5 RP0 00= banco0 (00h:07Fh 01=banco1 (080h:0FFh)
10=banco2 (100H:17Fh) 11=banco3 (180h:1FFh)
4 TO R Time out: 1=dopo power_up, CLRWDT o SLEEP, 0=dopo WDT time-out
3 PD R Power down; 1=dopo power down o CLRWDT, 0=durante SLEEP
2 Z RW Zero flag: 1=l‟ultima l‟operazione aritmetica o logica ha generato zero, 0=non generato zero
1 DC RW Digital carry (istruzioni ADDxx e SUBxx): 1= l‟operazione ha generato carry dal 4° bit, 0=no
0 C RW Carry: (istruzioni ADDxx e SUBxx): 1=l‟operazione ha generato carry dal 7° bit, 0=no
OPTION_REG (81H) controllo di R pull_up su pin input digitale, Timer0 e GP2 interrupt
portA e portB pull up resistor
7 RABPU RW 0=abilitazione R pull-up selezionate da WPUA e WPUB, 1=disabilita
6 INTEDG RW Interrupt GP2 edge selector: 1=interrupt su  di GP2, 0= su GP2
5 T0CS RW TMR0 clock select: 1=timer0 avanza su transizione di GP2, 0=timer0 su clock interno
4 T0SE RW TMR0 source edge select: 1= timer0 incrementa su  di GP2, 0= avanza su  di GP2
Prescaler assignment:
3 PSA RW 1=prescaler assegnato a WDT(watch dog timer), 0= assegnato a timer0
PS<2:0> su TMR0 su WDT
2 PS2 RW 000 1:2 1:1
001 1:4 1:2
1 PS1 RW 010 1:8 1:4
0 PS0 RW …. …. ….
111 1:256 1:128
INTCON (0BH e 8BH) abilitazione generale interrupt e abilitazioni singole periferiche
7 GIE RW Global interrupt enable: 1=abilitazione globale interrupt non mascherabili, 0=disabilitazione
6 PEIE RW Peripheral interrupt enable: 1= abilita interrupt tutte periferiche, 0=disabilita
5 T0IE RW TMR0 interrupt enable: 1=abilita interrupt da timer0, 0=disabilita
4 INTE RW RA2 interrupt enable: 1=abilita RA2 interrupt, 0=disabilita
3 RABIE RW 1=abilita interrupt da cambiamento su pin PORTA/B selezionati da IOCA/B, 0=disabilita
2 T0IF RW TMR0 overflow flag bit: 1=timer 0 ha fatto overflow (azzerare da software)
1 INTF RW RA2 interrupt flag: 1=RA2 ha chiesto interrupt (azzerare da software)
0 RABIF RW PORTA/B interrupt flag: 1= almeno un pin abilitato di PORTA/B ha cambiato stato (azzerare da
software)

File: PIC16F690.DOC –rev.8 pag. 4/18


ipia F. MARAZZI lab. di elettronica a.s. 2012/2013
26013 CREMA giancarlo.livraga@istruzione.it

T1CON (01H) controllo del Timer1


7
6 TMR1GE RW Se TMR1ON=1 allora 1= Abilita conteggio solo se T1G/GP4=0, 0=conteggio libero
5 T1CKPS1 RW Selezione prescaler:
4 T1CKPS0 RW 00=1:8 01=1:4 10=1:2 11=1:1 (no prescaler)
3 T1OSCEN RW Se nei bit di “__config” è stata selezionala la modalità oscillatore interno senza clockout su
GP4 allora 1=abilita oscillatore low power (LP) per timer1, 0=oscillatore LP spento
2 T1SYNC RW Se TMR1CS=1 allora: 1=non sincronizzare con il clock esterno, 0=sincronizza
1 TMR1CS RW Selezione clock per timer1: 1=sorgente esterna (T1CKI/GP5), 0=clock interno (f 0/4)
0 TMR1ON RW Abilitazione timer 1: 1= abilita (conteggio), 0=disabilita (conteggio fermo)
PIE1 (8CH) abilitazione gruppo di periferiche
7
6 ADIE RW 1= abilita interrupt da fine conversione AD, 0=disabilita
5 RCIE RW 1= abilita interrupt da completamento ricezione asincrona byte seriale, 0=disabilita
4 TXIE RW 1 = abilita interrupt da completamento trasmissione asincrona byte seriale, 0=disabilita
3 SSPIE RW 1= abilita interrupt da completamento tx/rx in modo sincrono , 0=disabilita
2 CCP1IE RW 1= abilita interrupt da modulo ECCP, 0= disabilita
1 TMR2IE RW 1= abilita interrupt da overflow di timer 2, 0=disabilita
0 TMR1E RW 1= abilita interrupt da overflow di timer1, 0=disabilita
PIE2 (0CH) abilitazione altro gruppo di periferiche
7 OSFIF RW 1= abilita interrupt da errore oscillatore interno, 0=disabilita
6 C2IF RW 1= abilita interrupt da comparatore 2, 0=disabilita
5 C1IF RW 1= abilita interrupt da comparatore 1, 0=disabilita
4 EEIF RW 1= abilita interrupt da scrittura di EEROM, 0=disabilita
3, 2, 1, 0
PIR1 (0CH) flag vari
7
6 ADIF RW 1= conversione AD completata (azzerare da software)
5 RCIF R 1 = buffer ricezione EUSART pieno (azzerare leggendo RCREG)
4 TXIF R 1 = buffer trasmissione EUSART vuoto (azzerare scrivendo TXREG)
3 SSPIF RW 1 = trasmissione/ricezione sincrona completata (azzerare da software)
2 CCP1IF RW 1 = eseguita cattura di TMR1 in modo capture ECCP o comparazione OK in modo compare
1 TMR2IF RW 1 = comparazione TMR2/PR2 OK (azzerare da software)
0 TMR1F RW 1 = Timer1 overflow ha fatto overflow (azzerare da software)
PCON (8EH) registro controllo potenza utilizzata dal dispositivo e flag relativi
7,6 x
5 ULPWUE RW 1= ultra low power wake_up ENABLE 0=disable
4 SBOREN 1=Software BOR ENABLE 0=disable
3,2 x
1 POR Power-on reset status
1= non avvenuto reset da power-on
0=avvenuto power-on reset (settare poi da software)
0 BOR RW Brown-out reset status (Brown-out: calo alimentazione sotto la soglia prefissata)
1= non avvenuto brown-out reset
0=avvenuto brown-out reset (settare poi da software)
OSCCON (05H o 105H) controllo del clock del dispositivo
7
6 IRCF2 RW Selezione della frequenza del clock interno
5 IRCF1 000=31KHz 001=125KHz 010=250KHz 011=500KHz
4 IRCF0 100=1MHz 101=2MHz 110=4MHz 111=8MHz
3 OSTS R 1=dispositivo funzionante con clock esterno (definito da FOSC<2:0>) 0=clock interno
2 HTS R
1 LTS R
0 SCS R
OSCTUNE (05H o 105H) regolazione ±12% frequenza del clock interno
7, 6, 5
4, RW 01111= frequenza massima NOTA: i numeri binari di calibrazione della frequenza
3, 01110=… dell’oscillatore interno sono espressi con notazione di
2, … complemento a due.

File: PIC16F690.DOC –rev.8 pag. 5/18


ipia F. MARAZZI lab. di elettronica a.s. 2012/2013
26013 CREMA giancarlo.livraga@istruzione.it

1, 00000= calibrazione di fabbrica


0 11111= 11111 è infatti il numero negativo (-1) che si ottiene com-
10000= frequenza minima plementando a due il numero 00001 (+1)
PIR2 (0CH) flags vari
7 OSFIF RW 1= Errore oscillatore interno (azzerare da software), 0= system clock regolare
6 C2IF RW 1= comparatore 2 ha cambiato di stato (azzerare da software), 0= nessun cambiamento
5 C1IF RW 1= comparatore 1 ha cambiato di stato (azzerare da software), 0= nessun cambiamento
4 EEIF RW 1= fine scrittura su EEROM (azzerare da software), 0=scrittura non completata o non iniziata
3, 2, 1, 0
PORT A (05H o 105H) registro di I/O
7,6
5 RA5 RW Corrispondente al pin esterno RA5
4 RA4 RW Corrispondente al pin esterno RA4
3 RA3 RW Corrispondente al pin esterno RA3
2 RA2 RW Corrispondente al pin esterno RA2
1 RA1 RW Corrispondente al pin esterno RA1
0 RA0 RW Corrispondente al pin esterno RA0
TRISA (85H) controllo direzione dei singoli bit di registro di I/O
7,6
5 TRISA5 RW Tri-state control bit:
4 TRISA4 RW 1=il corrispondente bit è configurato come input, 0=come output
3 TRISA3 RW Tri-state control bit: configurato fisso come input
2 TRISA2 RW
Tri-state control bit:
1 TRISA1 RW 1=il corrispondente bit è configurato come input, 0=come output
0 TRISA0 RW
WPUA (95H) selezione resistenze di pull_up per singoli pin di registro di I/O
7,6
5 WPUA5 RW
4 WPUA4 RW
3 1 = abilita resistenza di pull up per il pin corrispondente
2 WPUA3 RW 0 = disabilita
1 WPUA1 RW
0 WPUA0 RW
IOCA (96H) abilitazione richiesta interrupt da singoli pin di registro di I/O
7,6
5 IOCA5 RW
4 IOCA4 RW
3 IOCA3 RW 1=abilita interrupt su cambiamento di stato del corrispondente pin
2 IOCA2 RW 0=disabilita interrupt su cambiamento di stato del corrispondente pin
1 IOCA1 RW
0 IOCA0 RW
PORTB registro di I/O
7 RB7 RW Corrispondente al pin esterno RB7
6 RB6 RW Corrispondente al pin esterno RB6
5 RB5 RW Corrispondente al pin esterno RB5
4 RB4 RW Corrispondente al pin esterno RB4
3, 2, 1, 0
I registri TRISB, WPUB, IOCB replicano le medesime funzioni dei corrispondenti registri del portA con la
unica differenza del loro indirizzo, dell’adattamento dei loro nomi, della posizione e del nome dei singoli bit.
PORTC registro di I/O
7 RC7 Corrispondente al pin esterno RC7
6 RC6 Corrispondente al pin esterno RC6
5 RC5 RW Corrispondente al pin esterno RC5
4 RC4 RW Corrispondente al pin esterno RC4
3 RC3 RW Corrispondente al pin esterno RC3
2 RC2 RW Corrispondente al pin esterno RC2
1 RC1 RW Corrispondente al pin esterno RC1
0 RC0 RW Corrispondente al pin esterno RC0

File: PIC16F690.DOC –rev.8 pag. 6/18


ipia F. MARAZZI lab. di elettronica a.s. 2012/2013
26013 CREMA giancarlo.livraga@istruzione.it

I registri TRISC, WPUC replicano le medesime funzioni dei corrispondenti registri del portA con la unica dif-
ferenza del loro indirizzo, dell‟adattamento dei loro nomi, della posizione e del nome dei singoli bit.
Manca invece il corrispondente registro IOC_ di abilitazione dell‟interrupt sui singoli bit.
T2CON (19H) controllo del timer T2
7
6 TOUTPS3 selezione rapporto di postscaler 0000 = 1:1
5 TOUTPS2 0001 = 1:2
RW …
4 TOUTPS1
1111 = 1:16
3 TOUTPS0
2 TMR2ON RW 1= timer2 on 0= timer2 off
1 T2CKPS1 selezione rapporto prescaler
RW 00 = 1:1 01 = 4 1x = 16
0 T2CKPS1
Il registro PR2 è un normale registro RW che è continuamente comparato con il valore corrente del timer 2.
La condizione di uguaglianza, postscalata con il rapporto definito da T2CON setta il flag TMR2IF che, se abi-
litato, può generare interrupt.
IL MODULO ECCP (Enanched Capture Compare PWM)
Il modulo ECCP, con i suoi tre modi di funzionamento con i suoi tre modi di funzionamento, è estremamente flessibile e può liberare la
programmazione da molto lavoro aumentando le prestazioni del microcontrollore.
modo CAPTURE. Il valore di TIMER1 viene catturato nel registro
CCPR1H in conseguenza di un fronte (edge) di salita o di discesa sul pin
RC5. La disponibilità di un prescaler programmabile permette di attivare la
cattura del timer ogni 1, 4 o 16 fronti sul pin RC5. La cattura è accompa-
gnata dal set del flag CCP1IF (nel registro PIR1). Ogni valore catturato
sovrascrive il contenuto dei registri CCPR1H/L ed il flag CCP1IF se abili-
tato può generare interrupt.

modo COMPARE. In questa modalità il timer 1 viene costantemente com-


parato con i registri CCPR1H/L e la condizione di uguaglianza può (di-
pendendo dalla configurazione):
- lasciare inalterato o portare a uno o zero il pin RC5
- portare a uno il flag CCP1IF
- azzerare automaticamente il timer TMR1H/L (però non setta il corri-
spondente flag TMR1IF)
- iniziare una conversione AD se il convertitore è abilitato

modo PWM. Il timer TMR2 viene continuamente comparato con i registri


CCPR1H e con il registro PR2. La uguaglianza con il primo azzera lo stato
di Q mentre la uguaglianza con il secondo azzera TMR2 (ricomincia il ci-
clo) e setta la variabile Q. In questa maniera il segnale PWM ha il periodo
stabilito da PR2 ed una larghezza di impulso stabilita da (PR2 -
CCPR1H). Il controller di output poi può utilizzare questo segnale per ge-
stire:
- una singola uscita PWM (RC5),
- due uscite half bridge (mezzo ponte controllato, RC5 e RC4), per
alimentare carichi in alternata con doppia alimentazione
- full bridge (ponte intero, tutte 4 le uscite) in avanti ed indietro, per
alimentare carichi in alternata con alimentazione singola
CCP1CON General purpose input output register
7 P1M1 Se modo di funzionamento PWM (CCP1M<3:2> = 11) allora vale tabella blu.
6 P1M0 Negli altri modi questi bit sono ignorati: RC5 viene utilizzato per CAPTURE/COMPARE e gli altri pin sono liberi
P1M1 P1M0 RC5 RC4 RC3 RC2
RW 00 PWM x x x singola uscita PWM su R5
01 1 0 0 PWM full bridge foward
10 PWM PWM x x half bridge con tempo morto (dead time) tra PWM di RC5 e RC4
11 0 PWM 1 0 full bridge reverse
5 DC1B1 2 bit meno significativi che uniti al contenuto del registro CCPR1L determinano la durata
RW dell‟impulso PWM
4 DC1B0
3 CCP1M3 Modo di funzionamento del modulo ECCP
2 CCP1M2 00xx: modo CAPTURE 01xx, 10xx: modo COMPARE
RW 11xx: modo PWM
1 CCP1M1
0 CCP1M0 +
RC5 RC3
carico
Nel modo PWM l’insieme delle RC5 - +
carico
uscite è di solito utilizzato per -
RC4 RC2
controllare dispositivi di potenza +
attraverso dei driver opportuni -
come scematizzato a fianco. RC4
half bridge: si utilizza se è ne- full bridge: si utilizza se è necessario
cessario invertire la corrente sul invertire la corrente sul carico e si dispo-
File: PIC16F690.DOC –rev.8 carico e si dispone della doppia ne di una alimentazione singola pag. 7/18
alimentazione
ipia F. MARAZZI lab. di elettronica a.s. 2012/2013
26013 CREMA giancarlo.livraga@istruzione.it

PWM1CON (19H) controllo tempo morto tra commutazioni PWM


7 PRSEN RW SCHEMA HALF BRIDGE
6 PDC6 RW In modo PWM half-bridge (schema a fianco) i due MOS conducono alternativamente
…. … ma le conduzioni devono essere separate da un tempo morto per permettere il com-
… … pleto spegnimento del MOS che conduceva nel ciclo precedente. I 7 bit PDC<6:0>
0 PDC0 RW determinano questo tempo in funzione della frequenza del sistema come T=N fosc/4

PSTRCON (19H) Segnale PWM disponibile su più pin in parallelo


7, 6, 5
6 STRSYNC RW 1=la duplicazione si attiva al prossimo ciclo PWM 0=si attiva alla prossima istruzione di cpu
4 STRD 1= il segnale PWM disponibile su RC5/P1A in modalità singolo segnale
3 STRC (CCP1CON=00xx11xx) viene duplicato anche su pin RC4, 3 e 2 con polarità definita
RW dai bit CCP1CON<1:0>
STRB
STRA 0 = il corrispondente pin è libero e disponibile per il portC

ECCPAS (1Dh) autoshutdown (autospegnimento segnale PWM)


NOTA: in modo PWM è possibile utilizzare il cambiamento di stato i comparatori del PIC per spegnere immediatamente le uscite.
Per controllare la corrente su un carico induttivo si può inserire una piccola resistenza in serie (o anche utilizzare un senso-
re ad effetto HALL) e confrontare la tensione ottenuta con un riferimento prefissato mediante un comparatore e quindi spe-
gnere la corrispondente linea di uscita.
7 ECCPASE RW 1= è avvenuto uno shutdown 0=no shutdown avvenuto
6 ECCPAS2 000= disabilita shutdown
5 ECCPAS1 oppure shutdown causato da: 001=comparatore1 010=comparatore2
4 ECCPAS0 RW 011=entrambi comparatori 100= pin INT=0 101= comparatore1 o pin
INT=0
110=comparatore2 o pin INT=0 111= comparatore1 o comparatore2 o pin INT=0
3 PSSAC1 stato di shutdown 00= (RC5 e RC3)0
RW 01= (RC5 e RC3)1 1x= (RC4 e RC2)stato alta impedenza (pin aperti)
2 PSSAC0
1 PSSDB1 controllo shutdown di RC4 e RC2 00= (RC4 e RC2 = 0
RW 01= (RC4 e RC2) = 1 1x= (RC4 e RC2) = stato alta impedenza (pin aperti)
0 PSSDB0
CM1CON0 registro di controllo del comparatore 1
7 C1ON RW 1 = abilita comparatore 1 0 = disabilita
6 C1OUT R stato logico del comparatore 1 (uscita)
5 C1OE RW 1 = pin RA2 connesso alla uscita del comparatore 0 = RA2 libero per altri usi
4 C1POL RW 1 = inverte stato logico del comparatore (equivalente a scambio ingressi   ) 0 = non inverte
3
2 C1R RW 1 = input + connesso a C1Vref 0 = input + connesso a RA0
1 C1CH1 connessione input (-) 00 = RA1 01 = RC1
RW 10 = RC2 11 = RC3
0 C1CH0
CM2CON0 registro di controllo del comparatore 1
7 C2ON RW 1 = abilita comparatore 2 0 = disabilita
6 C2OUT R stato logico del comparatore 2 (uscita)
5 C2OE RW 1 = pin RC4 connesso alla uscita del comparatore 0 = RC4 libero per altri usi
4 C2POL RW 1 = inverte stato logico del comparatore (equivalente a scambio ingressi   ) 0 = non inverte
3
2 C2R RW 1 = input + connesso a C2Vref 0 = input + connesso a RC0
1 C2CH1 connessione input (-) 00 = RA1 01 = RC1
RW 10 = RC2 11 = RC3
0 C2CH0

File: PIC16F690.DOC –rev.8 pag. 8/18


ipia F. MARAZZI lab. di elettronica a.s. 2012/2013
26013 CREMA giancarlo.livraga@istruzione.it

CM2CON1 registro di controllo del comparatore 2


7 MC1OUT R replica dello stato logico del comparatore 1
6 MC2OUT R replica dello stato logico del comparatore 2
5, 4, 3
2 T1GSS RW 0 = stato logico del comparatore 2 come gate per timer T1 1 = RA4 come gate per T1
1 C2SYNC RW 1 = stato logico del comparatore sincronizzato con fronte discesa del clock di T1 0 = asincrono
SRCON registro di controllo del bistabile SR
7 SR1 RW 1 = RC4 (C2OUT) connesso alla uscita Q del bistabile SR 0= RC4 connesso a C2OUT
6 SR0 RW 1 = RA2 (C1OUT) connesso alla uscita Q del bistabile SR 0= RA2 connesso a C1OUT
5 C1SEN RW 1 = abilita comando SET da stato logico di comparatore 1 0 = disabilita
4 C2REN RW 1 = abilita comando RESET da stato logico di comparatore 2 0 = disabilita
3 PULSS RW 1 = fornisce un singolo impulso (1 Toss) di SET 0 = no impulso
0 PULSR RW 1 = fornisce un singolo impulso (1 Toss) di RESET 0 = no impulso
1, 0
VRCON (99H) registro di controllo del generatore interno di tensione di riferimento
7 C1VREN RW Vref enable: 1= acceso generatore interno tensione di riferimento per comparatore 1 0 = spento
6 C2VREN RW Vref enable: 1= acceso generatore interno tensione di riferimento per comparatore 2 0 = spento
5 VRR RW Vref range select: 1=seleziona intervallo di riferimento basso, 0=seleziona intervallo alto
4 VP6EN RW 1 = utilizza riferimento fisso a 0.6V 0 = non utilizza
3 VR3 RW
VR<3:0> coefficiente (nnnn) di calcolo della tensione di riferimento generata:
2 VR2 RW
Vref(intervallo alto) = Vdd(1/4+nnnn/32) intervallo [1/4…23/32]Vdd
1 VR1 RW Vref(intervallo basso) = Vdd(nnnn/24) intervallo [0…15/24]Vdd
0 VR0 RW
ANSEL (9FH) selezione modo analogico o digitale per i singoli pin
7 ANS7 1=RC3 assegnato all‟AD converter 0=RC3 libero per altri usi
6 ANS6 1=RC2 assegnato all‟AD converter 0=RC2 libero per altri usi
5 ANS5 1=RC1 assegnato all‟AD converter 0=RC1 libero per altri usi
4 ANS4 1=RC0 assegnato all‟AD converter 0=RC0 libero per altri usi
RW
3 ANS3 1=RA4 assegnato all‟AD converter 0=RA4 libero per altri usi
2 ANS2 1=RA2 assegnato all‟AD converter 0=RA2 libero per altri usi
1 ANS1 1=RA1 assegnato all‟AD converter 0=RA1 libero per altri usi
0 ANS0 1=RA0 assegnato all‟AD converter 0=RA0 libero per altri usi
ANSELH (9FH) selezione modo analogico o digitale per i singoli pin
7, 6, 5, 4
3 ANS11 1=RB5 assegnato all‟AD converter 0=RB5 libero per altri usi
2 ANS10 1=RB4 assegnato all‟AD converter 0=RB4 libero per altri usi
RW
1 ANS9 1=RC7 assegnato all‟AD converter 0=RC7 libero per altri usi
0 ANS8 1=RC6 assegnato all‟AD converter 0=RC6 libero per altri usi
NOTA: la assegnazione di un pin all’AD converter disabilita i corrispondenti usi digitali (anche R pull_up e interrupt on change). Il cor-
rispondente bit di TRISIO deve essere configurato come input (1)
ADCON0 (1FH) controllo convertitore AD
Registro di controllo del convertitore A/D
7 ADFM AD formatting measure: 1 = giustificazione destra, 0 = giustificazione sinistra
6 VCFG Selezione sorgente di riferimento: 1 = Vrefpin (RA1), 0 = Vdd (alimentazione)
CHS3 Selezione canale di misura:
CHS2 0000 = RA0 0001=RA1 0010=RA2 0011=RA4 0100=RC0 0101=RC1
RW 0110 = RC2 0111=RC3 1000=RC6 1001=RC7 1010=RB4 1011=RB5
CHS1
CHS0 1100 = Vref (da VRCON) 1101=0.6V fissi 1110/1111=riservati, non usare
1 GO 1 = inizia conversione AD,poi si porta automaticamente a zero alla fine della conversione
0 ADON Alimentazione modulo AD: 1 = modulo alimentato, 0 = spento
ADCON1 (1FH) controllo clock del convertitore AD
7
6 ADCS2 frequenza di conversione (f= frequenza principale della cpu):
5 ADCS1 RW 000=f/2 001=f/8 010=f/32 x11=clock interno dedicato 500KHz
4 ADCS0 100=f/4 101=f/16 110=f/64
3, 2, 1, 0
NOTE SULLA CONVERSIONE AD
La giustificazione a destra è opportuna se si vuole una risoluzione a 10 bit e poi si deve scalare o convertire il formato della misura
(ad esempio in BCD per visualizzarlo su un display) mentre la giustificazione sinistra va bene se ci si accontenta di 8 bit di risoluzio-
ne in formato binario trascurando i due bit meno significativi.

File: PIC16F690.DOC –rev.8 pag. 9/18


ipia F. MARAZZI lab. di elettronica a.s. 2012/2013
26013 CREMA giancarlo.livraga@istruzione.it

Con 10 bit di risoluzione il quanto di conversione è Vref/1023 mentre trascurando i due bit meno significativi il quanto è Vref/255.
Utilizzando Vref=Vdd (5V classici) si ottengono sensibilità dell’ordine di ~5mV e ~20mV rispettivamente. Per avere maggiore sensi-
bilità (ma minore portata) si può utilizzare una tensione di riferimento esterna al pin GP1 configurando il bit ADVON0,VCFG.
Portare contemporaneamente allo stato 1 i due bit ADON e GO (accensione modulo e start contemporaneamente) porta ad un erro-
re nella conversione: usare due istruzioni separate: prima accendere il modulo e successivamente iniziare una conversione.

**************** IL SEGUITO riprende i contenuti della dispensa sul PIC12F675 – IN ATTESA DI REVISIONE***********************
EEROM
Il PIC dispone di 128 byte EEPROM (electrically erasable programmable read-only memory) con indirizzi lo-
cali <00…7Fhche vengono usati per salvare dati volatili necessari alla successiva riaccensione. Le opera-
zioni di scrittura/lettura scrittura sono gestite dai seguenti registri:
EEDAT contiene i dati (8 bit lettura/scrittura) da trasferire tra RAM  EEPROM
EEDATH contiene i dati (6 bit lettura/scrittura) da trasferire tra
RAM  EEPROM sequenza di scrittura
EEADR contiene l‟indirizzo (8 bit) EEPROM sul quale fare il trasferimento su EEPROM

EEADRH contiene l‟indirizzo (4 bit) EEPROM sul quale fare il trasferimento bsf EECON1,WREN
EECON1 registro di controllo: bcf INTCON,GIE
bit movlw 0x55h
7 1= accede RAM programma, movwf 0=accede RAM SFR
EECON2
6, 5, 4 non usati movlw 0xAAh
3 WRERR (flag di scrittura) 1=scrittura abortita, 0=scrittura completata movwf EECON2
2 WREN (enable bit): 1=abilita cicli di scrittura, 0=disabilita bsf EECON1,WR
1 WR (se bit 7=0): 1=inizia scrittura, azzeramento automatico a fine scrittura
0 RD (read control): 1=inizia lettura, azzeramento automatico a fine lettura
Per leggere un dato dalla EEPROM si deve mettere l‟indirizzo in EEADR e settare EECON1,RD := 1. Il dato
sarà in EEDATA nel ciclo macchina successivo.
Per scrivere un dato nella EEPROM, dopo avere caricato il dato in EEDATA e l‟indirizo in EEADR si deve
obbligatoriamente seguire la sequenza a fianco (il registro EECON2 non è un registro reale):

L’ASSEMBLER (FORMATO DEI DATI E DIRETTIVE )

Nella scrittura del programma si possono utilizzare i Formato esempio


formati numerici della tabella a fianco: di solito con- Binario b‟00100110‟
viene utilizzare il formato binario per specificare i dati Ottale o‟710‟
di configurazione del PIC e anche i dati relativi a mo- Esadecimale h‟9F‟ oppure (più comodo) 0x9F
vimenti di input/output, il formato esadecimale per gli Decimale d‟198‟ oppure (più comodo) .198
indirizzi dei registri ed il formato decimale (meglio usare ASCII a‟Z‟ oppure „Z‟
il punto decimale piuttosto che il prefisso d) per le operazioni numeriche quali temporizzazioni e valori analogici.
I programmi in assembler, oltre alle effettive righe di codice macchina possono contenere anche righe di
istruzioni dedicate al programma assemblatore (e si chiamano direttive). Vengono di seguito elencate alcune
delle direttive più comuni disponibili nel MASM (Microchip Assembler).
#include<file> il file specificato (con il suo percorso) viene incluso in questa posizione. La prima riga di
un programma è in genere #include<p12f675.inc>; questo file è fornito da Microchip e
contiene una serie di dichiarazioni di equivalenza che permettono al programma di utiliz-
zare i nomi simbolici dei registri e dei bit del PIC al posto dei loro effettivi valori.
__config nnnn Il PIC richiede un byte (14 bit) di configurazione primaria che viene caricato in area di
programma in fase di programmazione del dispositivo. Questo byte può essere predispo-
sto in ambiente MPLAB dal menu Configure/Configuration bits ma è meglio prendere no-
ta del valore predisposto, spuntare la casella configuration bits set in code e riportarlo in
questa direttiva in modo da garantire sempre la configurazione primaria adottata.
Label Nome (etichetta). Può trovarsi lungo il programma per dare un nome simbolico a quella
posizione da utilizzarsi per esempio come destinazione di un goto o una call. Può anche
essere utilizzato per dare il nome ad una variabile o ad una costante. Di regola deve sta-
re all‟inizio di una riga.
cblock La struttura
nome1 “cblock…endc” …
endc definisce una
lista di label
(nomi) che
vengono as-
segnate se-
File: PIC16F690.DOC –rev.8 pag. 10/18
ipia F. MARAZZI lab. di elettronica a.s. 2012/2013
26013 CREMA giancarlo.livraga@istruzione.it

quenzialmente
alle locazioni
RAM a partire
dalla locazione
nnn. Nel caso
del PIC12F675
la RAM dispo-
nibile comincia
alla locazione
0x20h
endc termina
la lista iniziata
con cblock
Equ Dichiarazione di equivalenza, ad esempio GPIO EQU 5. Con questa dichiarazione è pos-
sibile utilizzare il nome GPIO al posto del numero 5. In questo caso la istruzione
MOVWF GPIO verrà interpretata come MOVWF 5 risultando più comprensibile.
Altro esempio: banco0 equ BCF STATUS,RP0. Posto che STATUS ed RP0 sono stati
precedentemente definiti con una loro equ con questa dichiarazione, ogni volta che si
vuole commutare su banco0 si potrà utilizzare il nome simbolico banco0 al posto della
istruzione completa.
Org nnn Fissa il Program Counter al valore nnn specificato. Nel caso del PIC12F675 si devono
specificare la origine org 0x00 che è il vettore di reset (l‟indirizzo che viene raggiunto in
seguito ad un reset o ad una accensione) ed org 0x04 che è il vettore di interrupt
(l‟indirizzo che viene raggiunto a seguito di una richiesta di interruzione da parte di una
periferica abilitata). Quindi l‟inizio del codice di programma per un PIC12F675 di solito è:
org 0x00 goto STAR
org 0X04 goto INTE
START: qui inizia i
… …

INTERRUPT_SUB: qui inizia la routine di servizio all’interrupt



End marca la fine del programma
; (punto e virgola) marca l‟inizio di un commento che terminerà con una andata a capo da tasto INVIO
$ in qualsiasi posto sia messo assume il valore del program counter di quel punto.

File: PIC16F690.DOC –rev.8 pag. 11/18


ipia F. MARAZZI lab. di elettronica a.s. 2012/2013
26013 CREMA giancarlo.livraga@istruzione.it

ESEMPI DI PROGRAMMAZIONE
NOTA: In un file sorgente che deve essere assemblato ogni andata a capo fatta con il tasto INVIO definisce
una nuova riga ed ogni riga può contenere solo uno statement. Gli esempio sviluppati sono formattati per
comodità di lettura ed il testo viene “wrappato” automaticamente con un rientro quando arriva sul bordo pa-
gina: questa forma grafica non è disponibile nell‟ambiente di sviluppo MPLAB.
ESEMPIO 1: comparatore
GP2 = 1 quando la tensione su GP0 sale sopra quella di GP1, GP5 è il negato di GP2.

- #include<p12F675.inc>;il file P12F675.inc contiene una serie di dichiarazioni EQU che permettono di utilizzare i nomi simbolici dei registri e dei bit.
- __config 0x3194 ;il PIC è configurato per: oscillatore interno, GP<5,4,3> liberi per I/O, MCLR interno, altre opzioni disabilitate
- #define bank0 bcf STATUS,RP0 ;Assegna il nome simbolico bank0 alla istruzione che commuta su RAM banco 0
- #define bank1 bsf STATUS,RP0 ;Assegna il nome simbolico ban1 alla istruzione che commuta su RAM banco 1
- ;**************AREA PROGRAMMA semplice riga di commento per marcare le varie zone del programma
- org 0x00 ;Program counter:=00. All‟atto della accensione o dopo un reset il PIC comincia sempre dalla posizione 0x00, quindi il programm
- goto start ;…e qui trova un salto necessario per scavalcare la posizione 0x04…
- org 0x04 ;Il PIC esegue la istruzione alla posizione 0x04 in risposta ad una richiesta di interruzione…
- retfie ;…ed in que
- ;**************PROLOGO DI CONFIGURAZIONE
- start: ;è una label (etichetta). Assegna un nome simbolico a questa posizione di programma
- bank1 ;Attiva RAM banco1 (la scritta bank1 sarà sostituita dalla corrispondente direttiva EQU)
- clrf ANSEL ;Azzera il registro ANSEL (nessun pin connesso all‟AD converter)
- movlw b'00000011' ;Carica un dato binario nell‟accumulatore…
- movwf TRISIO ;…e lo trasferisce a TRISIO (configura GP<1..0> come input e gli altri come output)
- bsf PIE1,CMIE ;il bit indirizzato viene posto ad 1 (abilita localmente l‟interrupt dal comparatore)
- bank0 ;seleziona banco 0 (istruzione definita prima con una EQU)
- movlw b'00000001' ;Carica dato binario nell‟accumulatore…
- movwf CMCON ;…e lo trasferisce a CMCON (configura modo 001, uscita non invertita)
- clrf INTCON;Azzera il registro INTCON (e quindi non ammette alcun interrupt, nemmeno quello del ;comparatore che è stato localme
- ;**************TERMINE PROLOGO DI CONFIGURAZIONE, INIZIO PROGRAMMA
- loop:
- btfsc CMCON,COUT ;(bit test file skip clear) scavalca la prossima istruzione se il bit CMCON,COUT vale zero
- goto V_high ;Salta alla label V_high
- V_low: ;label
- bsf GPIO,5 ;forza allo stato 1 il bit 5 del registro GPIO
- goto loop ;Salta alla label loop
- V_high: ;label
- bcf GPIO,5 ;forza allo stato 0 il bit 5 del registro GPIO
- goto loop ;salta alla label loop
- end ;fine del programma. Tutto quello che fosse scritto dopo la direttiva end sarà ignorato

In questo esempio il comparatore è stato configurato in modo 001. Dalla tabella del registro CMCON si vede
che in questa configurazione il comparatore utilizza tutti i pin a disposizione e la sua uscita COUT è connes-
sa a GP2. Il programma, dopo avere definito una configurazione minima (solo i registri ed i bit strettamente
interessati al problema) si limita ad un loop che testa il bit interno CMCON,COUT (e non lo stato di GP2 che
potrebbe essere alterato da una errata condizione di carico) per forzare GP5 al suo complemento. I due loop
tratteggiati si diramano alla riga 23 che scavalca la riga successiva se il bit indirizzato (CMCON,COUT) vale
zero.

File: PIC16F690.DOC –rev.8 pag. 12/18


ipia F. MARAZZI lab. di elettronica a.s. 2012/2013
26013 CREMA giancarlo.livraga@istruzione.it

ESEMPIO 2: comparatore
L’esempio precedente utilizza una procedura di POLLING per testare ciclicamente lo stato del sistema (in
questo caso solo lo stato del comparatore). Un simile approccio non è certamente il massimo della efficienza
per due motivi: il cambiamento di stato non viene rilevato sino a che il programma non passa per le istruzioni
che fanno il test e le istruzioni di test vengono ripetute continuamente anche se lo stato non cambia. La mo-
dalità di INTERRUPT invece è molto più efficace: le istruzioni di test e le conseguenze stanno scritte in una
subroutine che, sotto condizione di abilitazione, viene chiamata automaticamente dall’evento associato (in
questo caso dal cambiamento di stato del comparatore). Si propone quindi una variante del programma pre-
cedente utilizzando una procedura di INTERRUPT (ed anche u cambio di configurazione del comparatore).
GP5=1se V(GP0)>2V.
La variante proposta lascia inalterate le prime 10 righe dell’esercizio precedente che non vengono riscritte.
- ….
- org 0x00
- goto start
- org 0x04 ;Entrata da richiesta di interrupt…
- goto interrupt ;…e dirottamento alla subroutine di servizio interrupt
- start:
- bank1 ;Seleziona banco1
- clrf ANSEL ;Nessun pin per AD converter
- movlw b'00000011' ;
- movwf TRISIO ;GP0 e GP1 input (e GP3 input di suo), gli altri output
- bsf PIE1,CMIE ;Abilita interrupt da cambiamento di stato del comparatore
- movlw b’10000101’ ;Accende generatore di tensione di riferimento, uscita alto range…
- movwf VRCON ;…ed imposta per Vref=VDD(1/4+5/32)=2.03V (con VDD=5V)
- bank0 ;Seleziona banco 0
- movlw b'00011110' ;Modo 110 (vedi registro CMCON) CIS=1 (connette GP0)…
- movwf CMCON ;…CINV=1 (inversione dei segni)
- bsf INTCON,PEIE ;Abilita interrupt da gruppo periferiche (vedi PIE1)
- bsf INTCON,GIE ;Abilita interrupt globale (vedi INTCON)
- goto $ ;Loop di attesa

- interrupt:
- bcf INTCON,GIE ;GIE=0 automaticamente in risposta ad interrupt, per ora lasciata a promemoria.
- bcf PIR1,CMIF ;Azzera il flag che ha segnalato il cambiamento di stato del comparatore
- btfss CMCON,COUT ;Scavalca la prossima istruzione se la uscita del comparatore vale uno…
- goto low ;…oppure salta a “low” se vale zero.
- high:
- bsf GPIO,GP5 ;Qui se la uscita del comparatore vale uno, allora GP5 = 1
- retfie ;Riabilita (globale) interrupt e torna al punto nel quale era stato interrotto
- low:
- bcf GPIO,GP5 ;Qui se la uscita del comparatore era bassa, allora GP5=0
- retfie ;
- end ;fine del programma. Tutto quello che fosse scritto dopo la direttiva end sarà ignorato

Come spiegato in apertura questo secondo esempio, avendo a disposizione un “evento” che segnala la ne-
cessità di una operazione utilizza la modalità di “interrupt” per la gestione del sistema. Il programma è libero
di fare altre cose (anche se nell‟esempio resta fermo sul “goto $” ) e, se opportunamente abilitato, verrà in-
terrotto dall‟evento (in questo caso il cambio dello stato della uscita del comparatore).
Possono esserci più eventi abilitati a chiedere un interupt al programma: in questo caso, poiché il PIC ha so-
lo una entrata di interrupt, la subroutine di servizio dovrà effettuare una procedura di polling esplorando i flag
delle periferiche abilitate per determinare quale (o quali) abbiano chiesto interrupt per poi svolgere le opera-
zioni previste.

File: PIC16F690.DOC –rev.8 pag. 13/18


ipia F. MARAZZI lab. di elettronica a.s. 2012/2013
26013 CREMA giancarlo.livraga@istruzione.it

ESEMPIO 3: interrupt su Timer0


Timer0 può utilizzare il clock interno di sincronismo delle istruzioni che ha una frequenza pari a f0/4 (f0 è la frequenza dell’oscillatore
principale che, per come abbiamo configurato sin qui vale 4MHz) e per conseguenza il segnale primitivo di clock vale 1MHz (1s di pe-
riodo). Timer0 è un contatore a 8 bit e dispone di un prescaler configurabile da 1:1 sino a 1:256 (fino a 8 bit di prescaler). Come tutti i
timer, genera un segnale di overflow quando i suoi 8 bit passano dallo stato 11111111 allo stato 00000000.
Si vuole generare una richiesta di interrupt ogni 50ms. Ad ogni interrupt il programma deve portare GP5 allo
stato 1 se (digitale GP0 =0 e V(GP1)>2V).Tutti gli altri pin liberi.
Per costruire un ciclo da 50ms bisogna contare 50.000s (in questo caso 50000 impulsi del clock primitivo da 1s,) allora:
50.000/256 = 195 (con resto di 80s). Trascurando il resto dobbiamo generare un interrupt ogni 256x195 impulsi da 1s.
Il calcolo è elementare: poiché il prescaler offre rapporti di divisione da 2n si cerca il più piccolo divisore 2n di 50000 tale che il risultato
sia inferiore a 255 (che è il massimo numero rappresentabile dagli 8 bit di Timer0) e si assegna questo numero (256) al rapporto di pre-
scaler mentre il complemento del quoziente (255-195) viene usato per caricare il timer. Il resto (80s che rappresentano un errore dello
0.16%) può essere trascurato purchè l’interrupt non venga usato per aggiornare un orologio in tempo reale poiché questo errore si ac-
cumula ad ogni chiamata di interrupt.
Il programma prevede di utilizzare solo GP0, GP1 e GP5 e quindi si è scelta la modalità 100 del comparatore che connette solo GP1
(CINV=1 è una finezza che compensa via hardware il segno rispetto al testo del problema)
5. …
6. CICLO equ (.256 - .195) ;il valore da caricare in timer0: 195 stati prima dell’overflow
7. start:
8. bank1
9. clrf ANSEL ;Nessun pin per il convertitore AD
10. movlw b'00000011' ;GP0 e GP1 configurati com input (GP3 input di suo)…
11. movwf TRISIO ;… GP<2,4,5> output. LO stesso dato abiliterebbe R pull_up…
12. movwf WPU ;… per GP0 e GP1 (ma GP0 verrà interdetta dalla configurazione del comparatore)
13. clrf PIE1 ;Disabilita le periferiche di PIE1
14. movlw b‟10000101‟ ;Accende generatore di tensione di riferimento (VREN), uscita intervallo alto…
15. movwf VRCON ;…ed imposta per Vref=VDD(1/4+5/32)=2.03V (con VDD=5V)
16. movlw b‟00000111‟ ;Abilita R pull_up (GPPU), clock interno e prescaler per timer0 (T0SE e PSA)…
17. movwf OPTION_REG ;…e prescaler rate da 1/256
18. bank0 ;Seleziona banco 0 (istruzione definita prima con una EQU)
19. movlw CICLO ;Il valore delle costanti (come CICLO) è meglio che sia calcolato a parte…
20. movwf TMR0 ;… ed utilizzato quando serve (qui per caricare timer0)
21. movlw b'00011100' ;Cin-  GP0, CINV=1(uscita invertita) …
22. movwf CMCON ;…e configura il comparatore
23. bsf INTCON,T0IE ;Abilita interrupt da timer0
24. bsf INTCON,GIE ;Abilita interrupt globale e da periferiche
25. goto $ ;Resta qui aspettando una chiamata di interrupt
26. interrupt:
27. bcf INTCON,GIE ;
28. bcf INTCON,T0IF ;Azzera il flag di timer0
29. btfss CMCON,COUT ;Scavalca la prossima istruzione se la uscita del comparatore vale uno…
30. goto Gp_low ;…oppure salta a “low” se vale zero.
31. btfsc GPIO,GP0
32. goto low ;Qui se la uscita del comparatore vale uno, allora GP5 = 1
33. Gp_high:
34. btfsc GPIO,GP0
35. goto Gp_low
36. bsf GPIO,GP5 ;
37. movlw CICLO
38. movwf TMR0 ;ricarica timer0
39. retfie ;Riabilita (globale) interrupt e torna al punto nel quale era stato interrotto
40. Gp_low:
41. bcf GPIO,GP5 ;Qui se la uscita del comparatore era bassa, allora GP5=0
42. movlw CICLO
43. movwf TMR0 ;ricarica timer0…
44. retfie ; …e ritorna
45. end
Il timer1 viene usato principalmente per operazioni di conteggio su segnali esterni perché i suoi bit sono tutti leggibili e scrivibili (16 bit, 2
byte di banco0 TMR1H e TMR1L, mentre del Timer0 si possono leggere solo gli 8 bit del registro TMR0). Il segnale esterno da conteg-
giare può essere il segnale periodico di un oscillatore (al quarzo, di precisione) oppure un segnale da GP5/ T1CKI con possibilità di abi-
litarne o meno il conteggio utilizzando il pin GP4/T1G come gate. Per altro l’uso di timer1 con l’oscillatore interno (frequenza f0/4), inter-
rupt oppure no, è sostanzialmente identico all’uso di timer0 quindi non verrà sviluppato un programma di esempio.

File: PIC16F690.DOC –rev.8 pag. 14/18


ipia F. MARAZZI lab. di elettronica a.s. 2012/2013
26013 CREMA giancarlo.livraga@istruzione.it

ESEMPIO4: conversione analogico/digitale


Il PIC dispone di un modulo sample and hold integrato. Il fabbricante prescrive che la impedenza massima della sorgente di tensione da
convertire sia inferiore a 10Kohm (altrimenti il condensatore di sample non riesce a caricarsi completamente) ed ulteriormente sono for-
nite le indicazioni per calcolare il tempo minimo di acquisizione. Ci sono diversi aspetti importanti nell’uso della periferica AD che coin-
volgono il clock da utilizzare e, non ultimo, il fatto che durante la conversione converrebbe mettere il processore in “sleep” per non di-
sturbare la tensione di alimentazione. Il risultato della conversione (a 10 bit) è in formato binario su due registri ADRESH(0x1Eh) e
ADRESL(0x9Fh) e può essere allineato a sinistra (comodo se ci si accontenta di soli 8 bit) o a destra (se si vuole poi fare la conversione
da binario a BCD).
Nel prossimo esempio verrà eseguita una conversione AD sulla tensione del pin GP0 e GP5=1 se il valore
rilevato è maggiore di 1.5 V.
Verrà utilizzata la modalità base: oscillatore interno dedicato a 500KHz, allineamento a sinistra e verranno valutati solo gli 8 bit più signi-
ficativi (perdendo 2 bit di sensibilità). Utilizzando gli 8 bit più significativi ed i 5V di alimentazione come riferimento risulta che:
1.5V= 5nn/255 da cui nn=76.5 che arrotonderemo a 76.
cioè gli 8 bit più significativi del convertitore conterranno il numero 7610 se in entrata al convertitore erano presenti 1.5V e 76 sarà il ter-
mine di confronto per decidere lo stato di GP5. Ovviamente il prologo è sempre lo stesso e non è stato scritto..
- …
- VREF equ .76 ;punto 76 (.76) è in base 10
- start:
- bank1
- movlw b’00110001’ ;Configurazione AD converter…
- movwf ANSEL ;…clock interno a 500KHz e GP0 riservato ADC
- movlw b'00000011' ;GP0 e GP1 configurati input (GP3 input di suo)…
- movwf TRISIO ;… GP<2,4,5> output. lo stesso dato abilita…
- movwf WPU ;… R pull_up su GP<0,1> (ma GP0 è interdetta da ANSEL)
- bcf OPTION_REG,NOT_GPPU ;Abilita gruppo R pull_up
- bsf PIE1,ADIE ;Abilita interrupt da AD converter
- bank0
- movlw b’00000001’ ;Giustificazione sinistra, riferimento Vdd, input su GP0…
- movwf ADCON0,F ;… e accende modulo
- bsf INTCON,PEIE ;Abilita interrupt da periferiche
- bsf INTCON,GIE ;Abilitazione globale interrupt
- nop ;i nop non sono necessari, è solo uno sfizio.
- nop
- bsf ADCON0,GO ;Inizia la conversione AD
- goto $ ;Resta qui aspettando una chiamata di interrupt
- interrupt:
- bcf INTCON,GIE ;disabilitazione generale chiamate interrupt
- bcf PIR1,ADIF ;azzera il flag del convertitore AD
- movlw VREF ;Carica il valore di confronto
- subwf ADRESH,W ;W := ADRESH-VREF,
- btfsc STATUS,C ;Se C=0 ADRESH<VREF, quindi salta
- goto VoltHigh ;Qui non ha saltato, quindi ADRESH>=VREF
- VoltLow: ;Qui se ADRESH<VREF
- bcf GPIO,GP5
- bsf ADCON0,GO ;Riparte la conversione AD
- retfie
- VoltHigh:
- bcf GPIO,GP5
- bsf ADCON0,GO ; Riparte la conversione AD
- retfie

File: PIC16F690.DOC –rev.8 pag. 15/18


ipia F. MARAZZI lab. di elettronica a.s. 2012/2013
26013 CREMA giancarlo.livraga@istruzione.it

ESEMPIO5: L’indirizzamento indiretto


L’indirizzamento indiretto prevede che l’indirizzo su cui applicare la operazione voluta non sia specificato nella istruzione stessa ma stia
scritto in un registro da qualche parte nella RAM (nel nostro caso è d’obbligo nel registro FSR). Ma se l’indirizzo è nella RAM allora il
suo valore è manipolabile dal programma stesso. Se ad esempio si deve applicare la medesima operazione su un insieme di registri si
può utilizzare un loop che esegue la operazione richiesta ed anche la modifica dell’indirizzo.
Il PIC dispone della modalità di indirizzamento indiretto che utilizza il registro virtuale INDF(00h) ed il registro FSR (04h File Select Re-
gister). l’uso del nome INDF (o del corrispondente valore 00) nella parte di indirizzamento di una istruzione ha come conseguenza che
’indirizzo effettivo (9 bit) è ottenuto aggiungendo il bit STATUS,IRP agli 8 bit del registro FSR. La coppia di bit <IRP,FSR,7> indirizza il
banco RAM (fino a 4 banchi). Quindi per il PIC12F675 che ha solo 2 banchi il bit IRP va sempre tenuto a zero e nell’indirizzamento indi-
retto l’ottavo bit di FSR funge da switch del banco RAM al posto di STATUS,RP0. Nell’indirizzamento diretto invece la istruzione forni-
sce i primi 7 bit dell’indirizzamento e l’ottavo è fornito dal bit STATUS,RP0.
L’indirizzamento indiretto quindi consiste nel caricare l’indirizzo voluto nel registro FSR e quindi utilizzare INDF (o 00h) nella parte di
indirizzamento del codice.
Nel prossimo esempio (molto adatto al simulatore) verrà riempita l‟area RAM da 021H fino a 02Fh e poi, po-
nendo GP3=0, verrà azzerata in ordine inverso.
- …
- NumLoop EQU 0x2F-0x21 ;la quantità di registri sui quali operare
- CountLoop equ 0x20 ;l’indirizzo del registro usato come contatore
- StartReg equ 0x21 ;l’indirizzo di partenza
- start:
- bank1
- clrf ANSEL ;No pin su ADC
- bank0
- movlw b’00000111’
- movlw CMCON ;Comparatore off, pin liberi
- movlw NumLoop ;Il numero di registri su sui operare è caricato …
- movwf CountLoop ;…nel registro CountLoop che farà da contatore
- movlw StartReg ;L’indirizzo di partenza è caricato…
- movwf FSR ;…in FSR
- clrw ;Azzera l’accumulatore
- loop:
- movwf INDF ;Il contenuto dell’accumulatore è copiato all’indirizzo specificato da FSR
- decfsz CountLoop,F ;Decrementa CountLoop e salta se non ha finito
- goto nextLoop ;Ha finito di scrivere, torna indietro e cancella
- goto ritorno
- nextLoop:
- incf INDF,W ;Incrementa il valore indirizzato ma il risultato nell’accumulatore
- incf FSR,F ;passa al registro successivo
- goto loop ;e ripeti
- ritorno:
- btfsc GPIO,GP3
- goto ritorno ;Aspetta che venga premuto GP3
- decLoop:
- clrf INDF ;Cancella l’ultimo registro scritto
- decf FSR ;Fa un passo indietro
- movlw StartReg ;Prende l’indirizzo di partenza
- subwf FSR,W ;Indirizzo di partenza - FSR
- btfsc STATUS,C ;Se non genera Carry FSR<Indirizzo di partenza: fine
- goto decLoop ;Non ha finito, ripete
- goto $ ;fermoi qui
- end

File: PIC16F690.DOC –rev.8 pag. 16/18


ipia F. MARAZZI lab. di elettronica a.s. 2012/2013
26013 CREMA giancarlo.livraga@istruzione.it

ESEMPIO 6: le tabelle (1)


Le istruzioni di programma vengono eseguite in sequenza una dopo l‟altra a meno che il flusso non venga
alterato dalla seguenti istruzioni:
Dopo questa istruzione il programma prosegue alla posizione definita dalla “label”. Questo è detto un salto “assolu-
goto label to” perché la posizione di arrivo è definita in maniera fissa dalla posizione della label.
Dopo questa istruzione il programma si porta lla posizione definita dalla label e quando incontra una opportuna
call label istruzione di ritorno riprende dalla istruzione successiva alla call.
“test” ha la forma di “registro,bit” ed identifica un certo bit di un certo registro. Il programma Scavalca la istruzione
btfss test
successiva oppure no a seconda che il bit identificato soddisfi la condizione posta (btfss: skip set – scavalca se il bit
btffc test vale 1; btfsc: skip clear – scavalca se il bit vale zero)
in- Il programma termina la istruzione corrente e prosegue all‟indirizzo 0x04 (vettore di interrupt) e quando incontra una
richiesta di
terrupt opportuna istruzione di ritorno riprende dalla istruzione successiva al punto di interruzione.

Il PIC rende disponibili in RAM gli 8 bit parte bassa del program counter (registro PCL, indirizzo 0x02 dupli-
cato anche in banco1 a 0x82)e la istruzione RETLW K che è una istruzione di ritorno da subroutine con la
costante K nell‟accumulatore. Il combinato di queste prestazioni rende possibile la implementazione di ta-
belle mediante la realizzazione di quello che il manuale chiama “goto computato” e che corrisponde al clas-
sico salto relativo cioè ad un salto di “n” posizioni in avanti (o anche indietro).
L‟esempio seguente usa il “goto computato” per implementare la tabella di verità della conversione da codice
gray a 4 bit a codice binario a fianco riportata.
NOTA 1: questa procedura è equivalente a risolvere le funzioni logiche indipendenti ABCD della tabella di verità e quindi è di uso gene-
rale.
NOTA 2: la variabile tableLenght può essere usata sia per controllare che il dato non origini un salto fuori dalla
tabella (e conseguente crash del programma) sia per gestire un loop che volesse leggere tutta la tabella. GRAY ... binario
NOTA 3: la effettiva tabella (da tableStart: a tableEnd) può anche essere messa in un file esterno ed inserita ....... A B C D
in questa posizione con una direttiva include<>) rendendo il codice più pulito. 0000 ... 0 0 0 0
0001 ... 0 0 0 1
- … 0011 ... 0 0 1 0
- org 0x00 0010 ... 0 0 1 1
- goto start 0110 ... 0 1 0 0
- org 0x04 0111 ... 0 1 0 1
- retfie 0101 ... 0 1 1 0
- TABLE: ;il codice gray è contenuto nell’accumulatore W in forma 0000xxxx 0100 ... 0 1 1 1
- addwf PCL,F;il contenuto dell’accumulatore è sommato alla parte bassa del program counter così1100
generando
... 1 0un0 salto
0 in avanti pari al c
- tableStart: 1101 ...;accumulatore
1001 valore di rito
- retlw b’00000000’ 1111 ... 1 0 1 ;0000
0  00
- retlw b’00000001’ 1110 ... 1 0 1 ;0001
1  00
- retlw b’00000011’ 1010 ... 1 1 0 ;0010
0  00
- retlw b’00000010’ 1011 ... 1 1 0 ;0011
1  00
- retlw b’00000111’ 1001 ... 1 1 1 ;0100
0  01
- …. ;avanti a1000
riempire
...tutte
1 1 1le 1righe
- retlw b’00001010’ ;1111  10
- tableEnd:
- tableLenght = (tableEnd-tableStart-1) ;lunghezza della tabella
- start:
- … ;tutto quello che si vuole
- … ;posto che nell’accumulatore ci sia il codice da trasformare nella forma 0000xxxx
- call TABLE ;
- … ;di ritorno da TABLE l’accumulatore contiene il valore associato al codice
- …
- end

NOTA IMPORTANTISSIMA: il salto realizzato con la istruzione “addwf PCL,F” non genera riporto del carry
agli 8 bit parte alta del program counter per cui è obbligatorio che la tabella sia contenuta in una pagina della
memoria di programma. Per intenderci: la dimensione massima della tabella è di 255 byte ammesso che la
istruzione di salto sia nella posizione xx00 (già nell’esempio la istruzione di salto è all’indirizzo xx05 e la massima dimensione
della tabella è di 255-5=250 byte)

File: PIC16F690.DOC –rev.8 pag. 17/18


ipia F. MARAZZI lab. di elettronica a.s. 2012/2013
26013 CREMA giancarlo.livraga@istruzione.it

ESEMPIO 7: le tabelle (2)


Nell‟esempio 6 di cui riportiamo un estratto a fianco la istruzione “addwf PCL,F” che …
origina il salto computato viene eseguita nella certezza che il salto caschi sopra una TABLE:
istruzione del tipo “return”.
Se capitasse un salto più lungo della tabella a causa di un valore troppo grande prepara- addwf PCL,F
to nell‟accumulatore il programma andrebbe in crash poiché finirebbe su una posizione tableStart:
imprevista e da li andrebba avanti invece di tornare alla call di origine. retlw b’00000000’
È buona cosa prevedere un controllo di congruenza tra il valore del salto ricevuto dalla
chiamata e la lunghezza effettiva della tabella. La costante tableLen già presente ….
nell‟esempio 6 contiene il massimo valore ammesso per la istruzione di salto computato retlw b’….’ ;ultima riga della tabella
addwf PCL,F ed il programma può essere reso più sicuro e più flessibile se ogni volta tableEnd
che interviene la dimensione della tabella si verifica che questo sia compatibile con il
valore di tableLen. tableLen=(tableEnd-tableStart-1)
Si modifichi l’esempio 3 in modo che:

1. G
P3 e GP0 siano configurat1 come input e tutti gli altri pin siano configurati come output
2. I
l comparatore sia nello stato OFF (modalità 111)
3. La routine di interrupt generi ciclicamente la sequenza
GP< 5 4 2 1> GP5
1 0 0 0 GP4
0 1 0 0 GP2
0 0 1 0 GP1
0 0 0 1
1 0 0 0 ;ripete da capo

cblock 0x20
contatore ;il registro contatore verrà usato ler leggere la tabella
endc

org 0x00
goto start
org 0x04
goto interupt
TABLE: ;
addwf PCL,F ;
tableStart: ;
retlw b’00100000’ ;
retlw b’00010000’ ;
retlw b’00000100’ ;
retlw b’00000010’ ;
tableEnd:
tableLenght = (tableEnd-tableStart) ;lunghezza della tabella

start:

movlw b’00001001’
movwf TRISIO ;GP3 e GP0 come input, altro come output

movlw b’00000111’
movwf CMCON ;Comparatore spento

clrf contatore ;prepara pulito
decf contatore ;anticipa di un incremento


interrupt:
bcf INTCON,GIE
bcf INTCON,T0IE
movlw tableLen
subwf contatore
btfss STATUS,C
goto ripristina

File: PIC16F690.DOC –rev.8 pag. 18/18

Potrebbero piacerti anche