PIC18F47J53 COME FARE UN PWM FACILE E

Documenti analoghi
PIERIN PIC18 IL PROGRAMMA DEMO:

LE INTERRUPT. UTILIZZO PRATICO CON IL PIERIN PIC18 1

Vogliamo far lampeggiare i led collegati come in figura ai bit della porta D del PIC 18F8722 presente sulla demo board in dotazione al laboratorio.

PIC18F47J53 UN MODULO IN C PER

GENERATORE DI BASE TEMPI

GESTIONE DELLE INTERRUZIONI (INTERRUPT)

CONTATORE/TIMER PROGRAMMABILE CTC Z80 1. Piedinatura 2. Struttura interna 4. Modo timer 5. Modo Counter 8. Programmazione del CTC 13

TIMER H-M-S CON PIC [2] - IL PROGRAMMA 1

TUTORIAL GPL_BENZINA CON PIC16F1826 (UTILIZZO DELL ADC)

PIC18F47J53 NOZIONI DI BASE SULLA

del Linguaggio C Istruzioni di iterazione

Ing. Emiliano Capuzzo Remote Contro NEC 11/11/2003. Remote Control NEC

Corso di programmazione Arduino DI MALVEZZI DAVIDE

Arduino/Raspberry Board and GSM Library

Calcolatori Elettronici T Ingegneria Informatica A3 - Gestione delle interruzioni

La comunicazione con l esterno

Primo programma in C

Guida alla Settima Esercitazione

DISPOSITIVO PER LA LETTURA DI UN ENCODER INCREMENTALE

TERMOMETRO DIGITALE CON PIC18 PIERIN E NTC SENZA UTILIZZARE ADC 1

PIC E DISPLAY A 7 SEGMENTI CON

Laboratorio di Algoritmi e Strutture Dati

CONTROLLARE UN SERVOCOMANDO A DISTANZA. 1

PIERIN PIC18 - MISURARE LA TEMPERATURA CON

Arduino: Programmazione

Qualsiasi programma in C++ segue lo schema:

Prof. Pagani Corrado LINGUAGGIO C: SELEZIONE E CICLI

Lezione 5 e 6. Fabio Scotti ( ) Laboratorio di programmazione per la sicurezza. Valentina Ciriani ( ) Laboratorio di programmazione

Esercitazione 4. Comandi iterativi for, while, do-while

Fondamenti di Informatica A. A. 2018/19

Elap CM78N C-01 ISTRUZIONI PER LA CONFIGURAZIONE

Fondamenti di Informatica

Arduino & Oltre corso di coding ed elettronica maker

Informatica per Statistica Riassunto della lezione del 21/10/2011

Tipi di dato, variabili, istruzioni

LO HAI MAI REALIZZATO CON UN PIC? LA LAMPADA SIBILLA! 1

Informatica B a.a 2005/06 (Meccanici 4 squadra) PhD. Ing. Michele Folgheraiter

Il primo programma C++

Nicola Amoroso. Corso introduttivo sui microcontrollori A. S La programmazione dei PIC TIMERS.

SEA Descrizione. Centralina Controllo Strip LED RGB

Centralina controllo pompa

20/10/2014 M. Nappi/FIL 1

Elettronica dei Sistemi Programmabili A.A Microcontrollori. Introduzione allo sviluppo di progetti

Lezione 21 e 22. Valentina Ciriani ( ) Laboratorio di programmazione. Laboratorio di programmazione. Lezione 21 e 22

6 - Blocchi e cicli. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo

Facciamo lampeggiare un led

Fondamenti di Informatica

Corso introduttivo sui microcontrollori. Un sistema tastierino a matrice 4x4 da collegare alla nostra demoboard AnxaPic.

Assegnazione di una variabile

Architettura del calcolatore (Seconda parte)

Elementi di Informatica A. A. 2016/2017

Variabili e Funzioni. Informatica 1 / 19

Davide Gennaretti, Matteo Nicolini

Nella parte sx dello schema abbiamo gli input del microcontrollore il quale ha la funzione di elaborare dei dati che acquisisce in tempo reale.

Componenti principali

ROBOTICA Syllabus Versione 1.0

5 INSOLITI IMPIEGHI DEL 555

Laboratorio di Informatica I

Informatica B. Sezione D. Scuola di Ingegneria Industriale Laurea in Ingegneria Energetica Laurea in Ingegneria Meccanica

STRUTTURA DI UN ALGORITMO 1) LIBRERIE. 2) EVENTUALI COMMENTI // testo

ERRATA CORRIGE. void SvuotaBuffer(void); void SvuotaBuffer(void) { if(getchar()!=10) {svuotabuffer();} }

Componenti principali. Programma cablato. Architettura di Von Neumann. Programma cablato. Cos e un programma? Componenti e connessioni

Raccolta Test di Laboratorio di Sistemi a Microcontrollore

MULTIVIBRATORI. BISTABILE Entrambi gli stati sono stabili; l uscita commuta solo con un opportuno comando. Esempio i Flip-Flop

Lezione 6: Array e puntatori

I dispositivi di input/output

Dati due punti sul piano calcolare la loro distanza

Programmare con le interruzioni (2)

Laboratorio di Informatica I

Le modulazioni impulsive

1

MATLAB c. Lucia Gastaldi Dipartimento di Matematica Lezione 4 (15 ottobre 2003)

Le basi del linguaggio Java

Passare argomenti al programma

Elementi lessicali. Lezione 4. La parole chiave. Elementi lessicali. Elementi lessicali e espressioni logiche. Linguaggi di Programmazione I

Esercitazione Talentis. Marco Branciforte

Esame di INFORMATICA ARCHITETTURA DI VON NEUMANN. Lezione 4 ARCHITETTURA DI VON NEUMANN

Introduzione al MATLAB c Parte 2

GARA NAZIONALE DI ELETTRONICA E TELECOMUNICAZIONI PROVA SCRITTA. 7 maggio 2013

INFORMATICA. Strutture iterative

PIERIN PIC18 UNBOXING

Iterazione A. Ferrari

Università degli Studi di Cassino

Esercitazione 3. Espressioni booleane I comandi if-else e while

Appunti di informatica. Lezione 4 anno accademico Mario Verdicchio

Università degli Studi di Cassino

$QDOLVLGHOSURJUDPPDTXDGUDWR

#include <stdio.h> /* l esecuzione comincia dalla funzione main */ int main()

Capitolo IX. Convertitori di dati

Diagramma a blocchi per la selezione, in un mazzo di chiavi, di quella che apre un lucchetto

ANALIZZIAMO NEI DETTAGLI GLI STATEMENTS DI SELEZIONE E DI RIPETIZIONE FORNITI DAL LINGUAGGIO C STATEMENT SEMPLICE STATEMENT COMPOSTO BLOCCO

Modi di esecuzione user / kernel

LINEE GUIDA PER LA CONNESSIONE DI MCP PLUS A VIDEOTERMINALI PROFACE SERIE GP

Laboratorio di Informatica I

CORSO ARDUINO. Jacopo Belli Giulio Fieramosca Luca Mattii GOLEM Jacopo Belli Giulio Fieramosca Luca Mattii

Costrutti di Programmazione Strutturata. Informatica 1 / 22

Ing. Lorenzo Vismara

Transcript:

Steve Blackbird (TardoFreak) PIC18F47J53 COME FARE UN PWM FACILE E MULTICANALE 11 June 2013 Di tanto in tanto capita che qualche utente del forum richieda un circuito per variare in modo lineare o PWM l' intensità di LED. L' ultima discussione che ho letto si chiama "breathing LED" in cui si richiedeva un circuito in grado di far variare la luminosità di un LED con un andamento ascendente e discendente in modo da dare l' impressione che il LED respiri. La prima cosa che ho pensato è stata "Questo è un lavoro che con un micro si risolve in pochissimo tempo!". Infatti l' ho preso come spunto per implementarlo sul PIC18F47J53 cogliendo allo stesso tempo l' occasione per illustrare come le cose si possono fare con poco (spirito da vecchio microcontrollista eh eh eh) e come si utilizzano le fasi di funzionamento all' interno di un programma oltre che, ovviamente, implementare un PWM multicanale. Per la realizzazione pratica utilizzerò la scheda PIERIN PIC18. La tecnica PWM da implementare Non sarò di certo io quello che farà il solito pistolotto sulla tecnica di regolazione PWM (Pulse Width Modulation) perché sia ElectroYou che la rete ne sono pieni e la sua spiegazione esula dallo scopo di questo articolo. Quello che invece si deve sapere è che con questo programma si implementerà un controllo PWM a 32 livelli che verrà utilizzato per far variare la luminosità dei due LED che si trovano montati sul PIERIN PIC18 in modo lineare dando l' impressione che questi "respirino". In questo programma vengono comandati solo due LED ma, come si potrà ben vedere e capire, se ne potrebbero pilotare molti di più. La cosa che penso sia interessante è che non verrà utilizzata nessun' altra periferica che non sia stata utilizzata fino a questo articolo. In pratica utilizzerò solamente il Timer 2 che è già stato utilizzato nel programma di Demo e quindi conosciuto. E' vero che il PIC18F47J53 ha una ricca dotazione di timer con i quali si può fare qualsiasi cosa ma in questo caso se ne possono fare a meno. Abbiamo un micro potente e veloce ed un timer con comparatore. Non ci serve altro e tanto meno ci andremo a complicare la vita studiando altri tipi di timer... almeno per ora Descrizione del programma L' idea alla base del programma è realizzare, all' interno di un' interrupt ciclica, il controllo PWM. La frequenza deve essere sufficientemente alta da non fare apparire PIC18F47J53 COME FARE UN PWM FACILE E MULTICANALE 1

il LED sfarfallanti ma che, allo stesso tempo, sia gestibile con facilità dal microcontrollore. Nel programma di demo l' interrupt ciclica era realizzata con il timer 2 che generava una chiamata ogni millisecondo. Questa volta il timer 2 verrà inizializzato in modo da generare una interrupt ogni 100 us., dieci volte di più, con la particolarità che gestirà ugualmente i timer software (sempre con risoluzione 1 ms.) e contemporaneamente la larghezza dell' impulso delle due uscite collegate ai LED con una frequenza di 312,5 Hz (un periodo di 3,2 ms) sufficientemente alta da dare un buon effetto visivo ed evitare lo sfarfallamento. Gestione dei timer software Posto che si vuole mantenere il funzionamento dei timer software come nel programma demo (decremento ogni millisecondo) e sapendo che l' interrupt viene chiamata ogni 100 us si utilizza una variabile che funge da divisore. In pratica la si fa contare da 0 a 10 e, quando è arrivata a 10 la si azzera e si aggiornano i timer software. Il risultato è avere dei timer software che si decrementano ogni millisecondo esattamente come nel programma demo. Gestione del PWM Anche la gestione del PWM utilizza una variabile che conta da 0 a 32. Se il valore della variabile (che contiene il livello di luminosità del canale) è superiore al valore del contatore l' uscita corrispondente verrà tenuta alta mentre se il suo valore è inferiore l' uscita sarà tenuta a 0. Avremo così ottenuto in modo semplice la parzializzazione del periodo in 32 passi che possono essere tutti disattivati (nel caso che il valore valga 0) oppure tutti attivati del il valore vale 32. Il programma Il progetto è stato creato partendo dal progetto di base e si è lavorato esclusivamente su file main.c. La prima cosa che salta all' occhio è la dichiarazione delle variabili locali. Questa volta ne abbiamo 4 volatile unsigned short timer_delay_1; // Timer software 1 volatile unsigned short timer_delay_2; // Timer software 2 Che sono i due timer software ognuno utilizzato dalla sua funzione autonoma che gestisce l' effetto luminoso del suo led e volatile char pwm_level_1; // Livello luminosità LED1 (0-32) volatile char pwm_level_2; // Livello luminosità LED2 (0-32) Che sono le due variabili che contengono i livelli di luminosità dei due LED. Troviamo anche due prototipi di funzione in più che sono PIC18F47J53 COME FARE UN PWM FACILE E MULTICANALE 2

void gestione_led1(void); void gestione_led2(void); Si è deciso di fare due funzioni distinte ognuna per la gestione autonoma di ognuno dei due LED ma non solo per questo motivo. Questa volta prossima vedere come si gestiscono due processi contemporaneamente a patto di evitare alcune cose e seguire un certo rigore nella scrittura delle stesse. La funzione di servizio dell' interrupt Anche in questo caso il timer è stato inizializzato per generare una interrupt con priorità bassa mantenendo così le cose come sono nel programma di demo. Troviamo inizialmente la dichiarazione delle due variabili che fungono da divisore di base tempi e da contatore per il PWM. Sono dichiarate come statiche perché devono mantenere il loro valore anche al di fuori della funzione (se fossero dichiarate come variabili locali sarebbero azzerate ogni volta che viene chiamata la funzione) e, allo stesso tempo, non sono visibili al resto del programma. In pratica si comportano come variabili globali ma si possono usare solo all' interno della funzione. A loro viene assegnato un valore iniziale di 0. void lowpriorityinterrupt() // Verifica quale flag ha causato l' interrupt // Esegui la parte di codice di servizio dell' interrupt // Azzera il flag che ha causato l' interrupt //... static char time_base = 0; static char pwm_counter = 0; // Gestione dell' interrupt del timer 2 if(pir1bits.tmr2if) // Gestione del PWM del LED 1 if (pwm_level_1 < pwm_counter) LATDbits.LATD6 = 1; else LATDbits.LATD6 = 0; // Gestione del PWM del LED 2 if (pwm_level_2 < pwm_counter) LATDbits.LATD7 = 1; else LATDbits.LATD7 = 0; pwm_counter++; if (PWM_LEVELS == pwm_counter) pwm_counter = 0; // gestione del timer software. I timer software devono decrementarsi PIC18F47J53 COME FARE UN PWM FACILE E MULTICANALE 3

// fino ad arrivare a 0. Una volta arrivati a 0 restano fermi a 0. // La gestione avviene solo quando la variabile time_base raggiunge il // valore TIME_BASE_COUNTS in modo da aggiornare i timers ogni ms. time_base++; if (TIME_BASE_COUNTS == time_base) time_base = 0; if (timer_delay_1) timer_delay_1--; if (timer_delay_2) timer_delay_2--; // Resetta il flag che ha generato l' interrupt PIR1bits.TMR2IF = 0; La gestione delle uscite dei LED è semplicissima. Se il valore contenuto nella variabile che rappresenta la luminosità è inferiore al valore del contatore l' uscita viene mandata alta, altrimenti rimane bassa. Così, se il valore della variabile vale 0 l' uscita sarà sempre a 0, ma se il valore vale 32 (valore che il contatore non raggiunge mai) l' uscita sarà fissa ad 1. Notare infatti che il contatore viene incrementato solo dopo la gestione delle uscite e se vale 32 viene riportato a 0. In pratica varia da 0 a 31. La gestione dei timer software differisce da quella del programma demo solo proprio perché i timer vengono decrementati ogni 10 incrementi della variabile time_base ottenendo così un decremento ogni millisecondo. Le funzioni che gestiscono i due LED Sono due funzioni sostanzialmente uguali e quindi ne analizziamo una sola. Notare la dichiarazione di una variabile (statica) di tipo enum. Questa variabile può assumere solo due valori: fase_up e fase_down. Il perché è comprensibile: se dobbiamo fare vedere i LED che "respirano" ci sarà una prima fase in cui il LED aumenta la luminosità (fase_up) ed una in cui la diminuisce (fase_down). // Funzione per la gestione del LED1 // La luminosità sale lentamente e scende velocemente // Note: // utilizza il timer software soft_timer_1 e controlla la // luminosita del LED tramite la variabile pwm_level_1 void gestione_led1(void) PIC18F47J53 COME FARE UN PWM FACILE E MULTICANALE 4

static enum // variabile che contiene lo stato di funzionamento fase_up, fase_down fase_ciclo = fase_up; // Aggiorna la luminosità quando il timer_1 è arrivato a 0 if (!timer_delay_1) switch(fase_ciclo) // Salita lenta case fase_up: timer_delay_1 = 80; if (PWM_LEVELS == pwm_level_1) fase_ciclo = fase_down; else pwm_level_1++; break; // Discesa veloce case fase_down: timer_delay_1 = 20; if (0 == pwm_level_1) fase_ciclo = fase_up; else pwm_level_1--; break; //switch(fase_ciclo) // if (!timer_delay_1) Quindi quando la funzione sta eseguendo la fase ascendente verrà solo eseguita la parte di programma che sta sotto il case fase_up: e l'ì altra non verrà eseguita. Quando la fase ascendente sarà terminata, cioè quando il valore di luminosità avrà rangiunto il valore massimo la variabile fase_ciclo cambierà di valore assumendo il valore fase_down come indicato in questo disegno. PIC18F47J53 COME FARE UN PWM FACILE E MULTICANALE 5

Forse per due soli stati di funzionamento questo può sembrare eccessivo dichiarare una variabile enum ma gli stati di funzionamento potrebbero essere molti. In questo modo viene solo eseguita la parte relativa allo stato di funzionamento realizzando così una macchina a stati. Se non si introducono cicli che possono fermare l' elaborazione (come ad esempio i ritardi fissi o le attese di tasti premuti) ma si usa la macchina a stati si possono eseguire più compiti contemporanenamente. Una sorta di multitasking cooperativo (di bassa macelleria) ma che funziona... e pure bene. Il main Nel main, dopo le opportune inizializzazioni che non starò nuovamente ad analizzare (non vorrei essere ripetitivo) troviamo la parte operativa vera e propria. // Inizializza i livelli dei due LED ed azzera i due timer pwm_level_1 = 0; pwm_level_2 = 0; timer_delay_1 = 0; timer_delay_2 = 0; // -------- Ciclo infinito di funzionamento -------- for(;;) // Inserire il programma qui. gestione_led1(); gestione_led2(); //for(;;) PIC18F47J53 COME FARE UN PWM FACILE E MULTICANALE 6

E' effettivamente semplice: azzeramento delle variabili ed esecuzione continua delle due funzioni. Notare che in questo programma sono solo due perché ci sono da gestire solo gli effetti visivi di 2 LED ma ce ne potrebbero essere molte di più. Magari ci potrebbe essere una funzione che testa i pulsanti per farci un qualcosa, un' altra funzione che realizza una rete logica con altri ingressi ed uscite, un po' di tutto. L' importante è che si tenga presente che ogni funzione (task) non deve tenere il controllo del programma per più di un tempo stabilito a priori e, tanto meno, deve piantare il programma all' interno di una attesa! Se non si seguono queste regole allora niente funziona ma se si seguono le potenzialità di un programma diventano notevoli. Suggerimenti per la sperimentazione Il risultato visivo di questo programma è quello mostrato in questo video. I due LED non "resipirano" sincronizzati. E' un effetto voluto proprio per far vedere che due funzioni sono completamente autonome. Il programma esegue in buona sostanza due task in parallelo. Flash Per poterlo vedere funzionare anche senza compilare tutto il programma con MPLAB si può programmare il file.hex chiamato easy_pwm.hex direttamente dentro la scheda. Se poi si incomincia a variare i valori con cui sono caricati i timer software si variano le velocità di lampeggio. Si può anche leggere da un ingresso analogico, magari collegato ad un potenziometro, scalarne il valore in modo che vada da 0 a 32 e comandare manualmente la luminosità di un LED oltre che, naturalmente, PIC18F47J53 COME FARE UN PWM FACILE E MULTICANALE 7

aggiungere altri canali PWM. Con un po' di buona volontà il divertimento e gli esperimenti sono assicurati. Cio detto, e scusando di eventuali errori ed imprecisioni, non mi resta che augurare BUONA SPERIMENTAZIONE!. Il sorgente completo // File di definizione dei registri del micro. #include "p18f47j53.h" // File di libreria contenete le funzioni di ritardo #include "delays.h" // File di configurazione dei fuses #include "configurazione.h" // Mappatura delle interrupt #include "mappa_int.h" // Header del main #include "main.h" // Defines del programma // Numero di interrupts per base tempi 1ms. #define TIME_BASE_COUNTS 10 // Nmumero di livelli per le uscite PWM #define PWM_LEVELS 32 // Variabili globali #pragma udata volatile unsigned short timer_delay_1; // Timer software 1 volatile unsigned short timer_delay_2; // Timer software 2 volatile char pwm_level_1; // Livello luminosità LED1 (0-32) volatile char pwm_level_2; // Livello luminosità LED2 (0-32) // Funzione di servizio delle interrupt ad ALTA priorità PIC18F47J53 COME FARE UN PWM FACILE E MULTICANALE 8

#pragma code #pragma interrupt highpriorityinterrupt void highpriorityinterrupt() // Verifica quale flag ha causato l' interrupt // Esegui la parte di codice di servizio dell' interrupt // Azzera il flag che ha causato l' interrupt //... // Funzione di servizio delle interrupt a BASSA priorità #pragma interruptlow lowpriorityinterrupt void lowpriorityinterrupt() // Verifica quale flag ha causato l' interrupt // Esegui la parte di codice di servizio dell' interrupt // Azzera il flag che ha causato l' interrupt //... static char time_base = 0; static char pwm_counter = 0; // Gestione dell' interrupt del timer 2 if(pir1bits.tmr2if) // Gestione del PWM del LED 1 if (pwm_level_1 < pwm_counter) LATDbits.LATD6 = 1; else LATDbits.LATD6 = 0; // Gestione del PWM del LED 2 if (pwm_level_2 < pwm_counter) LATDbits.LATD7 = 1; else LATDbits.LATD7 = 0; pwm_counter++; if (PWM_LEVELS == pwm_counter) pwm_counter = 0; // gestione del timer software. I timer software devono decrementarsi // fino ad arrivare a 0. Una volta arrivati a 0 restano fermi a 0. // La gestione avviene solo quando la variabile time_base raggiunge il // valore TIME_BASE_COUNTS in modo da aggiornare i timers ogni ms. time_base++; if (TIME_BASE_COUNTS == time_base) PIC18F47J53 COME FARE UN PWM FACILE E MULTICANALE 9

time_base = 0; if (timer_delay_1) timer_delay_1--; if (timer_delay_2) timer_delay_2--; // Resetta il flag che ha generato l' interrupt PIR1bits.TMR2IF = 0; // Prototipi delle funzioni #pragma code void timer2_deinit(void); void gestione_led1(void); void gestione_led2(void); // Funzioni #pragma code // De-inizializza il timer 2 e lo porta nello stato in cui si trovava // subito dopo il RESET void timer2_deinit(void) T2CON = 0; // Resetta il timer 2 control register TMR2 = 0; // Azzera il contatore interno PR2 = 0; // Azzera il registro comparatore PIE1bits.TMR2IE = 0; // Disabilita l' interrupt IPR1bits.TMR2IP = 0; // Resetta il bit di priorità dell' interrupt PIR1bits.TMR2IF = 0; // Azzera il flag di interrupt // Funzione per la gestione del LED1 // La luminosità sale lentamente e scende velocemente // Note: // utilizza il timer software soft_timer_1 e controlla la // luminosita del LED tramite la variabile pwm_level_1 PIC18F47J53 COME FARE UN PWM FACILE E MULTICANALE 10

void gestione_led1(void) static enum // variabile che contiene lo stato di funzionamento fase_up, fase_down fase_ciclo = fase_up; // Aggiorna la luminosità quando il timer_1 è arrivato a 0 if (!timer_delay_1) switch(fase_ciclo) // Salita lenta case fase_up: timer_delay_1 = 80; if (PWM_LEVELS == pwm_level_1) fase_ciclo = fase_down; else pwm_level_1++; break; // Discesa veloce case fase_down: timer_delay_1 = 20; if (0 == pwm_level_1) fase_ciclo = fase_up; else pwm_level_1--; break; //switch(fase_ciclo) // if (!timer_delay_1) // Funzione per la gestione del LED2 // La luminosità sale velocemente e scende velocemente in modo simmetrico // Note: // utilizza il timer software soft_timer_2 e controlla la // luminosita del LED tramite la variabile pwm_level_2 void gestione_led2(void) static enum // variabile che contiene lo stato di funzionamento fase_up, fase_down fase_ciclo = fase_up; PIC18F47J53 COME FARE UN PWM FACILE E MULTICANALE 11

// Aggiorna la luminosità quando il timer_2 è arrivato a 0 if (!timer_delay_2) switch(fase_ciclo) // Salita veloce case fase_up: timer_delay_2 = 15; if (PWM_LEVELS == pwm_level_2) fase_ciclo = fase_down; else pwm_level_2++; break; // Discesa veloce case fase_down: timer_delay_2 = 15; if (0 == pwm_level_2) fase_ciclo = fase_up; else pwm_level_2--; break; //switch(fase_ciclo) // if (!timer_delay_2) // MAIN FUNCTION void main(void) // Fa partire il PLL. // Anche se viene selezionato tramite i bit di configurazione // il suo funzionamento non è automatico. Ha bisogno di un comando. OSCTUNEbits.PLLEN = 1; // Attende abbastanza tempo per far stabilizzare il PLL Delay1KTCYx(10); // Da ora in poi abbiamo il PLL funzionante ed il micro con il turbo. // -------- Inizializzazione delle periferiche -------- // Inizializza la PORTD // bit 4 input pulsante PL0 // " 5 input pulsante PL1 // " 6 output LED LED1 PIC18F47J53 COME FARE UN PWM FACILE E MULTICANALE 12

// " 7 output LED LED2 TRISD = 0x3F; // Mette a 0 tutte le uscite LATD = 0; // De-inizializza il timer2. Non sarebbe necessario perché il micro esce // allo stato di RESET ma è comunque buona pratica de-inizializzare sempre // le periferiche per non tralasciare nessun bit. timer2_deinit(); // Inizializza il timer 2 per interrupt ogni 100 microsecondi. // prescaler divide per 16 T2CONbits.T2CKPS = 2; // Postscaler divide per 5 T2CONbits.T2OUTPS = 4; // Imposta il valore comparatore a 150 PR2 = 15; // Imposta l' interrupt del Timer 2 a priorita' bassa IPR1bits.TMR2IP = 0; // abilita interrupt del timer PIE1bits.TMR2IE = 1; // -------- Selezione ed abilitazione delle interrupt -------- // Ora che si sono inizializzate tutte le periferiche si possono abilitare // Oppurtunamente le interrupt // abilita le interrupt a bassa priorita' RCONbits.IPEN = 1; // abilta tutte le interrupt a priorità bassa INTCONbits.GIEL = 1; // Abilita tutte le interrupt in generale INTCONbits.GIEH = 1; // -------- Attivazione delle periferiche -------- // Con le interrupt abilitate possiamo ora far partire il timer 2 // Accende il timer T2CONbits.TMR2ON = 1; // Inizializza i livelli dei due LED ed azzera i due timer pwm_level_1 = 0; pwm_level_2 = 0; timer_delay_1 = 0; timer_delay_2 = 0; PIC18F47J53 COME FARE UN PWM FACILE E MULTICANALE 13

// -------- Ciclo infinito di funzionamento -------- for(;;) // Inserire il programma qui. gestione_led1(); gestione_led2(); //for(;;) Estratto da "http://www.electroyou.it/mediawiki/ index.php?title=userspages:tardofreak:pic18f47j53-come-fare-un-pwm-facile-emulticanale" PIC18F47J53 COME FARE UN PWM FACILE E MULTICANALE 14