Vous êtes sur la page 1sur 18

TUTORIAL TACOMETRO EN LCD CON ATMEGA8

Por scar Razo Navarrete


INSTITUTO TECNOLGICO DE ESTUDIOS SUPERIORES DE ZAMORA
DPTO. DE INGENIERIA ELECTRNICA.
Este es el primer tutorial que realizo para COMUNIDAD ATMEL, y espero seguir aportando
conocimientos.
Bsicamente se trata de un tacmetro que valga la redundancia, nos servir para medir las vueltas
que da la flecha de un pequeo motor de 5 volts durante un minuto, el valor de las RPM ser
desplegado en
una pantalla de LCD de 16x2, aunque tambin se pueden desplegar los datos en displays si as lo
quisiramos, pero yo escog la pantalla porque es mas fcil, se ahorran pines, y puse un texto en la
lnea de debajo de la pantalla el cual dice: COMUNIDAD ATMEL.

FUNCIONAMIENTO
La forma que determina el funcionamiento de este programa es sencillo. Utilizaremos el Timer0
del ATMEGA8, el cual tiene una funcin que nos permite contar los pulsos externos generados por
un motor que tiene un disco (hecho con un pedazo de cartn) con 8 agujeros, el cual esta en
medio de un emisor y un receptor infrarrojos, y es el receptor el que el que enviar los pulsos a el
pin numero6 (que corresponde al bit 4 del puerto D) cada vez q el rayo es interrumpido. Una vez
que son los 100ms se lee el valor que existe en el TMR0, lo multiplica por 75 esto debido al tiempo
por minuto y el producto entre los agujeros 8, nos da como resultado 75.(O sea como estamos
muestreando cada 100ms, entonces en un segundo caben 10 veces 100 ms de acuerdo? Esto
quiere decir que a un minuto le caben 600 veces 100ms (espero haberme explicado) y es por esto
que 600/8=75 (8 es el numero de agujeros).
Por lo tanto el numero menor de revoluciones que podremos medir sern 75, ya que el numero
menor de pulsos que se pueden medir en 100ms es 1 y entonces 1x75=75.

Diferentes vistas del motor DC de 5 volts con un disco hecho de cartn el cual tiene 8 agujeros.


NOTA: Si se desea obtener una mayor resolucin, ser necesario hacer mas agujeros en el disco,
por ejemplo si el disco tiene 60 agujeros, entonces haremos: 600/60=10 y para este caso el
numero menor que se puede medir ser de 10 RPM, pero para efectos de este tutorial se utilizar
el disco con 8 perforaciones.


Emisor y receptor infrarrojos.

aqu estar el disco girando para interrumpir el rayo infrarrojo y contar los pulsos

Diagrama esquematico

De aqu tomaremos laseal para conectar
Al bit 4 del puerto D, o lo que es lo mismo el pin numero 6 del ATMEGA8.



Como se dijo anteriormente, los pulsos se cuentan de tal manera que en un lapso de 100ms
capturamos el numero de pulsos
que se generaron en el pin(es decir estamos haciendo un muestreo del contador del timer0 cada
100ms) y luego este valor(TCNT0), se multiplica por 75 para obtener el resultado, posteriormente
este
resultado se compara con el numero 9999 (esto debido a que solamente utiliz 4 digitos y el valor
mximo que se puede desplegar en 4 digitos es 9999) y si es menor a 9999, se divide entre 1000
para obtener el numero de los millares, el residuo se divide entre 100 para obtener las centenas,
el residuo de las centenas se divide entre 10 para obtener las decenas, y el residuo de las decenas
simplemente lo colocamos en las unidades.
IMPORTANTE: Es necesario estar refrescando el TCNT0, para que cada muestreo nos de el numero
de pulsos correspondiente, y por eso al principio de la ejecucin del programa borramos el TCNT0
(ya que si no lo borramos, el valor del TCNT0 se acumulara para el siguiente muestreo y nos dara
una lectura errnea del valor real de los pulsos obtenidos en ese siguiente muestreo)













CODE WIZARD
Haremos un nuevo proyecto en el code wizard en el cual escogeremos el ATMEGA8 (ojo no es el
ATMEGA 48, aunque tambin es posible realizar el programa, pero los timers son un poco distintos
asi que debemos tener cuidado a la hora de seleccionar nuestro microcontrolador, y checar su
respectiva hoja de datos) con una
frecuencia interna de 1 MHZ, es importante sealar que el code wizard no nos da la opcin de
dividir la frecuencia para el atmega8, como en el atmega48, solo escogeremos 1MHZ y listo.
Tambien seleccionaremos la pantalla de 16X2 para ser utilizada en el puerto B.
En la pestaa de timers vamos a dar click en Timer0 y luego en clock source vamos a
seleccionar la opcin de T0 pin Falling Edge porque los pulsos se contarn cuando haya un 0
lgico.
En la pestaa de ports vamos a seleccionar el pull up del bit 4 del puerto D, ya que es por este
pin por donde vamos a contar los pulsos, y si no le ponemos el pull up podran filtrarse seales
no deseadas por este pin.


Aqu seleccionamos ATMEGA8 a 1MHZ


Seleccionar pantalla LCD en el puerto B





Aqu seleccionamos el timer0 en la opcin T0 pin Falling Edge





Y por ultimo habilitar pull up del bit 4 del puerto D










El siguiente es el cdigo generado por el code wizard y lo que est en color azul es lo que se debe
agregar al programa:
/*****************************************************
This program was produced by the
CodeWizardAVR V2.03.6 Evaluation
Automatic Program Generator
Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project :
Version :
Date : 12/05/2009
Author : Freeware, for evaluation and non-commercial use only
Company :
Comments:


Chip type : ATmega8
Program type : Application
Clock frequency : 1.000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*****************************************************/

#include <mega8.h>
#include <delay.h>
unsigned int x; // definimos x del tipo int porque el resultado de
unsigned char y; // la multiplicacion no cabe en un byte
const char z=0x4b;
char unidades=0;
char decenas=0;
char centenas=0;
char millares=0;
char a=0;
char b=0;
char c=0;
char d=0;

// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h>

// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=P State3=T State2=T State1=T State0=T
PORTD=0x10;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: T0 pin Falling Edge
TCCR0=0x06;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// LCD module initialization
lcd_init(16);

lcd_gotoxy(1,1);
lcd_putsf("COMUNIDAD ATMEL");
lcd_gotoxy(4,0);
lcd_putsf("RPM=");

while (1)
{
// Place your code here

TCNT0=0; //borramos el contador del timer 0
delay_ms(100); //Se hace un retardo de 100 milisegundos
y=TCNT0; //pasamos el valor de TCNT0 a y
x=y*z; //recordemos que z vale 75
if(x<=9999) //haremos las operaciones solamente si las RPM son menores de 9999
{
millares=x/1000; x=x%1000; //aqui separamos el
centenas=x/100; x=x%100; //valor de x en unidades,decenas
decenas=x/10; unidades=x%10; //centenas y millares
}

a=0x30+millares; //le sumamos 0x30
b=0x30+centenas; //para desplegar los nmeros
c=0x30+decenas; //tal y como se vio en el
d=0x30+unidades; //tutorial de LCD

lcd_gotoxy(8,0); //desplegamos
lcd_putchar(a); //millares

lcd_gotoxy(9,0); //desplegamos
lcd_putchar(b); //centenas

lcd_gotoxy(10,0); //desplegamos
lcd_putchar(c); //decenas

lcd_gotoxy(11,0); //desplegamos
lcd_putchar(d); //unidades


};
}

Este es el diagrama de conexin, cabe sealar que para efectos de simulacin, se introdujo una
seal de reloj en el pin T0.







Esta es una foto real del circuito ya funcionando.

Si se desea variar la velocidad del motor, simplemente con variar el voltaje de alimentacin del
motor es suficiente.








Bueno, en este tutorial trato de explicar lo mas que puedo, ojal me haya dado a entender pero
espero que lo entiendan para que armen el circuito, ya que funciona muy bien.
Gracias.

scar Razo Navarrete, alumno del Instituto Tecnolgico de Estudios Superiores de Zamora, en la
carrera de Ingeniera en Electrnica.

mayo de 2009