4.PWM e PIC
Vediamo ora come generare dei segnali PWM con i microcontrollori PIC. Esistono
due modi per generare tali segnali: il primo (emulazione PWM software) consiste
nello scrivere del codice che generi un'onda quadra di frequenza e duty cycle
assegnata su un certo piedino di uscita, il secondo (PWM hardware) consiste
nell'utilizzare delle periferiche apposite dei PIC , i moduli CCP (capture compare
PWM), per generare l'onda. Risulta ovvio che il secondo metodo è il migliore(con
il primo la generazione dell'onda quadra può essere difficile e comunque
toglie preziosi cicli di clock al resto dell'applicazione) tuttavia non tutti
i microcontrollori PIC ne sono dotati: nel nostro caso utilizzeremo dei uC PIC16F877
e PIC16F876 che mettono a disposizione ben due moduli CCP per il PWM: tali moduli
si appoggiano al timer 2 e sono quindi vincolati ad avere la stessa frequenza
mentre il duty cycle può essere variato indipendentemente per i moduli
andando a scrivere in appositi registri.
Per poter utilizzare i moduli CCP è necessaria una fase di setup che
consiste nell'inserimento di opportuni valori nei registri che regolano il timer2
(T2CON e PR2), i due moduli CCP (CCP1CON , CCP2CON,CCPRxL) e la porta C (TRISC).
Cominciamo dai registri
del Timer2 dai quali dipende la frequenza di PWM:
T2CON è un registro a 8 bit così suddiviso:
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
- |
TOUTPS3 |
TOUTPS2 |
TOUTPS1 |
TOUTPS0 |
TMR2ON |
T2CKPS1 |
T2CKPS0 |
Il
bit 7 non viene utilizzato
I bit 6-3 servono per il valore del postscaler (nel nostro caso vanno messi
a 0)
Il bit 2 serve per attivare (valore 1) -disattivare (valore 0) il Timer2
I bit 1-0 servono per impostare il valore del prescaler (come vedremo è
uno dei parametri che permettono di impostare la frequenza di PWM)
un esempio di contenuto del registro può essere 0b00000100 (timer2 ON
e valori di postscaler e prescaler unitari).
Il valore del periodo di PWM viene stabilito scrivendo opportunamente sul registro
a 8 bit PR2.
La seguente equazione permette di ricavare il Periodo di PWM:
periodo PWM =[(PR2)+1]*4*Tosc*(TMR2 prescale value)
dove:
PR2 è il valore inserito nel registro PR2
Tosc è l'inverso della frequenza del quarzo esterno che fornisce il clock
al PIC
TMR2 prescale value è il valore dei due bit meno significativi del registro
T2CON
La tabella che segue raccoglie alcuni esempi di frequenze di PWM che si possono
ottenere con diverse impostazioni dei registri e delle frequenze del quarzo
esterno:
Frequenza Quarzo | Valore PR2 | Prescale Value | Frequenza di PWM |
4 MHz | 255(0xFF) | 1 | 4096 Hz |
4 MHz | 127(0x7F) | 2 | 4096 Hz |
20 MHz | 255(0xFF) | 1 | 20480 Hz |
Passiamo
ora alla configurazione dei due moduli CCP1 e CCP2, i registri CCPxCON (sostituire
la x con 1 e 2) svolgono una duplice funzione: contengono la configurazione
del modulo e parte del valore binario con cui è espresso il duty cycle.
Sono così suddivisi:
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
- | - | CCPxX | CCPxY | CCPxM3 | CCPxM2 | CCPxM1 | CCPxM0 |
I bit 7-6
non vengono utilizzati
I bit 5-4 contengono i bit meno significativi del valore del duty cycle
I bit 3-0 contengono la configurazione del modulo CCP corrispondente, per settare
il modulo per il funzionamento in PWM i bit 3 e2 devono essere posti a 1 mentre
il valore dei bit 1 e 0 è ininfluente (noi lo metteremo a 0).
Il registro TRISC deve essere configurato in modo che i pin 1 e 2 (quelli su
cui avremo l'uscita PWM) siano pin di uscita, quindi TRISC1 e TRISC2 dovranno
essere posti a 0.
I registri CCPR1L e CCPR2L contengono invece gli otto bit più significativi
del valore del duty cycle. Il duty cycle può quindi essere espresso con
una risoluzione di 10 bit (quindi valori da 0 a 1023!).
Ricapitolando ecco i settaggi da eseguire per inizializzare i moduli PWM:
1.Scrivere nel registro PR2 il periodo del PWM
2.Scrivere il duty cycle nei registri CCPRxL e nei bit 5:4 del registro CCPxCON
3.impostare i pin 1 e 2 della porta C come uscite azzerando gli opportuni bit
del registro TRISC
4.inizializzare il timer2 scrivendo sul registro T2CON
5.inizializzare i moduli CCP per le operazioni PWM scrivendo sui registri CCPxCON
Tali settaggi sono necessari solo all'inizio del programma che verrà
inserito nel microcontrollore, successivamente, quando sarà necessario
cambiare il duty cycle dell'onda quadra, sarà sufficiente modificare
i valori presenti nei registri CCPRxL e nei bit 5:4 dei registri CCPxCON (questi
ultimi due valori spesso non vengono modificati per comodità: così
facendo si perdono due bit di risoluzione ma per usi standard possono bastare).
Di seguito sono riportate quattro funzioni in linguaggio C che possono essere molto utili, la prima, PWMSetup(), si occupa di tutta la fase di inizializzazione, basterà quindi richiamarla una sola volta all'inizio del nostro main.
void PWMSetup(void) {Le altre tre funzioni permettono di variare il duty cycle del primo modulo CCP(PWMDuty1),del secondo modulo CCP (PWMDuty2) e di entrambi(PWMDuty).
void PWMDuty1(unsigned int duty1) {
CCP1Y= 0b00000001&duty1;
CCP1X= 0b00000001&(duty1>>1);
CCPR1L=0b11111111&(duty1>>2);
}
void PWMDuty2(unsigned int duty2) {
CCP2Y= 0b00000001&duty2;
CCP2X= 0b00000001&(duty2>>1);
CCPR2L=0b11111111&(duty2>>2);
}
void PWMDuty(unsigned int duty1,unsigned int duty2){
PWMDuty1(duty1);
PWMDuty2(duty2);
}