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

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

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Mensaje desplazado con timer0
« 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?
« Última modificación: 18 de Noviembre de 2021, 23:35:33 por Abner_emanuel »
El señor es mi pastor,  nada me faltará.

Desconectado remi04

  • PIC24F
  • *****
  • Mensajes: 657
Re:Mensaje desplazado con timer0
« Respuesta #1 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) {}

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1982
    • Sicoy
Re:Mensaje desplazado con timer0
« Respuesta #2 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
« Última modificación: 19 de Noviembre de 2021, 09:32:26 por DominusDRR »
Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Mensaje desplazado con timer0
« Respuesta #3 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.

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1982
    • Sicoy
Re:Mensaje desplazado con timer0
« Respuesta #4 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.
Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Mensaje desplazado con timer0
« Respuesta #5 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..
El señor es mi pastor,  nada me faltará.

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Mensaje desplazado con timer0
« Respuesta #6 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

 

* GIF 11-19-2021 10-39-22.gif
(37.63 kB, 498x393 - visto 375 veces)


(El led parpadea pero casi no se ve porque el tiempo apagado es corto)

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Mensaje desplazado con timer0
« Respuesta #7 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.
El señor es mi pastor,  nada me faltará.

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Mensaje desplazado con timer0
« Respuesta #8 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.
« Última modificación: 20 de Noviembre de 2021, 14:18:41 por Abner_emanuel »
El señor es mi pastor,  nada me faltará.

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Mensaje desplazado con timer0
« Respuesta #9 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. }

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Mensaje desplazado con timer0
« Respuesta #10 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.




El señor es mi pastor,  nada me faltará.

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Mensaje desplazado con timer0
« Respuesta #11 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?.
El señor es mi pastor,  nada me faltará.

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:Mensaje desplazado con timer0
« Respuesta #12 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.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Mensaje desplazado con timer0
« Respuesta #13 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

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Mensaje desplazado con timer0
« Respuesta #14 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?.
 
« Última modificación: 22 de Noviembre de 2021, 13:56:23 por Abner_emanuel »
El señor es mi pastor,  nada me faltará.


 

anything