GENERATORE PWM CON FREQUENZA E DUTY CYCLE VARIABILI CON PIC16F873A
La PIC16F873A possiede al suo interno l’hardware necessario per generare un segnale PWM, prima di immergerci nei meandri dei registri, dei bit, dei byte del controllore conviene fare mente locale su cosa è un segnale PWM.
A tale scopo analizziamo la fig.1.
Fig.1
In essa è rappresentato un segnale di periodo T = 50mS che rimane alto (nell’esempio ad 1V) per un tempo td = 10mS. Bene, il rapporto tra i due tempi rappresenta il duty-cycle come segue:
[1]
Moltiplicando la suddetta formula per 100 si ottiene il valore del duty-cycle in percentuale:
[2]
Adesso possiamo iniziare ad analizzare l’aspetto interiore della PIC, a tal scopo facciamo riferimento a fig.2
Fig.2
Per evitare che ci venga il mal di testa per cercare di capire tutto insieme andremo per passi cominciando a descrivere l’hardware che gestisce il periodo o reciprocamente la frequenza del segnale PWM che vogliamo venga generato dal PIC.
I registri usati per tale scopo sono i seguenti:
1. Registro ad 8 bit TMR2
2. Registro ad 8 bit PR2
Il registro TMR2 è raffigurato in fig.3.
Fig.3
Esso viene incrementato dal clock presente all’uscita di un prescaler programmabile, quest’ultimo è un semplice divisore e permette di incrementare il registro TMR2 con la frequenza (dove è la frequenza di sistema generata tipicamente da un quarzo) quando il Prescaler è programmato come divisore 1:1 o con altre due frequenze minori quando il Prescaler è programmato come 1:4 o 1:16.
Supponiamo di avere programmato il Prescaler come divisore 1:1, in fig.4 sono rappresentate le forma d’onda dei clock e l’incremento del registro TMR2.
Fig.4
Si nota che ogni 4 periodi del clock di sistema (), corrispondenti quindi ad un periodo della frequenza , il registro viene incrementato di 1.
PR2 è registro ad 8 bit che può essere letto o scritto ed è quello che decide il periodo, e quindi la frequenza, del segnale che si vuole fare generare dalla PIC .
Torniamo ora ad analizzare la fig.2, tra il registro TMR2 ed il PR2 c’è un comparatore; ogni qual volta il valore del registro TMR2 raggiunge quello memorizzato nel registro PR2 accadono i seguenti eventi (per il momento scrivo solo di quelli relativi al periodo del segnale generato, per il duty-cycle ne aggiungerò altri):
1. Il flip-flop viene settato e di conseguenza il pin della porta C (quello da dove esce il segnale) va alto.
2. Il registro TMR2 viene resettato
(Come vedremo in seguito il tempo durante il quale il livello del segnale rimarrà alto sarà determinato dal resto del circuito riguardante il duty-cycle).
Questo evento appena descritto è ben raffigurato in fig.5.
Fig.5
Ogni qualvolta il valore di TMR2 incontra quello di PR2 il segnale in uscita va alto, il registro TMR2 viene azzerato e ricomincia a contare ogni 4 periodi di clock di sistema (o ogni periodo di , è facile comprendere come sia possibile risalire al periodo T del segnale PWM semplicemente sommando tutti i periodi di clock contenuti in esso. Da questo si evince che:
[3]
Ovvero il tempo (sec) del periodo del segnale PWM è uguale al valore del registro PR2 + 1 (decimale) che dovrà essere raggiunto da TMR2 moltiplicato il clock (Hz) di sistema per quattro (dato che occorrono 4 periodi del clock per effettuare un incremento) moltiplicato per il valore del Prescaler () (decimale) che aumenta ulteriormente il periodo di incremento se settato a valori diversi da 1:1.
Il motivo per il quale occorre aggiungere un 1 al valore del registro PR2 è dovuto al fatto che quando il registro TMR2 incontra PR2 non si azzera istantaneamente ma deve attendere 1 periodo di come si vede in fig.6.
Fig.6
Per ricavare il valore del registro PR2 basta usare la seguente formula inversa:
[4]
Ricordo che:
[5]
Dove è la frequenza del segnale PWM
Per determinare il valore da immettere nel registro PR2 affinché il PIC generi un segnale di frequenza occorre predisporre il Prescaler; ricordando che il registro PR2 non può superare il valore 255 (è a 8 bit) si può andare per tentativi partendo da 1:1 e andando oltre nel caso lo si superi, oppure utilizzare uno dei tanti calcolatori di PWM on line, uno di questi, ad esempio, è al seguente indirizzo:
http://www.micro-examples.com/public/microex-navig/doc/097-pwm-calculator.html
Riprendiamo in considerazione la fig.2. In essa si notano altri due registri (CCPR1L ed CCPR1H) a 8 bit che vengono portati a 10 bit tramite due bit (bit 4 e bit 5) del registro CCP1CON che saranno i meno significativi del registro CCPR1L (b0 e b1), e un altro comparatore. Il registro CCPR1L più i due bit 4 e 5 di CCP1CON definiscono il duty-cycle come vedremo.
Ora occorre aggiungere degli eventi corrispondenti al momento in cui il registro TMR2 incontra PR2. Oltre a mandare alto il pin di uscita del PWM e resettare il registro TMR2 accade anche:
1. Viene trasferito il contenuto del registro CCPR1L in CCPR1H (questa azione evita che nel momento in cui scriviamo nel registro CCPR1L per decidere il duty-cycle si verifichino errori dovuti alla comparazione tra TMR2 ed il registro CCPR1L dove stiamo scrivendo i dati che magari non si sono ancora assestati).
Quando il valore del registro TMR2 incontra quello in CCPR1H il flip-flop viene resettato e conseguentemente il pin di uscita va a zero. Questo è rappresentato in fig.7.
Fig.7
Per far si che il registro TMR2 ad 8 bit ne incontri uno a 10 (CCPR1H) in questa fase gli vengono aggiunti due bit (b0 e b1) che essendo posizionati prima dei meno significativi del registro TMR2 (ora b2 e b3) per poter essere incrementati singolarmente hanno bisogno di una frequenza via via superiore a spostandosi da b3 a b0, la fig.8 è esplicativa.
Fig.8
Ovvero mentre b3 di TMR2 incrementa ogni quattro clock di sistema , b1 incrementa ogni due clock e b0 incrementa ogni clock ,
Per ottenere il tempo durante il quale il livello è alto basta applicare la seguente formula:
[6]
Ovvero il tempo (sec) durante il quale il segnale rimane alto è uguale al valore (decimale) contenuto nell’insieme dei registri CCPR1L e CCP1CON (8 bit nel primo 2 bit nel secondo) moltiplicato per il periodo di clock del sistema moltiplicato ancora per il valore del Prescaler.
Ricordo che:
Duty-Cycle = [7]
In ultima analisi trattiamo della risoluzione del duty-cycle. Per fare questo analizziamo la fig. 9.
Per esemplificare la spiegazione supponiamo che in un periodo del segnale PWM ( ci siano 8 clock di sistema ognuno di periodo , e che il segnale stesso abbia un duty-cycle del 50%. Allora l’incremento o il decremento di tale duty-cycle potrà avvenire solo per step di un periodo di clock, ad esempio senza fare riferimento ai tempi ma al numero dei clock in figura abbiamo:
Duty-Cycle = [8]
Ovvero come detto un duty-cycle del 50%.
Ora se vogliamo aumentarlo lo possiamo fare solo a step di un clock quindi:
Duty-Cycle = [9]
Ovvero un duty-cycle del 62,5%, non si potranno avere valori intermedi tra 0.5 e 0.625, questa è la risoluzione cioè il numero di step a disposizione per variare il duty-cycle.
Dato che il valore che determina il duty-cycle è binario (registro CCPR1:CPR1CON) per poter determinare quante combinazioni (quanti bit abbiamo a disposizione) dobbiamo semplicemente conoscere l’esponente di 2.
Ovvero facendo rapporto dei tempi o reciprocamente delle frequenze sappiamo quanti cicli di clock di sistema entrano in un periodo del segnale PWM:
[10]
Quindi per sapere qual è la risoluzione in bit:
[11]
Per le regole dei logaritmi:
[12]
Quindi più è alta la frequenza del PWM rispetto a quella del sistema minore sarà la risoluzione.
PROGRAMMA
Il programma che ho creato semplicemente genera un segnale PWM a frequenza e duty-cycle variabile. Ci sono non tre tasti:
Un tasto, collegato sulla porta A pin 0 che serve per decrementare la frequenza o il duty-cycle (suo led interno su porta A pin 5).
Un tasto, collegato sulla porta A pin 1 che serve per incrementare la frequenza o il duty-cycle (suo led interno su porta C pin 0).
Un tasto, collegato sulla porta A pin 2 che serve per scegliere che cosa far decrementare o incrementare agli altri due tasti (suo led interno su porta A pin 3).
Quest’ultimo tasto è stabile, se si preme una volta si illumina il suo led e predispone gli altri due tasti per agire sul duty-cycle. Se si preme di nuovo il suo led si spegne e predispone gli altri due tasti per agire sulla frequenza riportando il duty-cycle al 50%.
Notare che quando si varia la frequenza il duty-cycle rimane sempre al 50%.
Fabio