Salta la barra di navigazione [1] - Vai alla barra di navigazione [3] - Scrivimi una mail [4]

I moduli Timer2 e PWM

PIC18 in C - Sommario - Novità - Tutorial - Progetti - Risorse - Non solo elettronica

PWM

Timer 2 possiede due particolarità:

I segnali modulati a larghezza di impulsi (PWM, Pulse Width Modulation) permettono ad un sistema digitale di pilotare dispositivi analogici in corrente continua potendo variare con continuità la potenza erogata. Per una breve introduzione: Pulse Width Modulation.

La configurazione di Timer2

Timer2 ha le seguenti caratteristiche:

Diagramma a blocchi di Timer2

A fondo pagina un esempio che fa lampeggiare un LED, codice concettualmente analogo ad altri già visti (dove è però utilizzato un comparatore "esterno")

L'aspetto più utile da vedere è il calcolo della frequenza: nell'esempio si parte da un clock di 250 kHz. Questo viene diviso per 16 dal prescaler, quindi per 196 (conteggio da 0 a 195), infine ancora per 16 dal postscaler; complessivamente la frequenza con cui sono generate interruzioni è quindi circa 5 Hz, da cui la frequenza di lampeggio del LED di 2,5 Hz.

Il modulo PWM

La struttura del modulo appare piuttosto complessa, soprattutto per la scelta un poco barocca scelta dai progettisti per avere una risoluzione di 10 bit.

Il modulo PWM

Tre sono le impostazioni principali:

L'idea di base è la seguente (nel caso di una singola uscita):

  1. L'uscita viene alzata quando Timer2 è resettato
  2. L'uscita viene abbassata quando il conteggio di Timer 2 raggiunge un certo valore, impostato tramite il registro CCPR1x
  3. Quando Timer 2 viene resettato, il ciclo ricomincia

Il codice lo trovate a fondo pagina.

Da notare che Timer2, pur essendo dal punto di vista dell'utente un contatore a 8 bit, in realtà possiede altri flip flop al proprio ingresso, presenti nel prescaler o nel generatore della frequenza pari ad un quarto di quella del clock di sistema. Due di questi bit saranno usati, in posizione meno significativa, per una sorta di aumento della risoluzione, fino a 10 bit, ma solo in modalità PWM.

Impostazione della frequenza

Questa operazione in genere va fatta una sola volta, all'inizio. La scelta dipende dal contesto e può andare da frazioni di Hz (sistemi termici), a un centinaio di Hz (sistemi di illuminazione), a 20 o più kHz (pilotaggio di motori, per evitare l'emissione di fischi piuttosto fastidiosi).

E' sempre opportuno che il valore da caricare in Timer2 sia il più possibile vicino a 255, al fine di sfruttare al massimo la risoluzione del modulo.

Decidiamo di voler generare un segnale PWM con una frequenza di 20 kHz, adatta per pilotare motori. Questo ci obbliga a scegliere un clock per il processore più elevato di quello usato in molti degli esempi visti finora e a non usare il prescaler:

OSCCONbits.IRCF = 7; // Set internal clock to 16 MHz
T2CONbits.T2OUTPS = 0; // Timer2 1:1 Postscaler
T2CONbits.T2CKPS = 0; // Timer2 1:1 Prescaler

Dobbiamo calcolato il modulo di Timer2: 16 MHz / 4  / 1 / 1 / 20 kHz = 200, accettabile perché minore  (ma non troppo) di 255. Occorre osservare che un contatore modulo 200 conta da 0 a 199, numero quest'ultimo da utilizzare per il registro PR2.

PR2 = PWM_T; // Timer2 Period Register

Impostazioni delle uscite

Il codice di esempio utilizza una sola uscita. Per decidere a quale (o quali) dei pin fisici deve essere inviato il segnale PWM occorre utilizzare il pulse steering:

PSTRCONbits.STRSYNC = 1; // Output steering update occurs on next PWM period
PSTRCONbits.STRA = 0; // P1A pin is assigned to port pin
PSTRCONbits.STRB = 0; // P1B pin is assigned to port pin
PSTRCONbits.STRC = 0; // P1C pin is assigned to port pin
PSTRCONbits.STRD = 1; // P1D pin has the PWM waveform with polarity control from CCP1M<1:0>

Nell'esempio è utilizzato P1D (pin 14 - RC2/AN6/P1D/C12IN2-/CVREF/INT2) che deve essere manualmente configurato come uscita. Nulla impedisce di avere lo stesso segnale PWM su più pin contemporaneamente.

Impostazione del TON

Il numero di impulsi che determina il TON è memorizzato nel registro CCPR1L (8 bit) e nel registro  CCP1CON (2 bit). Tale valore deve essere modificato quando si intende modificare il Duty Cycle.

Tale valore deve essere compreso tra 0 e quanto caricato in Timer2: il TON deve infatti essere sempre minore di T! Occorre però osservare che, a causa del diverso allineamento dei bit, tale valore appare come essere 4 volte più grande di quello che è in realtà: deve essere diviso per quattro (shiftato di due posizioni verso destra) e quindi salvato in due diversi registri. In pratica:

CCPR1L = PWM_DC >> 2; // Set PWM Duty cycle -8 MSB bits- <= Timer2 content
CCP1CONbits.DC1B = PWM_DC & 0x03; // Set PWM Duty cycle - 2 LSB bits

Infine avviamo Timer2 e di conseguenza in generatore PWM:
T2CONbits.TMR2ON = 1; // Timer2 on

La configurazione è terminata e non è più richiesto l'intervento del software, se non, evidentemente, per modificare il TON (oppure, al limite, il periodo) del segnale generato.

Codice

Esercizi

  1. Scrivere il codice per configurare il modulo PWM usando le PLIB
  2. Scrivere il codice che fa passare il DC% da 0% a 100% con continuità, con un intervallo di una decina di millisecondi tra un valore e l'altro. Collegare un LED all'uscita

Approfondimento


PIC18 in C

Appendici:

Qualche utile informazione integrativa: C per sistemi embedded

Licenza Creative Commons Attribuzione 4.0 Internazionale


EN - Pagina principale - Sommario - Accessibilità - Note legali e privacy policy - Posta elettronica

XHTML 1.0 Strict - CSS 3