Autor Tema: Realizar temporización de tabla de valores XC8  (Leído 4681 veces)

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

Desconectado romanm

  • PIC10
  • *
  • Mensajes: 12
Realizar temporización de tabla de valores XC8
« en: 01 de Mayo de 2017, 23:58:10 »
Hola buenas noches gente, espero que este sea el lugar indicado para hacer esta pregunta, y si no lo es sepan disculparme.
Estoy realizando un programa para el pic 12f683 en XC8 y  me encuentro con una duda que tal vez sepan ayudarme.

En el programa tengo una tabla de 196 elementos que cada uno corresponde a un tiempo distinto que debo temporizar, y luego de que termine ese tiempo sacar un pulso por el puerto GP0. El arreglo es algo así:

static const uint16_t[196]={500,523,547,589,635,..................,3456}; //tiempos en uSeg

Quisiera saber si existe alguna forma de ingresar al arreglo anterior y temporizar el valor que se encuentra leyendo el programa en ese momento. (Por las dudas que alguno piense en el modo comparación, no lo puedo utilizar ya que el programa se encuentra todo el tiempo utilizando el Timer1 e iniciar el modo comparación me haría perder los valores de los registros del TMR1).

Muchas gracias de antemano, saludos cordiales

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Realizar temporización de tabla de valores XC8
« Respuesta #1 en: 02 de Mayo de 2017, 00:22:40 »
Si o Si debes usar un timer. Lo mejor es como decis usar el Timer1 con el CCP en modo compare, ya que es el que tendria mejor precision en la salida.
Y no solo eso, sino que ademas tenes que cargar 16bits lo cual es tu mejor opcion para esa aplicacion. Simplemente cargandolo tus valores en CCPR1x, y luego dejar que el modulo CCP se encargue.

Y tranquilamente podes usar otro timer en ves del Timer1 para lo otro que estes haciendo.

La otra y mucho mas engorrosa es que trates de hacerlo con otro Timer.

Si usas Timer 2: Es bueno por que te permite seleccionar un valor de "periodo" lo cual facilita el manejo del mismo, pero.. es de 8bits, asi que deberias tratar de dividir el valor tratando que quede lo mas grande posible y cercano a 255, y en ves de usar un uint16_t usas 2 uint8_t ( crea una estructura) la primer variable te indicaria cuantas veces debes hacer la interrupcion, y la segunda es el valor a cargar. En tu timer simplemente usas un contador y cuando sea igual a las veces que debe entrar activas tu salida. Ejemplo

En ves de hacer: 500, tenes 2 y 250, en ves de 523 tenes 3 y 174 (hay un error pero es lo mas simple)

250 cargas en tu PR2, y pones el contador en 0, llega a 250, aumentas contador, si contador es igual a 2 quiere decir que ya terminaste y pones contador a 0.

Como observas puede existir errores. Pero eso depende de que tan imporante sea ese microsegundo.

Si usas un Timer0 podes aplicar el mismo concepto anterior. El problema es que ahora vas a tener MUCHO mas error por que el Timer0 no se resetea solo como el Timer2.

Solucion al error de numeros que no se pueden dividir, una solucion seria tratar de mantener ese resto en algun lugar.
Poner 8bits mas por cada uno de los valores es una posibilidad. Eso te lleva a que cada valor tenga 24bits destinados al mismo.
Por otro lado podrias encapsularlo en los primeros 8 bits, es decir la variable que mantiene la cantidad de veces a entrar podria usar 4 bits para eso, y 4 bits para indicar esos ultimos ciclos que faltan.

De todas formas estamos hablando de microsegundos cuando el micro ese puede ir maximo a 0.2us cada instruccion, no te va a quedar demasiado tiempo, ademas otra interrupcion y significa que el tiempo que llevabas se fue al tarro.

Desconectado romanm

  • PIC10
  • *
  • Mensajes: 12
Re:Realizar temporización de tabla de valores XC8
« Respuesta #2 en: 02 de Mayo de 2017, 00:27:40 »
El problema justamente es ese!! no puedo dejar de utilizar el Timer1 para "lo otro", ya que lo que estoy haciendo es contar las revoluciones de un motor a través del modo captura, utilizo las interrupciones del módulo CCP y mido el tiempo entre 2 pulsos, de allí obtengo el valor de las RPM del motor. Si utilizo el TMR1 para temporizar no puedo medir las revoluciones del motor :/

Podría intentar usar el Timer2, me parece la opción más viable  de las que mencionaste. Por otro lado, no hay problema con intentar cargar un registro del timer con una variable o puntero que señale al array?
« Última modificación: 02 de Mayo de 2017, 00:43:45 por romanm »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Realizar temporización de tabla de valores XC8
« Respuesta #3 en: 02 de Mayo de 2017, 00:42:47 »
El tema esta tambien que si usas interrupciones para esto y necesitas activar una salida, puede que te demores un par de microsegundos mas. Y viendo que el primer escalon pasa de 500 a 523 (23us = 115 instrucciones separan ambos), dependiendo de las instrucciones que lleve realizar lo del modulo CCP seria tu error ( si es que ubicas correctamente los if de cada flag, es decir el ultimo if deberia ser el del Timer2 ) creo que seria el peor de los casos a no ser que tarde menos que salir y entrar de la interrupcion con todo lo que significa el guardar el contexto.

La otra es buscar un micro mas rapido, PIC18 que tiene un "autoguardado" de contexto para las interrupciones de alta prioridad.
Y sino buscar otro micro de  la misma marca u otra destinada a motores ( o aplicaciones de tiempo real ) para tener mejor precision con el tiempo.
« Última modificación: 02 de Mayo de 2017, 00:47:32 por KILLERJC »

Desconectado romanm

  • PIC10
  • *
  • Mensajes: 12
Re:Realizar temporización de tabla de valores XC8
« Respuesta #4 en: 02 de Mayo de 2017, 00:51:21 »
Voy a intentar usar el Timer2 para probar, podría poner en el arreglo los valores de precarga del TMR2 y así cargarlos en el registro del mismo con un puntero?
Por cierto, los cálculos los hice en base al TIMER0 y están todos dentro del rango que éste es capaz de temporizar sin desbordar, por lo cual ese problema me lo saco de encima. Con respecto al escalón, no es de 23 us ya que esa temporización se hace 1 sola vez por vuelta del motor, por lo cual es un tiempo muy ínfimo en cuanto al total de la revolución. Yo creo que va a dar bien con el Timer2.
Por otro lado, cómo sería la forma de cargar el registro del Timer2 con los valores del arreglo? Ahí estoy medio confundido también :(
« Última modificación: 02 de Mayo de 2017, 01:00:49 por romanm »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Realizar temporización de tabla de valores XC8
« Respuesta #5 en: 02 de Mayo de 2017, 14:30:06 »
El TMR2 es simple.

En el registro del TMR2 lo pones al 0 cuando comenzas y luego no lo tocas mas.
Luego tenes T2CON que es donde configuras el preescaler y activas el Timer 2,tambien configuras el postscaler.
Y por ultimo el valor al cual debe llegar TMR2 lo cargas en PR2.


El postscaler te podria servir, es como un contador de interrupciones... si lo pones en 1:1 apenas coincidan los registros TMR2 y PR2 tenes una interrupcion, si lo pones en 1:2 la interrupcion va a ocurrir cuando coincidan por segunda ves. Asi que si haces como te decia de contar cuantas veces entra, simplemente cambias el postscaler al valor que deseas ( Maximo 1:16 ) en ves de usar un contador por software.

Lo bueno es que el valor a cargar lo pones en PR2, lo que hace esto es que el TMR2 cuente hasta el valor PR2, cuando todos coincidan ( sean iguales ) procede a poner a 0 el TMR2.
Es decir que si lo comparas con el TMR0 no tenes que estar reescribiendo el valor del TMR2, si seteas el periodo ( PR2 ) ya esta.

Recorda una cosa, que tu arreglo tenes variables de 16bits, y el Timer2 es de 8bits
Por lo cual deberias implementar algo como te dije en el anterior mensaje.

Desconectado romanm

  • PIC10
  • *
  • Mensajes: 12
Re:Realizar temporización de tabla de valores XC8
« Respuesta #6 en: 02 de Mayo de 2017, 22:20:01 »
Estimado, muchas gracias por tu interés y ayuda. Te cuento lo que hice en el día de hoy con el programa.

El arreglo lo pasé a variables de 8 bits, quedando uint8_t tabla[199]= {0,0,0,0,.......,140,136,125,.........,7}; (Éstos son los valores que se deben cargar en PR2 para obtener la temporización que necesito)

Cada valor del arreglo coincide con el número de revoluciones por segundo (rps) del motor, es decir, en la posición 32 del arreglo el motor se encuentra a 32rps o 1920 RPM. El problema es que no está funcionando como yo quisiera, ya que el programa está leyendo equivocadamente la tabla. La forma que tengo de acceder al dato y setear PR2 es la siguiente:

PR2 = (tabla[rps]);
T2CONbits.TMR2ON = 1; (Cabe aclara que estoy utilizando prescaler 16 y postcaler1)

Luego de esto atiendo la interrupción, chequeando el flag TMR2IF.

Ahora bien, las rps las calculo dentro de la interrupción del modo captura (CCP con Timer1) de la siguiente forma:

if(PIR1bits.CCP1IF == 1)
{
      PIR1bits.CCP1IF =0;
      periodo = (TMR1H << 8 ) + TMR1L;
      rps = (1000000/periodo); (Tengo un cristal de 4MHz, por lo cual cada instrucción es de 1us)
      TMR1 = 0x00; (Siempre que termino de calcular reseteo el Timer1 y de esta forma evito que desborde)
}

No sé en que le estoy errando, podrías ver si estoy muy errado en el pensamiento del programa? Muchas gracias estimado
« Última modificación: 02 de Mayo de 2017, 22:29:58 por romanm »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Realizar temporización de tabla de valores XC8
« Respuesta #7 en: 02 de Mayo de 2017, 22:51:55 »
Pero una division te llevaria MUCHOS ciclos realizarse, estoy mas que seguro que pasaria unas cuantas interrupciones hasta que termine de calcular eso, es ecalculo deberia ir en el main y no en la interrupcion , otra es que la tabla tiene valores en 0, no se si estas cargando eso.. pero si pones 0 debe pasar de 255 a 0 para que te lo tome si no me equivoco.

La forma de buscar el valor es correcto, el problema esta en tu interrupcion del CCP, tarda demasiado y afecta a la interrupcion del TMR2.

PD: Si no me equivoco, podes hacer periodo = TMR1; como si fuera un registro de 16bits.
PD2: No se para que usas:

rps = (1000000/periodo);

Si usando los valores que puede tomar periodo que es de 0 a 65535, el resultado te va a dar desde 0 a 15, lo cual nunca vas a usar tus 196/199 valores de la tabla y solo usarias del 0 al 15.
Seguramente hay un error en la formula

Desconectado romanm

  • PIC10
  • *
  • Mensajes: 12
Re:Realizar temporización de tabla de valores XC8
« Respuesta #8 en: 02 de Mayo de 2017, 23:02:21 »
Lo de la división tenes razón, puede ser que esté interfiriendo. Los 0 del array si los estoy cargando, lo que pasa es que no quiero que sean leídos, la tabla teóricamente la comienzo a leer desde la posición 32, la cual corresponde a 32 rps. Por eso tenía la necesidad de hacer la división, para que de dicho resultado obtener directamente las posiciones del array.

No entiendo eso que me decis de que el resultado es de 0 a 15. Que el Timer1 tiene los valores desde 0 hasta 65535 si, está perfecto. Es más, al ser cada ciclo de instrucción de 1 useg, el tiempo que mide el Timer1 sería desde 0 hasta 65535 us.

Me sugieres alguna idea de como mejorarlo?
« Última modificación: 02 de Mayo de 2017, 23:29:25 por romanm »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Realizar temporización de tabla de valores XC8
« Respuesta #9 en: 03 de Mayo de 2017, 15:03:18 »
Citar
Los 0 del array si los estoy cargando, lo que pasa es que no quiero que sean leídos,

Entonces para que cargas 31 valores con 0, para eso restale 32 al numero que uses como indice y comenzas cargandole valores desde el 0 (que seria tu 32 )

Citar
No entiendo eso que me decis de que el resultado es de 0 a 15. Que el Timer1 tiene los valores desde 0 hasta 65535 si, está perfecto. Es más, al ser cada ciclo de instrucción de 1 useg, el tiempo que mide el Timer1 sería desde 0 hasta 65535 us.

Un eror mio tomar del 0 al 15, cuando deberia haberi sido para el otro lado, en realidad podes tener mucho mas problemas. Me explico mejor..
El TMR1 te va a dar numeros de 0 al 65535.

Y tenes tu formula asi:

rps = (1000000/periodo);

Si periodo es 65535 , el resultado es 15, O sea el minimo es el unmero 15,
Si periodo es 1, el resultado es 1000000 (0xF4240), que como rps seguramente sea de 16bits te queda 16960 (0x4240) o en caso de que sea 8bits  64 (0x40) , lo cual hay 2 problemas en tu tabla no tenes la posicion 16960, y la otra es que vas a tener mas valores que pueden darte eso, si usas el de 8 bits estarias accediendo como si tuvieras el numero 64. Observa que nada que ver con lo que deberia ser.

El minimo valor de "periodo" para que esto funcione es aquel numero que me daria los 199, es decir que tus valores de periodo deberian estar si o si dentro del rango 5001 a 65535


Citar
Me sugieres alguna idea de como mejorarlo?
No se que intentas hacer con la interrupcion que pensamos con el Timer2, tampoco se que tenes en el codigo y que pueda afectar, ya que tu problema son tiempos, y para hacer las cosas bien con los tiempos hay que ser bastante quisquilloso cuando no te sobra demasiada velocidad.

Desconectado romanm

  • PIC10
  • *
  • Mensajes: 12
Re:Realizar temporización de tabla de valores XC8
« Respuesta #10 en: 03 de Mayo de 2017, 18:35:05 »
Estimado, muchas gracias por tu tiempo y tus consejos, perdón por volverte loco trato de hacer lo mejor que puedo. La cosa es así:

Inicialmente, el Timer1 está siempre corriendo para el modo CCP captura, con el cual como ya expliqué anteriormente obtengo las revoluciones del motor.

Los valores de revoluciones que manejo son desde 16 RPS (960 RPM) hasta 167 RPS (10020 RPM). Valores superiores o inferiores a estos no me interesan.

El programa siempre se encuentra midiendo las revoluciones, y para cada valor de revolución debe dar un delay distinto, así es que:

Si RPS=16 (Timer1 = 62500) El programa debe ingresar en la tabla y dar un delay de 7993 us
Si RPS= 17 (Timer1 = 58823) El programa debe ingresar en la tabla y dar un delay de 7523 us
.....
....
....
....
...
Si RPS=167 (Timer1 = 5988) El programa debe ingresar en la tabla y dar un delay de 433 us

Eso es lo que debe hacer el programa. La parte de conteo de revoluciones ya está hecha, lo que me está volviendo un poco loco es crear el array y poder temporizarlo con el timer 2.

Disculpa si soy muy ignorante en el tema, pero trato de leer y entender las cosas y se me complica, si puedes guiarme (no pido que me des el código, solamente con un ejemplo puedo seguir avanzando e intentando hacer lo que necesito) estaría muy agradecido, muchas gracias

PD: Por cierto, el valor rps = 1000000/periodo lo uso solamente si el periodo se encuentra entre 33333 y 5988, que haciendo la división me da los valores 30 y 167, que coinciden con las posiciones del arreglo que estoy tratando de hacer. Ese es el fin de hacer esa división.
Como puedo saber cuanto tiempo me puede demorar el pic en hacer dicha división? Podría ponerla en el main y ver que pasa
« Última modificación: 03 de Mayo de 2017, 23:34:39 por romanm »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Realizar temporización de tabla de valores XC8
« Respuesta #11 en: 04 de Mayo de 2017, 15:43:10 »
Para saber cuanto te demora el PIC, podes crear un proyecto aparte de pruebas (esto para no involucre nada del otro codigo), crear las variables  y hace la division dentro del main, de alli lo vas a simular, poniendo breakpoints en la instruccion y una mas en otra instruccion adelante. Si observas en el Stopwatch te dice cuantos ciclos le toma realizarlo, Tambien te dice el tiempo pero para que sea correcto el tiempo tenes que configurar correctamente el oscilador en el MPLAB, asi que guiate por los ciclos.

Respecto a como hacerlo mas rapido... no se que decirte, obviamente que con una division llegas al resultado, pero no se que velocidad pensas tener de respuesta desde que calculaste el valor hasta cambiar las salidas.

Ejemplo, cree un proyecto el cual posee este codigo nomas:

Código: C
  1. // PIC12F683 Configuration Bit Settings
  2.  
  3. // 'C' source line config statements
  4.  
  5. #include <xc.h>
  6. #include <stdint.h>
  7.  
  8. // #pragma config statements should precede project file includes.
  9. // Use project enums instead of #define for ON and OFF.
  10.  
  11. // CONFIG
  12. #pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
  13. #pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
  14. #pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
  15. #pragma config MCLRE = OFF      // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
  16. #pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
  17. #pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
  18. #pragma config BOREN = OFF      // Brown Out Detect (BOR disabled)
  19. #pragma config IESO = OFF       // Internal External Switchover bit (Internal External Switchover mode is disabled)
  20. #pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
  21.  
  22.  
  23. void main (void)
  24. {
  25.     uint16_t periodo = 6000;
  26.     uint8_t rps;
  27.    
  28.         while(1)
  29.         {
  30.             rps = 1000000/periodo;
  31.             periodo += 500;
  32.         }
  33. }

Puse el breakpoint en la instruccion rps, es decir los valores que me van a dar de ciclos van a estar separados por unos 5 ciclos masomenos ocupados por las demas instruciones.

Estos son los valores que me dieron:

Citar
Target halted. Stopwatch cycle count = 921 (76,75 µs)
Target halted. Stopwatch cycle count = 921 (76,75 µs)
Target halted. Stopwatch cycle count = 925 (77,083333 µs)
Target halted. Stopwatch cycle count = 925 (77,083333 µs)
Target halted. Stopwatch cycle count = 926 (77,166667 µs)
Target halted. Stopwatch cycle count = 963 (80,25 µs)
Target halted. Stopwatch cycle count = 963 (80,25 µs)
Target halted. Stopwatch cycle count = 963 (80,25 µs)
Target halted. Stopwatch cycle count = 963 (80,25 µs)
Target halted. Stopwatch cycle count = 963 (80,25 µs)
Target halted. Stopwatch cycle count = 963 (80,25 µs)
Target halted. Stopwatch cycle count = 1383 (115,25 µs)  // Periodo es 500 aca
Target halted. Stopwatch cycle count = 1303 (108,583333 µs)
Target halted. Stopwatch cycle count = 1271 (105,916667 µs)
Target halted. Stopwatch cycle count = 1299 (108,25 µs)
Target halted. Stopwatch cycle count = 1201 (100,083333 µs)
Target halted. Stopwatch cycle count = 1187 (98,916667 µs)
Target halted. Stopwatch cycle count = 1163 (96,916667 µs)

Todo depende del valor de periodo, por lo que veo el minimo es de 925 ciclos y el maximo de 1380 aproximadamente. Es decir no es fijo.

Otra forma que probe fue:

Código: C
  1. rps = 15625/(4*(periodo>>8));

Viene de que si divido periodo por 256 deberia dividir ese millon por 256. lo cual me queda asi.. Lo bueno de esto que dividir por 256 es simplemente tomar el byte mayor, hay una perdida de  presicion al dividirlo por 8 y luego multiplicarlo por 4. ya que esos 2 ultimos bits quedan en 0. Hice un excel para ver cual era el error.
La formula usada en el excel fue:

Código: [Seleccionar]
TRUNC(15625/(4*(TRUNC(periodo/256))))
Y en los valores altos de periodo no hay error, pero acercandonos hacia lo que nos daria los RPS cercanos a 166 los errores aumentan en algunos hasta 3 de diferencia, es decir en ves de darte 166 me da 169, mas que eso aumentan a 5 o mas los errores. Lo bueno de todo esto es que ahora los ciclos bajaron a:

Citar
arget halted. Stopwatch cycle count = 336 (28 µs)
Target halted. Stopwatch cycle count = 337 (28,083333 µs)
Target halted. Stopwatch cycle count = 355 (29,583333 µs)
Target halted. Stopwatch cycle count = 354 (29,5 µs)
Target halted. Stopwatch cycle count = 354 (29,5 µs)
Target halted. Stopwatch cycle count = 354 (29,5 µs)
Target halted. Stopwatch cycle count = 354 (29,5 µs)
Target halted. Stopwatch cycle count = 354 (29,5 µs)
Target halted. Stopwatch cycle count = 667 (55,583333 µs) // Para cuando perdiodo es 500
Target halted. Stopwatch cycle count = 617 (51,416667 µs)
Target halted. Stopwatch cycle count = 574 (47,833333 µs)
Target halted. Stopwatch cycle count = 574 (47,833333 µs)
Target halted. Stopwatch cycle count = 532 (44,333333 µs)

Es decir la mitad a un error que podemos considerar tal ves razonable

Otro caso mas, incorporar el *4 dentro del shift:

Código: C
  1. // Programa
  2. rps = 15625/(periodo>>6);
  3. //Excel
  4. =TRUNC(15625/TRUNC(periodo/64))

Ahora el error maximo es de 2 y ocurre a ese valor, este caso tiene menos error que en anterior y lso ciclos estan

Citar
Target halted. Stopwatch cycle count = 370 (30,833333 µs)
Target halted. Stopwatch cycle count = 388 (32,333333 µs)
Target halted. Stopwatch cycle count = 387 (32,25 µs)
Target halted. Stopwatch cycle count = 387 (32,25 µs)
Target halted. Stopwatch cycle count = 387 (32,25 µs)
Target halted. Stopwatch cycle count = 387 (32,25 µs)
Target halted. Stopwatch cycle count = 387 (32,25 µs) // Periodo = 65500
Target halted. Stopwatch cycle count = 693 (57,75 µs) // Periodo = 500
Target halted. Stopwatch cycle count = 638 (53,166667 µs)
Target halted. Stopwatch cycle count = 607 (50,583333 µs)
Target halted. Stopwatch cycle count = 589 (49,083333 µs)
Target halted. Stopwatch cycle count = 572 (47,666667 µs)
« Última modificación: 04 de Mayo de 2017, 16:16:04 por KILLERJC »

Desconectado romanm

  • PIC10
  • *
  • Mensajes: 12
Re:Realizar temporización de tabla de valores XC8
« Respuesta #12 en: 04 de Mayo de 2017, 22:46:21 »
Hola querido muchas gracias por tu tiempo. Estuve pensando y tal vez exista otra forma de hacer las cosas.

Mirando bien, el pin5 (GP2) del pic 12f683 tiene el modo CCP y además posee la INTerrupción externa.

Sería posible medir las revoluciones del motor a través de las interrupciones externas del pin GP2 (Con Timer0 o Timer2) y realizar la temporización de la tabla a través del modo comparación (Con timer 1)??
Tal vez esa puede ser la solución más sencilla a todo este engorroso laburo

Por otro lado, puedo probar hacer lo que me dijiste en el mensaje anterior también, estoy abierto a probar distintas formas, en algún momento tiene que salir

« Última modificación: 04 de Mayo de 2017, 22:55:39 por romanm »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Realizar temporización de tabla de valores XC8
« Respuesta #13 en: 04 de Mayo de 2017, 23:14:02 »
Citar
Tal vez esa puede ser la solución más sencilla a todo este engorroso laburo

Tendrias el mismo problema.

A ver quiero que se entienda. Separemos en parte:

- Obtener el periodo
- Calcular las RPS
- Cargar el valor nuevo para el Timer2 asi hace lo que deba hacer

Lo primero esta realizado... Lo haces con el TMR1 y funciona, solo le faltaria un par de ifs por si ocurren valores no tenidos en cuenta.
El segundo ocupa tiempo para realizarse, como ves son "microsegundos" 500 ciclos son 100us a 20Mhz ( o 200us para 1000 ciclos), ESTO es lo que pienso que vas a tener problemas
Y finalmente el TMR2 que hace que cambie la salida, la cual solo debes cargarle los valores y luego esperar la interrupcion.

Estoy suponiendo que las interrupciones del TMR1 y TMR2 son muy cortas. Y que el calculo de las RPS esta realizado en el main.

Tu mayor problema actualmente no es como configurar el TMR2, tu mayor problema es que tan rapido queres (o necesitas ) que desde detectado el cambio en en el periodo se actualize lo del Timer2, si no importa que la salida del Timer2 luego de detectado por el timer1 que aumento o disminuyo, tarde 200us en "actualizarse" la salida del TMR2, entonces no hay ningun problema.

Desconectado romanm

  • PIC10
  • *
  • Mensajes: 12
Re:Realizar temporización de tabla de valores XC8
« Respuesta #14 en: 04 de Mayo de 2017, 23:26:16 »
Em si, el problema está en la demora que se tiene al calcular las rps.
Por eso decía que tal vez si uso el Timer0 para medir el período, estaría trabajando con valores mucho más chicos (de 0 a 255) y tal vez la operación de cálculo de las rps sea más rápida, estoy en lo correcto? o hacer una división u otra operación llevaría el mismo tiempo de procesado?