Arquitectura de Computadoras - Semana 5
Arquitectura de Computadoras - Semana 5
Arquitectura de Computadoras - Semana 5
Temario:
– Sistemas embebidos
– Microcontrolador (MCU)
– Clasificación de microcontroladores
– Familias de microcontroladores
– El microcontrolador ATmega2560
– El lenguaje de programación Assembly
– Arquitectura del ATmega2560
– Manipulación de puertos de Entrada/Salida
● Puede formar parte de otro sistema embebido: Un sistema embebido puede formar
parte de otro sistema embebido más complejo. Por ejemplo: un camión es un sistema
embebido; pero también lo es el sistema de monitoreo de presión de los neumáticos.
“Bestia de funcionalidad”
- Procesamiento de texto
- Reproducción de audio
- Reproducción de video
- Conexión Bluetooth
- Conexión Wi-fi
- Compra on-line
- Videojuegos
- Video conferencia
- Diseño gráfico
- Bases de datos
- Chat
- Etc.
“Sistema dedicado”
- Frecuencia cardiaca
- Movimiento
- Conexión con iPhone
– Mensajes
– Llamadas
– Apps
Núcleo(core)
Procesador con un solo núcleo
(single-core)
Buses del
sistema
2.- MICROCONTROLADORES
ALU Microprocesador
(Procesamiento intenso)
Núcleo
Registros Microcontrolador
µP/µC
(Sensores y actuadores)
Periféricos y Memoria
2.- MICROCONTROLADORES
Características generales:
2.- MICROCONTROLADORES
Periféricos
Memoria de Memoria de
Datos CPU Programa
(SRAM) (FLASH)
Periféricos
2.- MICROCONTROLADORES
2.- MICROCONTROLADORES
2.- MICROCONTROLADORES
2.- MICROCONTROLADORES
Microcontroladores de 8 bits
Manejo de datos: Bus de datos de 8 bits.
Poder de procesamiento: Hasta 20 MIPS
Periféricos: GPIO, Timer, PWM, ADC, UART, SPI, I2C, entre otros.
Aplicación: Electrónica de consumo (sensible al costo).
Microcontroladores de 16 bits
Manejo de datos: Bus de datos de 16 bits, acceso directo a memoria (DMA).
Poder de procesamiento: Más de 40 MIPS
Periféricos: DAC, IrDA, RTC, USB, CAN, LIN, CODEC, entre otros.
Aplicación: Sensores y sistemas de control (motores).
Microcontroladores de 32 bits
Manejo de datos: Bus de datos de 32 bits, acceso directo a memoria (DMA).
Poder de procesamiento: Más de 200 DMIPS (Dhrystone MIPS)
Periféricos: FPU, USB, Ethernet, CAN, calculador CRC, interfaz para LCD, entre otros .
Aplicación: Procesamiento digital de señales, aplicaciones con sistema operativo.
2.- MICROCONTROLADORES
PIC24
MCU de 16 bits ATxmega
dsPIC
SAM
MCU de 32 bits PIC32
SMART
2.- MICROCONTROLADORES
ADC DAC
Procesador
Comparador Puerto
Timer UART
Microcontrolador
2.- MICROCONTROLADORES
2.- MICROCONTROLADORES
B0 RB0
Puerto de salida tratado como
un espacio en memoria.
B1 RB1
B2 RB2
.
uint8_t Puerto_B .
.
B7 RB7
Clock
R0
R1
…
R31
Puertos E/S
Registros de configuración
Almacenamiento de datos
Incluido en el
Software programador: AVR-DUDE software de
Arduino
- Bootloader pre-programado.
- ADC de 10 bits.
3.4.- Documentación
Texto de consulta
Brinda detalles de la organización y arquitectura
(instrucciones) del microcontrolador. Asimismo, brinda
ejemplos simples que sirven como guía al estudiante.
Texto de consulta
● En aplicaciones donde se requiere que la ejecución del código sea lo más rápida posible
(por ejemplo, rutinas de interrupción), las rutinas suelen ser implementadas en lenguaje
ensamblador.
65 ● No definido.
0x41 ó $41
● La famila de microcontroladores
0b01000001 AVR no cuenta con instrucciones
para operar valores en punto
‘A’ flotante.
Formatos:
Hexadecimal Prefijo 0x ó $
Binario Prefijo 0b
Las directivas son palabras reservadas incluidas en el código. Estas palabras reservadas se
utilizan para brindar facilidades al programador al momento de escribir un programa.
● Las instrucciones son traducidas a datos binarios por el ensamblador, y ocupan espacio en
la memoria de programas.
.EQU
.SET
.ORG
.INCLUDE
.EQU (equate)
Esta directiva es usada para definir un valor constante o una dirección fija. La directiva
.EQU no lleva a cabo ningún tipo de almacenamiento, sino que asocia un número constante
con una etiqueta de datos o de memoria, de modo que cuando la etiqueta aparezca en el
programa, su constante sustituirá a la etiqueta.
Por ejemplo, se puede usar .EQU para inicializar una constante contador, y luego esta
constante puedecargarse al registro R21:
.SET
Esta directiva es usada para definir un valor constante o una dirección fija. Se diferencia
de .EQU en que el valor asignado por la directiva .SET puede ser reasignado posteriormente.
.ORG (origin)
La directiva .ORG es usada para indicar la dirección de inicio. Puede ser usada tanto para la
memoria de programas como para la memoria de datos.
.INCLUDE
Esta directiva es muy útil cuando el programa se organiza en múltiples archivos. También es
usada para incluir librerías o archivos con definiciones (etiquetas), proporcionados por el
fabricante.
Para este curso se empleará la directiva .INCLUDE para incluir el archivo con las definiciones
del microcontrolador ATmega2560, proporcionado por el fabricante:
.INCLUDE “m2560def.inc”
4) Cada ensamblador tiene algunas palabras reservadas que no deben ser usadas como
etiquetas en el programa. Entre las palabras reservadas más comunes tenemos los
mnemónicos de las instrucciones. Por ejemplo, “LDI” y “ADD” están reservados porque son
mnemónicos de instrucciones.
Un programa en Assembly es una serie de órdene, o líneas, las cuales pueden ser
instrucciones en Assembly (como ADD y LDI) o directivas.
Mientras que las instruccionas le indican a la CPU que hacer, las directivas (también llamdas
pseudo-instrucciones) proporcionan indicaciones al ensamblador.
Los corchetes indican que un campo es opcional y no todas las líneas los tienen. Los
corchetes no deben tipearse
Con respecto al formato mostrado anteriormente, deben aclararse los siguientes puntos
1) El campo etiqueta permite al programa referirse a una línea de código por nombre. Esto
es usado, por ejemplo, para referenciar una posición al emplear una instrucción de salto.
2) Los campos mnemónico y operando(s) juntos llevan a cabo el trabajo real del programa
y realizan las tareas para las cuales el programa fue escrito. En instrucciones en Assembly,
tales como:
ADD y LDI son los mnemónicos que producen los opcodes; los operandos son “$55”y “$67”.
3) El campo comentario empieza con un indicador de comentario punto y coma “;”. Los
comentarios pueden ir al final de una línea, o también pueden ocupar una línea completa.
El ensamblador ingnora los comentarios, pero éstos son esenciales para los
programadores.
; Programa en lenguaje Assembly para sumar algunos datos
; almacenar SUMA en la ubicación 0x300 de la SRAM
.EQU SUMA = 0x300;Ubicación 0x300 en SRAM para SUM
.ORG 00 ; Iniciar en la dirección 0
LDI R16, 0x25 ; R16 = 0x25
LDI R17, $34 ; R17 = 0x34
LDI R18, 0b00110001 ; R18 = 0x31
ADD R16, R17 ; sumar R17 a R16
ADD R16, R18 ; sumar R18 a R16
LDI R17, 11 ; R17 = 0x0B
ADD R16, R17 ; sumar R17 a R16
STS SUMA, R16 ; guardar la SUMA en la ubicación 0x300
AQUI: JMP AQUI ; permanecer aqui por siempre
Los pasos para crear un programa ejecutable en lenguaje Assembly se pueden resumir en la
siguiente imagen:
Microcontrolador
1) Primero, debemos usar un editor de texto para escribir un programa. En nuestro curso
utilizaremos el entorno integrado de desarrollo (IDE) Atmel Studio 7, el cual incorpora
editor de texto, ensamblador, simulador y muchas más herramientas en un solo paquete de
software. Sin embargo, es posible usar cualquier otro editor de texto como bloc de notas o
Kate. La extensión del archivo fuente creado debe ser “asm” (Assembly).
2) Luego, el archivo fuente (.asm) pasa por el ensamblador, el cual trabaja en dos etapas:
Primero encarga de verificar si no hay ningún error de sintaxis en el código escrito.
Adicionalmente, el pre-procesador también se encarga de interpretar (traducir) las
directivas encontradas en el código a indicaciones explícitas para el ensamblador.
● El archivo objeto (.obj) contiene las instrucciones expresadas en lenguaje máquina (unos y
ceros). El archivo objeto es usado como entrada para un simulador o emulador.
● El archivo mapa (.map) muestra las etiquetas definidas en el programa junto con sus
valores.
● El archivo lista (.lst), el cual es opcional, es muy útil para el programador. La lista muestra
el código fuente y también en formato binario; además muestra cuales instrucciones son
usadas en el código fuente, y la cantidad de memoria utilizada por el programa.
AVRASM ver. 2.1.2 F:\AVR\Sample\Sample.asm Sun Apr 13 20:31:14 2008
Los registros de función específica también son conocidos como registros de entrada/salida
(I/O), ya que entre ellos se encuentran los registros que controlan los puertos de
entrada/salida.
A continuación se detallará cada uno de las partes de la memoria de datos del ATmega2560,
así como las instrucciones básicas empleadas para manipular cada parte.
R0
R1
…
R31
Puertos E/S
Registros de configuración
Almacenamiento de datos
● En la CPU, los registros de propósito general son usados para almacenar datos
temporalmente. La información puede ser un byte de datos que será procesado, o una
dirección que apunta al dato que debe ser extraído.
● La gran mayoría de registros de los microcontroladores AVR son de 8 bits. En los AVR solo
existe un tamaño de dato: 8 bits.
● Estos registros pueden ser usados por todas las instrucciones aritméticas y lógicas.
● Solo los 16 últimos registros (desde R16 hasta R31) pueden ser utilizados por
instrucciones que empleen direccionamiento inmediato.
LDI Rd, K ; carga Rd (destino) con el valor inmediato K
; d debe encontrarse entre 16 y 31
La letra ‘I’ en LDI quiere decir “inmediato” (immediate). Si vemos la palabra “inmediato” en
cualquier instrucción, estamos tratando con un valor que debe ser proporcionado justo ahí, en
la instrucción (direccionamiento inmediato).
LDI R20, 0x25 ; carga R20 con 0x25 (R20 = 0x25)
Recuerde que: No es posible cargar valores inmediatos en los registros R0 – R15, y mover
un valor mayor a 255 causará un error.
LDI R5, 0x99 ; instrucción inválida
LDI R17, 0x7F2 ; ILEGAL 0x7F2 > 8 bits
La instrucción MOV es usada para copiar datos entre registros de propósito general (desde
R0 hasta R31). Esta instrucción tiene el siguiente formato:
MOV Rd, Rr ; Rd = Rr (Copiar Rr a Rd)
; Rd y Rr pueden ser cualquiera de los GPRs
MOV R10, R20 ; R10 = R20
Se debe tener claro que, si R20 contiene el valor 60, después de la ejecución de la
instrucción mostrada tanto R20 como R10 contendrán el valor 60.
ADD Rd, Rr ; suma Rr a Rd y almacena el resultado en Rd
La instrucción ADD le dice a la CPU que sume el valor de Rr a Rd y que coloque el resultado
de vuelta en el registro Rd.
Para sumar dos números, por ejemplo 0x25 y 0x34, uno puede hacer lo siguiente:
LDI R16, 0x25 ; carga 0x25 dentro de R16
LDI R17, 0x34 ; carga 0x34 dentro de R17
ADD R16, R17 ; suma el valor de R17 a R16 (R16 = R16 + R17)
Al ejecutarse las líneas de arriba se obtiene en R16 = 0x59 (0x25 + 0x34 = 0x59)
Debe quedar claro que la instrucción ADD no permite sumar valores inmediatos (no lleva
ninguna ‘I’ en el mnemónico). La instrucción ADD emplea direccionamiento directo para sus
operandos.
INC Rd ; incrementa el contenido de Rd en uno (0 < d < 31)
INC R2 ; R2 = R2 + 1
SUB Rd, Rr ; resta Rr de Rd y almacena el resultado en Rd
La instrucción SUB le dice a la CPU que reste el valor de Rr desde Rd y que coloque el
resultado de vuelta en el registro Rd.
Para restar dos números, por ejemplo 0x25 de 0x34, uno puede hacer lo siguiente:
LDI R20, 0x34 ; carga 0x34 dentro de R20
LDI R21, 0x25 ; carga 0x25 dentro de R21
SUB R20, R21 ; R20 = R20 R21
Al ejecutarse las líneas de arriba se obtiene en R20 = 0x0F (0x34 - 0x25 = 0x0F)
Al igual que la instrucción ADD, la instrucción SUB emplea direccionamiento directo para sus
operandos.
DEC Rd ; decrementa el contenido de Rd en uno (0 < d < 31)
DEC R10 ; R10 = R10 1
COM Rd ; reemplaza el contenido de Rd por su complemento a uno
La instrucción COM complementa (invierte) los bits del valor contenido en Rd y coloca el
resultado de vuelta en el registro Rd.
LDI R16, 0x55 ; R16 = 0x55
COM R16 ; complementar R16
Esta instrucción opera de forma análoga al operador a nivel de bits “~”, empleado en el
lenguaje de programación C.
NEG Rd ; reemplaza el contenido de Rd por su complemento a 2
Por ejemplo, en el siguiente código, se desea almacenar el valor -5, representado con 8 bits,
en el registro R16:
LDI R16, 5 ; R16 = 0x05
NEG R16 ; convertir R16 en su complemento a 2
● Cada ubicación tiene un ancho de 8 bits y puede ser usada para almacenar cualquier dato
que se desee, siempre y cuando no tenga más de 8 bits de ancho.
● Las instrucciones vistas hasta ahora trabajaban con el valor inmediato de K y los registros
de propósito general. Además, estas instrucciones empleaban los registros de propósito
general como destino (se vieron ejemplos como LDI y ADD).
● En esta sección del curso veremos instrucciones que permiten acceder a varias
ubicaciones de la memoria de datos.
R0
R1
…
R31
Puertos E/S
Registros de configuración
Almacenamiento de datos
LDS Rd, K ; carga Rd con el contenido de la ubicación K
; K es una dirección entre 0x0000 y 0xFFFF
La instrucción LDS le dice a la CPU que cargue (copie) un byte desde una dirección en la
memoria de datos hacia los registros de propósito general.
Luego de que esta instrucción es ejecturada , el GPR tendrá el mismo valor que la ubicación
en la memoria de datos.
La ubicación en la memoria de datos (K) puede ser cualquier parte del espacio de datos:
puede ser una ubicación en la SRAM interna, o uno de los registros de función específica
(SFR) o un registro de propósito general.
Por ejemplo, el siguiente código suma los contenidos de las ubicaciones 0x300 y 0x302. Para
hacer esto, antes es necesario cargar R0 con el contenido de la ubicación 0x300 y cargar R1
con el contenido de la ubicación 0x302, luego se debe sumar R0 y R1:
LDS R0, 0x300 ; R0 = contenido de la ubicación 0x300
LDS R1, 0x302 ; R1 = contenido de la ubicación 0x302
ADD R1, R0 ; suma R0 a R1
STS K, Rr ; almacena el contenido de Rr en la ubicación K
; K es una dirección entre 0x000 y 0xFFFF
La instrucción STS le dice a la CPU que almacene (copie) el contenido del registro de
propósito general a una dirección ubicada en la memoria de datos.
La ubicación en la memoria de datos (K) puede ser cualquier parte del espacio de datos:
puede ser una ubicación en la SRAM interna, o uno de los registros de función específica
(SFR) o un registro de propósito general.
STS 0x230, R25 ; almacena contenido de R25 en la ubicación 0x230
● Los SFRs o memoria de E/S, son un tipo de memoria dedicada a funciones específicas,
tales como registro de estado, temporizadores, comunicación serial, puertos E/S, ADC,
entre otros.
● Cada ubicación en memoria de datos tiene una dirección única, llamada dirección de la
memoria de datos.
● Algunos registros de función específica (64 registros) tienen una dirección relativa, que
toma como referencia el inicio de la memoria de E/S. Esta dirección es llamada la
dirección E/S.
● Cuando se necesite manipular los SFRs, se puede aplicar las mismas instrucciones que se
usan para manipular la SRAM (LDS. STS), vistas anteriormente. En este caso debe usarse
la dirección de la memoria de datos de los registros.
● Por otro lado, también es posible manipular los SFRs mediante las instrucciones
especiales IN y OUT. En este caso debe usarse la dirección E/S de los registros.
R0
R1
…
R31
Puertos E/S
Registros de configuración
Almacenamiento de datos
5.16.- La instrucción IN
IN Rd, A ; carga una ubicación E/S al GPR
; (0 < d < 31), (0 < A < 0x3F)
La instrucción IN le dice a la CPU que cargue (copie) un byte desde el registro de función
específica (SFR) hacia el registro de propósito general (GPR).
Luego de que esta instrucción es ejecutada , el registro de propósito general tendrá el mismo
valor que el registro de función específica.
IN R20, 0x16 ; carga en R20 el contenido de la ubicación 0x16
; 0x16 representa la dirección E/S
NOTA: Esta instrucción solo funciona con los SFRs con dirección E/S entre 0 y 63 (0x3F).
Para los SFRs ubicados fuera de este rango debe usarse la instrucción LDS y la dirección de
la memoria de datos.
OUT A, Rr ; almacena el contenido de Rr en la ubicación A
; (0 < d < 31), (0 < A < 3F)
La instrucción OUT le dice a la CPU que almacene (copie) el contenido del registro de
propósito general al registro de función específica.
Luego de que esta instrucción es ejecutada , el registro de función específica tendrá el mismo
valor que el registro de propósito general.
LDI R20, 0xE6 ; cargar R20 con 0xE6
OUT PORTA, R20 ; cargar R20 en PORTA
NOTA: Esta instrucción solo funciona con los SFRs con dirección E/S entre 0 y 63(0x3F).
Para los SFRs ubicados fuera de este rango debe usarse la instrucción STS y la dirección de
la memoria de datos.
Como se mencionó anteriormente, podemos usar la instrucción LDS para copiar el contenido
de una ubicación de memoria a un GPR. Esto quiere decir que podemos cargar el contenido
de un SFR a un GPR, usando la instrucción LDS.
● Al usar la instrucción IN podemos usar las etiquetas de los SFRs, proporcionadas por el
fabricante.
Como se pudo apreciar en el diagrama anterior, existen 03 flip-flops, cuyas salidas definen el
comportamiento de un pin de E/S del microcontrolador:
● DD (Data direction): Define la dirección del pin, es decir, si el pin se comportará como una
entrada o una salida digital. Si la salida de este Flip-Flop es ‘1’, entonces el pin funciona
como salida digital; de lo contrario, el pin funciona como entrada.
● PORT: Define el valor de la salida del pin, es decir, si la salida es un ‘1’ lógico o un ‘0’
lógico. Este valor de salida puede ser escrito y leído por la aplicación.
● PIN: Proporciona el valor detectado en el pin cuando éste funciona como entrada (DDR =
0). Este valor cambia cuando la señal de entrada cambia.
Los pines de E/S no trabajan de manera aislada, sino que se encuentran organizados en
grupos de 8, conocidos como puertos. Por esta razón, los flip-flops mencionados
anteriormente también se encuentran asociados en grupos de 8, llamados registros.
Por lo tanto, para un PUERTO x (A, B, C, etc.) de 8 pines, tenemos los siguiente registros:
DDRx. PORTx, y PINx.
Para escribir salidas digitales a través de un PUERTO x se deben seguir algunos pasos:
1) Definir el puerto que se desea usar como salida y verificar que no se encuentre conectado
a ninguna señal que pueda causar un conflicto (corto circuito).
3) Cargar en un registro de propósito general (GPR) el valor que se desea enviar a la salida.
Para leer entradas digitales a través de un PUERTO x se deben seguir algunos pasos:
1) Definir el puerto que se desea usar como entrada y verificar que el pin no se encuentre
“flotante”, es decir, que siempre se tenga una señal con nivel lógico definido (‘1’ ó ‘0’). Una
forma de hacer esto es colocando una resistencia pull-up o pull-down (la que encuentre
más conveniente).
Ejercicio 01:
Conectar 08 LEDs al PUERTO F del microcontrolador. Luego, escribir un programa que lleve
a cabo lo siguiente: Crear una etiqueta NUMERO que defina un valor constante. Luego,
cargar NUMERO al registro R18, incrementarlo, copiar el resultado al registro R8 y mostrar su
valor en el PUERTO F.
Ejercicio 02:
Conectar 08 LEDs al PUERTO F del microcontrolador. Luego, escribir un programa que lleve
a cabo lo siguiente: Almacenar valores en 02 GPRs, sumarlos y mostrar el resultado en el
PUERTO F.
Ejercicio 03:
Conectar 08 LEDs al PUERTO F del microcontrolador. Luego, escribir un programa que lleve
a cabo lo siguiente: Crear dos etiquetas VAR1 y VAR2, correspondientes a las posiciones
0x201 y 0x202 en la SRAM, respectivamente; almacenar dos valores en VAR1 y VAR2,
emplear los GPRs para llevar a cabo una sustracción entre estos dos valores, y mostrar el
resultado en el PUERTO F.
Ejercicio 04:
Conectar 08 LEDs al PUERTO F del microcontrolador y 08 pulsadores (con resistencias pull-
up/pull-down) al PUERTO K. Luego, escribir un programa que lleve a cabo lo siguiente: Leer
el PUERTO K completo (8 bits), calcular el complemento a uno del valor leído, almacenar el
resultado en la posición 0x300 de la SRAM, y mostrar el resultado en el PUERTO F.
7.- PREGUNTAS