Problema nella gestione di due sensori con PIC18F4550 in XC8
Ciao a tutti!
Premetto che so pochissimo di programmazione, l'XC8 è da un mese che lo utilizzo e questo è il mio primo programma. Il progetto consiste nel mostrare la temperatura ambientale (usando un LM335) e lo stato di un led (ON o OFF) che dipende da due sensori: un PIR e una fotoresistenza in un display LCD HD44780 16x2. La prima parte del programma, senza gli ultimi due sensori, funziona senza problemi al variare della temperatura. Il programma completo, invece, inizialmente controlla il valore di temperatura e lo scrive sul display e poi continua a rimanere nella seconda parte (PIR + fotoresistenza) senza cambiare la temperatura nonostante il tutto sia all'interno di un ciclo infinito.. perché? Non riesco proprio a capire.. 
Ecco il programma:
Ecco il programma:
- Codice: Seleziona tutto
//Librerie e costanti
#include<xc.h>
#include"PIC18F4550_config.h"
#define LCD_DEFAULT //Imposto i pin dell'LCD per l'interfacciamento con il PIC
#include"LCD_44780.h"
#include"LCD_44780.c"
#include"delay.h"
#include"delay.c"
#define _XTAL_FREQ 20000000 //Specifico la frequenza dell'oscillatore
#define NUMERO_CAMPIONI 32
//Prototipi di funzione
void board_initialization(); //Configurazione PORT
void ADCconfig(); //Configurazione dell'ADC
void temp(); //Funzione per la gestione della temperatura
/*Funzione map di arduino*/
long int map(long int x, long int in_min, long int in_max, long int out_min, long int out_max){
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
/*Funzione che legge il valore finale dell'ADC*/
unsigned int ADCRead(unsigned int ch){
if(ch>13) return 0; //Canale non valido
ADCON0=0x00; //Azzero il registro ADCON0
ADCON0=(ch<<2); //Seleziona il canale dell'ADC saltando i bit 0 e 1
ADON=1; //Abilita il modulo ADC
GODONE=1; //Avvia la conversione
while(GODONE); //Aspetta la fine della conversione
ADON=0; //Disabilita l'ADC
return ADRES; //Ritorna il risultato della conversione
}
//Programma principale
void main(){
board_initialization(); //Inizializzazione del PIC18F4550
ADCconfig(); //Inizializzo l'ADC
//Inizializzo il display LCD
initialize_LCD(20); //Lavoro con una frequenza di 20MHz
write_message_LCD (" Temp");
write_char_LCD (58); //Carattere ASCII ":"
write_message_LCD (" ");
write_char_LCD (223); //Carattere ASCII "°"
write_char_LCD ('C');
shift_cursor_LCD (LEFT,5);
unsigned int VLDR; //Tensione ai capi dell'LDR
delay_ms(1);
//Ciclo infinito
while(1){
//***************************************TEMPERATURA***********************************************
temp();
//************************************FOTORESISTENZA+PIR*******************************************
VLDR=ADCRead(1); //Lettura ADC nel canale 1 (pin RA1)
if(VLDR<612 && PORTAbits.RA2==1){ //Se si verifica la condizione di buio e il PIR rileva movimento
do{
goto_line_LCD(2);
write_message_LCD(" ON ");
delay_s(5);
} while (PORTAbits.RA2==1 && VLDR<512);
goto_line_LCD(2);
write_message_LCD(" OFF ");
}
if(VLDR>716){ //Se si verifica la condizione di luce
goto_line_LCD(2);
write_message_LCD(" OFF ");
}
}
}
//Funzione di configurazione dell'ADC
void ADCconfig(){
ADCON1 = 0b00001101; //VSS,VDD ref. AN0(pin RA0) e AN1(pin RA1) sono analogici
ADCON2 = 0b10100101; //ADCON2 setup: Right justified, Tacq=8Tad, Tad=16*Tosc (or Fosc/16)
}
//Funzione della temperatura
void temp(){
long int sommatoria=0; //Variabile per salvare la sommatoria dei dati letti
unsigned int lettura=0; //Variabile per salvare il valore della conversione
unsigned char numero_letture; //Variabile utilizzata per il numero delle letture
sommatoria=0;
for (numero_letture=0; numero_letture<NUMERO_CAMPIONI; numero_letture++){
lettura=ADCRead(0); //Lettura ADC nel canale 0 (pin RA0)
sommatoria=sommatoria+lettura; //Sommatoria delle letture fatte
}
sommatoria=sommatoria/NUMERO_CAMPIONI; //Calcolo del valore medio
sommatoria=sommatoria/2; //Divido per 2 per avere la temperatura in gradi
sommatoria=map(sommatoria, 0, 68, -20, 50); //Funzione che permette di visualizzare la temperatura da -20°C a 50°C
//Se la temperatura è maggiore o uguale a 0°C
if(sommatoria>=0){
write_message_LCD(" "); //"Elimino" il terzo carattere che si crea con il numero negativo
write_integer_LCD (sommatoria,2);
shift_cursor_LCD (LEFT,3);
delay_ms(500);
}
//Se la temperatura è inferiore a 0°C
if(sommatoria<0){
write_integer_LCD (sommatoria,3);
shift_cursor_LCD (LEFT,3);
delay_ms(500);
}
}
//Funzione di configurazione dei PORT
void board_initialization(){
//Imposto TRISA come INPUT
LATA=0;
TRISA=0xFF;
//Imposto TRISB come INPUT
LATB=0;
TRISB=0xFF;
//Imposto TRISC come INPUT
LATC=0;
TRISC=0xFF;
//Imposto TRISD come OUTPUT tranne RD6 e RD7 che sono impostati come INPUT perché non vengono utilizzati
LATD=0;
TRISD=0b11000000;
//Imposto TRISE come INPUT
LATE=0;
TRISE=0xFF;
}