6 ene 2009

Contador Digital de 0 a 99, Ya empieza a sonar a computadora.

Pues bien, ya a estas alturas espero que sean unos expertos para esto de las protoboards. Este que sigue ya es un poquito mas complicado. Vamos a conectar el Atmega8 a algo que nosotros podemos leer fácilmente. No uno, sino Dos, display's de 7 segmentos... (fanfardias y algarabía).

Existen en el mercado muchos tipos de displays de 7 segmentos (llamemosle D7s), pero la división inmediata mas importante para nosotros sera la "terminal común". Básicamente un D7S son ocho foquitos LED que tienen una de sus terminales (ánodo o cátodo) interconectada. De este modo los hay de Ánodo Común y Cátodo Común.

Desde "dentro" un display tipico se ve mas o menos asi:


Nosotros podríamos usar cualquiera de los dos, sin embargo al momento de esta publicación tenia yo dos de Cátodo Común y como prometí que todo lo probaría siempre al momento de redactar, pues esos son los que usaremos. El modelo que tengo a la mano es el DC05. Si tu posees otros de modelo diferente puedes usarlos, solo que tendrás que investigar la configuración de los pines en Internet. Para el modelo del ejemplo, el patillaje es el siguiente:


Los segmentos por tradición se llaman A, B, C, D, E, F y G. Suele escribirse el cátodo con la letra K para distinguirlo del segmento C. Para nuestro ejemplo no usaremos el punto.

Nuestro protoboard queda mas o menos asi:



Caray, se ve bien retro mi esquematico, me recordo al Atari2600 y mi Intellivision. Pero asi es como esta la cosa. Comp podran notar los anodos de cada segmento estan conectados en paralelo entre cada display, A con A, B con B, etc. Podria parecer que esto haria que los d7s presentaran el mismo numero cada vez, pero, los bits PORTC.0 y PORTC.1 estan conectados a los catodos de cada display. Si recordaran en el post de "Parpadeo, el 10 PRINT "HOLA" de los Microcontroladores" los bits pueden presentar un valor, que puede ser Alto (casi 5v) o Bajo (casi 0v), eso nos ofrece un diferencial de al rededor de 4.5v que son mas que suficientes para encender un led común. Eso nos lleva a otra reflexión, 4.5v son más que suficientes, de hecho son demasiados para encender un led cuya operación normal se acerca a los 3.3v. La solución de ambos problemas (Voltaje y presentar 2 dígitos a la vez) se encuentra en una técnica llamada escaneo. Ésta consiste en presentar un numero pero encender solo un d7s, después esperar un momento y presentar otro numero pero encendiendo el otro d7s. El efecto si es lo suficientemente rapido no se notara o se notara apenas. Por otro lado, nos proporciona un pwm "accidental" que permite que los leds no se sobre calienten a pesar de estar operando en sobre voltaje.

Ahora bien, ya sabemos que podemos expresar cualquier combinación de leds encendidos y apagados enviando un numero al PORTB. Entonces ¿que numeros corresponden a la combinación para formar cada digito en los display's?.

La idea es la siguiente:

Si queremos mostrar un 1 en el display necesitamos encender los segmentos B y C, asi que sumamos sus valores (2 y 4 respectivamente) y obtendremos un 6 que sera el valor que debemos enviar al PORTB. De este modo queda la siguiente tabla:

0 = 63
1 = 6
2 = 91
3 = 79
4 = 102
5 = 109
6 = 125
7 = 7 (que casualidad jeje)
8 = 127
9 = 103

Bien, explicado esto vamos a lo que te truje. Vamos a crear un proyecto nuevo en CodeVision como hemos hecho en las anteriores entradas, solo que en esta tambien vamos a programar el PORTC como salida.

Agregaremos la libreria delay.h agregando el comando #include<delay.h> en el area correspondiente, si no sabes donde checa los posts anteriores.

Las variables a definire seran:

int l; // (l sera el numero a contar)
int i; // (i nos va a servir para repetir el numero exhibido)
char seg []={63,6,91,79,102,109,125,7,127,103};
// (seg son los valores para expresar cada numero)

El programa en si quedara asi:


while (1)
{
if(l==100)
l=0;
for(i=0;i<5;i++)
{
PORTC=2;
PORTB=seg[l%10];
delay_ms(5);
PORTC=1;
PORTB=seg[l/10];
delay_ms(5);
}
l++;
};
}


Compilemos, montemos y eso es todo. Si no funciona checa la ortografia, mayusculas /minusculas, signos, etc.

Explicación del programa:


while (1) //Inicia el bucle principal del programa
{
if(l==100)l=0; //si l llega a 100, regresa su valor a 0
for(i=0;i<5;i++) //inica un bucle para i que se repetira 5 veces
{
PORTC=2; //manda negativo (un 0) al disp. de unidades, activandolo.
PORTB=seg[l%10]; //manda el valor de unidades a ambos display (solo hay uno activo)
delay_ms(5); // espera 5 milisegundos.
PORTC=1; //manda negativo (un 0) al disp. de decenas, activandolo.
PORTB=seg[l/10];//manda el valor de decenas a ambos display (solo hay uno activo)
delay_ms(5); // espera 5 milisegundos.
} // repite / termina el bucle de i
l++; //incrementa el valor de l
};
}

Algunos pueden tener duda de como separamos unidades y decenas. Recordemos 2 cosas: Tanto l como i son enteros (int) y en lenguaje c no hay división, sino modulación, es decir que no divide con decimales, sino con enteros y residuo. El signo % calcula el residuo de l/10 que nos dara las unidades. El signo / calcula los modulos de l/10 que nos dara las decenas.

No vallan a desmontar su circuito, lo vamos a necesitar para la proxima entrada.


2 comentarios:

  1. Quetal yo tambien compre un porgramador en comunidad atmel y ya soy miembro dela comunidad, he realizado los ejemplos que traen los tutoriales y tengo unos por ahi que he realizado con mis alumnos, muy sencillos pero didacticos espero poder pasarte algunos para aportar al desarrollo en atmega, saludos, charliesw...

    ResponderEliminar
  2. Voy a poner el link de tu blog en mi pàgina, a ver si me puedes enviar un correo porque perdì el tuyo. Atentamenet David Infante Sànchez.

    ResponderEliminar