Autor Tema: tiempo de ejecucion codigo C en MPLAB  (Leído 16358 veces)

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

Desconectado Rick_x

  • PIC10
  • *
  • Mensajes: 32
tiempo de ejecucion codigo C en MPLAB
« en: 28 de Enero de 2010, 18:21:53 »
Estimados foreros quisiera saber como puede medir el tiempo de ejecucion de un conjunto de instrucciones en MPLAB

ya que debo medir el tiempo exacto en que tomo cada muestra del ADC. para tener una frecuencia precisa de muestreo.

esta es mi funcion que deseo medir el tiempo de ejecucion:

   while(p!=4)                                                      <=== DESDE AQUI
   {
      set_adc_channel(0);   
      delay_us(20);         
      vol=read_adc();     

      set_adc_channel(1);     
      delay_us(20);
      cor=read_adc();

      if (vol<10)
           printf("   %lu",vol); 
       else   
            if(vol<100)
               printf("  %lu",vol); 
            else
               {   
               if (vol<1000)
                  printf(" %lu",vol);   
               else
                    printf("%lu",vol);   
               }   

   if (cor<10)
           printf("000%lu",cor); 
       else   
            if(cor<100)
               printf("00%lu",cor);   
            else
               {   
               if (cor<1000)
                  printf("0%lu",cor); 
               else
                    printf("%lu",cor);   
               }   


// Mostrar por el LCD

      lcd_gotoxy(1,1);
      printf(lcd_putc, "V = %lu   ", vol);
      printf(lcd_putc, "\nI = %lu   ", cor);

       delay_ms(100);        // AQUI AJUSTARE EL RETARDO NECESARIO PARA TENER EL TIEMPO QUE REQUIERO PARA TENER CIERTA FRECUENCIA DE MUESTREO

      d=kbd_getc();
      p=d-48;                         <====  HASTA AQUI

   }


muchas gracias

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: tiempo de ejecucion codigo C en MPLAB
« Respuesta #1 en: 28 de Enero de 2010, 20:01:34 »
Supongo que es CCS, que versión?

En las versiones 4 en la pestaña COMPILE hay un botón que se llama C/ASM List, cuando cliqueas ahí, previamente el programa haya sido compilado antes, te parece una nueva ventana que es el código ASM para el c que hiciste, ahí te fijas cuantas instrucciones hay y previamente sabiendo de la hoja de datos cuantos ciclos consume cada instrucción, y según la frecuencia de tu oscilador calculas el valor aproimado que tendrá en ejecutarse tu sección de código.

Otra forma todavía no la conozco, si tienes versiones más recientes de CCS, busca cada menú seguro encuentras esa opción de C/ASM List. O puedes buscar el archivo .LST que genera el compilador, eso al menos creo que siempre se genera sea la versión que sea.

saludos.
.

Desconectado Duende_Azul

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 902
Re: tiempo de ejecucion codigo C en MPLAB
« Respuesta #2 en: 28 de Enero de 2010, 22:20:15 »
En Mplab usa el "stopwatch" eso te dice cuanto tiempo ha tardado la ejecución del programa entre dos breakpoint.

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: tiempo de ejecucion codigo C en MPLAB
« Respuesta #3 en: 29 de Enero de 2010, 10:36:07 »
Muy buena opción Duende, no la sabía. Se la puede aplicar en C tb? o es solo para ASM.

Saludos.
.

Desconectado AKENAFAB

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3227
Re: tiempo de ejecucion codigo C en MPLAB
« Respuesta #4 en: 29 de Enero de 2010, 11:01:24 »

Sirve para los 2 .

Selecciona MPLAB SIM como debugger , luego ve a settings y en OSC/TRACE "PROCESSOR FRECUENCY" escribes la velocidad del pic y listo. Ahora selecciona STOP WATCH , de ahi ayudate con los breakpoints.

Saludos Pana!

Desconectado marito

  • PIC16
  • ***
  • Mensajes: 217
Re: tiempo de ejecucion codigo C en MPLAB
« Respuesta #5 en: 01 de Febrero de 2010, 15:27:22 »
Hola a todos!
Estoy utilizando el Stop Watch para calcular el tiempo de ejecución de programa para poder implementar un controlador.
Estoy intentando utilizar el Timer0 para hacer esta medición de tiempo; para hacer el cálculo cuento el número de veces que se activo la interrupción por desbordamiento del timer0 y el numero de cuentas que tengo en el timer0 en el momento de hacer el cálculo.
Lo que observo es que los valores obtenidos por ambos métodos, son muy diferentes. Cual de los dos se puede tomar como método más confiable y preciso para operar un controlador?
Gracias.
Saludos.

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: tiempo de ejecucion codigo C en MPLAB
« Respuesta #6 en: 01 de Febrero de 2010, 21:24:52 »
Hola gente.
Marito, yo utilizé en varias ocasiones el StopWatch del MPLAB y es preciso 100%. Hice en asm un generador de barras de colores para pruebas de TV y también para probar monitores y justamente utilizé el StopWatch para ir viendo el tema de los retardos que tenía que agregar para que la señal no pierda los tiempos y el TV o Monitor a probar se valla de sincronismos.

En cuanto al tema del TMR0, también es preciso. Habría que ver como hacés para calcular el tiempo. ¿Podés dar algunos detalles?
Yo usé el TMR0 con entrada externa para hacerme un Frecuencimetro y también me hice un tacómetro para aeromodelismo.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado marito

  • PIC16
  • ***
  • Mensajes: 217
Re: tiempo de ejecucion codigo C en MPLAB
« Respuesta #7 en: 01 de Febrero de 2010, 21:42:45 »
Hola!
AngelGris, te comento como tengo funcionando el medidor de tiempo con el Timer0.
Declare una variable contador de tipo entero global. Esta variable la incremento cada vez que se genera una interrupción RTCC producida por el Timer0.
Dentro de la rutina principal, la cual quiero calcular el tiempo de ciclicidad, tomo el valor del Timer0 en el momento en el que hago el cálculo en cuestión.
El cálculo lo realizo con la siguiente expresión:

CycleTime=(float)(0.0000512*get_timer0()+0.0131072*contadorglobal);

Las constantes las obtuve a partir de un cristal de 20MHz. Sabiendo que:

Tiempo= 4 * Preescaler / 20MHz.

Tiempo de ciclo de ejecución = 0.0000512 = 4 * 256 / 20MHz

Tiempo de desbordamiento = 0.0131072 = (4 * 256 / 20MHz) * 256

Los valores medidos los envío vía puerto serie (uso el max232) para visualizar en una terminal.

El tiempo que mido de esta manera es mucho menor que el que obtengo con el simulador de MPLAB. En el simulador, coloque un breakpoint en la primera instrucción de la rutina principal. Una vez que la ejecución llega ahí, reinicio el medidor y doy la orden de RUN. Así lo realizo varias veces para medir el tiempo dentro de la rutina.

No se si la comunicación serial metida en el medio puede afectar, más que nada en los cálculos echos en el simulador. (Uso el printf para enviar a la PC).

Gracias por la ayuda!!!
Saludos

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: tiempo de ejecucion codigo C en MPLAB
« Respuesta #8 en: 02 de Febrero de 2010, 12:15:58 »
Cuando inicias el conteo con el timer 0 seguramente escribes en el timer, lo cual provoca que haya 2 ciclos de reloj en el cual el timer no se incrementa. Luego al leer la cuenta, conviene detener el timer y luego leerlo. Prueba enviando por serial el contador de overflow y la lectura del timer para que determines la cantidad de ciclos y veas la diferencia que hay con el Stop Watch.


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

Desconectado marito

  • PIC16
  • ***
  • Mensajes: 217
Re: tiempo de ejecucion codigo C en MPLAB
« Respuesta #9 en: 02 de Febrero de 2010, 12:40:04 »
Hice una captura de los valores que obtengo para la rutina cíclica principal a la cual estoy midiendo el tiempo.
El tiempo que mido con el Stop Watch es de 66 mseg y con el timer0 calculo 13 mseg.
Un dato más, es que cuando incluyo la instrucción de delay de 10 mseg, ninguno de los dos metodos de calculo incrementa este tiempo.
Alguna sugerencia?
Saludos!
Adjunto imagen de captura
« Última modificación: 02 de Febrero de 2010, 12:44:47 por marito »

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: tiempo de ejecucion codigo C en MPLAB
« Respuesta #10 en: 02 de Febrero de 2010, 19:30:23 »
¿En la interrupción del TMR0 hacés algo más además de incrementar el contador? Porque tal vez te esté pasando lo que indica Suky
¿No te estará pasando que se desborde la variable contadorglobal (volviendo a 0)? y por ello cuando hacés el cálculo en el programa te da mucho menor que con el StopWatch. La variable contadorglobal conviene que sea "unsigned" ya que nunca va a tomar valores negativos y de ese modo le das más rango.

Yo también utilizaría la opción del MPLAB de ver los registros para ir viendo los valores que van tomando las variables.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado marito

  • PIC16
  • ***
  • Mensajes: 217
Re: tiempo de ejecucion codigo C en MPLAB
« Respuesta #11 en: 02 de Febrero de 2010, 19:37:04 »
En la interrupción del Timer0, sólo incremento el contador global.
El programa principal que estoy "cronometrando" es cortito, solo tiene 3 printf y el calculo del tiempo de ciclicidad, luego reseteo las variables de calculo.
En la medición con stopwatch, obtengo 66 ms y en el calculo con Timer 17ms. Por las pocas instrucciones que realizo, me inclino más por el calculo con timer0.
Aunque usando un breakpoint en cada sentencia con el stopwatch, pareciera que es correcta tambien la medicion. Lo unico que configure para usar el stopwatch, es el cristal a 20MHz. No se si me estar faltando algo.
Saludos!

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: tiempo de ejecucion codigo C en MPLAB
« Respuesta #12 en: 02 de Febrero de 2010, 19:52:53 »
¿Podés subir el programa?

Si incorporás es que rutinas de delay también tenés que configurar la frecuencia de cristal en el programa.

Yo haría lo siguiente. Comentaría todo el programa y probaría con algo sencillo en el programa principal, como para descartar cualquier error en como se calcula el tiempo.


Código: [Seleccionar]

#use delay (clock=20000000)

void mani()
{
    delay_ms (30);
    // tu rutina de calculo de tiempo
}

De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: tiempo de ejecucion codigo C en MPLAB
« Respuesta #13 en: 02 de Febrero de 2010, 20:54:06 »
Este es un código que use para probar las diferencias entre StopWatch y Tmr0
Código: [Seleccionar]
/*
Programa para evaluar las diferencias de medición entre el
StopWatch y el TMR0
*/

#include <16f628a.h>
#use delay(clock=20000000)

unsigned int ContadorGlobal;

#int_timer0
void timer0interrupt()
{
ContadorGlobal++;
clear_interrupt(int_timer0);
}


void main()
{
unsigned long  cuenta;
float CycleTime;
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER0);


while (1)
{
CycleTime = 0;
ContadorGlobal = 0;
set_timer0(0);
//delay_ms(30);
for (cuenta=400000; cuenta != 0; cuenta--);

CycleTime=(float)(0.0000512*get_timer0()+0.0131072*contadorglobal);
}
}

y te adjunto una captura de la pantalla donde se vé el tiempo que indica el StopWatch y la variable CycleTime

De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado marito

  • PIC16
  • ***
  • Mensajes: 217
Re: tiempo de ejecucion codigo C en MPLAB
« Respuesta #14 en: 03 de Febrero de 2010, 00:11:06 »
Antes que nada, gracias por la ayuda.
Un dato, es que cuando utilizo el simulador, siempre obtengo el mismo valor en el tiempo mostrado en el stop watch y en la variable cycletime, la diferencia la observo cuando comparo el valor del stopwatch en el simulador y el valor cycletime enviado por el PIC a la PC. El problema de esto es no saber cual de los valores es el correcto.

El programa que me pasaste funciona excelente, agregue un printf al final del for para visualizar via terminal el puerto serie. Por lo que el valor enviado por el PIC a la PC y el valor medido con el simulador son iguales.

El problema ocurre cuando intercalo un printf antes del for. Por ejemplo:


while (1)
   {
      CycleTime = 0;
      ContadorGlobal = 0;
      set_timer0(0);
      //delay_ms(30);
                printf(" %f ", cycleTime);       //nuevo printf para chequear el retardo introducido
      for (cuenta=400000; cuenta != 0; cuenta--);

      CycleTime=(float)(0.0000512*get_timer0()+0.0131072*contadorglobal);
   }



El valor enviado va a ser siempre 0, pero a fines de evaluar el efecto viene bien.
Ahora midiendo, con el StopWatch, obtengo 47,2 ms (colocando el break point en la primera instrucción dentro del while)
Mientras que el valor enviado via seria, calculado por Timer0 es de 23,9 ms.
El nuevo printf, produce un incremento de 33 ms en uno de los valores y en el otro de 10ms. Siendo los valores iniciales de 13ms aproximadamente(Dentro del bucle while).

Por lo que aparentemente, la diferencia puede ser causada por el printf de la tarnsmisión serie. Estás de acuerdo?

Nuevamente, gracias!
Saludos
« Última modificación: 03 de Febrero de 2010, 00:17:28 por marito »