#include "system.h"
#include "iomapping.h"
/*****************************************************************************
*Constantes
*****************************************************************************/
//ADC channels numbers
#define ADC_DENSIDAD ADC_DEN_CHAN //define canal densidad
#define ADC_HIDROGENO ADC_HID_CHAN //define canal hidrogeno
#define ADC_VOLTAJE ADC_VOL_CHAN //define canal voltaje
#define ADC_TEMPERATURA ADC_TEM_CHAN //define canal temperatura
#define ADC_SWITCH_DELAY 600 // Delay after input switching
#define ADC_POS_NUMBER 6 // Number position
#define ADC_POS_MEM 13 // Memory sign position
#define AVCC 1240 // Voltaje de Referencia, mV densidad
#define AVCC1 1300 // Voltaje de Referencia, mV hidrogeno
#define AVCC2 1350 // Voltaje de Referencia, mV voltaje
#define AVCC3 2600 // Voltaje de Referencia, mV temperatura
/*****************************************************************************
* Arrays: _densidad_str y las demas
* Overview: datos de variables y sus caracteres.
*****************************************************************************/
char _densidad_str[16] = "Den = ";
char _hidrogeno_str[16] = "Hid = ";
char _voltaje_str[16] = "Vol = ";
char _temperatura_str[16] = "Tem = ";
//char _peligro_str[16] = " FUERA DE RANGO ";
unsigned char _uADCState;
unsigned int _uADCWait;
unsigned int _uADCDensidad;
unsigned int _uADCHidrogeno;
unsigned int _uADCVoltaje;
unsigned int _uADCTemperatura;
unsigned char _uADCFromMemory; // Switch que toma valor de las variables de la
// EEPROM y no del ADC.
/*****************************************************************************
* Funcion: ADCInit
* Descripcion: Inicializacion ADC y màquina de estados.
******************************************************************************/
void ADCInit(){
AD1CON1 = 0x80E4; //Turn on, auto sample start, auto-convert
AD1CON2 = 0; //AVdd, AVss, int every conversion, MUXA only
AD1CON3 = 0x1F05; //31 Tad auto-sample, Tad = 5*Tcy
AD1CHS = ADC_DENSIDAD; //Con este canal se empieza la toma de datos
TRISBbits.TRISB2 = 1;
TRISBbits.TRISB3 = 1;
AN_DEN_PIN = 0; //Disable digital input on AN5
AN_HID_PIN = 0;
AN_VOL_PIN = 0;
AN_TEM_PIN = 0;
AD1CSSL = 0; //No scanned inputs
_uADCWait = ADC_SWITCH_DELAY;
_uADCState = 1;
_uADCFromMemory = 0; //Show current temperature
}
/*****************************************************************************
* Function: ADCProcessEvents
* Preconditions: ADCInit must be called before.
* Overview: Maquina de Estados para la toma de datos de la densidad por el
* potenciometro.
******************************************************************************/
void ADCProcessEvents(){
unsigned long Result;
switch(_uADCState){
case 1: // TOMA DE DATOS PARA DENSIDAD
while(!AD1CON1bits.DONE); // Espera que el dato se complete
Result = (long) ADC1BUF0;
Result = (Result*AVCC)/1024;
/***************************CODIGO PARA LECTURA DE DATOS EN LA EEPROM(DENSIDAD)***********************/
_uADCDensidad -= _uADCDensidad>>4;
_uADCDensidad += Result;
Result = _uADCDensidad>>4;
// Leer densidad almacenada en EEPROM
_densidad_str[ADC_POS_MEM] = ' ';
if(ADCIsFromMemory()){
Result = ADCLoadDensidad();
_densidad_str[ADC_POS_MEM] = 'M';
}
/****************************************************************************************************/
/****************************CODIGO PARA EL RANGO****************************************************/
if(Result>1000){
_densidad_str[ADC_POS_MEM] = 'P';
}
/****************************************************************************************************/
ADCShortToString((int)Result, 1, _densidad_str+ADC_POS_NUMBER);
_densidad_str[ADC_POS_NUMBER+4] = ' '; // Sweep least significant digit
AD1CHS = ADC_HIDROGENO;
_uADCState++;
break;
case 3: // TOMA DE DATOS PARA HIDROGENO
while(!AD1CON1bits.DONE); // Espera que el dato se complete
Result = (long) ADC1BUF0;
Result = (Result*AVCC1)/1024;
/***************************CODIGO PARA LECTURA DE DATOS EN LA EEPROM(HIDROGENO)***********************/
_uADCHidrogeno -= _uADCHidrogeno>>4;
_uADCHidrogeno += Result;
Result = _uADCHidrogeno>>4;
// Leer densidad almacenada en EEPROM
_hidrogeno_str[ADC_POS_MEM] = ' ';
if(ADCIsFromMemory()){
Result = ADCLoadHidrogeno();
_hidrogeno_str[ADC_POS_MEM] = 'M';
}
/********************************************************************************************/
/****************************CODIGO PARA EL RANGO****************************************************/
if(Result>1100){
_hidrogeno_str[ADC_POS_MEM] = 'P';
}
/****************************************************************************************************/
ADCShortToString((int)Result, 4, _hidrogeno_str+ADC_POS_NUMBER);
_hidrogeno_str[ADC_POS_NUMBER+4] = ' '; // Sweep least significant digit
AD1CHS = ADC_VOLTAJE; // aqui se cambiaria el canal a tomar
// AD1CHS = ADC_DENSIDAD;
_uADCState++;
break;
case 5: // TOMA DE DATOS PARA VOLTAJE
while(!AD1CON1bits.DONE); // Espera que el dato se complete
Result = (long) ADC1BUF0;
Result = (Result*AVCC2)/1024;
/***************************CODIGO PARA LECTURA DE DATOS EN LA EEPROM(VOLTAJE)***********************/
_uADCVoltaje -= _uADCVoltaje>>4;
_uADCVoltaje += Result;
Result = _uADCVoltaje>>4;
// Leer densidad almacenada en EEPROM
_voltaje_str[ADC_POS_MEM] = ' ';
if(ADCIsFromMemory()){
Result = ADCLoadVoltaje();
_voltaje_str[ADC_POS_MEM] = 'M';
}
/********************************************************************************************/
/****************************CODIGO PARA EL RANGO****************************************************/
if(1150 == Result){
LED1_TRIS = 0;
LED1_IO = 1;
}
else if(1300 == Result){
LED1_IO = 0;
}
/****************************************************************************************************/
ADCShortToString((int)Result, 3, _voltaje_str+ADC_POS_NUMBER);
_voltaje_str[ADC_POS_NUMBER+4] = ' '; // Sweep least significant digit
AD1CHS = ADC_TEMPERATURA; // aqui se cambiaria el canal a tomar
_uADCState++;
break;
case 7: // TOMA DE DATOS PARA TEMPERATURA
while(!AD1CON1bits.DONE); // Espera que el dato se complete
Result = (long) ADC1BUF0;
Result = (Result*AVCC3)/1024;
/***************************CODIGO PARA LECTURA DE DATOS EN LA EEPROM(TEMPERATURA)***********************/
_uADCTemperatura -= _uADCTemperatura>>4;
_uADCTemperatura += Result;
Result = _uADCTemperatura>>4;
// Leer densidad almacenada en EEPROM
_temperatura_str[ADC_POS_MEM] = ' ';
if(ADCIsFromMemory()){
Result = ADCLoadTemperatura();
_temperatura_str[ADC_POS_MEM] = 'M';
}
/********************************************************************************************/
/****************************CODIGO PARA EL RANGO****************************************************/
if(Result>2400){
_temperatura_str[ADC_POS_MEM] = 'P';
}
/****************************************************************************************************/
ADCShortToString((int)Result, 2, _temperatura_str+ADC_POS_NUMBER);
_temperatura_str[ADC_POS_NUMBER+4] = ' '; // Sweep least significant digit
AD1CHS = ADC_DENSIDAD; // aqui se cambiaria el canal a tomar
// AD1CHS = ADC_DENSIDAD;
_uADCState++;
break;
case 2:
case 4:
case 6:
case 8:
if(0 == _uADCWait--){ // Tiempo(Delay) entre cambio de canal
_uADCWait = ADC_SWITCH_DELAY;
_uADCState++;
}
break;
break;
default:
_uADCState = 1;
}
}
EN ROJO ES DONDE TENGO EL PROBLEMA ESTA ES LA MAQUINITA DE ESTADOS PARA LA TOMA DE DATOS DEL ADC MI PIC ES DE 16 bits me dijeron que lo pudia hacer por interrupciones..........EL PROBLEMA ES CUANDO SE APAGA EL LED YA QUE SE QUEDA PEGADO EL PROGRAMA.......................