89
1 Guia de VideoTutoriales Programador USBasp V3.0

Guia de VideoTutoriales HeTPro

Embed Size (px)

Citation preview

Page 1: Guia de VideoTutoriales HeTPro

1

Guia de VideoTutoriales Programador USBasp V3.0

Page 2: Guia de VideoTutoriales HeTPro

2

INDICE

_____________________________________________________________________________________

Introducción .................................................................................................................................................. 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

Interrupción Externa ................................................................................................................................... 37

Uso del ADC................................................................................................................................................. 42

Uso del PWM .............................................................................................................................................. 47

Servomotor ................................................................................................................................................. 55

Pantalla LCD ................................................................................................................................................ 62

Sensor ultrasónico SRF08 ............................................................................................................................ 70

Comunicación serial USART ........................................................................................................................ 81

Page 3: Guia de VideoTutoriales HeTPro

3

Introducción

Page 4: Guia de VideoTutoriales HeTPro

4

Introducción

Antes de empezar a leer esta guía, es recomendable leer la guía de usuario del programador, en la

que se explica cómo usar el Programador y como instalar los programas necesarios para poder empezar

a programar.

Esta guía es propiedad de HeTPro. Queda expresamente prohibida la reproducción total o parcial por

cualquier medio o soporte de los contenidos de esta publicación sin la autorización expresa del editor.

Todas las marcas y productos aparecidos en esta guía son marca registrada y/o copyright de sus

propietarios.

Cualquier comentario, duda o sugerencia favor de escribir a:

[email protected]

Page 5: Guia de VideoTutoriales HeTPro

5

Parpadeo de un LED

Page 6: Guia de VideoTutoriales HeTPro

6

Parpadeo

Descripción

En este programa se manejara el puerto para hacer parpadear un LED, en este caso se realizara el

parpadeo a través de dos métodos distintos de programación, 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 Esquemático

Materiales

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

Page 7: Guia de VideoTutoriales HeTPro

7

Introducción

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 ningún 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; //Todos los pines estan activos PORTB=0x00; //Todos los pines estan desactivados PORTB=0x03; //Solo los primeros dos bits del puerto estan activos

PIN

Page 8: Guia de VideoTutoriales HeTPro

8

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 instrucción. ej. valor=PINB; //El valor de PINB es asignado a la variable "valor"

Programa en C

#include <avr/io.h> //Librería de entradas y salidas

#include <util/delay.h> //Librería de retardos

int main (void){ //Inicio del programa

DDRB=0xFF; //Declarar el puerto como salida

while(1){ //Iniciar bucle infinito

PORTB=0x01; //Puerto B = 00000001

_delay_ms(250); //Espera 250 milisegundos

PORTB=0x00; //Puerto B = 00000000

_delay_ms(250);

PORTB|=_BV(PB0); //Bit 0 del puerto B = 1

_delay_ms(250);

PORTB&=~(_BV(PB0)); //Bit 0 del puerto B = 0

_delay_ms(250);

}

}

Page 9: Guia de VideoTutoriales HeTPro

9

Detalles del programa

#include <avr/io.h>

Incluimos la librería avr/io que contiene la información de las entradas y salidas del

microcontrolador.

#include <util/delay.h>

Esta librería es necesaria para poder utilizar los retardos de tiempo

int main (void){

El main es la función principal, es donde el programa inicia, siempre es necesario declarar la función

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

escribiría 0b11111111, en donde se puede ver claramente que los 8 bits del DDR están 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 paréntesis se cumpla, en este caso el 1 es lo mismo que TRUE,

por lo tanto, siempre se cumple y se ejecutaran cíclicamente las instrucciones dentro del while. Esto se

hace con la intención 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

alimentación del mismo viene del bit 0 o el primero pin del puerto B, como podemos ver en el código, 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 continuación describe el código.

Page 10: Guia de VideoTutoriales HeTPro

10

0 0 0 0 0 0 0 1

RETARDO 250

0 0 0 0 0 0 0 0

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 más complejas, ya

que se separa y se activa o desactiva el bit 0 del puerto B.

Prácticamente el código hace lo mismo, pero la principal diferencia y ventaja, es que al usar este

código, 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

Page 11: Guia de VideoTutoriales HeTPro

11

Manejo de los Puertos

Page 12: Guia de VideoTutoriales HeTPro

12

Manejo de los Puertos

Descripción

En este programa se verá un uso práctico 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 verán estructuras de control como el while y

el if.

Diagrama Esquemático

Materiales

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

Page 13: Guia de VideoTutoriales HeTPro

13

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

if else

Page 14: Guia de VideoTutoriales HeTPro

14

En el if/else, también hay una condición 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 condición haya sido falsa. if ("condicion"){ procesoA; }

else { ProcesoB; }

Programa en C

Detalles del programa

#include <avr/io.h>

Incluimos la librería avr/io que contiene la informacion de las entradas y salidas del

microcontrolador.

#include <util/delay.h>

#include <avr/io.h> //Librería necesaria para las entradas y salidas

#include <util/delay.h> //Librería para usar los retardos de tiempo

int main (void){ //Inicio del programa

DDRB=0x00; //Iniciar el puerto B como entrada

DDRD=0xFF; //Declarar el puerto D como salida

while(1){ //Bucle infinito

if (PINB==0x01){ //"si el PINB es igual a 1

PORTD=0x01; //Prender el LED conectado al bit 0 del puerto D

_delay_ms(1000); //Esperar 1000 mili segundos

PORTD=0x00; //Apagar el LED

}

}

}

Page 15: Guia de VideoTutoriales HeTPro

15

Esta librería es necesaria para poder utilizar los retardos de tiempo

int main (void){

El main es la función principal, es donde el programa inicia, siempre es necesario declarar la función

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 condición tiene que ir dentro de paréntesis, y en este caso como se puede ver se usa

doble símbolo de igual para diferenciarlo de cuando se le asigna un valor a una variable,

variable=14; //Se le asigna el valor de 14 a la variabe

variable==14 //Se comparan variable y 14, si es verdadero arroja un 1

Nótese que se está usando PINB, el cual pertenece al puerto B, el mismo que se declaro como salida

en el DDR. Esta condición corresponde al Push Button conectado en el pin del puerto B.

PORTD=0x01;

Se le da al puerto la instrucción 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);

Instrucción que espera 1000 milisegundos, el valor dentro de los paréntesis puede ser ajustado

como se requiera.

Page 16: Guia de VideoTutoriales HeTPro

16

PORTD=0x00;

Se desactivan todos los pines del puerto D

Bit 7 6 5 4 3 2 1 0

PORTD 0 0 0 0 0 0 0 0

Page 17: Guia de VideoTutoriales HeTPro

17

Rota-bit

Page 18: Guia de VideoTutoriales HeTPro

18

Rota-bit

Descripción

Se podrá visualizar el bit del puerto asignado, desplazándose por el puerto de lado a lado a través de

una serie de LEDs conectados al microcontrolador. En este ejemplo se verá el uso de la instrucción para

realizar un corrimiento ya sea a la derecha o a la izquierda.

Diagrama Esquemático:

Materiales

6 LEDs

6 Resistencias de 220 Ohms

1 Microcontrolador ATmega8

Programador USB asp V3.0

Introducción

LED

LED acrónimo de Light Emitting Diode o Diodo Emisor de Luz, es un dispositivo semiconductor que

emite luz al circular a través de él una corriente eléctrica.

Page 19: Guia de VideoTutoriales HeTPro

19

Los LEDs como los diodos normales tienen un ánodo y un cátodo, los cuales se pueden identificar de

manera fácil, siendo el ánodo la pata más 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 desempeño optimo se realiza a través de la

siguiente fórmula:

𝑹 =𝑽𝒄𝒄 − 𝑽𝑳𝑬𝑫

𝑰𝑳𝑬𝑫

En donde:

R: Resistencia

Vcc: Voltaje de la fuente

VLED: Voltaje del LED

ILED: Corriente del LED

Page 20: Guia de VideoTutoriales HeTPro

20

Programa en C:

Detalles del programa:

#include <avr/io.h>

Librería de entradas y salidas de los AVR. Esta contiene la información de los puertos y los pines de todos los microcontroladores AVR.

#include <util/delay.h>

Librería 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.

#include <avr/io.h> //Librería de entradas y salidas de los AVR #include <util/delay.h> //Librería para usar los retardos "_delay_ms()" int main(void){ //Inicio del programa DDRD=0xFF; //Declarar el registro del puerto D como salidas PORTD=0x01; //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

Page 21: Guia de VideoTutoriales HeTPro

21

PORTD=0x01;

El PORT maneja el puerto en caso de que lo hayamos asignado como salida, esta instrucción asigna

el nivel lógico a la salida física 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 demás se encontraran desactivados (0v) .

while(1){

La estructura de control while, se puede leer como "Mientras se cumpla esta condición, ejecutar las

instrucciones", pero como en este caso el 1 se toma como una situación "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 instrucción

PORTD=PORTD<<1; esto quiere decir que el registro se desplazara una posición a la izquierda, por

ejemplo:

Bit 7 6 5 4 3 2 1 0

PORTD=0x01 0 0 0 0 0 1 0 0 PORTD=PORTD<<1; 0 0 0 0 1 0 0 0

PORTD=PORTD>>1; 0 0 0 0 0 0 1 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

instrucción 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 posición 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.

Page 22: Guia de VideoTutoriales HeTPro

22

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 repetirán los desplazamientos del bit activo en el puerto, el cual

estará siendo desplazado de un extremo a otro.

Page 23: Guia de VideoTutoriales HeTPro

23

Contador de 0-99 con 2

Displays de 7

Segmentos

Page 24: Guia de VideoTutoriales HeTPro

24

Contador de 0-99 con 2 displays de 7

Segmentos

Descripción

El programa incrementara el valor de una variable, la cual se mostrara a través 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 Esquemático

Materiales

2 Displays 7 segmentos 7 Resistencias de 220 Ohms 2 Resistencias de 10 kOhms 2 Transistores de pequeña señal 1 Microcontrolador ATmega8 Programador USBasp V3.0

Page 25: Guia de VideoTutoriales HeTPro

25

Introducción Display 7 segmentos

El display de 7 segmentos es un dispositivo que nos sirve para mostrar números o caracteres, los cuales se visualizan al activar o desactivar los LEDs que este tiene, esto se hace conectando el común a la tierra y voltaje en el segmento que deseemos activar (en caso de ser cátodo común).

Para poder representar los números con el display, es necesario generar la tabla que nos dará el

valor que será necesario para generar el numero deseado.

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

información del numero, tendremos el valor que tomara el puerto para mostrar el numero deseado

a través 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 están conectados al mismo puerto del micro. Primero se

mostrara las decenas mientras se desactiva el display de las unidades y después de una fracción de

tiempo, se activa el de la unidad y se desactiva el de las decenas y el micro manda el valor de la

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

0 1 1 1 1 1 1 0 7E

1 0 1 1 0 0 0 0 30

2 1 1 0 1 1 0 1 6D

3 1 1 1 1 0 0 1 79

4 0 1 1 0 0 1 1 33

5 1 0 1 1 0 1 1 5B

6 1 0 1 1 1 1 1 5F

7 1 1 1 0 0 0 0 70

8 1 1 1 1 1 1 1 7F 9 1 1 1 1 0 1 1 7B

Page 26: Guia de VideoTutoriales HeTPro

26

unidad. Esto se repite determinadas veces a alta velocidad para dar la impresión 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 común del display, y este controlara el display activándolo o

desactivándolo 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 saturación, 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, //Se declara un vector de longitud 10 que contenga los 0x30, //valores obtenidos de la tabla, acomodados en orden 0x6D, //Según su posición del 0 al 9 0x79, 0x33, 0x5B, 0x5F, 0x70, 0x7F, 0x7B}; int mostrar(int numero){ //Creamos una función de tipo entero unidades=numero%10; //Al dividir un valor entre 10 el residuo nos da las unidades decenas =numero/10; //Se obtiene la decena dividiendo el numero entre 10

for(i=0;i<20;i++){ PORTD=0x02; //Se activa el transistor de las unidades PORTB=numeros[unidades]; //Se asigna al PORTB la variable numero en la posición unidades _delay_ms(5); PORTD=0x01; //Se activa el transistor de las decenas PORTB=numeros[decenas]; //Se asigna al PORTB la variable numero en la posición decenas _delay_ms(5); } return 0; }

Page 27: Guia de VideoTutoriales HeTPro

27

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 posición del vector corresponde al número 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 posición.

int mostrar(int numero){

Una función se declara como "tipo de dato" "nombre de la función" ( "tipo de dato" "nombre de

entrada"), en este caso la función 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;

Operación 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.

int main(void){ //Inicio del programa DDRB=0xFF; DDRD=0x03; while(1){ mostrar(contador); //Llamar a la función mostrar, mandando la variable contador contador++; //Incrementar el valor de la variable contador if (contador > 99) //Si llega a 99, que tome el valor de 0 contador=0; } }

Page 28: Guia de VideoTutoriales HeTPro

28

PORTB=numeros[unidades];

Al puerto B se le asigna el valor que tenga el vector números en la posición unidades, si tomamos el

ejemplo anterior, unidades valía 5, si vamos al vector números y vemos la quinta posición, veremos

un 0x5B la cual corresponde al número 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 función 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 función, esta ejecutara todas las instrucciones que se

encuentren dentro de la misma, al terminar regresara y continuara con la siguiente instrucción.

Page 29: Guia de VideoTutoriales HeTPro

29

Matriz de LEDs

Page 30: Guia de VideoTutoriales HeTPro

30

Matriz de LEDs

Descripción

Se hará un contador del 0-9, el cual visualizaremos a través 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 Esquemático

Materiales

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

Page 31: Guia de VideoTutoriales HeTPro

31

Introducción Matriz de LEDs

La matriz de LEDs no es más 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 código, por lo que debemos formar la figura, numero o letra que necesitemos separando la misma en 5 columnas. A continuación veremos cómo se forma el numero 3 el cual prestando atención al valor de las R's las cuales forman el código 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 lógico, lo cual está dado ya que la columna correspondiente

Page 32: Guia de VideoTutoriales HeTPro

32

está habilitada con un 1 lógico (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 formación de un numero 3

C bin C hex R bin R hex

00001 0x01 1011101 0x5D

00010 0x02 0111110 0x3E

00100 0x04 0110110 0x36

01000 0x08 0000000 0x00

10000 0x10 1001001 0x49

Page 33: Guia de VideoTutoriales HeTPro

33

Como se puede ver en la imagen anterior, el numero 3 se formo en base a la combinación 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. Después de hacer un proceso similar, se obtuvo una tabla con los valores de cada numero deseados, en este caso los números 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 C1 C2 C3 C4 C5

0 0x41 0x3E 0x3E 0x00 0x41

1 0x7E 0x5E 0x00 0x00 0x7E

2 0x4E 0x3C 0x38 0x02 0x46

3 0x5D 0x3E 0x36 0x00 0x49

4 0x07 0x77 0x77 0x00 0x00

5 0x8C 0x36 0x36 0x30 0x39

6 0x41 0x36 0x36 0x30 0x39

7 0x3F 0x37 0x37 0x00 0x0F

8 0x49 0x36 0x36 0x00 0x49

9 0x4D 0x36 0x36 0x00 0x41

Page 34: Guia de VideoTutoriales HeTPro

34

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}, //Se declara la matriz de los numeros

{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}};

int main (void){

DDRD=0xFF;

DDRC=0xFF;

PORTC=0x10; //Inicializar el puerto C para el barrido de las columnas

while(1){

for(j=0;j<25;j++){ //Ciclo de numero de barridos

for(i=0;i<5;i++){ //Ciclo de barrido de columnas

PORTD=numero[contador][i]; //Se le asigna al PORTD el código respecto a la columna

_delay_ms(1);

PORTC=PORTC>>1; //Siguiente columna

}

PORTC=0x10; //Se inicializa a las primera columna

}

contador++; //Incrementar en 1 el contador

if (contador==10) //Si el contador llega a 10

contador=0; //que vuelva a ser 0

}

}

Page 35: Guia de VideoTutoriales HeTPro

35

Detalles del programa

#include <avr/io.h>

#include <util/delay.h>

Incluir las librerías 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 añadimos la longitud de las filas y las columnas dentro de los

corchetes, como se puede ver en el código.

La matriz declarada e inicializada con los valores, es la misma que se encuentra representada en la

tabla en la introducción del proyecto, como se puede ver, la relación de la posición 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 código.

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 código 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

visualizándose el numero en la matriz. El número 25 en este ciclo for puede cambiarse para obtener

un conteo más rápido o más lento según se requiera.

Page 36: Guia de VideoTutoriales HeTPro

36

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 más, por lo tanto este

for se ejecutara completo el número 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 posición 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 número 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 asignándole un cero.

Page 37: Guia de VideoTutoriales HeTPro

37

Interrupción Externa

Page 38: Guia de VideoTutoriales HeTPro

38

Interrupción Externa

Descripción

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 interrupción y ejecutar las instrucciones dentro esta función, que para este caso es prender el

LED que se encuentra conectado al microcontrolador.

Diagrama Esquemático

Materiales

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

Page 39: Guia de VideoTutoriales HeTPro

39

Introducción Interrupción 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 interrupción 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

Page 40: Guia de VideoTutoriales HeTPro

40

Programa en C

Detalles del programa

#include <avr/interrupt.h>

Cada que se use alguna interrupción es necesario llamar a la librería avr/interrupt.h que es la que

contiene todos los vectores de interrupción de los AVR's.

cli();

Esta instrucción deshabilita las interrupciones.

sei();

Habilita las interrupciones.

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

Page 41: Guia de VideoTutoriales HeTPro

41

MCUCR=0x03;

Al asignársele 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 interrupción, como se puede ver en la tabla, hay cuatro opciones

que son: El nivel bajo de INT1, Cualquier cambio lógico, El flanco de bajada y El flanco de subida. Con los

bits 0 y 1 en unos, tenemos habilitada la opción 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 interrupción externa.

Page 42: Guia de VideoTutoriales HeTPro

42

Uso del ADC

Page 43: Guia de VideoTutoriales HeTPro

43

Uso del ADC

Descripción

Con este programa podremos visualizar a través de los LEDs, el valor en binario tomado del ADC

conectado a un potenciómetro. El ADC se trabajara a manera de conversión 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 Esquemático

Materiales

1 Potenciómetro 6 LEDs 7 Resistencias de 220 Ohms 1 Microcontrolador ATmega8 Programador USBasp V3.0

Introducción El ADC

El ADC convierte señales continuas a números discretos. El ADC es un dispositivo electrónico 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 características principales del ADC del ATmega8 son:

-Resolución de 10 bits -± 2 bits de precisión -13 a 260 us de tiempo de conversión

Page 44: Guia de VideoTutoriales HeTPro

44

-6 Canales de entrada multiplexados -Rango de voltaje de entrada de 0-Vcc -Selector de voltaje de referencia de 2.56v -Tipos de conversión continuo o simple -Interrupción de conversión -Ahorro de energía

Potenciómetro

El potenciómetro es un tipo de resistencia variable el cual varia conforme se gira la perilla que tiene,

en este caso el potenciómetro es usado para generar un divisor de voltaje el cual al variar la

resistencia, la salida de voltaje también cambiara proporcionalmente.

El potenciómetro tiene 3 patas las cuales son:

Programa en C

Detalles del programa

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

Page 45: Guia de VideoTutoriales HeTPro

45

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 conversión.

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 más significativos.

ADCSRA|=_BV(ADSC);

Al estar trabajando el ADC en este modo es necesario indicarle cada cuando tiene que realizar la

conversión, con esta instrucción solo entra al bit ADSC del registro y lo habilita, no se modifica

cualquier otro valor del registro ADCSRA.

Page 46: Guia de VideoTutoriales HeTPro

46

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 están usando solo 6 LEDs, esto se hace ajustando la

recta, multiplicando por el máximo de nuestra salida ideal y dividiéndolo por el máximo de la salida

obtenida.

Page 47: Guia de VideoTutoriales HeTPro

47

Uso del PWM

Page 48: Guia de VideoTutoriales HeTPro

48

Uso del PWM

Descripción

En este ejemplo se hará uso del PWM, o modulación 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 modulación, a más ancho el pulso mas ciclo de trabajo y el LED se

iluminara con mayor intensidad.

Diagrama Esquemático

Materiales

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

Page 49: Guia de VideoTutoriales HeTPro

49

Introducción PWM

Modulación por ancho de pulso o PWM (Pulse-Width Modulation), de una señal, es cuando se modifica el ciclo de trabajo o el ancho del pulso de una señal periódica, en este caso representado por una señal cuadrada, uno de los usos del PWM entre muchos otros, es controlar la cantidad de energía, 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 señal permanece fijo, por lo tanto, la frecuencia también, 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 posición de un servomotor, fuentes conmutadas, entre otras cosas más.

Page 50: Guia de VideoTutoriales HeTPro

50

Programa en C

Detalles del programa

#include <avr/io.h>

Incluimos la librería avr/io que contiene la informacion de las entradas y salidas del

microcontrolador.

#include <avr/io.h>

#include <util/delay.h>

int main(void){

DDRB=0x02;

DDRD=0x00;

TCCR1A=0b10000011; //Configurar el PWM en modo de fase

TCCR1B=0b00000001; //Sin preescalador

TCNT1 =0b00000000; //No se modifica

OCR1A=0; //Inicializar el TOP en cero

for(;;){ //Ciclo infinito

if ( PIND == 0x01 ) { //Si el boton 1 esta activado

OCR1A++; //Incrementar la modulacion

_delay_us(500);

}

if ( PIND == 0x02 ) { //Si el boton 2 esta activado

OCR1A--; //Decrementar la modulacion

_delay_us(500);

}

}

}

Page 51: Guia de VideoTutoriales HeTPro

51

#include <util/delay.h>

Esta librería es necesaria para poder utilizar los retardos de tiempo

int main (void){

El main es la función principal, es donde el programa inicia, siempre es necesario declarar la función

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 están activados, podemos ver que el modo de

operación 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 corrección 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 comparación al incrementar y ajusta

el OC1A en la comparación al decremento.

Page 52: Guia de VideoTutoriales HeTPro

52

A continuación se puede ver en la grafica tomada de la hoja de datos el funcionamiento del PWM en

modo de fase:

TCCR1B=0b00000001;

Page 53: Guia de VideoTutoriales HeTPro

53

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 instrucción 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 sección de código, 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 modulación, 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 botón, y dentro de este el

OCR1A se decrementara.

Page 54: Guia de VideoTutoriales HeTPro

54

El retardo se usa ya que como el microcontrolador corre a una velocidad de 1Mhz, para limitar la

velocidad del incremento, si no hubiera algún retardo, no podríamos observar que es lo que esta

pasado debido a la velocidad del incremento, ya que con solo presionar algún botón un instante de

tiempo, el código se repetiría cientos de veces y el OCR1A se incrementaría o decrementaria muy

rápido.

Page 55: Guia de VideoTutoriales HeTPro

55

Servomotor

Page 56: Guia de VideoTutoriales HeTPro

56

Servomotor

Descripción

Existen varias maneras de generar un PWM capaz de controlar un servomotor, pero esta vez, se

hará a través 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

potenciómetro conectado al ADC.

Diagrama Esquemático

Materiales

1 Servomotor 1 Resistencia de 220 Ohms 1 Potenciómetro de 10Kohms 1 Microcontrolador ATmega8 Programador USBasp V3.0

Page 57: Guia de VideoTutoriales HeTPro

57

Introducción Servomotor

Un servomotor es un dispositivo actuador que tiene la capacidad de ubicarse en cualquier posición dentro de su rango de operación, y de mantenerse estable en dicha posición. 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 señal, 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 señal.

Page 58: Guia de VideoTutoriales HeTPro

58

Programa en C

#include<avr/io.h>

#include<util/delay.h>

int servo(int SH){ //Función para generar la señal PWM por software

int i,k;

PORTB|=_BV(PB0); //Se activa el bit 0 del PORTB

for (i = 0; i <= SH; i++) //Ciclo for de 0 hasta el valor introducido por la entrada

{_delay_us(1);} //de la función, con la variable SH, SH veces

PORTB&=~(_BV(PB0)); //Desactiva el bit 0 del PORTB

for (k = 0; k <= (10000-SH); k++) //Ciclo de 0 hasta 10000-SH

{_delay_us(1);} //Se repetirá 10000-SH veces

}

return 0; //Como la función no es void se regresa un 0

}

int main (void) //Inicio del programa

{

int ADC_val;

DDRB = 0xFF;

ADCSRA = 0xC0; //Se configura el ADC

ADMUX = 0x22;

while(1) { //Ciclo infinito

ADCSRA|=_BV(ADSC); //Iniciar conversión

ADC_val=((ADCH*200)/254)+50; //Tomar valor y ajustarlo para el servo

servo(ADC_val); //Llamar la función servo, con la entrada ADC_va, la cual

} //dentro de la función, será SH

}

Page 59: Guia de VideoTutoriales HeTPro

59

Detalles del programa

int servo(int SH){

Esta función es la que nos servirá para generar los pulsos necesarios para hacer funcionar el

servomotor, nótese que en este caso, a diferencia del ejemplo anterior, se está generando PWM a

través de la programación 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);}

Después de activar el primer bit del puerto B, va a mandar un nivel de voltaje alto a través 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 instrucción 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 señal

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, también variaría la frecuencia, por lo tanto, se ajusta

restando el valor de SH para que la proporción que SH varia, también lo haga el tiempo en bajo, y así

se logra que la frecuencia sea fija.

Page 60: Guia de VideoTutoriales HeTPro

60

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 conversión.

ADC_val=((ADCH*200)/254)+50;

Al igual que en el ejemplo del ADC se ajustan los valores, pero en este caso se le añade un offset

(+50) ya que el servo no inicia con una modulación del 0%.

servo(ADC_val);

Se manda a llamar la función servo, con el valor del ADC_val como entrada, el cual será el tiempo en

alto de la señal, proporcional al ciclo de trabajo.

Page 61: Guia de VideoTutoriales HeTPro

61

Como se puede ver en las imágenes, aunque el SH se modifique, el tiempo en bajo siempre se ajusta

para no modificar la frecuencia, ya que el periodo de la señal es constante.

Page 62: Guia de VideoTutoriales HeTPro

62

Pantalla LCD

Page 63: Guia de VideoTutoriales HeTPro

63

Pantalla LCD

Descripción

En este ejemplo se trabajara con una pantalla LCD de 16x2, se verán 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 comunicación de 8 bits, la cual es más sencilla

que la de 4 bits. También se hará uso de un potenciómetro como divisor de voltaje para regular el PIN

Vee el cual controla el contraste de la pantalla.

Diagrama Esquemático

Materiales

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

Page 64: Guia de VideoTutoriales HeTPro

64

Introducción Pantalla LCD Una pantalla de cristal liquido o LCD es una pantalla delgada y plana formada por un determinado número de pixeles monocromos (para este caso), colocados delante de una fuente luminosa. Una de las principales características de las pantallas LCD es su bajo consumo de energía eléctrica.

Pantalla JHD-162A

Configuración de los pines, tamaño 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 páginas de

la hoja de datos del controlador en donde se pueden ver varias de las instrucciones que el LCD maneja.

Page 65: Guia de VideoTutoriales HeTPro

65

Programa en C

#include <avr/io.h> #include <util/delay.h> #define Enable_On PORTC|=_BV(PC2) //Definiciones #define Enable_Off PORTC&=~_BV(PC2) #define RS_On PORTC|=_BV(PC0) #define RS_Off PORTC&=~_BV(PC0) #define RW_On PORTC|=_BV(PC1) #define RW_Off PORTC&=~_BV(PC1) #define Data PORTD #define DelayL _delay_ms(5); int i=0; void PORT_init (void){ //Función para inicializar puertos DDRC=0x07; DDRD=0xFF; PORTC=0x00; PORTD=0x00; } void LCD_init (void){ //Función para inicializar el LCD Data=0x0F; Enable_On; DelayL; Enable_Off; Data=0x00; RS_On; DelayL; } void WriteLCD(char text[15]){ //Función para escribir en el LCD RS_On; for (i=0;i<16; i++){ Data=text[i]; Enable_On; DelayL; Enable_Off; DelayL; } i=0; Data=0x00; RS_Off; }

Page 66: Guia de VideoTutoriales HeTPro

66

Detalles del programa

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

void ClearLCD(void){ //Función para limpiar la pantalla del LCD Data=0x01; Enable_On; DelayL; Enable_Off; } int main (void){ //Inicio del programa PORT_init(); LCD_init(); while(1){ WriteLCD("Hola mundo"); //Escribir en el LCD _delay_ms(1000); ClearLCD(); //Limpiar la pantalla del LCD _delay_ms(500); } }

Page 67: Guia de VideoTutoriales HeTPro

67

La directiva #define define una macro que proporciona un mecanismo de reemplazo de código 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 asignándole a Enable_On la sección 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 función 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 código son las siguientes que se encuentran representadas en la tabla.

Instruc \ Pin

E R/W RS Data DB0:7

1 0 0 0 0x0F 2 1 0 0 0

3 0 0 0 0

4 0 0 1 0

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

Page 68: Guia de VideoTutoriales HeTPro

68

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, carácter por carácter, por lo tanto tenemos que

separar nuestro texto en caracteres, esto lo logramos haciendo la función con una entrada de tipo

char (carácter), pero en este caso va a ser un vector, esto es una serie de caracteres o de chars, por

lo tanto cuando llamemos la función y a la entrada de la misma pongamos algún texto este se

guardara en un vector de caracteres, por ejemplo en texto "Hola Mundo":

Posicion 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Caracter H o l a M u n d o

Para habilitar la entrada de texto, se activa el pin de RS, a continuación el código 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 carácter que está en el vector text en la posición j, por ejemplo en el

primer caso inicia con j=0 en caso de haber escrito el texto "Hola Mundo", el vector quedaría como

en la tabla superior y cómo podemos ver la posición 0 tendría el carácter "H", después 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

E R/W RS Data DB0:7

1 0 0 1 0

2 0 0 0 Caracter

3 1 0 0 0

4 0 0 0 0

Page 69: Guia de VideoTutoriales HeTPro

69

void ClearLCD(void){ Data=0x01; Enable_On; DelayL; Enable_Off; }

Para limpiar la pantalla, se escribió la función 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

E R/W RS Data DB0:7

1 0 0 0 0x01

2 1 0 0 0

3 0 0 0 0

int main (void){ PORT_init(); LCD_init();

La función 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"); //Escribir en el LCD _delay_ms(1000); ClearLCD(); //Limpiar la pantalla del LCD _delay_ms(500); }

Dentro del ciclo while infinito, se llama a la función WriteLCD la cual escribe el texto "Hola Mundo"

en el LCD de la manera que se explico previamente, a continuación damos un retardo de 1000 ms y

posteriormente se limpia la pantalla llamando a la función ClearLCD a lo que esperamos 500 ms,

después de esto el ciclo inicia de nuevo y el texto vuelve a aparecer.

Page 70: Guia de VideoTutoriales HeTPro

70

Sensor ultrasónico

SRF08

Page 71: Guia de VideoTutoriales HeTPro

71

Sensor ultrasónico SRF08

Descripción

Para este ejemplo se hará uso de un sensor ultrasónico, este es un modulo independiente, el cual es

controlado vía I2C (Inter-Integrated Circuit) , este protocolo es también conocido como TWI (Two-

Wire-Interface). El sensor nos entrega la distancia directamente en centímetros, la que estaremos

visualizando a través de una serie de LEDs conectados al microcontrolador.

Diagrama Esquemático

Materiales

Sensor ultrasónico SRF08 6 Resistencias de 220 Ohms 1 Microcontrolador ATmega8 Programador USBasp V3.0

Page 72: Guia de VideoTutoriales HeTPro

72

Introducción Sensor SRF08

El SRF08 Es un medidor ultrasónico de distancias comercial, el cual hace uso de su transmisor y receptor para ofrecer una medida de distancia bastante precisa, el sensor también cuenta con un LDR la cual nos indica la intensidad luminosa del lugar donde lo tengamos. Algunas de las características del sensor son: -5v de alimentación -15mA de consumo de corriente -Frecuencia 40KHz -Rango de medición: de 3cm a 6mts -Conexión I2C -Sensor de iluminación LDR -Unidades soportadas: uS, mm, pulgadas. -Tamaño: 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 irán conectados al microcontrolador como se ve en el diagrama esquemático.

I2C o TWI I2C es un bus de comunicaciones en serie. Su nombre viene de Inter-Integrated Circuit (Circuitos Inter-Integrados). La versión 1.0 data del año 1992 y la versión 2.1 del año 2000, su diseñador es Philips. La velocidad es de 100Kbits por segundo en el modo estándar, aunque también permite velocidades de 3.4 Mbit/s. Es un bus muy usado en la industria, principalmente para comunicar microcontroladores y sus periféricos en sistemas integrados (Embedded Systems) y generalizando más para comunicar circuitos integrados entre si que normalmente residen en un mismo circuito impreso.

Page 73: Guia de VideoTutoriales HeTPro

73

La principal característica de I²C es que utiliza dos líneas para transmitir la información: una para los datos y por otra la señal de reloj. También es necesaria una tercera línea, pero esta sólo es la referencia GND. Las líneas se llaman: SDA: datos SCL: reloj GND:

En la imagen se puede ver un ejemplo de conexión 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 Decimal Instrucción Lectura/Escritura

0xE0 224 Dirección del sensor -

0x00 0 Inicializar el calculo Escritura

0x51 81 Modo cálculo distancia - Resultado en centímetros Escritura

0x03 3 Fija la ganancia analógica máxima en 103 Lectura

El sensor SRF08 tiene muchas más instrucciones y diferentes modos de operación, esta tabla solo contiene algunas de las instrucciones que el sensor maneja, esto con la finalidad de entender el código que va en el micrcontrolador, ya que más adelante se hará uso de estas direcciones.

Page 74: Guia de VideoTutoriales HeTPro

74

Programa en C

#include<avr/io.h>

#include<util/delay.h>

#include<avr/interrupt.h>

#include<util/twi.h>

#define Clock 1000000 //Frecuencia de trabajo del microcontrolador

#define SRF02 0xE0;

void TWI_config(unsigned long int); //Declarar las funciones

void i2c_transmit(char,char,char);

char i2c_read(char,char);

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; // Registro para la frecuencia de SCL

TWSR=(0<<TWPS1)+(0<<TWPS0); // Preescala 1

}

Page 75: Guia de VideoTutoriales HeTPro

75

char i2c_read(char address, char reg)

{

char read_data = 0;

TWCR = 0xA4; // Mandar el bit de inicio para el bus I2C

while(!(TWCR & 0x80)); // Esperando la confirmación

TWDR = address; // Cargar dirección (adress) en el dispositivo

TWCR = 0x84; // Transmitir

while(!(TWCR & 0x80)); // Esperar confirmación de la transmisión

TWDR = reg; // Enviar número de registro a leer

TWCR = 0x84; // Transmitir

while(!(TWCR & 0x80)); // Esperar confirmación de la transmisión

TWCR = 0xA4; // Volver a mandar un bit de inicio

while(!(TWCR & 0x80)); // Esperar confirmación de la transmisión

TWDR = address+1; // Transmitir dirección por I2C con la lectura habilitada

TWCR = 0xC4; // Borrar la bandera de interrupción de transmisión

while(!(TWCR & 0x80)); // Esperar confirmación de la transmisión

TWCR = 0x84; // Transmitir (Solicitud del último byte)

while(!(TWCR & 0x80)); // Esperar confirmación de la transmisión

read_data = TWDR; // Tomar el dato

TWCR = 0x94; // Mandar un bit de paro al bus I2C

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 confirmación de la transmisión

TWDR = address; // Cargar dirección (adress) en el dispositivo

TWCR = 0x84; // Transmitir

while(!(TWCR & 0x80)); // Esperar confirmación de la transmisión

TWDR = reg;

TWCR = 0x84; // Transmitir

while(!(TWCR & 0x80)); // Esperar confirmación de la transmisión

TWDR = data;

TWCR = 0x84; // Transmitir

while(!(TWCR & 0x80)); // Esperar confirmación de la transmisión

TWCR = 0x94; // Mandar un bit de paro al bus I2C

}

Page 76: Guia de VideoTutoriales HeTPro

76

Detalles del programa

#include<avr/io.h>

#include<util/delay.h>

#include<avr/interrupt.h>

#include<util/twi.h>

Se llaman las librerías 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 continuación se usaran. Es importante notar en caso de escribir las

funciones después del main, es necesario declararlas.

TWI_config(100000);

Se llama a la función TWI_config con la entrada 1000000 que será la frecuencia del

microcontrolador, más adelante se explicara esta función.

i2c_transmit(0xE0,0,0x51);

_delay_ms(75);

valor = i2c_read(0xE0,3);

PORTD = valor;

_delay_ms(100);

Se puede ver en esta sección de código que se transmite por el I2C, y se lee el dato el cual se

muestra a través del puerto D. las funciones de transmitir y de leer se explican a continuación.

void TWI_config(unsigned long int frecuencia)

{

TWBR = ((Clock/frecuencia) - 16)/8;

TWSR=(0<<TWPS1)+(0<<TWPS0);

}

Page 77: Guia de VideoTutoriales HeTPro

77

El TWBR selecciona el factor de división de la frecuencia del SCL en modo maestro

Al registro de estado TWSR se le está escribiendo la instrucción (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; // Mandar el bit de inicio para el bus I2C

while(!(TWCR & 0x80)); // Esperando la confirmación

TWDR = address; // Cargar dirección (adress) en el dispositivo

TWCR = 0x84; // Transmitir

while(!(TWCR & 0x80)); // Esperar confirmación de la transmisión

TWDR = reg; // Enviar número de registro a leer

TWCR = 0x84; // Transmitir

while(!(TWCR & 0x80)); // Esperar confirmación de la transmisión

Page 78: Guia de VideoTutoriales HeTPro

78

TWCR = 0xA4; // Volver a mandar un bit de inicio

while(!(TWCR & 0x80)); // Esperar confirmación de la transmisión

TWDR = address+1; // Transmitir dirección por I2C con la lectura habilitada

TWCR = 0xC4; // Borrar la bandera de interrupción de transmisión

while(!(TWCR & 0x80)); // Esperar confirmación de la transmisión

TWCR = 0x84; // Transmitir, nack (Solicitud del último byte)

while(!(TWCR & 0x80)); // Esperar confirmación de la transmisión

read_data = TWDR; // Tomar el dato

TWCR = 0x94; // Mandar un bit de paro al bus I2C

return read_data;

}

La función i2c_read, lee el dato que manda el sensor, entre las cosas a destacar en esta función son

el uso del registro TWCR y del TWDR:

El TWCR se usa para controlar la operación del TWI. En él se habilita el TWI, se inicializa el acceso

con la condición de inicio, genera una condición de paro, entre otras cosas

En modo de transmisión, el TWDR contiene el siguiente byte para ser transmitido, y en modo de

recepción contiene el ultimo byte en ser recibido.

Dentro del la funcion i2c_read se encuentran varias instrucciones importantes las cuales son:

TWCR = 0xA4;

Esta instrucción nos indica que los bits 2, 5 y 7 los cuales son TWEN, TWSTA y TWINT

respectivamente, del registro TWCR están habilitados.

TWEN: Habilita y activa la comunicación TWI (I2C).

TWSTA: Al habilitarlo, se configura el TWI del microcontrolador como modo maestro.

TWINT: Al escribirle un 1 lógico, se limpia la bandera de interrupción.

Page 79: Guia de VideoTutoriales HeTPro

79

while(!(TWCR & 0x80));

El 0x80 en el TWCR corresponde a la bandera del bit TWINT, el ciclo espera a la bandera de

confirmación.

TWDR = address;

Se le asigna la variable address, la cual, como se puede ver en el código, tiene el valor de 0xE0. Este

valor es la dirección del dispositivo con el que se está comunicando. En este caso el sensor

ultrasónico responde a la dirección 0xE0

TWCR = 0x84;

Se limpia la bandera y habilita la comunicación.

TWDR = reg;

Envía 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 analógica máxima a 103. La finalidad de poder limitar la ganancia máxima 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 también 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 confirmación de la transmisión

TWDR = address; // Cargar dirección (adress) en el dispositivo

TWCR = 0x84; // Transmitir

while(!(TWCR & 0x80)); // Esperar confirmación de la transmisión

TWDR = reg;

TWCR = 0x84; // Transmitir

while(!(TWCR & 0x80)); // Esperar confirmación de la transmisión

TWDR = data;

TWCR = 0x84; // Transmitir

while(!(TWCR & 0x80)); // Esperar confirmación de la transmisión

Page 80: Guia de VideoTutoriales HeTPro

80

TWCR = 0x94; // Mandar un bit de paro al bus I2C

}

Las instrucciones de la función para transmitir como podemos ver son casi las mismas que para la

función leer, pero no perdamos de vista que al mandar llamar cada función se le asignan distintos

valores, entre las principales instrucciones a destacar se encuentran:

TWDR = reg;

A diferencia de la función read, el registro en este caso tiene un valor de 0 el cual le indica al sensor

que inicie la sesión de cálculo 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 cálculo de distancia y este nos da un resultado en centímetros.

Page 81: Guia de VideoTutoriales HeTPro

81

Comunicación serial

USART

Page 82: Guia de VideoTutoriales HeTPro

82

Comunicación Serial USART

Descripción

En este proyecto, se verá una de las maneras de entablar comunicación del microcontrolador con la

computadora, para poder realizar esta práctica se requerirá del uso de varios componentes los

cuales describiremos a continuación, la comunicación serial es una de las maneras más sencillas de

comunicar nuestro microcontrolador hacia el exterior, ya sea con una computadora o con algún 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. Básicamente 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

comunicación de cualquier proceso, en su momento es posible mandar un dato, aplicarle algún

proceso o algoritmo y regresar el resultado.

Diagrama Esquemático

Materiales

Max 232 4 capacitores de 10 uF 1 Microcontrolador ATmega8

Page 83: Guia de VideoTutoriales HeTPro

83

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

Introducción Características de la USART del ATmega8

La USART o Universal Synchronous and Asynchronous serial Receiver and Transmitter es un dispositivo de comunicación serial altamente flexible, sus principales características son: -Operación Full Dulpex -Registros de transmisión y recepción independientes -Operación síncrona o asíncrona -Generador de Baud Rate de alta resolución -Detección de error -Filtro de ruido -Modo de comunicación multiproceso -Doble velocidad en modo de comunicación asíncrono Diagrama a bloques de la USART El manejo de la comunicación serial presenta muchos beneficios, entre los que destacan, el control de sistemas a través de la computadora realizando cálculos complejos, visualizando y graficando datos, entre otros. Es importante destacar que también existen muchos programas aparte de la hyperterminal los cuales pueden entablar comunicación serial con el microcontrolador, programas como MatLab, LabVIEW, TeraTerm entre otros.

Page 84: Guia de VideoTutoriales HeTPro

84

Programa en C

Detalles del programa

#include<avr/io.h>

#include<util/delay.h>

int dato;

Se inicia el programa con las librerías respectivas, y se declara una variable "dato".

#include<avr/io.h>

#include<util/delay.h>

int dato;

void InitUART( unsigned char baudrate ) { //Configurando la UART

UBRRL = baudrate; //Seleccionando la velocidad

UCSRB = (UCSRB | _BV(RXEN) | _BV(TXEN)); //Habilitando la transmisión y recepción

}

unsigned char ReceiveByte( void ){ //Función para recibir un byte

while ( !(UCSRA & (1<<RXC)) ); //Esperar la recepción

return UDR; //Retornar el dato tomado de la UART

}

void TransmitByte( unsigned char data ) { //Funcion para transmitir dato

while ( !( UCSRA & (1<<UDRE)) ); //Esperar transmision completa

UDR = data; //Depositar el dato para transmitirlo

}

int main (void) {

InitUART( 51 ); //Inicializar la UART

while(1){

dato=ReceiveByte(); //Recibir un dato de la UART

TransmitByte(dato); //Mandar el mismo dato

}

}

Page 85: Guia de VideoTutoriales HeTPro

85

void InitUART( unsigned char baudrate ) {

UBRRL = baudrate;

UCSRB = (UCSRB | _BV(RXEN) | _BV(TXEN));

}

Se declara la función 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 comunicación, 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 asíncrono normal, tomamos la primeras formulas para calcular el UBRR y

después los Baudios. Primero resolvemos la del UBRR para obtener el valor calculándolo con 9600

baudios, después calculamos los baudios con el valor del UBRR (Pero el valor entero ya que en los

registros solo se pueden asignar números enteros), y el resultado nos dará los baudios reales.

𝑈𝐵𝑅𝑅 =𝑓𝑜𝑠𝑐

16𝐵𝐴𝑈𝐷− 1 =

8000000

16 ∗ 9600− 1 = 𝟓𝟏.𝟎𝟖𝟑𝟑𝟑

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.

𝐵𝐴𝑈𝐷 =𝑓𝑜𝑠𝑐

16 𝑈𝐵𝑅𝑅+ 1 =

8000000

16 51 + 1 = 𝟗𝟔𝟏𝟓.𝟑𝟖𝟒𝟔

Page 86: Guia de VideoTutoriales HeTPro

86

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 pequeño. Estas operaciones previamente

realizadas es para conocer un poco más el funcionamiento del registro y el cómo calcular el valor

respecto a algún baud rate deseado, pero también hay una tabla en la hoja de datos con los valores

más 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 código se habilitan los bits RXEN y TXEN los cuales habilitan el transmisor y el

receptor de la USART además de los pines correspondientes RXD y TXD.

Page 87: Guia de VideoTutoriales HeTPro

87

unsigned char ReceiveByte( void ){ //Función para recibir un byte

while ( !(UCSRA & (1<<RXC)) ); //Esperar la recepción

return UDR; //Retornar el dato tomado de la UART

}

El uso del registro UCSRA para la función 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 función 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 función de recibir un byte esta espera el UDRE en el UCSRA el cual indica que el buffer

de transmisión 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 función espera recibir un dato, una vez que se recibe el dato,

este mismo sin sufrir modificación alguna es mandado a través 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

Page 88: Guia de VideoTutoriales HeTPro

88

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 Variable char Terminal

Dec Bin Hex 97 0b01100001 0x61 'a' a 65 0b01000001 0x41 'A' A 51 0b00110011 0x33 '3' 3

Page 89: Guia de VideoTutoriales HeTPro

89