Escolar Documentos
Profissional Documentos
Cultura Documentos
FACULTAD DE INGENIERÍA
MANUAL DE PRÁCTICAS
PROGRAMACIÓN AVANZADA
MICROCONTROLADORES
Las prácticas deberán ser entregadas funcionando al 100%, y se debe entregar un reporte que
cumpla con las siguients condiciones:
Grupo 31 Grupo 32
Practica 1 28 enero 2017 26 enero 2017
Practica 2 25 febrero 2017 23 febrero 2017
Practica 3 18 marzo 2017 16 marzo 2017
Practica 4 1 abril 2017 30 marzo 2017
Practica 5 22 abril 2017 20 abril 2017
Practica 6 13 mayo 2017 11 mayo 2017
Practica 7 3 junio 2017 1 de junio 2017
PRÁCTICA 1. Introducción General a los Microcontroladores
1.1 OBJETIVO
Aprender a instalar las herramientas de software para programar un microcontrolador, así como
implementar el sistema mínimo de un microcontrolador y utilizando el microcontrolador Atmega 328P,
para controlar hardware.
El uso de los microcontroladores se ha extendido de manera exponencial hoy en día. Sus usos
más comunes los podemos ver alrededor de nosotros día con día, por lo que resulta muy importante
para un ingeniero en computación aprender a utilizar tales dispositivos e interactuar con ellos a través
de uns computadora personal, para el control y monitoreo de procesos.
1.2.2 El microcontrolador.
• Arquitectura.
• Velocidad de procesamiento en Número de Instrucciones por Segundo (IPS).
• Número de multiplicadores implementados en hardware.
• Capacidad de memoria para usuario y para programa, en bytes.
• Número de ciclos de escritura/borrado para la memoria Flash.
• Tiempo de retención del dato.
• Seguridad para evitar el robo de software.
• Periféricos disponibles. Por ejemplo, puertos, temporizadores, convertidor A/D,
comunicación serial, entre otros.
• Número de bits de datos.
5
Práctica 1: Introducción General a los Microcontroladores
0x0000 0x0000
32 Registros
0x001F
0x0020 Sección de
memoria
64 Registros
Flash para
de I/O
programación
0x005F del µC
0x0060
160
Registros de
I/O
extendidos
0x00FF
0x0100
Memoria Sección
interna Flash para
SRAM memoria de
(1048 x 8) arranque
0x08FF 0x3FFF
Memoria de Memoria de
Datos Programa
6
Práctica 1: Introducción General a los Microcontroladores
Los puertos del µC se consideraciones como puertos de propósito general, es decir, podemos
utilizarlos como puertos de I/O, o bien, configurarlos para un uso especial. Los usos especiales se
verán posteriormente en otras prácticas.
Para cada puerto se encuentran asociados dos registros. Configuración de terminales, el cual se
usa para indicar que pines serán entradas y cuales van a funcionar como salida. Escritura/lectura
externa, es decir, se utiliza para escribir datos del interior del µC hacia el exterior, o bien, en sentido
contrario.
PINB: Registro de Lectura de Datos del Puerto B. Se utiliza para leer datos de elementos externos
al µC. Solamente se pueden leer los bits que han sido configurados como lectura en el DDRB.
Bit 7 6 5 4 3 2 1 0
0x03 (0x23) PB7 PB6 PB5 PB4 PB3 PB2 PB1 PB0
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Initial Value N/A N/A N/A N/A N/A N/A N/A N/A
DDRB: Registro de Configuración de Dirección de Datos del Puerto B. Se utiliza para configurar
cada una de las terminales del puerto del µC. Si se escribe un ‘1’, la terminal se configura como
salida. El ‘0’ configura la terminal como entrada. Por ejemplo, si en el bit 6 se escribe un ‘1’ y el resto
permanece en ‘0’, la terminal 6 del puerto B (PB6) va a funcionar como salida de datos y solamente
se puede leer su valor a través del PINB. El resto funciona como entrada de datos.
Bit 7 6 5 4 3 2 1 0
0x04 (0x24) PB7 PB6 PB5 PB4 PB3 PB2 PB1 PB0
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Initial Value 0 0 0 0 0 0 0 0
PORTB: Registro de Salida de Datos del Puerto B. Se utiliza para escribir datos al exterior del µC.
La escritura de bits funciona solamente con aquellos que fueron configurados como salidas en el
DDRB.
Bit 7 6 5 4 3 2 1 0
0x05 (0x25) PB7 PB6 PB5 PB4 PB3 PB2 PB1 PB0
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Initial Value 0 0 0 0 0 0 0 0
Bit 7 6 5 4 3 2 1 0
0x06 (0x26) PC7 PC6 PC5 PC4 PC3 PC2 PC1 PC0
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Initial Value N/A N/A N/A N/A N/A N/A N/A N/A
Bit 7 6 5 4 3 2 1 0
0x07 (0x27) PC7 PC6 PC5 PC4 PC3 PC2 PC1 PC0
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Initial Value 0 0 0 0 0 0 0 0
7
Práctica 1: Introducción General a los Microcontroladores
Bit 7 6 5 4 3 2 1 0
0x08 (0x28) PC7 PC6 PC5 PC4 PC3 PC2 PC1 PC0
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Initial Value 0 0 0 0 0 0 0 0
Bit 7 6 5 4 3 2 1 0
0x09 (0x29) PD7 PD6 PD5 PD4 PD3 PD2 PD1 PD0
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Initial Value N/A N/A N/A N/A N/A N/A N/A N/A
Bit 7 6 5 4 3 2 1 0
0x0A (0x2A) PD7 PD6 PD5 PD4 PD3 PD2 PD1 PD0
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Initial Value 0 0 0 0 0 0 0 0
Bit 7 6 5 4 3 2 1 0
0x0B (0x2B) PD7 PD6 PD5 PD4 PD3 PD2 PD1 PD0
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Initial Value 0 0 0 0 0 0 0 0
1.3 DESARROLLO:
8
Práctica 1: Introducción General a los Microcontroladores
1.3.2 Programe el microcontrolador utilizando el siguiente código, para leer el dato digital de los 6
interruptores conectados al Puerto D, y el valor digital se debe exhibir en los led’s conectados
al Puerto C
#include <avr/io.h>
int main(void)
{
Ports_Setup(); //Mandamos llamar la función Ports_Setup()
while(1)
{
PORTC = PIND; //El Puerto D es leido y desplegado a través del Puerto C
}
}
1.3.4 Utilice el siguiente código para programar el microcontrolador. Se debe mostrar un contador
binario.
9
Práctica 1: Introducción General a los Microcontroladores
void Ports_Setup();
void Ports_setup()
{
DDRC = 0xFF; //Colocamos todo el puerto de Salida
}
int main(void)
{
Ports_setup();
while(1)
{
_delay_ms(200); //Espera 200 ms
PORTC++; //Despliega el dato en el Puerto C e incrementa el puerto
//C después de desplegarlo
}
}
#include <avr/io.h>
10
Práctica 1: Introducción General a los Microcontroladores
#include <util/delay.h>
void ports_setup();
void ports_setup()
{
DDRC = 0xFF;
PORTC = 0x00;
}
int main(void)
{
ports_setup();
while(1)
{
PORTC = 0x21;
_delay_ms(8000);
PORTC = 0x22;
_delay_ms(2000);
PORTC = 0xC;
_delay_ms(8000);
PORTC = 0x14;
_delay_ms(2000);
}
}
1.3.7 Implemente el siguiente circuito, para controlar el arranque de un motor de corriente directa.
Se omite las conexiones de alimentaciones y del cristal, para hacer más simple el diagrama, si
embargo, no olvide conectar esas etapas. Utilice un motor que consuma menos de 500 mA de
corriente. Vm es el voltaje de alimentación del motor.
11
Práctica 1: Introducción General a los Microcontroladores
void ports_setup();
void ports_setup()
{
DDRC = 0xFF;
PORTC = 0x00;
}
int main(void)
{
ports_setup();
while(1)
{
PORTC = 0x01;
_delay_ms(2000);
PORTC = 0x00;
_delay_ms(2000);
}
}
1.3.9 Modifique el ejemplo del semáforo para controlar 3 semáforos y un semáforo peatonal.
1.3.10 Ahora, cambie el motor por un relevador, y modifique el código y el hardware, para encender
un foco de 120 Vac, cuando se detecte la falta de luz ambiental. Se recomienda utilizar una
fotoresistencia.
1.3.11 En base a los ejercicios de los puntos 1 a 3, desarrolle los siguientes ejercicios:
a. Genere la siguiente secuencia en el puerto C: 000001, 000010, 000100, 001000,
010000, 100000 y se repite.
b. Modifique la secuencia del inciso b, para que el desplazamiento del 1 sea en las dos
direcciones, es decir: 000001, 000010, 000100, 001000, 010000, 100000, 010000,
001000, 000100, 000010, y se repite la secuencia.
c. Implemente un contador del 0 al 9 en un exhibidor de 7 segmentos.
d. Modifique el contador, para que una vez que llegue a 10, comience a contar
descendente. Mientras la cuenta desciende el motor debe estar encendido. Cuando la
cuenta llega a cero, se apaga el motor y comienza a contar ascendente.
1.3.12 Modifique el circuito del microcontrolador para controlar el sentido de giro de un motor de CD.
1.3.13 En base al ejercicio 5a y 5b, implemente un circuito para controlar el giro de un motor a pasos
unipolar.
1.3.14 En base al ejercicio 5a y 5b, implemente un circuito para controlar el giro de un motor a pasos
bipolar.
12
Práctica 1: Introducción General a los Microcontroladores
13
PRÁCTICA 2. Manejo de interrupciones externas INT0 e INT1.
2.1 OBJETIVO: Aprender a utilizar las interrupciones externas INT0 e INT1 en el microcontrolador, y
utilizarlas en tareas relacionadas con aplicaciones de control.
Los principales registros relacionados con la configuración de las interrupciones son los
siguientes:
Bit 7 6 5 4 3 2 1 0
(0x69) - - - - ISC11 ISC10 ISC01 ISC00
Read/Write - - - - R/W R/W R/W R/W
Initial Value - - - - 0 0 0 0
Estos bits sirven para configurar el nivel y borde de activación de las interrupciones INT1 e
INT0, de acuerdo a la siguiente tabla.
Este registro es utilizado para habilitar y deshabilitar (apagar y encender) las interrupciones
externas INT0 e INT1.
Bit 7 6 5 4 3 2 1 0
INT1 INT0 - - - - - -
Read/Write R/W R/W - - - - - -
Initial Value 0 0 - - - - - -
Estos bits sirven para habilitar las interrupciones externas. Si se escribe un ‘1’ lógico, se
habilita la interrupción correspondiente, si se escribe un ‘0’, la interrupción queda deshabilitada.
Observe la siguiente tabla.
Este registro se relaciona con las banderas de interrupción. Cuando una bandera se pone en
‘1’ lógico, indica que se ha realizado una petición de interrupción en la terminal INT correspondiente.
Mientras la, correspondiente a la interrupción INT1. Cuando la bandera se pone en ‘1’ y está
15
Práctica 2: Manejo de interrupciones externas INT0 e INT1
Bit 7 6 5 4 3 2 1 0
INTF1 INTF0 - - - - - -
Read/Write R/W R/W - - - - - -
Initial Value 0 0 - - - - - -
Estos bits sirven para habilitar las interrupciones externas. Si se escribe un ‘1’ lógico, se
habilita la interrupción correspondiente, si se escribe un ‘0’, la interrupción queda deshabilitada.
Observe la siguiente tabla.
2.3 DESARROLLO:
2.3.1 Implemente el siguiente circuito, para el manejo de las interrupciones INT0 e INT1.
void Ports_Setup()
{
DDRD = 0x00; //Se configura el puerto D como entrada
DDRC = 0xFF; //Se configura el puerto C como salida
PORTC = 0x00; //Limpiamos el puerto C
}
void External_Interrupts_Setup()
{
EICRA = (1<<ISC11)|(0<<ISC10)|(1<<ISC01)|(0<<ISC00); //La interrupción 0 es
//configurada para sensar flancos de bajada, la interrupción
//1 se configura para sensar flancos de bajada
EIMSK = (1<<INT1)|(1<<INT0); //Las interrupciones 0 y 1 son habilitadas
EIFR = (0<<INTF1)|(0<<INTF0); //Las banderas de interrupciones son borradas
PCICR = (0<<PCIE2)|(0<<PCIE1)|(0<<PCIE0); //Son deshabilitadas las
//interrupciones externas tipo "Pin-Change"
PCIFR = (0<<PCIF2)|(0<<PCIF1)|(0<<PCIF0); //Son borradas las banderas de las
//interrupciones tipo "Pin-Change"
PCMSK2 = 0x00; //Se deshabilitan las interrupciones Pin-Change para PCINT[23:16]
PCMSK1 = 0x00; //Se deshabilitan las interrupciones Pin-Change para PCINT[14:8]
PCMSK0 = 0x00; //Se deshabilitan las interrupciones Pin-Change para PCINT[7:0]
}
ISR(INT0_vect,ISR_NAKED)
{
PORTC++; //Se muestra el valor del puerto C y después se incrementa su valor
reti(); //Regreso de la interrupcion
}
ISR(INT1_vect,ISR_NAKED)
{
PORTC--; //Se muestra el valor del Puerto C y después decrementa su valor
reti(); //Regreso de la interrupcion
}
int main(void)
{
Ports_Setup();
External_Interrupts_Setup();
sei();
while(1)
{
}
}
2.3.3 Arme el siguiente circuito, el cual utiliza señales acopladas ópticamente (optoacopladores).
Considere que las tierras del motor son diferentes a las tierras del microcontrolador, esto
quiere decir que la tierra del motor y del microcontrolador NO deben unirse. Escriba un
programa que permita encender un motor cuando se active la interrupción INT1. Se debe
apagar una vez que la misma interrupción se vuelve a activar. El otro motor debe controlarse
utilizando la interrupción INT0.
17
Práctica 2: Manejo de interrupciones externas INT0 e INT1
2.3.4 Utilizando el mismo principio de señales aisladas ópticamente, investigue sobre un circuito
que permita controlar el sentido de giro de un motor, ármelo y conéctelo en lugar de los dos
motores del punto 3 de esta práctica.
2.3.5 Arme un circuito digital basado en el microcontrolador de forma que el funcionamiento sea el
siguiente:
a. Inicie el conteo en 0.
b. Al activar la interrupción INT0, el contador comienza a contar automáticamente en
forma ascendente, cada 250 ms.
c. Al activar la interrupción INT1, el contador cambia de dirección de conteo, es decir,
descendente, con el mismo intervalo de tiempo. Cada que se active INT1, se invierte el
sentido de conteo.
d. Al activar nuevamente la interrupción INT0, se detiene el conteo, sin perder la cuenta
ni el sentido de cuenta. Para continuar el conteo, se debe volver a activar INT0.
e. El conteo se debe mostrar en el exhibidor de 7 segmentos.
2.3.6 Arme un circuito que controle un motor a pasos unipolar, diseñe el programa y pruebe su
funcionamiento. Si el motor consume más de 100 mA, utilice el pricipio de señales opto-
acopladas.
2.3.7 Arme un circuito que controle un motor a pasos bipolar, diseñe el programa y pruebe su
funcionamiento. Si el motor consume más de 100 mA, utilice el principio de señales opto-
acopladas.
2.3.8 Modifique el ejercicio del semáforo, para que el semáforo peatonal se active únicamente por
medio de interrupción. Es decir, el semáforo peatonal no se activa si no existe petición de un
usuario.
18
PRÁCTICA 3. Manejo del Temporizador
3.1 OBJETIVO: Aprender a utilizar el temporizador como sistema de medición de tiempo, y utilizarlas
en tareas de control de secuencias de tiempo.
Bit 7 6 5 4 3 2 1 0
COM1A1 COM1A0 COM1B1 COM1B0 FOC1A FOC1B WGM11 WGM10
Read/Write R/W R/W R/W R/W W W R/W R/W
Initial Value 0 0 0 0 0 0 0 0
Modo Salida de Comparación, Modo PWM Rápido y PWM Corrección de Fase y Corrección de Fase
y Frecuencia.
• Bit 1:0 – WGM11:10: Modo de Generación de Forma de Onda (WGM, Waveform Generation
Mode)
Se combinan con los bits WGM13:12 del registro TCCR1B, y sirven para controlar la secuencia
del contador, la fuente del máximo valor de la cuenta (TOP), y el tipo de generación de forma de onda
a ser usada. En la tabla siguiente se observa las distintas combinaciones.
20
Práctica 3: Manejo del Temporizador
Mode WGM13 WGM12 WGM11 WGM10 Modo de Operación TOP Cambio Encendido
(CTC1) (PWM11) (PWM10) Temporizador/Contador en bandera
OCR1x TOV1
0 0 0 0 0 Normal 0xFFFF Inmediato MAX
1 0 0 0 1 PWM, fase corregida, 8 bit 0x00FF TOP BOTTOM
2 0 0 1 0 PWM, fase corregida, 9 bit 0x01FF TOP BOTTOM
3 0 0 1 1 PWM, fase corregida, 10 0x03FF TOP BOTTOM
bit
4 0 1 0 0 CTC OCR1A Inmediato MAX
5 0 1 0 1 Rápido PWM, 8 bit 0x00FF BOTTOM TOP
6 0 1 1 0 Rápido PWM, 9 bit 0x01FF BOTTOM TOP
7 0 1 1 1 Rápido PWM, 10 bit 0x03FF BOTTOM TOP
8 1 0 0 0 PWM, corrección de fase ICR1 BOTTOM BOTTOM
y frecuencia
9 1 0 0 1 PWM, corrección de fase OCR1A BOTTOM BOTTOM
y frecuencia
10 1 0 1 0 PWM, corrección de fase ICR1 TOP BOTTOM
11 1 0 1 1 PWM, corrección de fase OCR1A TOP BOTTOM
12 1 1 0 0 CTC ICR1 Inmediato MAX
13 1 1 0 1 Reservado - - -
14 1 1 1 0 Rápido PWM ICR1 BOTTOM TOP
15 1 1 1 1 Rápido PWM OCR1A BOTTOM TOP
Bit 7 6 5 4 3 2 1 0
ICNC1 ICES1 - WGM13 WGM12 CS12 CS11 CS10
Read/Write R/W R/W R R/W R/W R/W R/W R/W
Initial Value 0 0 0 0 0 0 0 0
• Bit 6 – ICES1: Selección de Borde de Captura de Entrada (Input Capture Edge Select)
ICES1 = 0 : Borde negativo
ICES1 = 1 : Borde positivo
• Bit 4:3 – WGM13:2: Modo de Generación de Forma de Onda (Waveform Generation Mode)
Ver la descripción del registro TCCR1A.
Registro utilizado para llevar la cuenta del temporizador, tomando como base la señal de reloj
configurada en CS1.
Bit 7 6 5 4 3 2 1 0
TCNT1H TCNT1[15:8]
TCNT1L TCNT1[7:0]
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Initial Value 0 0 0 0 0 0 0 0
Registro utilizado para realizar la comparación con el contenido del registro TCNT1, y cuando
ambos registros se igualan, generar la salida configurada en el registro TCCR1A.
Bit 7 6 5 4 3 2 1 0
OCR1AH OCR1A[15:8]
OCR1AL OCR1A[7:0]
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Initial Value 0 0 0 0 0 0 0 0
Registro utilizado para realizar la comparación con el contenido del registro TCNT1, y cuando
ambos registros se igualan, generar la salida configurada en el registro TCCR1B.
Bit 7 6 5 4 3 2 1 0
OCR1AH OCR1B[15:8]
OCR1AL OCR1B[7:0]
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Initial Value 0 0 0 0 0 0 0 0
Cuando se activa la terminal ICP1 del microcontrolador, el valor del registro TCNT1 pasa a este
registro. Este registro puede ser utilizado para la configuración del valor TOP del contador.
Bit 7 6 5 4 3 2 1 0
ICR1H ICR1[15:8]
ICR1L ICR1[7:0]
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Initial Value 0 0 0 0 0 0 0 0
3.3 DESARROLLO.
3.3.1 Implemente el siguiente circuito, el cual se utiliza para controlar un servomotor, utilizando la
técnica de PWM. Observe la señal PWM en un osciloscopio para que se reporte la forma de
onda.
22
Práctica 3: Manejo del Temporizador
void Ports_Setup()
{
DDRB = 0x02; //Se configura el pin OC1A como salida para el PWM rápido
}
void Timer1_Setup()
{
//PWM Rapido No Inverso, OC1B desconectado,
//TOP especificado por el registro ICR1
TCCR1A = (1<<COM1A1)|(0<<COM1A0)|(0<<COM1B1)|(0<<COM1B0)|
(1<<WGM11)|(0<<WGM10);
//Colocamos el Timer1 Detenido
TCCR1B = (0<<ICNC1)|(0<<ICES1)|(1<<WGM13)|(1<<WGM12)|(0<<CS12)|
(0<<CS11)|(0<<CS10);
23
Práctica 3: Manejo del Temporizador
void Timer1_Start()
{
//Encendemos el Timer con un prescalador de 8
TCCR1B = (0<<ICNC1)|(0<<ICES1)|(1<<WGM13)|(1<<WGM12)|
(0<<CS12)|(1<<CS11)|(0<<CS10);
}
int main(void)
{
Ports_Setup(); //Se llama la función de configuración de los puertos
Timer1_Setup(); //Se llama la función de configuración del Timer 1
Timer1_Start(); //Se enciende el Timer 1
OCR1A = 5000; //Ciclo util a 25%
while(1)
{
}
}
3.3.3 Modifique el código, para controlar la velocidad de un motor a pasos unipolar, utilizando el
temporizador en lugar de la función delay.
3.3.4 Modifique el código para controlar la velocidad y dirección de dos motores de DC, utilizando
las interrupciones para el arranque y paro de los motores. El funcionamiento de cada motor
debe ser de manera independiente.
3.3.5 Utilizando el modo de captura de entrada, realice un programa para el microcontrolador para
medir el tiempo de ocurrencia entre dos eventos. Lea la sección INPUT CAPTURE UNIT,
página 117, de la hoja de datos del Atmega328P. Así mismo, la sección de registros a partir
de la página 131.
3.3.6 Investigue que es un encoder y los tipos de encoder que existen, así como su principio de
funcionamiento.
3.3.7 Implemente un programa que maneje un encoder incremental/decremental.0
24
PRÁCTICA 4. Conversión Analógica/Digital (ADC)
4.1 OBJETIVO
Aprender a configurar los registros del convertidor analógico-digital, para digitalizar señales
analógicas.
• Resolución de 10 bit
• Presición absoluta de ±2 LSB
• Tiempo de conversión de 13 μs a 260 μs
• Velocidad de conversión de 15 kSPS a máxima resolución
• 8 canales sencillos de entrada multiplexado
• 7 Differential Input Channels
• 2 Differential Input Channels with Optional Gain of 10x and 200x
• Intervalo del voltaje de entrada analógico de 0 a VCC
• Referencia de voltaje seleccionable de 2.56V
• Modo de carrera libre o conversión sencilla
• Inicio de conversión ADC por disparo automático o por fuentes de interrupción
• Interrupción de conversión ADC completa
• Cancelador de ruido en modo de suspensión
La siguiente figura muestra un diagrama a bloques del sistema de ADC del dispositivo ATMega328P.
Práctica 3: Manejo del Temporizador
Bit 7 6 5 4 3 2 1 0
REFS1 REFS0 ADLAR MUX4 MUX3 MUX2 MUX1 MUX0
Read/Write R/W R/W R R/W R/W R/W R/W R/W
Initial Value 0 0 0 0 0 0 0 0
Bit 7 6 5 4 3 2 1 0
ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
Read/Write R/W R/W R R/W R/W R/W R/W R/W
Initial Value 0 0 0 0 0 0 0 0
1 ∶ 𝐴𝐴𝐴𝐴𝐴𝐴 ℎ𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎
𝐴𝐴𝐴𝐴𝐴𝐴𝐴𝐴 = �
0 ∶ 𝐴𝐴𝐴𝐴𝐴𝐴 𝑑𝑑𝑑𝑑𝑑𝑑ℎ𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎
26
Práctica 3: Manejo del Temporizador
El bit ADSC se lee como ‘1’ lógico mientras se está convirtiendo un dato, y cuando termina la convesión,
automáticamente retorna a ‘0’ lógico.
El ADC comenzará la conversión en el borde positivo de la señal de disparo seleccionada. La fuente de disparo
es seleccionada configurando los bit ADTS del registro ADCSRB.
Este bit se pone en 1 cuando el ADC ha realizado una conversión completa, y el registro de datos ha sido
actualizado. Se borra escribiendo un 1 lógico en la bandera, o por hardware cuando se ejectua una interrupción
de conversión completa.
Cuando se escribe un 1 a este bit I de SREG está en 1, se activa la Interrupción de Conversión Completa del
ADC.
Estos bits determinan el factor de división entre la frecuencia del cristal y el reloj de entrada al ADC.
Factor de
ADSP2 ADSP1 ADSP0
división
0 0 0 2
0 0 1 2
0 1 0 4
0 1 1 8
1 0 0 16
1 0 1 32
1 1 0 64
1 1 1 128
Bit 7 6 5 4 3 2 1 0
ACME ADTS2 ADTS1 ADTS0
Read/Write R/W R/W R/W R R/W R/W R/W R/W
Initial Value 0 0 0 0 0 0 0 0
• Bit 6 – ACME: Si se configura con un 1 lógico, indica si el ADC va a trabajar con el comparador analógico. Si
no se utiliza, entonces se pone en 0 lógico.
27
Práctica 3: Manejo del Temporizador
Bit 7 6 5 4 3 2 1 0
ADC5D ADC4D ADC3D ADC2D ADC1D ADC0D
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Initial Value 0 0 0 0 0 0 0 0
• Bit 5:0 – ADC5:0D: Se configura la terminal del microcontrolador, que va a ser utilizada como entrada
analógica, para que sólo funcione con el ADC, y que la parte interna de la terminal que tiene que ver con el
comportamiento digital no se vea afectado.
ADLAR = 0
Bit 15 14 13 12 11 10 9 8
ADCH ADC9 ADC8
ADCL ADC7 ADC6 ADC5 ADC4 ADC3 ADC2 ADC1 ADC0
7 6 5 4 3 2 1 0
Read/Write R R R R R R R R
Initial Value 0 0 0 0 0 0 0 0
ADLAR = 1
Bit 15 14 13 12 11 10 9 8
ADCH ADC9 ADC8 ADC7 ADC6 ADC5 ADC4 ADC3 ADC2
ADCL ADC1 ADC0
7 6 5 4 3 2 1 0
Read/Write R R R R R R R R
Initial Value 0 0 0 0 0 0 0 0
4.3 DESARROLLO.
4.3.1 Escriba y analice el siguiente código, el cual es para utilizar el convertidor analógico-digital, y
conteste las preguntas siguientes:
a. ¿Cuántos canales de conversión Analógico-Digital tiene el microcotnrolador?
b. ¿Cuál es el canal que se va a muestrear?
c. ¿Cuál es el número de bit de conversión?
d. ¿Cuál es la frecuencia de muestreo?
e. ¿Qué puerto es el que se utiliza para convertir?
f. ¿En qué puertos se muestran los resultados?
g. ¿Cuál es el valor del voltaje de referencia?
h. Coloque comentarios al código que explique la configuración que se está utilizando
para el microcontrolador.
28
Práctica 3: Manejo del Temporizador
#include <avr/io.h>
#include <avr/interrupt.h>
void Ports_Setup();
void ADC_Setup();
void Ports_Setup()
{
DDRD = 0xFF;
DDRC = 0x03;
}
void ADC_Setup()
{
ADMUX =
(0<<REFS1)|(1<<REFS0)|(0<<ADLAR)|(0<<MUX3)|(1<<MUX2)|(0<<MUX1)|(1<<MUX0);
ADCSRA =
(1<<ADEN)|(0<<ADSC)|(1<<ADATE)|(0<<ADIF)|(1<<ADIE)|(1<<ADPS2)|(1
<<ADPS1)| (1<<ADPS0);
ADCSRB = (0<<ACME)|(0<<ADTS2)|(0<<ADTS1)|(0<<ADTS0);
DIDR0 =
(1<<ADC5D)|(0<<ADC4D)|(0<<ADC3D)|(0<<ADC2D)|(0<<ADC1D)|(0<<ADC0D);
}
ISR(ADC_vect,ISR_NAKED)
{
PORTD = ADCL;
PORTC = ADCH;
reti();
}
int main(void)
{
Ports_Setup();
ADC_Setup();
sei();
ADCSRA |= (1<<ADSC);
while(1){}
}
4.3.3 Compruebe que el valor digital obtenido corresponde a los voltajes de entrada del punto 2.
29
Práctica 3: Manejo del Temporizador
4.3.4 Utilizando el código de la práctica 3 y de la práctica 4, realice un programa que permita variar
el ciclo de trabajo de una señal PWM, de acuerdo al valor analógico que entra al convertidor,
utilizando un potenciómetro en divisor de tensión.
4.3.5 Anote sus conclusiones.
30
PRÁCTICA 5. Comunicación Serial
5.1 OBJETIVO.
Desarrollar aplicaciones para el microcontrolador que sirva para realizar comunicación entre dos
dispositivos, para transferencia de datos.
Bit 7 6 5 4 3 2 1 0
UDR Lectura RxB 7 RxB 6 RxB 5 RxB 4 RxB 3 RxB 2 RxB 1 RxB 0
UDR Write TxB 7 TxB 6 TxB 5 TxB 4 TxB 3 TxB 2 TxB 1 TxB 0
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Initial Value 0 0 0 0 0 0 0 0
El Registro UDR se utiliza para el envío/recepción de datos seriales. Cuando se reciben datos, el
dato recibido está disponible en los bits RxB, y cuando se transmite se escribe en el registro TxB. Aún
cuando el registro UDR se llama de la misma manera, está configurado para realizar la doble función
de escritura/lectura.
Bit 7 6 5 4 3 2 1 0
RXC TXC UDRE FE DOR PE U2X MPCM
Read/Write R R/W R R R R R/W R/W
Initial Value 0 0 1 0 0 0 0 0
La bandera TXC se pone en 1 cuando se ha terminado de enviar un dato, y no existen más datos
en el bufer para ser transmitido. La bandera TXC se limpia automáticamente cuando se genera una
interrupción por recepción completa. En caso de no usar interrupción, se limpia escribiendo un 0 al bit
TXC. Esta bandera puede provocar una interrupción por transmisión completa (TXCIE).
La bandera UDRE indica si el bufer de transmisión está listo para recibir nuevos datos. Si UDRE
está en 1, el bufer está vacío, y puede recibir datos para trasnmitir. La bandera UDRE puede generar
una interrupción de registro de datos vacío (UDRIE).
Práctica 3: Manejo del Temporizador
Este bit se pone en 1 si el siguiente carácter recibido tiene un error de trama. Este error consiste
en leer el bit de paro como un 0 en lugar de leerse como un 1. Este bit es válido hasta que es leído el
dato recibido.
Se pone en 1 cuando el bufer de recepción está lleno y se detecta un nuevo bit de inicio en la
recepción. Este valor es válido hasta que se lee el dato recibido (UDR).
Este bit se pone en 1 si el siguiente carácter recibido tiene un error de paridad, y el bit de
habilitación de paridad está activado.
Este bit solamente tiene efecto en configuración asíncrona. Se escribe un 0 para modo síncrono.
Escribiendo un 1 en este bit, el divisor de frecuencia del generador de velocidad utiliza el valor de 8
en lugar de 16, por lo que la velocidad de transmisión puede ser el doble.
Cuando el bit MPCM es escrito a 1, todas las tramas recibidas por el USART que no contienen la
información de dirección, son ignoradas. En 0 se deshabilita el modo.
Bit 7 6 5 4 3 2 1 0
RXCIE TXCIE UDRIE RXEN TXEN UCSZ2 RxB8 TxB8
Read/Write R/W R/W R/W R/W R/W R/W R R/W
Initial Value 0 0 0 0 0 0 0 0
32
Práctica 3: Manejo del Temporizador
El bit UCSZ2 se combina con los bits UCSZ1:0 para establecer el tamaño de bits de la trama de
datos de transmisión, y es el mismo para transmisión y recepción.
Se utiliza como el noveno bit de datos de recepción cuando se configura un tamaño de trama de 9
bits.
Se utiliza como el noveno bit de datos de transmisión cuando se configura un tamaño de trama de
9 bits.
Bit 7 6 5 4 3 2 1 0
URSEL UMSEL UPM1 UPM0 USBS UCSZ1 UCSZ0 UCPOL
Read/Write R/W R/W R/W R/W R/W R/W R R/W
Initial Value 1 0 0 0 0 1 1 0
33
Práctica 3: Manejo del Temporizador
5.3 DESARROLLO.
5.3.1 Escriba y analice el siguiente código, el cual es para recibir datos de manera serial.
/*
* UART_en_C.c
*
* Created: 20/05/2014 17:24:33
34
Práctica 3: Manejo del Temporizador
* Author: SolaceLabsHardware
*/
#include <avr/io.h>
#include <avr/interrupt.h>
void Ports_Setup();
void USART_Init();
ISR(USART_RX_vect,ISR_NAKED)
{
char temp;
temp = UDR0;
switch(temp)
{
case 'A': PORTC=0x01;
break; //Al mandar una "A" se obtiene un 1 en el puerto C
case 'B': PORTC=0x02;
break; //Al mandar una "B" se obtiene un 2 en el puerto C
case 'C': PORTC=0x04;
break; //Al mandar una "C" se obtiene un 4 en el puerto C
case 'D': PORTC=0x08;
break; //Al mandar una "D" se obtiene un 8 en el puerto C
case 'E': PORTC=0x10;
break; //Al mandar una "E" se obtiene un 16 en el puerto C
case 'F': PORTC=0x20;
break; //Al mandar una "F" se obtiene un 32 en el puerto C
default: PORTC = 0x3F;
break; //Al mandar un "caracter no especificado"
}
reti();
}
int main(void)
35
Práctica 3: Manejo del Temporizador
{
Ports_Setup();
USART_Init();
sei();
while(1)
{
}
}
5.3.3 Para la comunicación serial requierer de un módulo interfaz de USB a serial, y se conecta
como se muestra a continuación.
5.3.4 El siguiente código es para transmitir un dato por comunicación serial. Pruebe el código.
36
Práctica 3: Manejo del Temporizador
#include <avr/io.h>
void Ports_Setup();
void USART0_Setup();
void Ports_Setup()
{
DDRC = 0x00;
DDRD = 0x02;
}
void USART0_Setup()
{
UCSR0A = (0<<TXC0)|(0<<U2X0)|(0<<MPCM0); // UCSR0 = 0x00
UCSR0B = (0<<RXCIE0)|(0<<TXCIE0)|(0<<UDRIE0)|(1<<RXEN0)|(1<<TXEN0)|
(0<<UCSZ02)|(0<<TXB80);
UCSR0C = (0<<UMSEL01)|(0<<UMSEL00)|(0<<UPM01)|(0<<UPM00)|(0<<USBS0)|
(1<<UCSZ01)|(1<<UCSZ00)|(0<<UCPOL0);
UBRR0H = 0;
UBRR0L = 71; // Para indicar el valor del cristal
}
int main(void)
{
Ports_Setup();
USART0_Setup();
while(1)
{
while((UCSR0A & (1<<UDRE0))==0); // Dentro de una condición,
// (1<<UDRE0) verifica si en el registro
// existe un '1'. un '1' enb UDRE0 indica
// que el registro de transmisión está vacío
UDR0 = PINC;
}
}
5.3.5 Haga un programa que envíe y reciba datos por el puerto de comunicación serial, y que se
comunique con una computadora.
5.3.6 Utilice el programa del motor a pasos, para que programe la velocidad del motor desde la
computadora.
5.3.7 Adquiera la señal de un sensor de temperatura, de un sensor infrarrojo, y una señal senoidal
de un generador de funciones. Transmita los valores a la computadora vía serial, y muestre la
forma de onda en la interfaz gráfica de usuario. El programa de la computadora debe permitir
configurar que canal o calaes se desea muestrear.
5.3.8 Revise los videos de las siguientes ligas.
https://www.youtube.com/watch?v=uQv7py84REs;
https://www.youtube.com/watch?v=zbJfcWparP0;
https://www.youtube.com/watch?v=JTLOx0C4Qhk; https://www.youtube.com/watch?v=wL-
kFomRMsU; https://www.youtube.com/watch?v=JTLOx0C4Qhk
37
PRÁCTICA 6. Comunicación serial con un módulo Bluetooth
6.1 OBJETIVO.
Aprender a utilizar la comunicación serial para comunicarse con un módulo bluetooth, para tener
comunicación con sistemas que utilicen este tipo de interfaz de comunicación.
6.2 DESARROLLO.
6.2.1 Implemente el siguiente circuito, el cual se utiliza para comunicarse con un módulo bluetooth.
6.2.2 Programe el microcontrolador con el siguiente código para recibir datos de manera serial, y
compruebe que funciona. Requiere utilizar el terminal en la computadora, así como un
adaptador de USB a serial, para poder realizar el intercambio de datos. Debe cuidar que la
salida de la interfaz no sea RS232, de lo contrario, requiere un circuito adicional MAX-RS232
para adaptarlo a 5V.
#include <avr/io.h>
#include <avr/interrupt.h>
void Ports_Setup();
void USART_Init();
(0<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00)|(0<<UCPOL0);
UBRR0=0x47;
}
ISR(USART_RX_vect,ISR_NAKED)
{
char temp;
temp = UDR0;
switch(temp)
{
case 'A': PORTC=0x01; break; //Con una "A", puerto C = 0x01
case 'B': PORTC=0x02; break; //Con una "B", puerto C = 0x02
case 'C': PORTC=0x04; break; //Con una "C", puerto C = 0x04
case 'D': PORTC=0x08; break; //Con una "D", puerto C = 0x08
case 'E': PORTC=0x10; break; //Con una "E", puerto C = 0x10
case 'F': PORTC=0x20; break; //Con una "F", puerto C = 0x20
default: PORTC = 0x3F; break;//Con otra cosa, puerto C = 0x3F
}
reti();
}
int main(void)
{
Ports_Setup();
USART_Init();
sei();
while(1)
{
}
}
6.2.3 Programe el microcontrolador con el siguiente código para enviar datos de manera serial, y
compruebe que funciona. Requiere utilizar el terminal en la computadora, así como un
adaptador de USB a serial, para poder realizar el intercambio de datos. Debe cuidar que la
salida de la interfaz no sea RS232, de lo contrario, requiere un circuito adicional MAX-RS232
para adaptarlo a 5V.
#include <avr/io.h>
void Ports_Setup();
void USART0_Setup();
void Ports_Setup()
{
DDRC = 0x00;
DDRD = 0x02;
}
void USART0_Setup()
39
Práctica 3: Manejo del Temporizador
{
UCSR0A = (0<<TXC0)|(0<<U2X0)|(0<<MPCM0); // UCSR0 = 0x00
UCSR0B = (0<<RXCIE0)|(0<<TXCIE0)|(0<<UDRIE0)|(1<<RXEN0)|(1<<TXEN0)|
(0<<UCSZ02)|(0<<TXB80);
UCSR0C = (0<<UMSEL01)|(0<<UMSEL00)|(0<<UPM01)|(0<<UPM00)|(0<<USBS0)|
(1<<UCSZ01)|(1<<UCSZ00)|(0<<UCPOL0);
UBRR0H = 0;
UBRR0L = 71; // Para indicar el valor del cristal
}
int main(void)
{
Ports_Setup();
USART0_Setup();
while(1)
{
while((UCSR0A & (1<<UDRE0))==0); // Dentro de una condición,
// (1<<UDRE0) verifica si en el registro
// existe un '1'. Un '1' en UDRE0 indica
// registro de transmisión vacío
UDR0 = PINC;
}
}
6.2.4 Investigue cuales son los registros relacionados con el UART, y describa brevemente el uso
de cada uno de ellos, así como de los bit que se utilizan.
6.2.5 Modifique el programa para que se maneje la transmisión y la recepción. Utilice dos
microcontroladores para probar la comunicación, mostrando en leds el valor recibido, y
utilizando interruptores para establecer el valor a transmitir. El valor recibido se muestra en los
leds y debe corresponder al dato introducido con los interruptores.
6.2.6 Pruebe la comunicación utilizando dos microcontroladores.
6.2.7 Implemente el siguiente circuito, el cual será utilizado para comunicarse con un módulo
Bluetooth. Debe conseguir las hojas de datos del módulo, para saber cuáles son los
comandos que debe utilizar.
40
Práctica 3: Manejo del Temporizador
6.2.8 Investigue cuales son los comandos del módulo Bluetooth, repórtelos y describa brevemente
el uso de cada uno de ellos.
6.2.9 Modifique el código del punto 2, para transmitir comandos al módulo bluetooth y establecer
una comunicación serial. Se recomienda probar primero los comandos del módulo utilizando la
computadora a través del terminal o algún software equivalente.
6.2.10 Pruebe la comunicación serial utilizando dos microcontroladores y dos módulos Bluetooth para
comunicarse entre ellos.
41
PRÁCTICA 7. Desarrollo de proyecto
7.1 OBJETIVO.
Desarrollar un proyecto donde se aplique los conocimientos estudiados a lo largo del semestre, para
garantizar el aprendizaje del estudiante, obteniendo un producto que funcione y pueda resolver
problemas reales.
7.2 DESARROLLO.
7.2.1 El proyecto debe ser registrado con el profesor de la asignatura, entregando la propuesta de
proyecto que cumpla con las siguientes condiciones. La evaluación del proyecto es realizada
de manera colegiada por un grupo de docentes ajenos al profesor de la asignatura.
• Examen oral.
Teniendo como base el funcionamiento total del proyecto se procederá a una sesión
de preguntas individuales (3 preguntas); la respuesta incorrecta a una de ellas
tendrá la penalización de un punto total sobre la calificación final.
7.2.4 El contenido del reporte debe ser el siguiente, y se debe entregar antes de presentar el
proyecto.
- Portada.
1. Datos generales (Universidad, Facultad, Carrera, Profesor y Materia).
2. Nombre del proyecto.
3. Integrantes del equipo (con Expedientes).
4. Fecha de entrega.
- Índice de contenido.
- Índice de figuras.
- Índice de tablas.
- Introducción.
1. Objetivo general.
2. Objetivos particulares.
- Marco teórico.
- Metodología.
- Resultados.
1. Resultados obtenidos.
2. Conclusión.
- Referencias.
- Anexos.
1. Anexo A. Código C (de todos los componentes).
2. Anexo B. Interfaz de monitoreo y control en Visual C.
3. Anexo C. Memoria fotográfica.
4. Anexo D. Hojas de datos de todos los componentes eléctricos y
electrónicos utilizados.
5. Anexo E. Esquemáticos electrónicos.
6. Anexo F. Imagen 3D de la tarjeta electrónica.
7. Anexo G. Video.
8. Anexo H. Costos.
*Los datos enumerados es información mínima requerida, pero no toda la correspondiente a los
puntos del reporte.
• En formato PDF.
• Grabado en un disco (junto con los códigos y aquella información que crean pertinente).
43
Práctica 3: Manejo del Temporizador
• El disco debe presentar la portada con estampa adherida al disco con el escudo de la
Facultad de Ingeniería, nombre del proyecto, nombre de los integrantes, grupo, período 2017-1.
44