TODOPIC

Microcontroladores PIC => * PROYECTOS * => Mensaje iniciado por: mariacontenis en 10 de Agosto de 2018, 11:30:07

Título: Calculo a lápiz de un tick
Publicado por: mariacontenis en 10 de Agosto de 2018, 11:30:07
Amigos una duda simple para ustedes pero yo no se la respuesta por eso pregunto. Decía mi maestro.... Es mejor una pregunta  tonta que un tonto sin preguntar.

Bueno ahí va!!!.

Como calcular el tiempo de un tick del PIC con un cristal externo a 4 MHz y un
#use delay(clock=48000000)

Gracias por leer..
Título: Re:Calculo a lápiz de un tick
Publicado por: KILLERJC en 10 de Agosto de 2018, 12:08:27
Depende a que le llamas "Tick",

- si es al tiempo en que se ejecuta una instruccion es:

4 / Fosc = Tcy (Periodo de una instruccion )

Es decir la frecuencia se divide por 4 , ya que le lleva 4 ciclos de reloj ejecutar una instrucción.

- Si es el tiempo en el cual un Timer se incremente ( o decrementa) en 1, los que vi usualmente usan el mismo Tcy de antes como entrada.. Es decir:

( 4 / Fosc ) * Preescaler = Tiempo que incrementa en 1 el Timer



Observa que en ningun momento hago diferencia de cristal puesto, el Fosc es la frecuencia de entrada, luego del PLL, luego de divirlo etc... Ejemplo..

Si tenes un cristal de 4Mhz y no usas PLL ni lo dividis, entonces tu Fosc = 4Mhz.
Si tenes un cristal de 4Mhz y usas PLL, pasa por el preescaler que es 1:1 asi entra 4Mhz al VCO, la salida es de 96Mhz y se divide en 2, quedando 48Mhz, entonces tu Fosc = 48Mhz.
Si tenes un cristal de 20Mhz y no usas PLL pero usas el preescaler solo de 1:2, entonces tu Fosc = 10Mhz.

Es decir, es la frecuencia que va a entrar CPU, todo queda mas claro si miras el esquema del oscilador de tu micro.
Título: Re:Calculo a lápiz de un tick
Publicado por: mariacontenis en 10 de Agosto de 2018, 17:06:40
Así es como lo tengo:

Código: C++
  1. #fuses PLL1,CPUDIV1,USBDIV,XTPLL,NOFCMEN,NOIESO,PUT,NOBROWNOUT,VREGEN,NOWDT,NOPBADEN,MCLR,NOSTVREN,NOLVP,NODEBUG,NOPROTECT,NOSTVREN,NOCPB,NOWRT  
  2.  
  3.          #use delay(clock=48000000,crystal=4000000)
Título: Re:Calculo a lápiz de un tick
Publicado por: scrwld en 10 de Agosto de 2018, 20:29:57
hola mariacontenis, aqui tienes un tutorial muy bien explicado:

http://picfernalia.blogspot.com/2012/06/uso-de-temporizadores-timers.html

saludos
Título: Re:Calculo a lápiz de un tick
Publicado por: mariacontenis en 11 de Agosto de 2018, 07:41:31
Si, gracias. Y me refiero al tick timer (incrementos del timer).
Título: Re:Calculo a lápiz de un tick
Publicado por: KILLERJC en 11 de Agosto de 2018, 10:09:11
Entonces  Fosc = 48Mhz, asumiendo que el preescaler es 1:1 entonces:

( 4 / 48Mhz ) * 1 = 83.33ns

Si tenes un preescaler en 256, haces 83.33ns * 256 = 21.33ms
Título: Re:Calculo a lápiz de un tick
Publicado por: mariacontenis en 16 de Agosto de 2018, 12:24:03
Entonces = ( 4 / 48Mhz ) * 1 = 0.08333 uS  como comentas KILLERJC.

Si quiero calcular el tiempo que demora mi adc, para el ejemplo seria de la siguiente manera?

Código: C#
  1. #include <18F4550.h>
  2.          #device ADC=10
  3.          #fuses PLL1,CPUDIV1,USBDIV,XTPLL,NOFCMEN,NOIESO,PUT,NOBROWNOUT,VREGEN,NOWDT,NOPBADEN,MCLR,NOSTVREN,NOLVP,NODEBUG,NOPROTECT,NOSTVREN,NOCPB,NOWRT,NOWRTC
  4.          #use delay(clock=48000000)
  5.          #include <lcd4x20.c>
  6.          
  7.          char resultado[27]={0,0,0,0,0,0,0,0,0,0};
  8.          unsigned int16 analog_data_ch0=0,analog_data_ch1=0,analog_data_ch2=0,analog_data_ch3=0;
  9.  
  10. /////////////////////////// Para Medir tiempo /////////////////////////////////
  11.  
  12.          int conteo=0;                                // PUSE
  13.          long long tiempo;                            // PUSE
  14.          float ver_tiempo;                            // PUSE
  15.          
  16.          #INT_TIMER0                                  // PUSE
  17.          void maximo_conteo(void)                     // PUSE
  18.          {                                            // PUSE
  19.          conteo++;                                    // PUSE
  20.          }                                            // TIEMPO
  21.          
  22. ///////////////////////////////////////////////////////////////////////////////
  23.  
  24.          void adquisicion_time(void)
  25.          {
  26.          output_toggle(PIN_B3);                             // led status transferencia (conexion activa)
  27.          set_adc_channel (0);
  28.          analog_data_ch0=read_adc();                        //adquisicion1
  29.          set_adc_channel (1);
  30.          analog_data_ch1=read_adc();                        //adquisicion2
  31.          set_adc_channel (2);
  32.          analog_data_ch2=read_adc();                        //adquisicion3
  33.          set_adc_channel (3);
  34.          analog_data_ch3=read_adc();                        //adquisicion4
  35.          sprintf(resultado,"a=%4lub=%4luc=%4lud=%4lu@",analog_data_ch0,analog_data_ch1,analog_data_ch2,analog_data_ch3);    // convertimos y damos formato a los datos del adc
  36.          }
  37.          
  38.          void main(void)
  39.          {
  40.          set_tris_a(0xff);                                        //config puertos
  41.          set_tris_b(0x00);
  42.          lcd_init();
  43.          setup_adc_ports(AN0);
  44.          setup_adc(ADC_CLOCK_INTERNAL);
  45.          set_adc_channel (0);
  46.          delay_ms(1000);
  47.          SETUP_TIMER_0(T0_INTERNAL|T0_DIV_1);             // PUSE
  48.          ENABLE_INTERRUPTS(INT_TIMER0);                   // PUSE
  49.          enable_interrupts(GLOBAL);
  50.                  
  51.          while (TRUE)
  52.          {
  53.          conteo=0;                                        // DESDE AQUÍ EMPIEZO A MEDIR
  54.          set_timer0(0);                                  
  55.          output_high(pin_c0);
  56.          adquisicion_time();
  57.          output_low(pin_c0);
  58.          tiempo=GET_TIMER0();        // AQUI TERMINO DE MEDIR
  59.          
  60.          ver_tiempo=(float)tiempo*0.0833+((float)conteo*(float)65535*0.0833);        // 0.0833 uS      
  61.          lcd_gotoxy(2,3); printf(lcd_putc,"T = %f uS",ver_tiempo);
  62.          }
  63.          }

Por que el proteus me manda lecturas diferentes en la LCD y el osciloscopio virtual?

Adjunto la imagen....
Título: Re:Calculo a lápiz de un tick
Publicado por: KILLERJC en 16 de Agosto de 2018, 22:37:31
En ves de mostrar el calculo... mejor mostra los valroes de "conteo" y "tiempo".

Código: C
  1. while (TRUE)
  2.          {
  3.            conteo=0;                                        // DESDE AQUÍ EMPIEZO A MEDIR
  4.            set_timer0(0);                                  
  5.            output_high(pin_c0);
  6.            adquisicion_time();
  7.            output_low(pin_c0);
  8.            tiempo=GET_TIMER0();        // AQUI TERMINO DE MEDIR
  9.            ultimo_conteo = conteo;
  10.          
  11.            lcd_gotoxy(2,3); printf(lcd_putc,"T= %u, C=%u ",tiempo,ultimo_conteo);
  12.          }

Citar
Por que el proteus me manda lecturas diferentes en la LCD y el osciloscopio virtual?

Tal ves algun error en las formulas... No se, por eso te pido esos otros 2 valores y no el tiempo ya calculado.

Citar
Si quiero calcular el tiempo que demora mi adc, para el ejemplo seria de la siguiente manera?

Recorda que ahi estas viendo el tiempo de muchas mas cosas, no solo el ADC, sino que tambien del sprintf, que seguramente sea uno de los mas consumidores de tiempo, la llamada a la funcion, el "extra" que le da  CSS a los output_pin, etc.

Aun asi, le creo mas al osciloscopio que lo calculado y mostrado en el LCD.
Título: Re:Calculo a lápiz de un tick
Publicado por: mariacontenis en 18 de Agosto de 2018, 11:36:30
Sucede algo raro, cargue el pic en el proteus a 4 Mhz aunque el codigo en ccs este a 48Mhz y los valores del osciloscopio y la lcd son identicos. en cambio si cargo el pic en elproteus a 48Mhz y comoel codigo esta para 48Mhz, entonces asi es como deberia de ser realmente, pues me da valores erroneos en la ldc.

Aquí el código:

Código: CSS
  1. [size=8pt] #include <18F4550.h>
  2.          #priority timer0
  3.          #device ADC=10
  4.          #fuses PLL1,CPUDIV1,USBDIV,XTPLL,NOFCMEN,NOIESO,PUT,NOBROWNOUT,VREGEN,NOWDT,NOPBADEN,MCLR,NOSTVREN,NOLVP,NODEBUG,NOPROTECT,NOSTVREN,NOCPB,NOWRT,NOWRTC
  5.          #use delay(clock=48000000,crystal=4000000)
  6.          #include <lcd4x20.c>        
  7.  
  8.          int16 conteo=0;                                // PUSE
  9.          int16 ultimo_conteo=0;
  10.          
  11.          #INT_TIMER0                                  // PUSE
  12.          void maximo_conteo(void)                     // PUSE
  13.          {                                            // PUSE
  14.          conteo++;                                    // PUSE
  15.          clear_interrupt(int_timer0);
  16.          }                                            // TIEMPO
  17.          
  18.          
  19.          void main(void)
  20.          {
  21.          long data;
  22.          long tiempo;                            // PUSE
  23.          float ver_tiempo;                            // PUSE
  24.          set_tris_a(0xff);                                        //config puertos
  25.          set_tris_b(0x00);
  26.        
  27.          SETUP_TIMER_0(T0_INTERNAL|T0_DIV_1);             // PUSE
  28.          SETUP_ADC_PORTS(AN0_TO_AN1|VSS_VREF);
  29.          setup_adc(ADC_CLOCK_INTERNAL);
  30.          set_adc_channel(1);
  31.          
  32.          ENABLE_INTERRUPTS(INT_TIMER0);                   // PUSE
  33.          enable_interrupts(GLOBAL);
  34.          lcd_init();
  35.          
  36.          while (TRUE)
  37.          {
  38.          conteo=0;                                  // PUSE        
  39.          set_timer0(0);
  40.          output_high(pin_c0);                              
  41.          data=read_adc();
  42.          output_low(pin_c0);
  43.          tiempo=GET_TIMER0();
  44.                  
  45.          ultimo_conteo = conteo;
  46.  
  47.          ver_tiempo=(float)tiempo*0.0833+((float)conteo*(float)65535*0.0833);        // 0.0833 uS  
  48.          lcd_gotoxy(2,3); printf(lcd_putc,"T = %Lu   C = %Lu ",tiempo,ultimo_conteo);
  49.          lcd_gotoxy(3,4); printf(lcd_putc,"VT = %f uS",ver_tiempo);
  50.          }
  51.          }
  52.          [/size]

Adjunto imagenes...
Título: Re:Calculo a lápiz de un tick
Publicado por: mariacontenis en 18 de Agosto de 2018, 11:40:35
Aquí la imágenes a 4Mhz aunque el código este a 48Mhz..