Autor Tema: Sobre los delays(xx)  (Leído 3694 veces)

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

Desconectado Berto

  • PIC16
  • ***
  • Mensajes: 191
Sobre los delays(xx)
« en: 10 de Febrero de 2016, 19:33:34 »
E re-comprobado que delay_ms(500); No se corresponde a 0.5 sg trabajando a 4Mhz tambien vi la primera vec que añadi un nuevo micro este se retrasaba mas incluso poniendolo a delay_ms(200); Esto al parecer era porque por defecto a los nuevos. Proteus los pone a 1Mhz si no le dices otra cosa.
Se que este tiempo aumenta con todas las instrucciones y funciones que tenga por detras, pero no me cuadra a 4 Mhz Cuales son los Mhz necesarios para que delay_ms(500); actue como 0.5sg
Luego esta esto Se que esta por el foro ya escrito pero lo siento no lo e encontrado, creo que hablo de picosegundos ¿como se ponia?

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re:Sobre los delays(xx)
« Respuesta #1 en: 10 de Febrero de 2016, 20:03:24 »
en lenguaje C ( a al menos en CCS) no conseguirás la precisión que buscas, en tu caso tiene 2 opciones:

- trabajas los retardos en asm
- reduces el valor xx hasta que consigas los 500ms

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Sobre los delays(xx)
« Respuesta #2 en: 10 de Febrero de 2016, 20:31:45 »
O no usar retardos :P

Desconectado Berto

  • PIC16
  • ***
  • Mensajes: 191
Re:Sobre los delays(xx)
« Respuesta #3 en: 10 de Febrero de 2016, 20:46:33 »
Bueno te as salido del tema. Pero me equivoque son microsegundos lo que buscaba us acabo de cambiar  delay_ms(1); delay_us(80); es poco ahora va de 19  4 fallos, prueba y error, prueba y error, esto es lo ultimo que are antes de acostarme

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Sobre los delays(xx)
« Respuesta #4 en: 10 de Febrero de 2016, 20:57:58 »
Sinceramente no se por que deberia darte mal... Puedo entender que no tengas una precision perfecta. Por que la mayoria define una funcion de delays  de unos 3 NOPs o 10. Y luego llama a esa funcion varias veces, el llamado a la funcion o el loop termina agregando un poco mas de tiempo.

Tambien otros limitantes que estan implicitos segun lo que nombre antes es que hay un limite minimo y un limite maximo que se le puede pasar a estas funciones. Pero no deberian diferir en demasiado el tiempo. Recorda que es C, y si queres realmente hacer algo en el que el tiempo es esencial al borde de 4 ciclos de reloj ( que es lo que manejan los PIC16/18 ) lo mejor es ASM.

Primero me aseguraria, creando un muy pequeño ejemplo y ahi veria la diferencia.. es decir:

Código: C
  1. //fuses
  2. #use fast_io(b)
  3. #use delay(clock=4M)
  4.  
  5. void main(void)
  6. {
  7.      set_tris_b(0);
  8.      while(1)
  9.      {
  10.            output_high(PIN_B1);
  11.            delay_us(40);
  12.            output_low(PIN_B1);
  13.            delay_us(40);
  14.      }
  15. }

Notaras en un osciloscopio que el pulso de 1 a 0 dura 40us y el pulso de bajo a alto tal ves dure unos 45us.
Y ahi comprobarias si realmente esta funcionando mal o no los "delays"
« Última modificación: 10 de Febrero de 2016, 21:02:30 por KILLERJC »

Desconectado Berto

  • PIC16
  • ***
  • Mensajes: 191
Re:Sobre los delays(xx)
« Respuesta #5 en: 11 de Febrero de 2016, 18:03:47 »
Este pequeño delay era para asegurarse de que otro micro abia recivido un flanco alto algo a si
PIC1
output_high(PIN_C7);//C7 salidaPIC1 a C7entradaPIC2
(necesitaba el microdelay aqui)
if(Input(PIN_c1))///recivido

PIC2
if(Input(PIN_c7))
output_high(PIN_C1);//C1 salidaPIC2 a C1entradaPIC1

Me e librado de el haciendo que la salida PIC1_C7 sea constante, pero si por un instante pasa a 0
PIC2 apagara su C1 salida asta que se cumpla cierto evento dentro de el independiente de que PIC1_C7 sea 1 constantemente

pero me es imposible olvidarme de otros y si que son de cuidado, parece que hay que tener en cuenta que en el transcurso de estos el micro no hace nada, adsolutamente nada, no atiende a nada.

Citar
creando un muy pequeño ejemplo

Tu mejor ejemplo esta en otra parte del foro, me ayudo a hacer esto:
Código: [Seleccionar]
mdi=0; //Elfor faborece la interrupcion 25x10 mejor que 250
for(cx=0;25>cx;cx++){
if(lee!=0) { if(!mdi){ mdi=1; modifica(lee); lee=0;  } }//trampas de juego

if(sx){ see(XX); pri(0,nu); } //sx=TRUE micro-sensor fue interrumpido para atender INT_EXT

delay_ms(10);  } //BUENA 25 X 10
}///constancia de suceso elcons*250mlsg

Citar
en lenguaje C ( a al menos en CCS) no conseguirás la precisión que buscas

Cierto con todo hay mas bien 2 animaciones por segundo como mucho, me pasba lo mismo con VB6, pero aqui todavia es mas exagerado.
Lo unico seguro con lo que puedo contar del todo es que es proporcional delay_ms(500); siempre sera un tiempo mayor a delay_ms(400);


 

 

Desconectado Berto

  • PIC16
  • ***
  • Mensajes: 191
Re:Sobre los delays(xx)
« Respuesta #6 en: 11 de Febrero de 2016, 18:41:38 »
Siempre Proteus. No utilizo crystal lo intente me parece una buena idea para sincronizar todos los flancos de subida y bajada de los micros a la vec Lo monte todo como vi en un video de youtu pero no me funciono el oscilador estaba kao no daba nada este proyecto ya no lo conservo. Si me pasa algo con los Mhz de 1 a 4 hay diferencia pero e probado a ponerlos a 10 y no hay mejoras  de rendimiento No se si es porque virtualmente no son independientes el simulador tiene que atender a 5 micros y muchos componentes a la vec. Todavia no e utilizado el timer

Desconectado Berto

  • PIC16
  • ***
  • Mensajes: 191
Re:Sobre los delays(xx)
« Respuesta #7 en: 14 de Febrero de 2016, 13:02:53 »
Vale esto es lo que hay puede ir un poco mas rapido poniendo las globales int1 DT=0 (detalle=false) cosa que no va bien al final pero esto es otro tema

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1937
    • Sicoy
Re:Sobre los delays(xx)
« Respuesta #8 en: 15 de Febrero de 2016, 15:40:02 »
en lenguaje C ( a al menos en CCS) no conseguirás la precisión que buscas, en tu caso tiene 2 opciones:

- trabajas los retardos en asm
- reduces el valor xx hasta que consigas los 500ms

Usa un temporizador y su interrupción para conseguir lo que quieres.
Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado Berto

  • PIC16
  • ***
  • Mensajes: 191
Re:Sobre los delays(xx)
« Respuesta #9 en: 16 de Febrero de 2016, 09:31:21 »
PCWHD CCS 5.0? Tengo que volver a instalarlo para ver "?" No lo dice en propiedades
Proteus 8
El zip donde lo e metido es este 7z920 . La ultima vec esta pagina no me acepto winrar.
Mandame uno valido.

Todabia estoy aprendiendo a ver de que color es SPI. Una cosa si el timer tiene que contar asta 255
¿sigue actuando bajo un delay? Si no es asi, no lo quiero. Aparte que este micro adicional no solo hace de temporizador de eventos lleva a cavo otras tareas controlando un motor y otro LCD claro que este ultimo es porque no se modificar la libria kbd para controlar un LCD 16X4

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Sobre los delays(xx)
« Respuesta #10 en: 16 de Febrero de 2016, 12:48:40 »
Citar
Una cosa si el timer tiene que contar asta 255
¿sigue actuando bajo un delay
Si y obviamente necesitas de una interrupcion

Desconectado Berto

  • PIC16
  • ***
  • Mensajes: 191
Re:Sobre los delays(xx)
« Respuesta #11 en: 19 de Abril de 2016, 13:36:27 »
Citar
Usa un temporizador y su interrupción para conseguir lo que quieres.

Problematico. Si estaba utilizando un 2ºmicro a parte como contador del 1º pero al intentar librarme de el metiendole el timer1 en el 1º ocurre que si este esta sumerjido bajo otra interrupcion, no atiende al void timer1 (ni debe hacerlo Int_ext es prioritaria)

Citar
Una cosa si el timer tiene que contar asta 255
¿sigue actuando bajo un delay
Si y obviamente necesitas de una interrupcion

Si eso parece pero si este contador se desborda durante el delay() o otra interrupcion. Este sigue adelante de 0 a set_timer pero sin atender en el momento adecuado a todos los desbordamientos. De la manera en que e elavorado el 1º no puedo librarme del 2º es mejor que este se encarge aparte de los timer.

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1937
    • Sicoy
Re:Sobre los delays(xx)
« Respuesta #12 en: 19 de Abril de 2016, 14:11:05 »
Citar
Usa un temporizador y su interrupción para conseguir lo que quieres.

Problematico. Si estaba utilizando un 2ºmicro a parte como contador del 1º pero al intentar librarme de el metiendole el timer1 en el 1º ocurre que si este esta sumerjido bajo otra interrupcion, no atiende al void timer1 (ni debe hacerlo Int_ext es prioritaria)

Citar
Una cosa si el timer tiene que contar asta 255
¿sigue actuando bajo un delay
Si y obviamente necesitas de una interrupcion

Si eso parece pero si este contador se desborda durante el delay() o otra interrupcion. Este sigue adelante de 0 a set_timer pero sin atender en el momento adecuado a todos los desbordamientos. De la manera en que e elavorado el 1º no puedo librarme del 2º es mejor que este se encarge aparte de los timer.

Pues si la interrupción del temporizador sucede cuando se está atendiendo a otra interrupción, deberías sumar el valor acumulado, ya que el temporizador sigue contando los pulsos de reloj después de desbordase.

Yo lo hago así, en este ejemplo:

Código: C
  1. #define PR1_    0xF380// Yo deseo que mi temporizador cuente desde 0xF380 hasta 0xFFFF
  2.  
  3. void InicializarTemporizador1(void)
  4. {
  5.     TMR1L = 0x80;
  6.     TMR1H = 0xF3;
  7.     T1CON = 0x40;
  8.     INTCONbits.PEIE = 1;
  9.     PIE1bits.TMR1IE = 1; // Habilito la interrupción
  10. }
  11.  
  12. /******** Interrupción por temporizador 1 *******/
  13.  
  14. if (PIR1bits.TMR1IF)
  15.     {
  16.         PIR1bits.TMR1IF = 0;
  17.         TMR1 += PR1_; // sumo el valor acumulado para compensar el error por la latencia de la interrupción
  18.         if (TMR1 < PR1_) TMR1 = 0xFFFF; // Si la suma es menor que PR1_, implica que hay que desbordar una segunda vez al temporizador
  19.         if (app_mtouch_datos.retardo) app_mtouch_datos.retardo--;
  20.        
  21.         if (app_proposito_general_datos.retardo) app_proposito_general_datos.retardo--;
  22.     }
« Última modificación: 19 de Abril de 2016, 14:13:33 por DominusDRR »
Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Sobre los delays(xx)
« Respuesta #13 en: 19 de Abril de 2016, 14:26:16 »
¿ Por que tendrias un 2do micro para ser de contador del 1ero ? Mejor no me lo respondas... Esto es peor que apretarselo contra la puerta.

Citar
ocurre que si este esta sumerjido bajo otra interrupcion, no atiende al void timer1

A no ser que poseas un micro con prioridades no vas a lograr eso JAMAS ( y darle prioridad al timer obviamente ), ademas una interrupcion debe ejecutarse rapidamente, si no lo hace provoca esos problemas y caeria en la categoria que esta mal programado. Pero el problema es que exigis que la prioridad sea de la interrupcion externa.

Y aca es donde tenes que decidir, si gastar 10us en la interrupcion del timer y demorar la externa o viceversa.

Citar
Si eso parece pero si este contador se desborda durante el delay() o otra interrupcion. Este sigue adelante de 0 a set_timer pero sin atender en el momento adecuado a todos los desbordamientos. De la manera en que e elavorado el 1º no puedo librarme del 2º es mejor que este se encarge aparte de los timer.

Si se desborda durante un delay deberia entrar a la interrupcion, si tenes un delay en una interrupcion entonces es un problema de mala programacion, si estas en otra interrupcion vas a tener que esperar para salir para poder entrar de nuevo a la interrupcion, y si,se va a pasar un par de microsegundos si usas el timer solo. Podes usar el modulo CCP para que esto no ocurra, es decir que si se retrasa 10us, esto no se traslade a la proxima interrupcion, si lo que intentas crear es una base de tiempo. Si ya tu interrupcion bloquea a tu timer/CCP por mas de 1 overflow, entonces esta mal programado.

El CCP en modo Compare,, la linea de tiempo seria asi, suponiendo que es de 10ms la interrupcion:

0us - Ocurre la igualdad, activa interrupcion, esta en otra interrupcion asi que no entra, le faltan 100us para salir de esa interrupcion
100us - Sale de la otra interrupcion, entra a la del CCP
10ms exactos - Se produce otra ves la interrupcion del CCP, esta ves no hay otra interrupcion en curso
20ms exactos - Se produce interrupcion del CCP, lamentablemente estaba en otra interrupcion y le faltaban 50us
20ms y 50us -  Entra a la interrupcion del CCP
30ms exactos - Se produce la otra interrupcion del CCP.

Eso con el timer solo hubiera sido distintos, hubieras tenido algo asi:

0us - Ocurre overflow, activa interrupcion, esta en otra interrupcion asi que no entra, le faltan 100us para salir de esa interrupcion
100us - Sale de la otra interrupcion, entra a la del timer, y se carga de nuevo el timer
10ms y 100us - Se produce otra ves la interrupcion del timer, esta ves no hay otra interrupcion en curso
20ms y 100us - Se produce interrupcion del timer, lamentablemente estaba en otra interrupcion y le faltaban 50us
20ms y 150us -  Entra a la interrupcion del timer y recarga
30ms y 150us - se produce la otra interrupcion del timer.

Como observaras se va acumulando el error. Mientras que usando el CCP no.

Ahora si necesitas que la reaccion sea exacta, entonces dedicalo a otro micro, pero me cuesta creer que necesites de algo tan complejo como eso. O mejor ir por una FPGA/CPLD


Citar
Pues si la interrupción del temporizador sucede cuando se está atendiendo a otra interrupción, deberías sumar el valor acumulado, ya que el temporizador sigue contando los pulsos de reloj después de desbordase.

Si necesita tanta precision como el dice eso no lo va a salvar, ya que tenes que tener en cuenta si posee preescaler eso no lo va a poder sumar o restar y siempre va a tener un error. Ademas es complicarse las cosas teniendo el CCP que te lo hace por vos mismo a las cosas.

En resumen, no se lo que busca el del timer, Si es que sea una base exacta de tiempo o tener la reaccion que apenas se produzca la interrupcion actuar. En paralelo no puede actuar a no ser que posea 2 nucleos o use una FPGA/CPLD.
« Última modificación: 19 de Abril de 2016, 14:35:11 por KILLERJC »

Desconectado Berto

  • PIC16
  • ***
  • Mensajes: 191
Re:Sobre los delays(xx)
« Respuesta #14 en: 20 de Abril de 2016, 16:50:06 »
enable_interrupts(INT_TIMER1);
supongo que es el que trata este registro en el tuyo
 PIE1bits.TMR1IE = 1; // Habilito la interrupción

Esta parte del codigo la desconozco, pero no veo que me pueda funcionar
Citar
TMR1 += PR1_; // sumo el valor acumulado para compensar el error por la latencia de la interrupción
        if (TMR1 < PR1_) TMR1 = 0xFFFF; // Si la suma es menor que PR1_, implica que hay que desbordar una segunda vez al temporizador

No entiendo lo de 2ª vez yo lo que veo es un incremento de compensacion para que lo haga antes. Sin entrar en hexadecimal
si quiero que mi timer1 cuente de 5500 a 6600 valdria si la durante la INT_EXT  el TMR1 solo hubiese contado unos 700 durante esta pero es que el problema es que puede ser mas de 7000/1100=se perdieron + de 6 eventos. No me compensa compensa desbordarlo 1ª sola vez de inmediato.

My mala programacion si no hay otro remedio que llamarla a si es que aunque el void timer1 este hecho para saltar cada 20ms
evento minimo cada 2 dc. El INT_EXT esta liado con el SPI y cuando hay muchos informes puede incluso llegar a + de 2 segundos, donde no puedo dar prioridad a timer1 este romperia la sincronizacion de todos los spi_read(); que recive del master

No veo mejor via que otro micro se encarge en paralelo de esto.

Lo que busco del timer aunque ahora esta de sobra con el 2ºPIC me gusta la idea de utilizarlo como evento interno veo util que este solo se produzca cada 20 o 0.5 ms como evento secundario sin interferir en el resto del codigo continuamente a lo que es prioritario.
Lo que no le veo al timer es que ventaja tiene para recoger un evento exterior. Yo para esto utilizo int_rb me parece mas logico leer un pequeño teclado nada mas pulsar una tecla y nada mas, un barrido continuo cada 0.5ms no lo veo util.

Que es CCP? Un memorizador de interrupciones?


 

anything