Autor Tema: Duda con el sleep en ccs  (Leído 6116 veces)

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

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Duda con el sleep en ccs
« en: 08 de Julio de 2014, 00:36:28 »
Hola a todos, acudo a ustedes porque tengo un problema con el modo sleep de un pic 16lf1826, el programa es para un control remoto, por lo cual debo ahorrar la mayor cantidad de batería, en un inicio(sin presionar ningún botón) el consumo del pic es de 0 (no lo alcanza a medir el multímetro), al momento de presionar un botón y enviar la señal, el consumo es de 6 mA, y en cuanto suelto el botón el consumo baja a 3 mA, pero se supone que debería entrar al sleep y no consumir tanto.

Ya probé poniendo todos los pines como entrada antes de mandar a dormir el pic, y también desactivando el pwm por si era eso lo que seguía consumiendo, finalmente hice una prueba configurando todo de nuevo antes de mandar a dormir el micro, pero el Pic sigue a¿haciendo lo mismo.

adjunto el código por si se les ocurre algo.

Básicamente el problema esta en el sleep y en la configuración, pero dejo el código completo por si ven algo que pueda afectar el sleep

Código: C
  1. /*Prueba Control remoto
  2.  *
  3.  */
  4. #include <16LF1826.h>
  5. #include <stdlib.h>
  6. #FUSES   INTRC_IO,noWDT,NOMCLR,PROTECT
  7. #USE     DELAY(clock=32000000,int=8M,restart_wdt)
  8. #define led1   pin_b0
  9. int1 ONF=0;
  10. #include "lib2.h"
  11.  
  12. static int1 level2=0;
  13. void main ()
  14. {
  15.    config();
  16.    int16 push=0;
  17.    memset(dir,0,8);
  18.    memset(s,0,9);
  19.    level=5;
  20.    strcpy(s,"00000000");
  21.    strcpy(dir,"00000000");
  22.    
  23.    
  24.    while (true)
  25.    {      
  26.       restart_wdt();
  27.       if(!input(btn3))
  28.       {      
  29.          delay_ms(10);
  30.          while(!input(btn3))
  31.          {
  32.             delay_ms(1);
  33.             push++;
  34.             if(push==20)
  35.             {
  36.                push=0;
  37.                if(ONF)send_train();
  38.             }
  39.          }
  40.          while(!input(btn3))restart_wdt();
  41.       }
  42.      
  43.       if(!input(btn1))
  44.       {
  45.          delay_ms(10);
  46.          if(!input(btn1))
  47.          {
  48.          
  49.             while(!input(btn1))
  50.             {
  51.                delay_ms(1);
  52.                push++;
  53.                if(push==20)
  54.                {
  55.                   push=0;
  56.                   send_train();
  57.                }
  58.             }
  59.             while(!input(btn1))restart_wdt();
  60.          }
  61.       }
  62.          
  63.          
  64.       config();    
  65.       //disable_interrupts(global);
  66.       enable_interrupts(int_rb);
  67.       sleep();
  68.       disable_interrupts(int_rb);
  69.       //enable_interrupts(global);
  70.       Start_Modules();      
  71.    }    
  72.    
  73. }
  74.  
  75.  
  76. static int current_val=0;
  77.  
  78. void Send_command(int update)
  79. {
  80.    
  81. }


y el .h con la configuración es el siguiente

Código: C
  1. #BYTE PSTR1CON       =  0x0296//
  2. #BYTE apfcon0       =  0x011D//
  3. #BYTE TRISA       =  0x008C//
  4. #BYTE TRISB       =  0x008D//
  5. //emisor
  6. #define btn1      pin_b1//
  7. #define btn2      pin_b5//
  8. #define btn3      pin_b5//
  9. #define led       pin_a1
  10.  
  11.  
  12.  
  13. #define  L0    "00000000"  
  14. #define  L1    "00101000"  
  15. #define  L2    "00101000"  
  16. #define  L3    "00101000"  
  17. #define  L4    "00101000"  
  18. #define  L5    "00101000"  
  19. #define  L6    "00101000"  
  20.  
  21.  
  22.      //b0,b5
  23. #use fast_io(a)
  24.  
  25. #use fast_io(b)
  26. char dir[8];
  27. char s[8];
  28.  
  29.  
  30. #define OND    0
  31. static int level=1;
  32.  
  33. void Send_command(int update);
  34.  
  35. void send_train()//se envia el tren de pulsos
  36. {
  37.    int j;
  38.    int16 delay;  
  39.    restart_wdt();
  40.    set_pwm1_duty(105);
  41.    apfcon0=2;
  42.    set_timer2(0);
  43.    delay_us(2600);  
  44.    set_pwm1_duty(OND);
  45.    apfcon0=2;
  46.    set_timer2(0);
  47.    delay_us(500);  
  48.    for (j=1;j<8;j++)
  49.    {
  50.       if(s[j]=='0')delay=100;
  51.       else if(s[j]=='1')delay=200;
  52.       else delay=0;
  53.       set_pwm1_duty(105);
  54.       apfcon0=2;
  55.       set_timer2(0);
  56.       delay_us(delay);
  57.       set_pwm1_duty(OND);
  58.       apfcon0=2;
  59.       set_timer2(0);      
  60.       delay_us(50);      
  61.    }  
  62. }
  63.  
  64. void setup_pwm()// configuracion del timer 2 para un pwm con 38Khz
  65. {
  66.    setup_timer_2(T2_DIV_BY_1,210, 1);//timer para pwm de 38khz
  67.    setup_ccp1(ccp_pwm|CCP_PULSE_STEERING_C); //pwm pin_c5
  68.    apfcon0=2;
  69.    set_pwm1_duty(OND);  //se pone en cero el pwm
  70.    apfcon0=2;
  71.    set_timer2(0);
  72.    restart_wdt();
  73. }
  74.  
  75. void config()
  76. {  
  77.    setup_adc(adc_off);
  78.    setup_adc_ports(no_analogs);
  79.    SETUP_PWM();
  80.    TRISA=(0b00000000);
  81.    port_a_pullups(0b00000000);
  82.  output_a(0);
  83.    TRISB=(0b11111111);    
  84.    port_b_pullups(0b11111111);        
  85.    
  86.    restart_wdt();
  87. }
  88.  
  89. void Start_Modules()
  90. {
  91.    restart_wdt();
  92.    SETUP_PWM();
  93.    TRISA=(0b00000000);
  94.    port_a_pullups(0b00000000);
  95. }
  96.  
  97. #int_RB
  98. void wake()
  99. {  
  100. //   delay_ms(1);
  101. }




"Nada es imposible, no si puedes imaginarlo"

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Duda con el sleep en ccs
« Respuesta #1 en: 10 de Julio de 2014, 22:57:27 »
Me respondo yo solo, y por si a alguien mas le sirve

Pues resulta que yo intentaba despertar al PIC usando la interrupción por cambio de estado en el puerto B, sin embargo, la instrucción enable_interrupts(int_rb), estaba configurando mal los registros para este pic, ya que al presionar una tecla, el pic se despertaba, pero al pasar nuevamente por la función de sleep, el micro despertaba inmediatamente sin que se hubiera presionado una tecla.

Por lo que leí en el datasheet para el modelo que uso, la interrupción se puede configurar para todo el puerto B y en cada pin se debe de especificar si la interrupción ocurrirá en flanco de subida o de bajada, por lo que cada pin tiene su prpia bandera de interrupción, finalmente solucioné el problema configurando los registros manualmente.

Espero le sirva a alguien para futuras referencias, y si necesitan una explicación mas detallada pregunten y con gusto explico mas a detalle

Saludos
"Nada es imposible, no si puedes imaginarlo"

Desconectado alev2477

  • PIC10
  • *
  • Mensajes: 21
Re: Duda con el sleep en ccs
« Respuesta #2 en: 12 de Julio de 2014, 07:21:22 »
Muchas gracias Rivale
Lo tendré en cuenta para mis proyectos.
Al preguntar aprendo y al responder aprendo tambien

Desconectado RALF2

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2062
Re: Duda con el sleep en ccs
« Respuesta #3 en: 12 de Julio de 2014, 08:44:07 »
Rivale y si al final del main colocas:

While(true)
  Sleep();

Asi deberia saltar a la ISLR y luego volverse a dormir

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Duda con el sleep en ccs
« Respuesta #4 en: 12 de Julio de 2014, 22:21:01 »
Rivale y si al final del main colocas:

While(true)
  Sleep();

Asi deberia saltar a la ISLR y luego volverse a dormir

Gracias por la sugerencia RALF, el problema era que el pic si entraba al sleep pero salía inmediatamente, con lo que comentas el micro quedaría siempre dormido y creo que nunca saldría de ahí, o entendí mal?
"Nada es imposible, no si puedes imaginarlo"

Desconectado RALF2

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2062
Re: Duda con el sleep en ccs
« Respuesta #5 en: 12 de Julio de 2014, 22:45:18 »
Amigo la interrupcion lo despertaria, esa es la idea, sino el micro estaria muerto para siempre  :D

Esa es una de las funciones de la interrupcion, despertar al muerto  :lol:
Luego que atienda la interrupcion se vuelve a dormir!   ;-)


Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Duda con el sleep en ccs
« Respuesta #6 en: 12 de Julio de 2014, 22:51:20 »
Amigo la interrupcion lo despertaria, esa es la idea, sino el micro estaria muerto para siempre  :D

Esa es una de las funciones de la interrupcion, despertar al muerto  :lol:
Luego que atienda la interrupcion se vuelve a dormir!   ;-)



 :D :D, si RALF, entiendo, eso, pero me refiero a que la interrupción solo hace que el micro despierte y brinque a la siguiente linea del código, son embargo, al tener un while(true)sleep; la siguiente linea seria volver al while y volver a dormir
« Última modificación: 12 de Julio de 2014, 22:59:19 por rivale »
"Nada es imposible, no si puedes imaginarlo"

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Duda con el sleep en ccs
« Respuesta #7 en: 12 de Julio de 2014, 22:59:57 »
Aquí esta la interrupción despertando al PIC  :mrgreen:
"Nada es imposible, no si puedes imaginarlo"

Desconectado RALF2

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2062
Re: Duda con el sleep en ccs
« Respuesta #8 en: 12 de Julio de 2014, 23:22:05 »
jajajajaja  :D
Citar
son embargo, al tener un while(true)sleep; la siguiente linea seria volver al while y volver a dormir

No en ese caso saltaria a la rutina de interrupcion, Rivale   ;-)  no se quedaria dentro del while, pruebalo para que veas  ;-)

Al salir de la interrupcion si se iria dentro del while  :mrgreen:

« Última modificación: 12 de Julio de 2014, 23:29:11 por RALF2 »

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Duda con el sleep en ccs
« Respuesta #9 en: 13 de Julio de 2014, 00:46:55 »
Hola de nuevo RALF, acabo de probar lo que comentas y lamento decirte que aunque el PIC si despierta, como está dentro de un while, se vuelve a dormir inmediatamente, la interrupción no hace que el pic brinque al vector de interrupción, solo hace que el PIC corra la siguiente instrucción espués del sleep. :?
"Nada es imposible, no si puedes imaginarlo"

Desconectado RALF2

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2062
Re: Duda con el sleep en ccs
« Respuesta #10 en: 13 de Julio de 2014, 15:08:28 »
Citar
la interrupción no hace que el pic brinque al vector de interrupción, solo hace que el PIC corra la siguiente instrucción después del sleep

Amigo, yo tengo hecha una aplicacion que probe usando interrupciones por puerto serial; cuando recibo un dato estando el micro en modo sleep, este salta a la interrupcion, envia un mensaje por rs232 y luego vuleve al modo sleep()  :mrgreen:

No entiendo porque tu programa no ejecuta la interrupcion, si quieres te pongo un ejemplo luego para que veas.
que si funciona, en CCS.

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Duda con el sleep en ccs
« Respuesta #11 en: 13 de Julio de 2014, 20:08:43 »
Hola Ralf
con rs232 creo que si he hecho lo que comentas, me imagino que es por el tipo de interrupción, ya que en el datasheet dice que solo lo despierta, pero no atiende la interrupción. en un rato subo mi ejemplo

"Nada es imposible, no si puedes imaginarlo"

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Duda con el sleep en ccs
« Respuesta #12 en: 13 de Julio de 2014, 21:15:18 »
Aca dejo mi simulación con el while que habias comentado RALF, nota que si quitas el while(true)sleep(); funciona bien

Saludos
"Nada es imposible, no si puedes imaginarlo"

Desconectado RALF2

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2062
Re: Duda con el sleep en ccs
« Respuesta #13 en: 13 de Julio de 2014, 22:54:55 »
Citar
#include <18F26K80.h>
#device adc=12
                             
#FUSES VREGSLEEP                //Ultra low-power regulator is disabled
#FUSES INTRC_LP                 //LF-INTOSC in Low-Power mode during Sleep
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES PLLEN                    //PLL habilitado, multiplica por 4 el cristal externo
#FUSES HSM                      //High speed Osc, medium power 4MHz-16MHz, solo para cristal externo           
#FUSES SOSC_DIG                 //Digital mode, I/O port functionality of RC0 and RC1
#FUSES PUT                      //Power Up Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES WDT_NOSLEEP              //Watch Dog Timer, disabled during SLEEP

#use delay(clock= 32000000)     //Ajusta las rutinas de retardo para operar a 32Mhz( 4 x 8Mhz), con el pll activado

#define led PIN_B0

#INT_EXT1
void Interrupcion_int1()
{
   for(int i=0; i<4; i++)
   {
      output_high(led);
      delay_ms(500);
      output_low(led);
      delay_ms(500);
   }   
}


void main()
{
   enable_interrupts(INT_EXT1_H2L);
   enable_interrupts(global);
   
   while(true)
      sleep();
}



El programa junto con el esquematico mostardo arriba lo probe en el proteus y en fisico y funciona tal cual como te dije, rivale  :mrgreen:

Cuando se genera una interrupcion en RB1 por flnco de bajada el pic entra en la interrupcion y hace titilar el led 4 veces y luego se vuelve a dormir  ;-)

Lo probe con un cristal externo de 8MHz, con el PLL activado para operar a 32MHz  :shock:

Saludos

Desconectado RALF2

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2062
Re: Duda con el sleep en ccs
« Respuesta #14 en: 13 de Julio de 2014, 23:09:08 »
Aca dejo mi simulación con el while que habias comentado RALF, nota que si quitas el while(true)sleep(); funciona bien

Saludos

rivale tu configuras los registros a pie  :shock:  puede ser eso lo que te este pasando, revisa y prueba el mio para que veas que si funciona y lo probe en fisico por lo que estoy 100% seguro de lo que digo, yo no veo que utilices las interrupciones que el ccs trae como enable_interrupts(global), enble_interrupts(int_ext)... podria ser esa la razon por la que no te anda  :?


 

anything