Autor Tema: Error en frecuencia Timer1  (Leído 2162 veces)

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

Desconectado pirata88

  • PIC10
  • *
  • Mensajes: 16
Error en frecuencia Timer1
« en: 29 de Agosto de 2009, 14:04:35 »
Hola, el problema esque tendria q generarse una onda cuadrada ( por software ) de 880Hz, pero sin embargo no da 880...sino unos 746Hz, la formula es clara, viene en el programa y si me equivoco por algun lado...seria de gran ayuda saber en donde, gracias y ay va el programa


#include <16f628a.h>
#use standard_io(a,b)
#fuses intrc_io, NOWDT, NOMCLR, NOBROWNOUT, NOLVP, NOCPD
#use delay(clock = 4000000)

#define ONDA PIN_B5

//T=Tosc*4*Preescaler*N
//Tosc es periodo reloj ( 4Mhz), 4 por el tiempo de ejecucion de cada instruccion, N el numero a cargar en timer1
//para una frecuencia de 880Hz, el numero N es 568.1818
//es decir, para una onda cuadrada de 880Hz generamos interrupcion con frecuencia de 1760Hz


float A=568.1818;

int16 A1=0;

int1 e=0;



#int_timer1
void Segunda_Onda(void)
{

if ( e==0){

A1=A;

set_timer1(65536-A1);
output_high(ONDA);
e=1;
}
else {

set_timer1(65536-A1);
output_low(ONDA);
e=0;
}


}





void main (void) {


disable_interrupts(global);

setup_timer_1 (T1_INTERNAL | T1_DIV_BY_1 );

disable_interrupts(INT_TIMER0);
enable_interrupts(INT_TIMER1);
disable_interrupts(INT_TIMER2);
disable_interrupts(INT_RB);
disable_interrupts(INT_EXT);
disable_interrupts(INT_TBE);
disable_interrupts(INT_RDA);
disable_interrupts(INT_CCP1);
disable_interrupts(INT_COMP);
enable_interrupts(global);
set_timer1(50000);

do {



}
while(true);
}

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Error en frecuencia Timer1
« Respuesta #1 en: 29 de Agosto de 2009, 15:12:48 »
El problema surge en las instrucciones que CCS realiza para salvaguardar los registros y seleccionar que interrupción se ha generado. Debido a eso es complicado tener exactitud. Puedes usar el módulo CCP en modo PWM para generar la señal.


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

Desconectado pirata88

  • PIC10
  • *
  • Mensajes: 16
Re: Error en frecuencia Timer1
« Respuesta #2 en: 30 de Agosto de 2009, 07:19:27 »
Podria no ser exacto en unos cuantos Hz, pero esque difieren mucho...nose, tendre q averiguar eso del pwm del timer 2

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Error en frecuencia Timer1
« Respuesta #3 en: 30 de Agosto de 2009, 10:27:19 »
No, fíjate que estas trabajando a 4MHz, osea Tcy=1us. Y la diferencia entre periodos de la deseada y la que estas obteniendo es de 204us, 204 instrucciones. Estas pueden ser la suma de lo anterior mencionado mas las instrucciones realizadas dentro de la interrupción (If/else)


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

Desconectado fabianjsm

  • PIC18
  • ****
  • Mensajes: 255
    • fabianjsm is on twitter
Re: Error en frecuencia Timer1
« Respuesta #4 en: 30 de Agosto de 2009, 12:15:50 »
Deberias optimizar un poco tu codigo quitando esas estructuras condicionales que estan ocacionando la perdida de tiempo.
La cuestion es que programando en lenguajes de alto nivel pierdes la nocion del tiempo y del espacio (que loco!).
En vez de utilizar la variable 'e' para controlar el nivel actual de la onda, podrias invertir directamente el quinto bit con un XOR.
No estaria mal definir ademas un valor de correccion que te permita 'calibrar' la frecuencia hasta que logres el valor buscado.
Quedaria algo asi, donde K es la correcion (solo toma valores enteros mayores o igual a cero):

Código: C
  1. #define K 0
  2. #define T 65536-568
  3. #int_timer1 void Segunda_Onda(void)
  4. {
  5.     PORTB ^= 32;
  6.     set_timer1(T-K);
  7. }

La diferencia de frecuencia con la que te encuentres es el valor que deberas asignarle a K.
« Última modificación: 30 de Agosto de 2009, 12:28:59 por fabianjm »
@fabianjsm is on twitter

Desconectado ppyote

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 929
Re: Error en frecuencia Timer1
« Respuesta #5 en: 30 de Agosto de 2009, 17:39:53 »
A1=A; ??

si el valor A es un valor de 32bits, y A1 es un valor de 16 bits... lo que pasara es que se desbordara, no crees?
PPyote... siempre estareis en mi corazon.... Te quiero Hermano...

Desconectado pirata88

  • PIC10
  • *
  • Mensajes: 16
Re: Error en frecuencia Timer1
« Respuesta #6 en: 31 de Agosto de 2009, 06:02:49 »
El caso esque esa frecuencia puede cambiar desde los 2000 Hz hasta 32.7 Hz, tendre q corregir el parametro K, ya lo habia hecho con los servos este año, controlaba 8 servos con un timer y tenia 16 comparaciones jeje, no habia pensao en lo de xor gracias!
A1=A solo es para que se copie la parte no decimal, ya que el timer no va cargar los decimales xD, porque las frecuencias aveces tienen decimales y se le aplican efectos...enfin que puede aparecer una frecuencia de 345.6 y al aplicarle la formula para obtener el numero es mas preciso con decimales que sin ellos, o sino como lo hago? como paso de un float a int16? si yo paso float a int16 los numeros despues de las comas, desaparecen, o eso me han explicado ami desde siempre, por lo que no se va desbordar...o me equivoco?

Desconectado ppyote

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 929
Re: Error en frecuencia Timer1
« Respuesta #7 en: 31 de Agosto de 2009, 07:53:42 »
No estoy seguro pero creo que te desbordara, aunque no estoy seguro... todo es mirarlo
pues con A1=(int16)A //te lo hara

prueba a ver que tal

puedes crear otro int 16 guardando los 4 ultimos decimales,

int16 prueba;

prueba=(A*10000)%10000;
PPyote... siempre estareis en mi corazon.... Te quiero Hermano...

Desconectado reiniertl

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1187
Re: Error en frecuencia Timer1
« Respuesta #8 en: 01 de Septiembre de 2009, 13:04:38 »
Prueba a utilizar TIMER1+CCP en modo comparación, con eso lo que tienes que hacer es ajustar el valor de comparación del módulo CCP cuando quieras que la frecuencia de salida sea otra y listo en la interrupción del CCP sólo tienes que cambiar el valor del pin que quieres a 1 ó 0 según sea el caso.

Más explicado:

Utilizar TIMER1+CCP para hacer un contador ascendente con tope configurable. Es decir auxiliarse del CCP para resetear el TIMER1 cuando éste llegue a un valor determinado, como el CCP hace este trabajo por hardware no hay que estar escribiendo el temporizador, cosa que seguramente es la causa de tu actual error.

Luego bastaría con cambiar el valor de "corte" para el TIMER1 en el módulo CCP cuando quieras una frecuencia diferente.

Como quieres un tren de pulso simétrico de ciclo útil 1/2 (50%) tienes que hacer que el TIMER1 se resetee dos veces por pulso, es decir un reset para el estado lógico alto y otro para el estado lógico bajo, así que en el ejemplo que pones se debe resetear el TIMER con una frecuencia de 440Hz.

En la interrupción del CCP (ahora ya no utilizarías la del TIMER1) lo único que tienes que hacer es cambiar el estado del pin por donde debe salir la onda cuadrada y listo.

En cualquier otra parte del programa cambiar el valor del registro CCP, cuando sea necesario (igual a como cambias ahora la variable que determina la frecuencia de interrupción del timer)

Yo creo que con eso debe bastarte

saludos
Reinier



 

anything