TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Rick_x en 28 de Enero de 2010, 18:21:53

Título: tiempo de ejecucion codigo C en MPLAB
Publicado por: Rick_x 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
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: Cryn 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.
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: Duende_Azul 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.
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: Cryn 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.
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: AKENAFAB 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!
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: marito 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.
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: AngelGris 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.
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: marito 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
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: Suky 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!
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: marito 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
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: AngelGris 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.
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: marito 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!
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: AngelGris 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
}

Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: AngelGris 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

Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: marito 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
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: AngelGris en 03 de Febrero de 2010, 14:03:48
En la pantalla del StopWatch hay un botón de "zero" que tendrías que presionarlo justo despues de ejecutar la instrucción "set_timer0(0)" Porque es apartir de allí que empieza a contar nuevamente el Timer0.

Se me ocurre que podés sacar la instrucción "CycleTime= 0" del ciclo "while" y de esa manera lo enviado por la instrucción "PrintF" anterior al "for" sólo va a ser cero la primera vez, luego ya va a ir teniendo el valor que tome "CycleTime".

Habría que ver como está implementado el "PrintF". Quizá anula las interrupciones y por tal motivo el TMR0 nunca va a ir incrementando el valor de ContadorGlobal....

¿Como configuraste el puerto para la transmisión? Así hago las pruebas en casa a ver que resultado obtengo.

De paso te cuento que en otra prueba que hice saqué el "for" y dejé el "delay_ms(30)" y los valores fueron

StopWatch 30.358800(ms) y variable CycleTime 0.0300032012 (30.0032012ms)
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: marito en 03 de Febrero de 2010, 14:17:23
El tema de zerar la cuenta, lo hice en la primera instrucción dentro del while, colocando un breakpoint y cerando cada vez que se detiene. Haciendo la medición desde el Set_Timer0, la diferencia es pequeña (adjunto imagen)

Para recibir el valor de tiempo de ciclo en la PC, agregue un printf despues del bucle for:

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

      CycleTime=(float)(0.0000512*get_timer0()+0.0131072*contadorglobal);
      printf(" %f ", cycleTime);      //Valor de tiempo de ciclo enviado a la PC
   }


Cuando mido en el simulador, dejo el ultimo printf como comentario.

La configuración de del puerto que uso, para el PIC16F876A, es la siguiente:

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) //establezco el 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

Como te comente anteriormente, las mediciones son las mismas, hasta el momento en el que agrego el printf para comunicación.


Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: AngelGris en 03 de Febrero de 2010, 14:56:16
Te cuento...

Agregué esta línea a mi programa para configurar el USART del 16f628A "#use rs232(baud=9600, xmit=PIN_B2, rcv=PIN_B1)"

Y agregué dos instrucciones "PrintF", una después de la instrucción de delay (y comenté el "for") y una después de el cálculo del valor de CycleTime.... te adjunto imágen de la simulación

También lo simulé con el primer "PrintF" antes de la instrucción de delay y los valores de tiempo son los mismos.

Noté que en tu captura aparecía un mensaje relativo al conversor AD, ¿No habrá algún problema con ello?
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: marito en 03 de Febrero de 2010, 15:33:50
Los valores que te dan iguales están ambos en el simulador? En mplab?
Porque los valores que mido en mplab me dan iguales, la diferencia la observo con el valor enviado desde el pic, cuando este ejecuta el programa y envia el valor a la PC.
Estoy investigando el tema de los warnings que me aparecen en el simulador.
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: AngelGris en 03 de Febrero de 2010, 15:51:22
Ahora entiendo mejor y si, los valores que me dan similares es simulando en el MPLAB.

¿Porque no enviás otro dato que sea float y conocido y lo comparás con lo que te llega a la PC? Quizá es como vos dijiste y hay algún problema en el "PrintF"
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: marito en 03 de Febrero de 2010, 16:01:15
Intente enviando una constante float. Llega bien.

Lo que observo, es que el valor del ciclo se incrementa en el simulador, por cada printf que agrego, con respecto al valor calculado en el pic.

Por ejemplo, con un printf--> el pic envia a la PC 23ms y en el simulador mido 46ms aprox.


P.D. Según los datos que tengo de los warnings, son solo alarmas que no deberían afectar.
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: AngelGris en 03 de Febrero de 2010, 16:50:01
Pude simular la transmisión desde el MPLAB. En la pestaña Debuggerngs -> Settings; vas a la pestaña "UART1 IO" pones "Enable UART1 IO", en la opción de "Output" elegís "window"

Y de esa manera simula la transmisión y te aparecen en dicha ventana los datos que envía el PIC. Te adjunto la captura.

Fijate que en la ventana output aparece un dato todo en 0 (corresponde al primer PrintF, cuanlo CycleTime vale 0), y el segundo dato enviado se corresponde perfectamente con el valor de CycleTime.  También se puede observar una clarísima diferencia con el valor del StopWatch. Esto es debido a que el StopWatch también está tomando el tiempo que tarda en ejecutarse el segundo "printf" mientras que el dato enviado por el segundo "PrintF" está siendo tomado con anterioridad a la ejecución de esa instrucción.

Yo creo que es ahí donde le estabamos pifiando.
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: marito en 03 de Febrero de 2010, 17:51:37
Hice la prueba con la configuración que me pasaste en la siguiente rutina:

                CycleTime = 0;
      ContadorGlobal = 0;
      set_timer0(0);
      Printf(" %f ", CycleTime);
      delay_ms(30);
      //for (cuenta=400000; cuenta != 0; cuenta--);

      CycleTime=(float)(0.0000512*get_timer0()+0.0131072*contadorglobal);
      Printf(" %f ", CycleTime);

Lamentablemente, el valor que mido con el StopWatch (muy similar al que genera en la ventana Sim Uart) difiere del que calcula el PIC y envia al PC. En el simulador mido 71 ms y en el pic 40 ms.

Creo que habría que hacer los cálculos sobre el código en assembler, para tener el valor verdadero. Eso va a facilitar encontrar en que punto está el problema

Adjunto capturas del simulador y el terminal recibiendo los valores. Por lo que parece, tenemos un problema con los calculos que hace el Simulador o tengo un problema con el PIC.
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: AngelGris en 03 de Febrero de 2010, 18:43:55
Yo tuve que poner así la línea para que me muestre como a vos el número enviado; printf(" %1.6f ", cycleTime);  si ponía
printf(" %f ", cycleTime); -sin el 1.6- el tiempo de printF variaba... ¿Será que con el agregado del 1.6 (para darle el formato de 1 entero y 6 decimales) se fuerza a la funcioón a que siempre envie la misma cantidad de bytes y es allí donde puede habar un fallo?
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: marito en 03 de Febrero de 2010, 18:49:49
Entonces, como conclusión, el StopWatch, se puede usar para calcular tiempos siempre que no se estén usando comandos de comunicación. Sino, hay que trabajar con el Timer del PIC.
Voy a ver de hacer los cálculos en assembler, y publico si encuentro algo interesante.
Esperemos que si alguien ha experimentado igual que nosotros, también pueda sumar para dar claridad al tema.
Saludos Angel! Gracias por el aguante!!!
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: AngelGris en 03 de Febrero de 2010, 18:52:51
Cambié mi respuesta anterior, porque si el USART trabaja en modo independiente no debería influir en los tiempos....
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: marito en 03 de Febrero de 2010, 19:17:49
Repasando un poco lo que vinimos haciendo, veo que en la gráfica Programa2, mediste un tiempo de 46ms.
Lo que calcula el PIC es 40 ms.
Lo que no estaría tan alejado, pero con el mismo programa, yo mido 71ms.

Tenes el programa que usaste en esa simulación?
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: AngelGris en 03 de Febrero de 2010, 19:41:22
Este es el programa, y ahora lo simulé sobre un 16f876a y obtuve los mismos valores.

Yo estoy usando el MPLAB 8.10, y si no me equivoco el CCS 4.104

Código: [Seleccionar]
/*
Programa para evaluar las diferencias de medición entre el
StopWatch y el TMR0
*/

#include <16f876a.h>
#use delay(clock=20000000)
#use rs232(baud=2400, xmit=PIN_C6, rcv=PIN_C7)

unsigned int ContadorGlobal;

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


void main()
{
unsigned long  cuenta;
float CycleTime = 0;
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);
printf(" %f ", cycleTime);
//for (cuenta=400000; cuenta != 0; cuenta--);
CycleTime=(float)(0.0000512*get_timer0()+0.0131072*contadorglobal);
printf(" %f ", cycleTime);
}
}
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: marito en 03 de Febrero de 2010, 20:23:47
Con el programa que me pasaste, mido 63ms colocando un breakpoint en el segundo(ultimo) printf. Tengo el MPLAB v8.36 CCS 3.4.

En la PC desde el PIC recibo 38ms.

Tendria que ver el tema de la versión del CCS...
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: AngelGris en 03 de Febrero de 2010, 20:30:51
En este hilo http://www.todopic.com.ar/foros/index.php?topic=19143.0 hablan de un comm virtual así que lo voy a bajar a ver que carajo obtengo
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: marito en 03 de Febrero de 2010, 20:32:39
Yo estoy descargando la versión que me dijiste que tenes del compilador, es la última. Te cuento si tuve algún cambio...
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: marito en 03 de Febrero de 2010, 20:50:17
Instale la última versión del compilador, la 4.104.

Ahora las mediciones en el simulador es de 47ms y en el PIC 39ms. Supongo que con un par de ajustes van a estar midiendo lo mismo!!!!

Excelente Angel!!!

Mañana continúo con las pruebas de ajuste y comento!!! Es hora de un descanso.

Un abrazo
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: AngelGris en 04 de Febrero de 2010, 12:20:07
Envié un mensaje anterior, pesaban mucho los adjuntos y hubo un error.

Ayer a la noche probé con tres programas de puertos virtuales y simulando en proteus. En el programa terminal leía 52.275 ms mientras que el MPLAB decía 63.283 ms.

Hoy desinstalé todos los programas y volví a instalar. MPLAB 8.43; CCS 4.104; Proteus 7.6. Simulé y tiraba los mismo números.
Entonces se me dio por poner una velocidad de 2400 baudios, tanto en el programa como en el terminal y en la simulación de Proteus. Ahora en las capturas se puede apreciar MPLAB 63.283 ms, y en el termnal 63.180 ms.

Yo creo que tendrías que programar tu PIC con esa velocidad puesta en el programa, y obviamente setear el terminal a esa velocidad, y ver que valor te llega.
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: marito en 04 de Febrero de 2010, 15:56:11
Efectivamente, con la versión 8.43 a la velocidad de 2400 da el mismo valor tanto en el PIC como en la salida del Simulador. A 9600 hay diferencia... que raro...

Lo que no puedo obtener, es el valor medido con el StopWatch, o sea, en la salida del simulador tengo el mismo valor que en el terminal (recibiendo del PIC). Hay que ver si la lógica del timer0 es la correcta para el cálculo
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: AngelGris en 05 de Febrero de 2010, 11:26:31
La lógica del cálculo es correcta.
Hoy estuve haciendo algunas pruebas. Hay un problema en la instrucción "CycleTime=(float)(0.0000512*(get_timer0())+0.0131072*contadorglobal);" El asunto está en que te toma el valor de Timer0 muy tempranamente, y entonces cuando termina de realizarse dicha intrucción el timer0 ya tiene otro valor.

Puse para ver el registro del Timer0 en el MPLAB, antes de comenzar dicha sentencia el Timer0 tiene el valor 212 y al terminar 218.

Al finalizar la sentencia "CycleTime = ....."   el StopWatch indica 63.636800 ms

Si hago los cálculos (con la fórmula que está en el programa) con timer0 en 212 el valor de CycleTime es 63.283 ms.

Pero si hago los cálculos con timer0 en 218 (que es el valor que tiene al finalizar la sentencia) CycleTime es 63.5904 ms.
Este valor es mucho más cercano al del StopWatch.

Veamos cuál es la diferencia concreta.... 63.6368 - 63.5904 = 46.4u -> 46.4u/200n (que es el tiempo de instrucción) = 232
este valor es la cantidad de instrucciones que se están quedando afuera de la cuenta. ¿Y por qué se quedan afuera? como se está usando un preescaler de 256 no se llega a incrementar una vez más el timer0
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: Suky en 05 de Febrero de 2010, 16:21:27
Yo hice una prueba, y como era de esperar los resultados son idénticos, hay una diferencia de 1 ciclo que puede ser de algún detalle que se escapa al no ver las instrucciones en assembler.

(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=29264.0;attach=11170)

Saludos!
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: AngelGris en 06 de Febrero de 2010, 15:06:18
Me cansé de hacer pruebas en CCS  :5]; si agregaba mas delay o ponía mas sentencias "printf...." antes de hacer el cálculo de CycleTime éste variaba enormemente. Definitivamente hay algún gran problema o en la implementación de printf o cuando se ingresa demasiado a la interrupción para incrementar ContadorGlobal.

Bajé rutinas de delay y serial para Hitech y me puse a probar con el... te subo dos capturas... ProgramaHitech1 muestra el valor que tiene el StopWatch antes del cálculo de la variable Ciclos; 69.4604 ms

En la captura ProgramaHitech2 vemos que el valor en la variable ciclos es 694272.

Si se divide el valor de ciclos en 10000 nos da el tiempo en ms 69.4272;
La diferencia entre StopWatch y ciclos es 33.2us que equivalen a 166 instrucciones. Este número se está quedando afuera porque no supera la división del prescaler del Timer0 (que está en 256);

Ahora bien, tuve que realizar los cálculos de esa manera porque intenté usar la función FTOA -FloatToASCII- pero no me tomaba bien los decimales. Entonces decidí hacer que ciclos sea "unsigned long" y usar todos número mayores que 0.

Código: [Seleccionar]
/*************
*
* Prueba para ver si puede usar el puerto serie con HiTech
*
*************/
#define   PIC_CLK 20000000



#include <htc.h>
#include "delay.c"
#include "serial.c"

//#include <stdlib.h>
//#include <stdio.h>
//#include <string.h>

#include "Definiciones.h"
/*
#define INTERNAL 0
#define EXT_L_TO_H 32
#define EXT_H_TO_L 48
#define TMR0_DIV_1 8
#define TMR0_DIV_2 0
#define TMR0_DIV_4 1
#define TMR0_DIV_8 2
#define TMR0_DIV_16 3
#define TMR0_DIV_32 4
#define TMR0_DIV_64 5
#define TMR0_DIV_128 6
#define TMR0_DIV_256 7
#define set_timer0(x) TMR0= x
#define setup_timer0(x) (OPTION = 0b11000000|x)
*/

unsigned int ContadorGlobal;

void interrupt tc_int(void)
{
if (T0IE && T0IF)
{
T0IF=0;
++ContadorGlobal;
}
}


void main (void)
{

unsigned long Ciclos;

setup_timer0(INTERNAL|TMR0_DIV_256);
serial_setup();
INTCON= 0b10100000;



while (1)
{
set_timer0(0);
ContadorGlobal = 0;
Ciclos = 0;
DelayMs(20);
putst ("Que Mal el CCS ");
DelayMs (30);
putst ("Que barbaro lo del Timer0");
Ciclos = (ContadorGlobal*131072) + (unsigned long)(TMR0)*512;

}
}
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: AngelGris en 06 de Febrero de 2010, 21:19:29
Terminé de hacer pruebas con HiTech y tengo el mismo problema  :x  :x  :x.
Quiero creer que entonces es el MPLAB que, al no simular bien la comunicación serie, se boludea -en términos técnicos- y calcula mal los ciclos
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: Suky en 06 de Febrero de 2010, 22:25:14
Me parece que en la simulación de la comunicación serial los 2 simulan de forma distinta el vaciamiento del buffer de comunicación. Habría que hacer las pruebas en hard real y ver realmente cual es el más acertado.


Saludos!
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: marito en 08 de Febrero de 2010, 19:39:54
Hola!!! Estuve desaparecido un par de dias porque estuve a full en el trabajo! Las últimas pruebas que estuve haciendo, me dieron valores muy parecidos, tanto en hardware como en software (simulador). Me da una pequeña diferencia, como comente en el último post que hice, pero voy a intentar ajustar el programa para ver si los valores se aproximan. Te comento que los valores de tiempo los necesito en este momento para hacer los cálculos de ángulo de inclinación con un giroscopo y utilizar este dato en un controlador PID. Estoy bastante entretenido!!!
Saludos!!!
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: Suky en 08 de Febrero de 2010, 21:13:42
Acá lo importante es estar seguro que la programación es correcta y mediante una salida y un osciloscopio comprobar las medidas. La simulación es solo eso, y no se puede confiar plenamente  ;-)


Saludos!
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: AngelGris en 09 de Febrero de 2010, 10:41:49
Esta buena esa. Activas dicha salida al principio del While y la desactivas justo después del cálculo de CycleTime; Al medirla con el osciloscopio se puede saber cuanto dura realmente el ciclo. Pero de todas maneras puede seguir habiendo una pequeña diferencia, ya que en la sentencia del cálculo de CycleTime se toma el valor del Timer0 en x punto y cuando termina dicha sentencia puede ser que el valor del Timer0 haya cambiado.

De hecho, simulándolo con el MPLAB (aunque no haya rutinas de comunicación, para que no alteren demasiado la medida) se llega a notar eso. (Que el valor del Timer0 es diferente cuando comienza la sentencia de cálculo de CycleTime a cuando termina dicha sentencia). Pero esto no sería demasiado problema ya que al valor calculado se le puede agregar uno fijo (que haga las veces de offset) y listo.
Título: Re: tiempo de ejecucion codigo C en MPLAB
Publicado por: marito en 03 de Marzo de 2010, 15:57:28
Finalmente pude realizar la medición de ciclo de programa con osciloscopio, forzando a uno el estado de un puerto al comienzo del programa y a cero al final. El tiempo medido con el mismo, coincide al que realiza el PIC utilizando el Timer0, por lo que ahora voy a estudiar bajo que condiciones, el cálculo con el simulador coincide con los anteriores.
Saludos!!!