Autor Tema: otra forma de generar retardos con el Timer  (Leído 26528 veces)

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

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: otra forma de generar retardos con el Timer
« Respuesta #15 en: 11 de Octubre de 2007, 18:21:02 »
Hola PalitroqueZ. Pase el programa de c a asm. ¿Cómo? muy facil pero trabajoso. Primero copié el programa, lo abri en el Mplab, luego cree el prooyecto y una vez generado el hex, lo abrí con el ICPROG y este tiene una herramienta que lo pasa a asm (lee el hex y da el asm, obvio).
El problema que no es muy legible, ya que no da la primera columna con palabras que usa el usuario. Si alguien le interesa, lo subo al foro.

Saludos.  :-/ :-/

sip, Trabajoso, porque hay que estudiar el código y eliminar lo que sea redundante, también hay que tener la tabla de las direcciones de los SFR para saber quien es quien .

Rulo, y es mas potente que solo pasar de C a ASM, ya que te separa cada comando que escribiste en C y te dice el equivalente en ASM de el.

SALUDOS!!

útil en el sentido de que por ejemplo algo que no sepamos hacer en asm, y nos ponemos de tramposo y miramos el listado del ccs haber como lo hace él  :twisted:  :5}

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

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: otra forma de generar retardos con el Timer
« Respuesta #16 en: 29 de Abril de 2008, 16:47:58 »
Teoría:

se me ocurrió otro ejemplo para madurar la forma de utilizar retardos y a la vez hacer otras cosas.

una situación común es utilizar funciones de inicialización empezando el main, el contador de programas (CP) entra y sale de la función y contínua normalmente.

es posible que dentro de una función de inicialización tengamos que hacer un retardo, bien aplicando lo aprendido usamos el retardo por interrupción del timer. perooo.. hay un pequeño detalle: la función se debe ejecutar una sola vez y el CP no debe entrar mas a ella. ¿como hacemos?

bien la respuesta que he estudiado es usar banderas y bucles condicionales

supongamos que tenemos la función vIniciar(), si vIniciar posee un retardo, entonces

- se debe partir el código interno exactamente donde vá el retardo.
- encerrar ambos pedazos en 2 if.
- al final del primer if, configuramos el timer para el retardo.
- ambos if serán regidos por unas banderas previamente declaradas.
- para ejecutar vIniciar una sola vez, en el bucle principal, encerramos a vIniciar dentro de un condicional guiado por otra bandera.

- así en cada pasada del bucle eterno, se preguntará por dicha bandera (llamemosla fIniciar) y NO se ejecutará mas nunca vIniciar.


Aquí va un programa de ejemplo:

Código: C
  1. /* Generando Retardos con el timer. 2 Parte
  2.    Pedro - PalitroqueZ
  3.  */
  4.  
  5. #include <18F4550.h>
  6. #fuses XT,NOMCLR,NOWDT,NOPROTECT,NOLVP
  7. #fuses NODEBUG,NOPBADEN,CPUDIV1,NOVREGEN //,PLL1
  8. #use delay(clock=4M)
  9.  
  10. int8 iBanderas;    // variables globales
  11. #bit fIniciar = iBanderas.0
  12. #bit fDurante_Retardo = iBanderas.1
  13. #bit fFin_Retardo = iBanderas.2
  14.  
  15. //***************************************
  16. // servicio de interrupción
  17. //***************************************
  18. #int_timer0
  19. void  tmr0_isr(){
  20.    fDurante_Retardo=1;
  21.    fFin_Retardo=1;
  22.    disable_interrupts(INT_TIMER0);
  23.    // deselecciona la fuente de interrupción
  24.    // para no ejecutarla a posteriori
  25. }
  26. //***************************************
  27. void vIniciar(){
  28.    if(!fDurante_Retardo){
  29.       delay_us(10);  // simula tiempo de lineas de programas
  30.       fDurante_Retardo=1;
  31.       set_timer0(21); // retardo de ~ 15ms
  32.       enable_interrupts(GLOBAL);
  33.       return;
  34.    }
  35.    if(fFin_Retardo){ //la otra mitad del programa dentro de vIniciar
  36.       delay_us(80);  // simula tiempo de lineas de programas despues del retardo
  37.       fIniciar=0;
  38.       disable_interrupts(INT_TIMER0);
  39.    }
  40. }
  41.  
  42. //***************************************
  43. // programa principal
  44. //***************************************
  45. void  main(){
  46.    int16 t;
  47.    // ... aqui va config puertos, modulos, etc.  
  48.    iBanderas=0b00000001;
  49.    //fIniciar = 1;
  50.    //fDurante_Retardo = 0;
  51.    //fFin_Retardo=0;
  52.    
  53.    
  54.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64|RTCC_8_BIT);
  55.    // configura el Timer0 base de tiempo interno, pre-escaler=1:64, contador de 8 bits
  56.    enable_interrupts(INT_TIMER0);
  57.    // selecciona la fuente de interrupción del timer0
  58.      
  59.    while(1){  // bucle eterno
  60.       delay_us(80);  // simula tiempo de otros procesos
  61.       if(fIniciar){ // pregunta para decidir si entrará o no a vIniciar
  62.          vIniciar();
  63.       }
  64.      
  65.       for(t=0;t<65000;t++){ // simula tiempo de otros procesos
  66.          delay_cycles(1);
  67.       }
  68.    }
  69. }

Ventajas:

- uuy muchas, principalmente se aprovecha el máximo tiempo permitido, la ejecución de multiples procesos.

- las interrupciones es lo mejor que hay.

- como quisiera que la gente de Microchip le fueran puesto interrupción a cada pin de los uCPIC


Desventajas:
- se estará preguntando si es posible la ejecución de una función en cada pasada del bucle eterno, pero si lo ven bien, no está mal perder unos cuantos ciclos, a que perder miles por un tonto retardo cíclico.

- si el CP dura mucho tiempo en volver al inicio del bucle, entonces vIniciar tomará mas tiempo en completar sus lineas de programa.

Eso depende de vIniciar. Si vIniciar requiere al menos retardo_calculado para funcionar correctamente, entonces no habrá problemas.

por el contrario, si retardo tiene que ser retardo_calculado y continuar las lineas faltantes inmediatamente, entonces hay que tomar medidas extremas como preguntar estrategicamente por la bandera fIniciar que rige a vIniciar. (calculando previamente los tiempos entre otros procesos para que cuadre el retardo de vIniciar)

- el programa se vuelve confuso si es largo, pero ¿quien ha dicho que lo óptimo es fácil?


corolarios de esta técnica:

- por cada retardo se usa 2 bandera + un condicional.
- se pueden reutilizar las banderas usadas en el timer.

« Última modificación: 06 de Mayo de 2008, 18:11:51 por PalitroqueZ »
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado marito

  • PIC16
  • ***
  • Mensajes: 217
Re: otra forma de generar retardos con el Timer
« Respuesta #17 en: 29 de Marzo de 2012, 19:57:04 »
Hola Palitroquez!!!

Necesito hacerte una consulta acerca del Timer0. Lo he usado en el PIC16F876A, y me ha funcionado de manera correcta; pero al intentar usarlo en el 18F4550 no me ha resultado.

El código de mi aplicación es el que sigue

Código: [Seleccionar]
#include <18F4550.h>
#fuses HSPLL,NOMCLR,NOWDT,PROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
#use rs232(baud=115200,xmit=pin_c6,rcv=pin_c7)//configuracion del puerto rs232 envia por pin_c6 y recibe por pin_c7
//#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, parity=N, bits=8) //habilitacón y configuración del protocolo de comunicación RS232 a través del MAX232, usando el PIN_A1 para transmitir al PC y el PIN_A2 para recibir desde el pc

int ContadorGlobal=0;

//Interrupción por desbordamiento del Timer0 RTCC
#int_TIMER0
void TMR0_isr(void)
{
ContadorGlobal++;
clear_interrupt(int_RTCC);




void main()
{

//Configuración de las interrupciones
//SETUP_COUNTERS(RTCC_INTERNAL,RTCC_DIV_256); // TIMER0: Clock Interno, Presescaler 128
SETUP_TIMER_0(RTCC_INTERNAL|RTCC_DIV_256);
ENABLE_INTERRUPTS(INT_TIMER0);                // Habilito Interrupción RTCC
ENABLE_INTERRUPTS(GLOBAL);                // Habilito Interrupciones

float Tiempo,VarA;

while(true)
{
//Rutina para calcular el tiempo de ciclo y reseteo de variables para timer
printf(" Tiempo = %f", tiempo);//imprimo datos por el usb;
//delay_ms(100);
Tiempo=(float)(0.000000083*get_timer0()+0.005461333*ContadorGlobal);

VarA=get_timer0();
ContadorGlobal=0;
set_timer0(0);

       
}
}

Lo que intento hacer, es medir el tiempo de mi bucle, pero resulta que el contador global no se incrementa nunca, por lo cual supongo que no debe generarse la interrupción del Timer0. Lo he intentado con el contador RTCC y tampoco ha funcionado.

Se te ocurre alguna razón por la cual me suceda esto viendo el código?

Desconectado AcoranTf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1093
Re: otra forma de generar retardos con el Timer
« Respuesta #18 en: 30 de Marzo de 2012, 12:47:23 »
Muy buen hilo, precisamente ayer charlaba con Kallitos el modo de hacer algo parecido, utilizando un solo timer y sus interrupciones, controlar varios temporizadores.
Me llamo la atencion que siendo tan practico este hilo, haya quedado "olvidado" desde hace casi dos años.

Para Marito, creo que se te olvido crear la funcion de atencion a la interrupcion, aparte no veo claro el resto de tu programita.

Saludos.

Desconectado marito

  • PIC16
  • ***
  • Mensajes: 217
Re: otra forma de generar retardos con el Timer
« Respuesta #19 en: 30 de Marzo de 2012, 12:52:51 »
AcoranTf, atiendo la interrupción en esta parte:

Código: [Seleccionar]
 
#int_RTCC
void RTCC_isr(void)
{
ContadorGlobal++;
clear_interrupt(int_RTCC);
}  

 

Aqui incremento el contador global con el cual luego calculo el tiempo de ejecucion de mi bucle.

Te referías a eso?

Desconectado AcoranTf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1093
Re: otra forma de generar retardos con el Timer
« Respuesta #20 en: 30 de Marzo de 2012, 23:08:18 »
Si, me referia a eso, no lo habia visto. No obstante no te puedo ayudar, ya que yo estoy empezando con C y precisamente los timers e interrupciones aun no los domino.

Saludos.

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: otra forma de generar retardos con el Timer
« Respuesta #21 en: 31 de Marzo de 2012, 00:10:02 »
Comparto la librería que desarrolle para C18: http://www.micros-designs.com.ar/c18-varias-temporizaciones-un-solo-timer/

Para ciertos proyectos es muy útil y se hace más practico y sencillo. Por ejemplo donde se necesiten activar alarmas temporizadas, que se activan si ocurre un evento por determinado tiempo, etc.. Para algo así la he utilizado con éxito  :)


marito, podes hacer un debug en Proteus o MPLAB SIM  ;-)


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado AcoranTf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1093
Re: otra forma de generar retardos con el Timer
« Respuesta #22 en: 01 de Abril de 2012, 11:01:03 »
Gracias Suky, voy a estudiar tu libreria. ¿Hay muchas diferencias entre CCS y C18?. Pienso que estudiar codigo ya hecho, ayuda a aprender y en el caso de las librerias ayuda a entender distintas formas de hacer las cosas.

Saludos.

Desconectado marito

  • PIC16
  • ***
  • Mensajes: 217
Re: otra forma de generar retardos con el Timer
« Respuesta #23 en: 01 de Abril de 2012, 12:58:13 »
Hola Suky, estoy haciendo usando el debug en MPLAB Sim, pero todavía no consigo hacer que funcione el timer0. Tengo que seguir trabajando con esto!

Desconectado marito

  • PIC16
  • ***
  • Mensajes: 217
Re: otra forma de generar retardos con el Timer
« Respuesta #24 en: 01 de Abril de 2012, 13:28:17 »
He logrado medir el tiempo de mi ciclo de programa, pero solo con el preescaler del RTCC en 1.

Cual puede ser el motivo por el que sólo puedo usar el pre escaler en 1?

Código: [Seleccionar]
SETUP_TIMER_0(RTCC_DIV_1);

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: otra forma de generar retardos con el Timer
« Respuesta #25 en: 01 de Abril de 2012, 13:40:04 »
Hola marito

respecto a tu pregunta inicial, lo que se me ocurre es que te faltó añadir algo en la configuración del timer, porque en los 18F hay que añadir otros parámetros. no recuerdo bien, pero deberías averiguar si ese timer trabaja con 8bits o 16 bits

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

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: otra forma de generar retardos con el Timer
« Respuesta #26 en: 01 de Abril de 2012, 14:30:46 »
Hola marito

respecto a tu pregunta inicial, lo que se me ocurre es que te faltó añadir algo en la configuración del timer, porque en los 18F hay que añadir otros parámetros. no recuerdo bien, pero deberías averiguar si ese timer trabaja con 8bits o 16 bits



Cierto, y en CCS en algunos casos si no se colocan todas las opciones del módulo se configura mal  :undecided:
No contesto mensajes privados, las consultas en el foro

Desconectado marito

  • PIC16
  • ***
  • Mensajes: 217
Re: otra forma de generar retardos con el Timer
« Respuesta #27 en: 01 de Abril de 2012, 16:48:14 »
Ok, voy a leer un poco el manual de CCS y las especificaciones del 18F4550. En un rato comento si encuentro algo!

Desconectado mariacontenis

  • PIC16
  • ***
  • Mensajes: 114
Re:otra forma de generar retardos con el Timer
« Respuesta #28 en: 03 de Enero de 2019, 12:36:55 »
Alguien se quedaría con la información de suky cuando puso es este mismo tema  http://www.micros-designs.com.ar/c18-varias-temporizaciones-un-solo-timer/     lo que pasa es que ya no está disponible esa í formación y me gustaría ver como lo pensó él hace tiempo para lograr el multi timer.

Desconectado Mecátronica2012

  • PIC10
  • *
  • Mensajes: 20
Re:otra forma de generar retardos con el Timer
« Respuesta #29 en: 02 de Agosto de 2019, 18:00:14 »
Desde hace algunos meses llevo implementando algo asi en mis programas con PIC, es algo similar a la funcion Mllis de arduino, incrementando una variable de tipo long, cada interrupcion del timer0, pero se me vienen varias interrogantes, es eficiente hacer esto? existira alguna otra alternativa para manejar eventos sin utilizar los dichosos delays()? Que pasaria por ejemplo si salta otra interrupcion distinta a la del timer0, podria afectarse mi medida de tiempo,?