Professional Documents
Culture Documents
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.
} 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.
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(); }
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.
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