TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: freshdesing en 16 de Julio de 2007, 12:39:41
-
Hola. Ante todo felicitar a los creadores del foro y a los participantes por este foro tan maravillo.
Mi duda es la siguiente:
Utilizo un pic 16F876
PICC
while(1) {
set_adc_channel(0);
delay_ms(1);
temperatura=read_adc();
delay_ms(20);
if(temperatura < 138) { //27ºc
output_bit(PIN_B3,1);
output_bit(PIN_B4,0);
output_bit(PIN_B5,0);}
.....
Tengo como Vref los 5V del pic, no tengo conectado nada a Vref+ ni Vref-. setup_adc_ports(ALL_ANALOG);
Mi problema es que al ponerlo así, los 138 corresponden a la tensión de 2,7V que le llegan por el AN0, pero si en lugar de poner 138 quiero poner los 27ºC que se corresponden con esa tensión ,es decir:
while(1) {
set_adc_channel(0);
delay_ms(1);
lectura_adc = read_adc();
delay_ms(20);
temperatura=(int) ((lectura_adc)*5*10/255);
if(temperatura < 27) {
output_bit(PIN_B3,1);
output_bit(PIN_B4,0);
output_bit(PIN_B5,0);}
....
De esta forma le ADC no funciona, pero el pic tampoco se queda colgado, simplemente no se enciende el led al superar los 27ºC. Es mi primer programa en C, y no veo el fallo. Si me podéis echar una mano, os lo agradecería.
El "enreino" es para controlar la temperatura de un acuario tropical, que ahora en verano se calienta más de la cuenta, y el control de la temperatura actúa sobre una bomba, haciendo recircular el agua del acuario por un barreño de agua con hielo (3ºC aprox). Para evitar poner bloques de hielo dentro del acuario cada 3 horas.
En cuanto tenga los esquemáticos y el código funcionando bien lo subo por si alguien lo quiere.
Un saludo.
-
Haría falta ver tu programa completo para entender cómo tienes declaradas las variables (int o float) porque sospecho que ahí está tu problema.
¿Con el programa en su primera versión funciona?, entonces casi seguro es un problema con el tipo de datos.
-
#include "16F876.h"
#fuses NOLVP,XT,NOWDT,NOPROTECT,PUT
#use delay (clock=4000000)
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#byte port_a = 5
#byte port_b = 6
#byte port_c = 7
#INT_TIMER1
control_timer1()
{
if ( input(PIN_c4)){output_bit(PIN_C4,0);}
else { output_bit(PIN_C4,1);}
}
void main(void) {
int lectura_adc;
int temperatura;
set_tris_a(0x0B); // RA0,RA1 y RA3 como entradas
port_b_pullups(TRUE); // Resistencias de polarización del puerto B
set_tris_b(0xC0); // RB7,RB6,RB2 & RB1 como entradas, RB3:5 & RB0 salidas
set_tris_c(0x00); // Puerto C entero como salida
setup_adc_ports(ALL_ANALOG);
enable_interrupts(GLOBAL);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
delay_us(30); // Tiempo de adquisición
output_bit(PIN_B3,0);
output_bit(PIN_B4,0);
output_bit(PIN_B5,0);
output_bit(PIN_C4,0);
// INICIAR TIMER 1 Y SU INTERRUPCION
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
enable_interrupts (INT_TIMER1);
while(1) {
set_adc_channel(0);
delay_ms(1);
temperatura=read_adc();
delay_ms(20);
temperatura=(int) ((temperatura*5*10/255);
if(temperatura < 27) { //27ºc
output_bit(PIN_B3,1);
output_bit(PIN_B4,0);
output_bit(PIN_B5,0);}
if(temperatura >= 27 & temperatura <= 28) { //27ºc y 28ºc
output_bit(PIN_B3,1);
output_bit(PIN_B4,1);
output_bit(PIN_B5,0);}
if(temperatura > 28) { //28ºc
output_bit(PIN_B3,1);
output_bit(PIN_B4,1);
output_bit(PIN_B5,1);}
}} // fin while
-
Prueba esto, a ver qué tal:
temperatura=(int) ((float)lectura_adc*50.0/255.0);
-
He estado mirando el datasheet porque quería recordar que el convertidor A/D era de 10 bits, y en muchos ejemplos he visto int =read_adc() y no lo entendía....
Me faltaba
#device adc=10
y las variables:
double lectura_adc;
double temperatura;
set_adc_channel(0);
delay_ms(1);
lectura_adc = read_adc();
delay_ms(20);
temperatura=lectura_adc*50.0/1023.0;
if(temperatura < 27) { //27ºc
output_bit(PIN_B3,1);
output_bit(PIN_B4,0);
output_bit(PIN_B5,0);}
if(temperatura >= 27 & temperatura <= 28) { //27ºc y 28ºc
output_bit(PIN_B3,1);
......
y así funciona perfectamente.
Gracias.