Generatore di onde quadre Il generatore di onde quadre consiste
di un treno di onde luminose caratterizzate da un periodo il cui
50% il livello logico alto e il restante 50% a livello logico
basso. Fare ci, significa gestire il tempo e quindi i ritardi sui
pic Un metodo molto semplice e forse, un po banale, quello di far
lavorare la macchina avuoto senza far eseguire alcuna operazione.
Listruzione per non far eseguire operazioni nop. La routine la
seguente: LIST p=16F628 include "P16F628.inc ; libreria dove sono
definiti I registri del 16f628 org 0x0000 movlw 0x07 movwf CMCON
;tutti i comparatori sono disattivati. Le porte che sono
multiplexate, fungono solo ;da I/O bsf STATUS, RP0 ; viene posto a
1 il bit RP0 del registro Staus per selezionare il bank1 movlw
b'00000000' movwf TRISB ;portb come output movwf TRISA ;porta come
output bcf STATUS, RP0 ; viene posto a 0 il bit RP0 del registro
Staus per selezionare il bank0
Slide 4
Loop del programma Loop movlw 0xff ; viene caricato il numero
;255 in formato esadecimale che tradotto un binario 11111111 movwf
PORTA ;porta a livello logico alto movwf PORTB ;portb a livello
logico alto nop ; viene inserito un ritardo di 1 microsecondo
;perch ogni ciclo macchina ha frequenza 1 Mhz nop ; per 1 us la
macchina non esegue operazioni movlw 0x00 ; viene caricato lo zero
movwf PORTA ;porta e portb sono a livello logico basso movwf PORTB
nop goto Loop end
Slide 5
Nop Nop listruzione che non fa eseguire alcuna operazione. A
che cosa pu servire? Fa lavorare il micro a vuoto per mantenere
fisso lo stato di un microcontrollore e non far cambiare stato.
Quanto pu durare un ritardo? Se la frequenza di clock di 4 MHz, il
periodo sar di 0,25 us e il tempo macchina 4*T clock =1us Ogni
ciclo macchina dura quindi 1 us se la frequenza di clock 4 MHz. Il
ritardo ottenuto quindi 2 us visto che sono state introdotte due
righe con listruzione nop
Slide 6
Senza libreria Se non avessimo inserito la libreria avremmo
dovuto dare delle direttive al compilatore: PORTA EQU 0x05 PORTB
EQU 0x06 TRISA EQU 0x05 TRISB EQU 0x06 STAUS EQU 0x03 RP0 EQU 0x05
; bit 5 del registro status CMCON EQU 0x1F
Slide 7
Riga programmaRegistro interessato Stato deI bit Registro MOVLW
0X07accumulatore00000111 MOVWF cmconcmcon00000111 Bsf status,rp05
bit registro status00100000 Movlw 0x00accumulatore00000000 Movwf
trisaTrisa del bank100000000 Movwf trisbTrisb del bank100000000 Bcf
status, rp05 bit registro status00000000 Movlw
0xffaccumulatore11111111 Movwf portaPorta del bank011111111 Movwf
portbPortb del bank011111111 nopNessun registro Movlw
0x00accumulatore00000000 Movwf portaPorta del bank000000000 Movwf
portbPortb del bank000000000
Slide 8
Ritardo con una routine di ritardo Con pochi microsecondi di
ritardo non possiamo renderci conto della differenza tra i due
livelli logici e, gestire un ritardo pi grande, comporterebbe la
scrittura di un numero enorme di istruzioni nop. Un metodo pi
efficace quello di inserire un valore in un registro GFR e,
decrementarlo. La macchina rimane nel suo stato fino a quando il
registro non zero Si passa alla istruzione successiva se tutto
nullo. Useremo quindi decfsz salta alla istruzione successiva se il
risultato nullo Il programma il seguente: LIST p=16F628 include
"P16F628.inc count1 equ 0x0C ; registro generale count2 equ 0x0D
org 0x00
Slide 9
Ritardo con una routine di ritardo movlw 0x07 movwf CMCON ;pone
I comparatori a 1 bsf STATUS, RP0 ;seleziona bank1 movlw
b'00000000' movwf TRISB movwf TRISA bcf STATUS, RP0 ;seleziona
banco 0 clrf PORTA ;porta non viene mai usata clrf PORTB loop: call
Delay bsf PORTB, 7 ;pone il bit 7 a livello logico alto call
Delay
Slide 10
Ritardo con una routine di ritardo: subroutine di ritardo
Spegni: bcf portb,7 ;pone a livello logico basso il bit 7 goto loop
Delay: movlw 0x0f movwf conta2 ;pone il valore 15 in un GFR movlw
0x0f movwf conta1 ;pone il valore 15 in un GFR Loop1: decfsz conta1
;decrementa il registro e salta se zero goto Loop1 Loop2: decfsz
conta2 ;decrementa il registro e salta se zero goto Loop2 return
end
Slide 11
Osservazioni Nel programma sono stati settati sia i registri
porta e trisa che non servono; non serve nemmeno il settaggio del
registro comcon che setta i comparatori. Se fosse stato utilizzato
tutto il registro trisa, sarebbe stato utile settare i comparatori.
Si noti che il ritardo sul cambio di stato di ogni porta di 30 us
perch il decremento di ciascun registro 0ch e 0dh dura 15 cicli
macchina e, ogni ciclo dura 1 us; 15 cicli durano 15 us. Siccome
sono due registri da decrementare, il ritardo sar di 30 us Per fare
un ritardo pi grande, si possono settare a 1 al massimo 8 bit di
ciascun registro per un numero di cicli massimi di decrementi pari
a 255 us
Slide 12
esercizio Scrivere un programma che faccia accendere e spegnere
alternativamente 2 led e ciascuno con un ritardo di 200 us
Slide 13
Osservazioni Quando si incontra listruzione goto oppure call
subroutine, si ha un salto e si interrompe il flusso del programma
per eseguire la linea programma o la subroutine. Nella memoria
programmi c una parte riservata allo stack pointer in cui si
inserisce lindirizzo in cui stato interrotto il programma.
Terminate le istruzioni in cui il programma saltato, lo stack
pointer fornisce lindirizzo della memoria programma dove
ritornare
Delay Riga programmiRegistriBit Movlw 0x02w00000010 Movwf
conta1Registro 0x0c00000010 Movlw 0x02W00000010 Movwf
conta2Registro 0x0d00000010 Decfsz conta10x0c00000001 Goto loop1
Decfsz conta10x0c00000000 Decfsz conta20x0d00000001 Decfsz
conta20x0d00000000 Return Supponiamo di inserire un ritardo molto
pi piccolo Ritorna allultima chiamata di subroutine.
Slide 16
Un tempo di ritardo pi lungo Delay: movlw 0x0f movwf conta2
;pone il valore 15 in un GFR Loop2: movlw 0x0f movwf conta1 ;pone
il valore 15 in un GFR Loop1: decfsz conta1 ;decrementa il registro
e salta se zero goto Loop1 decfsz conta2 ;decrementa il registro e
salta se zero goto Loop2 return end Questa volta, per ogni
decremento di conta2, si ritorna a loop2 Ogni decremento di conta2
genera 15 decrementi di conta1 I decrementi terminano quando conta2
zero Il tempo di ritardo 255 us=15*15
Slide 17
Sorgenti di segnali Ogni microcontrollore lavora secondo un
certo sincronismo I segnali di sincronizzazione possono essere
interni o esterni Se esterni, viene applicato un generatore di
impulsi ad una certa frequenza su un determinato pin. Nel caso del
pic16f628, il segnale viene applicato sul pin 3
Slide 18
Prescaler e interrupt Il pic 16f628 dotato di un timer interno
ad 8 bit. Il registro timer0, registro del bank0 allindirzzo 01h,
incrementa il proprio contenuto per ogni ciclo macchina
Loscillatore interno del pic genera una frequenza f=4 MHz; la
frequenza di un qualsiasi segnale proveniente dal pic quindi di
f/4=1 Mhz, frequenza macchina. Il registro timer0 incrementa cos il
proprio contenuto con la frequenza di 1 MHz La frequenza di
interruzione, frequenza di interrupt, si ha quando il timer inizia
a contare daccapo, cio quando passa da overflow a zero. Essendo il
timer0 di 8 bit, linterrupt si ha ogni 2 8 -1 cicli macchina+1=256
contando anche il passaggio da overflow a zero
Slide 19
Frequenza di interrupt La frequenza fi di interrupt si calcola
dividendo la frequenza macchina per 256: fi=f(osc)/(4*256) Si
potrebbe cambiare la frequenza di interrupt con due metodi:
Inizializzando il timer con un valore Nt diverso da 0. come
accorciare la lunghezza del timer cos impiegher meno tempo per
andare in overflow La nuova frequenza fi di interrupt sar:
fi=f(osc)/4/(256-Nt) La frequenza di interrupt pu cambiare se si
inserisce un prescaler, cio un divisore di frequenza. Il prescaler
formato dai tre bit del registro option che si trova allindirizzo
81h, cio un registro di bank1
Slide 20
Esercizi per impostare linterrupt senza prescaler 1. Calcolare
il periodo di interrupt se Nt=0 2. Calcolare il periodo e la
frequenza di interrupt se Nt=200 3. A quanto bisogna impostare Nt
se si chiede che fi=300 Hz
Slide 21
Registro Option Bit 0RBPUDisabilita o abilitai resistori
interni di pull up 0 disabilita 1 abilita Bit 1INTEDGSeleziona il
fronte di salita di interrupt su RB0/INT 0 fronte salita 1 fronte
discesa Bit 2TOCSSeleziona il fronte di segnale di clock del timer
0 clock interno 1 clock esterno Bit 3TOSESeleziona il fronte del
segnale per il clock del timer su RA4/TOCKL 0 fronte di discesa 1
fronte di salita Bit 4PSAAssegna il prescaler l timer TMR0 o al WDT
0 TMR0 1 WDT Bit 5PS2Selezione il fattore di divisione per il TMR0
Bit 6PS1 Bit 7PS0
Slide 22
Un piccolo schema
Slide 23
Prescaler Ps2Ps1Ps0Divisore 0002 0014 0108 01116 10032 10164
110128 111256 Se si vuole cambiare la frequenza fi di interrupt con
Np, il fattore di divisione di prescaler fi assumer la seguente
formula matematica: fi=fosc/4/Np
Slide 24
Prescaler La frequenza di interrupt pu essere cambiata anche
utilizzando sia il prescaler che cambiando il punto di partenza del
timerO. La frequenza fi pu cambiare nel seguente modo:
fi=fosc/4/Np*(256-Nt)
Slide 25
Esempio con il prescaler Supponiamo di voler generare un
interrupt ogni 3 ms Ti=256*Tm=256*4*Tclock=256/fosc/4 Si inserisce
il prescaler per cambiare Ti Ti=256*Np/f/4 Imponendo Ti=3
Np=Ti/256*fosc/4=11.72 Questo valore non nelle tabelle del
prescaler Si pu far partire il conteggio del timer da un valore
diverso da zero Si deve allora calcolare il valore Nt da dove far
partire il timer Si pu utilizzare la seguente formula per calcolare
il periodo di interrupt Ti=Np*((256-Nt)/fosc/4 Se si impone Ti=3
ms, Np=64, si calcola Nt=256- 3000/64=209,125=209
Slide 26
esempio Si vuole accendere e spegnere un led collegato su RA0
di un pic16f628 con periodo di 1 secondo. Si utilizza un clock di 4
MHz. Se si impone un divisore di prescaler pari a 64, la frequenza
di interrupt diventa 15625 Con un semplice conto, si calcola che
per avere 1 Hz basta far partire il timer da 125
Slide 27
Esercizi Se Nt=200 e Np=512, per un clock con frequenza 4 MHz,
che valore assumeranno fi e ti? Se si vuole una frequenza f pari a
300 con un clock di 4 MHz, come bisogna combinare Np ed Nt?
Slide 28
Registro INTCON GIEAbilitazione di tutti gli
interrupt0disabilitati 1abilitati EEIESegnala il completamento
nella memoria EEPROM 0Non completo 1Completo TOIEAbilita linterrupt
per il superamento di capacit del timer0 0Disabilitato 1Abilitato
INTEAbilita linterrupt su RB0/INT0 Disabilita 1 Abilita RBIEAbilita
linterrupt per il cambio di livello su RB7- RB4 0 Disabilita 1
abilita TOIFSegnala overflow su timer0 0 No Overflow 1 Overflow
avvenuto INTFSegnala la richiesta di interrupt su RB0/INT 0 Nessuna
richiesta 1 Richiesta avvenuta RBIFSegnale di cambio di livello su
RB7-RB4 0 Nessun cambio livello 1 Cambio di pi livelli
Slide 29
Routine di interrupt senza prescaler La routine di interrupt va
scritta a partire dalla locazione 004 della memoria programma Se si
vuole utilizzare il timer senza inserire il prescaler, bisogna
seguire questa sequenza di passaggi: Scrivere una routine di
interrupt a partire dalla locazione 004. Nella routine bisogna dare
le seguenti informazioni: Si carica il valore dal quale bisogna far
partire il timer Azzerare il flag di avvenuto interupt, bit 2 del
registro INTCON Ritornare al programma principale tramite il
comando RETFIE Nella routine principale bisogna scrivere: Porre a
zero il bit 5 del registro OPTION, cio porre in modalit timer
Caricare il valore iniziale del timer Abilitare linterrupt ponendo
a 1 il bit 5 di INTCON Abilitare gli interrupt ponendo a 0 il bit 7
del registro INTCON
Slide 30
Routine di interrupt con prescaler Bisogna scrivere la routine
di interrupt e partire dalla locazione 004 della memoria programma
o ricaricare il valore iniziale del timer o azzerare il flag di
avvenuto interrupt tramite il bit 2 del registro INTCON o terminare
la routine di interrupt tramite listruzione RETFIE Nel programma
principale si scrivono le seguenti istruzioni: o assegnare il
prescaler al timer ponendo a 0 il bit 3 del registro OPTION o
selezionare il fattore di divisione del prescaler o assegnare il
valore di inizio del timer o abilitare linterrupt del timer ponendo
a 1 il bit 5 di INTCON o abilitare tutti gli interrupt ponendo a 1
il bit 7 di INTCON
Slide 31
Come settare il prescaler
Slide 32
esempio Si vuol far accendere e spegnere un led su RA1 con
frequenza 1 Hz. Si utilizzi un quarzo di 4 MHz f(clock)=4000000Hz;
f(macchina)=1000000 Hz Si pone Np=(64) 10 =combinazione prescaler
101 256-Nt=125
Slide 33
Lampeggio di un led con frequenza di 1 Hz list p=16f628 radix
dec porta equ 5 portb equ 6 Timer equ 1 intcon equ 0x0b cont equ
0x0c flag equ 0x0d toif equ 0x02 toie equ 0x05 gie equ 0x07 goto
start
Lampeggio di un led:routine principale start: movlw 0xd5 ;
carica il valore 11010101 movwf option movlw 0xff tris portb movlw
0x00 tris porta RBPUINTEDGTOCSTOSEPSAPS2PS1PS0 11010101 Divisore di
prescaler=64 Clock interno Prescaler al timer
Slide 36
Lampeggio di un led movwf timer ;laccumulatore ancora azzerato
movwf cont bsf intcon, toie ;abilita linterrupt timer bsf intcon,
gie ;abilita gli interrupt ancora: movlw 125 xorwf cont,0 ;esegue
loperazione logica XOR tra cont e W e pone il risultato in W skpz ;
salta se il risultato zero. Il conteggio si ferma a 125 goto ancora
avanti: movwf cont comf flag,1 ;complementa flag e pone il
risultatp in flag btfsc flag,0 ;testa il bit 0 e salta se 0 goto
accendi bcf porta,0 goto ancora accendi: bsf porta,0 goto ancora
end