Autor Tema: Problema con INT0 H_T_L, entra sin pulsar  (Leído 2431 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado kain589

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 324
Problema con INT0 H_T_L, entra sin pulsar
« en: 25 de Diciembre de 2011, 09:25:45 »
Hola, he vuelto a los pics despues de un tiempo sin programar, y mas o menos la cosa va bien, aunque hoy me ha surgido un problema y no se si es fallo de mi logica programando o que se me pasa algo de la arquitectura del pic que no me acuerdo. El programa usa un LCD y un pulsador que se conecta a RB0 y que se usa para contar las pulsaciones a traves de la rutina de la interrupcion.
El problema es que cuando inicio el PIC me entra en la rutina de interrupcion sin pulsar una sola vez; uso la protoboard podria ser por rebotes, pero si hago un reset me pasa lo mismo me empieza contando en 1 en lugar de en 0

Código: C
  1. //Uso lcd y pulsador
  2.  
  3. #include <18F2550.h>
  4. #fuses HS,NOWDT,NOPROTECT,NOLVP,NODEBUG,NOUSBDIV,VREGEN
  5. #use delay(clock=4000000)
  6.  
  7. //Pines para lcd_flex
  8. #define LCD_DB4   PIN_B4
  9. #define LCD_DB5   PIN_B5
  10. #define LCD_DB6   PIN_B6
  11. #define LCD_DB7   PIN_B7
  12.  
  13. #define LCD_RS    PIN_C0
  14. #define LCD_RW    PIN_C1
  15. #define LCD_E     PIN_C2
  16.  
  17. #include "flex_lcd.c"
  18.  
  19. int8 interrupcion=0;
  20.  
  21. ///LLAMADA FUNCION INTERRUPCION
  22. #INT_EXT
  23. void IntRB0()
  24. {  interrupcion++;
  25.    if(interrupcion>9){               //9?
  26.       interrupcion=0;//Resetea
  27.    }
  28.    lcd_putc('\f');   //borra lcd
  29.    lcd_gotoxy(1,1);
  30.    printf(lcd_putc,"Esperando interrupcion \n");   //muestra por pantalla el mensaje
  31.    delay_ms(10);
  32.    printf(lcd_putc,"Interrupcion:%u",interrupcion);
  33.    delay_ms(200);//Evitar rebotes
  34. }
  35.  
  36. void main()
  37. {
  38.    setup_adc_ports(NO_ANALOGS|VSS_VDD);
  39.    setup_adc(ADC_OFF);
  40.    setup_spi(SPI_SS_DISABLED);
  41.    setup_wdt(WDT_OFF);
  42.    setup_timer_0(RTCC_INTERNAL);
  43.    setup_timer_1(T1_DISABLED);
  44.    setup_timer_2(T2_DISABLED,0,1);
  45.    setup_comparator(NC_NC_NC_NC);
  46.    setup_vref(FALSE);
  47. ///PROGRAMA
  48.    interrupcion=0;
  49.    lcd_init();         //inicializa lcd
  50.    lcd_putc('\f');     //borra lcd
  51. //Mensaje de inicio y conteo interrupciones  
  52.    printf(lcd_putc,"Esperando interrupcion \n");   //muestra por pantalla el mensaje
  53.    delay_ms(10);
  54.    printf(lcd_putc,"Interrupcion:%u",interrupcion);
  55.    delay_ms(1000);//Evitar rebotes
  56. //Activamos interrupciones e interrupcion externa en rb0
  57. //SE hace despues de usar el lcd para evitar rebotes al conectar la corriente
  58.    enable_interrupts(int_ext);      //activar interrupcion externa
  59.    ext_int_edge(H_TO_L);         //configuracion:interrupcion cuando señal esta en alta
  60.    enable_interrupts(GLOBAL);      //todas las interrupciones activadas
  61.       while(1)
  62.       {
  63.       }
  64. }

¿Alguna idea de por que me puede pasar? Para solucionarlo he hecho este otro programa, en el que uso una variable auxiliar, que soluciona el problema, aunque me gustaria saber por que falla

Código: C
  1. #include <18F2550.h>
  2. #fuses HS,NOWDT,NOPROTECT,NOLVP,NODEBUG,NOUSBDIV,VREGEN
  3. #use delay(clock=4000000)
  4.  
  5. //Pines para lcd_flex
  6. #define LCD_DB4   PIN_B4
  7. #define LCD_DB5   PIN_B5
  8. #define LCD_DB6   PIN_B6
  9. #define LCD_DB7   PIN_B7
  10.  
  11. #define LCD_RS    PIN_C0
  12. #define LCD_RW    PIN_C1
  13. #define LCD_E     PIN_C2
  14.  
  15. #include "flex_lcd.c"
  16.  
  17. int8 interrupcion=0;
  18. int1 primer;
  19.  
  20. ///LLAMADA FUNCION INTERRUPCION
  21. #INT_EXT
  22. void IntRB0()
  23. {  if(primer==0){
  24.       primer=1;
  25.    }else{
  26.       interrupcion++;
  27.       if(interrupcion>9){               //9?
  28.          interrupcion=0;//Resetea
  29.       }
  30.       lcd_putc('\f');   //borra lcd
  31.       lcd_gotoxy(1,1);
  32.       printf(lcd_putc,"Esperando interrupcion \n");   //muestra por pantalla el mensaje
  33.       delay_ms(10);
  34.       printf(lcd_putc,"Interrupcion:%u",interrupcion);
  35.       delay_ms(200);//Evitar rebotes
  36.    }
  37. }
  38.  
  39. void main()
  40. {
  41.    setup_adc_ports(NO_ANALOGS|VSS_VDD);
  42.    setup_adc(ADC_OFF);
  43.    setup_spi(SPI_SS_DISABLED);
  44.    setup_wdt(WDT_OFF);
  45.    setup_timer_0(RTCC_INTERNAL);
  46.    setup_timer_1(T1_DISABLED);
  47.    setup_timer_2(T2_DISABLED,0,1);
  48.    setup_comparator(NC_NC_NC_NC);
  49.    setup_vref(FALSE);
  50. ///PROGRAMA
  51.    primer=0;
  52.    interrupcion=0;
  53.    lcd_init();         //inicializa lcd
  54.    lcd_putc('\f');     //borra lcd
  55. //Mensaje de inicio y conteo interrupciones  
  56.    printf(lcd_putc,"Esperando interrupcion \n");   //muestra por pantalla el mensaje
  57.    delay_ms(10);
  58.    printf(lcd_putc,"Interrupcion:%u",interrupcion);
  59.    delay_ms(1000);//Evitar rebotes
  60. //Activamos interrupciones e interrupcion externa en rb0
  61. //SE hace despues de usar el lcd para evitar rebotes al conectar la corriente
  62.    enable_interrupts(int_ext);      //activar interrupcion externa
  63.    ext_int_edge(H_TO_L);         //configuracion:interrupcion cuando señal esta en alta
  64.    enable_interrupts(GLOBAL);      //todas las interrupciones activadas
  65.       while(1)
  66.       {
  67.       }
  68. }

Y ya aprovecho para preguntar ¿como se puede hacer que un mensaje rote a traves del LCD para que salga entero? lo tipico de los mp3 que el mensaje se desplaza para ver toda la informacion
« Última modificación: 25 de Diciembre de 2011, 09:28:09 por kain589 »
Saludos desde Córdoba, españa

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Problema con INT0 H_T_L, entra sin pulsar
« Respuesta #1 en: 25 de Diciembre de 2011, 15:15:30 »
Hola.

Lo mejor en el manejo de interrupciones es no demorarse en ellas. Esos printf toman mucho tiempo, y pueden generar malos funcionamientos en el resto del programa. Borra el flag antes de activar la interrupción para que inicie donde quieres.

Saludos
El papel lo aguanta todo

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Problema con INT0 H_T_L, entra sin pulsar
« Respuesta #2 en: 25 de Diciembre de 2011, 16:57:27 »
hola, adicional a lo que recomienda MLO_ , el fuse para cristal de 4mhz es XT.
Con respecto a la rotacion, creo que el lcd tiene una instruccion para ello pero la libreria en c no la implementa, podrias intentar hacer un bucle que imprima cada cierto tiempo y vaya incrementado la posicion del cursor en el lcd
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Problema con INT0 H_T_L, entra sin pulsar
« Respuesta #3 en: 25 de Diciembre de 2011, 17:09:58 »
Que despistado estoy  :D  no leí lo de la marquesina   :shock:

Algo así?


Lo que hago es cagar todo el mensaje en un string y roto el string con un for .... la función de desplazar de la LCD mueve las dos líneas.

Saludos

PD// No encuentro el hilo en donde postee el código
El papel lo aguanta todo

Desconectado kain589

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 324
Re: Problema con INT0 H_T_L, entra sin pulsar
« Respuesta #4 en: 25 de Diciembre de 2011, 17:29:58 »
Muchas gracias a todos por las respuesta.

- La verdad que lo del flag no se me habia ocurrido ahora lo hare a ver que pasa.

- Lo del cristal es verdad, fallo mio

- Se que no se deben demorar tanto las interrupciones, pero me gusta hacer programas que funcionen por interrupciones, esto son pruebas pero de cara a diseños practicos para disminuir el consumo.

- Y lo del string, a falta de una funcion especifica, a mi tb es la solucion que se me ocurre; ya con tiempo mirare para implementarla
Saludos desde Córdoba, españa

Desconectado kain589

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 324
Re: Problema con INT0 H_T_L, entra sin pulsar
« Respuesta #5 en: 26 de Diciembre de 2011, 09:23:01 »
Pues hoy he vuelto a hacer la prueba, he arreglado lo del cristal y aacedo al registro INTCON para borrar la bandera INT0IF, mediante las instrucciones:

Código: C
  1. #byte INTCON = 0xFF2 //Accede directo al registro INTCON para borrar bandera
  2. .......................
  3. bit_clear(INTCON,1); //Borra bandera de la interrupcion

Y asi funciona, muchas gracias a todos por la ayuda
Saludos desde Córdoba, españa

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Problema con INT0 H_T_L, entra sin pulsar
« Respuesta #6 en: 26 de Diciembre de 2011, 11:29:25 »
 ;-)

Que bueno que funcionara

Saludos
El papel lo aguanta todo