Autor Tema: Uso de Timer para determinar frecuencia de una onda  (Leído 636 veces)

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

Desconectado gioalex07

  • PIC10
  • *
  • Mensajes: 27
Uso de Timer para determinar frecuencia de una onda
« en: 12 de Febrero de 2018, 23:30:56 »
Hola comunidad,  estoy ingresando al mundo de atmel y micros de 8 bits, como primera parte se quiere saber cual es la frecuencia de una onda cuadrada por medio del uso de timers. He hecho la posible configuracion de TC0 y TC2 pero no se como llevarlo a cabo ya que no comprendo como puedo exportar el tiempo o el conteo del timer y usarlo para determinar dicha frecuencia y a su vez poder mostrarla en un lcd 2x16

agradezco puedan ayudarme ya que no existe mucha informacion para poder manejarlos de manera correcta.


#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "lcd.h"
char variable = 0;

int main(void){
   CLKPR = 1 << CLKPCE; // Configuracion de prescaler bit 7
   CLKPR = 0; // Division del prescaler en 1
   TCCR0A = 0;
   TCCR0B = 0b00000101; //Determina conteo por flancos de subida
   TIMSK0 = (1<<TOIE0); //Habilitacion de la interrupcion
   TIFR0 = (1<<TOV0); // Flancos de voltaje
   TCNT0 = 0; // Timer reseteado en 0
   TCCR2A = 0;
   TCCR2B = 0b00000111; // Prescalizado 1024
   TIMSK2 = (1<<TOIE2); //Habilitacion de la interrupcion
   TCNT2 = 0; // Timer reseteado en 0
   sei();
   DDRA |= 1;
   DDRB = _BV(PB0);
   PORTB |= 0b00000000;
   PORTA |= 0b00000001;
   lcd_init(LCD_DISP_ON);
   lcd_clrscr();
   lcd_home();
   lcd_gotoxy(0,0);
   lcd_puts("Frecuencia:");
   
    while (1) {
            
    }
}

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4744
Re:Uso de Timer para determinar frecuencia de una onda
« Respuesta #1 en: 13 de Febrero de 2018, 07:02:12 »
¿Qué frecuencias quieres medir?
¿Con cuánta precisión?

¿Qué micro estás utilizando, un Atmega328?
« Última modificación: 13 de Febrero de 2018, 07:10:19 por Picuino »

Desconectado gioalex07

  • PIC10
  • *
  • Mensajes: 27
Re:Uso de Timer para determinar frecuencia de una onda
« Respuesta #2 en: 13 de Febrero de 2018, 14:31:03 »
Se quiere medir la frecuencia de la toma de pared (60 Hz), ya se hizo la etapa de rectificación y cambio a señal cuadrada para que ingrese al puerto PB0 - T0 .. la precisión no sabria como manejar ya que hasta el momento estoy comprendiendo la prescalizacion del contador..

Gracias

*mi idea era usar TCNT0 para contar flancos de subida y TCNT2 para saber cuanto tiempo tardo entre flancos asi determinaría el periodo y por ende la frecuencia pero no se como lograrlo

** idealmente deberia mostrarme la frecuencia de cualquier señal
« Última modificación: 13 de Febrero de 2018, 14:45:04 por gioalex07 »

Desconectado AleSergi

  • PIC16
  • ***
  • Mensajes: 163
Re:Uso de Timer para determinar frecuencia de una onda
« Respuesta #3 en: 13 de Febrero de 2018, 14:50:04 »
....  mundo de Atmel...  ,  ya fue,  ahora es  AVR Microchip  (muy a mi pesar! )

La historia por la cual preguntás,  esta en rumbo,  pero no es el camino mejor.

Resulta ser que muchos AVR,  tienen un hardware llamado ICP,  en modo "capture event"  hace lo que estás preguntando.
Entonces,  se pone a correr el Tmr1,  la fuente es el oscilador del micro,  con o sin pre-escalador según tu necesidad, se activa la interrupción de éste hardware,  cuando se presenta un evento en el pin icp,  dispara la interrupción,  del Tmr1 copias el valor al momento de la interrupcion,  pones a cero el Tmr1,  tambien has activado la interrupcion por desborde del Tmr1 y obvio agendas su ocurrencia.
Ahora con esos números haces los cálculos y obtenés el tiempo ocurrido entre dos eventos que ocurren en el pin icp.

mira los enlaces que dejo,  Yo lo aprendi de allí,  hasta código tienen.

http://www.nerdkits.com/forum/thread/1273/

http://www.avrprojects.net/index.php/avr-learn/getting-started-with-avr/51-programming-the-timer-counter-1?showall=1


 

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4744
Re:Uso de Timer para determinar frecuencia de una onda
« Respuesta #4 en: 13 de Febrero de 2018, 16:31:48 »
Algunos comentarios:

1º. Es muy importante que el detector de cruce por cero sea muy exacto para evitar jitter.
Intenta filtrar el ruido de alta frecuencia para que no te afecte.

2º La precisión de la frecuencia de red es bastante baja. Con 4 ó 5 decimales tendrás suficiente.
A la larga se ajusta la frecuencia para que el desfase sea pequeño y se pueda usar como base de los relojes, pero en tiempos cortos la frecuencia varía mucho.

Yo lo haría contando pulsos de reloj entre cruces por cero pares (uno de cada dos) de la señal de red.
Si lo haces con todos los cruces por cero no funcionará bien porque la onda no es simétrica.

Si utilizas un reloj de 10MHz, contarás unos 166666 ciclos cada dos cruces por cero (como te dijo AleSergi con el TMR1 y su desbordamiento).

Después la fórmula es:

   Frecuencia de red = Frecuencia de reloj / Ciclos contados =  10000000/166666 = 60.0000

Con numeros flotantes de simple precisión obtendrás 4 decimales con error de +-4 en el último decimal. De sobra para la frecuencia de red.


3º No pongas a cero el TMR1
Es preferible hacer 'continous timestamp' que significa que cuentas pulsos de reloj y desbordamiento con 32 bits y luego calculas la diferencia entre dos samples.
Eso compensa los errores sistemáticos de medida y si en una medida has contado de más, en la siguiente contarás de menos.
Además podrás hacer medias mucho más precisas durante un tiempo mayor.

Saludos.

Desconectado gioalex07

  • PIC10
  • *
  • Mensajes: 27
Re:Uso de Timer para determinar frecuencia de una onda
« Respuesta #5 en: 15 de Febrero de 2018, 13:51:46 »
Bueno intente las soluciones planteadas (gracias por todo ese apoyo) pero pues mi docente dijo que debia solo usar TCNT0 nada más. Que a medida que se subia la intensidad de la materia se usaban las diversas funciones pero como es el primer uso del timer solo debia usar ese puerto.


En resumen (Debo poder medir una señal que entre por cualquier puerto y en un display lcd mostrar la frecuencia a la cual opera dicha señal.) La meta era que con este manejo de timer se pudiera interpretar la señal de un control remoto con protocolo IR y mostrar el boton oprimido. Es por eso que no puedo dar uso de otros

Desconectado gioalex07

  • PIC10
  • *
  • Mensajes: 27
Re:Uso de Timer para determinar frecuencia de una onda
« Respuesta #6 en: 17 de Febrero de 2018, 21:23:12 »
Alguien? No he podido..

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4744
Re:Uso de Timer para determinar frecuencia de una onda
« Respuesta #7 en: 18 de Febrero de 2018, 07:16:26 »
Es que no está claro lo que quieres hacer.
Ahora de repente aparece la limitación de usar solo el Timer 0.
¿Cuánta precisión necesitas? Lo digo porque con ese timer nada más, te va a costar tener buena precisión.

Además parece que tienes que hacer más cosas. No es lo mismo medir frecuencia sin hacer nada más, que medir frecuencia con un solo timer y además hacer otras cosas de forma concurrente.

¿No querías medir la frecuencia de red? ¿O al final es la frecuencia de una señal IR?

Creo que el problema no está bien explicado, de manera que es difícil plantear una solución a algo que no se conoce.
Si nos explicas con detalle qué es lo que necesitas, quizás podremos ayudarte.


Un saludo.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 6769
Re:Uso de Timer para determinar frecuencia de una onda
« Respuesta #8 en: 18 de Febrero de 2018, 11:00:06 »
Citar
¿Cuánta precisión necesitas? Lo digo porque con ese timer nada más, te va a costar tener buena precisión.

Si esta estudiando y recien comienza parece que no necesita tanta precisión. Primero que aprenda a manejar el TMR y luego las demas cosas, no introducirle todo junto, esa es la idea del profesor.

Citar
En resumen (Debo poder medir una señal que entre por cualquier puerto y en un display lcd mostrar la frecuencia a la cual opera dicha señal.) La meta era que con este manejo de timer se pudiera interpretar la señal de un control remoto con protocolo IR y mostrar el boton oprimido. Es por eso que no puedo dar uso de otros


Simple, pone a correr el TMR0... la idea ya te la dijeron como es..

Detecto un flanco descendente
Valor anterior =  el valor del TCNT0
Detecto otro flanco descendente
Valor actual =  el valor del TCNT0

Luego tenes que Valor actual - Valor anterior = Cantidad de ciclos que pasaron.

Sabiendo la entrada de reloj y de preescaler, podes calcular cuanto tiempo tarda en contar 1 el TMR0

Ejemplo con 10Mhz y preescaler de clk/1 te vas a encontrar conque cuenta 1 cada:

Preescaler * \frac{1}{Frecuencia} = Periodo del Timer

En este caso es de T = 0.1us
Si usas un preescaler de 1024, quedaria T = 102.4us

Conociendo el tiempo que pasa en cada cuenta, y conociendo cuantas cuentas pasaron ( gracias a tu resta de lso valores tomados del TMR0 ) podes conocer cuanto tiempo paso:

Suponiendo que

Valor actual - Valor anterior = 100
Y el periodo es T = 102.4us

Quiere decir que el periodo de la señal fue:
100 * 102.4us = 10.24ms
Y por consecuente su frecuencia es 1 / 10.24ms = 97.65625 Hz

----------------

Limitaciones y consideraciones en esto.
El TMR0 es de 8 bits si no mal me equivoco. Y existe un problema si es que ocurre un overflow.
El mayor problema esta en que si no se fija uno en este indicador, nos puede jugar una mala pasada.

Supongamos una frecuencia de 100Hz, pero esta ves vamos a usar un preescaler mas pequeño clk/1
El tema es que para conseguir este valor el Timer debe contar 100000, lo cual es imposible ya que su maxima cuenta es de 255.
Este caso es muy extremo, pero esto te da una idea que para una frecuencia baja tendrias que tener en cuenta esto. Si tu profesor te indica un rango de frecuencia msomenos fijo, entonces eso te sirve como para seleccionar adecuadamente el preescaler y no hacer demasiados artilugios para llevar bien la cuenta.

Sino vas a tener que observar siempre el indicador de overflow. Y como actuo sobre este?
Supongamos que tu primer flanco y el primer valor te dio 24, mientras esperas el segundo flanco, lees continuamente el bit de overflow y el del timer, si resulta que : TOV0 = 1 y TCNT0 >= 24 entonces a tu valor de resta le tenes que sumar 256, procedes a borrar el bit de TOV0, y esperar nuevamente el flanco y mirando esas 2 cosas.

Si pasa suponete en total 2 veces y el "Valor actual" es de 50, entonces el valor total va a ser de :

Ciclos totales = (Valor actual - Valor anterior) + (CantDeOV * 256)
En el ejemplo:
Ciclos totales = (50 - 24) + (2 * 256) = 538 ciclos

Y superaste el limite de contar solo 255 como maximo

PD: Valor actual y Valor anterior si o si son de 8 bits, asi aprovechar el overflow de estos al restar.

PD2:
Citar
) La meta era que con este manejo de timer se pudiera interpretar la señal de un control remoto con protocolo IR y mostrar el boton oprimido.

Es cierto que difiere bastante de la pregunta inicial, pero tu pregunta ya esta resuelta con este post.
« Última modificación: 18 de Febrero de 2018, 11:07:28 por KILLERJC »

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4744
Re:Uso de Timer para determinar frecuencia de una onda
« Respuesta #9 en: 18 de Febrero de 2018, 11:30:25 »
Uno de los problemas más frecuentes cuando un alumno comienza a aprender o cuando intenta resolver un problema consiste en que no comprende bien la pregunta que se le plantea.
Esto es también verdad para muchos profesionales con el 'culo pelado' de hacer proyectos.

Lo primero que hay que aclarar normalmente es el 'pliego de condiciones' o mejor dicho 'qué es realmente lo que el cliente/profesor quiere'

Es un error muy muy común comenzar a dar soluciones antes de entender realmente el problema.

A mí me parece que gioalex07 no tiene del todo claro qué tiene que hacer y eso es lo primero a solucionar.


Por ejemplo:
Si quieres poca precisión y la señal a medir es más o menos fija (60Hz de red o 38KHz de IR, ya veremos cómo queda al final) la respuesta es modificar el prescaler para que la medida sea menor de 256 cuentas y medir los pulsos con el TMR0.
También necesitas configurar una captura del valor del TMR0, pero con ese timer necesitas hacerla necesariamente con pooling por software y eso está peleado con realizar otras tareas mientras tanto.

O el profe se está haciendo pajas mentales y complicando mucho el problema de forma innecesaria (lo dudo) o el alumno no se entera de lo que le piden y nosotros tampoco.


Lo mejor es que el problema esté por escrito con todas las especificaciones con mucha claridad. De paso gioalex07 aprende a hacer las cosas bien desde el principio.


Un saludo.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 6769
Re:Uso de Timer para determinar frecuencia de una onda
« Respuesta #10 en: 18 de Febrero de 2018, 12:31:14 »
Comprendo lo que decis Picuino. Pero tus expectativas son un poco altas para muchos diria. Yo los trato como si fueran alumnos de educacion media ( 14-18 años ). Si me dijeran que son estudiantes de universidad, el trato es totalmente distinto.

Citar
A mí me parece que gioalex07 no tiene del todo claro qué tiene que hacer y eso es lo primero a solucionar.

Y con eso agrupaste al 95% de los estudiantes de educacion media. Y no quiero hablar mal pero tambien gran parte de los docentes de niveles medios.
El gran problema del estudiante, la comprension lectora, no comprenden lo que lee y es algo que al menos aca en Argentina y en el colegio donde me encuentro lo tienen todos los alumnos.

No se en que nivel esta gioalex07, pero por experiencia al dar clases me toco que por mas que le especifiques completamente todo, y para que se trata, el alumno siempre toma la mitad de las cosas, asi que no es sorprendente que el llegue con solo una parte. Una persona que se encuentra en la universidad, deberia minimo ponerse el a buscar.

Si supiera exactamente que es lo que debe hacer, para que lo esta haciendo, ni siquiera estaria preguntando aca. Vos le estas pidiendo que defina "requisitos" antes de comenzar un proyecto, cuando ni siquiera tiene conocimiento de los mismos, ni cuales, ni cuantos.
Y ahi te encontras con dos tipos de personas distintas, personas que preguntan cosas que pueden ser buscadas por google facilmente, y que leyendo obtendrian la respuesta. Y personas que crean un post comentan cual es su situacion, todas las posibles soluciones que  probaron con detalles y que aun asi no les dio ningun fruto o divergen de lo esperado.

El dijo que queria medir frecuencia. Correcto, lo llevaron entre Ale y vos a eso. Se presento una primera limitacion, solo el TMR0. Ellos no les va a preocupar que sea 59.9999 o 60.0001 y al profesor tal ves tampoco, ya que luego lo hara menos limitado en hardware, lo que le dara no solo un espectro mayor de modulos a elegir sino la diferencia que obtienen con estos.
Pienso que su primera aproximacion es que aprendan a usar el Timer, pero no usarlo, sino a comprender que es lo que hace el Timer. Que es un simple contador de la frecuencia que entra. Creo que esto es suficiente para el docente en este punto teniendo en cuenta que jamas tocaron un timer. Tal ves la idea del docente es un avance a medida de prueba-error

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4744
Re:Uso de Timer para determinar frecuencia de una onda
« Respuesta #11 en: 18 de Febrero de 2018, 14:14:11 »
Por el tipo de pregunta (manejo directo del timer, sin librerías ni Arduino) y el código adjunto en el primer post, he supuesto que gioalex07 es alumno de universidad que está comenzando con los microcontroladores.
La edad que he visto en el perfil parece confirmarlo.


gioalex07:
en estos casos se suele comenzar por algo muy básico que funcione y se va avanzando poco a poco.

Lo primero que yo suelo hacer es conectar con el PC a traves de la UART para poder comenzar a depurar. También puedes utilizar el programador en modo debugger. ¿Cómo programas y haces debug?

A partir de ahí vas poco a poco modificando el programa hasta que consigues lo que quieres.
Si en algún punto te atascas, entonces nos preguntas.
Así puedes ir poco a poco, comprendiendo cada paso y preguntar dudas concretas, que son las únicas que puedes esperar que te resolvamos aquí. El problema completo no te lo vamos a dar resuelto.

Un saludo.

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4744
Re:Uso de Timer para determinar frecuencia de una onda
« Respuesta #12 en: 18 de Febrero de 2018, 14:19:33 »
¿Qué frecuencias quieres medir?
¿Con cuánta precisión?

¿Qué micro estás utilizando, un Atmega328?

Desconectado gioalex07

  • PIC10
  • *
  • Mensajes: 27
Re:Uso de Timer para determinar frecuencia de una onda
« Respuesta #13 en: 18 de Febrero de 2018, 14:44:20 »
Primero muchas gracias !
Segundo: Utilizo el atmega644a con programador usbasp, son dos trabajos en 1, primero tengo que ser capaz de medir frecuencia de la red osea en mi caso para colombia es de 60 hz aproximadamente y si solo con el timer0 porque presente dudas al docente con timer1 y decia que era otro caso para manejar dicho timer, es decir, solo puedo usar el timer0 para saberlo manejar sin problemas, ya siendo capaz de medir esa frecuencia toca con un sensor infrarrojo leer la señal emitida por un control remoto pero si yo no se como usar timers ni leer la frecuencia ni pulsos ni flancos ni nada literal pues no podre hacerlo.. es ese el problema.

Intentare hacer lo que me indicaron y volvere a comentar con lo sucedido, gracias infinitas por entenderme y no dejar de ayudarme

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4744