You are on page 1of 8

CONTROL DE UNA INCUBADORA

karpic: Resulta que tengo el siguiente cdigo, pretende ser el control de una incubadora y resulta que cuando desactivo las resistencias pull-up para el puerto B deja de funcionar la pantalla LCD y si las activo lo que no me funciona es el control dimmer, esto lo hago en el proteus y no se si esta mal el cdigo o puede ser fallo del proteus. #include <16F876.h> #include <internal_eeprom.c> #use delay(clock=4000000) #fuses XT,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOCPD,NOWRT,NODEBUG #define use_portb_lcd TRUE #include "flex_lcd_.c" #include <sht11.h> int16 contador; //************ variables dimmer **************************** int pasada2=0; long int muestra2=0; int j=0; int contadora2=1; int intervalador2=1; int auxiliar2=0; //********************************************************** //******************** dimmer ****************************** // Interrupcin del TIMER1, encargado de calcular el tiempo de un semiciclo constantemente.

#INT_TIMER1 void temporizador() { set_timer1(0); }


// Interrupcin del TIMER0, provoca el retardo deseado antes de la excitacin

#INT_timer0 void tempo() { output_high(PIN_C4); // Ha transcurrido el tiempo, activo la salida }


// Interrupcin Externa, provocada por el paso por 0V de la seal de entrada

#INT_EXT void externa() { if (j==0){ output_high(PIN_B1); j=1; ext_int_edge(H_TO_L);

// Cambio la deteccin del flanco, // para que la proxima sea de bajada

} else { output_low(PIN_B1); j=0; ext_int_edge(L_TO_H); // La prxima interrupcin ser de subida } if (pasada2==0){ enable_interrupts(INT_TIMER1);

// Activo la cuenta

set_timer1(0); // Comenzando desde cero pasada2=1; } else if (pasada2==1){ muestra2=get_timer1(); // Tiempo medido entre dos pasos por 0 sucesivos set_timer1(0); // Inicio el Timer1 para una nueva cuenta intervalador2=(muestra2/8); // Equiparo los preescaler, y por tanto las unidades
// de tiempo de TIMER1 y timer0.

// 8 unidades de TIMER1 equivalen a 1 de timer0 auxiliar2=(intervalador2/4); // Divido el tiempo de un semiciclo en 4


//(por ejemplo).

intervalador2=256-auxiliar2; // Este es el valor final a cargar el timer0, //con esto retardo la seal 1/4 de su semiperido enable_interrupts(INT_timer0); //set_timer0(intervalador); set_timer0(200); output_low(PIN_C4); // Pongo a 0 la salida, y comienza el retardo } } //********************************************************************* // Interrupcin del TIMER2, encargado de calcular el // tiempo de un semiciclo constantemente. #INT_TIMER2 void INTERRUPTION() { contador ++; set_timer2(0); } //#byte port_c=0x07 //****************************************************************************** // input(pin_C0) Pulsador de menu y ok // input(pin_C1) Pulsador de flecha abajo (mas) // input(pin_C2) Pulsador de flecha arriba (menos) //****************************************************************************** short actualizar; typedef union { int16 i; float f; } valor; valor humedad, temperatura; byte errorsht11,checksum; unsigned test=1;//, i; int8 testado; float T, H; int16 X, Y, V, X1; // RUTINA SONDA void sonda(){ errorsht11=0; errorsht11+=sht11_medicion((byte*)&humedad.i, &checksum,HUMI); //measure humidity errorsht11+=sht11_medicion((byte*) &temperatura.i, &checksum, TEMP); //measure temperature if(errorsht11!=0) //in case of an error: connection reset { printf(lcd_putc,"\n\rerror:%U", errorsht11); sht11_hard_reset(); }

else { humedad.f=(float)humedad.i; //converts integer to float temperatura.f=(float)temperatura.i; //converts integer to float sht11_calculos(&humedad.f, &temperatura.f); //calculate humidity, temperature } //lcd_gotoxy(1,1); //printf(lcd_putc," Temp. Humedad"); //lcd_gotoxy(0,2); //printf(lcd_putc," %2.2f",temperatura.f); if (temperatura.f < (read_float_eeprom(1))) output_high(pin_A0); if (temperatura.f > (read_float_eeprom(1))) output_low(pin_A0); if (humedad.f < (read_float_eeprom(10)-1)) output_high(pin_A1); if (humedad.f > (read_float_eeprom(10)+1)) output_low(pin_A1); lcd_send_byte(1,0b11011111); //printf(lcd_putc,"C %2.2f%%HR",humedad.f); actualizar=true; delay_ms(100); } // RUTINA MENU PRINCIPAL void menus() { switch(testado){ case 1: lcd_putc("\f"); lcd_gotoxy(1,1); lcd_putc("1 Temperatura"); break; case 2: lcd_putc("\f"); lcd_gotoxy(1,1); lcd_putc("2 Humedad"); break; case 3: lcd_putc("\f"); lcd_gotoxy(1,1); lcd_putc("3 Volteo"); break; case 4: lcd_putc("\f"); lcd_gotoxy(1,1); lcd_putc("4 Salir"); break; } } // RUTINA MENU SECUNDARIO void menus2() { switch (testado){ case 1: delay_ms(100); T=read_float_eeprom(1); lcd_putc("\f"); lcd_gotoxy(1,1); lcd_putc("Set Grados "); lcd_putc(223);

//for(i=200;i!=255;i++) //{ //lcd_gotoxy(1,1); //lcd_putc(i); //printf(lcd_putc,"%u",i); //delay_ms(1000); //}; lcd_putc("C"); lcd_gotoxy(5,2); printf(lcd_putc,"%1.1f",T); while(input(pin_C0)) { delay_ms(50); if (!input(pin_C1)) //veo si se presiono xxxxx { delay_ms(50); while (!input(pin_C1)); //si es asi, espero a que se libere T=T+0.10; if (T>40) T=15.00; lcd_gotoxy(5,2); printf(lcd_putc,"%1.1f",T); } if (!input(pin_C2)) //veo si se presiono xxxxx { delay_ms(50); while (!input(pin_C2)); //si es asi, espero a que se libere T=T-0.10; if (T<15) T=40.00; lcd_gotoxy(5,2); printf(lcd_putc,"%1.1f",T); } } while (!input(pin_C0)); write_float_eeprom(1,T); break; case 2: delay_ms(100); H=read_float_eeprom(10); lcd_putc("\f"); lcd_gotoxy(1,1); lcd_putc("Set Humedad %"); lcd_gotoxy(5,2); printf(lcd_putc,"%1.1f",H); while(input(pin_C0)) { delay_ms(50); if (!input(pin_C1)) //veo si se presiono xxxxx { delay_ms(50); while (!input(pin_C1)); //si es asi, espero a que se libere H=H+0.10; if (H>90) H=20.00; lcd_gotoxy(5,2); printf(lcd_putc,"%1.1f",H); } if (!input(pin_C2)) //veo si se presiono xxxxx { delay_ms(50); while (!input(pin_C2)); //si es asi, espero a que se libere

H=H-0.10; if (H<20) H=90.00; lcd_gotoxy(5,2); printf(lcd_putc,"%1.1f",H); } } while (!input(pin_C0)); write_float_eeprom(10,H); break; case 3: delay_ms(100); V=read_eeprom(20); lcd_putc("\f"); lcd_gotoxy(1,1); lcd_putc("Set Volteo minu-"); lcd_gotoxy(1,2); lcd_putc("tos"); lcd_gotoxy(5,2); printf(lcd_putc,"%3lu",V); while(input(pin_C0)) { delay_ms(50); if (!input(pin_C1)) //veo si se presiono xxxxx { delay_ms(50); while (!input(pin_C1)); //si es asi, espero a que se libere V++; if (V>120) V=0; lcd_gotoxy(5,2); printf(lcd_putc,"%3lu",V); } if (!input(pin_C2)) //veo si se presiono xxxxx { delay_ms(50); while (!input(pin_C2)); //si es asi, espero a que se libere V--; if (V==-1) V=120; if (V<0) V=120; lcd_gotoxy(5,2); printf(lcd_putc,"%3lu",V); } } while (!input(pin_C0)); write_eeprom(20,V); contador = 0; break; case 4: test=0; break; } } // RUTINA PULSADOR void pulsador() { menus(); delay_ms(100); while(input(pin_C0)) { delay_ms(50);

if (!input(pin_C1)) { delay_ms(50); while (!input(pin_C1)); testado++; if(testado>4){testado=1;} menus(); } if (!input(pin_C2)) { delay_ms(50); while (!input(pin_C2)); testado--; if(testado==0){testado=4;} menus(); } } while (!input(pin_C0)); menus2(); //pulsador(); }

//veo si se presiono xxxxx

//si es asi, espero a que se libere

//veo si se presiono xxxxx

//si es asi, espero a que se libere

void main() { //****************************************************************************** setup_timer_2(T2_DIV_BY_16,255,16); set_timer2(0); setup_timer_1(T1_INTERNAL | T1_DIV_BY_8); setup_timer_0(RTCC_INTERNAL | RTCC_DIV_64); // Programacion timer0 ENABLE_INTERRUPTS(GLOBAL); // Habilita todas las interrupciones. ENABLE_INTERRUPTS(INT_TIMER2); ENABLE_INTERRUPTS(INT_EXT); ENABLE_INTERRUPTS(INT_RTCC); // Habilita interrupcion timer0. ENABLE_INTERRUPTS(INT_TIMER1); //****************************************************************************** ext_int_edge(L_TO_H); // port_b_pullups(true); setup_adc_ports(NO_ANALOGS); actualizar=true; lcd_init(); sht11_hard_reset();; testado=1; while(true) { V=read_eeprom(20); X1=V*10; X=1*X1; Y=2*X1; if(contador > X){ OUTPUT_HIGH(PIN_A2); } if(contador > Y){ OUTPUT_LOW(PIN_A2); contador = 0; } //lcd_gotoxy(0,2); //printf(lcd_putc,"%5lu",contador);

//printf(lcd_putc,"%4lu",X); //printf(lcd_putc,"%4lu",Y); //SET_RTCC(131);// RESET_RTCC; if (actualizar) { sonda(); lcd_gotoxy(1,1); printf(lcd_putc," Temp. Humedad"); lcd_gotoxy(0,2); printf(lcd_putc," %2.2f",temperatura.f); printf(lcd_putc,"C %2.2f%%HR",humedad.f); } if (!input(pin_C0)) { delay_ms(50); while (test){pulsador();} } test=1; testado=1; } }
Marttyn: Uy, karpic, creo que es mucho cdigo para que alguien se interese en leerlo por las buenas! Intenta poner solo la parte del cdigo afectado, porque realmente me gustara ayudarte, pero no tengo el tiempo (ni las ganas) de leer e interpretar tanto texto. Salu2 karpic: Gracias por tu sugerencia, pero no se realmente donde puede estar el problema. Por el puerto B controlo una LCD menos el pin RB0 que lo utilizo como interrupcin externa para detectar el paso por cero de la seal para control del dimmer. Como he dicho antes el problema es que al activar las resistencias pull-up del puerto B deja de funcionar la interrupcin externa y si las desactivo lo que no me funciona es la pantalla LCD. RedPic: La flex_lcd.c lleva unos defines en los que declaras qu pines son los que vas a utilizar para controlar el LCD, debes comprobar que no estn en conflicto con el resto de pines de los que haces uso en tu programa. Tambin y por otro lado debes tener claro qu ocurre cuando activas las pull-up y si realmente es lo que necesitas. Ten en cuenta primero que las pull-up conectan los pines del puerto b directamente a Vcc (a 5V), todos los pines y no solo uno de ellos. Segundo, debes usar las pull-ups para pines que sean de entrada. Para pines de salida es una incongruencia utilizarlas. Y solo se utilizan cuando lo externo que conectamos a ellos funcionan enviando la seal tirndola a masa, de forma que si estn inactivos devuelven, "leen", un 1 y cuando se activan, dan un pulso, devuelven, "leen", un 0. Si activas una pull-up para una entrada que enva un pulso positivo leers siempre un 1, cuando est en reposo ya que la pull-up est conectada a Vcc y cuando est activo ya que ste tambin enva una conexin a Vcc. Ve investigando todo esto en tu aplicacin y nos cuentas. karpic: Pues acabo de montar el circuito cargado con el programa que tenia las pull-up desactivadas, o sea en el que no funcionaba el lcd en el simulador, y cual ha sido mi sorpresa que es que funciona perfectamente, esto me hace pensar que el proteus no simula correctamente esta situacin, ahora solo me queda probar la parte del dimmer.

RESISTENCIAS PULL-UP Y RESISTENCIAS EXTERNAS A LOS PUERTOS PIC


FOXBATSK: Me podran explicar en si como funcionan las resistencias Pull-up y que utilidad tienen tenerlas activadas o desactivadas en un pic. Tambin, he ledo que se recomienda poner una resistencia de 10k a Vcc a un puerto cuando no se usa, pero, a este puerto lo debo de poner como entrada o salida?

RaDoN:
Las resistencias pull-up (a Vcc) o pull-down (a GND, masa...) solo son tiles cuando el puerto (sean internas o externas es igual) acta como entrada. Lo que hace es asegurar un estado en la puerta cuando no le llega ninguna seal, en caso de pull-up un 1, y el pull-down lo contrario, un 0. Pero a la vez estos estados son "flexibles", me explico, si en una pull-down (recuerda un 1 lgico) aparece en la entrada un 1 este prevalece al que tiene la resistencia. Espero haberme explicado, la gama 16f tiene las resistencias en el puerto B, de ello que se use en las aplicaciones para entradas y no tener que usar externas, adems como posee interrupciones por cambio de estado, lo hace mas ideal para usar este puerto como entrada. Por cierto, si necesitas usar externas, estas son del orden de 4k7 a 10k

LAS RESISTENCIAS DE PULL-UP


Una de las cualidades que distinguen a los microcontroladores de los microprocesadores es que encierran en un solo chip todos los elementos posibles de un sistema de control. Con este fin los AVR incorporan en todos sus puertos transistores a manera de fuente de corriente que en la prctica funcionan como resistencias de pull-up. Estas pull-ups nos pueden ahorrar el uso resistencias de sujecin externas en los pines de los puertos configurados como entradas. Las pull-ups se podran equiparar con resistencias de entre 20 K y 50 K. a partir de dichos valores podemos calcular la corriente que puede fluir por ellas si estn activadas. Las pull-ups se pueden habilitar pin por pin independientemente escribiendo un 1 en su registro de salida PORT. Las-pull ups solo sern efectivas en los pines que actan como entradas; en los pines configurados como salidas las pull-ups quedan automticamente deshabilitadas. Existe un bit llamado PUD en el registro MCUCR cuya funcin es deshabilitar todas las pull-ups de todos los puertos si su valor es 1. El bit PUD (Pull-Ups Disable) inicializa a 0 y un posible inters por setearlo puede ser eliminar la pequea corriente que puede fluir por las pull-ps cuando los pines en cuestin se conectan a 0 lgico. La siguiente figura muestra la conexin de un pulsador al AVR aprovechando la pull-up de un pin de E/S. Fjate en que las pull-ups no se pueden usar como resistencias para excitar dispositivos como LEDs, rels, etc. Ejemplo de uso de las resistencias de pull-up. La figura de ejemplo muestra la pull-up de un solo pin pero estn presentes en todos los pines de E/S del AVR.

You might also like