Leer TImer 1 16 Bits

Hola gente, tengo el Arduino Mega y quiero Leer el registro ICR1 perteneciente a la aplicacion de captura de eventos, y quiero saber si se puede leer directamente el registro, o al ser en 16 bits es necesario leer primero el valor bajo(LOW) y despues el alto, y si asi es, entonces como deberia hacerlo, he probado la siguiente manera:

x=ICR1L+ICR1H;

Solo quiero saber si el número que obtengo es el real o si no es ese el camino correcto para leer ese registro.

Gracias. :slight_smile:

Hola,

En mi opinion, puedes leer directamente ICR1. En el siguiente link tienes un buen tutorial (ingles):
http://winavr.scienceprog.com/avr-gcc-tutorial/program-16-bit-avr-timer-with-winavr.html

Otra cosa, para crear una variable de 16 bits, a partir de dos de 8 bits, no lo haces sumando..... Tienes que usar bitwise (<< - Arduino Reference).
Ej:
00000001 00000000 = 256 (decimal)
00000001 + 00000000 = 1 (decimal)

Saludos :wink:

Igor R.

Gracias por los links Igor, les echare un vistazo ahora.

Probando a leer el registro directamente el problema que he obtenido es que me salen tambien numeros negativos, y el tema es que si se supone que es una cuenta positiva no entiendo porque me da esos numeros negativos.

Lo de la captura de eventos lo estoy haciendo mediante una matriz, y en la cual cada vez que se efectua un evento introduzco el valor de ICR1 en cada una de sus posiciones, y asi poder hacer una especie de estadistica de tiempos y poder ver cada cuanto se efectua el evento, pero al tener numeros negativos como os comentaba esa estadistica es dificil de comprender.

Un saludo!

Hola,

Te adjunto un ejemplo de codigo que tengo para medir duty cycle y frecuencia por la entrada ICP, funciona bien:

// ---------------------------------------------------------
// Funcion para la interrupccion INPUT CAPTURE
ISR(TIMER1_CAPT_vect)
{

if (PINB & B00000001)
{
//Un nuevo flanco de subida significa fin de periodo
periodo=ICR1-flanco_subida;
tiempo_on=flanco_bajada-flanco_subida;
// Recojo el tiempo para medida del nuevo pulso
flanco_subida=ICR1;
//Cambio a flanco de bajada (bit 6 a "0")
TCCR1B=TCCR1B & 0xBF;
//contador_overflow=0;
//En la documentación explica que hay que poner un "1" para desactivarlo y es recomendable hacerlo cuando se trata de medir duty cycle
TIFR1|=(1<<ICF1);
rpmcount++;
}
else
{
flanco_bajada=ICR1;
//Cambio a flanco de subida(bit 6 a "1")
TCCR1B=TCCR1B | 0x40;
}

}
// ---------------------------------------------------------

Las variables son:

volatile long contador_overflow;
volatile long tiempo_on;
volatile long periodo;
unsigned int flanco_subida;
unsigned int flanco_bajada;

La configuracion de registros;

// CONFIGURO LOS REGISTROS PARA HABILITAR INPUT CAPTURE DEL TIMER 1
TCCR1A=0;
// Deshabilito Noise Canceler,Flanco de subida,1/8 preescaler
TCCR1B=(0<<7)|(1<<6)|(0<<4)|(0<<3)|(0<<2)|(1<<1)|(0<<0);
// Habilito Input Capture y Overflow
TIMSK1=(1<<5)|(0<<2)|(0<<1)|(0<<0);

Lo he extraido de parte de un programa que hace mas cosas... Espero no haberme dejado nada.... A ver si te sirve..... :wink:

Saludos

Igor R.

Gracias, creo que lo tengo mas pillado el tema, ya solo me quedaria una pregunta por hacer:

En que magnitud se supone que nos da el tiempo el ICR1?, en ms, us, frecuencia...

Gracias!

Te recomiendo leerte este link y el datasheet del Atmega168/328:

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=50106

Te ayudara a entender un poco mejor como funciona los timers.

Saludos :wink:

Igor R.

Gracias por el link Igor, viene bastante bien explicado el tema, tengo el data sheet del Atmega1280 lo unico que tampoco especifica el valor en que te daba registro TCNT1, creo que con el link de avr freaks sacare buen partido de ello.

Me alegro que te sirva. En el datasheet si que viene explicado, pero no es tan claro como el tutorial de AVR Freaks.
Ya veras que una vez que le pilles el funcionamiento, en el datasheet tienes todo. Pero hay que reconocer,que si no has visto nunca antes como funciona un timer/counter, pues el datasheet no es la mejor fuente para aprender.

Saludos

Igor R.