Bueno, no tarde mucho en darme cuenta de que era un problema de la bandera de interrupción, aunque franky tiene razon sobre que algunos modos de ahorro no son simulables, el modo sleep puede ser simulable, aca les dejo mi rutina, la cual solo sirve para verificar el funcionamiento correcto del modo Sleep(), encender y apagar un led, use una interrupcion por timer0 para verificar que entra en modo sleep y no interrumpe, use otra por timer1 con clock externo que es el que sigue trabajando en los modos de ahorro de energía para despertar el micro del modo sleep, la rutina funciona muy bien, para la configuracion de los timers y del modo sleep use librerias del C18 pero de igual manera esta la opcion de configurar los registros, ambas funcionan bien, pero en definitiva configurar los registros deja más claras las cosas, el oscilador interno tambien esta disponible en modo sleep que es a lo que se referia franky, pero es cierto que en la simulacion el proteus detiene el oscilador interno por lo que no puede verificarse el funcionamiento.
Para la simulacion con clock externo de timer1 o timer1 como oscilador secundario en el proteus se pone un generador de pulsos de reloj en el pin RC1/T1OSI, aunque en la hoja de datos aparece un crystal, eso es algo que me detuvo un poco.
Espero que esto le sirva a alguien.
#include<p18cxxx.h>
#include<timers.h>
#include<delays.h>
#pragma config OSC = HS, FCMEN = ON, IESO = OFF
#pragma config PWRT = OFF,BOREN = OFF, BORV = 0
#pragma config WDT = OFF,WDTPS = 32768
#pragma config MODE = MC, ADDRBW = ADDR20BIT, DATABW = DATA16BIT, WAIT = OFF
#pragma config MCLRE = ON,LPT1OSC = ON, ECCPMX = PORTE, CCP2MX = PORTC
#pragma config STVREN = ON,LVP = OFF,XINST = OFF,BBSIZ = BB2K, DEBUG = ON
#pragma config CP0 = OFF,CP1 = OFF,CP2 = OFF
#pragma config CPB = OFF,CPD = OFF
#pragma config WRT0 = ON,WRT1 = ON,WRT2 = OFF,WRT3 = OFF
#pragma config WRTB = OFF,WRTC = OFF,WRTD = OFF
#pragma config EBTR0 = OFF,EBTR1 = OFF,EBTR2 = OFF,EBTR3 = OFF
#pragma config EBTRB = OFF
void ISRTimer1(void);
void ISRTimer0(void);
void Timer1_Inicio(void);
void Sleep_mode(void);
/*#pragma code Interrupcion0 = 0x0008
void VectorInterrupcion0(void){
_asm goto ISRTimer0 _endasm
}
#pragma code*/
#pragma code Interrupcion1 = 0x0008
void VectorInterrupcion1(void){
_asm goto ISRTimer1 _endasm
}
#pragma code
#pragma interrupt ISRTimer0 //rutina de interrupcion timer0
void ISRTimer0(void){
if(INTCONbits.TMR0IF==1){
WriteTimer0(3036);
PORTBbits.RB0=0;
Delay10KTCYx(10);
INTCONbits.TMR0IF=0;
}
}
#pragma interrupt ISRTimer1 //rutina de interrupcion timer1
void ISRTimer1(void){
if(PIR1bits.TMR1IF==1){
//WriteTimer1(0);
TMR1H=0b10000000;
PORTBbits.RB0=0;
Delay10KTCYx(10);
PIR1bits.TMR1IF=0;
}
}
void main(void){
//OpenTimer0(TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_16);
//OpenTimer1(TIMER_INT_ON & T1_16BIT_RW & T1_SOURCE_EXT & T1_PS_1_2 & T1_OSC1EN_ON & T1_SYNC_EXT_ON);
Timer1_Inicio(); //función de configuracion de timer 1
RCONbits.IPEN=0; //deshabilita priordades en interrupciones
INTCONbits.PEIE=1; //habilita interrupciones por perifericos.
INTCONbits.GIE=1; //habilita interrupciones globales.
TRISB=0x00; //portb como salida
PORTB=0x00;
//WriteTimer0(3036); //precarga del timer 0
//WriteTimer1(0); //precarga del timer 1 por libreria timers.h
while(1){
PORTBbits.RB0=1;
Sleep(); //macro sleep
//Sleep_mode(); //configuracion de modos de ahorro(no simulable
} //a menos que sea modo Sleep).
}
void Timer1_Inicio(void)
{
PIR1bits.TMR1IF = 0; //limpiar bandera de interrupción
PIE1bits.TMR1IE = 1; //habilitar interrupción por timer 1
//T1CON=0b00001110; //configuracion del timer 1
T1CONbits.RD16=0; //16 u 8 bits
T1CONbits.T1RUN=1; //oscilador run
T1CONbits.T1CKPS1=0; //configuracion del preescales(2)
T1CONbits.T1CKPS0=1;
T1CONbits.T1OSCEN=1; //oscilador enabled
T1CONbits.T1SYNC=0; //no sincronizar
T1CONbits.TMR1CS=1; //external clock
T1CONbits.TMR1ON=0; //Stop timer 1
TMR1H=0b00000000; //precarga de 0 para 4 segundos
TMR1L=0;
T1CONbits.TMR1ON =1; //Enables timer 1
}
void Sleep_mode(void)
{
//OSCCONbits.IDLEN=1; //configuracion de los modos de ahorro
//OSCCONbits.IRCF2=1; //configuracion del oscilador interno
//OSCCONbits.IRCF1=1;
//OSCCONbits.IRCF0=0;
//OSCCONbits.SCS1=1; //seleccion del clock
//OSCCONbits.SCS0=0;
_asm //Sleep mode
SLEEP
_endasm
}
Algo que me dejo un poco insatisfecho es el hecho de que el máximo tiempo que puede desperta el micro con el reloj de 32768 es de 16 segundo, entonces si quieres llevar a cabo una rutina cada minuto o cada 3 minutos necesitas un contador cuando el contador acumule las veces equivalentes a un minuto o el tiempo que quieras mandas la rutina a ejecutar, pero mientras tanto el micro habrá despertado un buen número de veces, con lo que la reducción del consumo energético no me suena muy buena, aunque habría que medir directamente el consumo, ese es el paso que sigue.