Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
Buenas a todos.
Estoy provando el modulo ADC del PIC16F88. Tengo un circuito montado en una protoboard que consiste en: un LDR conectado al AN0 i el LED conectado al B5.
Simplemente quiero que cuando el valor que coge el LDR sea mayor a 200 el LED se encienda.
El problema es que el LED no me hace caso, siempre esta encendido.
Utilizo el compilador CCS, si alguien me puede ayudar le estaria agradecido.
#include <16f88>
#device ADC = 8
#FUSES HS //High Speed
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOCPD //No EE protection
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOMCLR //Master Clear pin enabled
#FUSES PUT //Power Up Timer
#FUSES BROWNOUT //Reset when brownout detected
#use delay(clock=20000000)
#use standard_io(b)
// Registros PORTS
#byte PORTA = 0x05
#byte TRISA = 0x85
#byte PORTB = 0x06
#byte TRISB = 0x86
// Registros ADC
#byte ANSEL = 0x9B
#byte ADCON0 = 0x1F
#byte ADCON1 = 0x9F
#byte ADRESH = 0x1E
#byte ADRESL = 0x9E
// Bits del conversor ADC 0
#bit ADGO = ADCON0.2
// Componentes
#bit LED = PORTB.5
#bit LDR = PORTA.0
// Otros
#define ON 1
#define OFF 0
void configure_ADC(void);
void select_ADC(unsigned canal);
void start_ADC(void);
void read_ADC(void);
unsigned int resultado; // Resultado de la lectura del ADC
void main()
{
//Configuracion por defecto
//---------------------------------------------------------------------------
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
//---------------------------------------------------------------------------
TRISA = 0b00000001;
PORTA = 0b00000001;
TRISB = 0b00000000;
PORTB = 0b00000000;
configure_ADC();
delay_ms(100);
while(true)
{
select_ADC(0); // llamamos a la función select_ADC dandole como parametro el canal
start_ADC(); // llamamos a dicha función
resultado = read_ADC(); // leer_AD nos devuelve el valor de la conversión y lo guarda en resultado
if(resultado > 200){
LED = ON;
}
else{
LED = OFF;
}
}
}
// FUNCIONES
//------------------------------------------------------------------------------
// Funció que configura y inicializa el ADC
void configure_ADC()
{
// Configuracion de todos los bytes
ANSEL = 0b00000001; // Configura el PIN AN0 como entrada
ADCON1 = 0b00000000; // Configura el voltage de referéncia; AVDD-AVSS
ADCON0 = 0b10000001; // FOSC/32; Channel 0; Inicia el modulo ADC
}
// Función que selecciona el canal del ADC
void select_ADC(unsigned canal)
{
switch (canal)
{
case 0:
adcon0 = 0b10000001; // Channel 0
break;
case 1:
adcon0 = 0b10001001; // Channel 1
break;
case 2:
adcon0 = 0b10010001; // Channel 2
break;
case 3:
adcon0 = 0b10011001; // Channel 3
break;
case 4:
adcon0 = 0b10100001; // Channel 4
break;
case 5:
adcon0 = 0b10101001; // Channel 5
break;
case 6:
adcon0 = 0b10110001; // Channel 6
break;
}
}
// Función que enciende el conversor A-D
void start_ADC()
{
ADGO = 1; //ponemos en marcha el conversor
}
int read_ADC()
{
int high, low;
while (ADGO);
high = ADRESH;
low = ADRESL;
return (int)high<<8 | low; //Hacemos una or de bajo y de alto convertido a long y desplazado 8 bits.
}
La función que lee el ADC es esa:
int read_ADC()
{
int high, low;
while (ADGO);
high = ADRESH;
low = ADRESL;
return (int)high<<8 | low; //Hacemos una or de bajo y de alto convertido a long y desplazado 8 bits.
}
Saludos y gracias.
Wolfskin, el montaje de la parte del LDR debe ser:
- Resistencia de pull up entre +Vcc y AN0
- LDR entre AN0 y GND.
No se si ese es el error (descuido más bien) porque no me he mirado con calma el código, pero es posible por lo que cuentas.
S2
Ranganok Schahzaman
Seguramente es lo que dice Ranganok, al conectar la LDR directamente al micro, nunca circula corriente por ella (aunque cambie su valor de resistencia), por tanto el micro nunca verá cambio.
Al poner la resistencia de pull-up a VCC y conectarla a la LDR lo que haces es un divisor de tensión. La LDR variará de valor y la otra será fija, por lo que tienes que tener cuidado con elegir el valor de la resistencia fija. Un valor muy elevado hará que los cambios en la LDR no tengan efecto. Comprueba con el polímetro los valores mínimo y máximo de la LDR (con y sin luz) y elige la resistencia en consequencia.
Por cierto, ya te cansaste de la sky-pic? Ya estas probando cosas por tu cuenta? Como vas de ánimos para montarte un velocista o un rastreador?
Un saludo.
Hay un paso que no acabo de entender.
TRISA = 0b00000001;
PORTA = 0b00000001;
Según creo con trisa configuras el puerto como salida excepto el bit 0 que es entrada, pero luego, con porta, ¿no le estas sacando un 1 por ese bit de esa puerta?
dragonet80, pues ahora estoy montandome una placa para hacer pruebas y mirando todas las funciones de los pics.
Respecto a un restreador o velocista, estoy montandome un mini-hexapodo. ^^