- PWM (Pulse Width Modulation)
- Pin PWM in ARM7-LPC2148
- Registri PWM in ARM7-LPC2148
- Componenti richiesti
- Schema elettrico e collegamenti
- Programmazione ARM7-LPC2148 per PWM
- Passaggi coinvolti nella programmazione di LPC2148 per PWM e ADC
Come sappiamo, i microcontrollori prendono l'input analogico dai sensori analogici e utilizzano ADC (convertitore da analogico a digitale) per elaborare quei segnali. Ma cosa succede se un microcontrollore desidera produrre un segnale analogico per controllare dispositivi ad azionamento analogico come un servomotore, un motore CC, ecc.? I microcontrollori non producono una tensione di uscita come 1 V, 5 V invece utilizzano una tecnica chiamata PWM per il funzionamento di dispositivi analogici. Un esempio di PWM è la ventola di raffreddamento del nostro laptop (motore CC) che deve essere controllata dalla velocità in base alla temperatura e la stessa è implementata utilizzando la tecnica PWM (Pulse Width Modulation) nelle schede madri.
In questo tutorial controlleremo la luminosità di un LED utilizzando il PWM nel microcontrollore ARM7-LPC2148.
PWM (Pulse Width Modulation)
PWM è un buon modo per controllare i dispositivi analogici utilizzando valori digitali come il controllo della velocità del motore, la luminosità di un led, ecc. Sebbene PWM non fornisca un'uscita analogica pura, ma genera impulsi analogici decenti per controllare i dispositivi analogici. PWM modula effettivamente la larghezza di un'onda di impulso rettangolare per ottenere una variazione del valore medio dell'onda risultante.
Ciclo di lavoro del PWM
La percentuale di tempo in cui il segnale PWM rimane ALTO (tempo di attivazione) viene chiamata duty cycle. Se il segnale è sempre ON è nel duty cycle del 100% e se è sempre spento è nel duty cycle dello 0%.
Ciclo di lavoro = Tempo di accensione / (Tempo di accensione + Tempo di spegnimento)
Pin PWM in ARM7-LPC2148
L'immagine sotto indica i pin di uscita PWM di ARM7-LPC2148. Ci sono sei pin in totale per PWM.
Canale PWM |
Pin porta LPC2148 |
PWM1 |
P0.0 |
PWM2 |
P0.7 |
PWM3 |
P0.1 |
PWM4 |
P0.8 |
PWM5 |
P0.21 |
PWM6 |
P0.9 |
Registri PWM in ARM7-LPC2148
Prima di entrare nel nostro progetto, dobbiamo conoscere i registri PWM in LPC2148.
Di seguito è riportato l'elenco dei registri utilizzati in LPC2148 per PWM
1. PWMPR: PWM Prescale Register
Uso: è un registro a 32 bit. Contiene il numero di volte (meno 1) che PCLK deve eseguire un ciclo prima di incrementare il contatore del timer PWM (in realtà contiene il valore massimo del contatore di prescala).
2. PWMPC: contatore prescaler PWM
Uso: è un registro a 32 bit . Contiene il valore del contatore incrementale. Quando questo valore è uguale al valore PR più 1, il PWM Timer Counter (TC) viene incrementato.
3. PWMTCR: PWM Timer Control Register
Utilizzo: contiene i bit di controllo Counter Enable, Counter Reset e PWM Enable. È un registro a 8 bit.
7: 4 |
3 |
2 |
1 |
0 |
RISERVATO |
ABILITA PWM |
RISERVATO |
COUNTER RESET |
COUNTER ENABLE |
- Abilita PWM: (Bit-3)
0- PWM disabilitato
1- PWM abilitato
- Abilita contatore: (Bit-0)
0- Disabilita contatori
1- Abilita contatore
- Reset contatore: (Bit-1)
0- Non fare nulla.
1- Ripristina PWMTC e PWMPC sul fronte positivo di PCLK.
4. PWMTC: contatore timer PWM
Uso: è un registro a 32 bit. Contiene il valore corrente del timer PWM incrementale. Quando il contatore del prescaler (PC) raggiunge il valore del registro del prescaler (PR) più 1, questo contatore viene incrementato.
5. PWMIR: registro interrupt PWM
Usa: è un registro a 16 bit. Contiene i flag di interrupt per i canali di corrispondenza PWM 0-6. Un flag di interrupt viene impostato quando si verifica un interrupt per quel canale (MRx Interrupt) dove X è il numero di canale (da 0 a 6).
6. PWMMR0-PWMMR6: registro delle partite PWM
Uso: è un registro a 32 bit . In realtà il gruppo Match Channel permette di impostare 6 uscite PWM controllate da un solo fronte o 3 uscite PWM controllate da due fronti. È possibile modificare i sette canali di corrispondenza per configurare queste uscite PWM in base alle proprie esigenze in PWMPCR.
7. PWMMCR: PWM Match Control Register
Uso: è un registro a 32 bit. Contiene i bit Interrupt, Reset e Stop che controllano il Match Channel selezionato. Si verifica una corrispondenza tra i registri di corrispondenza PWM e i contatori del timer PWM.
31:21 |
20 |
19 |
18 |
.. |
5 |
4 |
3 |
2 |
1 |
0 |
RISERVATO |
PWMMR6S |
PWMMR6R |
PWMMR6I |
.. |
PWMMR1S |
PWMMR1R |
PWMMR11 |
PWMMR0S |
PWMMR0R |
PWMMR01 |
Qui x è compreso tra 0 e 6
- PWMMRxI (Bit-0)
ABILITA O DISABILITA gli interrupt PWM
0- Disabilita gli interrupt PWM Match.
1- Abilita interrupt PWM Match.
- PWMMRxR: (Bit-1)
RESET PWMTC - Valore del contatore del timer ogni volta che corrisponde a PWMRx
0- Non fare nulla.
1- Ripristina il PWMTC.
- PWMMRxS: (Bit 2)
STOP PWMTC e PWMPC quando PWMTC raggiunge il valore del registro Match
0- Disabilita la funzione di arresto PWM.
1- Abilita la funzione PWM Stop.
8. PWMPCR: registro di controllo PWM
Uso: è un registro a 16 bit. Contiene i bit che abilitano le uscite PWM 0-6 e selezionano il controllo a fronte singolo o doppio fronte per ogni uscita.
31:15 |
14: 9 |
8: 7 |
6: 2 |
1: 0 |
NON UTILIZZATO |
PWMENA6-PWMENA1 |
NON UTILIZZATO |
PWMSEL6-PWMSEL2 |
NON UTILIZZATO |
- PWMSELx (x: da 2 a 6)
- Modalità Single Edge per PWMx
- 1- Modalità Double Edge per PWMx.
- PWMENAx (x: da 1 a 6)
- PWMx Disabilita.
- 1- PWMx abilitato.
9. PWMLER: PWM Latch Enable Register
Usa: è un registro a 8 bit. Contiene i bit Match x Latch per ogni Match Channel.
31: 7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
NON UTILIZZATO |
LEN6 |
LEN5 |
LEN4 |
LEN3 |
LEN2 |
LEN1 |
LEN0 |
LENx (x: da 0 a 6):
0- Disabilita il caricamento di nuovi valori di corrispondenza
1- Carica i nuovi valori di corrispondenza dal registro PWMMatch (PWMMRx) quando il timer viene azzerato.
Ora iniziamo a costruire la configurazione hardware per dimostrare la modulazione di larghezza di impulso nel microcontrollore ARM.
Componenti richiesti
Hardware
- Microcontrollore ARM7-LPC2148
- 3.3V regolatore di tensione IC
- Potenziometro 10k
- LED (qualsiasi colore)
- Modulo display LCD (16x2)
- Breadboard
- Collegamento dei cavi
Software
- Keil uVision5
- Strumento Flash Magic
Schema elettrico e collegamenti
Collegamenti tra LCD e ARM7-LPC2148
ARM7-LPC2148 |
LCD (16x2) |
P0.4 |
RS (selezione registro) |
P0.6 |
E (Abilita) |
P0.12 |
D4 (Data pin 4) |
P0.13 |
D5 (Data pin 5) |
P0.14 |
D6 (Data pin 6) |
P0.15 |
D7 (Data pin 7) |
GND |
VSS, R / W, K |
+ 5V |
VDD, A |
Collegamento tra LED e ARM7-LPC2148
L'ANODO del LED è collegato all'uscita PWM (P0.0) di LPC2148, mentre il pin CATHODE del LED è collegato al pin GND di LPC2148.
Collegamento tra ARM7-LPC2148 e potenziometro con regolatore di tensione 3.3V
3.3V regolatore di tensione IC |
Funzione pin |
Perno ARM-7 LPC2148 |
1. Perno sinistro |
- Ve di GND |
Pin GND |
2.Pin centrale |
Uscita + 3,3 V regolata |
All'ingresso del potenziometro e all'uscita del potenziometro su P0.28 di LPC2148 |
3.Pin destro |
+ Ve da 5V INGRESSO |
+ 5V |
Punti da notare
1. Un regolatore di tensione di 3,3 V viene utilizzato qui per fornire il valore di ingresso analogico al pin ADC (P0.28) di LPC2148 e poiché stiamo utilizzando una potenza di 5 V, dobbiamo regolare la tensione con un regolatore di tensione di 3,3 V.
2. Viene utilizzato un potenziometro per variare la tensione tra (0 V e 3,3 V) per fornire l'ingresso analogico (ADC) al pin P0.28 di LPC2148
Programmazione ARM7-LPC2148 per PWM
Per programmare ARM7-LPC2148 abbiamo bisogno dello strumento keil uVision e Flash Magic. Stiamo utilizzando il cavo USB per programmare ARM7 Stick tramite la porta micro USB. Scriviamo il codice usando Keil e creiamo un file esadecimale, quindi il file HEX viene aggiornato su ARM7 stick usando Flash Magic. Per saperne di più sull'installazione di keil uVision e Flash Magic e su come usarli, segui il link Primi passi con il microcontrollore ARM7 LPC2148 e programmalo usando Keil uVision.
In questo tutorial useremo la tecnica ADC e PWM per controllare la luminosità del LED. Qui LPC2148 riceve un ingresso analogico (da 0 a 3,3 V) tramite il pin di ingresso ADC P0.28, quindi questo ingresso analogico viene convertito in valore digitale (da 0 a 1023). Quindi questo valore viene nuovamente convertito in valore digitale (0 - 255) poiché l'uscita PWM di LPC2148 ha solo una risoluzione di 8 bit (2 8). Il LED è collegato al pin PWM P0.0 e la luminosità del LED può essere controllata utilizzando il potenziometro. Per saperne di più su ADC in ARM7-LPC2148 segui il link.
Passaggi coinvolti nella programmazione di LPC2148 per PWM e ADC
Passaggio 1: - La prima cosa da fare è configurare il PLL per la generazione del clock poiché imposta l'orologio di sistema e l'orologio della periferica di LPC2148 secondo le necessità dei programmatori. La frequenza di clock massima per LPC2148 è 60 Mhz. Le seguenti righe vengono utilizzate per configurare la generazione del clock PLL.
void initilizePLL (void) // Funzione per utilizzare PLL per la generazione di clock { PLL0CON = 0x01; PLL0CFG = 0x24; PLL0FEED = 0xAA; PLL0FEED = 0x55; while (! (PLL0STAT & 0x00000400)); PLL0CON = 0x03; PLL0FEED = 0xAA; PLL0FEED = 0x55; VPBDIV = 0x01; }
Passaggio 2: - La prossima cosa è selezionare i pin PWM e la funzione PWM di LPC2148 utilizzando il registro PINSEL. Usiamo PINSEL0 poiché usiamo P0.0 per l'uscita PWM di LPC2148.
PINSEL0 = 0x00000002; // Impostazione del pin P0.0 per l'uscita PWM
Passaggio 3: - Successivamente è necessario RESETTARE i timer utilizzando PWMTCR (Registro di controllo del timer).
PWMTCR = (1 << 1); // Impostazione del registro di controllo del timer PWM come azzeramento del contatore
Quindi, impostare il valore di prescala che decide la risoluzione del PWM. Lo sto impostando a zero
PWMPR = 0X00; // Impostazione del valore di prescala PWM
Passaggio 4: - Successivamente è necessario impostare il PWMMCR (registro di controllo della corrispondenza PWM) poiché imposta operazioni come ripristino, interruzioni per PWMMR0.
PWMMCR = (1 << 0) - (1 << 1); // Impostazione del registro di controllo corrispondenza PWM
Passaggio 5: - Il periodo massimo del canale PWM viene impostato utilizzando PWMMR.
PWMMR0 = PWMvalue; // Dare valore PWM Valore massimo
Nel nostro caso il valore massimo è 255 (per la massima luminosità)
Passaggio 6: - Successivamente dobbiamo impostare Latch Enable sui corrispondenti registri di corrispondenza utilizzando PWMLER
PWMLER = (1 << 0); // Enalbe PWM latch
(Usiamo PWMMR0) Quindi abilita il bit corrispondente impostando 1 in PWMLER
Passaggio 7: - Per abilitare l'uscita PWM al pin, è necessario utilizzare PWMTCR per abilitare i contatori del timer PWM e le modalità PWM.
PWMTCR = (1 << 0) - (1 << 3); // Abilitazione PWM e contatore PWM
Step 8: - Ora dobbiamo ottenere i valori del potenziometro per l'impostazione del duty cycle del PWM dal pin ADC P0.28. Quindi utilizziamo il modulo ADC in LPC2148 per convertire l'ingresso analogico dei potenziometri (da 0 a 3,3 V) nei valori ADC (da 0 a 1023).
Qui stiamo convertendo i valori da 0-1023 a 0-255 dividendoli per 4 poiché PWM di LPC2148 ha una risoluzione a 8 bit (2 8).
Passaggio 9: - Per selezionare il pin ADC P0.28 in LPC2148, usiamo
PINSEL1 = 0x01000000; // Impostando P0.28 come ADC INPUT AD0CR = (((14) << 8) - (1 << 21)); // Impostazione dell'orologio e del PDN per la conversione A / D
Le seguenti righe catturano l'ingresso analogico (da 0 a 3,3 V) e lo convertono in valore digitale (da 0 a 1023). E poi questi valori digitali vengono divisi per 4 per convertirli in (da 0 a 255) e infine alimentati come uscita PWM nel pin P0.0 di LPC2148 su cui è collegato il LED.
AD0CR - = (1 << 1); // Seleziona il canale AD0.1 nel ritardo del registro ADC (10); AD0CR - = (1 << 24); // Avvia la conversione A / D while ((AD0DR1 & (1 << 31)) == 0); // Controlla il bit DONE nel registro dati ADC adcvalue = (AD0DR1 >> 6) & 0x3ff; // Ottieni il RISULTATO dal registro dati ADC dutycycle = adcvalue / 4; // formula per ottenere i valori del duty cycle da (0 a 255) PWMMR1 = dutycycle; // imposta il valore del ciclo di esecuzione al registro di corrispondenza PWM PWMLER - = (1 << 1); // Abilita l'uscita PWM con il valore del ciclo di carico
Passaggio 10: - Successivamente visualizziamo questi valori nel modulo Display LCD (16X2). Quindi aggiungiamo le seguenti righe per inizializzare il modulo display LCD
Void LCD_INITILIZE (void) // Funzione per preparare l'LCD { IO0DIR = 0x0000FFF0; // Imposta il pin P0.12, P0.13, P0.14, P0.15, P0.4, P0.6 come tempo di ritardo OUTPUT (20); LCD_SEND (0x02); // Inizializza lcd in modalità operativa a 4 bit LCD_SEND (0x28); // 2 righe (16X2) LCD_SEND (0x0C); // Visualizza sul cursore spento LCD_SEND (0x06); // Incremento automatico del cursore LCD_SEND (0x01); // Visualizza LCD_SEND chiaro (0x80); // Prima riga prima posizione }
Poiché abbiamo collegato LCD in modalità 4 bit con LPC2148, dobbiamo inviare i valori da visualizzare come nibble per nibble (Upper Nibble & Lower Nibble). Quindi vengono utilizzate le seguenti righe.
void LCD_DISPLAY (char * msg) // Funzione per stampare i caratteri inviati uno per uno { uint8_t i = 0; while (msg! = 0) { IO0PIN = ((IO0PIN & 0xFFFF00FF) - ((msg & 0xF0) << 8)); // Invia il nibble superiore IO0SET = 0x00000050; // RS HIGH & ENABLE HIGH per stampare i dati IO0CLR = 0x00000020; // RW LOW Modalità di scrittura delaytime (2); IO0CLR = 0x00000040; // EN = 0, RS e RW invariati (cioè RS = 1, RW = 0) tempo di ritardo (5); IO0PIN = ((IO0PIN & 0xFFFF00FF) - ((msg & 0x0F) << 12)); // Invia il nibble inferiore IO0SET = 0x00000050; // RS & EN HIGH IO0CLR = 0x00000020; tempo di ritardo (2); IO0CLR = 0x00000040; tempo di ritardo (5); i ++; } }
Per visualizzare quei valori ADC e PWM usiamo le seguenti righe nella funzione int main () .
LCD_SEND (0x80); sprintf (displayadc, "adcvalue =% f", adcvalue); LCD_DISPLAY (displayadc); // Visualizza il valore ADC (da 0 a 1023) LCD_SEND (0xC0); sprintf (ledoutput, "PWM OP =%. 2f", luminosità); LCD_DISPLAY (ledoutput); // Visualizza i valori del ciclo di carico da (0 a 255)
Di seguito sono riportati il codice completo e la descrizione video del tutorial.