Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 1 Cesáreo Fernández Martínez
Introducción al 80C167
Introducción
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 2 Cesáreo Fernández Martínez
Introducción al 80C167
Objetivos
• Familiarizarse con el manejo de un micro (procesador/controlador)– Arquitectura
– Organización de un SED
– Entender la documentación
• Entender la especificación de un SED– Desde el punto de vista de la aplicación
– Desde el punto de vista del propio SED• Requisitos de CPU• Requisitos de memoria• Requisitos de I/O
• Desarrollar habilidades de diseño y depuración de un SED– Parte hardware
– Parte software (en C y/o Ensamblador)
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 3 Cesáreo Fernández Martínez
Introducción al 80C167
Programa
• Introducción
• Arquitectura del microcontrolador SIEMENS 80C167– Registros
– Lenguaje Ensamblador: Juego de instrucciones• Modos de direccionamieno
– Memoria y mapa de memoria
• Periféricos– Puertos paralelo/serie
– Timers
– Otros: Displays, teclados, etc.
• Interrupciones
• Programación en alto nivel: Lenguaje C
• Proyecto– Hardware/software
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 4 Cesáreo Fernández Martínez
Introducción al 80C167
Normas y bibliografía
• Evaluación (consultar información oficial)
– Nota = .7 Teoría+ .3 Lab
– Teoría• .3 Pruebas intermedias + .7 Prueba final• Habrá varias pruebas intermedias (Evaluación continua)• Habrá ejercicios para casa (algunos evaluables)
– Se pedirá la participación del alumno en clase
Incluso se podrán cambiar los porcentajes
Fundamental: la asistencia
• Bibliografía– Página WEB: Teoría, calendario, prácticas
– Manuales Siemens
– Libro de programación en C
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 5 Cesáreo Fernández Martínez
Introducción al 80C167
Introducción al SIEMENS 80C167
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 6 Cesáreo Fernández Martínez
Introducción al 80C167
SIEMENS 80C167
• Microcontrolador (Embedded Processor) de 16 bits– ALU y Registros de 16 bits
• Diseñado para tareas de control industrial– Robusto frente al ruido electromagnético
– P.e. PLC’s del LAB
• Rango direccionamiento: 16 Mbytes (memoria)
• Con memoria RAM interna– Ciertas versiones disponen también de ROM interna
• Con muchos dispositivos integrados en el chip– Controladores de comunicaciones serie
– Puertos paralelo
– Temporizadores (timers)
– Convertidor analógico/digital (A/D)
– Moduladores PWM (electrónica de potencia).
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 7 Cesáreo Fernández Martínez
Introducción al 80C167
“Modelo de programador” del 167Memoria
R800 0000
00 0001
FF FFFF
R9
R12
R10
R14
R13
R15
R0
R1
R4
R3
R2
R6
R5
R7 PC
R11
PSW
SP
Registros
CPU
00 FE00 00 FE02 00 FE0XI/O
(GPR’s)
(SFR’s)
(SFR’s)
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 8 Cesáreo Fernández Martínez
Introducción al 80C167
Memoria
• Organizada en “celdas” de 1 BYTE (8 bits)
• Cada byte tiene su DIRECCIÓN– Dada en 24 bits (16 Mbytes)
• Se accede a la memoria usando la dirección. Ejemplos– Lectura/escritura (datos/direcciones: 1’s y 0’s)
• Registros (CPU): Posiciones de memoria de acceso rápido
• I/O. En el 167 el acceso a puertos es similar al acceso a memoria
dato = READ (dirección) WRITE(dato, dirección)
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 9 Cesáreo Fernández Martínez
Introducción al 80C167
Primer ejemplo
• Suma de dos datos en ASS 167
Suma (940)+(942) en (942)
• Para llenar R0 hacen falta dos bytes! (2 bytes por dato)– En direcciones consecutivas de memoria (940/941)
– Parte baja del dato (en R0) en dirección par
MOV R0,0x940 ; READADD R0,0x942MOV 0x942,r0 ;WRITE
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 10 Cesáreo Fernández Martínez
Introducción al 80C167
Más ejemplos: Programas en C y Ensamblador
• Primer ejemplo: bucle “for”
• En lenguaje C
• En lenguaje ensamblador – N = 5; j en 00FA00 H ( j no está inicializada !)
for (i=1; i <=N; i++)j += 1;
500 E0 10 MOV R0,#1 ; r0 (i)502 E0 11 MOV R1,#1 ; auxiliar504 48 05 CMP R0,#5 ; if i>N506 DD 05 JMPR cc_sgt,512 ; then goto 512H508 04 F1 00 FA ADD 0fa00,R1 ; j += 150C 08 01 ADD R0,#1 ; i += 150E FA 00 04 05 JMPR cc_uc,504 ; salto sin condición512
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 11 Cesáreo Fernández Martínez
Introducción al 80C167
Notas
• En Ensamblador más largo que en C
• Línea ensamblador = operación elemental– “mov” de un dato de memoria-registro (registro-memoria)
– Suma dos datos
– Compara dos datos
– Saltos (con y sin condición)
• Las instrucciones se almacenan en memoria en formato BINARIO (1’s y 0’s)– Las instrucciones ocupan 2 ó 4 bytes
• Las instrucciones se almacenan en posiciones de memoria CONSECUTIVAS. Se ejecutan en orden– Salvo el los saltos
• La DIRECCIÓN (de memoria) de la próxima instrucción a ejecutar se almacena en el PC (Contador de Programa)
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 12 Cesáreo Fernández Martínez
Introducción al 80C167
Cómo se ejecuta un programa ?
• Dos pasos:– Captura de la instrucción (Instruction Fetch, usando el PC)
– Ejecución (usando la ALU)
• Fetch: Trae la instrucción de memoria, incrementa PC– CPU = MEM(PC); PC++;
• Execute: La ALU realiza la operación (suma, resta, etc.)
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 13 Cesáreo Fernández Martínez
Introducción al 80C167
Programa ensamblador
• Traduce las instrucciones de “pnemónico” a binario
• Por ejemplo, la instrucción
• Se convierte en (Codificación de instrucciones)
• Nuestra primera instrucción – que suponemos cargada en la posición 500 H de memoria
• Tipos de ensambladores– De línea: No soporta etiquetas (reside en el monitor de la tarjeta)
– De PC: Soporta etiquetas (reside en el PC)
MOV R0,#1
E0 10
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 14 Cesáreo Fernández Martínez
Introducción al 80C167
Ejemplo con etiquetas (ensamblador en PC)
• Las etiquetas facilitan la programación en ASS
• Los campos que forman una instrucción en ASS
• Los campos etiqueta y comentario son opcionales– TAB si no se usa el campo de etiqueta
MOV R0,#1 ; r0 (i)MOV R1,#1 ; auxiliar
bucle: CMP R0,#5 ; if i>NJMPR cc_sgt,fin ; then goto ´fin’ADD 0fa00H,R1 ; j += 1ADD R0,#1 ; i += 1JMPS bucle ; = jmpr cc_uc,
fin:
etiqueta: operación operandos ;comentario
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 15 Cesáreo Fernández Martínez
Introducción al 80C167
Operaciones y operandos (resumen)
• Operaciones– Transferencia: mov
– Aritméticas: add, sub, cmp, neg, mul, div
– Lógicas: and, or, cpl
– Desplazamientos: shr, shl
– Saltos: jmpr cc_uc (cc_eq, cc_ne, cc_ugt, cc_sgt, cc_ule, ...)
• Operandos, modos de direccionamiento– Inmediato: #1
– Directo a registro: R0
– Directo a memoria: 0fa00
– Indirecto: [R0]
• Números– Decimal 15
– Hexadecimal 0fa00 H (0 por delante si empiezan por letra)
– Binario 01001000 B
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 16 Cesáreo Fernández Martínez
Introducción al 80C167
Modos de direccionamiento.
• Directo a registro– mov r0,r1 ; R0 <- R1
• Inmediato– mov r0,#3 ; R0 <- 3 (no olvidar # !)
• directo a memoria– mov r0,0fa00H ; R0 <- Mem[fa00 H]
• Indirecto (“normal”, post-incremento, pre-decremento)– mov r0,[r1] ; R0 <- Mem[R1] (R1 Puntero)
– mov r0,[r1+] ; R0 <- Mem[R1], R1 <- R1 + 2
– mov r0,[-r1] ; R1 <- R1 - 2, R0 <- Mem[R1]
– mov r0,[r1+#4] ; R0 <- Mem[R1+#4]
• A nivel de byte– movb rl0,#3 ; R0 <- 3
– movb rh0,[r1+] ; R0 <- Mem[R1], R1 <- R1 + 1
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 17 Cesáreo Fernández Martínez
Introducción al 80C167
Tipos de instrucciones
• De transferencia de datos– Mov
• mov r0,#5 ; carga el número 5 en R0
• Aritméticas– Add, Sub, Neg, Cmp, Mul
• add r0,r1 ; R0 <- R0 + R1
• Lógicas– And, Or, Xor, Cpl
• Desplazamientos– Shl, Shr, Rol, Ror
• Saltos– JMPR: Con condición, sin condición (unconditional)
• Jmpr cc_eq, dir• Jmpr cc_uc. dir
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 18 Cesáreo Fernández Martínez
Introducción al 80C167
Más ejemplos
• if ( )– Alto nivel
– Ensamblador
if (a == b)a = 0;
MOV R0,aCMP R0,bJMPR cc_ne,nextMOV R0,#0MOV a,R0
next:
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 19 Cesáreo Fernández Martínez
Introducción al 80C167
Otro ejemplo
• while ( )– Alto nivel
– Ensamblador
i = 0;while (i<10) {
a[i] = i; i += 1;}
MOV R0,#0MOV R1,#1MOV R2,#0fa00h
otro: CMP R0,#10 JMPR cc_sge,nextMOV [R2],R0ADD R0,R1ADD R2,#2JMPS otro
next:
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 20 Cesáreo Fernández Martínez
Introducción al 80C167
Mapa de memoria del 80C167
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 21 Cesáreo Fernández Martínez
Introducción al 80C167
Mapa de memoria del 80C167
• Segmentada, en código. Paginada en datos.
FF FFFF H
01 0000 HS0
255 Segmentos
de 64 kB
P0 (ROM)
P1 (ROM)
P2
P3 (RAM I.)
00 0000 H 0000 H
4000 H
8000 H
C000 H
FFFF H
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 22 Cesáreo Fernández Martínez
Introducción al 80C167
• Los registros de control de los periféricos están en P3. Reciben el nombre de Special Function Registers.
• Los GPR’s son los registros R0 a R15 (en esta zona de memoria caben más de 16 registros de 16 bits!).
Página 3: RAM interna + SFR’s
SFR’s (bit)
F600 H
FC00 H
FD00 H
FFFF H
Stack
GPR’s
SFR’s
Bit a bit
FF00 H
FE00 H
RAM
SFR’s
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 23 Cesáreo Fernández Martínez
Introducción al 80C167
SFR’s
• Son: – PSW (Processor Status Word). Contiene los flags, ó códigos de
condición (para instrucciones de salto. P.e. “jmpr cc_eq,dir”)• N: Negative• C: Carry (acarreo)• V: Overflow (números con signo)• Z: Zero
– PC (Program Counter)• IP: Instruction Pointer (16 bits, apunta dentro del segmento)• CSP: Code Segment Pointer (8 bits, apunta al segmento en uso)
– SP (Stack Pointer)• Apunta a la zona de Stack (F600 H a FC00 H, crece hacia abajo).
– DPP’s (Data Page Pointer Registers)
– Otros: Control de periféricos (p.e. Las luces en FFC0 H)
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 24 Cesáreo Fernández Martínez
Introducción al 80C167
GPR’s
• Registros de propósito general (R0 a R15)
• Son de 16 bits– Los 8 primeros registros (R0 a R7) se pueden acceder a nivel de byte (8 bits). En este caso reciben los nombres:
• RL0 y RH0 (para R0)
– Los 4 primeros registros (R0 a R3) pueden almacenar direcciones (punteros)
• Ubicados en la zona (FC00 H a FD00 H)
• Se puede “reubicar” el banco de registros (los 16) en esta zona de memoria actuando sobre el registro (SFR):– CP (Contex Pointer)– CP inicial = FC00 H
• Más: rendimiento, prestaciones, capacidad, etc. No sólo CPU: sistema completo
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 25 Cesáreo Fernández Martínez
Introducción al 80C167
Puertos de entrada/salida del 80C167
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 26 Cesáreo Fernández Martínez
Introducción al 80C167
Entrada/salida. Puertos paralelo
• 9 puertos, 111 líneas (144 pin)
• P0 y P1 (16 bits): Bus de datos y bus de direcciones
• P2 (16 bits): de propósito general– Parte baja: Diodos led (y teclado en tarjeta de ampliación)
– Parte alta: Interruptores (tarjeta de ampliación)
• P3 (16 bits): Vía serie con PC (y display en tarjeta de ampliación)
• (P4, 8 bits: parte alta del bus de direcciones)
• P5 (16 bits): Entradas A/D.
• (P6, 8 bits: de “chip select”).
• (P7, 8 bits: de “PWM”).
• (P8, 8 bits: de “Capture Compare”)
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 27 Cesáreo Fernández Martínez
Introducción al 80C167
Puerto 2
• Dos registros de control de 16 bits: DP2 y P2
• DP2 en FFC2 H – DP2 (bits DP2.0 a DP2.15): “Data Direction Register”. Ej:
• DP2.0 = 1 : Línea de salida• DP2.0 = 0 : Línea de entrada
• P2 en FFC0 H– P2 (bits P2.0 a P2.15): “Data Register”. Ej;
• Si DP2.0 = 1, (P2 como registro de escritura)– P2.0 = 1: La Salida P2.0 se pone a 5 V.– P2.0 = 0: La Salida P2.0 se pone a 0 V.
• Si DP2.0 = 0, (P2 como registro de lectura)– Si P2.0 = 1: La Entrada P2.0 está a 5 V.– Si P2.0 = 0: La Entrada P2.0 está a 0 V.
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 28 Cesáreo Fernández Martínez
Introducción al 80C167
Diodos e interruptores• Tenemos diodos (leds) en parte baja P2 (P2.0 a P2.7) e
interruptores en la parte alta (P2.8 a P2.15).
• ¿Qué nivel lógico tengo que poner en P2.0 para que el diodo se encienda?
+ 5V
P2.0
+ 5V
P2.8
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 29 Cesáreo Fernández Martínez
Introducción al 80C167
Ejemplo de manejo de P2 en C
• Lee entradas, efectúa cierta operación con las mismas, pone el resultado en los diodos.
• ¿Qué operación se realiza con el dato introducido mediante los interruptores?
#include <reg167.h>void main(void){
int lect,temp1,temp2;
DP2 = 0x00ff;while (1) {
lect = P2;temp1 = lect & 0x0f00; temp1 = temp1 >> 8;temp2 = lect & 0xf000; temp2 = temp2 >> 12;P2 = ~(temp1 + temp2);
}}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 30 Cesáreo Fernández Martínez
Introducción al 80C167
Ejemplo de manejo de P2 en C
• De una forma más compacta
#include <reg167.h>void main(void){
DP2 = 0x00ff;while (1) {
P2 = ~(((P2 & 0x0f00) >> 8) + ((P2 & 0xf000) >> 12));
}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 31 Cesáreo Fernández Martínez
Introducción al 80C167
Programación avanzada en Ensamblador
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 32 Cesáreo Fernández Martínez
Introducción al 80C167
Ejemplo con etiquetas (ensamblador en PC)
• Las etiquetas facilitan la programación en ASS
• Los campos que forman una instrucción en ASS
• Los campos etiqueta y comentario son opcionales– TAB si no se usa el campo de etiqueta
MOV R0,#1 ; r0 (i)MOV R1,#1 ; auxiliar
bucle: CMP R0,#5 ; if i>NJMPR cc_sge,fin ; then goto ´fin’ADD 0fa00H,R1 ; j += 1ADD R0,#1 ; i += 1JMPS bucle ; = jmpr cc_uc,
fin:
etiqueta: operación operandos ;comentario
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 33 Cesáreo Fernández Martínez
Introducción al 80C167
Programando en ensamblador con etiquetas
• Línea de ensamblador típica– etiqueta: operanción operandos ; comentario
• El primer carácter de la etiqueta en columna 1• Campos separados por “tabs”• El campo de “etiqueta” se puede suprimir (poner un “tab”)
• Usando etiquetas
Ini: mov r0, #1..
Jmpr cc_uc, ini
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 34 Cesáreo Fernández Martínez
Introducción al 80C167
Tareas que realiza el programa ensamblador
• El programa ensamblador (A166)– Traduce el fuente (.a66) a código máquina (.obj)
– Cada instrucción tiene su código binario. Ejemplos:
– mov Rx, Ry en código máquina F0xy H• donde x e y están codificados en 4 bits cada uno de ellos (los
diferentes modos de direccionamiento van en el campo de instrucción)• Esta instrucción completa usa 16 bits (2 bytes)
– mov reg, # dato 16 en código máquina E6reg Dato16• donde reg esta codificado en 8 bits • Esta instrucción completa usa 32 bits (4 bytes)
• Resuelve los valores de las etiquetas– Lleva un contador direcciones en memoria de las instrucciones
• La etiqueta toma el valor de la dirección de memoria de la instrucción asociada
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 35 Cesáreo Fernández Martínez
Introducción al 80C167
Instrucción MOV.
• Directo a registro– mov r0,r1 ; R0 <- R1
• Inmediato– mov r0,#3 ; R0 <- 3 (no olvidar # !)
• directo a memoria– mov r0,0fa00H ; R0 <- Mem[fa00 H]
• Indirecto (“normal”, post-incremento, pre-decremento)– mov r0,[r1] ; R0 <- Mem[R1] (R1 Puntero)
– mov r0,[r1+] ; R0 <- Mem[R1], R1 <- R1 + 2
– mov r0,[-r1] ; R1 <- R1 - 2, R0 <- Mem[R1]
– mov r0,[r1+#4] ; R0 <- Mem[R1+#4]
• A nivel de byte– movb rl0,#3 ; R0 <- 3
– movb rh0,[r1+] ; R0 <- Mem[R1], R1 <- R1 + 1
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 36 Cesáreo Fernández Martínez
Introducción al 80C167
Mov: Flags. Extensión de signo.
• Flags– Mov actualiza N y Z
• p.e. se puede usar “jmpr cc_eq,dir” después del Mov.
• Extensión de signo– Movbz
• Carga el byte en parte baja, extiende (a los 16 bits) con ceros
– Movbs• Carga el byte en parte baja, extiende (a los 16 bits) con bit de signo
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 37 Cesáreo Fernández Martínez
Introducción al 80C167
Little/Big Endian
• En la operación (16 bits)– mov r0,0fa00H ; R0 <- Mem[fa00 H]
• El byte (8 bits) almacenado en la posición 0fa00H
– Va a la PARTE BAJA del REGISTRO (a RL0)
– El byte almacenado en fa01 va a la PARTE ALTA (RH0)
• El C167 es un Little-Endian
• En los procesadores MOTOROLA– Al revés
– En ambos casos NO se permite extraer un word (16 bits) de una dirección impar de memoria.
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 38 Cesáreo Fernández Martínez
Introducción al 80C167
Programando con etiquetas (para datos)
• La pseudoinstrucción EQU permite dar nombres a los distintos datos de programa– Variables (posiciones de memoria, ej 0fa00h)
– Constantes
var1 equ 0fa00hvar2 equ 0fa01h
MOVB RL0,var1MOVB RL1,var2MOVB var2,RL0MOVB var1,RL1
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 39 Cesáreo Fernández Martínez
Introducción al 80C167
Instrucciones aritméticas
• Aritmética en “Coma fija complemento a 2”– Números positivos: bit más significativo (bit 15) a 0.
– Números negativos: bit más significativo (bit 15) a 1.• -1 -> FFFF H, -2 -> FFFE H, ...., - 2^15 -> 8000 H
• Sumando dos positivos “nos vamos a los negativos”– 7FFF H + 1 = 8000 H ! (“Overflow”)
• Instrucción Add– Add Rx,op ; op: cualquier modo direccionamiento
– Add op,Rx ; menos “ortogonal” (que Mov)
• Flags– V = 1 si “Overflow” (cambio de signo)
– C = 1 si “Carry” (acarreo, no cabe el resultado en 16 bits)
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 40 Cesáreo Fernández Martínez
Introducción al 80C167
Otras instrucciones aritméticas
• ADDB. Suma a nivel de byte
• SUB. Resta
• SUBB. Resta a nivel de byte
• NEG. Complemento a 2 de un número (número “negado”).
• MUL. Multiplica números con signo.
• MULU. Multiplica números sin signo.
• DIV/DIVU. Divide (con y sin signo).
• MUL Rx,Ry ; Dos GPR’s
– Resultado en 32 bits en registro MD• MDL: Parte baja de MD (16 bits).• MDH: Parte alta de MD (16 bits).
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 41 Cesáreo Fernández Martínez
Introducción al 80C167
Instrucciones lógicas y desplazamientos.
• Lógicas. AND, OR, XOR, CPL– And Rx,op ; op: cualquier modo direccionamiento
– And op,Rx ; menos “ortogonal” (que Mov)• Mismos modos direccionamiento de ADD• Actualiza flags Z y N (C y V quedan a 0)
• Desplazamientos y “rotates”– Shl op1,op2
• Desplaza a la izquierda op1, el número de posiciones indicadas en op2• Introduce ceros por la derecha
– Rol op1,op2 • Desplaza a la izquierda op1, el número de posiciones indicadas en op2• El bit que sale por la izquierda se introduce por la derecha
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 42 Cesáreo Fernández Martínez
Introducción al 80C167
Control de flujo de programa. Saltos.
• Sin condición– Jmpr cc_uc, dir ; “dir” dirección de memoria
• Con condición. Ej:– cmp op1,op2 ; Instrucción que actualiza el flag Z
– jmpr cc_eq, dir ; si Z = 1
• Ejemplos de condición– cc_eq ; Z=1 (operandos iguales)
– cc_ ne ; Z=0 (operandos distintos)
– cc_ sgt ; op1 > op2 con signo
– cc_sge ; op1 >= op2 con signo
– cc_ugt ; op1 > op2 sin signo
– cc_sle ; op1 < = op2 con signo• etc: todas las combinaciones
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 43 Cesáreo Fernández Martínez
Introducción al 80C167
Saltos “a nivel de bit”
• Salto si el bit está a 1– jb bit, dir
• Salto si el bit está a 0– jnb bit, dir
• Sólo en zonas bit a bit
• Otros (Tiempo Real)– jbc (jump if bit set and clear)
– jnbs (jump if bit clear and set)
SFR’s (bit)
F600 H
FC00 H
FD00 H
FFFF H
Stack
GPR’s
SFR’s
Bit a bit
FF00 H
FE00 H
RAM
SFR’s
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 44 Cesáreo Fernández Martínez
Introducción al 80C167
“move” a nivel de bit
• Poner un bit a 1– bset bit
• Poner un bit a 0– bclr bit
• Mover un bit– bmov bitd, bits
• Lógicas (a nivel de bit)– band
– bor
– bxor
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 45 Cesáreo Fernández Martínez
Introducción al 80C167
C y Ensamblador
• if ( )– Alto nivel
– Ensamblador
if (a == b)a = 0;
MOV R0,aCMP R0,bJMPR cc_ne,nextMOV R0,#0MOV a,R0
next:
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 46 Cesáreo Fernández Martínez
Introducción al 80C167
Bucles
• for ( )– Alto nivel
– Ensamblador
for (i=START; i <= STOP; i++){a = STOP - i;
MOV R0,#START ; r0 (i)MOV R1,#STOPSUB R1,R0 ; r1 (STOP-START)JMPR cc_uc,test
for: MOV a,R1SUB R1,#1ADD R0,#1 ; i += 1
test: CMP R0,#STOPJMPR cc_sle,for ; i <= STOP
next:
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 47 Cesáreo Fernández Martínez
Introducción al 80C167
Bucles II
• for ( )– Alto nivel
– Ensamblador
for (i=START; i <= STOP; i++){a = STOP - i;
MOV R0,#START ; r0 (i)MOV R1,#STOPSUB R1,R0 ; r1 (STOP-START)
for: MOV a,R1CMPD1 R1,#0 ; hasta r1 = -1JMPR cc_sge,for ; i <= STOP
next:
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 48 Cesáreo Fernández Martínez
Introducción al 80C167
Otro ejemplo
• while ( )– Alto nivel
– Ensamblador
i = 0;while (i<10) {
a[i] = i; i += 1;}
MOV R0,#0MOV R1,#1MOV R2,#0fa00h
otro: CMP R0,#10 JMPR cc_sge,nextMOV [R2],R0ADD R0,R1ADD R2,#2JMS otro
next:
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 49 Cesáreo Fernández Martínez
Introducción al 80C167
Directivas. “Pseudoinstrucciones”
• El ensamblador de Keil (Siemens) no tiene ORG !
• Section: Comienzo de una sección– De código (programa) ó datos, a partir de una POS de memoria
– Ends: Cierra la sección
• Proc : Comienzo de un procedimiento (subrutina/función)– Endp: Cierra el procedimiento
• dsw: Reserva espacio para un word (dsb: para un byte)
• equ: Fuera de las secciones– Define una constante/variable (para esto último se prefiere dsw)
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 50 Cesáreo Fernández Martínez
Introducción al 80C167
Ejemplo completo
• Las directivas a usar en el ”for” anterior :
$nonsegmented
D100 section data at 200Hj dsw 1 ; datosD100 ends
ej section code at 300Hej1 proc NEAR
MOV R0,#START ; código....
fin: nop ; código (final)ej1 endpej ends
end
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 51 Cesáreo Fernández Martínez
Introducción al 80C167
Subrutinas (funciones)
• f(x), ejemplo pow2(x)– Alto nivel
– Ensamblador
pot = pow2(n);
MOV R1,#n ; maincall pow2 ; llamada (pow2) . .
Pow2: MOV R0,#1 ; 2^nSHL R0,R1RET ; Vuelta a main
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 52 Cesáreo Fernández Martínez
Introducción al 80C167
Stack
• ¿Cómo se encuentra la dirección de vuelta?– Está almacenada en el STACK
• CALL– SP <- SP - 2
– (SP) <- IP ; almacena la dirección de vuelta en el stack
– IP <- d_pow2 ; IP apunta a la dirección de pow2 (primera
instrucción)
• RET– IP <- (SP)
– SP <- SP + 2 ;Todo queda como estaba antes de llamar a
pow2
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 53 Cesáreo Fernández Martínez
Introducción al 80C167
Push y Pop
• PUSH R0– SP <- SP - 2
– (SP) <- R0 ; guarda R0 en el stack
• POP R0– R0 <- (SP)
– SP <- SP + 2 ; recupera R0 (vacía stack)
• Push y Pop sirven para poder “reutilizar” los GPR’s en las funciones llamadas (dentro de la función se comportan como las variables locales de C)
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 54 Cesáreo Fernández Martínez
Introducción al 80C167
Ejemplo: atoi
• Alto nivel. “Prototipo”:
– int atoi(char s[ ] ) ;
int atoi(char s[]) {int i,n;
n = 0;for(i=0; s[i] >= ’0’ && s[i] <= ’9’; i++)
n = 10 * n + (s[i] - ’0’);return n;
}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 55 Cesáreo Fernández Martínez
Introducción al 80C167
atoi en ensamblador
atoi: push r1 ; r1: puntero al string, r4: resultado push r10 ; r10 : variable “local” mov r4,#0 mov r10,#10for: mov r5,#0 movb rl5,[r1+] cmp r5,#'0' jmpr cc_slt,fin ; salto si carácter < '0' cmp r5,#'9' jmpr cc_sgt,fin ; salto si carácter > '9' mul r4,r10 ; n = 10 * n
mov r4,mdl sub r5,#'0' ; s[i] - '0' add r4,r5 ; s10 * n + [i] - '0' jmpr cc_uc,forfin:
pop r10 ; r10 no cambia (r5,mdl y mdh si) pop r1 ; r1 apunta a la base del string ret
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 56 Cesáreo Fernández Martínez
Introducción al 80C167
Ejemplo: itoa
• Alto nivel. “Prototipo”:
– int itoa(int n, char s[ ] ) ;
#define SMAX 6
int itoa(int n, char s[]) {int i = SMAX;
for(s[--i] = ’\0’; n/10 > 0; n /= 10) s[--i] = n % 10 + ’0’;
s[--i] = n % 10 + ’0’; }
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 57 Cesáreo Fernández Martínez
Introducción al 80C167
itoa en ensambladorMAXS equ 6 ; r1: puntero al string, r8: número a convertir itoa: push r1 push mdl push mdh push r10 add r1,#MAXS movb [-r1],#0 mov r10,#10 ;divisor mov mdl,r8 ;dividendofor: div r10 mov r4,mdh ;mdl:cociente, mdh:resto add r4,#'0' movb [-r1],rl4 cmp mdl,#0 jmpr cc_ne,forfin: pop r10 pop mdh pop mdl pop r1 ret
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 58 Cesáreo Fernández Martínez
Introducción al 80C167
Periféricos: Timer’s y Vía Serie
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 59 Cesáreo Fernández Martínez
Introducción al 80C167
Timer’s
• Ligados a la CAPCOM– Los usamos como timer’s de propósito general
• Registros de programación (SFR’s)– Registro de control: T01CON
– Registro de datos (contador): T0
– Registro de recarga: T0REL
• T01CON– T0I: Pre-escalado
– T0M: Modo (timer/counter)
– T0R: Bit Start/Stop
T0I
2 0
T0M
34
---
5
T0R---
67
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 60 Cesáreo Fernández Martínez
Introducción al 80C167
Funcionamiento
• Cuenta hacia arriba– Desde el valor inicial de T0, hasta FFFF H
• Rebose (bit T0IR)– En el paso de FFFF H a 0000 H
– T0 se carga con el valor almacenado en T0REL• Primera cuenta de T0 a FFFF H• Las siguientes cuenta va de T0REL a FFFF H
– El rebose queda registrado en el bit T0IR del registro T0IC
T0T0Iclk
T0IR
T0REL
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 61 Cesáreo Fernández Martínez
Introducción al 80C167
Dos niveles de ajuste
• Ajuste “Grueso”: Pre-escalado (T0I)– 000 8
– 001 16
– 010 32
– ....
– 111 1024
• Ajuste “Fino”– Valor en T0 (T0REL para ondas periódicas)
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 62 Cesáreo Fernández Martínez
Introducción al 80C167
Ejemplo de timer
• “leds a ritmo de reloj”
#include <reg167.h>#define PERIOD -2500main() {
T01CON = 0x00; // timer a 2.5 MHzT0REL = PERIOD;T0 = PERIOD;T01CON |= 0x40; // StartDP2 = 0x00FF;P2 = 0;
while (1) {while(!T0IR) ; // bucle de espera P2 ^= 0xFFFF;T0IR = 0; // flag rebose = 0
} }
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 63 Cesáreo Fernández Martínez
Introducción al 80C167
Comunicación serie asíncrona
• Convierte datos serie en paralelo y viceversa
• Nivel alto en descanso (sin tráfico)
• Datos encapsulados entre bits de arranque y parada.– Comenzando por el Least Singnificant Bit (LSB) First (primero)
1001..0
1 0 0 1
Start Stop
Rx
Tx
8 bits
Paralelo
S0TBUF / S0RBUF
(LSB)
1 0
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 64 Cesáreo Fernández Martínez
Introducción al 80C167
Vía serie S0 del 80C167
• Dos registros de datos: S0TBUF/S0RBUF
• Tx y Rx son los pines P3.10 y P3.11, respectivamente (DP3.10 = 1 y DP3.11 = 0).
• El registro de control S0CON (16 bits) contiene:– Número de bits/carácter
– Bits de control de errores (paridad, frame, etc)
– Bits de estado de errores.
– Modo loop-back
– Control de baud-rate.
• Ejemplo– S0CON = 0x8011; //Baud rate E, Recep. E., 8
bit/c
• Baud Rate Generator – Controla la velocidad de transmisión (en base al clk de muP).
– S0BG = 0x40 // 9600 baud (S0BG=0x10; 38400)
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 65 Cesáreo Fernández Martínez
Introducción al 80C167
Programa hello.c
• Cabecera de los programas que usan la vía serie
• Se compila con la etiqueta MCB167 definida cuando no se quiere que se (re)inicialice la vía serie– C166 HELLO.C CODE DEBUG MOD167 DF(MCB167)– (S0RIC/S0TIC control de interrupciones de vs)
#ifndef MCB167 /* do not initialize if you use Monitor-166 */ P3 |= 0x0400; /* SET PORT 3.10 OUTPUT LATCH (TXD) */ DP3 |= 0x0400; /* SET PORT 3.10 DIRECTION CONTROL (TXD OUTPUT) */ DP3 &= 0xF7FF; /* RESET PORT 3.11 DIRECTION CONTROL (RXD INPUT) */ S0TIC = 0x80; /* SET TRANSMIT INTERRUPT FLAG */ S0RIC = 0x00; /* DELETE RECEIVE INTERRUPT FLAG */ S0BG = 0x40; /* SET BAUDRATE TO 9600 BAUD */ S0CON = 0x8011; /* SET SERIAL MODE */#endif
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 66 Cesáreo Fernández Martínez
Introducción al 80C167
Polling
• Timer
• Vía serie (transmisión)
• T0IR y S0IR en registros de control de interrupciones
void espera(int tiempo) {... // inicializa timer (tiempo)while(!T0IR) ; // bucle de espera (polling)T0R = 0; // para el timerT0IR = 0; // bandera de rebose a 0
}
void puts(char *ps) { while (*ps) {
while(!S0TIR) ; // espera S0TBUF vacío (polling)S0TBUF = *ps++; // pone carácter a enviar (S0TBUF)
// S0TIR se pone automáticamente a 0 }}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 67 Cesáreo Fernández Martínez
Introducción al 80C167
Interrupciones (Introducción)
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 68 Cesáreo Fernández Martínez
Introducción al 80C167
Interrupciones
• Creadas para evitar los tiempos de espera de polling (desperdicio de ciclos de CPU).
• Mecanismo básico– (inicialización del periférico)
– Durante el “trabajo normal” el periférico solicita atención.
– El procesador suspende el “trabajo normal”
– Atiende al periférico
– Continúa con el “trabajo normal” (en el lugar interrumpido).
Programa principal
Interrupción
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 69 Cesáreo Fernández Martínez
Introducción al 80C167
Interrupciones II (en más detalle)
• El periférico solicita interrupción (línea IRQ bus control)– Ej: T0IR, S0TIR, etc (hasta 56 flags de interrupt request)
• El muP completa la instrucción actual (código máquina).
• El muP guarda PSW y PC (CSP+IP) en el Stack (de CPU).
• El muP lanza un ciclo de reconocimiento de interrupt.– Determina qué periférico ha solicitado la interrupción
• De entre todos ellos (56) el de mayor prioridad (16 niveles de prioridad. La prioridad se indica en el registro de control de la Interrupc.).
– Salta a la función de tratamiento de la interrupción• Tabla de “vectores de interrupción” . Vector: dirección de comienzo de
la subrutina de tratamiento de la interrupción.
– Durante el tratamiento en PSW se pone el nivel de la interrupción.
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 70 Cesáreo Fernández Martínez
Introducción al 80C167
Recursos 167 para tratamiento interrupciones
• Por cada fuente interrupción (56) tenemos:– Un vector de interrupción
• Tabla de vectores en RAM desde 0000H a 0100H (un salto a una subrutina de tratamiento para cada interrupción)
– Un registro de control
• Registro de control
– ILVL: Nivel de la interrupción (0 a 15. Nivel 15 nivel más alto)– xxIE: Bit de habilitación de la interrupción (I Enable)– xxIR: Bit de petición de interrupción (I Request, ej T0IR)
GLVLILVL
015 2
xxIExxIR
67815
xxIC
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 71 Cesáreo Fernández Martínez
Introducción al 80C167
Y además ...
• Registro de estado del procesador (PSW)
– Bit 11, IEN : Bit de habilitación global de interrupciones
• Prioridad del programa en curso en PSW (bits 12 a 15, ILVL) = Prioridad de la interrupción en curso– Bits de ILVL del xxIC de la interrupción en curso (todos a 0 cuando se
ejecuta main)
• ¿Por qué se salva en el stack no solo el PC sino que se salva también el PSW?
0711
Flags-IENILVL
1215
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 72 Cesáreo Fernández Martínez
Introducción al 80C167
Ejemplo
• Interrupción de timer 0 (main).
• Variable global: flag (enlace con la f. Interrupción).
void main(void) {
T01CON = 0x06; T0REL = PERIOD;/* set reload value */ T0 = PERIOD; T0IC = 0x44; /* set T0IE and ILVL = 1 */ IEN = 1; /* set global interrupt enable flag */ T0R = 1; /* start timer 0 */
while(1) { while(!flag) ; P2 ^= 0xffff ; flag = 0; }}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 73 Cesáreo Fernández Martínez
Introducción al 80C167
Ejemplo • Interrupción de timer 0 (subrutina de trat. de interrupt)
• Las funciones de tratamiento de interrupción son:– De tipo void xx(void) interrupt num_vect;.– La comunicación con main: con variables globales.
• Las funciones de tratamiento de interrupción son:– De tipo void xx(void) interrupt num_vect;.– La comunicación con main: con variables globales.
#include <reg167.h>#include <stdio.h>#define PERIOD 0
int flag;
void timer0(void) interrupt 0x20 {
flag = 1;}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 74 Cesáreo Fernández Martínez
Introducción al 80C167
Tratamiento interrupts
• Reglas para escribir una función de tratamiento de interrupción CORRECTA:
• Escribir funciones cortas– A mayor prioridad, menos líneas de código (es tiempo de CPU que
se “roba” a otras interrupciones de menor nivel, y a la propia interrupción con lo que se pueden “perder” interrupciones).
– No usar printf (incluye la librería matemática).
• En Ass además– Inicializar el vector de interrupción (“a mano”).
– Salvar todos los registros que se usan en la f. Trat. Interr. (cambio de contexto) en el Stack! (para recuperalos a la salida).
– ¿Que puede suceder si no se hace así?.
– Comprobar (si es posible) a la entrada de la función de tratamiento el xxIR (flag de petición de interrupción).
– Retorno de interrupción RETI (RET retorno de función “normal”)
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 75 Cesáreo Fernández Martínez
Introducción al 80C167
Ejemplo: Reloj/Calendario
• Programa principal
#include <reg167.h>#include <stdio.h>#define PERIOD -2500
int ticks, sec, min, hour;
void main(void) {
ticks = sec = min = hour = 0;
T01CON = 0x00; T0REL = PERIOD; /* set reload value */ T0 = PERIOD; T0IC = 0x44; /* set T0IE and ILVL = 1 */ IEN = 1; /* set global interrupt enable flag */ T0R = 1; /* start timer 0 */
while(1) ;}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 76 Cesáreo Fernández Martínez
Introducción al 80C167
Interrupción
• Los contadores se llevan en la interrupción
• Main se encargará de utilizar estos contadores
void timer0(void) interrupt 0x20 {
ticks++;if (ticks == 1000) {
ticks = 0; sec++;if (sec == 60) {
sec = 0; min++;if (min == 60) {
min = 0; hour++;if (hour == 24)
hour = 0; }
}}
}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 77 Cesáreo Fernández Martínez
Introducción al 80C167
Un ejemplo más
• Supuesto que la vía serie está inicializada
char buffer[MAXB], *ps;int bandera;
void main(void) {
S0TIC = 0x48; /* set S0TIE and ILVL = 2 */ IEN = 1; /* set global interrupt enable flag */ bandera = 0;
while(1)if (!bandera){
strcpy(buffer,”mensaje”);bandera = 1;ps=buffer;S0TIC |= 0x80;
}}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 78 Cesáreo Fernández Martínez
Introducción al 80C167
Interrupción
• La interrupción “salta” cuando acaba de salir un carácter de S0TBUF
• Si en la subrutina de tratamiento – No se pone carácter en S0TBUF– No “salta” una nueva interrupción !!
• ¿Para qué sirve la bandera?– main no se pelea con main
– MUTEX: Mutua Exclusión en el acceso a buffer
void vs(void) interrupt 0x2A {
if (*ps)S0TBUF = *ps++;
elsebandera = 0;
}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 79 Cesáreo Fernández Martínez
Introducción al 80C167
Lenguaje C para Microprocesadores
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 80 Cesáreo Fernández Martínez
Introducción al 80C167
C para muP
• Tipos básicos– Enteros
– Flotantes
– Variables lógicas
– Caracteres (char’s)
• Control/Operadores/Expresiones lógicas
• Cadenas de caracteres/Vectores
• Punteros
• Funciones (variables locales/globales)
• Entrada/Salida (I/O, en ”bajo nivel”)
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 81 Cesáreo Fernández Martínez
Introducción al 80C167
Enteros
• Números en coma fija, complemento 2 (-2^n-1 a 2^n-1 -1)– int (16 bits) : -32768 a 32767
– char (8 bits): -128 a 127
– long (32 bits): -2^31 a 2^31-1
• Enteros en distintas bases– int i = 0xff; // Hexadecimal (-1)
– int i = 0377; // Octal (-1)
– int i = -1; // Decimal
• Enteros sin signo– unsigned char c = 0xff; // de 0 a 2^n -1
• Operadores– Unitarios: -, ++, --
– Binarios: *, /, % // 2/5 ?
– Binarios: +, -
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 82 Cesáreo Fernández Martínez
Introducción al 80C167
Enteros II• Printf
– printf(“El valor es %6d”, i); // qué es el 6?
– scanf(“%d”, &i);
– printf(“El valor es %x”, i); // en hexadecimal
• Promoción de enteros – unsigned int i;
– unsigned char c = 0xff;
– i = c;
– ¿Cuanto vale i?
• Promoción de enteros – int i;
– char c = 0xff;
– i = c;
– ¿Cuanto vale i?
• En ensamblador hay instrucciones específicas (promoc.)
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 83 Cesáreo Fernández Martínez
Introducción al 80C167
Flotantes
• Distintas precisiones– float // Simple precisión
– double // Doble precisión
– long double
• printf– printf(“El valor es %6.2f”, 5.0/9); // No olvidar .0 !
• Conversión de tipos– int -> float // Promoción automática
– float -> int // Trunca
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 84 Cesáreo Fernández Martínez
Introducción al 80C167
Variables lógicas
• En C no hay variables lógicas !
• Cualquier variable entera (char, int, long)– Si == 0 // Falso– Si != 0 // Verdadero
• Ejemplo
• Operadores lógicos y de comparación– Lógicos: && (AND lógico), || (OR lógico), ! (NOT lógico)– !=, ==, <, >, <=, >= // No olvidar == en: if, while, for, ...
int i = 5;
while (i) {printf(“%d \n”, i);-- i;
}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 85 Cesáreo Fernández Martínez
Introducción al 80C167
Instrucciones de control
• If– if (e) { } // e: variable/expresión lógica
• if “encadenados” y “anidados”
• ¿ Con quien va el else? (Cuidado con la indentación !)
• Con 1 instrucción (en el bloque), se pueden omitir las llaves
if(e1) {
}else if (e2) {
}else {
}
if(e1) { if (e2) {
} else {
}}
if(e1) { if (e2) {
}else printf (” ”);}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 86 Cesáreo Fernández Martínez
Introducción al 80C167
Operadores bit a bit y desplazamientos
• Bit a bit:– & (AND bit a bit)
– | (OR bit a bit)
– ^ (XOR bit a bit)
– ~ (Unitario: Complemento a 1)
• Desplazamientos:– >> (Desplazamiento a derecha, divide potencia de 2)
– << (Desplazamiento a izquierda , multiplica potencia de 2)
• Ejemplo:
a = P2; a &= 0x000F; // ¿Cuanto vale a?a = P2; a |= 0x000F; // ¿Cuanto vale a?a = P2; a >>= 4; // ¿Cuanto vale a?a = P2; a <<= 4; // ¿Cuanto vale a?
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 87 Cesáreo Fernández Martínez
Introducción al 80C167
Expresiones lógicas. Ejemplos.
• Asignación vs. Igualdad.
• And lógico vs. Bit a bit
• Otros ejemplos
if(a == b) {
}
if(a = b) {
}
if(a && b) {
}
if(a & b) {
}
if(a & 0x0f) {
}
if(a = getchar()) {
}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 88 Cesáreo Fernández Martínez
Introducción al 80C167
Precedencia de operadores
• En orden de mayor a menor
[ ] // Vectores (por índice)! ~ ++ -- & * // not lógico y bit a bit, puntero/ * % // Aritméticos+ ->> << // Desplazamientos< > >= <= // Relacionales== !=& // Bit a bit^|&& // Lógicos||= += *= (etc) // Asignaciones
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 89 Cesáreo Fernández Martínez
Introducción al 80C167
Cadenas de caracteres
• Vector de char’s (8 bits/char). Acaban con un ’\0’ (8 bits a 0)
• Se escriben con: printf(”%s”,s);
• Otra forma (programado “a mano”)
main ( ) {char s[] = ”Hola”; // El compilador pone el 0 del finalprintf(“%s \n”, s);
}
main ( ) {char s[25]; // espacio suficientes[0]=’H’; s[1]=’o’; s[2]=’l’; s[3]=’a’; s[4]=’\0’; // MUY IMPORTANTE
}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 90 Cesáreo Fernández Martínez
Introducción al 80C167
scanf(”%d”, &numero); ” en bajo nivel”
• La siguiente función (getentero) hace el trabajo
• La función gets– Prototipo: char *gets(char s[ ]);– Deja los caracteres (tecleados) en la cadena apuntada por s (pone
el ’\0’ del final)– Devuelve un ”puntero” a la base de s (puntero NULL si error)
int getentero (void ) {char s[MAXINT]; if(gets(s))
return atoi(s);else
return 0;}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 91 Cesáreo Fernández Martínez
Introducción al 80C167
Punteros
• El puntero es una VARIABLE (en memoria) que almacena la DIRECCIÓN de otra VARIABLE (apunta a ...)
• Todos los punteros ocupan lo mismo en memoria– ¿Cuantos bits se necesitan para almacenar una dirección/puntero en el
167?
char
Apuntado
Char *
Puntero
intint *
longlong *
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 92 Cesáreo Fernández Martínez
Introducción al 80C167
Punteros en Ass y C
• En Ass
• En C
• *pi=7; // ¿i1?, ¿i2? ++*pi; // ¿i1?
MOV R0,#5MOV 200H,R0MOV R1,#200H ; R1 punteroMOV R2,[R1] ; ¿R2?
main() {int i1,i2;int *pi;
i1 = 5;pi = &i1;i2 = *pi; // ¿i2?
}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 93 Cesáreo Fernández Martínez
Introducción al 80C167
Cadenas y punteros
• Versión con índices
• Los índices válidos de la cadena van de 0 a n-1.
void strcpy(char cadd[],char cads[] ) {int i=0;while (cads[i]) {
cadd[i] = cads[i];i++;
}cadd[i] = cads[i]; // 0 del final
}
main ( ) {char s1[] = ”Hola”; char s2[25]; // espacio suficiente
strcpy(s2,s1);}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 94 Cesáreo Fernández Martínez
Introducción al 80C167
Cadenas y punteros II• Versión con punteros
• ¿Copia el 0 del final?
• ¿Copia el 0 del final?
void strcpy(char *pd,char *ps) { // PUNTEROSwhile (*pd++ = *ps++) ;
}
main ( ) {char s1[] = ”Hola”; // CADENASchar s2[25];
strcpy(s2,s1);}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 95 Cesáreo Fernández Martínez
Introducción al 80C167
Cadenas y punteros III
• Ambas declaraciones de punteros son equivalentes– char s[ ] y char *ps
• Lo que se pasa a la función cuando hacemos– strcpy(s2,s1);
• Son las DIRECCIONES de s2 y s1
• strcpy carga ambas direcciones en sendos punteros
• RESERVAR siempre suficiente ESPACIO en la CADENA DESTINO !!!!!– El puntero no es más que “un mecanismo alternativo” de acceso a
la cadena.
– pd[25] está fuera de la cadena (escribe en una variable DISTINTA de la cadena apuntada por pd !)
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 96 Cesáreo Fernández Martínez
Introducción al 80C167
Cadenas y punteros IV
• Otra forma (equivalente):
• Pero esto último es demasiado redundante – No usar ! .
void strcpy(char *pd,char *ps) {while (*pd++ = *ps++) ;
}
main ( ) {char s1[] = ”Hola”; // cadenachar s2[25]; // cadenachar *ps, *pd; // punteros
ps = &s1[0];;pd = &s2[0];strcpy(pd,ps);
}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 97 Cesáreo Fernández Martínez
Introducción al 80C167
Vectores
• Los vectores pueden ser de cuaquier tipo básico (o incluso de tipos propios: estructuras).– El 0 es un elemento más (no acaban en 0).
• Declaración– int vec[25]; // Reserva espacio para 25 int’s– Indices válidos de 0 a 24
• Inicialización– vec [0] = 57; vec [1] = 34; etc.
• Declaración e inicialización– int vec[ ] = {57, 455, ....}; // No aportar dimensión
• El nombre del vector es una constante– No puede aparecer a la izquierda del signo = !!!
• Un puntero es una variable
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 98 Cesáreo Fernández Martínez
Introducción al 80C167
Ejercicio: “Volcado” de memoria
• Cambiando el tipo de lo apuntado
• Puntero– Dirección de memoria– Tipo de lo apuntado
main ( ) {unsigned char mc[] ={1, 2, ’1’, ’2’};unsigned char *pc, c;unsigned int *pi,i;
pc = mc;c = *pc++; // Cuanto vale cc = *pc; // Cuanto vale c
pi = (unsigned int *)mc;i = *pi++; // Cuanto vale i (INTEL/MOTOROLA)i = *pi; // Cuanto vale i
}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 99 Cesáreo Fernández Martínez
Introducción al 80C167
Tamaños Tipos (revisados)
• Comentar el cast– Procesos de pérdida de información
• No llevan cast• Ej: puntero int -> puntero void
– Procesos de ganar información (necesitan el cast)• Dar tipo al contenido de una dirección• Ej: puntero void -> puntero int
• Tipos: con y sin signo– El dato sacado de la memoria se asigna a una variable sin signo
(si se quiere imprimir en valor absoluto)• Para que de esta forma si se pasa a un itoa, el char no promocione a
int con signo (acaban saliendo números negativos!)
• Los programas para micros llevan muchos unsigned !
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 100 Cesáreo Fernández Martínez
Introducción al 80C167
Aritmética de punteros
• El puntero “avanza” según el tamaño de lo apuntado– p++; - -p; // una posición si apuntan a char
– p++; - -p; // dos posiciones si apuntan a int
– p++; - -p; // cuatro posiciones si apuntan a long int, etc.
• Acceso a la i-ésima posición del vector– *(p+i)
– p[i]
• Los punteros se pueden restar (resultado: desplazamiento)
• Los punteros no se suman !
• A un puntero se le puede sumar un desplazamiento – Este desplazamiento no es el número de bytes
– Es el número de elementos del tipo apuntado
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 101 Cesáreo Fernández Martínez
Introducción al 80C167
Funciones
• Las funciones son un elemento básico para la estructuración de los programas– Hacer funciones cortas y que hagan una sola cosa ! (fáciles de
desarrollar y de depurar, reutilizables)
• Las funciones deben ser declaradas y definidas
• Declaración (prototipo)
• Definición (código)int power(int base, int n) {
int i, p;
p = 1;for (i=1; i<=n; i++)
p = p * base; return p;
}
int power(int base, int n);
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 102 Cesáreo Fernández Martínez
Introducción al 80C167
Prototipo• A incluir en la cabecera de programa cuando las funciones se definen en el fichero de entrada DESPUES de main.
• El prototipo indica– Número y tipo de argumentos (de la función)– Tipo de resultado
• El prototipo indica– Número y tipo de argumentos (de la función)– Tipo de resultado
int power(int base, int n);
main () {printf(”%d %d \n”, 10, power(2,10));
}int power(int base, int n) {
int i, p;
p = 1;for (i=1; i<=n; i++)
p = p * base;return p;
}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 103 Cesáreo Fernández Martínez
Introducción al 80C167
Variables locales/globales
• Variables locales– Argumentos y
– Variables definidas dentro del cuerpo de la función
• Las variables locales se crean en el Stack!– La variable i de una función es DISTINTA de la i de otra (función)!.
• Variables globales– Definidas fuera de las funciones (incluida main)
• Las variables globales se crean en el heap
• “Alcance” (scope) de las variables– Las locales son solo accesibles dentro de la función
– Las globales son comunes a todas las funciones (incluida main)
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 104 Cesáreo Fernández Martínez
Introducción al 80C167
Con variables globales
• Las variables globales son comunes (a main y funciones)
• Las variables globales son peligrosas!– Darles nombres largos (evitan que se puedan actualizar de forma no intencionada).
void power(void);
int base=2, exponente = 10, potencia;
main () {power();printf(”%d %d \n”, exponente,potencia);
}void power(void) {
int i;
potencia = 1;for (i=1; i<=exponente; i++)
potencia *= base;}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 105 Cesáreo Fernández Martínez
Introducción al 80C167
Paso de parámetros
• Los parámetros se puede pasar por– Valor: Tipos básicos (atómicos: char, int, long, etc.).
– Referencia: Tipos compuestos (vectores, cadenas).
• Paso por referencia para tipos atómicos. Ejemplo:
void swap(int x, int y) {int temp;
temp = x;x = y;y = temp;
}main () {
int a=5, b=6;swap(a,b);
}
void swap(int *px, int *py) {int temp;
temp = *px;*px = *py;*py = temp;
}main () {
int a=5, b=6;swap(&a,&b);
}
Por Valor Por Referencia
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 106 Cesáreo Fernández Martínez
Introducción al 80C167
Variables en el Stack
• Mediante paso por valor se actúa sobre variables de la función– No hay forma de actuar sobre las variables de main
• Mediante paso por referencia se actúa sobre la variable de main. Ej:– prinf(”%d”, i); scanf(”%d”, &i);
a
b
dir_v
x
y
temp
main
swap
a
b
dir_v
px
py
temp
main
swap
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 107 Cesáreo Fernández Martínez
Introducción al 80C167
¿Cómo se devuelve una cadena?
• Una cadena no se puede devolver vía “return”
• La cadena se crea (define) en main– La función actualiza la cadena de main vía puntero
– La función puede devolver un puntero
• Ejemplo: gets
char *gets (char *ps ) {
while ((*ps++=getchar()) != ’\n’) ;*ps = 0; // 0 del finalreturn ps; // falta control ERR
}
main ( ) {char s[80], *ps;ps = gets(s); // cuanto vale ps-s ?printf(“%s \n”, s);
}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 108 Cesáreo Fernández Martínez
Introducción al 80C167
gets para 167 (por vía serie)
• puts por “polling (recordamos ...)
• Gets por polling (por interrupción funciona mejor)
void puts(char *ps) { while (*ps) {
while(!S0TIR) ; // espera S0TBUF vacío (polling)S0TBUF = *ps++; // pone carácter a enviar (S0TBUF)
// S0TIR se pone automáticamente a 0 }}
char *gets(char *ps) { while (1) {
while(!S0RIR) ; // espera S0RBUF lleno (polling)S0RIR = 0;if ((*ps++ = S0RBUF) == ’\r’)
break; } *ps = 0; return ps;}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 109 Cesáreo Fernández Martínez
Introducción al 80C167
Control de errores
• Las funciones deben devolver código de error– Caso de que algo vaya mal (no hacen printf por pantalla !!)
• La función gets(s) de librería– Devuelve un puntero a la base de s (lo mismo que recibe).
– Devuelve el puntero NULL en caso de error
• Forma de controlarlo (pe. en getentero)
int getentero (void ) {char s[MAXINT]; if(gets(s)!= NULL) //control de errores
return atoi(s);else
return 0;}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 110 Cesáreo Fernández Martínez
Introducción al 80C167
Proyectos en C
• 1) Dividir el programa en funciones
• Diseñar/documentar las funciones haciendo uso de PSEUDOCÓDIGO
• 2) Agrupar las funciones en distintos ficheros– Cada fichero contiene un cierto “grupo de funciones”
– Los grupos de funciones son reutilizables (librerías)
• Cada módulo de librería contiene: – Un fichero con el código fuente (.c)
– Un fichero de declaraciones (.h) a incluir por los usuarios de la lib:• Prototipos de las funciones• Declaraciones de constantes (“define’s”)• Declaraciones de variables externas (“extern’s”)
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 111 Cesáreo Fernández Martínez
Introducción al 80C167
Ejemplo sencillo
• Ejemplo basado en el “filtrado rebotes”– Típico programa de micros (pseudocode cercano a C)
• con un “while (1)” en main• con “actual” y “anterior”
main ( )
contador = 0 anterior = P2 while (1) {
actual = P2if (anterior != actual)
retraso (tiempo)actual = P2if (anterior != actual && actual == 1)
contador++P2 = contadoranterior = actual
}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 112 Cesáreo Fernández Martínez
Introducción al 80C167
Funciones/librerías
• Dos funciones: main y retraso– main: “no sabe nada del retraso (timer)
– retraso: sólo sabe del timer
• Módulo de librería (time), formado por:– time.h : Prototipos de funciones (y “defines”)
– time.c :Fuentes C de nuestra librería (pseudocode)
void retraso (int tiempo);
void retraso (int tiempo)
ini_timer(tiempo)espera_rebose //polling o interrupciónreturn
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 113 Cesáreo Fernández Martínez
Introducción al 80C167
Proyecto
• Ejemplo de creación/utilización de librerías– Los módulos se COMPILAN POR SEPARADO !
• Se “linkan” para obtener el ejecutable
#include <reg167.h>#include ”time.h”#include ”io.h”main (){ inicializaciones while (1) { }
}
#include ”time.h”
void retraso (int tie)
ini_timer espera_rebose return
#include ”io.h”
void puts(char *ps) while (*ps) {
while(!S0TIR) ....
void retraso (int tie); void puts(char *);char* gets(char *);
main.ctime.c
io.c
time.h io.h
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 114 Cesáreo Fernández Martínez
Introducción al 80C167
Variables locales/globales
• Alcance– Locales: En la función en que se definen
– Globales: En el fichero
• Para usar una global definida en otro fichero: extern
• La declaración– No genera código
– Se puede incluir en fichero .h (para usar varias veces)
• NO incluir DEFINICIONES en los .h !!!
int i;int val[MAX];
extern int i;extern int val[MAX];
Fich1.c Fich2.c
Definición Declaración
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 115 Cesáreo Fernández Martínez
Introducción al 80C167
Librerías típicas
• Todas las distribuciones suelen contener– stdio: Entrada salida estándar (stdio.h)
– string: Manejo de strings (string.h)• char * strcpy(char *to, char *from);• char * strcmp(char *to, char *from);• char * strcat(char *to, char *from); etc ,
– stdlib: Librería estandar (stdlib.h)• int atoi(char *s);• char *itoa(int i, char *s); // No viene en la dist, del 167 !• float atof(char *s);
– math: Librería matemática (math.h)• sin• cos• abs, etc
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 116 Cesáreo Fernández Martínez
Introducción al 80C167
Errores de programación C típicos
• Variables sin inicializar
• Tamaños y tipos– Promoción: char -> int, unsigned char -> unsigned int
– Los tipos unsigned se utilizan muy frecuentemente en micros• (ej:Representación de números en hexadecimal)
• Punteros que no apuntan a nada (sin inicializar)
• Acceso fuera del espacio reservado para una cadena– Típicamente usando un puntero– Ej: strcat(cadena_d,cadena_s); // Espacio en cadena_d
• Olvidar el control de errores– Se debe recoger el valor devuelto por la función
– No hacer printf en la función• La función se convierte en “no reutilizable”• “Reportar” el error hacia arriba (main)
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 117 Cesáreo Fernández Martínez
Introducción al 80C167
Teclado y buses externos (hardware)
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 118 Cesáreo Fernández Martínez
Introducción al 80C167
Teclado
• El teclado está conectado a la parte baja de P2
P2.0
P2.3
P2.7
+ 5 V
P2.4
0
1
1
1
1
0
1
1
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 119 Cesáreo Fernández Martínez
Introducción al 80C167
Configuración del teclado
• Filas: Conectadas a las líneas P2.0 a P2.3 (Salidas)
• Columnas: Conectadas a líneas P2.4 a P2.7 (Entradas)– El otro extremo de las líneas forzado a alimentación
• Energización de salidas/Estado de entradas– Con todas las salidas (filas) a 1, entradas (columnas) a 1
– Con Primera salida a 0 (resto de salidas a 1),• una tecla de la primera fila pulsada =>
– Columna correspondiente a 0 (resto de columnas a 1)
– Mismo para el resto de filas
• Nota. El teclado es simétrico !– (Se pueden intercambiar filas por columnas en el texto anterior)
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 120 Cesáreo Fernández Martínez
Introducción al 80C167
Barrido de teclado
• Energizando por filas
• Comprobando el estado de las columnas
• Nota: Completar siempre el barrido !
int barrido ( ) {
for (i=0; i < 4; i++) {P2 = energiza_fila(i);for (j=0; j < 4; j++)
if (energizada_columna(j))tecla = i*4+j;
}return tecla;
}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 121 Cesáreo Fernández Martínez
Introducción al 80C167
Validación de las teclas pulsadas (polling)
• Se compara la tecla pulsada en el barrido anterior con la tecla pulsada en el barrido actual– Se valida la tecla UNA VEZ en el momento que se pulsa!
• tecla es el vector de carátulas del teclado– char teclas = ”123 ....”
main ( )
tant = barrido(); while (1) {
tact = barrido();if (tant != tac)
putchar(teclas[tact]);tant = tact;retraso(tiempo); /* filtrado rebotes */
}}
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 122 Cesáreo Fernández Martínez
Introducción al 80C167
Filtrado de rebotes
+ 5V
• + 5V
+ 5V
t
tratri
ta
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 123 Cesáreo Fernández Martínez
Introducción al 80C167
Buses
CPU
• Tres buses básicos– Bus de Direcciones: del micro a la memoria (y al I/O)
– Bus de Datos: Bidireccional
– Bus Control (distintas líneas en ambos sentidos)
MEM I/O
DATA
ADDRESS
Control
RD
WR
RD
WR
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 124 Cesáreo Fernández Martínez
Introducción al 80C167
Ciclo de acceso a memoria
CPU
• Ejemplo: ciclo de lectura de memoria– Lectura de la posición de memoria: mov R0, fa00
– Secuencia: fa00 -> RADD -> ADD(RD) -> DATA -> R0
MEM
DATA
ADDRESS
RD
RIR0
R1
RADD MRADD
MRDD
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 125 Cesáreo Fernández Martínez
Introducción al 80C167
Un micro de 8 bits
• Tiene 8 bits en el BUS de DATOS– Y típicamente 16 líneas en el de direcciones: 64 Kbyte
• Sistema digital– ROM: para almacenar el programa
– RAM: para datos• e instrucciones en fase de depuración
– I/O: para comunicación con el exterior
• ¿En qué direcciones situamos cada una de estas cosas?
• !Decodificación del mapa de memoria!
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 126 Cesáreo Fernández Martínez
Introducción al 80C167
Decodificación del mapa de memoria
• Por ejemplo: Queremos– RAM en la zona baja del mapa de memoria, direcciones
• 0000 - 7FFF
– ROM en direcciones más altas• 8000 - EFFF
– I/O en direcciones muy altas• F000 - FFFF
• Truco– Fijarse en las líneas altas del bus de direcciones
• Para la RAM: A15 = 0• Para el I/O; A15 =1, A14 =1, A13 =1, A12 =1• Para la ROM: A15 = 1, y A14 ó A13 ó A12 en 0
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 127 Cesáreo Fernández Martínez
Introducción al 80C167
RAM
CPU
• 0000 a 7FFF– 15 líneas directas (las bajas: A0-A14) ¿Tamaño?
– Línea A15 al Chip Select de la RAM ¿En qué rango está activa?
– Las 8 líneas del bus de datos se conectan directamente
RAM
DATA (8 bits)
ADDRESS (A0 - A14)
RD
WR
A15CS
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 128 Cesáreo Fernández Martínez
Introducción al 80C167
I/O
CPU
• F000 a FFFF– 4 líneas altas a 1
– Líneas bajas de acuerdo con el número de registros del periférico (log2 n)
I/O
DATA (8 bits)
ADDRESS (A0 - AX)
CS
A15
A14
A13
A12
RD/WR
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 129 Cesáreo Fernández Martínez
Introducción al 80C167
ROM
• 8000 a EFFF: En el segmento alto (A15=1) excluyendo el (sub)segmento del I/O
• Líneas bajas A0 a A14 directas– Tamaño de la ROM?– Tamaño útil ?
A15
A14
A13
A12
CS (ROM)
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 130 Cesáreo Fernández Martínez
Introducción al 80C167
Buses del 167
CPU
• Los tres buses básicos– Direcciones (P1/P4, unidireccional: De la CPU a la memoria e I/O)
– Datos (P0, bidireccional)
– Control (distintas líneas en ambos sentidos)
MEM I/O
DATA (16 bits)
ADDRESS (24 bits)
Control
RD
WR
RD
WR
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 131 Cesáreo Fernández Martínez
Introducción al 80C167
Ciclo de acceso: Diagrama temporal
• Ciclo de lectura de memoria
1 2 3 4 1
CLK
P1/P4
ADDRESS
ALE
RD#
P0
DATA
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 132 Cesáreo Fernández Martínez
Introducción al 80C167
Organización de la memoria del 167• Bus de datos del 167 (P0): 16 bits
• Bus de datos de las memorias comerciales: 8 bits
• Al 167 la memoria se le conecta en DOS BANCOS
CPU PAR IMPAR
DATA (16 bits)
ADDRESS (23 bits)
CONTROL
A0# BHE#
CS CS
A1-23 A1-23 A1-23
D0-15 D0-7 D8-15
RD/WR
P0
P1/P4
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 133 Cesáreo Fernández Martínez
Introducción al 80C167
Little Endian/Big Endian
• El 167 es un “Little-Endian” (al igual que los INTEL x86)– El Banco PAR está conectado a la PARTE BAJA del bus de datos
• El byte BAJO de un registro va a la dirección PAR de memoria (parte baja registro => parte baja bus de datos)
– Al contrario que en los micros de MOTOROLA
• ¿Y en los accesos a nivel de byte?– movb RL0,0fa001H
XXYYR0
YYXXFA00
LH
FA01
Registro:
Memoria:
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 134 Cesáreo Fernández Martínez
Introducción al 80C167
Decodificación del mapa de memoria
• Selección de distintos bancos de memoria usando los CS’s de las memorias– ROM (solo lectura)
– RAM (lectura/escritura)
– I/O (entrada/salida, se accede como si fuera memoria)
• Los chips de memoria disponen de– 8 líneas de datos
– XX líneas de direcciones (de acuerdo con el tamaño)
– Líneas de control: CS, OE, RD, WR (de acuerdo con el modelo)
• La decodificación del mapa de memoria se encarga de – GENERAR los CS’s de los distintos bancos de memoria (ROM,
RAM, etc.)
– De acuerdo con el mapa de memoria especificado (rangos de direcciones de la ROM, RAM, etc.).
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 135 Cesáreo Fernández Martínez
Introducción al 80C167
Decodificación sencilla
• Situar– ROM en direcciones de 00 0000 a 1F FFFF (2 Mbyte)
– RAM en direcciones de 20 0000 a 3F FFFF(2 Mbyte)
– Un I/O en direcciones de E0 0000 a FF FFFF(2 Mbyte)
• Esto se consigue con un simple decodificador de 3 a 8– En el primer segmento A21/A22/A23 = 0
A23
A22
A21
CS (ROM)
CS (RAM)
CS (PER)
00 0000
20 0000
E0 0000
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 136 Cesáreo Fernández Martínez
Introducción al 80C167
Más de un periférico
• Para ubicar 8 periféricos en el segmento más alto – 256 Kbyte para cada periférico (un periférico no necesita tanto, ya
que se maneja con un par de registros de datos y uno de control).
A20
A19
A18
CS (PER1)
CS (PER2)
CS (PER7)
E0 0000
E4 0000
FC 0000
CS (PER)
E
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 137 Cesáreo Fernández Martínez
Introducción al 80C167
Decodificación realista
• Los rangos (del mapa de memoria) anteriores son muy grandes
• Un caso más realista. Situar– RAM. Dos chips de 32 Kbyte cada uno en 00 0000 a 03 FFFF
– ROM. Dos chips de 64 Kbyte cada uno en F0 0000 a FD FFFF
– 8 periféricos (iguales) en FE 0000 FF FFFF
• Regla general: – Llevar las líneas bajas del bus de direcciones directamente a la
memoria (de acuerdo con el tamaño de la misma. A0 excluida)
– Llevar las líneas altas del bus de direcciones que definen el segmento (líneas constantes en el segmento) a una (varias) puerta(s) de generación de CS.
– El resto de las líneas (del bus de direcciones) “no importa”.
• Cuidado con dar CS a más de un chip !– Cortocircuito en el bus de datos
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 138 Cesáreo Fernández Martínez
Introducción al 80C167
RAM
• Para la RAM– Líneas de A1 a A15 directamente a ambos bancos de memoria
(PAR e IMPAR). A0 (junto con BHE) selecciona banco PAR/IMPAR
– Líneas A23 a A18 (a 0 en todo el segmento) a lógica de selección
– Líneas A17 y A16 “no importa”
– ¿Que posición de la RAM se accede en la dirección 01 0000?
A23
A18
CS (RAM)
A0CS (PAR)
BHE
CS (IMPAR)
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 139 Cesáreo Fernández Martínez
Introducción al 80C167
ROM
• Para la ROM (y periféricos)– Líneas de A1 a A16 directamente a ambos bancos de memoria
(PAR e IMPAR). A0 (junto con BHE) selecciona banco PAR/IMPAR
– Líneas A23 a A20 (a 1 en todo el segmento) a lógica de selección
– Líneas A19, A18 y A17 pueden tomar cualquier combinación salvo la 1 1 1 (rango reservado a los periféricos)
A23
A20
CS (ROM)
A19
A17
CS (PER)
(a decoder 3/8)A18
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 140 Cesáreo Fernández Martínez
Introducción al 80C167
Ejercicio
• Diseñar el decodificador– RAM. Dos chips de 64 Kbyte cada uno en 00 0000 a 7F FFFF
– ROM. Dos chips de 128 Kbyte cada uno en 80 0000 a EF FFFF
– 8 periféricos (iguales) en F0 0000 FF FFFF
Siemens 80C167
UPCO ICAI Departamento de Electrónica y Automática 141 Cesáreo Fernández Martínez
Introducción al 80C167
Decodificador programable
• El 167 tiene hasta 4 decodificadores (de mapa de memoria) internos y programables (genera 5 CS’s en P6.0 a P6.4)
• Los decodificadores son muy rápidos (1 clk de reloj, no introducen retrasos en el acceso a la memoria externa).
• Registros de programación– ADDRSEL (1 a 4): Definición de una “ventana” de direcciones
– BUSCON (0 a 4): Manejo líneas de bus de control en la ventana
– RGSZ: Tamaño de la ventana
– RGSAD: Dirección base de la ventana
RGSZ
034
RGSAD
15
ADDRSEL