ROBOTICA\PWM Tutorial


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) {
CCP1CON=0; //resetto il modulo CCP1
CCP2CON=0; //resetto il modulo CCP2
PR2=0xFF; //inserire qui il valore di PR2 desiderato
PWMDuty1(512); //DC 50% con LAP
PWMDuty2(512); //DC 50% con LAP
TRISC2=0; //setto come out il pin
TRISC1=0;
T2CON=0b00000100; //senza prescaler e post scaler e attivo Timer2
CCP1M3=1; CCP1M2=1; CCP1M1=0; CCP1M0=0; //modalit... PWM
CCP2M3=1; CCP2M2=1; CCP2M1=0; CCP2M0=0; //modalit... PWM
}

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);
}

Indice