- Messaggi: 128
- Ringraziamenti ricevuti 6
Esempio utilizzo modulo pwm a 16bit del pic12f1572 (Come promesso)
7 Anni 11 Mesi fa - 7 Anni 11 Mesi fa #1
da Nutshell
Esempio utilizzo modulo pwm a 16bit del pic12f1572 (Come promesso) è stato creato da Nutshell
Salve a tutti, avevo segnalato un paio di giorni fa la scoperta di questo pic di recente uscita in casa microchip. La caratteristica di questa mcu è la presenza di ben tre moduli pwm con registro a 16bit, che possono essere usati in modo dipendente uno dall'altro o del tutto indipendente. Per il resto il pic in questione è un piccolissimo dispositivo a 8 pin con la stessa pidinatura di tanti altri pic standard che già conosciamo, come per esempio il pic12f1840 che era nel mio progetto prima della scoperta di questo nuovo.
Premetto che stiamo lavorando in ambiente mplabX e che il pic in questione supporta il compilatore XC8.
Veniamo al dunque:
Tralascio la config word, non ha niente di diverso rispetto alle solite config word che usiamo ogni giorno con gli altri pic, e se non avete confidenza con il codice potete autogenerarlo dall'utility di mplabx sotto "Window -> PIC MEMORY VIEWS -> CONFIGURATION BITS".
Ciò che manca per utilizzare il modulo pwm è impostare alcuni registri legati ad esso:
1. Il registro TRISA che suppongo già conosciamo, serve a impostare la funzione dei vari pin della porta A del pic. (per ogni bit associato al pin della porta A avremo: 0 = output, 1 = input). Inutile dire che generando un segnale pwm dovremo impostare il corrispondente pin come uscita. In questo caso noi useremo il modulo PWM 1, associato al pin 2 del pic, individuato dal quinto bit del registro TRISA. Non tenendo conto degli altri bit che non ci interessano in questo momento, avremo TRISA=0bxx0xxxxx;
2. A differenza dei moduli pwm incontrati precedentemente, che facevano uso del timer 2 come sorgente del clock, questo modulo ha una sorgente del tutto dedicata, ed è proprio questa l'innovazione di questo dispositivo. Per ognuno dei tre moduli ci sta un registro PWMxCLKCON (dove al posto della x ci sta il numero del modulo), che serve a scegliere la sorgente del clock ed un eventuale prescaler dedicato. Questo vuol dire che i tre moduli non solo possono avere sorgenti diverse, ma anche prescaler diversi fra loro! Il caso tipico è quello di utilizzare con sorgente di clock proprio FOSC (cioè la frequenza di clock della MCU). Non entrerò nel merito delle altre opzioni in questa sede. Assegnerò per esempio al prescaler il rapporto 1:1, per avere la massima frequenza possibile.
Avremo quindi molto semplicemente PWM1CLKCON=0b0000000;
3. Il registro PWMxPH, a 16 bit, serve ad impostare la fase del segnale pwm. In parole povere serve a generare un offset sulla forma d'onda rispetto al clock assoluto. Questo registro è strettamente legato al duty cycle, ma a meno che non dobbiate fare qualche particolare applicazione, potete cavarvela tenendolo a 0. Quindi PWM1PH=0;
4. Il registro PWMxPR è il period count, ed è quindi legato alla frequenza del nostro segnale pwm. La formula per ricavare il valore da assegnare a questo registro in base alla frequenza desiderata si ricava facilmente dal datasheet, io per i miei test ho trasferito la formula su un foglio elettronico in modo da crearmi uno specchietto di riferimento durante i test. Il registro PWMxPR è a 16 bit ed è formato dalle due componenti H e L a 8 bit, ma grazie al compilatore XC8 non dobbiamo perdere tempo in noiose scomposizioni binarie perchè è sufficiente caricare sul registro il nostro valore direttamente a 16bit. Nel nostro esempio, supponendo di utilizzare l'oscillatore interno del pic impostato a massima frequenza (32MHZ), e volendo generare un segnale pwm a 10kHz calcoleremo un valore del period count di 3199. Quindi avremo PWM1PR=3199;
5. Il registro PWMxDC, anche esso a 16 bit contiene il valore del duty cycle. Come abbiamo detto la fase e il duty cycle sono strettamente legati, in quanto nel caso in cui la fase fosse diversa da zero, si dovrebbe compensare il suo valore sottraendolo al valore del registro del registro PWMxDC, per ottenere il duty cycle desiderato. Ma come abbiamo detto, a meno che non serva specificatamente un valore di fase particolare, esso si tiene a 0 e il valore del registro PWMxDC non è altro che il valore di PWMxPR moltiplicato per il rapporto del duty cycle. Per esempio un duty cycle del 40% ha un rapporto di 0,4 , che moltiplicato per il nostro registro PWM1PR (che era 3199) ci da 1279,6 (1280 arrotondato per eccesso). Quindi avremo: PWM1DC=1280;
6. Infine il registro PWMxCON , a 8 bit, che serve a impostare dei parametri generali come la selezione fra le 4 modalità di funzionamento, l'attivazione del modulo, l'attivazione dell'uscita e la polarità. Trovate la bitmap sul datasheet. Attiveremo e imposteremo il nostro modulo in "standard mode" con PWM1CON=0b11000000;
7. Ci sarebbero alcuni altri registri legati ad ognuno dei tre moduli PWM, come i registri che stabiliscono gli interrupt legati al pwm, ma in questa sede non ci interessiamo ad essi. Ci interessa per ora far funzionare il modulo.
N.B. : Volendo cambiare frequenza o duty cycle "on the run", poichè i tre moduli sono stati ideati per lavorare, volendo, in simbiosi uno con l'altro è stato introdotta l' operazione di RELOAD. In pratica ogni volta che vengono aggiornati i valori di duty cycle, fase, periodo, o offset su uno dei moduli (o tutti), il ricaricamento dei nuovi valori avviene in due fasi. La prima è quella in cui tutte le variabili vengono "armate" e la seconda è quella in cui viene alzato un flag che fa premere il grilletto su tutti i registri simultaneamente in modo da mantenere la sincronizzazione fra i tre moduli. Il comando può avvenire in modo immediato, alla fine del primo periodo dopo aver posto a 1 il bit LDA del registro PWMxLDCON, oppure in modo "triggered" che è dipendente da un altro modulo. Inutile dire che per un modulo indipendente si utilizza il modo immediato, ed è quindi necessario, dopo aver "armato" i registri, porre a 1 il bit LDA perchè la modifica abbia effetto.
Bene, a questo punto, compilando e programmando il pic (è supportato l' ICSP con pickit3) troveremo sul pin 2 del pic un segnale PWM a 10kHz con un duty cycle del 40%, e sapremo come manipolare il nostro modulo per ottenere il nostro risultato.
Buona programmazione a tutti.
Premetto che stiamo lavorando in ambiente mplabX e che il pic in questione supporta il compilatore XC8.
Veniamo al dunque:
Tralascio la config word, non ha niente di diverso rispetto alle solite config word che usiamo ogni giorno con gli altri pic, e se non avete confidenza con il codice potete autogenerarlo dall'utility di mplabx sotto "Window -> PIC MEMORY VIEWS -> CONFIGURATION BITS".
Ciò che manca per utilizzare il modulo pwm è impostare alcuni registri legati ad esso:
1. Il registro TRISA che suppongo già conosciamo, serve a impostare la funzione dei vari pin della porta A del pic. (per ogni bit associato al pin della porta A avremo: 0 = output, 1 = input). Inutile dire che generando un segnale pwm dovremo impostare il corrispondente pin come uscita. In questo caso noi useremo il modulo PWM 1, associato al pin 2 del pic, individuato dal quinto bit del registro TRISA. Non tenendo conto degli altri bit che non ci interessano in questo momento, avremo TRISA=0bxx0xxxxx;
2. A differenza dei moduli pwm incontrati precedentemente, che facevano uso del timer 2 come sorgente del clock, questo modulo ha una sorgente del tutto dedicata, ed è proprio questa l'innovazione di questo dispositivo. Per ognuno dei tre moduli ci sta un registro PWMxCLKCON (dove al posto della x ci sta il numero del modulo), che serve a scegliere la sorgente del clock ed un eventuale prescaler dedicato. Questo vuol dire che i tre moduli non solo possono avere sorgenti diverse, ma anche prescaler diversi fra loro! Il caso tipico è quello di utilizzare con sorgente di clock proprio FOSC (cioè la frequenza di clock della MCU). Non entrerò nel merito delle altre opzioni in questa sede. Assegnerò per esempio al prescaler il rapporto 1:1, per avere la massima frequenza possibile.
Avremo quindi molto semplicemente PWM1CLKCON=0b0000000;
3. Il registro PWMxPH, a 16 bit, serve ad impostare la fase del segnale pwm. In parole povere serve a generare un offset sulla forma d'onda rispetto al clock assoluto. Questo registro è strettamente legato al duty cycle, ma a meno che non dobbiate fare qualche particolare applicazione, potete cavarvela tenendolo a 0. Quindi PWM1PH=0;
4. Il registro PWMxPR è il period count, ed è quindi legato alla frequenza del nostro segnale pwm. La formula per ricavare il valore da assegnare a questo registro in base alla frequenza desiderata si ricava facilmente dal datasheet, io per i miei test ho trasferito la formula su un foglio elettronico in modo da crearmi uno specchietto di riferimento durante i test. Il registro PWMxPR è a 16 bit ed è formato dalle due componenti H e L a 8 bit, ma grazie al compilatore XC8 non dobbiamo perdere tempo in noiose scomposizioni binarie perchè è sufficiente caricare sul registro il nostro valore direttamente a 16bit. Nel nostro esempio, supponendo di utilizzare l'oscillatore interno del pic impostato a massima frequenza (32MHZ), e volendo generare un segnale pwm a 10kHz calcoleremo un valore del period count di 3199. Quindi avremo PWM1PR=3199;
5. Il registro PWMxDC, anche esso a 16 bit contiene il valore del duty cycle. Come abbiamo detto la fase e il duty cycle sono strettamente legati, in quanto nel caso in cui la fase fosse diversa da zero, si dovrebbe compensare il suo valore sottraendolo al valore del registro del registro PWMxDC, per ottenere il duty cycle desiderato. Ma come abbiamo detto, a meno che non serva specificatamente un valore di fase particolare, esso si tiene a 0 e il valore del registro PWMxDC non è altro che il valore di PWMxPR moltiplicato per il rapporto del duty cycle. Per esempio un duty cycle del 40% ha un rapporto di 0,4 , che moltiplicato per il nostro registro PWM1PR (che era 3199) ci da 1279,6 (1280 arrotondato per eccesso). Quindi avremo: PWM1DC=1280;
6. Infine il registro PWMxCON , a 8 bit, che serve a impostare dei parametri generali come la selezione fra le 4 modalità di funzionamento, l'attivazione del modulo, l'attivazione dell'uscita e la polarità. Trovate la bitmap sul datasheet. Attiveremo e imposteremo il nostro modulo in "standard mode" con PWM1CON=0b11000000;
7. Ci sarebbero alcuni altri registri legati ad ognuno dei tre moduli PWM, come i registri che stabiliscono gli interrupt legati al pwm, ma in questa sede non ci interessiamo ad essi. Ci interessa per ora far funzionare il modulo.
N.B. : Volendo cambiare frequenza o duty cycle "on the run", poichè i tre moduli sono stati ideati per lavorare, volendo, in simbiosi uno con l'altro è stato introdotta l' operazione di RELOAD. In pratica ogni volta che vengono aggiornati i valori di duty cycle, fase, periodo, o offset su uno dei moduli (o tutti), il ricaricamento dei nuovi valori avviene in due fasi. La prima è quella in cui tutte le variabili vengono "armate" e la seconda è quella in cui viene alzato un flag che fa premere il grilletto su tutti i registri simultaneamente in modo da mantenere la sincronizzazione fra i tre moduli. Il comando può avvenire in modo immediato, alla fine del primo periodo dopo aver posto a 1 il bit LDA del registro PWMxLDCON, oppure in modo "triggered" che è dipendente da un altro modulo. Inutile dire che per un modulo indipendente si utilizza il modo immediato, ed è quindi necessario, dopo aver "armato" i registri, porre a 1 il bit LDA perchè la modifica abbia effetto.
Bene, a questo punto, compilando e programmando il pic (è supportato l' ICSP con pickit3) troveremo sul pin 2 del pic un segnale PWM a 10kHz con un duty cycle del 40%, e sapremo come manipolare il nostro modulo per ottenere il nostro risultato.
Buona programmazione a tutti.
Ultima Modifica 7 Anni 11 Mesi fa da Nutshell.
Ringraziano per il messaggio: alfa75
Si prega Accedi o Crea un account a partecipare alla conversazione.
- Nutshell
- Autore della discussione
- Premium Member
Riduci
Di più
7 Anni 11 Mesi fa #2
da Mauro Laurenti
Risposta da Mauro Laurenti al topic Esempio utilizzo modulo pwm a 16bit del pic12f1572 (Come promesso)
Grazie della dettagliata spiegazione.
Cercando su google "PIC12f1572 PWM" compare la tua spiegazione, per cui tornerà utile a molti altri...
Saluti,
Mauro
Cercando su google "PIC12f1572 PWM" compare la tua spiegazione, per cui tornerà utile a molti altri...
Saluti,
Mauro
Si prega Accedi o Crea un account a partecipare alla conversazione.
7 Anni 11 Mesi fa #3
da Nutshell
Risposta da Nutshell al topic Esempio utilizzo modulo pwm a 16bit del pic12f1572 (Come promesso)
Di nulla, l'ho scritta in 5 minuti.. e dopo aver imparato le basi sulla programmazione dei microcontroller, anni fa sul tuo libro, era il minimo.
Si prega Accedi o Crea un account a partecipare alla conversazione.
- Nutshell
- Autore della discussione
- Premium Member
Riduci
Di più
- Messaggi: 128
- Ringraziamenti ricevuti 6
6 Anni 9 Mesi fa #4
da Lello Guidi
Risposta da Lello Guidi al topic Esempio utilizzo modulo pwm a 16bit del pic12f1572 (Come promesso)
C'è un errore nel testo "In questo caso noi useremo il modulo PWM 1, associato al pin 2 del pic,".
Anche qui "troveremo sul pin 2 del pic un segnale PWM a 10kHz con un duty cycle del 40%".
Il PWM1 è associato al pin6/RA1.
Sto provando a creare un eseguibile aiutandomi con lo scritto di sopra ma non mi funziona.
Saluti
Lello
Anche qui "troveremo sul pin 2 del pic un segnale PWM a 10kHz con un duty cycle del 40%".
Il PWM1 è associato al pin6/RA1.
Sto provando a creare un eseguibile aiutandomi con lo scritto di sopra ma non mi funziona.
Saluti
Lello
Si prega Accedi o Crea un account a partecipare alla conversazione.
6 Anni 8 Mesi fa #5
da Nutshell
Risposta da Nutshell al topic Esempio utilizzo modulo pwm a 16bit del pic12f1572 (Come promesso)
Ciao grazie per la segnalazione, ma in realtà ció che ho scritto è corretto. Se vai a pagina 3 del datasheet trovi la descrizione dei pin con le varie funzionalità associate, tra cui troverai sul pin2 anche il PWM1 (pin alternativo) da abilitare tramite il registro apfcon come ho mostrato nell'allegato sotto.
Ringraziano per il messaggio: Lello Guidi
Si prega Accedi o Crea un account a partecipare alla conversazione.
- Nutshell
- Autore della discussione
- Premium Member
Riduci
Di più
- Messaggi: 128
- Ringraziamenti ricevuti 6
Moderatori: Mauro Laurenti, Pinna, StefA, Matteo Garia
Registrati al sito
Accedi a tutte le risorse e articoli non visibili pubblicamente, puoi registrarti con pochi passi.