TODOPIC

Microcontroladores PIC => * PROYECTOS * => Mensaje iniciado por: Abner_emanuel en 18 de Noviembre de 2021, 23:24:51

Título: Mensaje desplazado con timer0
Publicado por: Abner_emanuel en 18 de Noviembre de 2021, 23:24:51
Saludos Hermanos del Foro.

Les muestro este código  para pasar a lo que pretendo (con su ayuda, claro) :mrgreen:

Código: C#
  1. const char LCD_buffer1[]={"\377 Disel agotado o Sensor da\356ado \377 Disel agotado o Sensor da\356ado "};
  2.          char LCD_buffer2[21]={""};                                                          
  3.          int8 posicion=0, caracter=0;                                                
  4.          
  5.          void main(void)                                                                    
  6.          {    
  7.          lcd_init();                                                                        
  8.          
  9.          while(true)                                                                        
  10.          {
  11.          output_high(pin_c0); delay_ms(1000); output_low(pin_c0);
  12.          
  13.          for(posicion=0;posicion<20;posicion++)                                            
  14.          {
  15.          LCD_buffer2[posicion]=LCD_buffer1[posicion+caracter];
  16.          }
  17.          lcd_gotoxy(1,4); printf(lcd_putc,"%s",LCD_buffer2); [b]delay_ms(300);[/b]
  18.          caracter++;
  19.          if(caracter==34) {caracter=1;}
  20.          }
  21.          }

Bueno pues estoy desplazando el mensaje de izquierda a derecha en una lcd4x20 y el mensaje que se desplaza es Disel agotado o Sensor dañado, hasta ahí todo bien, pues el mensaje se desplaza de manera correcta.

Lo que quiero hacer es quitar ese retardo de 300ms en la linea lcd_gotoxy(1,4); printf(lcd_putc,"%s",LCD_buffer2); delay_ms(300); y hacerlo con el timer0, ya que tengo mas lineas de código ( output_high(pin_c0); delay_ms(1000); output_low(pin_c0); son para simular otro proceso únicamente ) y con este retarlo me hace lentas mis demás tareas en el programa.

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Ahora este es el código con timer0 y el pic a 20Mhz que estoy intentando pero no me resulta...

       
Código: C#
  1. short msj=0;
  2.  
  3.          #int_timer0                                                                   // Interrupcion para 1S
  4.          void timer0(void)
  5.          { msj=1; set_timer0(46005);}                                       // 46005 para que el timer sea aproximadamente de 250 ms
  6.  
  7.          const char LCD_buffer1[]={"\377 Disel agotado o Sensor da\356ado \377 Disel agotado o Sensor da\356ado "};
  8.          char LCD_buffer2[21]={""};                                                          
  9.          int8 posicion=0, caracter=0;                                                
  10.          
  11.          void main(void)                                                                    
  12.          {    
  13.          lcd_init();                                                                        
  14.          enable_interrupts(INT_TIMER0);
  15.          setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64);                
  16.          set_timer0(46005);
  17.          enable_interrupts(GLOBAL);  
  18.  
  19.          while(true)                                                                        
  20.          {
  21.          output_high(pin_c0); delay_ms(1000); output_low(pin_c0);     // Solo para simular otro proceso del programa
  22.          
  23.         if(msj==1) {
  24.  
  25.          for(posicion=0;posicion<20;posicion++)                                            
  26.          {
  27.          LCD_buffer2[posicion]=LCD_buffer1[posicion+caracter];
  28.          }
  29.          lcd_gotoxy(1,4); printf(lcd_putc,"%s",LCD_buffer2); msj=0;      
  30.          }        
  31.          caracter++;
  32.          if(caracter==34) {caracter=1;}
  33.          }
  34.          }

Pues el resultado es que no hace nada, el mensaje con no se muestra en pantalla con el intento del timer0, me podrían orientar el hacerlo de manera correcta?
Título: Re:Mensaje desplazado con timer0
Publicado por: remi04 en 19 de Noviembre de 2021, 06:04:13
Durante el delay_ms(1000); no se atienden interrupciones.

 Por otro lado, esto:

Código: C
  1. caracter++;
  2. if(caracter==34) {caracter=1;}

  Te lo has dejado fuera del condicional if (msj == 1) {}
Título: Re:Mensaje desplazado con timer0
Publicado por: DominusDRR en 19 de Noviembre de 2021, 09:25:39
Saludos Hermanos del Foro.

Les muestro este código  para pasar a lo que pretendo (con su ayuda, claro) :mrgreen:

Código: C#
  1. const char LCD_buffer1[]={"\377 Disel agotado o Sensor da\356ado \377 Disel agotado o Sensor da\356ado "};
  2.          char LCD_buffer2[21]={""};                                                          
  3.          int8 posicion=0, caracter=0;                                                
  4.          
  5.          void main(void)                                                                    
  6.          {    
  7.          lcd_init();                                                                        
  8.          
  9.          while(true)                                                                        
  10.          {
  11.          output_high(pin_c0); delay_ms(1000); output_low(pin_c0);
  12.          
  13.          for(posicion=0;posicion<20;posicion++)                                            
  14.          {
  15.          LCD_buffer2[posicion]=LCD_buffer1[posicion+caracter];
  16.          }
  17.          lcd_gotoxy(1,4); printf(lcd_putc,"%s",LCD_buffer2); [b]delay_ms(300);[/b]
  18.          caracter++;
  19.          if(caracter==34) {caracter=1;}
  20.          }
  21.          }

Bueno pues estoy desplazando el mensaje de izquierda a derecha en una lcd4x20 y el mensaje que se desplaza es Disel agotado o Sensor dañado, hasta ahí todo bien, pues el mensaje se desplaza de manera correcta.

Lo que quiero hacer es quitar ese retardo de 300ms en la linea lcd_gotoxy(1,4); printf(lcd_putc,"%s",LCD_buffer2); delay_ms(300); y hacerlo con el timer0, ya que tengo mas lineas de código ( output_high(pin_c0); delay_ms(1000); output_low(pin_c0); son para simular otro proceso únicamente ) y con este retarlo me hace lentas mis demás tareas en el programa.

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Ahora este es el código con timer0 y el pic a 20Mhz que estoy intentando pero no me resulta...

       
Código: C#
  1. short msj=0;
  2.  
  3.          #int_timer0                                                                   // Interrupcion para 1S
  4.          void timer0(void)
  5.          { msj=1; set_timer0(46005);}                                       // 46005 para que el timer sea aproximadamente de 250 ms
  6.  
  7.          const char LCD_buffer1[]={"\377 Disel agotado o Sensor da\356ado \377 Disel agotado o Sensor da\356ado "};
  8.          char LCD_buffer2[21]={""};                                                          
  9.          int8 posicion=0, caracter=0;                                                
  10.          
  11.          void main(void)                                                                    
  12.          {    
  13.          lcd_init();                                                                        
  14.          enable_interrupts(INT_TIMER0);
  15.          setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64);                
  16.          set_timer0(46005);
  17.          enable_interrupts(GLOBAL);  
  18.  
  19.          while(true)                                                                        
  20.          {
  21.          output_high(pin_c0); delay_ms(1000); output_low(pin_c0);     // Solo para simular otro proceso del programa
  22.          
  23.         if(msj==1) {
  24.  
  25.          for(posicion=0;posicion<20;posicion++)                                            
  26.          {
  27.          LCD_buffer2[posicion]=LCD_buffer1[posicion+caracter];
  28.          }
  29.          lcd_gotoxy(1,4); printf(lcd_putc,"%s",LCD_buffer2); msj=0;      
  30.          }        
  31.          caracter++;
  32.          if(caracter==34) {caracter=1;}
  33.          }
  34.          }

Pues el resultado es que no hace nada, el mensaje con no se muestra en pantalla con el intento del timer0, me podrían orientar el hacerlo de manera correcta?

El problema de las funciones 'delay' y similares es que producen un 'deadlock' o bloqueo del CPU, ya que están en un lazo infinito 'matando el tiempo' y con las interrupciones bloqueadas como indica remi04.

Yo te recomendaría escribir tu código en estados de maquina y tareas independientes, de esa manera tienes un proceso independiente para cada periférico y también puedes hacer retardos que no bloquen el CPU, es decir puedes hacer otras cosas mientras un retardo se está produciendo.

En el siguiente hilo, traté de explicar eso alguien con un problema relacionado con las funciones delay:

http://www.todopic.com.ar/foros/index.php?topic=50932.msg419330#msg419330 (http://www.todopic.com.ar/foros/index.php?topic=50932.msg419330#msg419330)
Título: Re:Mensaje desplazado con timer0
Publicado por: Eduardo2 en 19 de Noviembre de 2021, 09:41:06
Durante el delay_ms(1000); no se atienden interrupciones.
...

Durante el delay sí se atienden interrupciones,  justamente el problema que tienen cuando hay interrupciones es que el retardo es mas largo y variable.
Título: Re:Mensaje desplazado con timer0
Publicado por: DominusDRR en 19 de Noviembre de 2021, 09:45:39
Durante el delay_ms(1000); no se atienden interrupciones.
...

Durante el delay sí se atienden interrupciones,  justamente el problema que tienen cuando hay interrupciones es que el retardo es mas largo y variable.

Recuerdo que en PICC al analizar el ensamblador, las bandera GIE pasaba a cero lógico al iniciar un delay, pero posiblemente ya cambiaron eso,  Lo que te cuento fue hace 13 años, desde esa época sólo he usado otros compiladores.
Título: Re:Mensaje desplazado con timer0
Publicado por: Abner_emanuel en 19 de Noviembre de 2021, 09:54:25
Hola remi04.

Aun así cubriendo lo que.comentas, la interrupcion no se realiza.

DominusDRR, e leído el post y me parece interesante.

Gracias por los comentarios..
Título: Re:Mensaje desplazado con timer0
Publicado por: Eduardo2 en 19 de Noviembre de 2021, 10:51:25
Aun así cubriendo lo que.comentas, la interrupcion no se realiza.

????  Al menos en el código que subiste la la interrupción sí se realiza.

Si a eso le agrego todo lo que debiste agregar , achico ese delay_ms(1000) porque recién lee msj después del retardo

  - Tienes que ingresar para ver archivos adjuntos -  

(El led parpadea pero casi no se ve porque el tiempo apagado es corto)
Título: Re:Mensaje desplazado con timer0
Publicado por: Abner_emanuel en 19 de Noviembre de 2021, 12:21:26
Edurdo2

 output_high(pin_c0); delay_ms(1000); output_low(pin_c0);

Jejeje.. ya me di cuenta.. Error fatal el mio, no me di cuenta que falto un delay para el apagado del led.

Ahora probaré y comento, pero ya creo lo que comentas. Jajajaja, gracias Eduardo2.
Título: Re:Mensaje desplazado con timer0
Publicado por: Abner_emanuel en 20 de Noviembre de 2021, 13:38:22
Eduardo2.

Creo que aun así no lo hace, si se pone el retardo asi: output_high(pin_c0); delay_ms(1000); output_low(pin_c0); delay_ms(1000); dentro del while, el mensaje corre pausando a 1000ms letra a letra recorrida.

Ahora bien, poniendo todo dentro del la interrupción si lo hace como se requiere, aquí muestro el código...

Código: C#
  1. const char LCD_buffer1[]={"\377 Disel agotado o Sensor da\356ado \377 Disel agotado o Sensor da\356ado "};
  2.          char LCD_buffer2[21]={""};                                                          
  3.          int8 posicion=0, caracter=0;                                                          
  4.  
  5.          #int_timer0                                                                   // Interrupcion para 1S
  6.          void timer0(void)
  7.          {
  8.          set_timer0(46005);
  9.          for(posicion=0;posicion<20;posicion++)                                            
  10.          { LCD_buffer2[posicion]=LCD_buffer1[posicion+caracter]; }
  11.          lcd_gotoxy(1,4); printf(lcd_putc,"%s",LCD_buffer2);
  12.          caracter++;
  13.          if(caracter==34) {caracter=1;}
  14.          }                                       // 46005 para que el timer sea aproximadamente de 250 ms
  15.          
  16.          void main(void)                                                                    
  17.          {    
  18.          lcd_init();                                                                        
  19.          enable_interrupts(INT_TIMER0);
  20.          setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64);                
  21.          set_timer0(46005);
  22.          enable_interrupts(GLOBAL);  
  23.  
  24.          while(true)                                                                        
  25.          {
  26.          output_high(pin_c0); delay_ms(1000); output_low(pin_c0); delay_ms(1000);   // Solo para simular otro proceso del programa      
  27.          }
  28.          }

De esta manera el retardo del timer0 lo hace cada 250ms letra a letra recorrida independiente de cualquier otra cosa del código ( sin importarle cuanto demore otra cosa como  output_high(pin_c0); delay_ms(1000); output_low(pin_c0); delay_ms(1000); ) y el mensaje se muestra en corrimiento cada 250 ms. esto es lo pretendido, pero.....

Peeeero (aquí hay un pero..), como el mensaje lcd_gotoxy(1,4); printf(lcd_putc,"%s",LCD_buffer2); también esta dentro del timer0 y como ya sabemos un printf demora mucho tiempo para una interrupción, el compilador  muestra algunos warning (solo warning por que en realidad el código lo compila y hace lo requerido).

Tal vez aquí se podría poder algunas banderas para que solo imprima?.

Saludos.
Título: Re:Mensaje desplazado con timer0
Publicado por: Eduardo2 en 20 de Noviembre de 2021, 19:51:56
No se con cuales micros y/o versiones de CCS  hay un ¿bug?  del compilador que te deshabilita las interrupciones en parte del delay.

Se soluciona de manera chancha pero fácil  redeclarando  #USE DELAY .

Me tomé la libertad de modificar tu código según mis gustos personales  :smiley:  y agregué otro #USE DELAY antes del void main()

Código: C
  1. #include<18F4550.h>
  2. #use delay(crystal=20M)
  3.  
  4. #NOLIST
  5.     #define LCD_ENABLE_PIN  PIN_D2
  6.     #define LCD_RS_PIN      PIN_D0
  7.     #define LCD_RW_PIN      PIN_D1
  8.     #define LCD_DATA4       PIN_D4
  9.     #define LCD_DATA5       PIN_D5
  10.     #define LCD_DATA6       PIN_D6
  11.     #define LCD_DATA7       PIN_D7
  12.  
  13.     #include<lcd.c>
  14. #LIST
  15.  
  16. const char Texto[]={"\377 Diesel agotado o Sensor da\356ado "};
  17. #define szTexto    (sizeof(Texto)-1)
  18.  
  19. int1 msjDiesel_habilitado=0 ;
  20.  
  21. //-------------------------------------------------------------
  22. #int_timer1           // Interrupcion cada 26.2144ms
  23. void timer1(void)
  24. {
  25. #define N_ms  (int8)(250/26.2144+.5)
  26.  
  27. static int8 caracter=0 , cont_lcd=N_ms ;   // ~250ms
  28.    
  29.     if(msjDiesel_habilitado)
  30.     {
  31.         if(--cont_lcd==0){ cont_lcd = N_ms ;  // ~250ms      
  32.            
  33.             lcd_gotoxy(1,4);
  34.             for(int8 ptxt=caracter,posicion=0 ; posicion<20 ; posicion++,ptxt++)
  35.             {
  36.                 if(ptxt==szTexto)   ptxt=0 ;     // ajusto ptxt                
  37.                 lcd_putc(Texto[ptxt]) ;
  38.             }            
  39.             if(++caracter==szTexto) caracter=0;
  40.         }
  41.     }
  42. }
  43. //-------------------------------------------------------------    
  44.  
  45. #use delay(crystal=20M)         // Si eliminás esto se pudre la interrupcion
  46. void main(void)
  47. {
  48.     lcd_init();
  49.     setup_timer_1(T1_INTERNAL|T1_DIV_BY_2);     //26.2 ms overflow
  50.     enable_interrupts(INT_TIMER1);
  51.     enable_interrupts(GLOBAL);
  52.  
  53.     msjDiesel_habilitado = true ;
  54.    
  55.     while(true)
  56.     {
  57.         output_high(pin_c0);
  58.         delay_ms(1000);
  59.         output_low(pin_c0);
  60.         delay_ms(1000);   // Solo para simular otro proceso
  61.      }
  62. }
Título: Re:Mensaje desplazado con timer0
Publicado por: Abner_emanuel en 20 de Noviembre de 2021, 22:08:36

Eduardo2.

Eres un Master, que manera de programar.  ((:-)).

Y gracias por tu tiempo, el código funciona, lo e armado físicamente y lo único raro que veo es que corre un poco lento, tal pareciera que ese retardo de 250 ms fueran de 2,500 ms pues el mensaje se dezplaza muy lento, pero en si Whooooo!!!.

Se ve muy chevere tu código.




Título: Re:Mensaje desplazado con timer0
Publicado por: Abner_emanuel en 21 de Noviembre de 2021, 23:38:38
Eduardo2

Retiro lo dicho y me retracto de lo comentado en el mensaje anterior. En realidad funciona al 100.

Citar
lo único raro que veo es que corre un poco lento, tal pareciera que ese retardo de 250 ms fueran de 2,500 ms pues el mensaje se dezplaza muy lento,

Como ahora lo digo, no corre lento, mas bien yo tenia un error.

Solo tengo una duda, se que el desborde del timer0 es 26.2144 ms como se ve en la imagen (gracias al Señor Rojo por ahorrarnos los cálculos a lápiz  :mrgreen:), ahora solo y para no llevármelo como receta de cocina.

Como haces para que el retardo sea de ~250ms`y esa, mi duda, al parecer viene en esto #define N_ms  (int8)(250/26.2144+.5)
o donde esta la parte para que sean los 250ms?.

Podridas explicarme por favor?.
Título: Re:Mensaje desplazado con timer0
Publicado por: Eduardo2 en 22 de Noviembre de 2021, 01:33:36
...
Como haces para que el retardo sea de ~250ms`y esa, mi duda, al parecer viene en esto #define N_ms  (int8)(250/26.2144+.5)
o donde esta la parte para que sean los 250ms?.
...

La interrupción ocurre cada 26.2144ms ,  por lo tanto tengo que dejar pasar 9 o 10 interrupciones (250/26.2144=9.536) antes de escribir el LCD. En realidad van a ser 262ms  (10*26.2144ms)

Al #define lo uso para que el compilador me haga el cálculo de cuantas interrupciones hay que dejar pasar.
Como el compilador te trunca el resultado de la operación, le sumo .5 para que resulte redondeado al entero mas cercano.
El (int8)  ahi no es necesario, sí lo es cuando se trata de un macro mas complejo porque te puede asignar mal.
Título: Re:Mensaje desplazado con timer0
Publicado por: KILLERJC en 22 de Noviembre de 2021, 05:16:42
Y en el programa lo tenes aca:

Citar
void timer1(void)
{
#define N_ms  (int8)(250/26.2144+.5)
 
static int8 caracter=0 , cont_lcd=N_ms ;   // ~250ms
   
    if(msjDiesel_habilitado)
    {
        if(--cont_lcd==0){ cont_lcd = N_ms ;  // ~250ms
Título: Re:Mensaje desplazado con timer0
Publicado por: Abner_emanuel en 22 de Noviembre de 2021, 12:19:56
Ok ok. Entendí como esta  :P.

Gracias nuevamente.

Ok ok. Entendí como esta  :P.

Gracias nuevamente.

*************************************************

El código así muestra 3 warning generados por que se está imprimiendo dentro de la interrupcion timer0. 

Interrupts disabled during call to prevent re-entrancy. 

Se pudieran poner algunas banderas para solo imprimir dentro del while { lcd_putc(Texto[ptxt]) ; } el texto y evitar estos warning o solo son advertencias y las ignoro?.
 
Título: Re:Mensaje desplazado con timer0
Publicado por: DominusDRR en 22 de Noviembre de 2021, 13:49:54
Ok ok. Entendí como esta  :P.

Gracias nuevamente.

¿Y hay manera de hacerlo sin interrupciones?
Título: Re:Mensaje desplazado con timer0
Publicado por: Eduardo2 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. 
Título: Re:Mensaje desplazado con timer0
Publicado por: DominusDRR 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
Título: Re:Mensaje desplazado con timer0
Publicado por: Eduardo2 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. }
Título: Re:Mensaje desplazado con timer0
Publicado por: mariacontenis 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.
Título: Re:Mensaje desplazado con timer0
Publicado por: DominusDRR en 01 de Diciembre de 2022, 20:44:36
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.

Googléalo:


https://www.google.com/search?q=millis()%3B+en+Arduino%3F&rlz=1C1CHBD_esEC914EC916&sourceid=chrome&ie=UTF-8 (https://www.google.com/search?q=millis()%3B+en+Arduino%3F&rlz=1C1CHBD_esEC914EC916&sourceid=chrome&ie=UTF-8)

https://robots-argentina.com.ar/didactica/arduino-usando-la-funcion-millis-en-lugar-de-delay/#:~:text=millis()%20devuelve%20el%20n%C3%BAmero,sin%20signo%20(unsigned%20long). (https://robots-argentina.com.ar/didactica/arduino-usando-la-funcion-millis-en-lugar-de-delay/#:~:text=millis()%20devuelve%20el%20n%C3%BAmero,sin%20signo%20(unsigned%20long).)
Título: Re:Mensaje desplazado con timer0
Publicado por: Eduardo2 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.
Título: Re:Mensaje desplazado con timer0
Publicado por: mariacontenis 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?.
Título: Re:Mensaje desplazado con timer0
Publicado por: Eduardo2 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.
Título: Re:Mensaje desplazado con timer0
Publicado por: mariacontenis 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?.
Título: Re:Mensaje desplazado con timer0
Publicado por: Eduardo2 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)
Título: Re:Mensaje desplazado con timer0
Publicado por: mariacontenis 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.
Título: Re:Mensaje desplazado con timer0
Publicado por: Eduardo2 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.
Título: Re:Mensaje desplazado con timer0
Publicado por: mariacontenis 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