TUTORIAL GPL_BENZINA CON PIC16F1826 (UTILIZZO DELL ADC) Tutorial di Maroncelli Matteo e Zoffoli Federico, 5A. Creare un programma che simula gli indicatori di livello da serbatoi GPL e Benzina. Attraverso il primo trimmer si potrà simulare gli indicatori di livello benzina utilizzando come Pin di ingresso RA0, come variabile conversione e come uscita tutti gli 8 LED del PIC16F1826. Attraverso il secondo trimmer, utilizzando come ingresso RA4, come variabile conversione2 si potrà simulare gli indicatori di livello benzina utilizzando sempre come uscita gli 8 LED del PIC16F1826. Attraverso il pulsanti S1 verranno mandati a livello logico zero tutti gli 8 LED come impostazione di RESET. 1. Creare un nuovo progetto su MPLAB-X. 2. Verificare di avere già installato MPLAB -X Code Configurator e updatarlo nel caso non si disponga dell ultima versione. 3. Se non lo si ha installato correttamente, eseguire i seguenti passaggi: Per mantenere versione funzionante del MCC 3.36 bis occorre: a) Tools >> Plugins >> Settings >> MicroChip Plugins b) Click in Edit c) Devi stare ==> Check for update automatically Per installare libreria aggiuntiva serie Pic32MXxxx a1) Tools >> Options >> Plugins >> install Library b1) Selezionare ==> file pic32mx_v1.25.jar Da notare che la cartella in questione è reperibile in condivisione. 4. Una volta eseguito questo passaggio è necassario aprire System Module impostare il Clock a 4MHz, selezionare FOSC in System Clock Select e fare le spunte come in figura. 1
Dopodichè utilizzare Code Configurator per indicare al pic i pin di ingresso e di uscita. Selezioniamo RA0 ed RA4 come ingressi per la lettura da ADC, RA2 ed RA3 come ingressi collegati ai pulsanti, e tutti i pin di portb come output indirizzati agli 8 led. 2
Come si evince a pag.159 del datasheet del PIC16F1826, ad una frequenza di clock di 4MHz, riusciamo a campionare attraverso l ADC interno una tensione dividibile in 256 quanti ad una velocità di 15.6kHz, ovvero un campione di tensione ogni 64 microsecondi, velocità adatta alle esigenze del nostro progetto. 3
Andiamo su System Module Easy Setup, impostare il quarzo interno a 4Mhz, disabilitiamo la programmazione a bassa tensione Low-Voltage Programming Enable bit dato che dobbiamo programmare alla tensione massima disponibile come è possibile vedere a pag. 46 del datasheet. Inoltre togliamo le spunte PLL Enable: il PLL, ovvero Phase Locked Loop, è una funzione che permette di moltiplicare di 4 volte la frequenza del clock, al fine di far funzionare il microcontrollore ad una frequenza maggiore rispetto ad altri dispositivi aggiunti che possono necessitare di una frequenza minore. In questo caso la funzione pll non è necessaria. 4
Selezionare Pin Module dalla voce in alto a sinistra e togliere la spunta da WPU e lasciare quelle di Output e Analog come in figura: Non ci deve essere la spunta di WPU perché, come è possibile notare a pag.30 e pag.128 del datasheet, questa particolare funzione del registro PortB a 8bit non ci serve per il funzionamento del programma e quindi, per disabilitare questa funzione, il valore logico deve essere pari a zero. In particolare la funzione WPU rappresenta un pull-up sulla linea corrispondente del PortB. Gli ingressi Analog spuntati sono corrispondenti ad RA0-RA4 e verranno collegati direttamente ai pin del trimmer, mentre tutte le uscite del PortB vengono abilitate poiché sono corrispoindenti agli 8LED. 5
Nel riquadro in basso selezionare ADC e cliccarlo due volte per aggiungere al programma l uso del convertitore ADC. Cliccare su Register ed impostare il CHS ad AN0come in figura. La funzione CHS (datasheet pag. 137) deve essere indirizzata ad AN0 perché rappresenta l indirizzo di selezione per l abilitazione dell uscita del Multiplexer interno che riceve il dato dall ADC, per poter eseguire correttamente la conversione dal pin opportunamente scelto. 6
Una volta aperto Easy Setup dell ADC spuntare l icona Enable ADC Interrupt, impostare la frequenza di campionamento 1/32 di quella interna FOSC/32 aperto e controllare l alimentazione VDD, VSS come in figura. La funzione Enable ADC Interrupt (Datasheet pag.144) va spuntata perché questa opzione che ci consente l interruzione del programma non ci serve. Inoltre impostiamo come riferimenti di tensione positiva VDD e negativa VSS come è possibile vedere a pag. 140 del datasheet. Dopo di che è necessario cliccare su Generate per generare il file main.c che si apre cliccando su Source Files in alto a sinistra come in figura. Questo passaggio ci consente di poter scrivere il nostro programma in C configurandolo con il Pic16F1826. 7
Una volta trascritto il programma presente giù di seguito potete caricarlo sulla scheda e provarlo!! // programma di Maroncelli Matteo e Zoffoli Federico #include "mcc_generated_files/mcc.h" int conversione = 0; //Inizializzazione Variabile Conversione per GPL char conversione2= 0; //Inizializzazione Variabile Conversione 2 per Benzina void CanaleADC(int a) //Questa funzione cambia il valore del registro { //ADCON0 in base a quali pin dell'adc vogliamo utilizzare if(a==0)adcon0=0b00000001; if(a==1)adcon0=0b00000101; if(a==2)adcon0=0b00001001; if(a==3)adcon0=0b00001101; if(a==4)adcon0=0b00010001; //Utilizzo //Utilizzo //Utilizzo //Utilizzo //Utilizzo pin pin pin pin pin RA0 RA1 RA2 RA3 RA4 /* Main application */ void main(void) { // initialize the device SYSTEM_Initialize(); while (1) { if(io_ra2_port==1){ // Se il Puls1 è premuto, si spengono titti i 8 Led IO_RB0_SetLow(); IO_RB1_SetLow(); IO_RB2_SetLow(); IO_RB3_SetLow(); IO_RB4_SetLow(); IO_RB5_SetLow(); IO_RB6_SetLow(); IO_RB7_SetLow(); CanaleADC(0); //Impostazione del canale d'ingresso RA0 ADC_StartConversion(); //Richiamo La Funzione Che Fa Partire La Conversione Dell' ADC while(adcon0bits.go_ndone ==1){ //Fino A Che Il Bit Che Indica Il Completamento Della Conversione è a 1 continue; // Continuo conversione = ADRESH; /*Assegno Alla Variabile conversione Il Valore Del Registro ADRESH Che Contiene Il Valore Della Conversione*/ 8
if(conversione>0){ //Se Il Valore di Conversione é > Di 0 IO_RB0_SetHigh(); // Accendo RB0 IO_RB0_SetLow(); // Spengo RB0 if(conversione>32){ //Se Il Valore di Conversione é > Di 32 IO_RB1_SetHigh(); // Accendo RB1 IO_RB1_SetLow(); // Spengo RB1 if(conversione>64){ //Se Il Valore di Conversione é > Di 64 IO_RB2_SetHigh(); // Accendo RB2 IO_RB2_SetLow(); // Spengo RB2 if(conversione>96){ //Se Il Valore di Conversione é > Di 96 IO_RB3_SetHigh(); // Accendo RB3 IO_RB3_SetLow(); // Spengo RB3 if(conversione>128){ //Se Il Valore di Conversione é > Di 128 IO_RB4_SetHigh(); // Accendo RB4 IO_RB4_SetLow(); // Spengo RB4 if(conversione>160){ //Se Il Valore di Conversione é > Di 160 IO_RB5_SetHigh(); // Accendo RB5 IO_RB5_SetLow(); // Spengo RB5 if(conversione>192){ //Se Il Valore di Conversione é > Di 192 IO_RB6_SetHigh(); // Accendo RB6 IO_RB6_SetLow(); // Spengo RB6 if(conversione>224){//se Il Valore di Conversione é > Di 224 IO_RB7_SetHigh(); // Accendo RB7 IO_RB7_SetLow(); // Spengo RB7 CanaleADC(4); //Impostazione del canale d'ingresso RA4 ADC_StartConversion(); //Richiamo La Funzione Che Fa Partire La Conversione Dell' ADC 9
while(adcon0bits.go_ndone ==1){ //Fino A Che Il Bit Che Indica Il Completamento Della Conversione è a 1 //continue; Continuo conversione2 = ADRESH; //Assegno Alla Variabile conversione Il Valore Del Registro ADRESH Che Contiene Il Valore //Della Conversione if(conversione2>0){ //Se Il Valore di Conversione é > Di 0 IO_RB0_SetHigh(); // Accendo RB0 IO_RB0_SetLow(); // Spengo RB0 if(conversione2>32){ //Se Il Valore di Conversione é > Di 32 IO_RB1_SetHigh(); // Accendo RB1 IO_RB1_SetLow(); // Spengo RB1 if(conversione2>64){ //Se Il Valore di Conversione é > Di 64 IO_RB2_SetHigh(); // Accendo RB2 IO_RB2_SetLow(); // Spengo RB2 if(conversione2>96){ //Se Il Valore di Conversione é > Di 96 IO_RB3_SetHigh(); // Accendo RB3 IO_RB3_SetLow(); // Spengo RB3 if(conversione2>128){ //Se Il Valore di Conversione é > Di 128 IO_RB4_SetHigh(); // Accendo RB4 IO_RB4_SetLow(); // Spengo RB4 if(conversione2>160){ //Se Il Valore di Conversione é > Di 160 IO_RB5_SetHigh(); // Accendo RB5 IO_RB5_SetLow(); // Spengo RB5 if(conversione2>192){ //Se Il Valore di Conversione é > Di 192 IO_RB6_SetHigh(); // Accendo RB6 IO_RB6_SetLow(); // Spengo RB6 if(conversione2>224){//se Il Valore di Conversione é > Di 224 IO_RB7_SetHigh(); // Accendo RB7 10
IO_RB7_SetLow(); // Spengo RB7 // Fine Passiamo ora al cablaggio del nostro circuito, affinche possiamo rilevare tramite il pic il dato in tensione di gpl e benzina. Per farlo utilizzeremo due trimmer, da collegare dall alimentazione del pic (+5V ; GND) rispettivamente ai pin 1 e 3 del componente, mentre collegheremo il pin 2 (ovvero quello centrale) ad uno dei due ingressi analogici a cui abbiamo adibito da software la lettura da parte dell ADC. L ADC suddivide la tensione letta dagli ingressi in 256 livelli, per cui avendo 8 led a disposizione, secondo il codice riportato si accenderà un led ogni 32 livelli, corrispondenti a 0,24V. Dopo aver premuto uno dei due pulsanti si può vedere come cambiando la resistenza del trimmer con il cacciavite, si accendano in sequenza gli 8 LED. Successivamente si può notare come ad ogni combinazione ci sia un valore corrispondente di tensione corrispondente ad n LED * 0,24V. 11
12