Problemas con el PIC16F1939 en interrupciones.

Estoy lidiando con este PIC indomable o mi ignorancia (quizas un poco de ambas). Pero en la libreria propuesta por CCS para este pic me salen lo siguiente:
Código:
// Constants used in ENABLE/DISABLE_INTERRUPTS() are:
#define GLOBAL                    0x0BC0
#define PERIPH                    0x0B40
#define INT_RB                    0x31FF0B08
#define INT_EXT_L2H               0x50000B10
#define INT_EXT_H2L               0x60000B10
#define INT_EXT                   0x300B10
#define INT_TIMER0                0x300B20
#define INT_TIMER1                0x309101
#define INT_TIMER2                0x309102
#define INT_CCP1                  0x309104
#define INT_SSP                   0x309108
#define INT_TBE                   0x309110
#define INT_RDA                   0x309120
#define INT_AD                    0x309140
#define INT_TIMER1_GATE            0x309180
#define INT_LCD                   0x309204
#define INT_BUSCOL                0x309208
#define INT_EEPROM                0x309210
#define INT_COMP                  0x309220
#define INT_COMP2                 0x309240
#define INT_OSC_FAIL              0x309280
#define INT_TIMER4                0x309302
#define INT_TIMER6                0x309308
#define INT_CCP3                  0x309310
#define INT_CCP4                  0x309320
#define INT_CCP5                  0x309340
#define INT_CCP2                  0x309201
#define INT_RB0                   0x31010B08
#define INT_RB0_L2H               0x11010B08
#define INT_RB0_H2L               0x21010B08
#define INT_RB1                   0x31020B08
#define INT_RB1_L2H               0x11020B08
#define INT_RB1_H2L               0x21020B08
#define INT_RB2                   0x31040B08
#define INT_RB2_L2H               0x11040B08
#define INT_RB2_H2L               0x21040B08
#define INT_RB3                   0x31080B08
#define INT_RB3_L2H               0x11080B08
#define INT_RB3_H2L               0x21080B08
#define INT_RB4                   0x31100B08
#define INT_RB4_L2H               0x11100B08
#define INT_RB4_H2L               0x21100B08
#define INT_RB5                   0x31200B08
#define INT_RB5_L2H               0x11200B08
#define INT_RB5_H2L               0x21200B08
#define INT_RB6                   0x31400B08
#define INT_RB6_L2H               0x11400B08
#define INT_RB6_H2L               0x21400B08
#define INT_RB7                   0x31800B08
#define INT_RB7_L2H               0x11800B08
#define INT_RB7_H2L               0x21800B08

Disculpen la longitud pero necesito resolver algunas dudas. Se puede observar casi al comienzo de la lista INT_EXT; esta interrupcion se ejecuta cdo hay cambios en RBO, ahora bien mas abajo se puede observar INT_RB0 (o_O) que diferencia existe? Este pic no tiene modos RA y RC?? Además se pueden ver grandes numeros HEXA definidos a cada tipo de interrupción. ¿A que hacen referencia estos valores? (Ejemplo: Con #define INT_RB5 → tiene asociado→ 0x31200B08 )

Para ir terminando comento que he estado probando el siguiente programita:
Código:
#include <16f1939.h>
#fuses noieso, nowdt,NOFCMEN,nostvren, nodebug,NOBROWNOUT,novcap, nowrt,nocpd, noprotect
#define LEDCOMUN PIN_C0
#define LEDINT PIN_C1
#use delay(internal=4MHz)
#INT_EXT

cambio(){
output_toggle(LEDINT);
}
void main()
{
set_TRIS_B(0x01);
output_c(0x00); 
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
while(true){
output_toggle(LEDCOMUN);
delay_ms(500);
}
}

El objetivo es que un led (en RC0) este en intermitente cada medio segundo. Cuando presiono un pulsador asociado al pin RB0 este cambia el estado de un led en RC1 y vuelve al main. En proteus anda excelente pero en la realidad solo parpadea el led del main, la interrupción con el pulsador en pull up por RB0 nunca se manifiesta.

LA PREGUNTA DEL MILLÓN (PARA TODOS LOS QUE TIENEN ESTE PROBLEMA CON EL 1939): ¿ Es la librería, el compilador o que estoy haciendo mal?? ...
 
necesito resolver algunas dudas.
Se puede observar casi al comienzo de la lista INT_EXT; esta interrupcion se ejecuta cuando hay cambios en RB0, ahora bien, mas abajo se puede observar INT_RB0 (o_O) ¿Qué diferencia existe?
INT_EXT Habilita la interrupción por RB0 como comentas.
INT_RB0 El compilador lo toma como una directiva inválida y debe ser un error en la librería.
¿Este PIC no tiene modos RA y RC?
No sé a qué te refieres con eso, pero puedes ver la hoja de datos para enterarte.
Además se pueden ver grandes números HEXA definidos a cada tipo de interrupción.
¿A que hacen referencia estos valores? (Ejemplo: Con #define INT_RB5 → tiene asociado→ 0x31200B08 )
Son las constantes numéricas que el compilador toma como referencia.
Tú entiendes comandos escritos pero el compilador interpreta esos valores como una referencia.
El objetivo es que un LED (en RC0) esté en intermitente cada medio segundo.
Cuando presiono un pulsador asociado al pin RB0, éste cambia el estado de un LED en RC1 y vuelve al main.
En proteus anda excelente pero en la realidad sólo parpadea el LED del main y la interrupción con el pulsador en pull-up por RB0 nunca se manifiesta.
No tengo ese PIC, pero prueba con éstas modificaciones.
Código:
#include <16f1939.h>
#fuses   NOIESO,NOFCMEN,NOBROWNOUT
#use     delay(internal = 4MHz)


#define LEDCOMUN PIN_C0
#define LEDINT PIN_C1


#INT_EXT
void cambio()
{
   output_toggle(LEDINT);
}

void main()
{
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);
   port_b_pullups(0b00000001);   // Sólo habilitar WPUB0 (Resistencia pull-up en RB0)
   ext_int_edge(H_TO_L);         // Generar la interrupción por cambio de estado 1 a 0
   output_low(LEDINT);           // Iniciar con LEDINT en 0
   
   
   while(true)
   {
      output_toggle(LEDCOMUN);
      delay_ms(500);
   }
}
¿Es la librería, el compilador, o qué estoy haciendo mal?
Al parecer, la librería, en cuanto a tener directivas no válidas, pero también es bien sabido que el compilador de CCS sigue teniendo bugs en algunas cosas.
 
Última edición:
Una consulta más. ¿Si no especifico todos los demás NO(FUSE) (el que sea) qué interpretaría el PIC?
Los que el compilador tenga por defecto para el PIC.
Pero depende también la manera de usar #use delay()

Por ejemplo, para el PIC16F1939:
Si escribes; #use delay (clock = 4MHz) sin definir los fuses, el compilador establece los fuses por defecto.
16F1939 Fuses por defecto.jpg

Y si escribes; #use delay (crystal = 4MHz), ahora el compilador sabrá que se usará un cristal de mediana frecuencia y establecerá la configuración _XT_OSC.
16F1939 Fuses con XT_OSC.jpg

Si escribes; #use delay (crystal = 20MHz), ahora el compilador establecerá el fuse _HS_OSC
Y si te fijas ahora, también ha cambiado el fuse _PLLEN_ON por _PLLEN_OFF
Para el oscilador interno; #use delay (internal = 4MHz), también establecería el fuse _FOSC_INTOSC y actuaría también sobre el registro OSCCON para establecer los bits correspondientes, dependiendo de la frecuencia establecida.

Nota:
Los nombres de los fuses los escribí para lenguaje ensamblador para mejor comprensión.

El PIC C Compiler se encarga automáticamente de escribir los fuses sobre las dos locaciones para este PIC.
_CONFIG1 EQU H'8007'
Y
_CONFIG2 EQU H'8008'


Ahora, para determinar los fuses necesarios y no incluir todos, conviene hacer una precompilación de cabecera para saber lo que el compilador establece y después leerlos con algún programador, por ejemplo, WinPic800, para así determinar cuales debemos usar y cuales no, o cuales modificar y cuales no.
También es conveniente leer el archivo *.inc de Microchip correspondiente al tipo de PIC a usar, porque ahí está explicado el funcionamiento de cada fuse y muchas cosas más.

Suerte.
 
Atrás
Arriba