Autor Tema: Mensaje desplazado con timer0  (Leído 7292 veces)

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

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1982
    • Sicoy
Re:Mensaje desplazado con timer0
« Respuesta #15 en: 22 de Noviembre de 2021, 13:49:54 »
Ok ok. Entendí como esta  :P.

Gracias nuevamente.

¿Y hay manera de hacerlo sin interrupciones?
Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Mensaje desplazado con timer0
« Respuesta #16 en: 22 de Noviembre de 2021, 14:14:18 »
No usar interrupciones te obliga a leer el timer en cada ciclo del mainloop manteniendo un conteo. Y cada x tiempo realizar la tarea.
Eso si, prohibidos terminantemente los delays largos y tareas apropiativas. 

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1982
    • Sicoy
Re:Mensaje desplazado con timer0
« Respuesta #17 en: 22 de Noviembre de 2021, 14:38:26 »
No usar interrupciones te obliga a leer el timer en cada ciclo del mainloop manteniendo un conteo. Y cada x tiempo realizar la tarea.
Eso si, prohibidos terminantemente los delays largos y tareas apropiativas.

Ahí es donde entraría tareas en estados o un RTOs
Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Mensaje desplazado con timer0
« Respuesta #18 en: 22 de Noviembre de 2021, 17:42:42 »
Mas bien estados, las funcionalidades son mas elementales que las de un RTOS.

Por ejemplo, planteando como ejercicio hacer parpadear leds con tiempos diferentes, activando/desactivando via rs232 (emulada) usando
un 12F508 que no tiene interrupciones,  una de las infinitas maneras puede ser asi:

Código: C
  1. #include <12F508.h>
  2. #FUSES NOWDT,NOMCLR
  3. #USE FAST_IO(all)
  4. #define set_option(x)   #asm ASIS   \
  5.                         movlw x     \
  6.                         option      \
  7.                         #endasm
  8. #use delay(internal=4MHz)
  9. #use rs232(baud=9600,xmit=PIN_b4,rcv=PIN_b3)
  10. // -------------------------------------
  11. #byte TMR  = 1
  12.  
  13. int8  T0,T1,T2 ;
  14. int16 T3 ;
  15. // -------------------------------------
  16. void main()
  17. {
  18.     set_option(DISABLE_WAKEUP_ON_CHANGE |
  19.                DISABLE_PULLUPS          |
  20.                RTCC_DIV_256) ;    // 65.536ms overflow
  21.  
  22.     output_b  (0b010000);
  23.     SET_TRIS_b(0b001000);
  24.  
  25.     T0=T1=T2=T3=0 ;
  26.  
  27.     while(true){
  28.        
  29.         // Mantiene contadores
  30.         // Cuando llegan a 1 detienen la cuenta
  31.    
  32.         if(bit_test(TMR,7)){    // Usa el bit7 como bandera
  33.             bit_clear(TMR,7) ;  // Cada 32.768ms
  34.             if(T0>1) T0-- ;
  35.             if(T1>1) T1-- ;
  36.             if(T2>1) T2-- ;
  37.             if(T3>1) T3-- ;
  38.         }
  39.  
  40.         // Ejecuta la tarea cuando corresponda
  41.         // Cuando el contador está en 0 está
  42.         // deshabilitado                
  43.    
  44.         if(T0==1){
  45.             output_toggle(pin_b0) ;
  46.             T0 = 9  ;   // 262ms
  47.         }
  48.  
  49.         if(T1==1){
  50.             output_toggle(pin_b1) ;
  51.             T1 = 16 ;   // 491ms
  52.         }
  53.  
  54.         if(T2==1){
  55.             output_toggle(pin_b2) ;
  56.             T2 = 5  ;   // 131ms
  57.         }
  58.  
  59.         if(T3==1){
  60.             output_toggle(pin_b5) ;
  61.             T3 = 306 ;  // 10s
  62.         }
  63.  
  64.         // Según lo recibido via rs232 se modifica las tareas  
  65.         // (activa/desactiva)
  66.        
  67.         if(kbhit()){
  68.             switch(getc()){
  69.                 case '0':
  70.                     if(T0==0) T0=1 ; else T0=0 ;
  71.                     output_low(pin_b0) ;
  72.                     break ;
  73.                 case '1':
  74.                     if(T1==0) T1=1 ; else T1=0 ;
  75.                     output_low(pin_b1) ;
  76.                     break ;
  77.                 case '2':
  78.                     if(T2==0) T2=1 ; else T2=0 ;
  79.                     output_low(pin_b2) ;
  80.                     break ;
  81.                 case '3':
  82.                     if(T3==0) T3=1 ; else T3=0 ;
  83.                     output_low(pin_b5) ;
  84.              }
  85.         }
  86.     }
  87. }

Desconectado mariacontenis

  • PIC16
  • ***
  • Mensajes: 116
Re:Mensaje desplazado con timer0
« Respuesta #19 en: 01 de Diciembre de 2022, 20:40:17 »
Eduardo2 Eso es como la función millis(); en Arduino?. E escuchado que Arduino tiene una función llamada así  :)

En la que puedes hacer varias cosas a distintos tiempos o algo así jejeje.

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1982
    • Sicoy
Re:Mensaje desplazado con timer0
« Respuesta #20 en: 01 de Diciembre de 2022, 20:44:36 »
Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Mensaje desplazado con timer0
« Respuesta #21 en: 01 de Diciembre de 2022, 20:57:08 »
Eduardo2 Eso es como la función millis(); en Arduino?. E escuchado que Arduino tiene una función llamada así  :)

En la que puedes hacer varias cosas a distintos tiempos o algo así jejeje.

En ese ejemplo el parecido está en decidir si algo se ejecuta en base al contenido de un contador.

Pero mientras que millis() mantiene un contador de 32bits que se actualiza por una interrupción periódica, ahí se manejan varios contadores que se actualizan en cada ciclo del while.

Desconectado mariacontenis

  • PIC16
  • ***
  • Mensajes: 116
Re:Mensaje desplazado con timer0
« Respuesta #22 en: 01 de Diciembre de 2022, 21:03:18 »
Sería posible pasar esa función millis(); o lo más parecido a ella con pic ccs c?.

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Mensaje desplazado con timer0
« Respuesta #23 en: 02 de Diciembre de 2022, 01:42:40 »
Y ... si.    En un PIC conviene usar el Timer2 porque es mas flexible que los otros.

- Lo programas para una interrupción cada milisegundo y vas incrementando una variable de 32bit.
Código: [Seleccionar]
    // clk de 8MHz
    setup_timer_2(T2_DIV_BY_4,249,2);   // overflow 500us
                                        // interrupcion 1.0ms
    enable_interrupts(INT_TIMER2);
    enable_interrupts(GLOBAL);

Código: [Seleccionar]
int32 cont32
#INT_TIMER2
void  TIMER2_isr(void)
{             
    cont32++ ;
}

- Al leer esa variable hay que deshabilitar la interrupción del timer y luego habilitarla.  Esto es porque existe la posibilidad que a la mitad de la lectura de la variable te entre la  interrupción y la incremente (leas cualquier cosa).  Cuando se está leyendo continuamente la variable esperando que se cumpla el intervalo pasa esto.
Código: [Seleccionar]
int32 millis(void){
    disable_interrupts(INT_TIMER2);
    int32 x32 = cont32 ;
    enable_interrupts(INT_TIMER2);
    return x32 ;
}

- Hacer una copia de millis() le veo sentido en cuanto a su uso, pero no en cuanto a la precisión o cantidad de bits.
En la mayoría de los casos los intervalos usados están sobrados con 8 o 16 bits. Además que tampoco se necesita que el incremento sea 1ms exacto.

Desconectado mariacontenis

  • PIC16
  • ***
  • Mensajes: 116
Re:Mensaje desplazado con timer0
« Respuesta #24 en: 02 de Diciembre de 2022, 10:46:48 »
Habrá que hacer que cont32 vuelva a cero en algún momento?. O que pasaría si llegara a su cuenta final?.

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Mensaje desplazado con timer0
« Respuesta #25 en: 02 de Diciembre de 2022, 11:05:09 »
Cuando llega a 0xFFFFFFFF la cuenta siguiente es 0x00000000.   A 1ms de conteo eso pasa cada 49 dias.  No recuerdo bien pero me parece que millis() te activa una variable señalando overflow)

Si tu intervalo es menor de 22.5 dias no necesitás hacer nada, simplemente restar los tiempos transcurridos.
Si fuera mayor...   pues llevá un contador de mas bits (con 40bits es overflow cada 34 años)  o usá incrementos mayores (en lugar de 1ms de 100ms por ejemplo)

Desconectado mariacontenis

  • PIC16
  • ***
  • Mensajes: 116
Re:Mensaje desplazado con timer0
« Respuesta #26 en: 02 de Diciembre de 2022, 11:18:40 »
Oohhh. Esto está interesante. Podrías poner un pequeño ejemplo para encender un LED con delay_ms y en el mismo con esta función millis() para ver que funcione sin que se interrumpan los tiempos. Bueno no sé si sea mucho pedir.

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Mensaje desplazado con timer0
« Respuesta #27 en: 02 de Diciembre de 2022, 16:10:39 »
A millis() se la suele usar de esta forma:


Código: [Seleccionar]
#INCLUDE <16F628A.H>
#use delay(internal=4MHz)

#use fast_io(all)

int32 cont32=0 ;

#INT_TIMER2
void  TIMER2_isr(void)
{   
    cont32++ ;
}               
       
int32 millis(void){

    disable_interrupts(INT_TIMER2);       
    int32 x32 = cont32 ;
    enable_interrupts(INT_TIMER2);   
    return x32 ;
}       
   
void main(void){
int32 T0 ;
   
    set_tris_b(0xFE) ;
       
    setup_timer_2(T2_DIV_BY_4,249,1); //1.0 ms overflow, 1.0 ms interrupt
 // setup_timer_2(T2_DIV_BY_4,249,10); //1.0 ms overflow, 10.0 ms interrupt
                                           
    enable_interrupts(INT_TIMER2);   
    enable_interrupts(GLOBAL);       
   
    output_high(PIN_B0);
    T0 = millis() ;
   
    #define T_LED 1000
   
    while(1){
       
        //--------------------------------
        if((millis()-T0) >= T_LED){
            output_toggle(PIN_B0);
            T0 = millis() ;
        }
        //--------------------------------
       
       
        // lo que sea     
       
       
       
    }
}

Con delay_ms()  es escribir en el bucle
Código: [Seleccionar]
    while(1){       
        //--------------------------------
       delay_ms(1000) ;
       output_toggle(PIN_B0);

        //--------------------------------
       
       
        // lo que sea     
       
       
       
    }
}



Pero usar millis() para controlar el encendido de un led es poco imaginativo, es mejor que la interrupción del Timer2 se encargue de apagarlo/encenderlo.

Desconectado mariacontenis

  • PIC16
  • ***
  • Mensajes: 116
Re:Mensaje desplazado con timer0
« Respuesta #28 en: 06 de Diciembre de 2022, 10:41:22 »
Grácias Eduardo2. Funciona perfecto  ((:-))
Probé en físico y Eurekaaa!!. Creo que es un buen recurso para evitar el delay_ms. Creo que se podrá utilizar en rutinas diferentes a el solo encender y apagar un LED