Mostrando entradas con la etiqueta asbasp. Mostrar todas las entradas
Mostrando entradas con la etiqueta asbasp. Mostrar todas las entradas

3 ago 2010

Cuando lo analogo se vuelve digital.

Bien, en esta entrada vamos a usar el ADC del Atmega8. ADC es el acronimo en inglés para Conversor Analogo Digital. Existen muchos elementos analogos que podemos usar a travez del ADC: Fotoceldas, termopares(para medir temperatura), sensores de presión, sensores de distancia, etc. En este caso vamos a usar una LDR (Resistencia Dependiente de la Luz) para saber si nuestro dia esta nublado (ok es medio inutil, pero algun ejemplo hay que dar). Para hacerlo mas interesante, vamos a agrega un boton para establecer el umbral de cambio.

Vamos a usar el mismo conexionado de Programus Interruptus. Con la excepción de que vamos a icluir una LDR y una resistencia de, digamos, 1Mohms.


Ahora vamos a elegir las opciones para nuestro Atmega8. Quedando asi:

Notemos que he dejado el bit 3 del puerto D como entrada con resistencia pull-up, de este modo no tenemos que agregar la resistencia de 10kohms externa.


El programa se encuentra aqui. Incluye las explicaciones.

Algunos ya se habran dado cuenta de que copiar el programa tal cual se los entrego sobreescribe todas las opciones que elegimos al generar el proyecto con el CodeWizard. No obstante sigo haciendolo por cuestiones didacticas.

En la siguiente entrada vamos a agregar una cosita mas. Algo llamado PWM.

Los quiero banda. Comenten.

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.


4 ene 2009

Parpadeo: El ' 10 Print "Hola" ' de los Microcontroladores.

En mis tiempos... si, ya habían coyotes, y eran coyotes dientes de sable.... El primer lenguaje que uno aprendía a programar era BASIC y lo primero que uno aprendía a programar en BASIC era:

10 PRINT "Hola"

Run
Hola

Ese arcaísmo de allá arriba lo único que lograba es que una computadora dijera hola. Sin embargo uno debe siempre empezar por algo.

El equivalente a esta practica en cuanto a microcontroladores e refiere es el parpadeo de un led. Es igual de inútil, pero cuando uno lo logra por primera vez, y aun mas cuando logra variar la velocidad del parpadeo suena la musica de fondo de "Odisea 2001" con nosotros interpretando al chango mas listo. Ok, esto ultimo jue una alegoría.

Primero vamos a conectar el foquito. Partiendo de que ya conectamos nuestro programador al Atmega8 y que lo tenemos conectado al puerto USB. El programador tomara 5v de la conexión con la computadora y alimentara al AVR así que no necesitaremos otra fuente de energía para probar nuestro circuito. Necesitaremos un led y una resistencia de 1Kohm. La siguiente ilustración indica como debemos conectarlo. Recuerda que la patita mas larga va conectada al pin 14 del AVR ya que entrega la señal positiva.


Vamos a entender a donde hemos conectado el dichoso foquito.


En esta ilustración podemos ver que el chip tiene 3 puertos de entradas/salidas programables PORTB, con 8 bits disponibles PORTC, con 7 bits disponibles y PORTD con 8 bits a su vez. El patillaje nos dice, por ejemplo que el bit 0 (lsb) del PORTB es la terminal 14 del chip. Tal vez se pregunten ¿Por que están los bits todos fuera de orden? La razón recae en que así es mas fácil soldar las terminales a la pastilla de silicón dentro del encapsulado. Para quien haya usado un 4017 alguna vez esto no sera una sorpresa.

Ahora bien preparemonos para programar. La programación se hace en lenguaje C. No te espantes, yo tampoco lo había usado nunca y se aprende en 3 patadas, al menos lo suficiente como lo para aprovechar estos tutoriales/ejemplos.

Abrimos el CodeVisión por primera vez. En caso de que nos aparezca un programa en la pantalla, este sera el ultimo que usamos. En tal caso elegimos File -> Close All.

Vamos a llamar al asistente Code Wizard que tiene un engrane como icono.

Las imágenes de CodeVision, el programa y nombre CodeVision AVR C Copmiler y demás material incluido en esta son propiedad de HP Info Tech© y se encuentran protegidas por los derechos de autor correspondientes. Se usan con fines meramente didácticos sin perjuicio económico ni moral. Si algún representante debidamente identificado lo solicita serán removidas de este sitio.

Este asistente nos permite configurar el tipo de AVR que usaremos, que tipo de reloj utilizara y la configuración de sus puertos para conectarlo a diversos dispositivos. Lo primero que haremos sera configurar el tipo de chip como Atmega8 quedando de la siguiente manera. (Recuerde que al hacer click en las imágenes estas se muestran mas grandes).

Aquí estamos indicando que nuestro AVR es un Atmega8, que trabajaremos a 1Mhz y que haremos una aplicación.

Una vez hecho esto, vamos a configurar el puerto B (PORTB) como salida. Quedando como sigue:

Una vez hecho esto elegimos File-> Generate, Save and Exit y pediremos que guarde los tres archivos con el nombre 1.cwp, 1.c y 1.prj respectivamente. Usaremos la carpeta c:\atmega8 claro que esta puede ser la que uno desee, pero para fines de mantener este sitio comprensible siempre usaremos esa carpeta.


Ok ahora en el fondo de la pantalla se genero el siguiente script. Recuerda que el signo // significa comentario y es ignorado por el microcontrolador. Solo se agrega para poder dar un mejor seguimiento 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 : 18/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>


// Declare your global variables here

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

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

// 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=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
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;

while (1)
{
// Place your code here

};
}



Vamos a concentrar nuestra atención en la parte que dice #include<mega8.h>. Es en esta zona del programa donde indicaremos las librerias que utilizaremos. Debajo de esa linea vamos a agregar #include<delay.h> que es la librería que nos permite hacer un retraso de tiempo.

Quedando (el fragmento) así:



Data Stack size : 256
*****************************************************/

#include <mega8.h>
#include <delay.h>

// Declare your global variables here


Despues localizaremos la parte donde el verdadero programa debe escribirse. Es facil encontrarlo, se encuentra al final e incluye el comentario //Place your code here.



while (1)
{
// Place your code here

};
}


Todo lo que se encuentre entre la llave { y la llave }; de esta zona se repetira infinitamente mientras el chip este encendido y no se indique otra cosa. Una vez klocalizado esto escribimos los siguientes comandos:

PORTB.0=1; // Esto pone el bit 0 (pin 14) del puerto B en nivel alto (casi 5v).
delay_ms(200); // Esto produce un retardo de 200 milisegundos.
PORTB.0=0; // Esto pone el bit 0 (pin 14) del puerto B en nivel alto (casi 0v).
delay_ms(200); // Esto produce un retardo de 200 milisegundos.

Quedando el fragmento de la siguiente manera.



while (1)
{
// Place your code here
PORTB.0=1;
delay_ms(200);
PORTB.0=0;
delay_ms(200);
};
}

De este modo le hemos ordenado al chip que prenda y apage el foco en intervalos de 200ms continuamente.

Ahora vamos a compilar y ensamblar el codigo ejecutable 1.hex. Para eso podemos pulsar Shift +F9 o bien dar click en el siguiente icono:



Si hemos hecho las cosas correctamente, debera aparecer la siguiente ventana:


Si hemos cometido un error nos lo indicara en la parte de abajo de la ventana genereal, los errores mas comunes a esta altura son:

1.- No terminar los comandos con ;
2.- Escribir PORTB en minusculas (portB, PortB, portb, etc)
3.- Escribir la vocal O en lugar del numero 0
4.- Errores ortograficos ejemplos: dilay_ms(200); o PARTB.0=1;

Corrijamos e intentemos compilar de nuevo.

Bien pues solo falta montar nuestro programa. Para ello abriremos la consola de Windows (boton Inicio-> Ejecutar -> cmd):

El logotipo de Windows asi como la marca registrada Windows© y demas imagenes propias de dicho sistema operativo son propiedad de Microsoft© y son usadas para fines meramente didacticos. Si algun representante debidamente identificado de dicha empresa lo solicita seran retiradas de este blog.

Nos colocamos en la carpeta c:\atmega8\Exe que es donde se guardo el ejecutable (1.hex). Despues llamaremos al comando avrdude con las opciones -p m8 que es nuestro avr, -c usbasp que es nuestro programador, -e que indica que borre todo programa anterior, -u par que no use el modo seguro (mas lento), -V para que no verifique si se cargo correctamente (tambien mas lento) y por ultimo -U flash:w:1.hex que significa cargar el progrma 1.hex en la memori flash en modo de escritura.

En pantalla luce así:



Al dar Enter el programa se cargara en el AVR y en segundos el LED empezara a parpadear.

Si no lo hace:
1.- Revisa las conexiones y la polaridad del LED.
2.- Prueba que tu led no este quemado.
3.- Compila y Monta de nuevo.
4.- Intenta empezar todo de nuevo.
5.- Agrega un comentario solicitando ayuda (probablemente necesite una foto de tu protoboard). Incluye tu correo electronico.

Cosas que hacer una vez que logramos que este primer programa/aplicación funcione: (recuerda compilar y montar cada vez que hagas cambios para que estos funcionen)

* Juega con los valores de delay_ms(); para producir pulsos asimetricos.
ejemplo:

PORTB.0=1;
delay_ms(50);
PORTB.0=0;
delay_ms(500);

*Agrega mas lineas de encendido y apagado.
ejemplo:

PORTB.0=1;
delay_ms(50);
PORTB.0=0;
delay_ms(50);
PORTB.0=1;
delay_ms(50);
PORTB.0=0;
delay_ms(200);

* Intenta conectar el led en el bit PORTB.1 (patita 15) y cambia la programación.
Ejemplo:

PORTB.1=1;
delay_ms(200);
PORTB.1=0;
delay_ms(200);

Recuerda que la patita mas larga del led debera ir a la pata en cuestion (en este caso la 15) del avr y la mas corta del led en serie con la resistencia de 1kohm a tierra (gnd) (patita 8 del avr).

Pues bien, esto es todo para esta entrada, de momento hemos conseguido un ne555 muy caro, pero no se preocupen, en la siguiente se empezara a notar un poco mas de provecho jeje. Buena Suerte


Nota: Escribir esto se me hizo eterno jeje. Recuerden que la mayor parte de mis imagenes son originales y estan protegidas por la Ley Federa de Derechos de Autor y su Reglamento. Asi que si desean usarlas en otros sitios deberan mantenerlas sin modificación y mencionar este sitio como fuente. En caso de utilizarse con fines comerciales requeriran una autorización por escrito que podra o no tener un costo.

3 ene 2009

Instalando el software

Bien, para este ejercicio necesitamos que instales los dos siguientes programas + un driver:

WinAVR: Este programa contiene la utileria avrdude que nos permitirá montar el programa en el chip.

CodeVision AVR C Compiler©: Esta aplicación nos permitirá generar un programa en c con todas los ajustes necesarios según el tipo de avr y opciones que necesitemos. La versión de evaluación es gratuita para fines no comerciales.

Driver del USBasp: Este driver viene siempre con tu programador.

Instala los programas, con las opciones por default sera adecuado.

Conecta el programador a un puerto usb libre en tu maquina, te va a pedir un driver, asi que mete el cd que deben haberte enviado con tu programador y dale continuar. Si falla interna de nuevo.

Básicamente eso es todo, en algún punto en el futuro voy a incluir una explicación mas detallada, pero de momento me parece suficiente. Aun así, si necesitas algún tipo de ayuda agrega tu pregunta a comentarios.