Sei sulla pagina 1di 89

Guia de VideoTutoriales

Programador USBasp V3.0

INDICE
_____________________________________________________________________________________ Introduccin .................................................................................................................................................. 3 Parpadeo de un LED ...................................................................................................................................... 5 Manejo de los Puertos ................................................................................................................................ 11 Rota-bit ....................................................................................................................................................... 17 Contador de 0-99 con 2 Displays de 7 Segmentos...................................................................................... 23 Matriz de LEDs ............................................................................................................................................ 29 Interrupcin Externa ................................................................................................................................... 37 Uso del ADC................................................................................................................................................. 42 Uso del PWM .............................................................................................................................................. 47 Servomotor ................................................................................................................................................. 55 Pantalla LCD ................................................................................................................................................ 62 Sensor ultrasnico SRF08 ............................................................................................................................ 70 Comunicacin serial USART ........................................................................................................................ 81

Introduccin

Introduccin

Antes de empezar a leer esta gua, es recomendable leer la gua de usuario del programador, en la que se explica cmo usar el Programador y como instalar los programas necesarios para poder empezar a programar. Esta gua es propiedad de HeTPro. Queda expresamente prohibida la reproduccin total o parcial por cualquier medio o soporte de los contenidos de esta publicacin sin la autorizacin expresa del editor. Todas las marcas y productos aparecidos en esta gua son marca registrada y/o copyright de sus propietarios. Cualquier comentario, duda o sugerencia favor de escribir a:

soporte@hetpro.com.mx

Parpadeo de un LED

Parpadeo
Descripcin
En este programa se manejara el puerto para hacer parpadear un LED, en este caso se realizara el parpadeo a travs de dos mtodos distintos de programacin, utilizando todo el puerto o solo un bit del mismo, seleccionaremos el pin deseado el cual lo conectaremos a un LED en el cual visualizaremos el parpadeo.

Diagrama Esquemtico

Materiales
1 LED 1 Resistencia de 220 Ohms 1 Microcontrolador ATmega8 Programador USBasp V3.0

Introduccin
El microcontrolador tiene varios puertos de los cuales podemos hacer uso, estos puertos los podemos configurar como nosotros queramos, como entrada o como salida, para poder hacer esto es necesario escribir en los registros del puerto para darle las instrucciones necesarias. Existen tres principales formas de controlar los puertos, tomamos como ejemplo el puerto B.

DDR
Para obtener que el puerto B se comporte como entrada, como salida o ambos, es necesario indicarle esto en el DDR, este registro no activara ni desactivara ningn pin del microcontrolador, simplemente le indicara al puerto si este ser entrada o salida.

Para indicarle al DDR si el puerto sea de entrada o salida, el 1 indica salida, y el 0 entrada, se le puede escribir como hexadecimal, decimal, o binario, por ejemplo, si queremos que todos los bits del puerto sean salidas lo podemos escribir como sigue: DDRB=0xFF; //Como Hexadecimal DDRB=255; //Como Decimal DDRB=0b11111111;//Como Binario Si queremos que algunos bits funcionen como entradas: DDRB=0x8C; //Como Hexadecimal DDRB=140; //Como Decimal DDRB=0b10001100;//Como Binario Se puede escribir en cualquiera de los tres tipos (binario hexadecimal y decimal), en todos los registros.

PORT
El PORT controla la salida del puerto, este se usa en caso de que el DDR haya sido seleccionado como salida, un 1 en el PORT indica un nivel alto en el puerto como salida, un 0 indica que el pin esta en nivel bajo. Varias configuraciones de ejemplo para el PORT: PORTB=0xFF; PORTB=0x00; PORTB=0x03; //Todos los pines estan activos //Todos los pines estan desactivados //Solo los primeros dos bits del puerto estan activos

PIN

El PIN es un registro de lectura (notar en la imagen del registro donde dice Read/Write, todos son R), este registro nos da un 1 si a un pin del microcontrolador se le est alimentando externamente, y un cero si esta en nivel bajo de voltaje. En este caso el valor del PIN se le puede asignar a una variable la cual guardara el valor del miso, al momento de ejecutar la instruccin. ej. valor=PINB; //El valor de PINB es asignado a la variable "valor"

Programa en C
#include <avr/io.h> #include <util/delay.h> int main (void){ DDRB=0xFF; while(1){ PORTB=0x01; _delay_ms(250); PORTB=0x00; _delay_ms(250); //Librera de entradas y salidas //Librera de retardos //Inicio del programa //Declarar el puerto como salida //Iniciar bucle infinito //Puerto B = 00000001 //Espera 250 milisegundos //Puerto B = 00000000

PORTB|=_BV(PB0); //Bit 0 del puerto B = 1 _delay_ms(250); PORTB&=~(_BV(PB0)); //Bit 0 del puerto B = 0 _delay_ms(250); } }

Detalles del programa


#include <avr/io.h> Incluimos la librera avr/io que contiene la informacin de las entradas y salidas del microcontrolador. #include <util/delay.h> Esta librera es necesaria para poder utilizar los retardos de tiempo int main (void){ El main es la funcin principal, es donde el programa inicia, siempre es necesario declarar la funcin main. DDRB=0xFF; Los puertos del micro contienen tres registros los cuales son, el DDR el PORT y el PIN, en este caso estamos haciendo uso del DDR este es el que determina el uso que se le va a dar al puerto del microcontrolador, si se le asigna un uno es de salida, y un cero es de entrada. En este caso 0xFF es la nomenclatura para indicar un valor hexadecimal, si lo pasamos a binario, este se escribira 0b11111111, en donde se puede ver claramente que los 8 bits del DDR estn siendo activados como salidas. while(1){ El ciclo while, es un ciclo que ejecuta todas las instrucciones que se encuentran dentro de sus corchetes, siempre y cuando lo que este dentro del parntesis se cumpla, en este caso el 1 es lo mismo que TRUE, por lo tanto, siempre se cumple y se ejecutaran cclicamente las instrucciones dentro del while. Esto se hace con la intencin de que el programa nunca se detenga, y siempre repita lo mismo. PORTB=0x01; _delay_ms(250); PORTB=0x00; _delay_ms(250); Una manera de hacer parpadear un LED es activando y desactivando la fuente, en este caso, la fuente de alimentacin del mismo viene del bit 0 o el primero pin del puerto B, como podemos ver en el cdigo, se le asigna un 0x01, se espera 250 milisegundos, se le asigna 0x00 y vuelve a esperar el mismo tiempo. Estas instrucciones manejan a los 8 bits del puerto, la tabla a continuacin describe el cdigo.

0 0

0 0

0 0

0 0

0 0

0 0

0 0

1 0

RETARDO 250 RETARDO 250

PORTB|=_BV(PB0); _delay_ms(250); PORTB&=~(_BV(PB0)); _delay_ms(250); En este caso las instrucciones de activar y desactivar el pin del puerto, son algo ms complejas, ya que se separa y se activa o desactiva el bit 0 del puerto B. Prcticamente el cdigo hace lo mismo, pero la principal diferencia y ventaja, es que al usar este cdigo, se manejan independiente los bits del puerto, esto es, que al aislar los bits, podemos trabajar con ellos de manera que si cambiamos uno, no afecte al otro. Esto se observa en la siguiente tabla. 0 RETARDO 250 1 RETARDO 250

10

Manejo de los Puertos

11

Manejo de los Puertos


Descripcin
En este programa se ver un uso prctico de los registros de los puertos, para poder hacer prender un LED conectado a un pin del microcontrolador, para esto se conectara un Push Button que al presionarlo har que prenda el LED. En este ejemplo se vern estructuras de control como el while y el if.

Diagrama Esquemtico

Materiales
1 LED 1 Resistencia de 220 Ohms 1 Push Button 1 Resistencia de 10Kohms 1 Microcontrolador ATmega8 Programador USBasp V3.0

12

Introduccin While

Como se puede ver en el diagrama de flujo, el ciclo while, ejecuta toda instruccin dentro del mismo, siempre y cuando la condicin se cumpla. La nomenclatura del ciclo while es: while("Condicion"){ instruccion A; instruccion B; } Por lo tanto, siempre y cuando la condicin se cumpla, las instrucciones se ejecutaran, en caso de que la condicin no se cumpla, se brinca las instrucciones y el programa continua.

if else

13

En el if/else, tambin hay una condicin y si esta se cumple ejecuta el proceso o las instrucciones indicadas dentro de los corchetes, en caso de que no se cumpla es opcional escribir el "else" el cual ejecutara un proceso, en caso de que la condicin haya sido falsa. if ("condicion"){ procesoA; } else { ProcesoB; }

Programa en C
#include <avr/io.h> #include <util/delay.h> int main (void){ DDRB=0x00; DDRD=0xFF; while(1){ if (PINB==0x01){ PORTD=0x01; _delay_ms(1000); PORTD=0x00; } } } //Librera necesaria para las entradas y salidas //Librera para usar los retardos de tiempo //Inicio del programa //Iniciar el puerto B como entrada //Declarar el puerto D como salida //Bucle infinito //"si el PINB es igual a 1 //Prender el LED conectado al bit 0 del puerto D //Esperar 1000 mili segundos //Apagar el LED

Detalles del programa


#include <avr/io.h> Incluimos la librera avr/io que contiene la informacion de las entradas y salidas del microcontrolador. #include <util/delay.h>

14

Esta librera es necesaria para poder utilizar los retardos de tiempo int main (void){ El main es la funcin principal, es donde el programa inicia, siempre es necesario declarar la funcin main. DDRB=0x00; DDRD=0xFF; Se declara el puerto B como entrada y el puerto D como salida. while(1){ Ya que el 1 es igual a verdadero, el ciclo while nunca se termina. if (PINB==0x01){ Al usar el if la condicin tiene que ir dentro de parntesis, y en este caso como se puede ver se usa doble smbolo de igual para diferenciarlo de cuando se le asigna un valor a una variable, variable=14; variable==14 //Se le asigna el valor de 14 a la variabe //Se comparan variable y 14, si es verdadero arroja un 1

Ntese que se est usando PINB, el cual pertenece al puerto B, el mismo que se declaro como salida en el DDR. Esta condicin corresponde al Push Button conectado en el pin del puerto B. PORTD=0x01; Se le da al puerto la instruccin de tomar el valor 0x01, previamente el puerto D se declaro como salida. Bit 7 6 5 4 3 2 1 0 PORTD 0 0 0 0 0 0 0 1 _delay_ms(1000); Instruccin que espera 1000 milisegundos, el valor dentro de los parntesis puede ser ajustado como se requiera.

15

PORTD=0x00; Se desactivan todos los pines del puerto D Bit 7 PORTD 0 6 0 5 0 4 0 3 0 2 0 1 0 0 0

16

Rota-bit

17

Rota-bit
Descripcin
Se podr visualizar el bit del puerto asignado, desplazndose por el puerto de lado a lado a travs de una serie de LEDs conectados al microcontrolador. En este ejemplo se ver el uso de la instruccin para realizar un corrimiento ya sea a la derecha o a la izquierda.

Diagrama Esquemtico:

Materiales
6 LEDs 6 Resistencias de 220 Ohms 1 Microcontrolador ATmega8 Programador USB asp V3.0

Introduccin
LED
LED acrnimo de Light Emitting Diode o Diodo Emisor de Luz, es un dispositivo semiconductor que emite luz al circular a travs de l una corriente elctrica.

18

Los LEDs como los diodos normales tienen un nodo y un ctodo, los cuales se pueden identificar de manera fcil, siendo el nodo la pata ms larga como se observa en la figura.

Como se puede apreciar en la figura superior, al LED se le coloca una resistencia en serie para limitar la corriente del mismo, en este caso que se alimentara con 5v se sugieren usar resistencias de 220 Ohms. Para calcular las resistencias exactas y obtener un desempeo optimo se realiza a travs de la siguiente frmula: = En donde: R: Resistencia Vcc: Voltaje de la fuente VLED: Voltaje del LED ILED: Corriente del LED

19

Programa en C:
#include <avr/io.h> #include <util/delay.h> int main(void){ DDRD=0xFF; PORTD=0x01; //Librera de entradas y salidas de los AVR //Librera para usar los retardos "_delay_ms()" //Inicio del programa //Declarar el registro del puerto D como salidas //Asignarle el valor de 0x01 (Hexadecimal) al puerto D

while(1){ //Iniciar un ciclo while infinito while( PORTD < 0x20) //"Mientras que el Puerto D sea menor a 0x20 continua" { PORTD=PORTD<<1; //Recorrer el Puerto D un lugar a la izquierda _delay_ms(200); //Esperar 200 milisegundos } while( PORTD > 0x01 ) //"Mientras que el Puerto D sea mayor a 0x01 continua" { PORTD=PORTD>>1; //Recorrer el Puerto D un lugar a la derecha _delay_ms(200); //Esperar 200 milisegundos } } //Terminar el while infinito } //Fin del main

Detalles del programa:


#include <avr/io.h> Librera de entradas y salidas de los AVR. Esta contiene la informacin de los puertos y los pines de todos los microcontroladores AVR. #include <util/delay.h> Librera necesaria para poder utilizar los retardos "_delay_ms( x )" donde "x" es el numero de milisegundos a esperar. DDRD=0xFF; El DDR solamente configura el registro del puerto que le indica si se va a comportar como entrada o como salida, este se le puede asignar un 1 para indicar una salida o un 0 para entrada, en el caso de asignarle 0xFF (que es lo mismo en binario que 0b11111111 o en decimal 255), quiere decir que el puerto actuara como salida.

20

PORTD=0x01; El PORT maneja el puerto en caso de que lo hayamos asignado como salida, esta instruccin asigna el nivel lgico a la salida fsica del microcontrolador, en este caso el puerto D tiene 8 bits a lo que le estamos asignando un 0x01 el cual en binario es 0b00000001, esto quiere decir que el primer bit del puerto D estar activo (5v) y los dems se encontraran desactivados (0v) . while(1){ La estructura de control while, se puede leer como "Mientras se cumpla esta condicin, ejecutar las instrucciones", pero como en este caso el 1 se toma como una situacin "True" o verdadera, el ciclo siempre se cumple y por lo tanto el programa se repite ejecutando todas las instrucciones dentro del while. while( PORTD < 0x20) { PORTD=PORTD<<1; _delay_ms(200); } Este ciclo while se puede leer como "Mientras que el puerto D sea menor a 0x20 continua ejecutando las siguientes instrucciones", por lo tanto si continua podemos ver la instruccin PORTD=PORTD<<1; esto quiere decir que el registro se desplazara una posicin a la izquierda, por ejemplo: Bit PORTD=0x01 PORTD=PORTD<<1; PORTD=PORTD>>1; 7 6 5 4 3 2 1 0

0
0 0

0
0 0

0
0 0

0
0 0

0
1 0

1
0 0

0
0 1

0
0 0

En la tabla previa podemos ver el valor inicial del PORTD representada en binario, en el cual esta activado el bit 2, si le aplicamos un corrimiento con el operador << o >> este desplazara todo el registro del puerto por lo que veremos el bit recorrerse. Como se puede observar en la tabla, en esta se encuentran las instrucciones de corrimiento a la derecha o a la izquierda. En este caso, por lo tanto, empezara el ciclo con el bit 0 activo (previamente activado con la instruccin PORTD=0x01), el while revisara que el PORTD sea menor a 0x20, ya que lo es, va a entrar y desplazar el bit del 0 a la posicin 1, si observamos va a seguir en el ciclo hasta que llegue a 0x20 el cual en binario es 0b00100000, al llegar a ese valor terminara el ciclo y el programa continuara.

21

while( PORTD > 0x01 ) { PORTD=PORTD>>1; _delay_ms(200); } Este bloque trabaja de igual manera que el anterior, solo con la diferencia de que recorre el puerto a la derecha hasta que este alcanza de nuevo el valor de 0x01. Al salir de este while el programa regresara al primer while(1), ya que este se ciclara por lo comentado previamente, y se repetirn los desplazamientos del bit activo en el puerto, el cual estar siendo desplazado de un extremo a otro.

22

Contador de 0-99 con 2 Displays de 7 Segmentos

23

Contador de 0-99 con 2 displays de 7 Segmentos


Descripcin
El programa incrementara el valor de una variable, la cual se mostrara a travs de un par de displays de 7 segmentos, los cuales se controlaran de manera multiplexada, uno a la vez, a una velocidad que el ojo no alcance a detectar el cambio y perciba ambos displays encendidos a la vez.

Diagrama Esquemtico

Materiales
2 Displays 7 segmentos 7 Resistencias de 220 Ohms 2 Resistencias de 10 kOhms 2 Transistores de pequea seal 1 Microcontrolador ATmega8 Programador USBasp V3.0

24

Introduccin
Display 7 segmentos
El display de 7 segmentos es un dispositivo que nos sirve para mostrar nmeros o caracteres, los cuales se visualizan al activar o desactivar los LEDs que este tiene, esto se hace conectando el comn a la tierra y voltaje en el segmento que deseemos activar (en caso de ser ctodo comn).

Para poder representar los nmeros con el display, es necesario generar la tabla que nos dar el valor que ser necesario para generar el numero deseado.

Num PB6/A PB5/B PB4/C PB3/D PB2/E PB1/F PB0/G HEX


0 1 2 3 4 5 6 7 8 9 1 0 1 1 0 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 0 1 1 0 1 1 1 0 1 0 0 0 1 0 1 0 1 0 0 0 1 1 1 0 1 1 0 0 1 1 1 1 1 0 1 1 7E 30 6D 79 33 5B 5F 70 7F 7B

Por ejemplo, se puede observar que para hacer un cero se busca que enciendan todos los segmentos menos el g (pin 10 del display el cual va conectado al PB0 del Micro), con esa informacin del numero, tendremos el valor que tomara el puerto para mostrar el numero deseado a travs del display. Para controlar dos displays a la vez, se har uso de un par de transistores, en este caso conmutaran entre uno y otro, mientras los displays estn conectados al mismo puerto del micro. Primero se mostrara las decenas mientras se desactiva el display de las unidades y despus de una fraccin de tiempo, se activa el de la unidad y se desactiva el de las decenas y el micro manda el valor de la

25

unidad. Esto se repite determinadas veces a alta velocidad para dar la impresin de que siempre se encuentran prendidos los dos displays. Para activar y desactivar los displays se les pondr un transistor a modo de swhitch el cual se conectara del colector al comn del display, y este controlara el display activndolo o desactivndolo desde la base.

Para este caso el transistor se est usando como un swhitch, eso es que se est trabajando en las regiones de corte y saturacin, lo que nos dice que al pasar una corriente en la base, el transistor se comporta como un interruptor que se abre o se cierra.

Programa en C
#include <avr/io.h> #include <util/delay.h> int contador=0; int unidades, decenas,i; int numeros[10]={0x7E, 0x30, 0x6D, 0x79, 0x33, 0x5B, 0x5F, 0x70, 0x7F, 0x7B}; int mostrar(int numero){ unidades=numero%10; decenas =numero/10; for(i=0;i<20;i++){ PORTD=0x02; PORTB=numeros[unidades]; _delay_ms(5); PORTD=0x01; PORTB=numeros[decenas]; _delay_ms(5); } return 0; } //Se activa el transistor de las unidades //Se asigna al PORTB la variable numero en la posicin unidades

//Se declara un vector de longitud 10 que contenga los //valores obtenidos de la tabla, acomodados en orden //Segn su posicin del 0 al 9

//Creamos una funcin de tipo entero //Al dividir un valor entre 10 el residuo nos da las unidades //Se obtiene la decena dividiendo el numero entre 10

//Se activa el transistor de las decenas //Se asigna al PORTB la variable numero en la posicin decenas

26

int main(void){ DDRB=0xFF; DDRD=0x03; while(1){

//Inicio del programa

mostrar(contador); contador++; if (contador > 99) contador=0; } }

//Llamar a la funcin mostrar, mandando la variable contador //Incrementar el valor de la variable contador //Si llega a 99, que tome el valor de 0

Detalles del programa


int numeros[10]={0x7E, 0x30, 0x6D, 0x79, 0x33, 0x5B, 0x5F, 0x70, 0x7F, 0x7B}; Aqu se est declarando un vector de tipo entero, el cual le indicamos la longitud del mismo, el cual tiene 10 datos, se acomodaron conforme a que la posicin del vector corresponde al nmero que representa ese valor en el display, en el caso del 3 el cual es el 0x79 (previamente obtenido en la tabla), podemos ver que se encuentra en la tercera posicin. int mostrar(int numero){ Una funcin se declara como "tipo de dato" "nombre de la funcin" ( "tipo de dato" "nombre de entrada"), en este caso la funcin obtendr la unidad y la decena de cualquier numero entre 0-99 y mandara el dato para mostrarlo en el display. unidades=numero%10; decenas =numero/10; Operacin para obtener separar un numero entre su unidad y decena. Por ejemplo el 45, si lo dividimos entre 10, esto es 45/10 = 4 (recuerde que como son variables de tipo entero es solo 4 y no 4.5), y con el operador mod (de modulo) "%" el resultado es 45%10 = 5. Gracias a esto tenemos en una variable el numero 4 y en otra el numero 5.

27

PORTB=numeros[unidades]; Al puerto B se le asigna el valor que tenga el vector nmeros en la posicin unidades, si tomamos el ejemplo anterior, unidades vala 5, si vamos al vector nmeros y vemos la quinta posicin, veremos un 0x5B la cual corresponde al nmero 5 en la tabla, esto es, que al mostrarlo por el puerto B aparecer el 5 en el display. mostrar(contador); Aqu se manda a llamar a la funcin mostrar, a la cual se le manda el valor de la variable contador, el cual puede ser un numero del 0-99, al llamar la funcin, esta ejecutara todas las instrucciones que se encuentren dentro de la misma, al terminar regresara y continuara con la siguiente instruccin.

28

Matriz de LEDs

29

Matriz de LEDs
Descripcin
Se har un contador del 0-9, el cual visualizaremos a travs de una matriz de LEDs la cual estar controlada por el microcontrolador, la matriz a utilizar es una matriz de LEDs de 5x7 la cual contiene un total de 35 LEDs.

Diagrama Esquemtico

Materiales
Matriz de LEDs 5x7 7 Resistencias de 220 Ohms 1 Microcontrolador ATmega8 Programador USBasp V3.0

30

Introduccin
Matriz de LEDs
La matriz de LEDs no es ms que un arreglo de LEDs agrupados dentro de un encapsulado, los cuales se encuentran agrupados en forma de matriz. Este acomodo nos ayuda para poder generar cualquier cosa que nosotros queramos siempre y cuando se pueda representar dentro de la matriz.

La matriz de LEDs que se usara en este ejemplo es una como la de la foto superior, esta es de 5 columnas por 7 filas, las columnas son representadas por una C y las filas por una R, en la imagen inferior podemos ver como se encuentran distribuidos los pines de la matriz a usar.

Para poder formar algo en la matriz, es necesario realizar un barrido en las columnas para controlarlas de manera independiente, cada columna tendr su cdigo, por lo que debemos formar la figura, numero o letra que necesitemos separando la misma en 5 columnas. A continuacin veremos cmo se forma el numero 3 el cual prestando atencin al valor de las R's las cuales forman el cdigo deseado mientras que las C's generan un barrido de las columnas. Es importante destacar que en las R's el LED prende con un 0 lgico, lo cual est dado ya que la columna correspondiente

31

est habilitada con un 1 lgico (Vcc), el led en las R's prendera con la diferencia de voltaje, por lo tanto en las R's se usa el 0 como prendido. Ejemplo de la formacin de un numero 3

C bin 00001 00010 00100 01000 10000

C hex 0x01 0x02 0x04 0x08 0x10

R bin 1011101 0111110 0110110 0000000 1001001

R hex 0x5D 0x3E 0x36 0x00 0x49

32

Como se puede ver en la imagen anterior, el numero 3 se formo en base a la combinacin de controlar las C's y las R's, trabajo que le asignaremos al microcontrolador, este proceso se repetir varias veces a una velocidad lo suficientemente alta, como para no alcanzar a percibir los cambios, y tener la idea de que todos los LEDs deseados se encuentran prendidos a la vez.

Despus de hacer un proceso similar, se obtuvo una tabla con los valores de cada numero deseados, en este caso los nmeros se crearon de determinada forma, la cual puede cambiar dependiendo las necesidades de cada persona, ya sea que se necesite mostrar letras o caracteres distintos.

Numero 0 1 2 3 4 5 6 7 8 9

C1 0x41 0x7E 0x4E 0x5D 0x07 0x8C 0x41 0x3F 0x49 0x4D

C2 0x3E 0x5E 0x3C 0x3E 0x77 0x36 0x36 0x37 0x36 0x36

C3 0x3E 0x00 0x38 0x36 0x77 0x36 0x36 0x37 0x36 0x36

C4 0x00 0x00 0x02 0x00 0x00 0x30 0x30 0x00 0x00 0x00

C5 0x41 0x7E 0x46 0x49 0x00 0x39 0x39 0x0F 0x49 0x41

33

Programa en C
#include <avr/io.h> #include <util/delay.h> int contador=0; int i,j; int numero[10][5]={

{0x41,0x3E,0x3E,0x00,0x41}, {0x7E,0x5E,0x00,0x00,0x7E}, {0x4E,0x3C,0x38,0x02,0x46}, {0x5D,0x3E,0x36,0x00,0x49}, {0x07,0x77,0x77,0x00,0x00}, {0x8C,0x36,0x36,0x30,0x39}, {0x41,0x36,0x36,0x30,0x39}, {0x3F,0x37,0x37,0x00,0x0F}, {0x49,0x36,0x36,0x00,0x49}, {0x4D,0x36,0x36,0x00,0x41}};

//Se declara la matriz de los numeros

int main (void){ DDRD=0xFF; DDRC=0xFF; PORTC=0x10; while(1){ for(j=0;j<25;j++){ for(i=0;i<5;i++){ PORTD=numero[contador][i]; _delay_ms(1); PORTC=PORTC>>1; } PORTC=0x10; } contador++; if (contador==10) contador=0; } } //Ciclo de numero de barridos //Ciclo de barrido de columnas //Se le asigna al PORTD el cdigo respecto a la columna //Siguiente columna //Se inicializa a las primera columna //Incrementar en 1 el contador //Si el contador llega a 10 //que vuelva a ser 0

//Inicializar el puerto C para el barrido de las columnas

34

Detalles del programa


#include <avr/io.h> #include <util/delay.h> Incluir las libreras necesarias para el proyecto. int numero[10][5]={ {0x41,0x3E,0x3E,0x00,0x41}, {0x7E,0x5E,0x00,0x00,0x7E}, {0x4E,0x3C,0x38,0x02,0x46}, {0x5D,0x3E,0x36,0x00,0x49}, {0x07,0x77,0x77,0x00,0x00}, {0x8C,0x36,0x36,0x30,0x39}, {0x41,0x36,0x36,0x30,0x39}, {0x3F,0x37,0x37,0x00,0x0F}, {0x49,0x36,0x36,0x00,0x49}, {0x4D,0x36,0x36,0x00,0x41}};

Como se puede ver se inicializa una variable de tipo entero, pero en este caso es una matriz, a la cual, al momento de declararla le aadimos la longitud de las filas y las columnas dentro de los corchetes, como se puede ver en el cdigo. La matriz declarada e inicializada con los valores, es la misma que se encuentra representada en la tabla en la introduccin del proyecto, como se puede ver, la relacin de la posicin de la fila es la misma que el numero que representa, por ejemplo el numero 3 se encuentra en la 3ra fila, esto nos ayudara al momento de realizar el cdigo. DDRD=0xFF; DDRC=0xFF; PORTC=0x10; Se inicializan los puertos como salida, y el puerto C toma el valor de 0x10 el cual activa el bit 4 del puerto con el que empezara la primera columna, posteriormente se desplazara el bit, para hacer el barrido. for(j=0;j<25;j++){ El primer ciclo for del cdigo representa, las veces que se va ha hacer el barrido completo, por lo tanto ser el total de veces que se muestra un numero completo y esto es el tiempo que dura visualizndose el numero en la matriz. El nmero 25 en este ciclo for puede cambiarse para obtener un conteo ms rpido o ms lento segn se requiera.

35

for(i=0;i<5;i++){ El segundo for, es para hacer el barrido, en este caso el 5 es constante y no debe cambiarse ya que este representa las columnas de la matriz, como se puede ver, este for trabaja en conjunto con el otro, cuando este termina en el otro for, se incrementa la variable "j" en uno ms, por lo tanto este for se ejecutara completo el nmero de veces que el for exterior marque. PORTD=numero[contador][i]; _delay_ms(1); PORTC=PORTC>>1; Aqu se puede ver como se asigna el numero, en este caso la variable numero esta con dos corchetes los cuales corresponden a la filas y a las columnas, se aprecia que la "i" del ciclo est cambiando dentro del for interior, que representa las columnas mientras que la variable contador permanece fija durante los dos ciclos for, esta representa la fila, y como se comento anteriormente, el numero corresponde a la posicin del mismo en la fila. El PORTC est siendo desplazado para recorrer el bit que controla a las columnas de la matriz, terminando el ciclo for, se inicializa para comenzar de nuevo. contador++; El contador incrementa, para asignar otro nmero a la matriz. if (contador==10) contador=0; Se limita el incremento del contador, con un if, en este caso si llega a 10, un numero del cual no hay fila en la matriz, se inicializa de nuevo asignndole un cero.

36

Interrupcin Externa

37

Interrupcin Externa
Descripcin
El push button estar conectado al microcontrolador el cual se encuentra configurado para las interrupciones externas, esto es, que el programa deja de hacer lo que est haciendo para atender la interrupcin y ejecutar las instrucciones dentro esta funcin, que para este caso es prender el LED que se encuentra conectado al microcontrolador.

Diagrama Esquemtico

Materiales
1 Push Button 1 Resistencia de 220 Ohms 1 Resistencia de 1 kOhms 1 LED 1 Microcontrolador ATmega8 Programador USBasp V3.0

38

Introduccin
Interrupcin externa
Las interrupciones externas en el ATmega8 son activadas con los pines INT0 y INT1, en caso de que se habiliten las interrupciones los pines INT siempre activaran alguna interrupcin sin importar como se haya configurado el puerto en el que estos pines se encuentren. Las interrupciones externan se habilitan cuando la entrada del pin, cambia de estado, se puede configurar si se requiere que se active cuando cambia de un estado bajo a uno alto o viceversa. Resistencia de Pull down Cuando se conecta un pin del microcontrolador a un switch este al presionarlo nos presenta un nivel alto en el pin, pero cuando este est abierto con la resistencia de pull down aseguramos un cero o nivel bajo en el microcontrolador.

Resistencia de Pull-down

39

Programa en C
#include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> int main (void) { DDRB=0xFF; cli(); MCUCR=0x03; GIFR =0x40; GICR=0x40; sei(); while(1){ } } ISR(INT0_vect) { PORTB=0x01; _delay_ms(2000); PORTB=0x00; } //Vector de interrupcin externa del INT0 //Activar las interrupciones globales //Desactiva las interrupciones globales //Libreria necesaria para manejar las interrupciones

Detalles del programa


#include <avr/interrupt.h> Cada que se use alguna interrupcin es necesario llamar a la librera avr/interrupt.h que es la que contiene todos los vectores de interrupcin de los AVR's. cli(); Esta instruccin deshabilita las interrupciones. sei(); Habilita las interrupciones.

40

MCUCR=0x03;

Al asignrsele un 0x03 le estamos indicando que active los bits 0 y 1 los cuales para el registro MCUCR nos indican de que manera se active la interrupcin, como se puede ver en la tabla, hay cuatro opciones que son: El nivel bajo de INT1, Cualquier cambio lgico, El flanco de bajada y El flanco de subida. Con los bits 0 y 1 en unos, tenemos habilitada la opcin del flanco de subida.

GIFR =0x40;

0x40 = 0b01000000, esto es, que estamos seleccionando el bit 6 del registro GIFR el cual nos indica que al activarlo limpiamos la bandera INTF0. GICR=0x40;

Al igual que en el registro pasado se est activando el bit 6 del GICR el cual nos indica que se usara el pin INT0 para la interrupcin externa.

41

Uso del ADC

42

Uso del ADC


Descripcin
Con este programa podremos visualizar a travs de los LEDs, el valor en binario tomado del ADC conectado a un potencimetro. El ADC se trabajara a manera de conversin simple y se tomaran solo 8 de los 10 bits, de los cuales se ajustaran para que la salida vaya de 0 a 63, que ser representada por los LEDs conectados al microcontrolador.

Diagrama Esquemtico

Materiales
1 Potencimetro 6 LEDs 7 Resistencias de 220 Ohms 1 Microcontrolador ATmega8 Programador USBasp V3.0

Introduccin
El ADC
El ADC convierte seales continuas a nmeros discretos. El ADC es un dispositivo electrnico que pasa un nivel de voltaje de entrada a un valor digital proporcional a la magnitud de la entrada, la salida digital puede estar descrita por diferentes codificaciones. En este caso, el ADC a utilizar es el del microcontrolador ATega8 el cual es un ADC de 10 bits, de los cuales solo usaremos 8. Las caractersticas principales del ADC del ATmega8 son: -Resolucin de 10 bits - 2 bits de precisin -13 a 260 us de tiempo de conversin

43

-6 Canales de entrada multiplexados -Rango de voltaje de entrada de 0-Vcc -Selector de voltaje de referencia de 2.56v -Tipos de conversin continuo o simple -Interrupcin de conversin -Ahorro de energa

Potencimetro
El potencimetro es un tipo de resistencia variable el cual varia conforme se gira la perilla que tiene, en este caso el potencimetro es usado para generar un divisor de voltaje el cual al variar la resistencia, la salida de voltaje tambin cambiara proporcionalmente. El potencimetro tiene 3 patas las cuales son:

Programa en C
#include<avr/io.h> #include<util/delay.h> int main (void) { int ADC_val; DDRD = 0xFF; ADCSRA = 0xC0; ADMUX = 0x22; while(1) { ADCSRA|=_BV(ADSC); ADC_val=(ADCH*63)/255; PORTD = ADC_val; } } Detalles del programa //Activar el bit ADSC del registro ADCSRA inicio de conversion //Ajustar la recta para que vaya de 0 a 63 //Configurar el registro ADCSRA //Configurar el registro ADMUX

44

Detalles del programa


ADCSRA = 0xC0;

Para el registro ADCSRA se asigno 0xC0 o 0b11000000, hexadecimal o binario respectivamente. El bit 7 ADEN habilita el uso del ADC, y el bit 6 ADSC al escribirle un uno inicia la conversin. ADMUX = 0x22;

Se activan los bits 5 y 2 por lo que el registro nos queda como 0b00100010 (lo que es igual en hexadecimal a 0x22), al activar el bit 1 le indicamos al ADC que tome la entrada del pin del ADC2

con el bit 5 (ADLAR) del registro ADMUX configuramos la manera en la que nos deposita el valor en los dos registros, para este caso se configuro de la siguiente manera, en la que como se puede ver se ignoraron los dos bits ms significativos.

ADCSRA|=_BV(ADSC); Al estar trabajando el ADC en este modo es necesario indicarle cada cuando tiene que realizar la conversin, con esta instruccin solo entra al bit ADSC del registro y lo habilita, no se modifica cualquier otro valor del registro ADCSRA.

45

ADC_val=(ADCH*63)/255; Ya que el valor del ADCH es de 8 bits (como se ve en la imagen al ajustar el ADLAR), se tiene que ajustar la salida a que sea de 6 bits, ya que se estn usando solo 6 LEDs, esto se hace ajustando la recta, multiplicando por el mximo de nuestra salida ideal y dividindolo por el mximo de la salida obtenida.

46

Uso del PWM

47

Uso del PWM


Descripcin
En este ejemplo se har uso del PWM, o modulacin por ancho de pulso, la cual consiste en modificar el ancho del pulso dejando la frecuencia intacta, el programa aceptara dos entradas, que son los Push Buttons conectados al microcontrolador, y tendr una salida, que es el LED, el cual indicara el nivel de modulacin, a ms ancho el pulso mas ciclo de trabajo y el LED se iluminara con mayor intensidad.

Diagrama Esquemtico

Materiales
1 LED 1 Resistencia de 220 Ohms 2 Push Button 2 Resistencias de 10Kohms 1 Microcontrolador ATmega8 Programador USBasp V3.0

48

Introduccin PWM
Modulacin por ancho de pulso o PWM (Pulse-Width Modulation), de una seal, es cuando se modifica el ciclo de trabajo o el ancho del pulso de una seal peridica, en este caso representado por una seal cuadrada, uno de los usos del PWM entre muchos otros, es controlar la cantidad de energa, en este caso el voltaje promedio es mayor conforme aumenta el ciclo de trabajo.

En la imagen anterior se puede observar, que el periodo de la seal permanece fijo, por lo tanto, la frecuencia tambin, solamente cambia el ciclo de trabajo, en la primera se observa que el ciclo de trabajo es de aproximadamente 50% lo cual nos indica que es el porcentaje de voltaje promedio entregado a la carga. El PWM se puede utilizar en varias cosas, como el control de la velocidad de motores de DC, la posicin de un servomotor, fuentes conmutadas, entre otras cosas ms.

49

Programa en C
#include <avr/io.h> #include <util/delay.h> int main(void){

DDRB=0x02; DDRD=0x00; TCCR1A=0b10000011; TCCR1B=0b00000001; TCNT1 =0b00000000; OCR1A=0; for(;;){ if ( PIND == 0x01 ) { OCR1A++; _delay_us(500); } if ( PIND == 0x02 ) { OCR1A--; _delay_us(500); } } } //Configurar el PWM en modo de fase //Sin preescalador //No se modifica //Inicializar el TOP en cero //Ciclo infinito //Si el boton 1 esta activado //Incrementar la modulacion

//Si el boton 2 esta activado //Decrementar la modulacion

Detalles del programa


#include <avr/io.h> Incluimos la librera avr/io que contiene la informacion de las entradas y salidas del microcontrolador.

50

#include <util/delay.h> Esta librera es necesaria para poder utilizar los retardos de tiempo int main (void){ El main es la funcin principal, es donde el programa inicia, siempre es necesario declarar la funcin main. DDRB=0x02; DDRD=0x00; Se declaran el bit 1 del puerto B como salida y el puerto D como entrada. TCCR1A=0b10000011;

Los primeros dos bits del TCCR1A los cuales se observa que tanto en el registro como en la tabla sonWGM11 y WGM10, y como en este caso ambos estn activados, podemos ver que el modo de operacin es el de PWM en fase de 10 bits.

Acerca del bit 7 este depende de qu tipo de PWM se est trabajando, ya que en este caso se est trabajando el de correccin de fase, vemos la tabla que le corresponde y vemos que el tenemos el COM1A1 habilitado el cual nos indica que limpia el OC1A en la comparacin al incrementar y ajusta el OC1A en la comparacin al decremento.

51

A continuacin se puede ver en la grafica tomada de la hoja de datos el funcionamiento del PWM en modo de fase:

TCCR1B=0b00000001;

52

Se ajusta el PWM para que no haya preescalador desde el Clk, se puede ver en la tabla de los ltimos tres bits del registro.

OCR1A=0; Se inicializa el valor al que llega el PWM, como se puede ver en la imagen anterior los picos del TCNTn dependen del OCRnx, en este caso es el OCR1A el cual se inicializa en cero. for(;;){ En este caso, es otro manera de generar un loop infinito, esta instruccin es equivalente al while(1){ if ( PIND == 0x01 ) { OCR1A++; _delay_us(500); } if ( PIND == 0x02 ) { OCR1A--; _delay_us(500); } En general lo que se hace en esta seccin de cdigo, es que primero verifica si el Push Button1 est siendo presionado al comparar el puerto con un 0x01, en caso de que si este, se incrementa el valor del OCR1A el cual define el ancho del pulso en la modulacin, por consiguiente, como se vio previamente, a mayor ancho del pulso se entrega un mayor voltaje promedio. El segundo if funciona de la misma manera, solo que para activarlo hay que presionar el otro botn, y dentro de este el OCR1A se decrementara.

53

El retardo se usa ya que como el microcontrolador corre a una velocidad de 1Mhz, para limitar la velocidad del incremento, si no hubiera algn retardo, no podramos observar que es lo que esta pasado debido a la velocidad del incremento, ya que con solo presionar algn botn un instante de tiempo, el cdigo se repetira cientos de veces y el OCR1A se incrementara o decrementaria muy rpido.

54

Servomotor

55

Servomotor
Descripcin
Existen varias maneras de generar un PWM capaz de controlar un servomotor, pero esta vez, se har a travs de un PWM por software, esto es, se generara la rutina para activar y desactivar un pin del puerto es cual controlara el servomotor, que a su vez, estar siendo controlado con un potencimetro conectado al ADC.

Diagrama Esquemtico

Materiales
1 Servomotor 1 Resistencia de 220 Ohms 1 Potencimetro de 10Kohms 1 Microcontrolador ATmega8 Programador USBasp V3.0

56

Introduccin Servomotor
Un servomotor es un dispositivo actuador que tiene la capacidad de ubicarse en cualquier posicin dentro de su rango de operacin, y de mantenerse estable en dicha posicin. Est formado por un motor de corriente continua, una caja reductora y un circuito de control, y su margen de funcionamiento generalmente es de menos de una vuelta completa. El servomotor usado para el ejemplo es un Hitec HS475HB.

Los servomotores trabajan con PWM, estos tienen tres cables, uno para alimentar el motor, otro de tierra y el tercero es el de la seal, el cual se conectara al microcontrolador al pin de salida del PWM.

Como se puede ver en la imagen, a mayor ancho de pulso, es mayor el ngulo de trabajo del servomotor. Este al posicionarse en determinado ngulo, permanecer en el mismo con torque siempre y cuando se siga generando la seal.

57

Programa en C
#include<avr/io.h> #include<util/delay.h> int servo(int SH){ int i,k; //Funcin para generar la seal PWM por software

PORTB|=_BV(PB0); for (i = 0; i <= SH; i++) {_delay_us(1);} PORTB&=~(_BV(PB0)); for (k = 0; k <= (10000-SH); k++) {_delay_us(1);} } return 0; } int main (void) { int ADC_val; DDRB = 0xFF; ADCSRA = 0xC0; ADMUX = 0x22; while(1) { ADCSRA|=_BV(ADSC); ADC_val=((ADCH*200)/254)+50; servo(ADC_val); } }

//Se activa el bit 0 del PORTB //Ciclo for de 0 hasta el valor introducido por la entrada //de la funcin, con la variable SH, SH veces //Desactiva el bit 0 del PORTB //Ciclo de 0 hasta 10000-SH //Se repetir 10000-SH veces //Como la funcin no es void se regresa un 0

//Inicio del programa

//Se configura el ADC

//Ciclo infinito //Iniciar conversin //Tomar valor y ajustarlo para el servo //Llamar la funcin servo, con la entrada ADC_va, la cual //dentro de la funcin, ser SH

58

Detalles del programa


int servo(int SH){ Esta funcin es la que nos servir para generar los pulsos necesarios para hacer funcionar el servomotor, ntese que en este caso, a diferencia del ejemplo anterior, se est generando PWM a travs de la programacin y no del modulo que el microcontrolador ya trae integrado. Esto con la finalidad de no depender de el miso. PORTB|=_BV(PB0); for (i = 0; i <= SH; i++) {_delay_us(1);} Despus de activar el primer bit del puerto B, va a mandar un nivel de voltaje alto a travs del pin correspondiente. El ciclo for como se puede ver, va desde 0 hasta que sea mayor o igual a SH, y dentro del ciclo se est repitiendo la instruccin de retardo de 1 micro segundo, por lo tanto, se puede interpretar como que se activa el pin de puerto con un tiempo de SH micro segundos.

PORTB&=~(_BV(PB0)); for (k = 0; k <= (10000-SH); k++) {_delay_us(1);}

En este caso, ocurre algo similar que en el paso anterior, con la principal diferencia de que la seal va de un nivel alto a un nivel bajo, y espera una cantidad de 10000-SH micro segundos. La resta es necesaria, ya que no se puede suponer un valor fijo para el tiempo en bajo, ya que si el tiempo fuera fijo, en caso de que el tiempo en alto variase, tambin variara la frecuencia, por lo tanto, se ajusta restando el valor de SH para que la proporcin que SH varia, tambin lo haga el tiempo en bajo, y as se logra que la frecuencia sea fija.

59

ADCSRA = 0xC0; ADMUX = 0x22; El ADC se configura de la misma manera que se configuro para el ejemplo del ADC ADCSRA|=_BV(ADSC); Se le indica al ADC que inicie la conversin. ADC_val=((ADCH*200)/254)+50; Al igual que en el ejemplo del ADC se ajustan los valores, pero en este caso se le aade un offset (+50) ya que el servo no inicia con una modulacin del 0%.

servo(ADC_val); Se manda a llamar la funcin servo, con el valor del ADC_val como entrada, el cual ser el tiempo en alto de la seal, proporcional al ciclo de trabajo.

60

Como se puede ver en las imgenes, aunque el SH se modifique, el tiempo en bajo siempre se ajusta para no modificar la frecuencia, ya que el periodo de la seal es constante.

61

Pantalla LCD

62

Pantalla LCD
Descripcin
En este ejemplo se trabajara con una pantalla LCD de 16x2, se vern un par de funciones de la misma que se realizaran como escribir texto o limpiar la pantalla. En este caso para evitar un grado de complejidad mayor se trabajara la pantalla LCD con una comunicacin de 8 bits, la cual es ms sencilla que la de 4 bits. Tambin se har uso de un potencimetro como divisor de voltaje para regular el PIN Vee el cual controla el contraste de la pantalla.

Diagrama Esquemtico

Materiales
1 Pantalla LCD 16x2 JHD-162A 1 Resistencia de 220 Ohms 1 Potenciometro de 10 kOhms 1 Microcontrolador ATmega8 Programador USBasp V3.0

63

Introduccin
Pantalla LCD
Una pantalla de cristal liquido o LCD es una pantalla delgada y plana formada por un determinado nmero de pixeles monocromos (para este caso), colocados delante de una fuente luminosa. Una de las principales caractersticas de las pantallas LCD es su bajo consumo de energa elctrica.

Pantalla JHD-162A
Configuracin de los pines, tamao de la pantalla y de los caracteres.

Controlador de la pantalla JHD-162A, HD44780


El controlador HD44780 es el circuito que se encuentra en la pantalla JHD-162A y es el que controla el manejo del LCD, en este es recomendable revisar la hoja de datos del mismo ya que explica los modos de manejo del LCD y las instrucciones de este. En la siguiente imagen podemos ver una de las pginas de la hoja de datos del controlador en donde se pueden ver varias de las instrucciones que el LCD maneja.

64

Programa en C
#include <avr/io.h> #include <util/delay.h>

#define Enable_On #define Enable_Off #define RS_On #define RS_Off #define RW_On #define RW_Off #define Data #define DelayL int i=0; void PORT_init (void){ DDRC=0x07; DDRD=0xFF; PORTC=0x00; PORTD=0x00; } void LCD_init (void){ Data=0x0F; Enable_On; DelayL; Enable_Off; Data=0x00; RS_On; DelayL; } void WriteLCD(char text[15]){ RS_On; for (i=0;i<16; i++){ Data=text[i]; Enable_On; DelayL; Enable_Off; DelayL; } i=0; Data=0x00; RS_Off; }

PORTC|=_BV(PC2) PORTC&=~_BV(PC2) PORTC|=_BV(PC0) PORTC&=~_BV(PC0) PORTC|=_BV(PC1) PORTC&=~_BV(PC1) PORTD _delay_ms(5);

//Definiciones

//Funcin para inicializar puertos

//Funcin para inicializar el LCD

//Funcin para escribir en el LCD

65

void ClearLCD(void){ Data=0x01; Enable_On; DelayL; Enable_Off; } int main (void){ PORT_init(); LCD_init();

//Funcin para limpiar la pantalla del LCD

//Inicio del programa

while(1){ WriteLCD("Hola mundo"); _delay_ms(1000); ClearLCD(); _delay_ms(500); } }

//Escribir en el LCD

//Limpiar la pantalla del LCD

Detalles del programa


#define Enable_On #define Enable_Off #define RS_On #define RS_Off #define RW_On #define RW_Off #define Data #define DelayL PORTC|=_BV(PC2) PORTC&=~_BV(PC2) PORTC|=_BV(PC0) PORTC&=~_BV(PC0) PORTC|=_BV(PC1) PORTC&=~_BV(PC1) PORTD _delay_ms(5);

66

La directiva #define define una macro que proporciona un mecanismo de reemplazo de cdigo por una secuencia de caracteres, en este caso la sintaxis del #define es: #define macro_identificador <secuencia-de-tokens> tomando como referencia uno de las definiciones previamente usadas podemos ver que lo que se est haciendo con: #define Enable_On PORTC|=_BV(PC2)

es asignndole a Enable_On la seccin de codigo PORTC|=_BV(PC2) la cual activa el bit 2 del registro PORTC. void PORT_init (void){ DDRC=0x07; DDRD=0xFF; PORTC=0x00; PORTD=0x00; } Esta es una funcin en la que dentro de ella se configuran los registros de los puertos void LCD_init (void){ Data=0x0F; Enable_On; DelayL; Enable_Off; Data=0x00; RS_On; DelayL; } Para inicializar la pantalla LCD tenemos que seguir una serie de instrucciones las cuales como se puede apreciar en el cdigo son las siguientes que se encuentran representadas en la tabla. Instruc \ Pin 1 2 3 4 E 0 1 0 0 R/W 0 0 0 0 RS 0 0 0 1 Data DB0:7 0x0F 0 0 0

Despus de inicializar la pantalla un puntero debe aparecer en la misma, y nos indica que esta lista para recibir los caracteres.

67

void WriteLCD(char text[15]){ RS_On; for (i=0;i<16; i++){ Data=text[i]; Enable_On; DelayL; Enable_Off; DelayL; } i=0; Data=0x00; RS_Off; } Para escribir en el LCD es necesario seguir una serie de instrucciones, las cuales nos llevaran a escribir el texto, que queramos ver en el LCD, carcter por carcter, por lo tanto tenemos que separar nuestro texto en caracteres, esto lo logramos haciendo la funcin con una entrada de tipo char (carcter), pero en este caso va a ser un vector, esto es una serie de caracteres o de chars, por lo tanto cuando llamemos la funcin y a la entrada de la misma pongamos algn texto este se guardara en un vector de caracteres, por ejemplo en texto "Hola Mundo":

Posicion 0 Caracter H

1 o

2 l

3 a

5 M

6 u

7 n

8 d

9 o

10

11

12

13

14

15

Para habilitar la entrada de texto, se activa el pin de RS, a continuacin el cdigo inicia un ciclo for de 0 a 15, para lograr desplazarnos por las 16 posiciones que tiene la pantalla. Al iniciar el ciclo se le asigna a la variable Data el carcter que est en el vector text en la posicin j, por ejemplo en el primer caso inicia con j=0 en caso de haber escrito el texto "Hola Mundo", el vector quedara como en la tabla superior y cmo podemos ver la posicin 0 tendra el carcter "H", despus se le da un pulso al Enable un retardo y el ciclo for continua. Al terminar se limpian las variables y el RS se desactiva

Instruc \ Pin 1 2 3 4

E 0 0 1 0

R/W 0 0 0 0

RS 1 0 0 0

Data DB0:7 0 Caracter 0 0

68

void ClearLCD(void){ Data=0x01; Enable_On; DelayL; Enable_Off; } Para limpiar la pantalla, se escribi la funcin ClearLCD la cual inicializa el puntero de la pantalla y borra todos los caracteres escritos en ella. Para limpiar la pantalla se realizaron las siguientes instrucciones. Instruc \ Pin 1 2 3 int main (void){ PORT_init(); LCD_init(); E 0 1 0 R/W 0 0 0 RS 0 0 0 Data DB0:7 0x01 0 0

La funcin main o principal, a la cual al correr el micro es la primera en ejecutar, en este caso llama a las funciones inicializadoras de los puertos y del LCD.

while(1){ WriteLCD("Hola mundo"); _delay_ms(1000); ClearLCD(); _delay_ms(500); }

//Escribir en el LCD

//Limpiar la pantalla del LCD

Dentro del ciclo while infinito, se llama a la funcin WriteLCD la cual escribe el texto "Hola Mundo" en el LCD de la manera que se explico previamente, a continuacin damos un retardo de 1000 ms y posteriormente se limpia la pantalla llamando a la funcin ClearLCD a lo que esperamos 500 ms, despus de esto el ciclo inicia de nuevo y el texto vuelve a aparecer.

69

Sensor ultrasnico SRF08

70

Sensor ultrasnico SRF08


Descripcin
Para este ejemplo se har uso de un sensor ultrasnico, este es un modulo independiente, el cual es controlado va I2C (Inter-Integrated Circuit) , este protocolo es tambin conocido como TWI (TwoWire-Interface). El sensor nos entrega la distancia directamente en centmetros, la que estaremos visualizando a travs de una serie de LEDs conectados al microcontrolador.

Diagrama Esquemtico

Materiales
Sensor ultrasnico SRF08 6 Resistencias de 220 Ohms 1 Microcontrolador ATmega8 Programador USBasp V3.0

71

Introduccin
Sensor SRF08
El SRF08 Es un medidor ultrasnico de distancias comercial, el cual hace uso de su transmisor y receptor para ofrecer una medida de distancia bastante precisa, el sensor tambin cuenta con un LDR la cual nos indica la intensidad luminosa del lugar donde lo tengamos. Algunas de las caractersticas del sensor son: -5v de alimentacin -15mA de consumo de corriente -Frecuencia 40KHz -Rango de medicin: de 3cm a 6mts -Conexin I2C -Sensor de iluminacin LDR -Unidades soportadas: uS, mm, pulgadas. -Tamao: 43x20x17 mm

En la imagen superior podemos ver las conexiones del sensor, en este caso como se puede apreciar el cuarto pin no se conecta, y los pines SDA y SCL son los del protocol I2C los cuales irn conectados al microcontrolador como se ve en el diagrama esquemtico.

I2C o TWI
I2C es un bus de comunicaciones en serie. Su nombre viene de Inter-Integrated Circuit (Circuitos Inter-Integrados). La versin 1.0 data del ao 1992 y la versin 2.1 del ao 2000, su diseador es Philips. La velocidad es de 100Kbits por segundo en el modo estndar, aunque tambin permite velocidades de 3.4 Mbit/s. Es un bus muy usado en la industria, principalmente para comunicar microcontroladores y sus perifricos en sistemas integrados (Embedded Systems) y generalizando ms para comunicar circuitos integrados entre si que normalmente residen en un mismo circuito impreso.

72

La principal caracterstica de IC es que utiliza dos lneas para transmitir la informacin: una para los datos y por otra la seal de reloj. Tambin es necesaria una tercera lnea, pero esta slo es la referencia GND. Las lneas se llaman: SDA: datos SCL: reloj GND: En la imagen se puede ver un ejemplo de conexin de un microcontrolador, en modo maestro y varios otros dispositivos conectados como esclavos, como ADCs DACs otros microcontroladores, sensores etc.

Algunas de las instrucciones a utilizar del sensor SRF08

Hexadecimal 0xE0 0x00 0x51 0x03

Decimal 224 0 81 3

Instruccin Direccin del sensor Inicializar el calculo Modo clculo distancia - Resultado en centmetros Fija la ganancia analgica mxima en 103

Lectura/Escritura Escritura Escritura Lectura

El sensor SRF08 tiene muchas ms instrucciones y diferentes modos de operacin, esta tabla solo contiene algunas de las instrucciones que el sensor maneja, esto con la finalidad de entender el cdigo que va en el micrcontrolador, ya que ms adelante se har uso de estas direcciones.

73

Programa en C
#include<avr/io.h> #include<util/delay.h> #include<avr/interrupt.h> #include<util/twi.h> #define Clock 1000000 #define SRF02 0xE0; void TWI_config(unsigned long int); void i2c_transmit(char,char,char); char i2c_read(char,char); //Frecuencia de trabajo del microcontrolador

//Declarar las funciones

int main(void) //Inicio del programa { DDRD = 0xFF; TWI_config(100000); //Llamar la funcion para configurar el I2C o TWI unsigned char valor=0; while(1) { i2c_transmit(0xE0,0,0x51); //Transmitir: direccion 0xE0, registro 0, dato 0x51 _delay_ms(75); valor = i2c_read(0xE0,3); //leer: direccion 0xE0, registro 3 PORTD = valor; //Mandar el valor leido al puerto D _delay_ms(100); } }

void TWI_config(unsigned long int frecuencia) { TWBR = ((Clock/frecuencia) - 16)/8; TWSR=(0<<TWPS1)+(0<<TWPS0); }

// Registro para la frecuencia de SCL // Preescala 1

74

char i2c_read(char address, char reg) { char read_data = 0; TWCR = 0xA4; while(!(TWCR & 0x80)); TWDR = address; TWCR = 0x84; while(!(TWCR & 0x80)); TWDR = reg; TWCR = 0x84; while(!(TWCR & 0x80)); TWCR = 0xA4; while(!(TWCR & 0x80)); TWDR = address+1; TWCR = 0xC4; while(!(TWCR & 0x80)); TWCR = 0x84; while(!(TWCR & 0x80)); read_data = TWDR; TWCR = 0x94; return read_data; } void i2c_transmit(char address, char reg, char data) { TWCR = 0xA4; // Mandar el bit de inicio para el bus I2C while(!(TWCR & 0x80)); // Esperar confirmacin de la transmisin TWDR = address; // Cargar direccin (adress) en el dispositivo TWCR = 0x84; // Transmitir while(!(TWCR & 0x80)); // Esperar confirmacin de la transmisin TWDR = reg; TWCR = 0x84; // Transmitir while(!(TWCR & 0x80)); // Esperar confirmacin de la transmisin TWDR = data; TWCR = 0x84; // Transmitir while(!(TWCR & 0x80)); // Esperar confirmacin de la transmisin TWCR = 0x94; // Mandar un bit de paro al bus I2C } // Mandar el bit de inicio para el bus I2C // Esperando la confirmacin // Cargar direccin (adress) en el dispositivo // Transmitir // Esperar confirmacin de la transmisin // Enviar nmero de registro a leer // Transmitir // Esperar confirmacin de la transmisin // Volver a mandar un bit de inicio // Esperar confirmacin de la transmisin // Transmitir direccin por I2C con la lectura habilitada // Borrar la bandera de interrupcin de transmisin // Esperar confirmacin de la transmisin // Transmitir (Solicitud del ltimo byte) // Esperar confirmacin de la transmisin // Tomar el dato // Mandar un bit de paro al bus I2C

75

Detalles del programa


#include<avr/io.h> #include<util/delay.h> #include<avr/interrupt.h> #include<util/twi.h> Se llaman las libreras necesarias para el programa. void TWI_config(unsigned long int); void i2c_transmit(char,char,char); char i2c_read(char,char); Se declaran las funciones que a continuacin se usaran. Es importante notar en caso de escribir las funciones despus del main, es necesario declararlas. TWI_config(100000); Se llama a la funcin TWI_config con la entrada 1000000 que ser la frecuencia del microcontrolador, ms adelante se explicara esta funcin. i2c_transmit(0xE0,0,0x51); _delay_ms(75); valor = i2c_read(0xE0,3); PORTD = valor; _delay_ms(100); Se puede ver en esta seccin de cdigo que se transmite por el I2C, y se lee el dato el cual se muestra a travs del puerto D. las funciones de transmitir y de leer se explican a continuacin. void TWI_config(unsigned long int frecuencia) { TWBR = ((Clock/frecuencia) - 16)/8; TWSR=(0<<TWPS1)+(0<<TWPS0); }

76

El TWBR selecciona el factor de divisin de la frecuencia del SCL en modo maestro

Al registro de estado TWSR se le est escribiendo la instruccin (0<<TWPS1)+(0<<TWPS0); la cual nos indica que a los bits TWPS1 y TWPS0 se les est asignando un 0 a cada uno, esto es, para corroborar que se est usando una preescala de 1.

char i2c_read(char address, char reg) { char read_data = 0; TWCR = 0xA4; while(!(TWCR & 0x80)); TWDR = address; TWCR = 0x84; while(!(TWCR & 0x80)); TWDR = reg; TWCR = 0x84; while(!(TWCR & 0x80)); // Mandar el bit de inicio para el bus I2C // Esperando la confirmacin // Cargar direccin (adress) en el dispositivo // Transmitir // Esperar confirmacin de la transmisin // Enviar nmero de registro a leer // Transmitir // Esperar confirmacin de la transmisin

77

TWCR = 0xA4; while(!(TWCR & 0x80)); TWDR = address+1; TWCR = 0xC4; while(!(TWCR & 0x80)); TWCR = 0x84; while(!(TWCR & 0x80)); read_data = TWDR; TWCR = 0x94; return read_data; }

// Volver a mandar un bit de inicio // Esperar confirmacin de la transmisin // Transmitir direccin por I2C con la lectura habilitada // Borrar la bandera de interrupcin de transmisin // Esperar confirmacin de la transmisin // Transmitir, nack (Solicitud del ltimo byte) // Esperar confirmacin de la transmisin // Tomar el dato // Mandar un bit de paro al bus I2C

La funcin i2c_read, lee el dato que manda el sensor, entre las cosas a destacar en esta funcin son el uso del registro TWCR y del TWDR:

El TWCR se usa para controlar la operacin del TWI. En l se habilita el TWI, se inicializa el acceso con la condicin de inicio, genera una condicin de paro, entre otras cosas

En modo de transmisin, el TWDR contiene el siguiente byte para ser transmitido, y en modo de recepcin contiene el ultimo byte en ser recibido. Dentro del la funcion i2c_read se encuentran varias instrucciones importantes las cuales son: TWCR = 0xA4; Esta instruccin nos indica que los bits 2, 5 y 7 los cuales son TWEN, TWSTA y TWINT respectivamente, del registro TWCR estn habilitados. TWEN: Habilita y activa la comunicacin TWI (I2C). TWSTA: Al habilitarlo, se configura el TWI del microcontrolador como modo maestro. TWINT: Al escribirle un 1 lgico, se limpia la bandera de interrupcin.

78

while(!(TWCR & 0x80)); El 0x80 en el TWCR corresponde a la bandera del bit TWINT, el ciclo espera a la bandera de confirmacin. TWDR = address; Se le asigna la variable address, la cual, como se puede ver en el cdigo, tiene el valor de 0xE0. Este valor es la direccin del dispositivo con el que se est comunicando. En este caso el sensor ultrasnico responde a la direccin 0xE0 TWCR = 0x84; Se limpia la bandera y habilita la comunicacin. TWDR = reg; Enva el registro a leer en el TWDR, en este caso la variable reg es igual a 3 lo que en el sensor indica el ajuste de la ganancia analgica mxima a 103. La finalidad de poder limitar la ganancia mxima es permitirle iniciar mediciones a una frecuencia mayor de 65mS. read_data = TWDR; Toma el dato y lo coloca en la variable read_data TWCR = 0x94; Manda un bit de paro, activando tambin el TWSTO Stop Condition Bit. void i2c_transmit(char address, char reg, char data) { TWCR = 0xA4; // Mandar el bit de inicio para el bus I2C while(!(TWCR & 0x80)); // Esperar confirmacin de la transmisin TWDR = address; // Cargar direccin (adress) en el dispositivo TWCR = 0x84; // Transmitir while(!(TWCR & 0x80)); // Esperar confirmacin de la transmisin TWDR = reg; TWCR = 0x84; // Transmitir while(!(TWCR & 0x80)); // Esperar confirmacin de la transmisin TWDR = data; TWCR = 0x84; // Transmitir while(!(TWCR & 0x80)); // Esperar confirmacin de la transmisin

79

TWCR = 0x94; }

// Mandar un bit de paro al bus I2C

Las instrucciones de la funcin para transmitir como podemos ver son casi las mismas que para la funcin leer, pero no perdamos de vista que al mandar llamar cada funcin se le asignan distintos valores, entre las principales instrucciones a destacar se encuentran: TWDR = reg; A diferencia de la funcin read, el registro en este caso tiene un valor de 0 el cual le indica al sensor que inicie la sesin de clculo de la distancia. TWDR = data; Se puede ver en el main que a la variable data, se le asigna un 0x51 el cual le indica al sensor que trabaje en modo de clculo de distancia y este nos da un resultado en centmetros.

80

Comunicacin serial USART

81

Comunicacin Serial USART


Descripcin
En este proyecto, se ver una de las maneras de entablar comunicacin del microcontrolador con la computadora, para poder realizar esta prctica se requerir del uso de varios componentes los cuales describiremos a continuacin, la comunicacin serial es una de las maneras ms sencillas de comunicar nuestro microcontrolador hacia el exterior, ya sea con una computadora o con algn otro microcontrolador. Para este proyecto se configurara el microcontrolador con el oscilador interno a 8 Mhz y se usara del programa Teraterm el cual es el equivalente de la hyperterminal en Windows Vista. Bsicamente el programa realizara un eco del dato mandado, si se manda una "a" el microcontrolador recibir esa "a" y la enviara de vuelta. Esto con la finalidad de aislar la comunicacin de cualquier proceso, en su momento es posible mandar un dato, aplicarle algn proceso o algoritmo y regresar el resultado.

Diagrama Esquemtico

Materiales
Max 232 4 capacitores de 10 uF 1 Microcontrolador ATmega8

82

Programador USBasp V3.0 1 Cable USB a Serial en caso de que la computadora no tenga puerto serial

Introduccin
Caractersticas de la USART del ATmega8
La USART o Universal Synchronous and Asynchronous serial Receiver and Transmitter es un dispositivo de comunicacin serial altamente flexible, sus principales caractersticas son: -Operacin Full Dulpex -Registros de transmisin y recepcin independientes -Operacin sncrona o asncrona -Generador de Baud Rate de alta resolucin -Deteccin de error -Filtro de ruido -Modo de comunicacin multiproceso -Doble velocidad en modo de comunicacin asncrono Diagrama a bloques de la USART

El manejo de la comunicacin serial presenta muchos beneficios, entre los que destacan, el control de sistemas a travs de la computadora realizando clculos complejos, visualizando y graficando datos, entre otros. Es importante destacar que tambin existen muchos programas aparte de la hyperterminal los cuales pueden entablar comunicacin serial con el microcontrolador, programas como MatLab, LabVIEW, TeraTerm entre otros.

83

Programa en C
#include<avr/io.h> #include<util/delay.h> int dato; void InitUART( unsigned char baudrate ) { UBRRL = baudrate; UCSRB = (UCSRB | _BV(RXEN) | _BV(TXEN)); } unsigned char ReceiveByte( void ){ while ( !(UCSRA & (1<<RXC)) ); return UDR; } void TransmitByte( unsigned char data ) { while ( !( UCSRA & (1<<UDRE)) ); UDR = data; } int main (void) { InitUART( 51 ); while(1){ dato=ReceiveByte(); TransmitByte(dato); } } //Inicializar la UART //Recibir un dato de la UART //Mandar el mismo dato //Configurando la UART //Seleccionando la velocidad //Habilitando la transmisin y recepcin

//Funcin para recibir un byte //Esperar la recepcin //Retornar el dato tomado de la UART

//Funcion para transmitir dato //Esperar transmision completa //Depositar el dato para transmitirlo

Detalles del programa


#include<avr/io.h> #include<util/delay.h> int dato; Se inicia el programa con las libreras respectivas, y se declara una variable "dato".

84

void InitUART( unsigned char baudrate ) { UBRRL = baudrate; UCSRB = (UCSRB | _BV(RXEN) | _BV(TXEN)); } Se declara la funcin que configura el USART, recordemos que en este caso se trabajara el microcontrolador a una frecuencia de 8 Mhz. El primer registro a configurar es el UBRRL

Como se puede ver el UBRR (11:0) contiene 12 bits, en este registro se ajusta la velocidad de trabajo de la comunicacin, el baud rate. Hay que substituir los valores indicados en las siguientes formulas para obtener el valor que va en el UBRR y l % de error.

Como se usara el modo asncrono normal, tomamos la primeras formulas para calcular el UBRR y despus los Baudios. Primero resolvemos la del UBRR para obtener el valor calculndolo con 9600 baudios, despus calculamos los baudios con el valor del UBRR (Pero el valor entero ya que en los registros solo se pueden asignar nmeros enteros), y el resultado nos dar los baudios reales. = 8000000 1= 1 = . 16 16 9600

El valor obtenido para 9600 baudios fue de 51.0833 por lo tanto, se tomara el valor de 51 redondeando el valor obtenido, y con el cual calculamos los baudios reales. = 8000000 = = . 16 + 1 16 51 + 1

85

9615.3846 Sera el valor real de baudios por segundo con los que el microcontrolador trabajara, para obtener el %de error respecto al valor de 9600 aplicamos la siguiente formula.

% =

9615.3846 9600

1 100 = 0.16%

Como se puede ver el porcentaje de error es muy pequeo. Estas operaciones previamente realizadas es para conocer un poco ms el funcionamiento del registro y el cmo calcular el valor respecto a algn baud rate deseado, pero tambin hay una tabla en la hoja de datos con los valores ms usados.

Como se puede ver, los valores obtenidos para el UBRR son similares a los de la tabla. Volviendo al registro, solo se le asigna el valor al UBRRL el cual es suficiente modificar ya que el 51 en binario es 0b110011, como se puede ver solo se necesitan los bits del 0 al 6.

Para el UCSRB

Como se observa en el cdigo se habilitan los bits RXEN y TXEN los cuales habilitan el transmisor y el receptor de la USART adems de los pines correspondientes RXD y TXD.

86

unsigned char ReceiveByte( void ){ while ( !(UCSRA & (1<<RXC)) ); return UDR; }

//Funcin para recibir un byte //Esperar la recepcin //Retornar el dato tomado de la UART

El uso del registro UCSRA para la funcin de recibir un byte, es por el bit 7 el RXC el cual indica que hay algun dato para leer en el registro. Por lo tanto el ciclo while espera hasta que haya un dato, posteriormente finaliza la funcin con un return, el cual regresa el valor en el UDR (donde se encuentra el dato) fuera de la misma. void TransmitByte( unsigned char data ){ while ( !( UCSRA & (1<<UDRE)) ); UDR = data; }

Al igual que la funcin de recibir un byte esta espera el UDRE en el UCSRA el cual indica que el buffer de transmisin est listo para recibir nuevos datos, una vez que salga del ciclo, se coloca el dato deseado en el UDR para transmitirlo. init main (void) { InitUART( 51 ); while(1){ dato=ReceiveByte(); TransmitByte(dato); } }

Como ya se explico, se inicializa la UART con un 51 el valor correspondiente, una vez configurada el programa entra al ciclo, en donde la funcin espera recibir un dato, una vez que se recibe el dato, este mismo sin sufrir modificacin alguna es mandado a travs de la UART. Recordemos que se est mandando un byte esto es, que al recibir el microcontrolador una letra en una variable de tipo entero, esta variable tendr el valor que corresponde a esa letra (ver la tabla ASCII), por ejemplo si se manda una variable con el valor 57 en la terminal veremos una "a", pero si

87

mandamos una variable tipo char con una 'a' en la terminal veremos esa misma "a", en la tabla se muestran varios ejemplos. Por lo tanto dependiendo del programa que estemos usando, debemos de tener cuidado si este recibe los bytes y los toma como caracteres o como enteros. Variable Int Dec Bin 97 0b01100001 65 0b01000001 51 0b00110011 Variable char Hex 0x61 0x41 0x33 'a' 'A' '3' Terminal a A 3

88

89

Potrebbero piacerti anche