Autor Tema: Problema interrupcion  (Leído 2334 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado horty69

  • PIC10
  • *
  • Mensajes: 17
Problema interrupcion
« en: 07 de Junio de 2015, 14:39:24 »
Bueno pues estoy haciendo un programa sencillo para familiarizarme con las interrupciones y al simularlo en Proteus no me funciona.
He probado varias cosas pero no hay manera, haber si alguien puede encontrar el fallo porque yo no lo consigo ver

Código: C
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <pic16f886.h>
  4. #include <xc.h> //librería del compilador de C XC8
  5. /* Estas dos definiciones están como macros desde customice en XC8 compiler */
  6. #define _XTAL_FREQ 4000000  // necesario para macros __delay_ms()
  7. #define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
  8.  
  9. #pragma config FOSC = XT// Oscillator Selection bits (INTOSC oscillator: CLKOUT function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
  10. #pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
  11. #pragma config PWRTE = ON      // Power-up Timer Enable bit (PWRT disabled)
  12. #pragma config MCLRE = OFF       // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR)
  13. #pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
  14. #pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
  15. #pragma config BOREN = ON       // Brown Out Reset Selection bits (BOR enabled)
  16. #pragma config IESO = OFF       // Internal External Switchover bit (Internal/External Switchover mode is disabled)
  17. #pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
  18. #pragma config LVP = OFF        // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)
  19.  
  20. // CONFIG2
  21. #pragma config BOR4V = BOR40V   // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
  22. #pragma config WRT = OFF        // Flash Program Memory Self Write Enable bits (Write protection off)
  23.  
  24. void main()
  25. {
  26.    
  27.     ANSEL =0X00 ; //Deshabilitar ADC
  28.     ANSELH =0X00 ; //Deshabilitar ADC
  29.     TRISB = 0xF0 ; // Configurar puerto B como entradas/salidas;
  30.     TRISC = 0XF0 ; // Configurar puerto C como salidas;
  31.     PORTB = 0X00 ; // Poner las salidas a cero;
  32.     PORTC = 0X00;
  33.     TRISA = 0X00 ; // Configurar puerto A como salidas;
  34.     PORTA= 0X00;
  35.  
  36.     INTCON=0;
  37.     OPTION_REGbits.nRBPU=0;
  38.     INTCONbits.RBIE=1;
  39.     INTCONbits.RBIF=0;
  40.     INTCONbits.GIE=1;
  41.  
  42.     while(1){
  43.         PORTCbits.RC2=1;
  44.         __delay_ms(300);
  45.         PORTCbits.RC2=0;
  46.         __delay_ms(300);
  47.     }
  48. }
  49. void interrupt pinb ()
  50. {
  51.  
  52.     if(INTCONbits.RBIF==1)
  53.     {
  54.         //PORTCbits.RC3=1;
  55.         PORTBbits.RB3=1;
  56.     __delay_ms(200);
  57.     }
  58.  
  59.     INTCONbits.RBIF=0;
  60.     __delay_ms(10);
  61.  
  62. }

Lo programo con el MPLABX y lo compilo con el XC8
Muchas gracias de antemano

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Problema interrupcion
« Respuesta #1 en: 07 de Junio de 2015, 20:47:17 »
Un consejo, nunca pongas delays dentro de rutinas de interrupcion.

Por el otro lado te faltaron configurar registros.
El PIC16F886 permite seleccionar que pin es el activado por una interrupcion al cambio.
Eso se hace con el registro:
IOCB: INTERRUPT-ON-CHANGE PORTB REGISTER

Otro cosa mas que el Pull-UP es tambien individual y se hace con el registro:
WPUB: WEAK PULL-UP PORTB REGISTER

Una cosa a recordar cuando usas la interrupcion por cambio del portB, es que antes de limpiar el flag de interrupcion debes leer el puertoB asi te permite limpiar el flag, sino queda en 1 y aparecen los problemas de que queda encerrado en la interrupcion.
Para saber todos los registros que te afectan al puerto, te vas al datasheet buscas I/O Ports -> PORT B, ahi explica todo e incluso uno por uno los registros, pero si queres ver cuales son todos, te vas al final de la seccion del PORTB y aparecen todos los registros y bits.

Desconectado horty69

  • PIC10
  • *
  • Mensajes: 17
Re: Problema interrupcion
« Respuesta #2 en: 08 de Junio de 2015, 09:52:32 »
Muchas gracias con tus indicaciones he solucionado el problema.
Ahora tengo una pregunta, si en vez de activar un pin del puertoC, desde la interrupcion llamo a una función, ¿esta funcionaria?
Lo he estado probando un poco por encima y no me funciona dicha interrupcion.
Muchas gracias

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Problema interrupcion
« Respuesta #3 en: 08 de Junio de 2015, 12:59:21 »
Si, deberia funcionar. Algo bastante simple seria encender y apagar un led en esa otra funcion.

Código: C
  1. void interrupt pinb ()
  2. {
  3. int basura;
  4.    
  5.      if(INTCONbits.RBIF==1)
  6.     {
  7.         otra_funcion();
  8.         basura=PORTB;
  9.         INTCONbits.RBIF=0;
  10.     }
  11. }
  12.  
  13. void otra_funcion() {
  14.         PORTCbits.RC3^=1;
  15. }

Desconectado horty69

  • PIC10
  • *
  • Mensajes: 17
Re: Problema interrupcion
« Respuesta #4 en: 08 de Junio de 2015, 19:31:57 »
Tengo otra pregunta y es que estoy haciendo un programa un poco extenso y me da unos problemas que no entiendo a que se deben.
El programa compila pero me da un warning que nose porque es:
Código: C
  1. matematicas.c:106: warning: (1393) possible hardware stack overflow detected, estimated stack depth: 10

Si voy a donde me dice el warning es donde empiezo a declarar todos los registros

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Problema interrupcion
« Respuesta #5 en: 08 de Junio de 2015, 22:07:45 »
No creo que logres llamar a 10 funciones , una dentro de otra. o tal ves use algunos if como CALL.

Basicamente tenes un stack donde cuando vos haces un CALL ( instruccion en ASM ) este guarda la direccion desde donde se llamo y luego con un RETURN vuelve.

Serial algo parecido en C a esto:

void funcion1(){
    funcion2();
    // Apagar led
}

void funcion2(){
   //Encender led
}

es decir desde la funcion 1 se llama a la funcion 2 y cuando termina vuelve a funcion1. Eso se produce con un CALL/RETURN normalmente, si tenes muchas anidadas puede que ocurra eso, pero 10 me parece una locura.


Eso si se refiere como HW stack a justamente lo que digo, no creo que se refiera a la RAM. Y que no posea suficiente lugar para pasar los parametros a una funcion. En la que C cree un stack en la RAM. Pero bueno eso vas a tener que simularlo/debuggearlo y ver el HW stack ( esta en la solapa de Program Memory)