Autor Tema: Ayuda rápida con modo Sleep y timer1  (Leído 5650 veces)

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

Desconectado alex1987

  • PIC10
  • *
  • Mensajes: 16
Ayuda rápida con modo Sleep y timer1
« en: 27 de Abril de 2010, 21:41:32 »
Soy nuevo en el foro, espero no meter ruido y que me puedan hechar una mano, seré breve.

Estoy en la parte final de un proyecto, y he batallado un poco con los modos de ahorro de energía de los microcontroladores, siendo especifico utilizo en pic18f8722 actualmente, y programa en C18.
Ya he configurado el Timer 1 para que funcione con clock externo, he logrado que haga interrupcion. Hice un programa rápido solo para comprobar que le micro despierte mediante ka interrupción del Timer 1, este programa mantiene un led encendido y pone el micro en modo Sleep, si se realiza la interrupción entonces el led se apagará. Hasta ahora el código no funciona un vez que entra en modo sleep.
A continuación el código, espero su apoyo, gracias de antemano.

#include<p18cxxx.h>
#include<timers.h>
#include<delays.h>

#pragma config OSC = HS, FCMEN = OFF, IESO = ON
#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 = OFF, 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 Timer1_Inicio(void);

#pragma code Interrupcion = 0x0008
void VectorInterrupcion(void){
      _asm goto ISRTimer1 _endasm
}
#pragma code

#pragma interrupt ISRTimer1
void ISRTimer1(void){
      if(PIR1bits.TMR1IF==1){
            //WriteTimer1(0);
            TMR1H=0b10000000;
            PORTBbits.RB0=0;
            Delay10KTCYx(50);
            PIR1bits.TMR1IF=0;
      }
}
            
void main(void){
      //OpenTimer1(TIMER_INT_ON & T1_16BIT_RW & T1_SOURCE_EXT & T1_PS_1_2 & T1_OSC1EN_ON & T1_SYNC_EXT_ON);
      Timer1_Inicio();
      Delay10KTCYx(50);
      RCONbits.IPEN=0;
      INTCONbits.PEIE=1;
      INTCONbits.GIE=1;
      TRISB=0x00;
      PORTB=0x00;
      //WriteTimer1(0);

      while(1){
            PORTBbits.RB0=1;
            //Sleep();
      }
}

void Timer1_Inicio(void)
{
      PIR1bits.TMR1IF = 0;
      PIE1bits.TMR1IE = 1;
        //T1CON=0b00001110;
      T1CONbits.RD16=0;
      T1CONbits.T1RUN=0;
      T1CONbits.T1CKPS1=0;
      T1CONbits.T1CKPS0=0;
      T1CONbits.T1OSCEN=1;
      T1CONbits.T1SYNC=1;
      T1CONbits.TMR1CS=1;
      T1CONbits.TMR1ON=0;
      TMR1H=0b10000000;
      TMR1L=0;
      T1CONbits.TMR1ON =1;
}

Desconectado alex1987

  • PIC10
  • *
  • Mensajes: 16
Re: Ayuda rápida con modo Sleep y timer1
« Respuesta #1 en: 30 de Abril de 2010, 00:27:03 »
Bueno he modificado algunas cosas, en lugar de utilizar el macro Sleep() he intentado configurar los registros como sigue:

void Sleep_mode(void)
{
      //T1CONbits.T1RUN=1;
      Delay1KTCYx(50);
      //OSCCONbits.OSTS=0;
      OSCCONbits.SCS1=0;
      OSCCONbits.SCS0=1;
      OSCCONbits.IDLEN=1;
      _asm
      SLEEP
      _endasm
      //Delay10KTCYx(10);
}
Los bits SCS deberian servir para la configuración del Clock, el bit IDLEN activo sirve para escoger un modo Idle, ejecutando la instruccion SLEEP deberia de entrar en un modo de energia SEC_IDLE funcionando con el oscilador Timer 1, pero aparentemente no funciona, al simular de nuevo no logra salir del modo de ahorro aun con la interrupcion del Timer 1, inclusive al depurar el codigo se muestra un mensaje que dice "SCS no puede ser activado, ya que el bit de switcheo no esta activado en la configuracion de los registros, me fui a la configuracion de los registros modifique los OSC, FCMEN, IESO pero aun no lo logro, si alguien tiene algo, agradesco el apoyo.

Desconectado bmfranky

  • PIC16
  • ***
  • Mensajes: 165
    • La Tienda De Fran
Re: Ayuda rápida con modo Sleep y timer1
« Respuesta #2 en: 30 de Abril de 2010, 09:44:15 »
Una pregunta tonta, ¿lo estas simulando o lo tienes montado en un board?. por esperiencia propia se que el proteus no simula bien el sleep de muchos micros. simplemente detiene todo el micro incluyendo el oscilador interno del pic y el externo del timer1.
Visiten La Tienda De Fran ;-) Aqui. y mi nueva Web Aqui.

Desconectado alex1987

  • PIC10
  • *
  • Mensajes: 16
Re: Ayuda rápida con modo Sleep y timer1
« Respuesta #3 en: 30 de Abril de 2010, 11:57:11 »
Gracias por tu respuesta, lo estoy simulando solamente, no tenia idea de que el proteus no pudiera simular el modo Sleep de algunos micros, pero de hecho cuando entra en modo sleep es como si todo se congelará, si tengo un led encendido este led no se apaga, cuando se supone que los perifericos deberian dejar de funcionar, si intento activar un modo IDLE se muestra el siguiente mensaje: "this fearture is not modelled", ahi se entiende que no modela los modos IDLE.
Entonces creo que no tiene caso que siga con la simulacion, estaré en espera de mis componentes y comentaré más adelante si el resultado varió.
Gracias.

Desconectado alex1987

  • PIC10
  • *
  • Mensajes: 16
Re: Ayuda rápida con modo Sleep y timer1
« Respuesta #4 en: 30 de Abril de 2010, 12:57:01 »
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.

Desconectado alex1987

  • PIC10
  • *
  • Mensajes: 16
Re: Ayuda rápida con modo Sleep y timer1
« Respuesta #5 en: 03 de Mayo de 2010, 23:46:22 »
Como mencione, para simular se usa un generador de pulsos de reloj, pero en la hoja de datos aparece un crystal tipo LP (Low-power), asi que...alguien a probado esto en un board, fisicamente alguien a probado con que componente funciona bien un generador de pulsos de reloj en RC1 o un crystal tipo LP entre RC0 y RC1?

Desconectado alex1987

  • PIC10
  • *
  • Mensajes: 16
Re: Ayuda rápida con modo Sleep y timer1
« Respuesta #6 en: 07 de Mayo de 2010, 12:15:03 »
Bueno responderé mi pregunta anterior, ya pude hacerlo en un board y use un crystal de 32768, el modo Sleep funciona y la interrupcion se realiza exitosamente, tambien probe los modos Idle los cuales tambien se realizan exitosamente, medi el consumo de energia en el modo SEC_IDLE el consumo es de 15 microamperes, tambien lo medi para el modo Sleep y es de 3 microamperes lo cual me parece bueno aunque la hoja de especificaciones dice que se puede llegar a 0.1 microamperes, solo hubo que hacer un cambio en el código, a pesar de que en la simulación funciona bien tal cual esta el código, en el board no funciona, para que funcione el modo Sleep es necesario que no se sincronize el oscilador externo, para cualquier otro modo de ahorro de energía el oscilador debe estar sincronizado.

Desconectado f-traxx

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 116
Re: Ayuda rápida con modo Sleep y timer1
« Respuesta #7 en: 19 de Octubre de 2010, 03:37:46 »
Hola alex1987, he estado buscando un poco de ayuda para hacer funcionar el modo sleep, si pudieras me vendria bien que dejaras el trozo de codigo con el que utilizas ese modo para poder entenderlo mejor y empezar a practicar con el muchas gracias...

Ya se que me arriesgo a no recibir respuesta ya que me sale el mensaje de (Advertencia: no se han publicado mensajes en este tema por aproximadamente 120 días.)

pero para probarlo no pierdo nada jeje.... :mrgreen: :mrgreen:

Desconectado alex1987

  • PIC10
  • *
  • Mensajes: 16
Re: Ayuda rápida con modo Sleep y timer1
« Respuesta #8 en: 12 de Noviembre de 2010, 19:54:10 »
Hola f-traxx, ciertamente lleva un rato que estuve con lo del modo sleep, bueno, el código que me funcionó lo puedes encontrar aca mismo unos parrafos arriba, puedes usar la macro sleep() o hacerlo mediante la configuracion de los registros que muestro en el código, espero la información te sirva.