Microcontroladores MCS51 y MCS251 (Recovered 1)
Click here to load reader
-
Upload
juan-carlos-romero -
Category
Documents
-
view
275 -
download
23
Transcript of Microcontroladores MCS51 y MCS251 (Recovered 1)
POLITEXT 97
MicrocontroladoresMCS-51 y MCS-251
EDICIONS UPC
POLITEXT
José Matas Alcalá
Rafael Ramón Ramos Lara
MicrocontroladoresMCS-51 y MCS-251
EDICIONS UPC
La presente obra fue galardonada en el séptimo concurso
"Ajuts a l'elaboració de material docent" convocado por la UPC.
Primera edición: febrero de 2001
Diseño de la cubierta: Manuel Andreu
© Los autores, 2001
© Edicions UPC, 2001
Edicions de la Universitat Politècnica de Catalunya, SL
Jordi Girona Salgado 31, 08034 Barcelona
Tel.: 934 016 883 Fax: 934 015 885
Edicions Virtuals: www.edicionsupc.es
E-mail: [email protected]
Producción: Barcelona Digital, S.L.
Rosselló 77, 08029 Barcelona
Depósito legal: B-10.539-2001
ISBN: 84-8301-454-8
Quedan rigurosamente prohibidas, sin la autorización escrita de los titulares del copyright, bajo las san-
ciones establecidas en las leyes, la reproducción total o parcial de esta obra por cualquier medio o pro-
cedimiento, comprendidos la reprografía y el tratamiento informático, y la distribución de ejemplares de
ella mediante alquiler o préstamo públicos.
A Gemma y Alex, a mi familia, a mis amigos
más próximos, a mis compañeros de la
EUPVG, y a la memoria de mi padre.
José Matas
A Paula y a Rosa, a mi familia, a mis
compañeros de la EUPVG y a mis amigos.
Rafael Ramos
© Los autores, 2001; © Edicions UPC, 2001.
Índice 9
Índice
1 Estructura básica de un sistema microprocesador
1.1 Introducción . . . . .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. ..
1.2 Estructura básica de un sistema microprocesador . . .... .. ... . ... .. .. .. .. ... .. .. .. .. .. .
1.2.1 Unidad central de proceso (CPU) . . .... .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. ..
1.2.2 Módulo de entradas/salidas (E/S) . . .. .. ... .. .. .. .. .. ... ... . .. .. .. ... .. .. .. .. .. ... .. .
1.2.3 Buses del sistema . . .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. ..
1.3 Estructura general de un sistema basado en microprocesador . . .. ... .. .. .. .. .. ... .. .. ..
1.4 Estructura general de un sistema basado en microcontrolador . . . ... .. .. .. .. ... .. .. .. ..
15
15
16
18
18
21
23
2 Las familias de microcontroladores de Intel y de otros fabricantes
2.1 La familia MCS-48 . . . . ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. ..
2.2 La familia MCS-51 . . . . ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. ..
2.3 La familia MCS-151 . . . .. ... . ... .. .. .. .. .. ... .. .. .. .. ... ... . .. .. .. ... .. .. .. .. .. ...
2.4 La familia MCS-251 . . . .. ... . ... .. .. .. .. .. ... .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ...
2.5 Microcontroladores de otros fabricantes . . .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. ..
2.5.1 Microcontroladores de Philips . . . ... .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. ..
2.5.2 Microcontroladores de Siemens . . . . .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ...
2.5.3 Microcontroladores de Atmel . . . . .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. ..
2.5.4 Microcontroladores de Dallas Semiconductor . . . . .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ..
25
25
26
27
28
28
30
31
31
3 Arquitectura de las familias MCS-51 y MCS-251
3.1 Arquitectura interna de la MCS-51 . . . . .. ... .. .. .. .. .. .... . .. .. .. .. ... .. .. .. .. .. ... .
3.1.1 Relación de terminales . . . ... . .. .. .. .. ... .. .. .. .. .. ... ... . .. .. .. ... .. .. .. .. .. ... .. .
3.1.2 Puertos de entrada/salida . . . . .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... ..
3.2 Organización de la memoria y de los registros internos de la MCS-51 . . . .. ... .. .. .. .. ..
3.2.1 Área de memoria de código de programa y memoria de datos . . . . .. .. .. .. ... .. .. .. .. ..
3.2.2 Área de memoria interna y de registros de propósito general . . . . ... .. .. .. .. .. ... .. .. ..
3.2.3 Área de registros especiales (SFR) . . ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. ... . ... .. .. ..
3.3 Arquitectura interna de la MCS-251 . . . .. .. .. .. ... .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. ..
3.3.1 Relación de terminales . . . ... . .. .. .. .. ... .. .. .. .. .. ... ... . .. .. .. ... .. .. .. .. .. ... .. .
3.3.2 Estructura interna de los puertos de entrada/salida . . . . ... ... . .. .. .. ... .. .. .. .. .. ... .. .
3.4 Organización de los espacios de memoria de la MCS-251 . .. .. .. .. ... .. .. .. .. .. ... .. ..
3.4.1 Área de memoria . . . .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. .... . .. .. .. .. ... .. .. .. .. .. ... .
3.4.2 Área de registros de propósito genérico . . . ... .. .. .. .. .. ... .. .. .. .. ... .. .. .. .. .. ... ..
3.4.3 Área de registros de función específica SFR . .. .. .. .. ... ... . .. .. .. ... .. .. .. .. .. ... .. .
33
34
36
38
38
40
41
44
45
48
48
49
51
54
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25110
3.4.4 Compatibilidad con la arquitectura de la familia MCS-51 . .. . .. .. ... .. .. .. .. .. ... .. .. .
3.5 Configuración de la serie 8XC251Sx . . . .. .. ... .. .. .. .. ... .. .. .. .. .. .. ... .. .. .. .. .. .
3.5.1 Configuración del acceso a la memoria externa . . . . .. .. .... . .. .. .. ... .. .. .. .. .. ... .. .
57
58
58
4 Programación de las familias MCS-51 y MCS-251
4.1 Introducción . . .. .. .. .. ... ... . .. .. .. ... .. .. .. .. .. ... .. ... . .. .. ... .. .. .. .. .. ... .. .
4.2 Tipos de direccionamiento . . . .. .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. .
4.2.1 Direccionamiento inmediato . . . . .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. ... . ... .. .. .. .. ..
4.2.2 Direccionamiento directo . . . . . ... .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. .
4.2.3 Direccionamiento por registro .. ... .. .. .. .. .. ... .. .. .. .. ... .. .. .. .. .. .. ... .. .. .. .. .
4.2.4 Direccionamientoindirecto . . . .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. ..
4.2.5 Direccionamiento por desplazamiento o indexado . . . . .. .. .. ... .. .. .. .. .. ... .. .. .. ..
4.2.6 Direccionamiento de bit . . . .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. ..
4.2.7 Direccionamiento relativo . . .. . .. .. .. ... .. .. .. .. .. .. ... ... . .. .. .. ... .. .. .. .. ... .. .
4.3 Conjunto de instrucciones de la familia MCS-51 y MCS-251 . . .. .. .. ... .. .. .. .. .. ...
4.3.1 Formato de una instrucción . . . ... .. .. .. .. .. ... .. .. .. .. ... .. .. .. .. .. .. ... .. .. .. .. .
4.3.2 Directivas de ensamblador . . . .. .. .. .. .. .. ... .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ...
4.3.3 Los registros de estado PSW y PSW1 . . ... .. .. .. .. .. ... ... . .. .. .. ... .. .. .. .. .. ... .
4.3.4 Instrucciones aritméticas . . ... . .. ... .. .. .. .. .. ... .. .. .. ... . ... .. .. .. .. .. ... .. .. .. .
4.3.5 Instrucciones lógicas . . . ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... ..
4.3.6 Instrucciones de transferencia de datos . . . ... .. .. .. .. .. .... . .. .. .. .. ... .. .. .. .. .. ..
4.3.7 Instrucciones booleanas . . . ... . .. .. .. ... .. .. .. .. .. ... .. ... . .. .. ... .. .. .. .. .. ... .. .
4.3.8 Instrucciones de control . . . .. . .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. ..
63
64
65
66
67
68
69
70
73
73
74
75
77
79
83
86
90
92
5 El modelo de programación
5.1 Creación y consulta a tablas . . .. .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. ... . .
5.2 Transferencia de bloques de datos . . . . .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. .
5.3 Funciones booleanas . . . .. ... . .. .. .. ... .. .. .. .. .. ... .. ... . .. .. ... .. .. .. .. .. ... .. .
5.4 Retardos de tiempo . .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .... . . ... .. ..
5.5 Suma y resta de datos . . .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. ..
5.6 Contador en BCD .. .. .. .. ... . ... .. .. .. .. .. ... .. .. .. .. ... .. .. .. .. .. .. ... .. .. .. .. .
5.7 Multiplicación y división de datos de 16 bits . . . . .. .. .. ... .. .. .. ... .. .. .. .. .. .. ... ..
5.8 Suma y resta de datos con signo . . . .. .. ... .. .. .. .. .. ... ... . .. .. .. ... .. .. .. .. .. ... .
5.9 Multiplicación y división de 16 bits con signo . . . .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. ..
5.10 Ejemplos de aplicación . . . ... . .. .. .. ... .. .. .. .. ... .. .. ... . .. .. ... .. .. .. .. .. ... .. .
5.10.1 Generación de una señal cuadrada . . . .. .. ... .. .. .. .. .. .... . .. .. .. .. ... .. .. .. .. .. ..
5.10.2 Conexión de teclas al microcontrolador . . . .. .. .. .. ... .. ... . .. .. ... .. .. .. .. .. ... .. .
5.10.3 Conexión de un dígito de siete segmentos . . . . .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. ..
5.10.4 Conexión de un teclado matricial de 4 x 4 teclas . . .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. ..
5.10.5 Conexión de varios dígitos de siete segmentos, aplicación de “Su turno” . . . . .. .. ... .. .
5.10.6 Contador de piezas . . .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. .... . .. .. .. .. ... .. .. .. .. .. ..
5.10.7 Control de un ascensor . . . ... .. .. .. .. .. .. ... .. .. .. .. .. .... . .. .. .. .. ... .. .. .. .. .. ..
5.10.8 Control de un calefactor . . . .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... ..
5.10.9 Control de una cinta elevadora . . . . .. ... .. .. .. .. .. ... .. ... . .. .. ... .. .. .. .. .. ... .. .
5.10.10 Control de la temperatura de un horno de cocción . . . .. .. ... .. .. .. .. .. .... . .. .. .... .
97
98
99
100
101
103
105
109
109
113
113
115
117
118
121
125
127
129
131
134
© Los autores, 2001; © Edicions UPC, 2001.
Índice 11
6 Las interrupciones
6.1 Introducción . . .. .. .. .. ... ... . .. .. .. ... .. .. .. .. .. ... .. ... . .. .. ... .. .. .. .. .. ... .. .
6.2 Las interrupciones en la familia MCS-51 . . . ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. ..
6.2.1 Vectorización de interrupciones en la MCS-51 . . .. ... . .. ... .. .. .. .. .. .. ... .. .. .. .. .
6.2.2 Habilitación de interrupciones y establecimiento de prioridades en la MCS-51 .. . .. .. ..
6.2.3 Tiempos de respuesta del proceso de interrupción . . . .. .. ... .. .. .. .. .. ... .. .. .. .. .. .
6.3 El sistema de interrupciones en la familia MCS-251 . . .. .. .. .. .. ... .. .. .. .. .. ... .. ..
6.3.1 Habilitación de las interrupciones . . . .. .. .. .. .. ... .. .. .. ... . ... .. .. .. .. .. ... .. .. .. .
6.3.2 Niveles de prioridad de las interrupciones . . . . .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. ..
6.3.3 Interrupciones externas /INT0 e /INT1 . . ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ...
6.3.4 Interrupción de los Timers . . . . .. .. ... .. .. .. .. .. ... .. .. ... . .. ... .. .. .. .. .. ... .. .. .
6.3.5 Interrupción del array de contadores programables (PCA) . . . . ... .. .. .. .. .. ... .. .. ..
6.3.6 Interrupción del puerto serie . . . .. .. .. .. .. ... .. .. .. .. .. .... . .. .. .. .. ... .. .. .. .. .. ..
137
139
142
143
145
152
155
156
158
163164
165
7 Temporizadores/contadores internos y watchdog
7.1 Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.2 Temporizadores/contadores para la MCS-51 . ... .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ...
7.2.1 Timer 0 y Timer 1 . . . . ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. ..
7.2.2 Timer 2 . . . . .. ... .. .. .. .. ... .. .. .. .. .. .. ... .. .. .. .. .. ... ... . .. .. ... .. .. .. .. .. ...
7.2.3 Timer 0, 1 y 2 como contador . . . .. .. ... .. .. .. .. .. ... .. ... . .. .. ... .. .. .. .. .. ... .. .
7.3 Temporizadores para la MCS-251 . . . .. .. ... .. .. .. .. .. .... . .. .. .. .. ... .. .. .. .. .. ..
7.4 Funcionamiento de los Timers . . . . ... .. .. .. .. .. ... ... . .. .. .. ... .. .. .. .. .. ... .. .. ..
7.4.1 Funcionamiento como temporizador . . . . ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ...
7.4.2 Funcionamiento como contador . . . . .. .. .. .. ... .. .. .. .. ... .. .. .. .. .. .. ... .. .. .. .. .
7.5 Timer 0 y Timer 1 . . . . ... .. .. .. .. .. ... .. .. ... . .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. ..
7.5.1 Habilitación de los Timers 0 y 1 . . . .. .. .. ... .. .. .. .. .. .... . .. .. .. .. ... .. .. .. .. .. ..
7.5.2 Desbordamiento de los Timers 0 y 1 ... .. .. ... .. .. .. .. .... . .. .. .. .. ... .. .. .. .. .. ..7.5.3 Modos de funcionamiento de los Timers 0 y 1 . . . .. .. .. .... . .. .. .. ... .. .. .. .. .. ... .
7.6 Timer 2 . . . .. .. .. .. .. .. ... .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. ..
7.6.1 Modo captura . . ... .. ... .. ... . .. .. ... .. .. .. .. .. ... .. .. ... . .. ... .. .. .. .. .. ... .. .. .
7.6.2 Modo autorrecarga . . ... .. ... . ... .. .. .. .. .. ... .. .. .. .. ... .. .. .. .. .. .. ... .. .. .. .. .
7.6.3 Modo de generador de baudios (Baud Rate Generator Mode) . . . . .. ... .. .. .. .. .. ... ..
7.6.4 Modo Clock-out . . . .. .. .. ... . ... .. .. .. .. .. ... .. .. .. .. ... .. .. .. .. .. .. ... .. .. .. .. .7.7 Timer watchdog . . . .. .. .. ... . ... .. .. .. .. .. ... .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. .
7.7.1 Descripción de funcionamiento . . . ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. ..
7.7.2 Utilización del timer WDT ..... .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. ..
7.7.3 Timer WDT durante el modo Idle . . . .. .. .. .. .. .. ... .. .. ... . .. ... .. .. .. .. .. ... .. .. .
7.7.4 Timer WDT durante Power Down . . . . .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ...
173
174
174
181
186
191
192
193
193
194
194
198
199
213
215
215
217
217
219
219
220
220
220
8 Memoria externa
8.1 Introducción . . .. .. .. .. ... ... . .. .. .. ... .. .. .. .. .. ... .. ... . .. .. ... .. .. .. .. .. ... .. .
8.2 Memorias semiconductoras . . . . .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. ..
8.3 Estructura externa de las memorias . . . . .. .. ... .. .. .. .. .. .... . .. .. .. .. ... .. .. .. .. ..
8.4 Ciclos de fetch, de lectura y de escritura . . .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... ..
221
221
223
224
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25112
8.5 Conexión entre la MCS-51 y la memoria externa . . . ... .. ... . .. .. ... .. .. .. .. .. ... .. .
8.5.1 Diagramas de tiempo para la MCS-51 . ... .. .. ... . .. ... .. .. .. .. .. ... .. .. .. .. .. ... ..
8.6 Ejemplos de conexión para la MCS-51 . . .. .. .. .. ... .. .. ... . .. ... .. .. .. .. .. ... .. .. .
8.7 Conexión con la memoria externa para la familia MCS-251 . . . . .. .. .. .. ... .. .. .. .. ..
8.8 Configuraciones de acceso a la memoria externa . . . . .. .. ... . .. ... .. .. .. .. .. ... .. .. .
8.8.1 18 bits de bus de direcciones (RD1, RD0 = 00) . . ... .. .. .. .. ... .. .. .. .. .. ... .. .. .. ..
8.8.2 17 bits de bus de direcciones (RD1, RD0 = 01) . . ... .. .. .. .. ... .. .. .. .. .. ... .. .. .. ..
8.8.3 16 bits de bus de direcciones (RD1, RD0 = 10) . . ... .. .. .. .. ... .. .. .. .. .. ... .. .. .. ..
8.8.4 16 bits de bus de direcciones (RD1, RD0 = 11) . . ... .. .. .. .. ... .. .. .. .. .. ... .. .. .. ..
225
225
227
231
233
233
239
240
240
9 Puerto de comunicación serie
9.1 Introducción . . .. .. .. .. ... ... . .. .. .. ... .. .. .. .. .. ... .. ... . .. .. ... .. .. .. .. .. ... .. .
9.2 La comunicación serie en la MCS-51 . . . . .. ... .. .. .. .. .. ... .. .. .. .. ... .. .. .. .. .. ..
9.3 Modos de funcionamiento del puerto serie . . . .. .. .. .. .. .. ... .. .. .. .. ... .. .. .. .. .. ..
9.3.1 Modo 0. Modo síncrono . . . .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. ..
9.3.2 Modos 1, 2 y 3. Modos asíncronos . . .. .. .. .. .. ... .. .. .. ... . ... .. .. .. .. .. ... .. .. .. .
9.3.3 El Timer 2 como base para el puerto serie . . . .. .. .. .. ... ... . .. .. .. ... .. .. .. .. .. ... .
9.4 Detección de errores . . ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. ..
9.5 La comunicación serie en la MCS-251 . . . .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. ..
9.6 Modos de operación . .... .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. ... .
9.6.1 Modo 0 o síncrono . . . . .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. ..
9.6.2 Modos 1, 2 y 3. Modos asíncronos . . .. .. .. .. .. ... .. .. .. ... . ... .. .. .. .. .. ... .. .. .. .
9.7 Detección de errores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9.8 Comunicación multiprocesador . . ... .. .. .. .. ... .. .. .. .. ... .. .. .. .. .. .. ... .. .. .. .. .
9.9 Reconocimiento automático de direcciones . . . .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. ..
9.9.1 Direcciones given . . . .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. .... . .. .... . . ... .. .. .. .. .. ..
9.9.2 Direcciones broadcast . . . .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. ..
247
248
250
250
250
252
253
262
264
264
267
272
272
273
273
274
10 El array de contadores programables (PCA)
10.1 Introducción . . .. .. .. .. ... ... .. . .. .. ... .. .. .. .. .. ... .. ... . .. .. ... .. .. .. .. .. ... .. .
10.2 Temporizador/contador del PCA ... .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. ..
10.3 Módulos de comparación/captura del PCA . .. ... .. .. .. .. ... .. .. .. .. .. .. ... .. .. .. .. .
10.3.1 Modo captura . . ... .. ... .. ... . .. .. ... .. .. .. .. .. ... .. .. ... . .. ... .. .. .. .. .. ... .. .. .
10.3.2 Modos de comparación . . . .. . .. .. .. .. ... .. .. .. .. .. ... ... . .. .. ... .. .. .. .. .. ... .. .
277
279
280
280
287
11 Entradas y salidas analógicas
11.1 Introducción . . .. .. .. .. ... ... . .. .. .. ... .. .. .. ... . ... .. ... . .. .. ... .. .. .. .. .. ... .. .
11.2 Conexión de un convertidor D/A . . .. .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. ..
11.3 Convertidor A/D de bajo coste mediante aproximaciones sucesivas . . . .. .. ... .. .. .. ..
11.4 Conexión de un convertidor A/D . . .. .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. ..
11.5 Conversión A/D utilizando los temporizadores del microcontrolador . . ... .. .. .. .. ... .
297
298
302
305
317
© Los autores, 2001; © Edicions UPC, 2001.
Índice 13
12 Modos especiales de funcionamiento
12.1 Introducción . . .. .. .. .. ... ... . .. .. .. ... .. .. .. .. .. ... .. ... ... . . ... .. .. .. .. .. ... .. .
12.2 Registro de control de potencia (PCON) . .. .. ... .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. .
12.2.1 Bits de control del puerto serie . . . .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. ..
12.2.2 Bit de Power Off (POF) . . .... . .. .. ... .. ... . .. .. ... .. .. ... . .. ... .. .. .. .. .. ... .. .. .
12.3 Modo Idle . . . .. .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ...
12.4 Modo Power Down . . . .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. ..
12.5 Modo ONCE (On-Circuit Emulation) . . . ... .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... ..
327
327
327
327
328
329
330
Apéndice Juego de instrucciones de la familia MCS-51 y MCS-251 . . . .. .. ... .. .. .. .. 331
Bibliografía .... .. .. ... ... . .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. ... .. .. .. .. .. .. 337
© Los autores, 2001; © Edicions UPC, 2001.
Bibliofrafía 337
Bibliografía
BERNARD ODANT; Microcontroladores 8051 y 8052. Paraninfo, 1995.
GONZÁLEZ VAZQUEZ, J.A; Introducción a los microcontroladores 8X52, 8X51. Mc Graw Hill,
1992.
ANGULO, J.Mª; Microprocesadores y Microcontroladores 8085, MCS-51 y ST6. Paraninfo, 1992.
Embedded Microcontroller User’s Manual. 8XC251SA, 8XC251SB, 8XC251SP, 8XC251SQ.
SENCER YERALAN Y ASHUSTOSH AHLUWALIA; Programming and interfacing the 8051Microcontroller. Addison-Wesley, 1995.
JAMES W. STEWART; The 8051 Microcontrollers, Hardware, Software and interfacing. Prentice-
Hall, 1993.
THOMAS W. SHULTZ; C and the 8051. Programming and Multitasking. Prentice-Hall, 1993.
JOHN UFFENBECK; Microcomputers and Microprocessors. The 8080, 8085, and Z-80. Prentice-
Hall, 1991.
BARRY B. BREY; Los microprocesadores de INTEL. Arquitectura. Programación e interfaces.
Prentice-Hall, 1994.
RICHARD J. PRESTOPNIK; The Microprocessor Peripheral IC Reference Manual. Prentice-Hall,
1989.
MATAS, José, et al ; Entorno de desarrollo para la placa evaluadora EV80C51FX. Revista Española
de Electrónica, pág. 52-55, Abril 1995.
ANDREW TANENBAUM; Structured computer organization. Prentice-Hall, 1990.
DOUGLAS V. HALL; Microprocessors and Interfacing, Programming and Hardware. Mc-Graw
Hill, 1992.
A.C. DOWNTON; Computadores y Microprocesadores. Addison-Wesley, 1993
© Los autores, 2001; © Edicions UPC, 2001.
1 Estructura básica de un sistema microprocesador 15
1 Estructura básica de un sistema microprocesador
1.1 Introducción
Un sistema microprocesador se puede concebir como un sistema procesador secuencial de
instrucciones (figura 1.1), que puede ejecutar un conjunto determinado de instrucciones, lo que hace
que sea un sistema flexible, capaz de controlar una amplia gama de aplicaciones, de abaratar costos y
de reducir el tiempo necesario de diseño.
Algoritmo
oprograma
Sistema
procesador
Proceso
a
gobernar
SalidasEntradas
Salida del
proceso
Fig. 1.1 Esquema general de un sistema procesador
Un sistema procesador puede ser de programa fijo, como es el caso de las calculadoras de bolsillo no
programables, o de lógica programable, como es el caso de los microprocesadores,
microcontroladores, procesadores digitales de señal (DSP), etc. Los sistemas procesadores también
pueden trabajar en paralelo, aumentando la velocidad de ejecución de los programas.
1.2 Estructura básica de un sistema microprocesador
La estructura básica de un sistema microprocesador (figura 1.2), se basa en la arquitectura de Von
Newman que, a pesar de los grandes avances producidos en la tecnología de los semiconductores, ha
permanecido inalterada desde el momento de su concepción.
En la estructura básica de un sistema microprocesador (figura 1.2) se distinguen los siguientes
bloques: la unidad central de proceso CPU, la memoria, el módulo de entradas/ºsalidas y los buses de
direcciones, de datos y de control.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25116
Memoria
( M )
Unidad
central
de
proceso
(CPU)
Módulo
de
E/S
Bus de direcciones
Bus de control
Bus de datos
Fig. 1.2 Diagrama de bloques de la estructura básica de un sistema microprocesador
La CPU está formada principalmente por dos bloques funcionales: la unidad de control y la unidad deproceso. La unidad de control se encarga de buscar, interpretar y ejecutar las instrucciones
almacenadas en la memoria. La unidad de proceso se encarga de realizar una serie de operaciones
aritméticas, lógicas, de transferencia de datos, etc.
La memoria está destinada a almacenar las instrucciones y los datos del programa y los resultados
obtenidos en su ejecución. Sobre la memoria opera la CPU, leyendo instrucciones y escribiendo o
leyendo datos. Existen dos tipos básicos de memoria: la memoria ROM de sólo lectura y la memoria
RAM de lectura/escritura. Para acceder a la memoria se deben realizar una selección previa de ésta,
más un direccionamiento de la posición concreta a que se desea acceder para la lectura o la escritura.
El módulo de entradas/salidas, E/S o I/O, permite la comunicación del sistema microprocesador con el
exterior, haciendo que este sea un sistema abierto, es decir, accesible por dispositivos externos.
Los buses son el conjunto de líneas físicas que permiten la transferencia de información entre todos
los bloques que constituyen el sistema microprocesador. Los buses se pueden clasificar, en función del
tipo de información que transportan, en tres tipos: el bus de direcciones, el bus de datos y el bus de
control. El bus de direcciones determina la dirección de memoria a que se va a acceder por la CPU y,
también, se utiliza para seleccionar, dentro de un rango de direcciones, distintos tipos de memoria, de
la misma forma que para seleccionar distintos tipos de periféricos a través del módulo de E/S.
1.2.1 Unidad central de proceso (CPU)
La CPU está formada por la unidad de control y por la unidad de proceso. La unidad de control
gestiona el funcionamiento completo de la CPU y del resto de los bloques del sistema
© Los autores, 2001; © Edicions UPC, 2001.
1 Estructura básica de un sistema microprocesador 17
microprocesador, encargándose de buscar, decodificar, ejecutar las instrucciones y de generar las
señales de control adecuadas para ello.
La unidad de proceso está formada por la unidad aritmético-lógica, ALU, y por los registros del
sistema microprocesador. La ALU se encarga de realizar las operaciones aritméticas y lógicas del
sistema, como pueden ser la suma, resta, multiplicación, función AND lógica, función OR lógica, etc.
En los registros se almacenan datos que son el origen o el destino de las operaciones de la ALU, y el
origen o destino de la transferencia de datos entre la CPU (figura 1.2)ºº y la memoria del sistema.
La unidad de control tiene también el registro PC (Program Counter), o contador de programa, que es
un registro especial encargado de enviar, por medio del bus de direcciones, la posición de memoria
que corresponde a la siguiente instrucción que se debe ejecutar. El contador de programa, PC, se
actualiza automáticamente cuando se ejecuta una instrucción, de manera que siempre apunta a la
siguiente instrucción que se debe ejecutar en el programa.
El conjunto de bloques formado por la unidad de control y la unidad de proceso constituye la CPU,
que se caracteriza por el repertorio de instrucciones que es capaz de ejecutar.
ALU
Acumulador
Registro de
2º operando
Unidad
de
control (UC)
Registro
de estado
Bus interno de la CPU
Unidad de proceso (UP)
Control
Fig. 1.3 Diagrama de bloques de la CPU
De la figura 1.3 cabe destacar al acumulador como un registro de suma importancia, pues siempre
suele recibir uno de los operandos que intervienen en una operación aritmética, o suele ser, en la CPU,
el registro destinatario del resultado obtenido en la operación.
Otro registro que se debe destacar es el registro de estado, debido a que contiene bits que actúan como
indicadores o alarmas de ciertos sucesos acontecidos en las operaciones aritméticas. Uno de los bits
que suele llevar es el bit C de acarreo, que se activa en operaciones de suma y resta; o el bit P de
paridad, que indica la paridad “par” o “impar” del número contenido en el acumulador.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25118
1.2.2 Módulo de entradas/salidas (E/S)
El sistema microprocesador necesita de dispositivos de entrada/salida para gobernar y comunicarse
con el entorno de la aplicación, con la función principal de hacer de interfaz entre el sistema y los
periféricos externos asociados a éste.
Módulo
de
E/S
Bus de datos
Bus de control
Bus de direcciones
Enlaces con
dispositivos
periféricos
Fig. 1.4 Modelo genérico de un módulo de E/S
Las operaciones de E/S se hacen sobre una amplia gama de periféricos conectados al sistema
microprocesador (impresoras, teclados, monitores, convertidores A/D y D/A, sensores, actuadores,
etc.), y con los que se suelen intercambiar señales de control y de datos. En estas operaciones se debe
coordinar el tráfico entre los recursos internos del sistema microprocesador y los periféricos, pues a
menudo la velocidad de transferencia de datos de los periféricos es más lenta, o necesitan un
determinado sincronismo.
El módulo de E/S se puede realizar por medio de instrucciones específicas que lo conforman y que
residen en el programa del sistema microprocesador; se puede hacer mediante interrupciones, donde
los periféricos pueden activar líneas de interrupción de la CPU, que detienen la ejecución del
programa y pasan a ejecutar un programa específico pensado para atender al periférico que ha causado
la interrupción; se puede hacer tratando las entradas/salidas como posiciones de memoria, donde se
seleccionan los periféricos mediante ciertos rangos de direcciones y se envían y reciben datos que
gestionan al periférico.
También se ofrecen en el mercado numerosos circuitos integrados de soporte al sistema
microprocesador, que suelen ser configurables mediante software y son capaces de adaptar al sistema
todo tipo de periféricos.
1.2.3 Buses del sistema
Un bus es el medio por el cual se transmite información por los distintos módulos que componen un
sistema microprocesador. Un bus puede ser unidireccional o bidireccional, es decir, puede transmitir
la información en una única dirección, del emisor al receptor, o en ambas direcciones, del emisor al
receptor, y viceversa.
Cuando hay varios dispositivos conectados a un mismo bus, como ocurre, por ejemplo, con el bus de
datos, éstos disponen de la característica triestado, que consiste en un estado de alta impedancia en las
líneas del dispositivo conectados al bus, de forma que permite que quede desconectado eléctricamente
del bus, y que así la CPU pueda acceder a uno de los distintos dispositivos conectados al mismo.
© Los autores, 2001; © Edicions UPC, 2001.
1 Estructura básica de un sistema microprocesador 19
Un dispositivo triestado tiene una señal de control que determina si el estado será de alta impedancia,
o no. El estado en alta impedancia hace que el dispositivo se desconecte eléctricamente de la línea en
cuestión (figuras 1.5 y 1.6).
0
1
Control
Control
0
1
0
1
Alta impedancia
a
b
a
b
Fig. 1.5 Conexión de dos buffers triestados a una mismalínea de bus
....
....
....
....
....
....
Control
Entradas Salidas
Buffer
Fig. 1.6 Estructura de un buffer triestado
La figura 1.5 muestra la conexión de dos buffers de salida a una misma línea de un bus. En esta figura
se observa el caso en que, para evitar colisiones entre los estados lógicos de la salida de ambos
buffers, el buffer a permanece en estado de alta impedancia mientras el buffer b está transmitiendo
información por la línea del bus.
El bus de direcciones tiene la tarea de llevar la dirección de la posición de memoria, o del módulo de
E/S, a la que la CPU desea acceder. El contenido del bus es unidireccional y siempre lo proporciona la
CPU a través de la unidad de control. El número de líneas del bus de direcciones está relacionado con
la capacidad de direccionamiento de la CPU. Por ejemplo, si se desea direccionar una memoria de
64kbytes, es decir, con 216
posiciones de memoria, serán necesarias 16 líneas de dirección para formar
el bus de direcciones.
El bus de datos debe soportar el traspaso de información entre la CPU, la memoria y los módulos de
E/S. El bus de datos es bidireccional y triestado, pues está compartido por todos los bloques del
sistema microprocesador.
El bus de control está formado por las líneas destinadas a llevar las señales que gobiernan y
sincronizan todo el sistema microprocesador, como son las señales del tipo /RD, /WR, ALE, reset,líneas de interrupción, etc. Con estas señales se llevan a cabo distintas operaciones como, por ejemplo,
la selección, lectura y escritura en las memorias externas, o en los periféricos externos.
Uno de los problemas que se debe considerar en un bus es la carga que puede soportar, es decir, el
número de dispositivos o de puertas lógicas que se pueden conectar a una misma línea. En general,
cada nuevo dispositivo receptor que se conecta a una línea supone un incremento en la corriente que
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25120
debe suministrar el emisor cuando está a nivel alto, VOH (1 lógico), y en la corriente que debe absorber
cuando está a nivel bajo, VOL (0 lógico), tal y como se indica en las figuras 1.7 y 1.8, respectivamente.
Las especificaciones de VOH, VOL, IOH, IOL, IIH y IIL, se dan para el peor de los casos y dependen de la
tecnología o de la familia lógica utilizada. La tabla 1.1 muestra el valor de estos parámetros para
circuitos integrados TTL, CMOS y LSTTL (Low-Power Schottky TTL). En esta tabla las corrientes
negativas indican que la corriente se suministra por el transmisor. Con esta tabla se puede determinar
el número máximo de receptores que puede soportar un emisor específico.
IH1
I H2
I H3
IH4I OH
V=VOH
Emisor
Receptores
4H3H2H1HOH IIIII ÷÷÷[
Fig. 1.7 Corriente que suministra el emisor cuando susalida está a nivel alto, VOH (1 lógico)
IL1
I L2
I L3
IL4I OL
V=VOL
Emisor
Receptores
4L3L2L1LOL IIIII ÷÷÷[
Fig. 1.8 Corriente que absorbe el emisor cuando susalida está a nivel bajo, VOL (0 lógico)
Tabla 1.1 Especificaciones de nivel lógico para las familias lógicas TTL, LSTTL y CMOS (esta última dada parala familia GS CD4000 serie “B” con una tensión de alimentación de VDD=5V)
Descripción TTL CMOS LSTTLVOH Valor mínimo de tensión de salida a 1 lógico 2.4V 4.95V 2.7V
VOL Valor máximo de tensión de salida a 0 lógico 0.4V 0.05V 0.5V
VIHValor mínimo de tensión de entrada
aceptable como un 1 lógico2.0V 3.5V 2.0V
VILValor máximo de tensión de entrada
aceptable como un 0 lógico0.8V 1.5V 0.8V
IIH Corriente máxima absorbida a 1 lógico 40]A 0.3]A 20]A
IIL Corriente máxima suministrada a 0 lógico -1.6mA -0.3]A -0.4mA
IOH Corriente máxima de salida a 1 lógico -400]A -0.16mA -400]A
IOLCorriente máxima absorbida de salida a 0
lógico16mA 0.44mA 8mA
Otro problema que es común a los buses es el de las reflexiones que se pueden producir en las líneas,
debido a que un pulso situado en una línea de un bus se comporta de manera parecida a una señal de
radio frecuencia en una línea de transmisión. Este fenómeno afecta sobre todo a las líneas de larga
longitud, haciendo que aparezcan sobreoscilaciones y transitorios repentinos en la recepción de los
pulsos transmitidos por las líneas, que distorsionan los niveles lógicos transmitidos. Las reflexiones
producidas en las líneas (figura 1.9) son debidas a la falta de adaptación de impedancias entre el
emisor y el receptor, de forma que el receptor no absorbe toda la energía transmitida y parte de esta
energía se refleja hacia el emisor.
© Los autores, 2001; © Edicions UPC, 2001.
1 Estructura básica de un sistema microprocesador 21
Emisión Recepción
Pulso corto
Pulso largo
Fig. 1.9 Reflexiones en el receptor debidas a reflexiones producidas en la línea
Para que no se produzcan reflexiones la impedancia de entrada de los receptores debe ser idéntica a la
impedancia que presenta la línea conectada a éstos. La impedancia de una línea trazada en un circuito
impreso suele tener un valor comprendido entre los 100∑ y 200∑, por lo que la adaptación se puede
conseguir conectando una resistencia de adaptación de 180∑ ó 220∑ entre la entrada del receptor y
masa, lo que se denomina terminación pasiva.
220∑
470∑
5V
220∑
Terminación pasiva
Terminación activa
Emisor
Emisor
Receptor
Receptor
Fig. 1.10 Terminaciones pasiva y activa de una línea de un bus para eliminar o reducir las reflexiones en líneasde larga longitud
La terminación pasiva, no obstante, presenta el problema de que la resistencia de adaptación es una
carga más para el transmisor, por lo que reduce el número de receptores que se le pueden conectar.
Esta situación se puede mejorar utilizando un divisor de tensión que sitúa la línea a la mitad del
margen de tensión para la familia TTL, y que, además, adapta el receptor a la impedancia
característica de la línea (figura 1.10). Esta solución se denomina terminación activa. Con la
terminación activa se asegura que, al menos, la amplitud del pulso reflejado será siempre menor que el
valor del pulso transmitido, eliminando las reflexiones de forma paulatina.
1.3 Estructura general de un sistema basado en microprocesador
La estructura de los diferentes sistemas basados en microprocesadores suele presentar bastantes
características comunes, como son los dispositivos de entrada/salida, las memorias para albergar
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25122
programas y datos, los dispositivos de comunicación asíncrona con otros sistemas, los dispositivos de
entrada y visualización de información, como mediante teclados y visualizadores, etc. La figura 1.11
muestra la estructura general de un sistema basado en microprocesador, considerando una buena parte
de los dispositivos necesarios para desarrollar satisfactoriamente cualquier aplicación, sin llegar a
especificar el tipo de microprocesador, los dispositivos y los periféricos empleados.
Memorias
RAMEPROM
EEPROM
Puertosde E/S
E/Sanalógicas
Timers Puertoserie
CPU
Generadoresde reloj y
sincronismo
Controladorde teclado yvisualización
RS-232CRS-422RS-485
Accesodirecto amemoria
DMA
Buses de direcciones, control y datos
Otr
osdi
spos
itiv
os
Fig. 1.11 Diagrama general de bloques de un sistema basado en microprocesador
En la figura 1.11 se pueden distinguir puertos de E/S, memorias, temporizadores, puerto serie de
comunicación, etc. Cada uno de estos bloques suele estar implementado por un circuito integrado, CI,
que proporcionan los fabricantes como soporte de sus microprocesadores o microcontroladores, y que
facilitan la tarea del diseño y mejoran las prestaciones del sistema.
Las memorias son uno de los elementos de los que hay mayor variedad y oferta en el mercado, donde
se pueden encontrar memorias SRAM, DRAM, PROM, EPROM, EEPROM, FLASH, NOVRAM,
etc. Es imprescindible en todo sistema que exista una memoria no volátil, como la PROM, la FLASH
y la EPROM, para albergar el programa del sistema, como una memoria volátil, como la SRAM o
DRAM, para albergar los datos generados y utilizados por el programa.
En los sistemas basados en microcontrolador las memorias más ampliamente utilizadas son del tipo
EPROM y SRAM, aunque también se usan otro tipo de memorias como la OTPROM (One timeprogrammable), la NOVRAM (Non-volatile RAM) y memorias del tipo serie que envían y reciben los
datos vía serie con la CPU.
Por otra parte, existen circuitos integrados que proporcionan 2, 3 ó 4 puertos de E/S, programables por
el usuario y de propósito general. Estos circuitos integrados se utilizan en los microprocesadores/
microcontroladores, para disponer de E/S o para ampliar el número de E/S. A través de los puertos de
E/S se puede hacer el control de los periféricos, la transmisión y recepción de datos entre la CPU y los
periféricos, la activación de actuadores, la lectura del estado de sensores, teclas, finales de carrera, etc.
Un ejemplo de puerto de E/S es el 8255 de Intel Corporation que soporta hasta tres puertos de E/S de
© Los autores, 2001; © Edicions UPC, 2001.
1 Estructura básica de un sistema microprocesador 23
8 líneas cada uno, y el PI/T MC68230 de Motorola, que es una interfaz paralela, bidireccional o
unidireccional, de 8 ó 16 bits, con un temporizador programable de 24 bits.
En aplicaciones que requieran de la generación y del sincronismo de señales, o de la temporización de
determinados sucesos, se necesitan circuitos integrados Timers, que son temporizadores/contadores
capaces de contabilizar y temporizar señales de acuerdo con una señal de reloj de entrada. Además,
también hay circuitos integrados específicos para la generación de varias señales de reloj y el
sincronismo de sistemas basados en microprocesador. En este sentido, por ejemplo, se pueden
encontrar el 8253 y 8254 de Intel, o el MFP MC68901 de Motorola. Este último es un circuito
multifunción, con cuatro temporizadores programables, un controlador de hasta 16 fuentes de
interrupción, un puerto de E/S programable y un canal USART de comunicación serie asíncrona.
Otro elemento importante es el puerto serie que proporciona el soporte al sistema microprocesador
para poder comunicarse, vía serie, con otros sistemas, empleando estándares del tipo RS-232C, RS-
422, etc. En este sentido existen en el mercado circuitos integrados que soportan la comunicación
serie asíncrona, haciendo de puerto serie para el sistema microprocesador. Como CI integrado de este
tipo, por ejemplo, se puede encontrar al 8250 de Intel que soporta un puerto serie para la
comunicación con otros sistemas, o el SIO MC68564 de Motorola que soporta la comunicación serie
síncrona y asíncrona con otros sistemas.
La variedad de circuitos integrados específicos que se ofrecen para el soporte de los sistemas basados
en microprocesador es amplia. Prácticamente, se encuentran disponibles en el mercado circuitos
integrados de todo tipo, como controladores del acceso directo a memoria (DMA), circuitos
integrados capaces de leer un teclado matricial y de gestionar, al mismo tiempo, un visualizador
compuesto por un número determinado de dígitos, circuitos integrados para el arbitraje y la gestión de
los buses del sistema microprocesador, circuitos integrados para la gestión de interrupciones, circuitos
integrados para el control y acceso de una unidad lectora de disquetes, circuitos integrados para
detectar las caídas de tensión de la red eléctrica, etc. El número de circuitos integrados de soporte a un
sistema basado en microcontrolador es considerable y está sometido a un proceso continuo de mejora
y renovación, por lo que se debe procurar tener un buen conocimiento de estos dispositivos y estar al
tanto de las nuevas propuestas que surgen de forma periódica en el mercado.
1.4 Estructura general de un sistema basado en microcontrolador
En un principio se desarrollaron los sistemas basados en microprocesador y se aplicaron al control de
multitud de procesos industriales, a la computación y procesado de datos y al procesado de señales. A
medida que la tecnología de silicio fue evolucionando, permitiendo la integración de un mayor
número de transistores en la misma área de silicio, la complejidad de los microprocesadores aumentótambién y se produjo una especialización según el campo de aplicación. En este momento, los
microprocesadores se especializan básicamente en el entorno de la computación y del procesado de
datos, aunque también se aplican en determinados procesos industriales donde se necesita de una
computación intensa de datos. Por otra parte, aparecen los microcontroladores, especialmente
concebidos para el ámbito de control de procesos industriales y para la gestión y el control de
máquinas diversas. Por último, también surgen los procesadores digitales de señal (DSP),
especialmente pensados para el procesado de señal, como, por el ejemplo, el procesado de la señal de
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25124
voz en teléfonos móviles y el filtrado de señales de televisión; aunque también se emplean en el
control de motores y en tareas de control, en general, donde las señales son de rápida variación.
CPU
Generadoresde reloj y
sincronismo
Controladorde teclado yvisualización
RS-232CRS-422RS-485
Accesodirecto amemoria
DMA
Otr
osdi
spos
itiv
os
CI Microcontrolador
Puertosde E/S
E/Sanalógicas
Timers
Memorias
RAMEPROM
EEPROM
Puertoserie
Buses de direcciones, control y datos
Fig. 1.12 Concepción de un microcontrolador basada en la inclusión de la CPU y otros elementos de un sistemamicroprocesador en un único circuito integrado
En cuanto al concepto de microcontrolador, éste se concibe como la inclusión de algunos de los
dispositivos que aparecen en la figura 1.11 dentro del mismo circuito integrado. En consecuencia,
según la figura 1.12, un microcontrolador está formado por una CPU, más los elementos
imprescindibles para interactuar con el exterior y para solucionar y simplificar una buena parte de las
aplicaciones que hasta el momento se venían realizando con los sistemas basados en microprocesador.
En la actualidad los microcontroladores suelen incorporar, además de la CPU, puertos de E/S,
memoria ROM, EPROM, OTPROM o FLASH para albergar el programa realizado, memoria RAM,
registros de propósito general que facilitan la tarea del programador, temporizadores y contadores para
contabilizar y temporizar eventos, puerto serie con el que implementar estándares del tipo RS-232C,
etc, convertidor analógico/digital para la lectura de señales analógicas, salidas con modulación de
pulsos, etc.
En este momento, en el mercado existen multitud de fabricantes de microcontroladores que, además,
ofrecen una amplia gama de versiones, capaces de ajustarse a distintos tipos de aplicaciones. En
consecuencia, el diseñador debe tener muy claros los criterios de elección, en función de las
prestaciones y los costos de las herramientas de desarrollo que se deben adquirir, como son los
emuladores, las tarjetas de evaluación y los programas de software para el desarrollo de la aplicación.
© Los autores, 2001; © Edicions UPC, 2001.
2 Las familias de microcontroladores de Intel y de otros fabricantes 25
2 Las familias de microcontroladores de Intel y de otros fabricantes
2.1 La familia MCS-48
La MCS-48 fue la primera familia de microcontroladores de 8 bits de la compañía Intel Corporation.
Esta familia fue diseñada para emplearse en pequeñas aplicaciones y podía soportar hasta un máximo
de 4k bytes de código de programa y 256 bytes para datos. La MCS-48 ya no se fabrica en la
actualidad. Las principales características que tenía esta familia se resumen en la tabla 2.1.
Tabla 2.1 Principales características de la familia MCS-48
MicrocontroladoresVersión básica 8035AHL 8039AHL 8049AHL
Versión con ROM 8048AH 8049AH 8050AHL
Versión con EPROM 8748H 8749H -
CaracterísticasMemoria RAM interna 64 128 256
Memoria EPROM/ROM 1k bytes 2k bytes 4k bytes
Temporizadores 1 1 1
Fuentes de interrupción 2 2 2
Líneas de E/S 27 27 27
2.2 La familia MCS-51
La MCS-51 es en la actualidad la familia básica de microcontroladores de 8 bits de Intel. Esta familia
es adecuada para soportar aplicaciones sencillas y de mediana complejidad y se ha convertido en uno
de los estándares del mercado, puesto que se ha utilizado en multitud de aplicaciones y, además, otros
fabricantes, como Siemems Components, Atmel, Philips Semiconductors, OKI Semiconductor, etc.,
proporcionan versiones especializadas de ésta. La tabla 2.2 muestra los principales componentes de
esta familia, donde se han excluido las versiones con memoria ROM interna, puesto que ésta debe ser
implementada por el propio fabricante mediante máscara en la fase de producción, lo que supone que
tan sólo sea rentable en grandes series de producción; está, pues, lejos del alcance de la economía de
la mayor parte de los usuarios. Las principales características de la MCS-51 se listan a continuación:
- 32 líneas de entrada/salida (E/S), distribuidas en 4 puertos de 8 bits cada uno.
- Memoria RAM interna de hasta 256 bytes.
- 4 bancos de 8 registros de un byte cada uno.
- Área de registros de función especial (SFR).
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25126
- Espacio de memoria para programas de hasta 64k.
- Espacio de memoria para datos de hasta 64k.
- Hasta 3 temporizadores de 16 bits cada uno.
- Comunicación serie asíncrona (UART full-duplex).
- De 5 a 6 fuentes de interrupción con 2 niveles de prioridad.
- 2 modos especiales de bajo consumo (Power Down y Idle).
- Juego de instrucciones con capacidad de procesamiento booleano.
Tabla 2.2 Microcontroladores de la MCS-51
VersiónOTROM/EPROMbytes
Mem.RAMBytes
Líneasde E/S
Nº de
Timers
Líneas deinterrup.
Nºcanales
PCAA/D
Modosbajo
consumo
Veloc.relojMhz
8031AH - 128 32 2 5 0 0 - 12
8751BH 4K EPROM 128 32 2 5 0 0 - 12
8032AH - 256 32 3 6 0 0 - 12
8752BH 8K EPROM 256 32 3 6 0 0 - 12
80C31BH - 128 32 2 5 0 0�
12,16
87C51 4K EPROM 128 32 2 5 0 0�
12,16,20,24
87C52 8K EPROM 256 32 3 6 0 0�
12,16,20,24
87C54 16K EPROM 256 32 3 6 0 0�
12,16,20,24
87C58 32K EPROM 256 32 3 6 0 0�
12,16,20,24
87L52 8K OTPROM 256 32 3 6 0 0�
12,16,20
87L54 16K OTPROM 256 32 3 6 0 0�
12,16,20
87L58 32K OTPROM 256 32 3 6 0 0�
12,16,20
80C51FA - 256 32 3 7 5 0�
12,16
87C51FA 8K EPROM 256 32 3 7 5 0�
12,16,20,24
87C51FB 16K EPROM 256 32 3 7 5 0�
12,16,20,24
87C51FC 32K EPROM 256 32 3 7 5 0�
12,16,20,24
87L51FA 8K OTPROM 256 32 3 7 5 0�
12,16,20
87L51FB 16K OTPROM 256 32 3 7 5 0�
12,16,20
87L51FC 32K OTPROM 256 32 3 7 5 0�
12,16,20
80C51GB - 256 48 3 15 10 8�
12,16
87C51GB 8K EPROM 256 48 3 15 10 8�
12,16
80C152JA - 256 40 2 11 0 0�
16.5
80C152JB - 256 56 2 11 0 0�
16.580C51SL-BG - 256 24 2 10 0 4
�
1687C51SLAH 16K EPROM 256 24 2 10 0 4
�
16
2.3 La familia MCS-151
La familia MCS-151 de microcontroladores de 8 bits es totalmente compatible, a nivel de juego de
instrucciones y de encapsulado, con la MCS-51. Esta familia, al igual que la familia posterior MCS-
251, es una mejora y actualización en prestaciones de la familia MCS-51. El número de componentes
de la MCS-151 es reducido y se muestra en la tabla 2.3, y sus principales características se resumen a
continuación:
- Procesamiento paralelo de instrucciones “Pipeline”.
- Juego de instrucciones y encapsulado compatibles con la MCS-51.
© Los autores, 2001; © Edicions UPC, 2001.
2 Las familias de microcontroladores de Intel y de otros fabricantes 27
- Espacio de memoria para programas de hasta 64k.
- Espacio de memoria para datos de hasta 64k.
- Memoria interna ROM/OTPROM de 8 ó 16k bytes.
- Memoria RAM interna de hasta 256 bytes.
- Hasta 3 temporizadores de 16 bits cada uno.
- 32 líneas de entrada/salida (E/S).
- 7 fuentes de interrupción con 4 niveles de prioridad.
- Batería o array de contadores programable (PCA).
- Salidas con modulación de anchura de pulsos (PWM).
- Temporizador de watchdog.
- Comunicación serie asíncrona (UART full-duplex).
- Terminal WAIT de estados de espera para memorias.
- Modos no paginado y paginado de acceso a la memoria externa.
- Modos especiales de bajo consumo (Power Down y Idle).
Tabla 2.3 Microcontroladores de la familia MCS-151
Versión ROM/OTPROM RAM interna
80C151SB - 256 bytes
83C151SA 8K bytes ROM 256 bytes
83C151SB 16K bytes ROM 256 bytes
87C151SA 8K bytes OTPROM 256 bytes
87C151SB 16K bytes OTPROM 256 bytes
2.4 La familia MCS-251
La familia de microcontroladores de 8 bits MCS-251 es el resultado de la mejora y actualización de
las familias MCS-51 y MCS-151. Esta familia presenta un aumento general de prestaciones con
respecto a las anteriores, en cuanto al número de instrucciones, velocidad y flexibilidad; mantiene, al
mismo tiempo, la compatibilidad tanto a nivel de hardware como de software, lo que posibilita que
pueda sustituir, con un mínimo coste y de manera directa, a la MCS-51, y actualizar así las
aplicaciones que están soportadas por esta familia.
El primer miembro de la familia MCS-251 es el 8XC251Sx que se comercializa en varias versiones,
en función de la cantidad de memoria interna disponible. En la tabla 2.4 se muestran los
microcontroladores que forman parte de esta familia, y a continuación se listan sus principales
características:
- Procesamiento paralelo de instrucciones “Pipeline”.
- 24 líneas de dirección internas que permiten un espacio de hasta 16 Mbytes de memoria.
- Juego de instrucciones ampliado con respecto a la MCS-51, con instrucciones aritméticas y
lógicas de 16 y de 32 bits.
- Encapsulado y juego de instrucciones, en modo binario, compatibles con la MCS-51.
- Acceso a los registros de propósito general a nivel de byte, de Word (2 bytes) y de DoubleWord (4 bytes).
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25128
- Puntero de la pila (registro Stack Pointer) de 16 bits, que permite acceder a una memoria de
pila de hasta 64 kbytes.
- Tiempo mínimo de ejecución de una instrucción de 2 periodos de reloj.
- Memoria interna ROM/OTPROM de 8 ó 16k bytes.
- Memoria RAM interna de hasta 1024 bytes.
- Hasta 3 temporizadores de 16 bits cada uno.
- 32 líneas de entrada/salida (E/S).
- 7 fuentes de interrupción con 4 niveles de prioridad.
- Batería o array de contadores programable (PCA).
- Salidas con modulación de anchura de pulsos (PWM).
- Temporizador de watchdog.
- Comunicación serie asíncrona (UART full-duplex).
- Terminal WAIT de estados de espera para memorias.
- Modos no paginado y paginado de acceso a la memoria externa.
- Modos especiales de bajo consumo (Power Down y Idle).
Tabla 2.4 Microcontroladores de la familia MCS-251
Memoria interna
Versión OTPROM/EPROM(kbytes)
ROM(kbytes)
RAM(bytes)
80C251SB
80C251SQ
0
0
0
0
1024
512
83C251SA
83C251SB
83C251SP
83C251SQ
0
0
0
0
8
16
8
16
1024
1024
512
512
87C251SA
87C251SB
87C251SP
87C251SQ
8
16
8
16
0
0
0
0
1024
1024
512
512
Estas características proporcionan importantes mejoras con respecto a la familia MCS-51, como son el
incremento de la velocidad de ejecución para una misma frecuencia de reloj, el incremento de la
eficiencia en los programas escritos en lenguaje C, debido al acceso en los tipos Word y Double Word,
y la capacidad de procesar programas de mayor tamaño.
2.5 Microcontroladores de otros fabricantes
2.5.1 Microcontroladores de Philips
Philips Semiconductors tiene una gran variedad de microcontroladores de 8 bits basados en la
arquitectura de la MCS-51. La oferta que tiene es muy extensa, por lo que es fácil hallar una versión
que se ajuste a las necesidades de un proyecto. Este fabricante tiene microcontroladores con memoria
EPROM, OTPROM o FLASH internas, versiones que soportan el bus serie I2C, temporizador de
© Los autores, 2001; © Edicions UPC, 2001.
2 Las familias de microcontroladores de Intel y de otros fabricantes 29
watchdog, array de contadores programable PCA, convertidores A/D de 8 y 10 bits, funcionamiento
en baja tensión, etc. La tabla 2.5 muestra los principales componentes de esta familia.
Tabla 2.5 Microcontroladores de Philips Semiconductors
Ver
sión
RO
M
OT
P o
FL
ASH
RA
M (
byte
s)
Tim
ers
PW
M
PC
A
Watc
hdo
g
Lín
eas
E/S
(I/
O)
Inte
rrup
cion
es
Int.
ext
erna
s
A/D
(bi
ts)
A/D
(ca
nale
s)P
rote
cció
npr
ogra
ma
UA
RT
I2 C
Car
cter
ísti
cas
espe
cial
es
Max
. fre
q.(M
Hz)
80C31/80C32 - - 128-256 3 - - - 32 6 2 - -���
- 2.7-5.5V,Low-power 33
8xC51/8xC52 8k 8k 128-256 3 - - - 32 6 2 - -���
- 2.7-5.5V,Low-power 33
8xC54/8xC58 16-32k 16-32k 256 3 - - - 32 6 2 - -���
- 2.7-5.5V,Low-power 33
89C5x - 4-32k 128-256 3 - - - 32 6 2 - -���
- MTP Flash 33
8xC51Fx 8-32k 8-32k 256 4�����
32 7 2 - -���
- 2.7-5.5V 33
8xC51Rx+ 16-64k 16-64k 512-1024 4�����
32 7 2 - -���
- 2.7-5.5V 33
89C51Rx+ - 32-64k 512-1024 4�����
32 7 2 - -���
- Flash-12V ISP 33
87LPC762 - 2k 128 2 - -�
18 12 3 - -����� BOD,PUR,Keypad
interrupt.Low-power20
87LPC764 - 4k 128 2 - -�
18 12 3 - -����� BOD,PUR,Keypad
interrupt.Low-power20
87LPC767 - 4k 128 2 - -�
18 12 3 8 4�����
51LPC con A/D 20
87LPC768 - 4k 128 2�
-�
18 12 3 8 4�����
A/D y PWM 20
87LPC769 - 4k 128 2 - -�
18 12 3 8 4�����
A/D y D/A 20
8xC591 16k 16k 512 3�
-�
32 15 2 10 6�����
CAN 2.0B/PeliCAN 16
89C51Rx2 - 16-64k 512-1024 4�����
32 7 2 - -���
- Flash,5V,ISP/IAP 33
89C66x - 16-64k 1k-2k 4�����
32 8 2 - -�����
Flash,5V,ISP/IAP 20/33
8xC554 16k 16k 512 3�
-�
48 15 2 10 8 -��� 2.7-5.5V,Capture/
compare16
80/83C557E4
89C557E432k 32k 1024 3
�
-�
48 2 10 8����� Low EMI, 2 PWM
Capture/compare16
80C557E6
83C557E648k 48k 1536 3
�
-�
48 2 10 8����� Low EMI, 2 PWM
Capture/compare16
8xC557E8 64k 64k 2048 3�
-�
48 2 10 8����� Low EMI, 2 PWM
Capture/compare16
8xC524 16k 16k 512 3 - -�
32 8 2 - - -���
- 24
8xC528 32k 32k 512 3 - -�
32 8 2 - -�����
- 16
80/83/87C552 8k 8-16k 512 3�
-�
48 15 2 10 8 -���
- 24
80/83/87C652 8k 8-16k 256 2 - - - 32 7 2 - -�����
- 24
8xC750 1k 1k 64 1 - - - 19 2 - - - - - - 16
8xC748 2k 2k 64 2 - - - 19 2 - - - - - - 16
8xC751 2k 2k 256 1 - - - 19 2 - - - -�
- 16
8xC575 8k - 256 3 -���
32 2 - - -�
- - 16
8xC576 8k - 256 3 -���
32 2 10 6 -�
- - 16
8xC749 2k 2k 64 2�
- - 21 2 8 5 - - - - 16
8xC752 2k 2k 64 1�
- - 21 2 8 5 - -�
- 16
8xC591 16k 16k 512 3�
-�
32 15 2 10 6�����
CAN 2.0B/PeliCAN 16
8xC592 16k 16k 512 3�
-�
48 6 2 10 8���
- CAN bus controller 16
8xCE598 32k 32k 512 3�
-�
48 6 2 10 8�����
CAN bus controller 16
Las versiones que tienen bus serie I2C se pueden conectar por medio de este bus a distintos periféricos
y microcontroladores. El bus I2C utiliza tan sólo dos terminales del microcontrolador, uno como línea
de datos y otro como línea de reloj, y es capaz de operar en un sistema con multi-másters y de soportar
multitud de periféricos en el mismo bus.
Las versiones con un bus del tipo CAN (Control Area Network) se pueden utilizar en aplicaciones
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25130
para la industria del automóvil y en sistemas de manufactura automatizada, pues inicialmente este bus
fue concebido para reducir el número elevado de cables en un automóvil. El bus CAN es un bus serie
de alta velocidad formado por dos hilos, que puede llegar a distancias de hasta 40 metros y con el que
se pueden realizar estructuras de bus con hasta 30 nodos de comunicación.
2.5.2 Microcontroladores de Siemens
Siemens es un fabricante que tiene una amplia gama de productos en multitud de sectores distintos. En
el ramo de semiconductores tiene la familia C500 de microcontroladores, compatibles tanto a nivel de
hardware como de software con la MCS-51. La tabla 2.6 muestra los principales componentes de esta
familia. Los microcontroladores de Siemens pueden funcionar a altas frecuencias de reloj, pueden
tener memoria ROM o OTPROM, puerto serie full-duplex, modos especiales de bajo consumo, varios
registros de punteros de datos DPTR, etc.
Tabla 2.6 Microcontroladores de Siemens
Ver
sión
RO
M
RA
M (
byte
s)
RO
M P
rote
gida
Lín
eas
E/S
A/D
(bi
ts)
A/D
(C
anal
es)
Tim
ers
(16
bits
)
Nº
Inte
rrup
cion
es
MD
U
Pue
rto
seri
e
PW
M (
cana
les)
Pun
tero
s de
dat
osD
PT
R (
16 b
its)
Watc
hdo
g
Max
. fre
q. r
eloj
(MH
z)
C501G-L/-1R -/8k 256�
32 - - 3 6 - USART - 1 - 40
C501G-E 8k OTP 256�
32 - - 3 6 - USART - 1 - 40
C504-L/-2R -/16k 512�
32 10 8 4 12 - USART 6 1�
40
C504-2E 16k OTP 512�
32 10 8 4 12 - USART 6 1�
40
C513-1R 8k 256 - 32 - - 3 7 - USART+SSC - 1 - 12
C513A-L/-R/-2R -/12k/16k 512 - 32 - - 3 7 - USART+SSC - 1 - 12
C513A-2E 16k OTP 512�
32 - - 3 7 - USART+SSC - 1 - 16
C505L-4E 32k OTP 512 - 46 10 8 3 12 - USART 4 8�
20
C505-L/-2R -/16k 512�
34 8 8 3 12 - USART 4 8�
20
C505C-L/-2R -/16k 512�
34 8 8 3 12 - USART 4 8�
20
C505A-4E 32k OTP 1280�
34 10 8 3 12 - USART 4 8�
20
C505CA-4E 32k OTP 1280�
34 10 8 3 12 - USART 4 8�
20
C515-L/-1R -/8k 256�
56 8 8 3 12 - USART 4 1�
24
C515A-L/-4R -/32k 1280�
56 10 8 3 12 - USART 4 1�
24
C515C-L/-8R -/64k 2304�
57 10 8 3 15 - USART+SSC 4 8�
10
C515C-8E 64k OTP 2304�
57 10 8 3 15 - USART+SSC 4 8�
10
C517A-L/4R -/32k 2304�
68 10 12 4 17�
USART+UART 21 8�
24
C509-L - 3328 - 64 10 15 5 19�
USART+UART 29 8�
16
SAB 80C515 8k 256�
56 8 8 3 12 - USART 4 1�
20
SAB 80C535 - 256 - 56 8 8 3 12 - USART 4 1�
20
SAB 80C515A - 1280 - 56 10 8 3 12 - USART 4 1�
18
SAB 83C515A-5 32k 1280�
56 10 8 3 12 - USART 4 1�
18
SAB 80C517 8k 256�
68 8 12 3 12�
USART+UART 21 8�
16
SAB 80C537 - 256 - 68 8 12 4 14�
USART+UART 21 8�
16
SAB 80C517A - 2304 - 68 10 12 4 17�
USART+UART 21 8�
18
SAB 83C517A-5 32k 2304�
68 10 12 4 17�
USART+UART 21 8�
18
Las versiones SAB80C517, SAB80C517A, SAB80C517A-5, SAB80C537, C517A-L/4R y C509-L
tienen una unidad de multiplicación y división por hardware, MDU, que es capaz de realizar
divisiones de datos de 32 bits y multiplicaciones de datos 16 bits. Las versiones C505-L, C505-2R,
C505CA-4E, C515C-L, C515-8R y C515C-8E soportan el bus serie FCAN 2.0B.
© Los autores, 2001; © Edicions UPC, 2001.
2 Las familias de microcontroladores de Intel y de otros fabricantes 31
2.5.3 Microcontroladores de Atmel
El fabricante Atmel Corporation tiene una familia de microcontroladores de 8 bits basados en la
arquitectura de la MCS-51. Una de las características más relevantes de los microcontroladores de este
fabricante es que todos ellos tienen memoria interna flash. Estos microcontroladores tienen un precio
más reducido que los microcontroladores con memoria interna EPROM. La tabla 2.7 muestra los
microcontroladores con memoria flash de Atmel y las distintas características de cada uno. Las
características generales de estos microcontroladores son:
- Memoria interna flash para programas.
- Memoria RAM interna.
- Patillas bidireccionales de I/O accesibles bit a bit.
- Varios temporizadores/ contadores de 16 bits.
- UART Full-Duplex.
- Múltiples fuentes de interrupción.
- La versión AT89S tiene 2K de memoria EEPROM interna, una interfaz SPI
de bus serie y un temporizador de Watchdog.
Tabla 2.7 Características de los microcontroladores flash de Atmel
Características AT89C1051 AT89C2051 AT89C51 AT89LV51 AT89C52 AT89LV52 AT89C55 AT89S8252
Memoria flash (bytes) 1K 2K 4K 4K 8K 8K 20K 8K
Memoria RAM (bytes) 64 128 128 256 256 256 256 256
Mem. EEPROM interna 0 0 0 0 0 0 0 2K
Interfaz serie SPI - - - - - - -�
Proframación In-system�
SI SI SI SI SI SI�
Nº de Timers 1 2 2 3 3 3 4 3
Nº de bits de seguridad
(Lock bits)2 2 3 3 3 3 3 3
Watchdog timer - - - - - - -�
UART serie -� � � � � � �
Salida de Power Downmediante interrupción
- - - - - - -�
Comparador analógico SI SI - - - - - -
Terminales de I/O 15 15 32 32 32 32 32 32
Fuentes de interrupción 3 6 6 6 8 8 8 9
Bus externo de datos/
direcciones- -
� � � � � �
Modos Power Down y
Idle� � � � � � � �
Alimentación Vcc 2.7-6.0 2.7-6.0 4.0-6.0 2.7-6.0 4.0-6.0 2.7-6.0 2.7-6.0 2.7-6.0
Frecuencia Clock 0-24 0-24 0-24 0-24 0-24 0-24 0-33 0-33
Patillas del encapsulado 20 20 40/44 40/44 40/44 40/44 40/44 40/44
I/O Current Sink(por patilla)
20mA 20mA 10mA 10mA 10mA 10mA 10mA 10mA
Corriente total máxima de
I/O (mA)80mA 80mA 71mA 71mA 71mA 71mA 71mA 71mA
2.5.4 Microcontroladores de Dallas Semiconductor
Dallas Semiconductor tiene un par de familias de microcontroladores compatibles con la MCS-51.
Una de las familias de este fabricante se centra en la seguridad anticopia del programa, con
encriptación en tiempo real, y en utilizar memoria del tipo NOVRAM para almacenar el programa, en
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25132
lugar de ROM o EPROM. La segunda familia que oferta es de alta velocidad, capaz de ejecutar las
instrucciones hasta tres veces más rápidamente que la familia MCS-51.
La primera familia está formada por los microcontroladores DS5000 y DS5002T, cuyas principales
características son:
- 100% compatible en hardware y software con la MCS-51.
- NOVRAM de 8k ó 32kbytes.
- Zona particionada para código y para datos.
- Cuatro puertos de E/S.
- Memoria RAM de 128 bytes.
- Dos temporizadores/contadores de 16 bits.
- Una puerto UART serie.
- Watchdog Timer.
- Seguridad anticopia para el código.
- Generador aleatorio de número.
- Interrupción por fallo de tensión.
La familia de alta velocidad está formada por los microcontroladores DS80C310, DS80C320,
DS80C323, DSC390, DS83C520, DS83C530, DS87C520, DS87C530 y DS87C550. Las
características comunes a estos microcontroladores son:
- 100% compatible en hardware y software con la MCS-51.
- Dos puertos serie UART de alta velocidad.
- Tres temporizadores de 16 bits.
- Detección de fallo de tensión.
- Dos punteros de datos, DPTR, para acceder a memoria externa.
- Temporizador de watchdog.
- Memoria RAM interna de 256 bytes.
La versión DS80C320 tiene 13 fuentes de interrupción, de las que 6 corresponden a fuentes externas.
Las versiones DS87C520 y DS87C530 tienen 13 y 14 fuentes de interrupción, respectivamente,
1kbyte de memoria SRAM interna accesible con la instrucción MOVX y 16kbytes de memoria
EPROM. La versión DS87C550 tiene estas mismas características y, además, incluye un convertidor
A/D de 10 bits y con 8 canales multiplexados, 8kbytes de memoria EPROM y 4 canales de PWM con
una precisión de 8 bits.
La versión DS80C310 es un modelo reducido de la DS80C320, pensada para las aplicaciones donde el
coste es un factor importante. La versión DS80C323 es un modelo de bajo consumo y baja tensión de
la DS80C320; tiene una frecuencia máxima de reloj de 18MHz, consume tan sólo 10mA y puede
alimentarse entre 2.7V y 5.5V.
La versión DSC390 incorpora un bus serie CAN dual de alta velocidad, formado por dos interfaces
CAN 2.0B. Esta versión también incorpora 4kbytes de memoria SRAM interna. Por último, las
versiones DS83C520 y la DS83C530 tienen 16kbytes de memoria ROM interna, al ser ideadas para
grandes series de fabricación.
© Los autores, 2001; © Edicions UPC, 2001.
3 Arquitectura de las familias MCS-51 y MCS-251 33
3 Arquitectura de las familias MCS-51 y MCS-251
3.1 Arquitectura interna de la MCS-51
La figura 3.1 muestra el diagrama general de bloques para los microcontroladores de la familia MCS-
51, cuyas características generales ya se han descrito en el capítulo 2. De esta arquitectura cabe
resaltar el área de registros especiales y el direccionamiento de la memoria interna.
SCON
PCON
TCON TMOD TH0
TH1 TL1
TL0
SBUF
RCAP2H*
RCAP2L* TH2* TL2*
T2CON*
IE IP
Interrupciones. Puerto serie.
Temporizadores. PCA
Registro de
direcciones
programa
Incrementador
PC
BUFFER
PC
DPTR
Memoria
EPROM/ROM
LatchPuerto 2
LatchPuerto 0
LatchPuerto 1
LatchPuerto 3
Puerto 0 Puerto 2
Puerto 3Puerto 1
ACC
TMP1 TMP2
ALU
PSW
B
Memoria
RAMinterna
StackPointer
SP
Control
y
secuenc.
Reg
istr
o d
ein
stru
ccio
nes
Reg
istr
o d
edir
ecc.
RA
M
OSC
XTAL1XTAL2 P1.0 ... P1.7 P3.0 ... P3.7
P2.0 ... P2.7P0.0 ... P0.7
PSEN
ALE
EA
RESET
VCC
VSS
* Sólo en las versiones con 3 temporizadores
Fig. 3.1 Arquitectura interna de la familia MCS-51
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25134
El núcleo del microcontrolador está formado por la unidad de control, la unidad aritmético-lógica
(ALU), el registro de estado (PSW), el acumulador y el contador de programa (PC). Este último es un
registro de 16 bits que se utiliza como puntero hacia la memoria de programas y su valor apunta
siempre a la dirección de memoria que contiene la instrucción a ejecutar.
Cabe destacar, en esta figura, la importancia del acumulador, puesto que interviene en la mayor parte
de las instrucciones, sobre todo en las instrucciones aritméticas.
La familia MCS-51 tiene cuatro puertos: P0, P1, P2 y P3. Los puertos son de 8 bits, y cada bit puede
ser configurado de forma individual como entrada o como salida (E/S), siendo transparente para el
programador. La MCS-51 tiene versiones con memoria interna de programas EPROM, OTPROM o
ROM; no obstante, en caso de necesitar memoria externa, los puertos P0 y P2 soportan un bus de
direcciones de 16 bits y un bus de datos de 8 bits para acceder a ésta. En este caso, el byte bajo del bus
de direcciones y el bus de datos comparten el mismo puerto, P0, mediante una multiplexación
temporal entre ambos buses. En cuanto al byte alto del bus de direcciones, éste queda íntegramente
soportado por el puerto P2. La multiplexación temporal realizada en el puerto P0 es una manera hábil
de optimizar el número de terminales del microcontrolador, minimizando el tamaño de su
encapsulado.
En la figura 3.1 aparecen, además, un bloque que representa la memoria RAM interna, con la cual
opera el puntero de la pila (SP, Stack Pointer), el área de registros especiales (SFR) y el puerto P3,
que soporta las siguientes funciones alternativas: puerto de comunicación serie asíncrona,
interrupciones externas, el control de lectura y escritura de la memoria externa de datos y las entradas
de los temporizadores/contadores de la familia. El puerto P1 en las versiones 8X51C51FX soporta las
entradas y salidas del array de contadores programable PCA.
3.1.1 Relación de terminales
La disposición de los terminales de esta familia se muestra en la figura 3.2. En concreto se muestra el
encapsulado de los microcontroladores 87C51BH en formato DIP y PLCC.
VCC
P0.0/AD0
P0.1/AD1
P0.2/AD2
P0.3/AD3
P0.4/AD4
P0.5/AD5
P0.6/AD6
P0.7/AD7
(/EA)/(VPP)
ALE/(/PROG)
/PSEN
P2.7/A15
P2.6/A14
P2.5/A13
P2.4/A12
P2.3/A11
P2.2/A10
P2.1/A9
P2.0/A80
T2/P1.0
T2EX/P1.1
P1.2
P1.3
P1.4
P1.5
P1.6
P1.7
RESET
RXD/P3.0
TXD/P3.1
(/INT0)/P3.2
(/INT1)/P3.3
T0/P3.4
T1/P3.5
(/WR)/P3.6
(/RD)/P3.7
XTAL2
XTAL1
VSS
8
7
5
1
B
H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
40
39
38
37
36
35
34
33
32
31
30
29
28
27
26
25
24
23
22
21
P0.4/AD4
P0.5/AD5
P0.6/AD6
P0.7/AD7
(/EA)/(VPP)
ALE/(/PROG)
/PSEN
P2.7/A15
P2.6/A14
P2.5/A13
P1.5
P1.6
P1.7
RESET
RXD/P3.0
TXD/P3.1
(/INT0)/P3.2
(/INT1)/P3.3
T0/P3.4
T1/P3.5
(/W
R)/
P3
.6P
1.4
A1
2/P
2.4
A1
1/P
2.3
A1
0/P
2.2
A9/P
2.1
A8/P
2.0
NC
VS
S
XT
AL
1
XT
AL
2
(/R
D)/
P3
.7P
1.3
P1
.2
P1
.0
P1
.1
NC
VC
C
P0
.0/A
D0
P0
.1/A
D1
P0
.2/A
D2
P0
.3/A
D3
18 19 20 21 22 23 24 25 26 27 28
17
16
15
14
13
12 NCNC
11
10
9
8
76 5 4 3 2 1 44 43 42 41 40
39
38
37
36
35
34
33
32
29
30
31
8751BH
Fig. 3.2 Microcontrolador 87C51BH en encapsulado DIP o PLCC
© Los autores, 2001; © Edicions UPC, 2001.
3 Arquitectura de las familias MCS-51 y MCS-251 35
La relación de terminales que aparecen en la figura es la siguiente:
- VCC: tensión de alimentación: +5V.
- VSS: terminal de masa.
- P0.0, P0.1… P0.7: puerto bidireccional bit a bit de E/S P0. P0 puede soportar el byte bajo del bus de
direcciones y el bus de datos mediante una multiplexación temporal en el caso de tener que utilizar
memoria externa (AD0,…, AD7).
- P2.0, P2.1… P2.7: puerto bidireccional bit a bit de E/S P2. P2 puede soportar el byte alto del bus de
direcciones (A8,…, A15) en el caso de tener que utilizar memoria externa.
- P1.0, P1.1… P1.7: puerto bidireccional bit a bit de E/S P1. P1 es un puerto de propósito general,
aunque para aquellas versiones que tienen 3 temporizadores, los terminales P1.0 y P1.1 realizan las
funciones alternativas T2 y T2EX del temporizador Timer2, respectivamente. El puerto en las
versiones con array de contadores programable PCA soporta las entradas y salidas de ésta. Los
terminales P1.3, P1.4, P1.5, P1.6, P1.7 son las entradas/salidas, CEX0, CEX1, CEX2, CEX3 y CEX4,
de la PCA, respectivamente (tabla 3.1). Estos terminales actúan como entradas de los módulos 0, 1, 2,
3 y 4 de la PCA cuando trabaja en modo captura, respectivamente, y como salidas de los mismos
módulos cuando la PCA trabaja en modo comparación y en modulación de anchura de pulsos (PWM).
- P3.0, P3.1… P3.7: puerto bidireccional bit a bit de E/S P3. P3 es un puerto de propósito general; no
obstante soporta las funciones especiales más importantes de la familia MCS-51, como las señales
TXD y RXD del puerto de comunicación serie, las entradas de interrupción /INT0 y /INT1, las
entradas externas T0 y T1 de los temporizadores y las señales de lectura y escritura en memoria
externa de datos /RD y /WR, respectivamente (tabla 3.1).
- ALE/(/PROG): este terminal (ALE, Addres Latch Enable) permite deshacer la multiplexación
temporal entre el byte bajo del bus de direcciones y el bus de datos, realizada en el puerto P0. La señal
ALE suele conectarse a la señal de reloj de un latch de 8 bits, como por ejemplo el 74373, que permite
deshacer la multiplexación. En las versiones de la familia con memoria de programa interna EPROM o
OTPROM, este terminal se emplea en modo /PROG en la fase de programación de la memoria.
-/PSEN: este terminal (/PSEN, Program Store Enable) se activa a 0 lógico cuando el microcontrolador
accede a la memoria externa de programas y se pone a 1 lógico en caso contrario.
- (/EA)/VPP: este terminal (/EA, External Acces) colocado a 1 lógico (Vcc) hace que el
microcontrolador ejecute el código almacenado en la EPROM, OTPROM o ROM internas. Si se
coloca a “0” (masa), el microcontrolador ejecuta el código de programa de la memoria externa de
programas, y activa el bus de direcciones, el bus de datos y las señales de control. Como VPP, el
terminal se utiliza para proporcionar la tensión de programación necesaria de la memoria EPROM o
OTPROM interna.
- RESET: este terminal cuando se pone a “1” reinicializa el microcontrolador, poniendo el contador de
programa (PC) a 0000H, el puntero de la pila (SP) a 07H, todos los puertos (P0 a P3) a FFH y la
mayoría de los registros a cero.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25136
-XTAL1, XTAL2: estos terminales son la entrada de la señal de reloj del microcontrolador. Puede
utilizarse un resonador cerámico o un cristal de cuarzo (figura 3.3); aunque, también se puede utilizar
una señal de reloj externa.
XTAL2
XTAL1
VSS
MCS-51
C
C
Fig. 3.3 Oscilador con cristal de cuarzo o resonador cerámico para la MCS-51.C=30pF÷10pF para cristales de cuarzo. C=40pF÷10pF para resonadores cerámicos
Tabla 3.1 Funciones alternativas de los puertos P1 y P3
Nombre Función alternativa Descripción de la función alternativa
P1.0 T2* Entrada o salida de reloj del Timer 2.
P1.1 T2EX* Entrada externa del Timer 2.
P1.2 ECI† Entrada externa de reloj del PCA.
P1.3 CEX0† Entrada/salida del módulo 0 del PCA.
P1.4 CEX1† Entrada/salida del módulo 1 del PCA.
P1.5 CEX2† Entrada/salida del módulo 2 del PCA.
P1.6 CEX3† Entrada/salida del módulo 3 del PCA.
P1.7 CEX4† Entrada/salida del módulo 4 del PCA.
P3.0 RXD Recepción del puerto de comunicación serie.
P3.1 TXD Transmisión del puerto de comunicación serie.
P3.2 /INT0 Interrupción externa 0.
P3.3 /INT1 Interrupción externa 1.
P3.4 T0 Entrada externa del Timer 0.
P3.5 T1 Entrada externa del Timer 1.
P3.6 /WR Habilitación de escritura en memoria externa.
P3.7 /RD Habilitación de lectura de memoria externa.
* En todas las versiones con 3 temporizadores†
En las versiones con PCA (8XC51FX y 8XL51FX)
3.1.2 Puertos de entrada/salida
La constitución interna de cada uno de los puertos se muestra en la figura 3.4. En el caso del puerto
P0, cualquier de sus terminales, al disponer de un par de transistores NMOS conectados a P0.X, puede
tener tres estados diferentes: 1 lógico (Vcc) si el transistor NMOS1 está en conducción y el transistor
NMOS2 en corte, 0 lógico (tierra) si el transistor NMOS1 está en corte y el transistor NMOS2 en
conducción, y alta impedancia cuando ambos transistores están en corte, por lo que el terminal queda
flotante desconectado de Vcc y de masa.
© Los autores, 2001; © Edicions UPC, 2001.
3 Arquitectura de las familias MCS-51 y MCS-251 37
El resto de los terminales que pertenecen a los puertos P1, P2 y P3, (figura 3.4), tienen una resistencia
de Pull-up1
y un transistor NMOS conectado a tierra, por lo que tan sólo pueden tener dos estados: 1
lógico si el transistor NMOS está en corte y 0 lógico si el transistor está en conducción.
ESCRIBE
EN LATCH
D
LATCH
CL
Q
Q
B1
B2
1
0
MUX
N1
P0.X
N2
DIREC/DATO
CONTROL
VCC
BIT DEL PUERTO 0 (P0)
BUS INT.
LEE
LATCH
LEE
PIN
ESCRIBE
EN LATCH
BUS INT.D
LATCH
CL
Q
Q
B1
B2
1
0
MUX
P2.X
DIREC
CONTROL
VCC
BIT DEL PUERTO 2 (P2)
LEE
LATCH
LEE
PIN
PULL-UPINTERNO
BIT DEL PUERTO 3 (P3) y PUERTO 1 (P1)
D
LATCH
CL
Q
Q
B1
B2
P3.X
VCC
LEE
LATCH
LEE
PIN
PULL-UPINTERNO
Funciónalternativade salida
ESCRIBE
EN LATCH
BUS INT.
Función alternativade entrada
Fig. 3.4 Arquitectura interna de los puertos de la familia MCS-51
Según la figura 3.4, todos los terminales de los puertos tienen una báscula D interna que se emplea
para almacenar la información que se desea leer o escribir en cada terminal, de manera que basta con
que una instrucción ponga un estado determinado en un terminal, para que este estado se mantenga
estable hasta que sea cambiado por otra instrucción del programa. Por ejemplo la instrucción SETB
P1.1 pone a 1 lógico el terminal P1.1: para ello se almacena un 1 lógico en la báscula D, lo que pone
al transistor asociado en corte, pues la puerta NAND fuerza un 0 lógico en su base.
Los puertos P0 y P2 tienen además un multiplexor, MUX, y una lógica adicional, que permite al
microcontrolador utilizar estos puertos como tales o como bus de direcciones y de datos. En este
último caso, el microcontrolador emplea las señales DIREC, DATO y CONTROL para establecer los
estados adecuados en los terminales de estos puertos.
Los puertos P1 y P3 tienen la misma estructura, pues deben realizar distintas funciones alternativas,
como son las entradas y salidas de la PCA, en las versiones 8XC51FX, y las entradas de
interrupciones /INT0 e /INT1, las entradas T0 y T1 para los temporizadores internos, etc. Estas
funciones alternativas se introducen mediante la puerta NAND que aparece en la figura 3.4.
1
Pull-up es el término anglosajón empleado para definir a una resistencia conectada a la tensión de alimentación del
circuito, Vcc. Esta resistencia asegura que el terminal esté a la tensión Vcc cuando en transistor NMOS está en corte.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25138
Todos los puertos tienen al menos un buffer conectado al pin de entrada (B1), y un buffer conectado a
la salida de la báscula D (B2), que intervienen en el proceso de lectura de los puertos. El buffer B1
está gobernado por la señal Read Latch, mientras que el buffer B2 está gobernado por la señal ReadPin. En el juego de instrucciones de la MCS-51, existen instrucciones que leen el estado lógico
procedente del buffer B2 y instrucciones que leen el estado lógico procedente del buffer B1. Estas
últimas son instrucciones que leen el estado lógico de la báscula D, modifican este estado y escriben el
resultado obtenido en la báscula D. A este tipo de instrucciones se les denomina de “lectura-
modificación- escritura” y, en concreto, son las instrucciones: ANL, ORL, XRL, JBC, CPL, INC,
DEC, DJNZ, (MOV PX.Y,C), CLR PX.Y y SETB PX.Y, siempre que operen con uno de los puertos.
Estas instrucciones leen el estado de la báscula para evitar un posible error producido por una mala
interpretación del nivel lógico en la entrada del terminal de un puerto.
En cuanto a la conexión de dispositivos externos, los puertos P1, P2 y P3 pueden soportar una
corriente de entrada máxima en un terminal de 1.6mA en estado lógico cero, transistor NMOS en
conducción. En cambio, el puerto P0 puede soportar hasta una corriente de 3.2mA a cero lógico.
3.2 Organización de la memoria y de los registros internos de la MCS-51
En los microcontroladores de la familia MCS-51 se pueden distinguir tres tipos de memoria:
- Área de memoria de programas y memoria de datos.
- Área de memoria interna y de registros de propósito general.
- Área de registros de función especial SFR, Special Function Registers.
La memoria de programas y la memoria de datos son áreas de memoria externa al microcontrolador,
aunque hay versiones con memoria ROM, EPROM o OTPROM en su interior. La memoria interna y
los registros de propósito general pertenecen a la estructura interna de la MCS-51. Los registros de
función especial SFR son registros que configuran los recursos internos de la MCS-51, como son las
interrupciones, el funcionamiento de los temporizadores, la comunicación serie asíncrona, etc.
3.2.1 Área de memoria de código de programa y memoria de datos
El mapa de memoria de la MCS-51 está segmentada en dos bloques de memoria de 64kbytes de
tamaño cada uno (figura 3.5), un bloque está destinado a almacenar el código de programa (memoria
de programa) y el otro a contener las variables y datos asociados al programa (memoria de datos).
Estos dos bloques se direccionan a través de las 16 líneas de direcciones, A0-A15, de la familia. La
memoria de programa (figura 3.5a) es de sólo lectura2
y suele ser externa, aunque se han de considerar
las versiones con memoria ROM, EPROM y OTPROM interna, que son de tamaño reducido y
destinadas a albergar los programas realizados en aplicaciones poco complejas o de tipo medio3
. El
bloque de memoria de datos (figura 3.5b) (64kbytes) es externo al microcontrolador y puede ser tanto
de lectura como de escritura.
2
Notar que /PSEN es una señal de lectura que sólo actúa sobre la memoria externa de programas.3
Hay versiones con 4k, 8k, 16k o 32kbytes de memoria interna de programas.
© Los autores, 2001; © Edicions UPC, 2001.
3 Arquitectura de las familias MCS-51 y MCS-251 39
Mem.externa
FFFFH
EA = 0
PSEN
a) b) c)
PSEN
RD RD128k
0000H
Mem.interna
EA = 1
0000H
0FFFH/1FFFH
Mem.externa
1000H/2000H
FFFFH
Memoria de programa
(sólo lectura)
00H
7FH80H
FFH
FFH
Mem. RAM
interna
128 bytes
Área de
registros
especiales
SFR
Mem. RAM
interna 8032/8052
128 bytes
(80H-FFH)
Memoria de datos
(lectura/escritura)
0000H
FFFFH
RD
WR
Mem.externa
Fig. 3.5 Estructura de la memoria de la MCS-51
El microcontrolador activa diferentes señales en función del tipo de bloque de memoria al que accede.
Si va a realizar una lectura del código de programa, sitúa la dirección que desea leer en el bus de
direcciones, A0-A15, y activa la señal /PSEN4
. Por contra, si va a realizar una lectura o escritura en la
memoria de datos, sitúa la dirección correspondiente en A0-A15 y activa la señal /RD o /WR, según
vaya a leer o a escribir un dato, respectivamente. La CPU comienza a ejecutar el programa, tras un
reset o al conectar la alimentación, por la dirección 0000H, puesto que el contador de programa (PC)
se inicializa con este valor.
En las versiones con memoria interna de programa los microcontroladores pueden ir a buscar el
código de programa a la memoria interna o a la memoria externa5
, y para aclarar cuál es el tipo de
memoria del que debe leer el código, dispone de la señal /EA. Si /EA está a 0 lógico, el
microcontrolador ejecuta el código almacenado en la memoria externa, y si /EA está a 1 lógico,
ejecuta el código almacenado en la memoria interna. En esta última situación, el microcontrolador no
activa la señal /PSEN ni los buses de direcciones y datos, puesto que no son necesarios. No obstante,
el fabricante contempla la particularidad de que el código de programa pueda estar almacenado en
ambos tipos de memoria, parte en la memoria interna y el resto en la memoria externa. En este caso, el
microcontrolador ejecuta primero el código de programa de la memoria interna y, luego, pasa a
ejecutar el código almacenado en la memoria externa; activa entonces la señal /PSEN y los buses de
direcciones y datos. Cabe destacar que esta particularidad carece de sentido, puesto que los
microcontroladores con memoria EPROM o OTPROM tienen un coste más elevado que el del resto, y
su utilización sólo se justifica por el mayor número de puertos útiles6
y por la reducción del área de
circuito impreso que posibilitan.
La memoria de programas y la memoria de datos pueden combinarse, si se desea, en un único bloque
de memoria de 128kbytes: para ello se deben combinar las señales /RD y /PSEN para que formen una
4
La señal /PSEN es activa cuando está en estado 0 lógico.5
Habitualmente la memoria externa de programa se implementa mediante una memoria EPROM.6
Debido a que los puertos P0 y P2 no deben formar el bus de direcciones y el bus de datos.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25140
única señal de lectura, lo que se consigue mediante una puerta AND lógica (figura 3.5c).
3.2.2 Área de memoria interna y de registros de propósito general
Según la figura 3.6, la familia MCS-51 tiene 128 bytes de memoria interna -posiciones de la 00H a la7FH- y un área para los registros de función especial (SFR) de 128 bytes -posiciones de la 80H a laFFH-. El área de memoria interna está estructurada en tres partes: a) área de registros de propósitogeneral formado por cuatro bancos con ocho registros cada uno, b) área accesible bit a bit y c) área dememoria RAM general.
Sólodirecc.
indirecto
Direcc.directo eindirecto
Sólodirecc.directo
00H
7FH80H 80H
FFH FFHSFRMem. Int
*
* Sólo en 8032/8052
00H07HBANCO 0
08H0FH
BANCO 1
10H17HBANCO 2
18H1FH
BANCO 3
20H
2FH
7 6 ............ 0F 8E ............
............30H
7FH
Bancos deregistros32 bytes
MemoriaRAM general
80 bytes
Área direcc.bit a bit.16 bytes,128 bits
a) b)
7E7F
Fig. 3.6 a) Memoria interna de la MCS-51. b) Organización de los primeros 128 bytes de esta memoria
a) Área de registros de propósito general
El área de registros de propósito general -posiciones de la 00H a la 1FH (figura 3.6b)- está formadapor cuatro bancos de registros con ocho registros cada uno, lo que hace un total de 32 registrosdisponibles. De estos cuatro bancos de registros, sólo uno puede estar activo en un instantedeterminado, mediante una selección previa con los bits RS0 y RS1 del registro de estado (PSWProgram Status Word, -tabla 3.2-). Luego, en realidad tan sólo se pueden usar los ocho registroscorrespondientes al banco de registros seleccionado.
A los ocho registros de cada banco de registros se les denomina R0, R1, R2, R3, R4, R5, R6 y R7,respectivamente. Estos registros, en realidad, ocupan las mismas posiciones de memoria que abarcacada uno de los bancos: por ejemplo, para el banco 0, el registro R0 está ubicado en la posición 00Hde la memoria interna, el registro R1 en la posición 01H, el registro R2 en la posición 02H, y así
sucesivamente hasta el registro R7, que está en la posición 07H de la memoria interna; siguiendo esteorden el registro R0 del banco 1 ocupa la posición 08H de la memoria interna, el registro R0 del banco2 está en la posición 10H de la memoria interna y el registro R0 del banco 3 ocupa la posición 18H dela memoria interna.
Tabla 3.2 Selección del banco de registros
Direcciones RS1 (PSW) RS0 (PSW)Banco 0 00H-07H 0 0Banco 1 08H-0FH 0 1Banco 2 10H-17H 1 0Banco 3 18H-1FH 1 1
© Los autores, 2001; © Edicions UPC, 2001.
3 Arquitectura de las familias MCS-51 y MCS-251 41
b) Posiciones direccionables bit a bit
En la memoria interna de la MCS-51 existen 16 bytes –posiciones entre 20H y 2FH (figura 3.7)- que
son accesibles a nivel de bit, por lo que se dispone de 128 bits accesibles de manera individual.
Memoria RAM interna
7 6 5 4 3 2 1 0
7 6 5 4 3 2 1 0
7 6 5 4 3 2 1 0
21H
20H
2FH
Memoria RAM interna
07H 06H 05H 04H 03H 02H 01H 00H
21H
20H
2FH
0FH 0EH D0H 0CH 0BH 0AH 09H 08H
7FH 7EH 7DH 7CH 7BH 7AH 79H 78H
Fig. 3.7 Posiciones de la memoria interna que son direccionables bit a bit
Existen dos formas de acceder a cada bit de esta zona: la primera consiste es indicar el bit mediante un
punto que lo define como bit de un byte. Por ejemplo, al bit 5 del byte 20H se puede acceder como
20H.5. La otra forma consiste en utilizar una dirección para cada uno de los bits de esta zona, donde
hay un total de 128 bits; por tanto, el primer bit, el 20H.0, tiene asignada la dirección 00H y el último
bit, el 2FH.7, tiene asignada la dirección 7FH ó 127 en base decimal.
c) Área de memoria RAM general
El área de memoria RAM general es una zona de 80 bytes comprendida entre las posiciones 30H y
7FH de la memoria interna (figura 3.6b). En las versiones 8032AH, 8052AH y 8752BH esta zona se
amplía en 128 bytes más, y está situada entre las direcciones 80H y FFH.
3.2.3 Área de registros especiales (SFR)
El área de registros especiales SFR (tabla 3.3) está ubicada entre las direcciones 80H y FFH de la
memoria interna y contiene los registros que determinan el modo de funcionamiento y la configuración
de los recursos internos de la familia MCS-51.
La tabla 3.3 muestra la situación de los registros del SFR dentro del espacio de memoria y el valor que
toman tras la realización de un reset. Los registros con el superíndice * aparecen en todas las versiones
con 3 temporizadores y los registros con el superíndice † aparecen en las versiones 8XC51FX. Las
zonas en blanco de la tabla 3.3 no están implementadas físicamente, y quedan reservadas para futuras
ampliaciones de registros que desee hacer el fabricante. La tabla 3.4 muestra el listado de los registros
del SFR, una pequeña descripción de éstos y la dirección que corresponde a cada registro.
Se debe destacar que todos los registros de la tabla 3.3 que aparecen en la primera columna son
accesibles bit a bit, mientras que el resto de registros no lo son. Los registros de la primera columna
son aquellos que tienen una dirección que acaba en 0 ó 8, es decir: 80H, 88H, 90H, 98H, A0H, etc.
Por tanto, al bit 3 del acumulador se puede acceder como ACC.3, al bit 2 del registro B se puede
acceder como B.2, etc.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25142
Tabla 3.3 Situación de los registros del SFR de la MCS-51 y su valor tras un reset
F8 CH†
00000000
CCAP0H†
XXXXXXXX
CCAP1H†
XXXXXXXX
CCAP2H†
XXXXXXXX
CCAP3H†
XXXXXXXX
CCAP4H†
XXXXXXXX
FF
F0 B00000000
F7
E8 CL†
00000000
CCAP0H†
XXXXXXXX
CCAP1H†
XXXXXXXX
CCAP2H†
XXXXXXXX
CCAP3H†
XXXXXXXX
CCAP4H†
XXXXXXXX
EF
E0 ACC00000000
E7
D8 CCON†
00X00000
CMOD†
00XXX000
CCAPM0†
X0000000
CCAPM1†
X0000000
CCAPM2†
X0000000
CCAPM3†
X0000000
CCAPM4†
X0000000
DF
D0 PSW00000000
D7
C8 T2CON*
00000000
T2MOD*
XXXXXX00
RCAP2L*
00000000
RCAP2H*
00000000
TL2*
00000000
TH2*
00000000
CF
C0 C7
B8 IPX0000000
SADEN†
00000000
BF
B0 P311111111
IPH†
X0000000
B7
A8 IE00000000
SADDR†
00000000
AF
A0 P211111111
A7
98 SCON00000000
SBUFXXXXXXXX
9F
90 P111111111
97
88 TCON00000000
TMOD00000000
TL000000000
TL100000000
TH000000000
TH100000000
8F
80 P011111111
SP00000111
DPL00000000
DPH00000000
PCON00XX0000
87
X=Estado indefinido * En todas las versiones con 3 temporizadores†
En las versiones con PCA (8XC51FX y 8XL51FX)
Las versiones con 256 bytes de memoria interna tienen los 128 bytes altos situados entre las
posiciones 80H y FFH. En consecuencia, comparten las mismas direcciones que el SFR (80H-FFH),
por lo que se produce un solapamiento en cuanto a asignación de direcciones. Para resolver este
conflicto y poder acceder a ambas zonas de la memoria interna, se utiliza el modo de direccionamiento
de las instrucciones de la familia; en concreto, si el direccionamiento se realiza de forma directa7
(direccionamiento directo), se accede al área de SFR; y si, por contra, el direccionamiento se realiza
de una forma indirecta8
(direccionamiento indirecto), se accede al área ampliada de memoria. Los
distintos modos de direccionamiento se tratarán en el capítulo siguiente.
7
En el direccionamiento directo, la dirección es de forma directa un operando de la instrucción.
Ej. MOV 90H, #3BH; Escribe 3BH en la localización 90H=P1 (Puerto P1) del SFR.8
En el direccionamiento indirecto, la dirección está contenida en un registro del microcontrolador. Para un 8052:
Ej. MOV R0, #90H;
MOV @R0, #3BH; Escribe 3BH en la posición de memoria interna 90H.
Nota: # indica el número es un dato numérico y @ es el indicativo del direccionamiento indirecto.
© Los autores, 2001; © Edicions UPC, 2001.
3 Arquitectura de las familias MCS-51 y MCS-251 43
Tabla 3.4 Registros del área de SFR para la MCS-51
Símbolo Nombre DirecciónP0
P1
P2
P3
SP
DPL
DPH
PCON
TCON
TMOD
TL0
TH0
TL1
TH1
SCON
SBUF
IE
SADDR†
IPH†
IP
SADEN†
T2CON*
RCAP2L*
RCAP2H*
TL2*
TH2*
PSW
CCON†
CMOD†
CCAPM0†
CCAPM1†
CCAPM2†
CCAPM3†
CCAPM4†
ACC
CL†
CCAP0L†
CCAP1L†
CCAP2L†
CCAP3L†
CCAP4L†
B
CH†
CCAP0H†
CCAP1H†
CCAP2H†
CCAP3H†
CCAP4H†
Puerto 0.
Puerto 1.
Puerto 2.
Puerto 3.
Puntero de la Pila (Stack Pointer).
Byte bajo del puntero de datos DPTR.
Byte alto del puntero de datos DPTR.
Control del consumo de energía (Power Control).Control de los temporizadores (Timer Control).Configuración de los temporizadores (Timer Mode).
Byte bajo del temporizador 0.
Byte alto del temporizador 0.
Byte bajo del temporizador 1.
Byte alto del temporizador 1.
Control de la comunicación serie (Serial Control).Buffer de datos de la comunicación serie (Serial Buffer).
Habilitación de interrupciones (Interrupt Enable).
Dirección esclavo (Slave Address).
Byte alto del registro de prioridad de interrupciones.
Registro de prioridad (Interrupt Priority).
Máscara de direcciones esclavo (Slave Address Mask).
Control del temporizador 2.
Byte bajo del registro de captura del temporizador 2.
Byte alto del registro de captura del temporizador 2.
Byte bajo del temporizador 2.
Byte alto del temporizador 2.
Registro de estado (Program Status Word).
Registro de control del Timer/Counter del PCA.
Registro de modo del Timer/Counter del PCA.
Registro modo 0 del Timer/Counter del PCA.
Registro modo 1 del Timer/Counter del PCA.
Registro modo 2 del Timer/Counter del PCA.
Registro modo 3 del Timer/Counter del PCA.
Registro modo 4 del Timer/Counter del PCA.
Acumulador.
Byte bajo del Timer/Counter del PCA.
Byte bajo del módulo 0 de comparación/captura del PCA.
Byte bajo del módulo 1 de comparación/captura del PCA.
Byte bajo del módulo 2 de comparación/captura del PCA.
Byte bajo del módulo 3 de comparación/captura del PCA.
Byte bajo del módulo 4 de comparación/captura del PCA.
Registro B.
Byte alto del Timer/Counter del PCA.
Byte alto del módulo 0 de comparación/captura del PCA.
Byte alto del módulo 1 de comparación/captura del PCA.
Byte alto del módulo 2 de comparación/captura del PCA.
Byte alto del módulo 3 de comparación/captura del PCA.
Byte alto del módulo 4 de comparación/captura del PCA.
80H
90H
A0H
B0H
81H
82H
83H
87H
88H
89H
8AH
8CH
8BH
8DH
98H
99H
A8H
A9H
B7H
B8H
B9H
C8H
CAH
CBH
CCH
CDH
D0H
D8H
D9H
DAH
DBH
DCH
DDH
DEH
E0H
E9H
EAH
EBH
ECH
EDH
EEH
F0H
F9H
FAH
FBH
FCH
FDH
FEH
* En todas las versiones con 3 temporizadores†
En las versiones con PCA (8XC51FX y 8XL51FX)
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25144
3.3 Arquitectura interna de la MCS-251
La figura 3.8 muestra el diagrama funcional de bloques de la arquitectura interna de los
microcontroladores de la familia MCS-251. Al igual que en la MCS-51, esta familia dispone de cuatro
puertos de entrada/salida, P0, P1, P2 y P3, de 8 bits cada uno, donde cada bit puede ser configurado
individualmente como entrada o como salida, o bien puede realizar una función alternativa relacionada
con los periféricos o con el acceso a la memoria externa. De la misma forma que para la MCS-51, los
puertos P0 y P2 soportan el bus de datos y el bus de direcciones, para el caso de necesitar memoria
externa. Las funciones alternativas de los puertos P1 y P3 están relacionadas con los periféricos y con
señales de control.
Código
OTPROM/ROM
8Kbytes ó16Kbytes
Puerto 0
drivers
P0.7:0
Puerto 2
drivers
P2.7:0
Puertos de entrada/salida y
buses de acceso a memoria
RAM
512 Bytes o
1024 Bytes
Puerto 1
drivers
P1.7:0
Puerto 3
drivers
P3.7:0
Puertos de entrada/salida
y señales de periféricos
Temporizador
watchdog
Temporizadores
contadores
PCA
Puerto Serie
Periféricos
Bu
s IB
Intefaz de
los periféricos
Control de
interrupciones
Clocky reset
Memoria de datos (16)
Memoria de direcciones (16)
Interfaz del Bus
Secuenciador
de instrucciones
Bu
s d
e dato
s (8
)
Bu
s d
e d
irec
cion
es (
24)
SRC1 (8)
SRC2 (8)
Interfaz de
la memoria
de datos
Registros de
propósito
general
DST (16)
Clock y reset
ALU
Núcleo de los µC de la familia MCS-251
Microcontroladores 8XC251SA/SB/SP/SQ
Fig. 3.8 Diagrama funcional de la arquitectura interna de la familia MCS-251
© Los autores, 2001; © Edicions UPC, 2001.
3 Arquitectura de las familias MCS-51 y MCS-251 45
La familia MCS-251 tiene una serie de innovaciones y mejoras con respecto a la MCS-51, sin dejar de
ser compatible con ésta en cuanto a encapsulado y juego de instrucciones. A pesar de esta
compatibilidad, el juego de instrucciones en la MCS-251 ha sido considerablemente ampliado, e
incluye instrucciones que operan con datos de 8, 16 y 32 bits y que facilitan el desarrollo de programas
en lenguajes de alto nivel como el lenguaje C. Para mantener al mismo tiempo la compatibilidad con
la MCS-51 y la ampliación y mejora del juego de instrucciones, se han definido los modos de trabajo
fuente source y binario binary. En el modo fuente se puede emplear las nuevas instrucciones y los
tipos de direccionamientos ideados para la MCS-251, por lo que el código de programa generado
suele ser más compacto y eficiente. En el modo binario se programa de la misma manera que con la
MCS-51 y por tanto es completamente compatible con ésta. Con este modo la MCS-251 puede
sustituir a la MCS-51 de forma directa, en aplicaciones ya desarrolladas, y sin necesidad de tener que
generar nuevos programas.
El espacio de memoria que es capaz de direccionar la familia MCS-251 es de 16Mbytes tanto para
código de programa como para datos, puesto que el contador de programa es de 24 bits, pero en
realidad el espacio de memoria real es de 256kbytes de memoria externa, ya que como bus de
direcciones se dispone de los puertos P0 y P2, y las líneas A16 y A17, que son funciones alternativas
de los puertos P3 y P1, respectivamente.
La MCS-251 incorpora también cierta cantidad de memoria interna de programa y datos, así como un
controlador de interrupciones y distintos periféricos como un temporizador Watchdog, tres
temporizadores/contadores, un array de contadores programable (PCA) y un puerto de comunicación
serie.
Una de las características de la MCS-51 consiste en que multiplexa temporalmente el byte bajo del bus
de direcciones (A0-A7) y el bus de datos (D0-D7) en el puerto P0. Esta multiplexación se mantiene
para la MCS-251 y se denomina modo no paginado. Sin embargo, para la MCS-251 la multiplexación
temporal también se puede hacer entre el byte alto del bus de direcciones (A8-A15) y el bus de datos
(D0-D7) en el puerto P2, pues de esta manera y como se explicará más adelante el acceso a la
memoria externa es más eficiente, el puerto P0 en este caso permanecería estable con la dirección
correspondiente al byte bajo del bus de direcciones (A0-A7). Esta manera de realizar la multiplexación
temporal en el puerto P2 se denomina modo paginado.
La familia también incorpora dos modos de funcionamiento de bajo consumo denominados Idle y
Power Down, que son adecuados para aplicaciones alimentadas con baterías. El modo Idle para la
señal de reloj de la CPU, detiene la ejecución del programa y ello hace que el consumo de energía sea
un 40% menor, pero mantiene la señal de reloj en los periféricos, y permite que sigan en
funcionamiento. El modo Power Down detiene las señales de reloj de la CPU y de los periféricos, con
lo que consigue una reducción en el consumo de energía de hasta un 60%.
3.3.1 Relación de terminales
La figura 3.9 muestra el encapsulado en formato DIP y PLCC, y la disposición de terminales de la
MCS-251.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25146
1234567891011121314151617181920
4039383736353433323130292827262524232221
P1.0/T2P1.1/T2EX
P1.2/ECIP1.3/CEX0P1.4/CEX1P1.5/CEX2
P1.6/CEX3/WAITP1.7/CEX4/A17/WCLK
RSTP3.0/RXDP3.1/TXDP3.2/INT0P3.3/INT1
P3.4/T0P3.5/T1
P3.6/WRP3.7/RD/A16
XTAL1XTAL2
VSS
VCC
AD0/P0.0AD1/P0.1AD2/P0.2AD3/P0.3AD4/P0.4AD5/P0.5AD6/P0.6AD7/P0.7EA/VPALE/PROG/PSENA15/P2.7A14/P2.6A13/P2.5A12/P2.4A11/P2.3A10/P2.2A9/P2.1A8/P2.0
8XC251Sx
6 5 4 3 2 14
44
34
24
14
0
3938373635343332313029
18
19
20
21
22
23
24
25
26
27
28
7891011121314151617
8XC251Sx
AD4/P0.4AD5/P0.5AD6/P0.6AD7/P0.7EA/VPVSS2
ALE/PROGPSENA15/P2.7A14/P2.6A13/P2.5
P1.5/CEX2P1.6/CEX3/WAIT
P1.7/CEX4/A17/WCLKRST
P3.0/RXDVCC2
P3.1/TXDP3.2/INT0P3.3/INT1
P3.4/T0P3.5/T1
P3
.6/W
RP
3.7
/RD
/A16
XT
AL
2X
TA
L1
VS
S
VS
S2
A8
/P2
.0A
9/P
2.1
A1
0/P
2.2
A1
1/P
2.3
A1
2/P
2.4
P1.4
/CE
X1
P1.3
/CE
X0
P1
.2/E
CI
P1
.1/T
2E
XP
1.0
/T2
VS
S1
VC
C
AD
0/P
0.0
AD
1/P
0.1
AD
2/P
0.2
AD
3/P
0.3
Fig. 3.9 Microcontroladores 8XC251Sx en encapsulado DIP 40 pines y PLCC de 44 pines
La relación de terminales de los microcontroladores de la familia MCS-251 es la siguiente:
- VCC, VCC2: entradas de alimentación. Vcc y VCC2 se deben poner a +5V. VCC2 permite reducir el
ruido que puede haber en la línea de alimentación.
- VSS, VSS1, VSS2: terminales de masa del microcontrolador.
- P0.0, P0.1… P0.7: puerto bidireccional bit a bit de E/S P0. P0 puede soportar el byte bajo del bus de
direcciones y el bus de datos mediante una multiplexación temporal en el modo no paginado, en el
caso de tener que utilizar memoria externa (AD0,…, AD7). En las versiones con memoria interna de
programa, el código de programa se introduce a través de este puerto, en la fase de programación y
verificación.
- P2.0, P2.1… P2.7: puerto bidireccional bit a bit de E/S P2. P2 puede soportar el byte alto del bus de
direcciones y el bus de datos mediante una multiplexación temporal, en el modo paginado (A8,…,
A15) de acceder a la memoria externa.
- P1.0, P1.1 … P1.7: puerto bidireccional bit a bit de E/S P1. P1 es un puerto de propósito general, no
obstante soporta varias funciones especiales de la familia MCS-51 (tabla 3.5), que están relacionadas
con el temporizador Timer 2, con el array de contadores programable PCA, la señal WAIT que
controla los estados de espera en los ciclos de acceso a la memoria externa, la línea A17 del bus de
direcciones y la señal WCLK que es la salida de reloj para estados de espera en el acceso de memoria
externa.
Los terminales P1.3, P1.4, P1.5, P1.6, P1.7 son entradas/salidas CEX0, CEX1, CEX2, CEX3, CEX4
de la PCA, respectivamente. Estos terminales actúan como entradas de los módulos 0, 1, 2, 3 y 4 de la
PCA cuando trabaja en modo captura, respectivamente, y como salidas de los mismos módulos cuando
la PCA trabaja en modo comparación y en modulación de anchura de pulsos (PWM).
La función alternativa de P1.7 se determina mediante RD1 y RD0 del registro de configuración
UCONFIG0. Si RD1=RD0= 0, su función es la línea A17 del bus de direcciones. No obstante, si el bit
WCON.1 está 1, en P1.7 se genera una señal cuadrada de frecuencia que es la mitad de la señal de
reloj del microcontrolador.
© Los autores, 2001; © Edicions UPC, 2001.
3 Arquitectura de las familias MCS-51 y MCS-251 47
- P3.0, P3.1 … P3.7: puerto bidireccional bit a bit de E/S P3. P3 es un puerto de propósito general que
soporta diversas funciones especiales de la familia MCS-51 al igual que el puerto P1 (tabla 3.5). Las
funciones que soporta este puerto son las señales TXD y RXD del puerto de comunicación serie, las
entradas de interrupción /INT0 y /INT1, las entradas externas T0 y T1 de los temporizadores, las
señales de lectura y escritura en memoria externa /RD y /WR, y la línea A16 del bus de direcciones.
La función alternativa de P3.7 también depende del estado de los bits RD1 y RD0 de UCONFIG0. Si
RD1=RD0= 1, su función alternativa es /RD y si RD1= 0 y, RD0 = 1 o RD1= 0 y RD0=0, su función
alternativa es la línea A16 del bus de direcciones.
Tabla 3.5 Descripciones de las funciones de los pines de los puertos de entrada/salida
Nombredel pin
Nombre del pin confunción alternativa
Descripción de la función alternativa
P1.0 T2 Entrada/salida de reloj del Timer 2.
P1.1 T2EX Entrada externa del Timer 2.
P1.2 ECI Entrada externa de reloj del PCA.
P1.3 CEX0 Entrada/salida del módulo 0 del PCA.
P1.4 CEX1 Entrada/salida del módulo 1 del PCA.
P1.5 CEX2 Entrada/salida del módulo 2 del PCA.
P1.6 CEX3 Entrada/salida del módulo 3 del PCA.
P1.7 CEX4, A17, WCLK E/S del módulo 4 del PCA o A17 del bus de direcciones.
P3.0 RXD Entrada de datos del puerto serie.
P3.1 TXD Salida de datos del puerto serie.
P3.2 /INT0 Entrada interrupción externa 0.
P3.3 /INT1 Entrada interrupción externa 1.
P3.4 T0 Entrada Timer 0.
P3.5 T1 Entrada Timer 1.
P3.6 /WR Habilitación de escritura en memoria externa.
P3.7 /RD, A16 Habilitación de lectura en mem. externa o A16 del bus de
direcciones
- /PSEN: este terminal se activa cuando el microcontrolador realiza operaciones de lectura en la
memoria externa en determinados rangos de direcciones, dependiendo del valor de los bits de
configuración RD1 y RD0.
- (/EA)/VP: este terminal puesto a 1 hace que el microcontrolador ejecute el código almacenado en las
EPROM, OTPROM o ROM internas. Si se coloca a 0, el microcontrolador ejecuta el código de
programa de la memoria externa de programas, activa el bus de direcciones, el bus de datos y las
señales de control. VP se utiliza para proporcionar la tensión de programación necesaria de la
memoria EPROM o OTPROM interna.
- XTAL1, XTAL2: estos terminales son la entrada de la señal de reloj del microcontrolador. Puede
utilizarse un resonador cerámico o un cristal de cuarzo. También se puede utilizar una señal externa de
reloj. El esquema circuital es el mismo que el de la figura 3.3 para la MCS-51.
- RST: entrada de reset del microcontrolador. Se debe colocar a nivel alto durante al menos 64
períodos de reloj para realizar la operación de reset.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25148
3.3.2 Estructura interna de los puertos de entrada/salida
La estructura interna de los puertos de E/S es la misma que la descrita para la MCS-51, salvo alguna
diferencia como el hecho de que el puerto P1 tenga funciones alternativas y se introduzcan los modos
paginado y no paginado de direccionar la memoria. Debido a ello, en el puerto P2 se introduce la señal
DATO para determinar los estados lógicos del puerto, puesto que en el modo paginado el puerto pasa
a soportar el bus de datos además del byte alto del bus de direcciones; y los puertos P1 y P3 pasan a
tener la misma estructura interna (figura 3.10).
La estructura interna de los puertos de la MCS-251 es prácticamente idéntica a la estructura de la
MCS-51, por lo que la explicación de su funcionamiento se ha realizado en el apartado 3.1.2.
ESCRIBE
EN LATCH
D
LATCH
CL
Q
Q
B1
B2
1
0
MUX
N1
P0.X
N2
DIRECC/DATO
CONTROL
VCC
BIT DEL PUERTO 0 (P0)
BUS INT.
LEE
LATCH
LEE
PIN
ESCRIBE
EN LATCH
BUS INT.D
LATCH
CL
Q
Q
B1
B2
1
0
MUX
P2.X
DIRECC/DATO
CONTROL
VCC
BIT DEL PUERTO 2 (P2)
LEE
LATCH
LEE
PIN
PULL-UPINTERNO
BIT DEL PUERTO 1 y 3 (P1 y P3)
D
LATCH
CL
Q
Q
B1
B2
P3.X
VCC
LEE
LATCH
LEE
PIN
PULL-UPINTERNO
Funciónalternativade salida
ESCRIBE
EN LATCH
BUS INT.
Función alternativade entrada
Fig. 3.10 Latchs de los bits de los puertos y buffers de entrada/salida para la MCS-251
3.4 Organización de los espacios de memoria de la MCS-251
En los microcontroladores de la familia MCS-251 (figura 3.11), se tienen tres espacios distintos de
memoria:
-El espacio de memoria para programas y datos.
-El área de registros de propósito general.
-El área de registros de función especial SFR.
En la figura 3.11 se observa cómo los espacios de memoria de la familia MCS-251 se han ampliado
considerablemente respecto a la familia MCS-51.
El espacio de memoria para programas y datos de la MCS-251 se utiliza para almacenar el código del
programa que debe ejecutar el microcontrolador, así como los datos, resultados intermedios y
© Los autores, 2001; © Edicions UPC, 2001.
3 Arquitectura de las familias MCS-51 y MCS-251 49
resultados finales relacionados con dicho programa. Este espacio tiene un tamaño de 16Mbytes de
posiciones de memoria distribuidas en 256 regiones de 64kbytes cada una, numeradas de la 00: a la
FF:.
La familia MCS-251 está diseñada para tener hasta un máximo de 64kbytes de memoria interna no
volátil, ubicada en la región FF:. La memoria RAM interna está ubicada en la región 00:, comenzando
a partir de la dirección 00:0020H. La dimensión de la memoria interna depende de la versión de
microcontrolador.
El área de registros de propósito general contiene 64 registros de 8 bits numerados decimalmente del 0
al 63. Estos registros tienen la función de guardar los datos y resultados que intervienen con más
frecuencia en el programa.
El espacio SFR puede tener hasta 512 registros de 8 bits de función específica que están, en la mayoríade los casos, relacionados con la programación de los periféricos que incorpora el microcontrolador.
Las direcciones de los registros de este área van de la S:000H a la S:1FFH. En la dirección de un
registro del área SFR se utiliza el prefijo “S:” para diferenciarla de una dirección de memoria.
Área de memoria
16 Mbytes
Área SFR
512 bytes
Área de registros de
propósito general
64 bytes
00:0000H
FF:FFFFH
0
63
S:000H
S:1FFH
Fig. 3.11 Espacio de direcciones para la familia MCS-251
3.4.1 Área de memoria
En la figura 3.12 se muestra el área de memoria de los microcontroladores 8XC251Sx. De los
16Mbytes de memoria teóricamente útiles, tan sólo se pueden usar 8 regiones de 64 kbytes, en
concreto la 00:, 01:, 02:, 03:, FC:, FD:, FE: y FF:, donde se pueden almacenar indistintamente código
de programa o datos. El resto de regiones de memoria, de la 04: a la FB:, están reservadas y no pueden
ser utilizadas por el usuario.
El número de líneas de direcciones de los microcontroladores de la serie 8XC251Sx es configurable
por el usuario: el valor máximo es 18, lo que limita el número máximo de posiciones de memoria
externa que se pueden direccionar de forma directa a 256kbytes.
Las 8 posiciones de memoria que van de la dirección FF:FFF8H a la FF:FFFFH están reservadas para
la configuración del dispositivo. En concreto, en la versión 8XC251Sx se utilizan sólo los bytes
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25150
FF:FFF8H y FF:FFF9H para realizar la configuración, el resto se reservan para la configuración de
futuras versiones de este microcontrolador.
En la región 00: se ubica la memoria RAM interna, en concreto entre la dirección 00:0020H y la
00:021FH, para aquellas versiones que disponen de 512 bytes de memoria RAM interna, o bien entre
la dirección 00:0020H y la 00:041FH para aquellas versiones que disponen de 1Kbyte de posiciones
de memoria RAM interna. La memoria RAM interna está destinada exclusivamente a guardar datos ya
que no se puede ejecutar instrucciones almacenadas en ella. Los primeros 32 bytes de memoria, de la
dirección 00:0000H a la 00:001FH, están asociados al área de registros. Por otra parte, las posiciones
de memoria comprendidas entre la 00:0020H y la 00:007FH son accesibles a nivel de bit.
Bytes de configuración
FF:FFF8H - FF:FFFFH
Memoria externaFF:FFF7H
FF:2000H/FF:4000H
OTPROM/ROM interna
SB, SQ:16 Kbytes (FF:0000H - FF:3FFFH)
SA, SP: 8 Kbytes (FF:0000H - FF:1FFFH)
RAM interna
SB, SQ: 1 Kbytes (00:0020H - 00:041FH)
SA, SP: 512 bytes (00:0020H - 00:021FH)
32 bytes de registros de trabajo
00:0000H - 00:001FH
Memoria externa
00:FFFFH
00:0220H/00:0420H
Área de memoria
16 Mbytes
Memoria externa
FF:0000H
Regiones reservadas 04: a FB:
FF:FFFFH
FE:FFFFH
FE:0000H
FD:FFFFH
FD:0000H
FC:FFFFH
FC:0000H
03:FFFFH
03:0000H
02:FFFFH
02:0000H
01:FFFFH
01:0000H
00:FFFFH
00:0000H
Memoria externa
Memoria externa
Memoria externa
Memoria externa
Memoria externa
Región FF:
Región 00:
Fig. 3.12 Implementación hardware del área de memoria de los microcontroladores 8XC251SA, SB, SP y SQ
La memoria interna de lectura está ubicada en la dirección FF:. Las diferentes versiones del
microcontrolador 8XC251Sx disponen de 0, 8 ó 16kbytes de memoria interna del tipo ROM
(83C251Sx) o OTPROM/EPROM (87C251Sx).
En la figura 3.12 las zonas sombreadas se corresponden con la memoria interna, mientras que el resto
de zonas se deben implementar, en caso que se utilicen, mediante de integrados de memoria externos.
© Los autores, 2001; © Edicions UPC, 2001.
3 Arquitectura de las familias MCS-51 y MCS-251 51
3.4.2 Área de registros de propósito genérico
El área de registros de propósito general de la familia MCS-251 dispone de 64 registros numerados
desde el 0 al 63, aunque los registros que están ubicados entre las posiciones 32 y 55 están reservados
para futuras versiones, lo que reduce el número total de registros disponibles a 40, como se muestra en
la figura 3.13.
0 1 2 3 4 5 6 7
8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23
24 25 26 27 28 29 30 31
56 57 58 59 60 61 62 63
Posiciones
32-55 reservadas
Área de registros
Fig. 3.13 Área de registros de propósito general
Los registros situados entre la posición 0 y 7 están implementadas físicamente en las direcciones
00:0000H a 00:001FH. Estas 32 posiciones de memoria constituyen un área dentro del espacio de
memoria denominada banco de registros, similar a la que poseen los microcontroladores de la familia
MCS-51. Hay en total 4 bancos de registros de 8 posiciones cada uno, que aparecen representados en
la figura 3.14.
0 1 2 3 4 5 6 7
Bancos de registros
Área de memoria
18H 1FH
10H 17H
08H 0FH
00H 07H Banco 0
Banco 1
Banco 2
Banco 3
Área de registros
0 1 2 3 4 5 6 7
8
63
00:0020H
FF:FFFFH
Fig. 3.15 Ubicación de las localizaciones 0 –7 del área de registros
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25152
Al igual que ocurre en la familia MCS-51, sólo uno de los cuatro bancos es accesible a través de los
registros. El banco accesible o activo se selecciona a través de los bits RS0 y RS1 del registro de
estado PSW (tabla 3.6).
Tabla 3.6 Selección del banco de registros
Banco Rango de Bits de selección de bancodirecciones RS1 RS0
Banco 0 00H-07H 0 0
Banco 1 08H-0FH 0 1
Banco 2 10H-17H 1 0
Banco 3 18H-1FH 1 1
Después de hacer un reset del microcontrolador, el banco activo por defecto es el banco cero, ya que
los bits RS1 y RS0 se ponen a cero. Para cambiar de banco de registro se debe modificar el valor de
los bits RS1 y RS0 mediante la instrucción adecuada.
El área de registros tiene la particularidad de que permite acceder a la información contenida en ella a
nivel de byte, 16 bits (Word) y 32 bits (Dword), lo cual facilita la tarea de los compiladores de C para
esta familia. No todos los registros del área de registros son accesibles de las tres formas indicadas: las
localizaciones que son accesibles a nivel de byte son las que van de la cero a la 15. Para identificar un
registro al cual se accede a nivel de byte, se utiliza la letra R seguida del número de la localización
correspondiente (figura 3.16). Por ejemplo, si se desea escribir el byte 5BH en la localización 9 se
debe utilizar el nombre R9 para hacer referencia a esta localización:
MOV R9,#5BH
Sólo el rango de localizaciones de la 0 a la 31 es accesible a nivel de Word. Un registro tipo Word estáformado por dos localizaciones y se identifica con las letras WR seguido del número de la localización
de menor peso que interviene en dicho registro. Por ejemplo, el registro WR2 está formado por las
localizaciones 2 y 3. En la figura 3.16 están indicados todos los registros Word disponibles.
Todas las localizaciones del área de registros son accesibles a nivel de Dword. Un Dword estáformado por cuatro localizaciones y se identifica con las letras DR y el número de la localización de
menor peso que interviene en el registro Dword. Por ejemplo, el registro DR28 está formado por las
localizaciones 28, 29, 30 y 31. En la figura 3.16 se indican todos los registros Dwords posibles.
Existen 4 registros del área de registros que por motivos de compatibilidad con los microcontroladores
de la familia MCS-51 poseen una función específica. Estos registros son:
- R10 es el registro B.
- R11 es el registro acumulador (ACC o A).
- DR56 es el registro puntero de datos extendido, DPX.
- DR60 es el registro puntero de pila extendido, SPX.
Los registros R10, R11, y algunas localizaciones de los registros DR56 y DR60, son accesibles
también a través del área de registros de función específica (SFR).
© Los autores, 2001; © Edicions UPC, 2001.
3 Arquitectura de las familias MCS-51 y MCS-251 53
Una de las mejoras que tiene la familia MCS-251 respecto a la MCS-51, es que cualquiera de sus
registros de tipo byte, del R0 al R15, puede realizar la función del acumulador en las instrucciones
aritméticas y lógicas, lo que evita el cuello de botella que el acumulador supone para la MCS-51.
En las instrucciones de la familia MCS-51 el registro acumulador era el principal registro en
transferencias y operaciones aritméticas y lógicas. En cambio en la familia MCS-251 cualquier
registro, del R0 al R15, puede realizar la tarea de acumulador. Por lo tanto, el acumulador no tiene, en
esta familia, la importancia que posee en la familia MCS-51.
El puntero de datos extendido DPX está ubicado en el registro DR56 (figura 3.16). Los tres bytes de
menor peso del DPX (DPL, DPH y DPXL) son accesibles también a través del área SFR. Los registros
DPL y DPH forman el puntero de datos DPTR de 16 bits. En la familia MCS-51 este registro se
emplea de forma única para acceder a la memoria externa de datos; sin embargo, para la familia MCS-
251 el acceso a la memoria externa o interna se puede hacer mediante cualquier registro de tipo Wordo Dword. El registro DPXL ubicado en la localización 57 del área de registros, permite seleccionar la
región de memoria (00:-FF:) a la que se desea acceder a través del puntero de datos extendido.
0 1 2 3 4 5 6 7
8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23
24 25 26 27 28 29 30 31
56 57 58 59 60 61 62 63
Localizaciones
32-55 reservadas
Área de registrosR0 R1 R2 R3 R4 R5 R6 R7
R8 R9 R10 R11R12 R13 R14 R15
Registro byte
WR0 WR2 WR4 WR6
WR8 WR10 WR12 WR14
WR16 WR18 WR20 WR22
WR24 WR26 WR28 WR30
Registro word
Registro dword
DR0
DR8
DR16
DR24
DR56
DR4
DR12
DR20
DR28
DR60
0 1 2 3 4 5 6 7
Bancos de registros
Fig. 3.16 Posibilidades de acceso al área de registros
El registro Dword DR60 es el puntero de datos extendido, SPX (figura 3.17). El byte de la
localización 63 es el puntero de pila, SP, de la familia MCS-51. EL byte de la localización 62 es la
parte alta del puntero de pila, SPH. Estos dos bytes controlan el funcionamiento de la pila, que en la
familia MCS-251 puede tener una dimensión máxima de 64 kbytes correspondientes a la región 00: de
memoria.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25154
DR60 = Puntero extendido de pila, SPX
60 61 62 63
SPH SP
SPH S:BEH
SP S:81H
Parte alta del puntero de pila
Puntero de pila
DPXL DPH DPL
56 57 58 59
DR56 = Puntero extendido de datos, DPX
DPXL S:84H
DPH S:83H
DPL S:82H
Parte alta del puntero de pila
Parte baja del puntero de datos
Parte baja del puntero extendido de datos
R10, Registro B; R11, registro acumulador
B ACC
B S:F0H
ACC S:E0H
Área de registros Area SFR
Fig. 3.17 Registros dedicados y su correspondencia en el área de registros SFR
3.4.3 Área de registros de función específica SFR
La mayoría de los registros del área de registros de función específica (SFR) están vinculados a la
programación de los periféricos de la familia MCS-251. En la tabla 3.7 aparecen los registros del área
SFR junto con el valor que adquieren cuando se realiza un reset del microcontrolador.
Las direcciones del área SFR que no están ocupadas por registros (zonas sombreadas en la tabla 3.7)
no están implementadas, por lo que no se pueden utilizar. Al área SFR sólo se puede acceder a nivel
de bit o byte, pero no a nivel de Word o Dword.
En la tabla 3.8 se indican los distintos registros del área SFR, junto con la dirección y una pequeña
descripción de la función que realizan.
© Los autores, 2001; © Edicions UPC, 2001.
3 Arquitectura de las familias MCS-51 y MCS-251 55
Tabla 3.7 Registros del área SFR y sus valores de reset
0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F
F8 CH
00000000
CCAP0H
xxxxxxxx
CCAP1H
xxxxxxxx
CCAP2H
xxxxxxxx
CCAP3H
xxxxxxxx
CCAP4H
xxxxxxxx
FF
F0 B
00000000
F7
E8 CL
00000000
CCAP0L
xxxxxxxx
CCAP1L
xxxxxxxx
CCAP2L
xxxxxxxx
CCAP3L
xxxxxxxx
CCAP4L
xxxxxxxx
EF
E0 ACC
00000000
E7
D8 CCON
00x00000
CMOD
00xxx000
CCAPM0
x0000000
CCAPM1
x0000000
CCAPM2
x0000000
CCAPM3
x0000000
CCAPM4
x0000000
DF
D0 PSW
00000000
PSW1
00000000
D7
C8 T2CON
00000000
T2MOD
xxxxxx00
RCAP2L
00000000
RCAP2H
00000000
TL2
00000000
TH2
00000000
CF
C0 C7
B8 IPL0
x0000000
SADEN
00000000
SPH
00000000
BF
B0 P3
11111111
IPH0
x0000000
B7
A8 IE0
00000000
SADDR
00000000
AF
A0 P2
11111111
WDTRS
xxxxxxxx
A7
98 SCON
00000000
SBUF
xxxxxxxx
9F
90 P1
11111111
97
88 TCON
00000000
TMOD
00000000
TL0
00000000
TL1
00000000
TH0
00000000
TH1
00000000
8F
80 P0
11111111
SP
00000111
DPL
00000000
DPH
00000000
DPXL
00000001
PCON
00xx0000
87
0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F
Tabla 3.8 Registros del área SFR
Mnemónico Nombre Dirección
Registros básicos
ACC Acumulador S:E0H
B Registro B S:F0H
PSW Registro de estado (Program Status Word) S:D0H
PSW1 Registro de estado 1 S:D1H
SP Parte baja del puntero de pila (Stack Pointer) S:81H
SPH Parte alta del puntero de pila S:BEH
DPTR Puntero de datos (Data Pointer) --
DPL Parte baja del DPTR S:82H
DPH Parte alta del DPTR S:83H
DPXL Parte baja del puntero extendido de datos S:84H
PCON Registro de control de potencia (Power Control) S:87H
IE0 Registro de habilitación de interrupciones S:A8H
IPH0 Parte alta del registro de prioridad de interrupciones S:B7H
IPL0 Parte baja del registro de prioridad de interrupciones S:B8H
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25156
Tabla 3.8 Registros del área SFR (continuación)
Mnemónico Nombre Dirección
Registros de los puertos de entrada/salida
P0 Puerto 0 S:80H
P1 Puerto 1 S:90H
P2 Puerto 2 S:A0H
P3 Puerto 3 S:B0H
Puerto de comunicación serie
SCON Registro de control del puerto serie S:98H
SBUF Registro buffer del puerto serie S:99H
SADEN Máscara de direcciones esclavo (Slave Address Mask) S:B9H
SADDR Dirección esclavo (Slave Address) S:A9H
Registros del Watchdog y de los Timer/Counter 0, 1 y 2
TL0 Parte baja del Timer/Counter 0 S:8AH
TH0 Parte alta del Timer/Counter 0 S:8CH
TL1 Parte baja del Timer/Counter 1 S:8BH
TL2 Parte alta del Timer/Counter 1 S:8DH
TL2 Parte baja del Timer/Counter 2 S:CCH
TH2 Parte alta del Timer/Counter 2 S:CDH
TCON Registro de control de los Timer/Counter 0 y 1 S:88H
TMOD Registro de control de modo de los Timer/Counter 0 y 1 S:89H
T2CON Registro de control del Timer/Counter 2 S:C8H
T2MOD Registro de control de modo del Timer/Counter 2 S:C9H
RCAP2L Byte bajo de captura del Timer/Counter 2 S:CAH
RCAP2H Byte alto de captura del Timer/Counter 2 S:CBH
WDTRST Registro Watchdog S:A6H
Registros del array de controladores programables (PCA)
CCON Registro de control del Timer/Counter PCA S:D8H
CMOD Registro de modo del Timer/Counter PCA S:D9H
CCAPM0 Registro modo 0 del Timer/Counter PCA S:DAH
CCAPM1 Registro modo 1 del Timer/Counter PCA S:DBH
CCAPM2 Registro modo 2 del Timer/Counter PCA S:DCH
CCAPM3 Registro modo 3 del Timer/Counter PCA S:DDH
CCAPM4 Registro modo 4 del Timer/Counter PCA S:DEH
CL Byte bajo del Timer/Counter del PCA S:E9H
CH Byte alto del Timer/Counter del PCA S:F9H
CCAP0L Byte bajo del módulo 0 de comparación/captura del PCA S:EAH
CCAP1L Byte bajo del módulo 1 de comparación/captura del PCA S:EBH
CCAP2L Byte bajo del módulo 2 de comparación/captura del PCA S:ECH
CCAP3L Byte bajo del módulo 3 de comparación/captura del PCA S:EDH
CCAP4L Byte bajo del módulo 4 de comparación/captura del PCA S:EEH
CCAP0H Byte alto del módulo 0 de comparación/captura del PCA S:FAH
CCAP1H Byte alto del módulo 1 de comparación/captura del PCA S:FBH
CCAP2H Byte alto del módulo 2 de comparación/captura del PCA S:FCH
CCAP3H Byte alto del módulo 3 de comparación/captura del PCA S:FDH
CCAP4H Byte alto del módulo 4 de comparación/captura del PCA S:FEH
© Los autores, 2001; © Edicions UPC, 2001.
3 Arquitectura de las familias MCS-51 y MCS-251 57
3.4.4 Compatibilidad con la arquitectura de la familia MCS-51
Las áreas de memoria y los registros de la arquitectura MCS-51 están contenidos dentro de los
espacios de direcciones de la familia MCS-251, lo que posibilita la compatibilidad con los programas
diseñados para la familia MCS-51. En la figura 3.18 se muestra cómo quedan ubicados los espacios de
direcciones de la familia MCS-51 dentro de la arquitectura de la familia MCS-251. Los 64kbytes de
memoria de programa de la familia MCS-51 se corresponden con la región FF: del área de memoria de
la familia MCS-251.
Memoria interna de datosMCS-51
Memoria externa de datosMCS-51
Memoria de programa
MCS-51
Área de memoria (16Mbytes)
SFRs MCS-51
Reg. MCS-51
Área SFR (512 Bytes)
Área de registros (64 Bytes)
0
8
63
S:000H
S:07FH
S:1FFH
S:100H
FFFFH
0000HFF:0000H
02:0000H
01:0000H
00:0000H 00H
FFH
FFFFH
0000H
FFH
80H
Fig. 3.18 Correspondencia de espacios de direcciones entre la familia MCS-51 y la MCS-251
Los 64kbytes de la memoria de datos externa se ubican en la región de memoria especificada por el
registro DPXL. Se puede acceder a este registro a través de la localización 57 o a través de la
dirección S:084H del área SFR. El valor que adquiere por defecto este registro después de hacer un
reset es el 01:, como se muestra en la figura 3.18, por lo que inicialmente la memoria externa de datos
está ubicada en la región 01:. La memoria externa de datos se puede reubicar en otra región
programando adecuadamente el registro DPXL.
Los 256 bytes de memoria RAM interna de la familia MCS-51 están ubicados en las direcciones del
área de memoria 00:0000H-00:00FFH.
Los 128 bytes del área SFR de la familia MCS-51 están ubicados dentro de los 512 bytes del área SFR
de la familia MCS-251 a partir de la dirección S:080H, como se muestra en la figura 3.18, para
mantener la compatibilidad con la familia MCS-251.
Los registros de trabajo R0-R7 de la familia MCS-51, están ubicados en los 32 primeros bytes del área
de memoria de la familia MCS-251 para mantener la compatibilidad.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25158
3.5 Configuración de la serie 8XC251Sx
Una de las características más interesantes de la familia de microcontroladores MCS-251 es la
posibilidad de configurar ciertas prestaciones de su funcionamiento para adaptarlo a las exigencias
específicas de la aplicación, lo que proporciona al usuario una gran flexibilidad en el diseño. Las
opciones de configuración abarcan diferentes categorías:
[ Interfaz con la memoria externa.
[ Modos de obtención del código de operación.
[ Selección de los bytes guardados en la pila por una interrupción.
Reubicación de los 8kbytes de memoria de lectura interna en la región 00: para aquellas versiones que
disponen de 16kbytes de memoria interna de tipo ROM/OTPROM/EPROM.
Los bytes utilizados para configurar los microcontroladores de la serie 8XC251Sx son el UCONFIG0,
en la dirección FF:FFF8H, y el UCONFIG1, en la dirección FF:FFF9H (figura 3.19).
---- /WSA1 /WSA0 /XALE RD1 RD0 /PAGE SRC
---- ---- ---- INTR WSB /WSB1 /WSB0 /EMAP
UCONFIG0
UCONFIG1
/WSA1,0 : Control de inserción de estados de espera para memoria externa
/XALE : Activación de la señal ALE extendida
RD1,0 : Selección del número de líneas del bus externo de direcciones
/PAGE : Selección de modo paginado o no paginado
SRC : Selección de modo fuente o modo binario
INTR : Selección de bytes almacenados en la pila por una interrupción
WSB : Activación de estado de espera en accesos a memoria externa
/WSB1,0 : Control de inserción de estados de espera para memoria externa
/EMAP : Reubicación de la memoria de lectura interna en la región 00:
Fig. 3.19 Bytes de configuración UCONFIG0 y UCONFIG1
Para los dispositivos que incorporan memoria ROM/OTPROM/EPROM interna, la información sobre
la configuración se almacena en memoria no volatil en estas direcciones. Para aquellas versiones de
microcontrolador que no disponen de memoria ROM/OTPROM/EPROM interna la configuración se
almacena en memoria externa en las direcciones indicadas.
3.5.1 Configuración del acceso a la memoria externa
Existen distintas opciones que permiten configurar el acceso a la memoria externa de forma más
adecuada a la aplicación que se está diseñando:
© Los autores, 2001; © Edicions UPC, 2001.
3 Arquitectura de las familias MCS-51 y MCS-251 59
1. La ubicación del bus de datos en el puerto cero (modo no paginado) o el puerto 2
(modo paginado).
2. El número de líneas del bus de direcciones externo (16, 17 o 18).
3. Las regiones de memoria asignadas a las señales de control de lectura /RD y /PSEN.
4. Los estados de espera en el acceso a la memoria externa (0, 1, 2 ó 3 estados de espera).
La ubicación de cierta cantidad de memoria de programa interna en la región 00:.
3.5.1.1 Modos paginado y no paginado
Con respecto a la ubicación del bus de datos, se puede elegir entre dos posibilidades: modo paginado o
modo no paginado, utilizando el bit /PAGE (bit 1 de la localización UCONFIG0).
En el modo no paginado (/PAGE = 1) el bus de datos está ubicado en el puerto cero, al igual que en
los microcontroladores de la familia MCS-51. Por tanto, este modo es el adecuado para aplicaciones
donde se requiera compatibilidad a nivel de hardware con la familia MCS-51.
En el modo paginado (/PAGE = 0) el bus de datos está ubicado en el puerto dos, lo que permite, bajo
ciertas condiciones, reducir el tiempo de acceso a la memoria externa. En este modo se puede leer un
código de operación en tan sólo 2 ciclos de reloj, en lugar de los cuatro ciclos necesarios en el modo
no paginado.
3.5.1.2 Número de líneas del bus de direcciones
Los bits RD y RD1 (bits 2 y 3 de la localización UCONFIG0) permiten seleccionar el número de
líneas de bus de direcciones externas y el rango de direcciones controlado por las señales de lectura
/RD y /PSEN y la señal de escritura /WR.
En la tabla 3.9 se muestran las distintas posibilidades de configuración con respecto a los bits RD0 y
RD1.
RD1:0 = 00 (18 líneas de bus de direcciones)
Si se programan los bits RD1 y RD0 a cero lógico se obtiene una configuración de 18 líneas de bus
externo de direcciones, lo que permite direccionar un total de 256kbytes de posiciones de memoria
externas, que es la máxima cantidad de memoria que pueden direccionar los microcontroladores de la
serie 8XC251Sx. Las 16 primeras líneas del bus de direcciones (de la A0 a la A15) están soportadas
por los puertos P0 y P2, la línea A16 del bus de direcciones está ubicada en el canal P3.7 y la línea de
mayor peso, A17, en el canal P1.7. Con esta configuración se utilizan dos señales para controlar el
acceso ala memoria externa:
[ /PSEN: controla las operaciones de lectura de la memoria externa para cualquier dirección (de
la 00:0000H a la FF:FFFFH).
[ /WR: controla las operaciones de escritura de la memoria externa para cualquier dirección (de
la 00:0000H a la FF:FFFFH).
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25160
RD1:0 = 01 (17 líneas de bus de direcciones)
Si se programan los bits RD1 y RD0 con los valores 0 y 1 respectivamente, se obtiene 17 líneas de bus
externo de direcciones: las 16 primeras líneas, A0-A15, implementadas mediante los puertos P0 y P2,
y la línea A16 implementada con el canal P3.7. Con esta configuración se pueden direccionar hasta
128kbytes de memoria externa. Las señales que controlan la lectura y escritura en la memoria externa
son las mismas que para la configuración RD1:0 = 00.
RD1:0 = 10 (16 líneas de bus de direcciones)
La configuración RD1 =1 RD0 = 0 permite tener un total de 16 líneas de bus de direcciones, de la A0
a la A15, implementadas con los puertos P0 y P2. Esta configuración permite direccionar hasta
64kbytes de memoria externa. Las señales de control de lectura y escritura son las mismas que en las
dos configuraciones anteriores.
RD1:0 = 11 (16 líneas de bus de direcciones)
Con esta configuración se tienen sólo 16 líneas de bus externo de direcciones, implementadas en los
puertos P0 y P2. Esta es la única configuración que mantiene la compatibilidad con la familia MCS-51
y para ello dispone de tres señales de control de acceso a la memoria externa (como en la familia
MCS-51):
[ /PSEN: señal de control de lectura en la memoria externa para las regiones FC:, FD:, FE: y FF:.
[ /RD: señal de control de lectura en la memoria externa para las regiones 00:, 01:, 02: y 03:.
[ /WR: señal de control de escritura en la memoria externa para las regiones 00:, 01:, 02: y 03:.
Tabla 3.9 Selección de señales de control para los posibles valores de RD1, RD0
RD1 RD0 P1.7/CEX/A17 P3.7/RD/A16 Direcciones asociadas a las señales de controlPSEN RD WR
00 A17 A16 Todas A16 Todas
01 P1.7/CEX4 A16 Todas A16 Todas
10 P1.7/CEX4 P3.7 Todas P3.7 Todas
11 P1.7/CEX4 /RD ] 80:0000H ∑ 7F:FFFFH ∑ 7F:FFFFH
3.5.1.3 Estados de espera en el acceso a la memoria externa
Los estados de espera permiten alargar los ciclos de acceso a la memoria externa. Esto es necesario
cuando la memoria externa a la que accede el microcontrolador no es suficientemente rápida. Cada
estado de espera alarga la duración del ciclo 2 períodos de reloj y es posible incluir hasta un máximo
de 3 estados de espera.
Se puede especificar la inserción de estados de espera de forma independiente en la región 01:, lo cual
permite ubicar una memoria lenta en esa región manteniendo, sin embargo, un acceso rápido en el
resto de regiones.
Existen 4 bits para especificar los estados de espera: los bits WSA0 y WSA1 (bits 5 y 6 de la
localización UCONFIG0), que permiten definir estados de espera para todas las regiones excepto la
01:, y los bits WSB0 y WSB1 (bits 1 y 2 de la localización UCONFIG1), que permiten definir estados
© Los autores, 2001; © Edicions UPC, 2001.
3 Arquitectura de las familias MCS-51 y MCS-251 61
de espera en la región 01:.
En la tabla 3.10 se muestran los estados de espera que se introducen en función de los valores que
adquieren los bits antes indicados.
Tabla 3.10 Configuración de los estados de espera
Regiones WSA1 WSA0 Estados de espera00: 02: 03: FC: FD: FE: FF: 0 0
0 1
1 0
1 1
3
2
1
0
WSB1 WSB001: 0 0
0 1
1 0
1 1
3
2
1
0
Por otra parte poniendo a cero el bit /XALE (bit 4 de la localización UCONFIG0) se alarga el tiempo
durante el cual la señal ALE está activa.
3.5.1.4 Configuración del código de operación
Con respecto a los modos de asignación de códigos de operación a las instrucciones, el usuario puede
seleccionar dos posibles modos: el modo binario que genera un código de operación compatible con
los microcontroladores de la familia MCS-51, y el modo fuente, que es específico de la familia MCS-
251.
Cuando se configura el microcontrolador se debe elegir necesariamente uno de los dos modos. Se debe
elegir aquel modo que permita obtener el código más eficiente. En principio los microcontroladores de
la familia MCS-251 tienen dos tipos de instrucciones:
[ Instrucciones originales de la familia MCS-51.
[ Instrucciones exclusivas de la familia MCS-251.
En general, las instrucciones originales de la familia MCS-51 generan un código más eficiente en
modo binario; en cambio las instrucciones exclusivas de la familia MCS-251 generan un código más
eficiente en modo fuente.
A modo de ejemplo se presenta en la tabla 3.11 varias instrucciones (de la familia MCS-51 y MCS-
251) con sus correspondientes códigos de operación obtenidos en los dos modos.
Tabla 3.11 Ejemplos de códigos de operación en modo binario y modo fuente
Instrucción Familia Código de operaciónModo binario Modo fuente
DEC A MCS-51 14H 14H
SUBB A,R4 MCS-51 9CH A5 9CH
SUB R4,R4 MCS-251 A5 9CH 9CH
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25162
3.5.1.5 Reubicación de memoria de programa en la región 00:
Para las versiones del microcontrolador 8XC251Sx con 16kbytes de memoria interna, el usuario tiene
la posibilidad de reubicar 8kbytes en la región 00:, lo cual permite un acceso más rápido a tablas de
constantes almacenadas en esta memoria usando direccionamiento directo.
Para poder realizar esta reubicación será necesario poner a cero el bit /EMAP (bit 0 de la localización
UCONFIG1). Con este bit a cero, los 8kbytes de memoria de programa interna que van de la dirección
FF:2000H a la dirección FF:3FFFH quedan reubicados en las direcciones 00:E000H-00:FFFFH
(figura 3.20).
Región FF:
FF:0000H
FF:1FFFH
8 Kbytes
8 Kbytes
FF:2000H
FF:3FFFH
FF:4000H
FF:FFFFH
Región 00:
00:E000H
00:FFFFH
8 Kbytes
00:0000H
00:DFFFH
EMAP = 0
Fig. 3.20 Reubicación de memoria de programa en la región 00:
3.5.1.6 Bytes cargados en la pila por una interrupción
En cuanto a los bytes que se cargan en la pila por una interrupción, el usuario puede elegir entre dos
opciones: una de ellas permite cargar en la pila los dos primeros bytes del contador de programa (PC);
la otra opción carga los tres bytes del contador de programa y el registro de estado PSW1.
El bit INTR (bit 4 de la localización UCONFIG1) configura una de las dos opciones. Si se pone este
bit a cero se almacenan en la pila sólo dos bytes del contador de programa. Si se pone a 1 se almacena
todo el contador de programa más el registro de estado.
© Los autores, 2001; © Edicions UPC, 2001.
4 Programación de las familias MCS-51 y MCS-251 63
4 Programación de las familias MCS-51 y MCS-251
4.1 Introducción
El desarrollo de los programas o del software necesarios para una aplicación determinada de un
sistema basado en un microcontrolador es una fase importante del diseño de este sistema; por ello, el
programador debe tener un sólido conocimiento del conjunto de instrucciones que incorpora el
microcontrolador y de las técnicas de programación que se pueden desarrollar con las instrucciones
disponibles. La finalización del programa está sujeta a un largo proceso de depuración y de continuas
modificaciones y mejoras realizadas durante el proceso de diseño. En el caso de aplicaciones sencillas,
normalmente el programa tiene un tamaño reducido, por lo que se realiza en lenguaje ensamblador
mediante el conjunto de instrucciones que proporciona el fabricante del microcontrolador. No
obstante, cuando la aplicación resulta complicada y requiere de un tamaño mayor de código de
programa, se suele combinar el uso de la programación en bajo nivel (lenguaje ensamblador) con el
empleo de la programación en alto nivel (como pueden ser los lenguajes PLM o C).
La realización del programa en lenguaje ensamblador permite obtener un tamaño de código de
programa mucho más compacto, eficiente y que usa mejor los recursos disponibles por el
microcontrolador; sin embargo, el desarrollo del programa realizado en este lenguaje resulta ser más
tedioso y complicado de seguir por cualquier otro programador. Por otra parte, mediante el lenguaje
en alto nivel, la complejidad y el tiempo de realización del programa resultan menores y más fácil de
entender por otros programadores, aunque el código generado por estos lenguajes es de mayor tamaño
y de menos eficiencia. En consecuencia, los programas complejos y complicados se suelen hacer en
lenguaje de alto nivel, combinando éste con pequeñas rutinas en lenguaje ensamblador, encargadas de
realizar la gestión de aquellas partes del hardware del sistema que necesitan de un código más
optimizado, eficiente y compacto. Mientras que los programas que resultan ser reducidos y más
sencillos se suelen realizar en únicamente en lenguaje ensamblador.
En este capítulo se explicarán los distintos modos de direccionamiento y se describirá el conjunto
completo de instrucciones en lenguaje ensamblador soportados por las familias de microcontroladores
MCS-51 y MCS-251 de Intel. Por ser la familia MCS-251 una versión mejorada de la familia MCS-51
y, además, ser absolutamente compatible con ésta a nivel de encapsulado y de programación, el
desarrollo de este capítulo se orientará primero a la programación de la familia MCS-51, para luego
proceder a la explicación de las mejoras introducidas en la familia MCS-251, con las que se superan
las limitaciones en el uso de los registros y en el direccionamiento de la familia MCS-51.
En la elaboración de un programa en lenguaje ensamblador, el programador debe conocer las técnicas
más comunes que se emplean en este lenguaje, y que resultan imprescindibles para llevar a cabo con
© Los autores, 2001; © Edicions UPC, 2001.
64 Microcontroladores MCS-51 y MCS-251
éxito el programa que soluciona una aplicación. Entre estas técnicas se encuentran las siguientes:operaciones aritméticas con más de un byte, operaciones aritméticas con signo, tratamiento de tablas,conversión de datos en diferentes formatos (hexadecimal-BCD, hexadecimal-siete segmentos, BCD-hexadecimal, etc.), realización de rutinas de interrupción, etc. La exposición de estas técnicas deprogramación, junto con los ejemplos y ejercicios propuestos, son el tema central del siguientecapítulo. Por tanto, este capítulo, junto con el siguiente, constituye el núcleo fundamental que todoprogramador que desee trabajar con las familias de microcontroladores MCS-51 y MCS-251 debeconsiderar y conocer.
4.2 Tipos de direccionamiento
Una de las características de los microprocesadores o microcontroladores, en general, consiste en losdistintos modos de direccionamiento que pueden soportar para llevar a cabo la ejecución de cualquierinstrucción del conjunto de instrucciones disponible. El modo de direccionamiento determina la formade especificar el origen o el destino de los operandos de una instrucción, ya sean éstos de tipo bit,byte, Word o double word. En concreto, las familias de microcontroladores MCS-51 y MCS-251disponen de siete modos de direccionamiento distintos:
- Direccionamiento inmediato.- Direccionamiento directo.- Direccionamiento por registro.- Direccionamiento indirecto.- Direccionamiento por desplazamiento o indexado.- Direccionamiento relativo.- Direccionamiento de bit.
Tabla 4.1 Notación utilizada para la descripción del direccionamiento y del conjunto de instrucciones comunesa la MCS-51 y a la MCS-251
Mnemónico Descripcióndir8 Dirección directa de 8 bits. Posiciones de memoria interna o área de SFR.
dir16 Dirección 16 bits de memoria empleada en direccionamientos directos.dir11 Dirección de 11 bits.#dato Constante de 8 bits.
#dato16 Constante de 16 bits.Rn Registro de tipo byte, R0 a R7.
@Ri Direccionamiento indirecto a través de R0 ó R1. Se accede a las posiciones (00H-FFH) de la memoria interna.
bit Bit de la memoria RAM interna o de un registro del área de SFR accesible bit a bit.rel Dirección de salto. Puede ser un salto incondicional, condicional o de llamada a
subrutina.
A lo largo de este capítulo se empleará una notación específica que es útil para realizar la descripcióndel direccionamiento y de las instrucciones de las familias de microcontroladores. La tabla 4.1 muestrala notación utilizada para la familia MCS-51 mientras que la tabla 4.2 muestra la notación empleadapara la familia MCS-251.
Esta notación también es válida para la familia MCS-251. No obstante, como en la MCS-251 se
© Los autores, 2001; © Edicions UPC, 2001.
4 Programación de las familias MCS-51 y MCS-251 65
pueden emplear operandos del tipo byte Word y double word, la notación para esta familia aumenta en
cantidad, lo que se muestra en las tablas 4.2 y 4.3.
En estas tablas se indica si la notación es propia de las instrucciones de la familia MCS-51, de las
nuevas instrucciones que incorpora la familia MCS-251 o de ambas.
Tabla 4.2 Notación específica utilizada en las instrucciones de la familia MCS-251
Notación de losregistros
Descripción
Rm
Rms
Rmd
Registro tipo byte de R0 a R15.
Registro fuente.
Registro destino.
WRj
WRjd
WRjs
@WRj+dis16
Registro de tipo Word WR0, WR2, …., WR30.
Registro destino.
Registro fuente.
Dirección de memoria (00:0000H-00:FFFFH) direccionada indirectamente por un
registro de tipo Word (WR0-WR30) mas un valor de desplazamiento de 16 bits.
DRk,
DRkd
DRks
@DRk+dis24
Registro de tipo DR (Double Word) DR0, DR4, …, DR28 DR56, DR60.
Registro de destino.
Registro fuente.
Dirección de memoria (00:0000H-00:FFFFH) direccionada indirectamente por un
registro de doble palabra (DR0, DR4, …, DR56, DR60) más un valor de
desplazamiento de 24 bits.
Dato inmediato Descripción#0dato16
#1dato16
Constante de 32 bits que se direcciona de forma inmediata en una instrucción. Los
16 bits de mayor peso del dato deben ser 0 (#0dato16) ó 1 (#1dato16).
#short Constante igual a 1, 2 ó 4, direccionada de forma inmediata en una instrucción.
Direcciones Descripciónrel Dirección relativa de 8 bits expresada en complemento a 2.
addr11 Dirección de 11 bits.
addr16 Dirección de 16 bits.
addr24 Dirección de 24 bits. Permite acceder a cualquier dirección de los 16Mbyte del
espacio de memoria de la familia MCS-251.
4.2.1 Direccionamiento inmediato
En el direccionamiento inmediato el operando de la instrucción es una constante que está definida
dentro de la propia instrucción. Este tipo de direccionamiento es común para las familias MCS-51 y
MCS-251. Para la familia MCS-51 el tamaño de la constante está limitado a 8 bits (1 byte), mientras
que para la familia MCS-251 la constante puede ser de 8 bits (byte), 16 bits (Word) o 32 bits (Doubleword).
En la familia MCS-51, por ejemplo, la instrucción “MOV A, #09H” pone el dato 09H mediante
direccionamiento inmediato en el acumulador. Esta instrucción está formada por un código máquina
de 2 bytes: 74H y 09H. El byte 09H es el operando mientras que el byte 74H es el código de
operación de la instrucción. El dato 09H está dentro de la propia instrucción; por tanto, es un
© Los autores, 2001; © Edicions UPC, 2001.
66 Microcontroladores MCS-51 y MCS-251
operando que la CPU coloca de forma directa en el acumulador, sin necesidad de obtenerlo de la
memoria o de algún registro del microcontrolador. Este tipo de instrucción se usa de manera frecuente
a lo largo de los programas y, especialmente, en la inicialización de éstos, puesto que se hace preciso
asignar valores iniciales a las variables definidas por el programador.
El direccionamiento inmediato también se emplea en aquellas instrucciones que operan únicamente
con algún registro determinado del área SFR, como puede ser el acumulador o el registro DPTR. Un
ejemplo de ello es la instrucción “INC A” que incrementa en una unidad el acumulador. El código
máquina de esta instrucción está formado solamente por el byte 04H; luego en este mismo byte de
código está contenida la dirección del acumulador dentro del área SFR como operando.
Para la familia MCS-251 las constantes de 32 bits (Dword) deben tener todos los 16 bits de mayor
peso a cero (indicado como #0dato16), o bien, todos a uno (indicado como #1dato16). Las
instrucciones de incremento o decremento de esta familia, además, incorporan un dato inmediato, que
especifica el valor del tamaño del incremento o decremento. Este valor puede ser 1, 2 ó 4. Como
ejemplo, las siguientes instrucciones de la familia MCS-51 utilizan el direccionamiento inmediato:
INC A ;Incrementa el contenido del acumulador
MOV A, #255; ;Coloca el número 255 en el acumulador
MOV A, #0FFH1 ;Coloca 0FFH en el acumulador
MOV A, #11111111b ;Coloca 0FFH (en binario) en el acumulador
MOV DPTR, #1969H ;Coloca 1969H en el DPTR
Análogamente, para la familia MCS-251 las siguientes instrucciones utilizan direccionamiento
inmediato:
INC WR0,#02H ;Incrementa el registro WR0 en dos unidades
MOV DR4,#FFFF2350H ;Carga el dato FFFF2350H en el registro DR4
4.2.2 Direccionamiento directo
En el direccionamiento directo la ubicación del operando se especifica de forma directa mediante una
dirección de ocho bits. Para la familia MCS-51, con este direccionamiento, es posible leer y escribir
sobre cualquier dirección especificada, que puede corresponder con un byte de la memoria RAM
interna (00H-7FH) o con un registro del área SFR.
Ejemplo:
ADD A, 3BH ; Suma el contenido del acumulador (A) con el contenido de la posición de
; memoria 3BH. El resultado se deja en el acumulador (A):
; A ÷ (A) + (3BH)
MOV A, 80H ; Transfiere el contenido del puerto P0 (posición 80H en el área de SFR) al
; acumulador: A ÷ (80H)
1
H indica que el número es hexadecimal y b que es uno binario. Cuando no lleva indicativo es un número decimal.
© Los autores, 2001; © Edicions UPC, 2001.
4 Programación de las familias MCS-51 y MCS-251 67
Para la familia MCS-251, el direccionamiento directo puede utilizar direcciones de 8 bits o de 16 bits.
Con las direcciones de 8 bits se puede acceder a la memoria RAM interna (00H-7FH), para leer o
escribir un byte o un Word, y también se puede acceder al área de registros de función específica SFR
(S:080H-S:1FFH), para leer o escribir un byte únicamente. Con las direcciones de 16 bits se pueden
realizar accesos de tipo byte o Word en memoria (00:0000H-00:FFFFH).
Ejemplo:
MOV R7,S:090H ; Carga en el registro R7 el contenido del puerto P2 (dirección S:090H
; del área SFR): R7 ÷ (S:090H)
MOV R0,1200H ; Transfiere el contenido de la dirección de memoria 1200H en el
; registro R0: R0 ÷ (1200H)2
4.2.3 Direccionamiento por registro
En el direccionamiento por registro el dato que maneja la instrucción está incluido en uno de los
registros del microcontrolador. En el direccionamiento por registro de la familia MCS-51 se utilizan
los registros de propósito general, R0-R7, para almacenar el operando de la instrucción. A cada uno
de estos registros se puede acceder mediante su nombre (direccionamiento por registro), o mediante su
dirección (direccionamiento directo).
Cuando una instrucción incluye un registro por su nombre, éste se codifica dentro de la propia
instrucción mediante 3 bits, lo que permite compactar el código generado por la instrucción. Por el
contrario, cuando se accede al registro mediante su dirección, la instrucción debe contener la dirección
del registro, por lo que el tamaño de la instrucción se incrementa en 1 byte, que corresponde con la
dirección dada para el registro. En consecuencia, es conveniente, en la medida de lo posible, utilizar
los registros por su nombre, debido a que se obtiene así un código más compacto y eficiente.
En el siguiente ejemplo las instrucciones de la familia MCS-51 transfieren el contenido del
acumulador al registro R0, y luego el contenido del registro R7 al acumulador. Mediante los bits RS0
y RS1 del registro PSW se selecciona, de forma previa, el banco 2 de registros, por lo que los registros
empleados, R0 y R7, se corresponden con las posiciones 10H y 17H de la memoria interna,
respectivamente.
Ejemplo:
MOV PSW,#10H ; Se selecciona el banco 2 de registros
MOV R0, A ; Transfiere el contenido del acumulador (A) al registro R0
; R0 ÷ (A)
ADD A, R7 ; Suma el contenido del registro R7 con el acumulador.
; A ÷ (A) + (R7)
2
Cuando un registro o una dirección se encuentra entre paréntesis se refiere al contenido. (A) es el contenido del
acumulador. (3B) es el contenido de la posición de memoria 3BH. Las operaciones que se deben realizar se muestran a la
derecha de la flecha (÷), y a la izquierda se indica sobre qué elemento se deja el resultado.
© Los autores, 2001; © Edicions UPC, 2001.
68 Microcontroladores MCS-51 y MCS-251
En cuanto a los registros del área de registros de función específica (SFR), existen algunas
instrucciones que son propias de registros específicos, como es el caso del acumulador. Se puede
acceder al acumulador de forma directa o mediante su dirección en el SFR (posición E0H), de manera
que las siguientes instrucciones son equivalentes:
MOV A, #10H ; Almacena la constante 10H en el acumulador
MOV 0E0H, #10H ; Almacena la constante 10H en la posición E0H del SFR
La primera instrucción tiene un código máquina de 2 bytes, 74H y 10H, mientras que la segunda tiene
un código máquina de 3 bytes, 75H, E0H y 10H. En la primera instrucción la dirección del
acumulador está incluida en el código de operación, mientras que en la segunda instrucción para
acceder al acumulador se debe especificar su dirección, incrementando, por tanto, en un byte el
tamaño de ésta. Debe resaltarse que la familia de microcontroladores MCS-51 optimiza el tiempo de
ejecución y el tamaño de código de las instrucciones que utilizan de forma inmediata el acumulador A,
el registro B y los registros del banco de registros seleccionado.
En las instrucciones de la familia MCS-251 que soportan direccionamiento por registro, el operandopuede estar ubicado en un registro tipo byte (del R0 al R15), en un registro tipo Word (WR0, WR2,…,
WR30), o en un registro tipo Dword (DR0, DR4, …, DR28, DR56, DR60).
Ejemplo:
MOV R4, R8 ; Transfiere el contenido del registro R8 al registro R4
; R4 ÷ R8
MOV WR4,WR6 ; Transfiere el contenido del registro WR6 al registro WR4
; WR4 ÷ WR6
4.2.4 Direccionamiento indirecto
En el direccionamiento indirecto la dirección del operando viene especificada por el contenido de un
registro del microcontrolador. La familia MCS-51 utiliza el direccionamiento indirecto mediante los
registros R0, R1, SP (puntero de la pila o Stack Pointer) y DPTR (puntero externo de datos o DataPointer de 16 bits). De esta manera, se puede acceder tanto a la memoria interna como a la memoria
externa de datos del microcontrolador. Debe notarse que como identificador de este tipo de
direccionamiento se emplea el símbolo @, que debe ir delante del registro.
A la memoria interna de datos (00H-FFH), se accede únicamente con los registros R0 y R1, aunque
también se puede acceder mediante el puntero de la pila SP o Stack Pointer. Para acceder a la
memoria externa de datos se pueden emplear los registros DPTR, R0 y R1.
Los microcontroladores de la familia MCS-251 soportan el mismo modo de direccionamiento
indirecto que el que se ha descrito para la familia MCS-51, pero, además, también pueden emplear
registros de tipo Word y Dword. Mediante los registros del tipo Word (@WRj, j=0, 2, 4, …, 30) se
puede acceder a las direcciones de memoria comprendidas en el margen (00:0000H-00:FFFFH).
Mediante los registros del tipo Dword (@DRk, k = 0, 4, 8, …, 28, 56 y 60) se puede acceder a los
16Mbytes del espacio de memoria; para ello se debe cargar previamente en los 24 bits de menor peso
del registro la dirección a la que se desea acceder, teniendo a cero los 8 bits de mayor peso.
© Los autores, 2001; © Edicions UPC, 2001.
4 Programación de las familias MCS-51 y MCS-251 69
Ejemplo:
MOV R0, #30H
ADD A, @R0
; Suma el contenido del acumulador (A) con el contenido de la posición
; de memoria apuntada por el registro R0. Si (R0)=30H, la operación es:
; A ÷ (A) + 30H
MOV R1, #30H
MOV @R1, #70H
; Pone 70H en la posición de memoria interna 30H
; (30H) ÷ #70H
MOV DPTR, #1000H
MOVX A, @DPTR
; Transfiere el contenido de la posición de memoria apuntada por DPTR
; al acumulador (A). Con MOVX se accede a la memoria externa de
; datos, activando un ciclo de lectura de dato en la memoria externa:
; A ÷ (1000H)
MOV WR0, #2000H
ADD R15, @WR0
;Carga en el registro R15 el contenido de la posición de memoria
; apuntada por el registro WR0. Si (WR0)=2000H, la operación es:
; R15 ÷ (2000H)
MOV DR4, #15000H
MOV R4,#00H
MOV @DR4, #A0H
;Almacena el valor A0H en la posición de memoria
; FF:5000H ÷ #A0H
4.2.5 Direccionamiento por desplazamiento o indexado
En el direccionamiento por desplazamiento o indexado el operando se obtiene mediante una dirección,
cuyo valor es el resultado de la suma de una dirección base con un valor relativo de desplazamiento
respecto de esta dirección base. El direccionamiento indexado está especialmente concebido para
facilitar la lectura y el movimiento de tablas de datos en un programa.
Para la familia MCS-51, en este direccionamiento se utilizan los registros DPTR y PC (contador de
programa) como punteros que apuntan a la dirección inicial o base de la tabla de datos a tratar. La
posición concreta del dato dentro de la tabla, se obtiene mediante la suma del contenido del
acumulador con la dirección base de la tabla; de esta forma el acumulador contiene la posición relativa
del dato dentro de la tabla. Se debe destacar que las únicas instrucciones que tienen este tipo de
direccionamiento son la instrucción “MOVC” y la instrucción “JMP”, por lo que su uso está limitado a
la lectura de tablas fijas en la memoria de código de programas (MOVC) y a realizar saltos indexados
de ejecución del programa.
Como ejemplo se plantea la lectura de una tabla de datos situada en la posición 1000H de la memoria
de programas, que se utiliza para realizar la conversión de datos expresados en formato BCD al
formato “siete segmentos”, necesario para la posterior visualización en un dígito de siete segmentos.
Ejemplo:MOV DPTR, #1000H ; Pone en el DPTR la dirección de la tabla
MOV A, #05H ; Pone en A el dato numérico 5, para realizar
MOVC A, @A+DPTR ; la conversión a siete segmentos
En este ejemplo el registro DPTR toma el valor 1000H y el acumulador el valor 05H, luego la
instrucción “MOVC” realiza una lectura de un byte en la posición 1005H de la memoria de
programas, que resulta de sumar el DPTR con el acumulador (1000H + 05H). La tabla existente en la
memoria de programas tiene la siguiente forma:
© Los autores, 2001; © Edicions UPC, 2001.
70 Microcontroladores MCS-51 y MCS-251
1000H
1001H
1002H
1003H
1004H
1005H
1006H
1007H
1008H
1009H
Dirección Memoria
C0H
F9H
A4H
B0H
99H
92H
82H
F8H
80H
90H
A = 0
A = 1
A = 2
A = 3
A = 4
A = 5
A = 6
A = 7
A = 8
A = 9
En la familia MCS-251 se utiliza este tipo de direccionamiento para realizar transferencias de datos
entre el área de registros y la memoria. El desplazamiento puede ser un valor de 16 bits que, sumado al
contenido de un registro tipo Word (@WRj+dis16), dará como resultado la dirección de memoria a
que se debe acceder. De esta forma se puede acceder a los primeros 64kbytes del espacio de memoria.
El valor del desplazamiento puede ser positivo o negativo y se representa en complemento a 2 (-32768
< dis16 < 32767). Si el resultado de la suma excede los 16 bits sólo se toman los 16 primeros para
determinar la dirección de acceso.
El desplazamiento puede ser también un valor de 24 bits (@DRk+dis24); en este caso el registro base
debe ser un registro Dword (DR0, DR4, DR8, …, DR28, DR56 o DR60). Con este tipo de
desplazamiento es posible acceder de forma indirecta a los 16Mbytes del espacio de memoria de la
MCS-251.
Ejemplo:
MOV WR0, #3000H
ADD R4, @WR0+0030H
; Carga en el registro R4 el contenido de la posición de memoria
; apuntada por el registro WR0+30H. Si (WR0)=3000H, la
; operación es: R4 ÷ (3030H)
MOV DR8, #02000H
MOV R0, @DR8+0080H
; Almacena en el registro R0 el contenido de la posición de
; memoria apuntada por el registro DR8+80H. Si (DR8)=2000H,
; la operación es: R0 ÷ (2080H)
A modo de resumen, en las tablas 4.3 y 4.4 se presentan las distintas posibilidades de
direccionamiento inmediato, directo, por registro, indirecto e indexado de las familias MCS-51 y
MCS-251 respectivamente.
4.2.6 Direccionamiento de bit
Este tipo de direccionamiento se caracteriza por permitir direccionar bits individualmente. El
direccionamiento de bit tan sólo se puede emplear en algunos registros del área SFR o en las
posiciones de la memoria RAM interna a que puede accederse bit a bit. La tabla 4.5 muestra, para las
familias MCS-51 y MCS-251, las posiciones de la RAM interna y del área del SFR a las que puede
accederse de esta manera.
© Los autores, 2001; © Edicions UPC, 2001.
4 Programación de las familias MCS-51 y MCS-251 71
Tabla 4.3 Direccionamiento por registro, inmediato, directo e indirecto para la MCS-51
Direcciona-miento
Rango de direccionesdel operando
Notación Comentarios
Registro 00H - 1FH R0-R7 (Banco seleccionado con PSW).
Inmediato El operando está en la
instrucción
#dato=#00-#FFH
Directo 00H - 7FH dir8=00H-7FH RAM interna.
SFRs dir8=80H-FFH o nombre de un registro
del SFR.
Direcciones del área SFR.
00H - FFH @R0, @R1 RAM interna o memoria de
datos externa (MOVX).
Indirecto 0000H - FFFFH @DPTR, @A+DPTR Acceso a la memoria externa
de datos (MOVX).
0000H - FFFFH @A+DPTR, @A+PC Acceso a la memoria de
programa (MOVC).
Tabla 4.4 Direccionamiento por registro, inmediato, directo, indirecto y por desplazamiento para la MCS-251
Modo dedireccionamiento
Rango dedirecciones del
operando
Notación Comentarios
Registro 00:0000H-00:001FH
(R0-R7, WR0-WR3,
DR0,DR2) (1)
R0-R15,WR0-WR30,
DR0-DR28,
DR56-DR60
R0-R7, WR0-WR6, DR0 y DR6 están
ubicados en el banco de registros
seleccionado por RS0 y RS1.
Inmediato 2 bits #short=1, 2 ó 4 Se utiliza sólo en instrucciones de
incremento y decremento.
Inmediato 8 bits #dato8=#00H-#FFH
Inmediato 16 bits #dato16=#0000H-
#FFFFH
Directo 00:0000H-00:007FH dir8=00:0000H-
00:007FH
RAM interna
direcciones de 8 bits SFRs dir8=S:080H-S:1FFH
o el nombre del
registro
Direcciones del área SFRs.
Directo direcciones
de 16 bits
00:0000H-00:FFFFH dir16=00:0000H-
00:FFFFH
Indirecto direcciones
de 16 bits
00:0000H-00:FFFFH @WR0-@WR30
Indirecto direcciones
de 24 bits
00:0000H-
FF:FFFFH
@DR0-@DR30,
@DR56, @DR60
Los 8 bits de mayor peso del registro
DRk deben ser 00H.
Desplazamiento con
direcciones de 16
bits
00:0000H-00:FFFFH @WRj+dis16 =
@WR0+0H hasta
@WR30+FFFFH
El desplazamiento se expresa en
complemento a 2.
Desplazamiento con
direcciones de 24
bits
00:0000H-
FF:FFFFH
@DRk+dis24 =
@DR0+0H hasta
@DR56+FFFFH,
@DR56+(0H-FFFFH),
@DR60+(0H-FFFFH)
El desplazamiento se expresa en
complemento a 2. Los 8 bits de mayor
peso del registro DRk debe ser 00H.
(1) Estos registros están implementados en el espacio de memoria
© Los autores, 2001; © Edicions UPC, 2001.
72 Microcontroladores MCS-51 y MCS-251
Tabla 4.5 Áreas de direccionamiento de bit
Arquitectura Localizaciones de bit
RAM interna SFR
MCS-51 20H-2FH Registros SFR cuya dirección acaba con 0 ó 8:
80H, 88H, 90H, 98H, …,F8H.
MCS-251 20H-7FH Todos los registros SFR definidos.
Tal y como se observa en esta tabla, el rango de bits que se puede direccionar a nivel de bit en la
familia MCS-251 es mucho mayor que en la familia MCS-51.
Para la familia MCS-51 existen dos maneras de direccionar los bits de la memoria RAM interna:
i) Especificando la dirección donde está ubicado el bit junto con la posición del bit dentro del
byte que lo soporta.
ii) Especificando la dirección propia del bit perteneciente al rango 00H-7FH.
La figura 4.1 muestra de forma gráfica estas dos posibles formas. Por ejemplo, el bit número 3 de la
posición de memoria 21H se puede referir como 21H.3, o bien como 0BH.
Memoria RAM interna
7 6 5 4 3 2 1 0
7 6 5 4 3 2 1 0
7 6 5 4 3 2 1 0
21H
20H
2FH
Memoria RAM interna
07H 06H 05H 04H 03H 02H 01H 00H
21H
20H
2FH
0FH 0EH D0H 0CH 0BH 0AH 09H 08H
7FH 7EH 7DH 7CH 7BH 7AH 79H 78H
Fig. 4.1 Direccionamiento de bits de la memoria RAM interna en la familia MCS-51
La familia MCS-51 dispone también de dos formas de direccionar, a nivel de bit, los bits del área
SFR:
i) Especificando la dirección o nombre del registro donde está ubicado el bit junto con la
posición del bit dentro del byte que lo soporta.
ii) Especificando la dirección propia del bit perteneciente al rango 80H-FFH.
Por ejemplo, la dirección del bit 3 del acumulador se puede escribir como ACC.3, E0H.3 o E3H. En la
familia MCS-251, la dirección de un bit se indica mediante la dirección donde está ubicado el bit y la
posición que ocupa dentro del byte que lo contiene. Para el caso de bits ubicados en el área SFR, en
lugar de la dirección se puede indicar, si se desea, el nombre del registro.
© Los autores, 2001; © Edicions UPC, 2001.
4 Programación de las familias MCS-51 y MCS-251 73
Area SFRF8H
F0H
E8H
E0H
D8H
D0H
C8H
C0H
B8H
B0H
A8H
A0H
98H
90H
88H
80H
B
ACC
PSW
T2CON
IP
P3
IE
P2
SCON
P1
TCON
P0
Area SFR
B
ACC
PSW
T2CON
IP
P3
IE
P2
SCON
P1
TCON
P0
F8H
F0H
E8H
E0H
D8H
D0H
C8H
C0H
B8H
B0H
A8H
A0H
98H
90H
88H
80H
F9H
F1H
E9H
E1H
D9H
D1H
C9H
C1H
B9H
B1H
A9H
A1H
99H
91H
89H
81H
FAH
F2H
EAH
E2H
DAH
D2H
CAH
C2H
BAH
B2H
AAH
A2H
9AH
92H
8AH
82H
FBH
F3H
EBH
E3H
DBH
D3H
CBH
C3H
BBH
B3H
ABH
A3H
9BH
93H
8BH
83H
FCH
F4H
ECH
E4H
DCH
D4H
CCH
C4H
BCH
B4H
ACH
A4H
9CH
94H
8CH
84H
FDH
F5H
EDH
E5H
DDH
D5H
CDH
C5H
BDH
B5H
ADH
A5H
9DH
95H
8DH
85H
FEH
F6H
EEH
E6H
DEH
D6H
CEH
C6H
BEH
B6H
AEH
A6H
9EH
96H
8EH
86H
FFH
F7H
EFH
E7H
DFH
D7H
CFH
C7H
BFH
B7H
AFH
A7H
9FH
97H
8FH
87H
Fig. 4.2 Direccionamiento de bit en el área SFR de la familia MCS-51
4.2.7 Direccionamiento relativo
El direccionamiento relativo está vinculado a las instrucciones de salto. En este tipo de
direccionamiento la instrucción incluye un valor que indica la magnitud del salto a realizar. El valor es
de 8 bits y está expresado en complemento a 2, de forma que la magnitud del salto es de -128
posiciones de memoria hacia atrás o de 127 posiciones de memoria hacia delante, empezando a contar
a partir de la dirección donde está ubicado el primer byte de la siguiente instrucción.
Ejemplo:
SJMP rel ;Realiza un salto incondicional cuya magnitud se indica con el valor de 8 bits “rel”JC rel ;Realiza un salto condicional donde la condición de salto es CY=1
4.3 Conjunto de instrucciones de la familia MCS-51 y MCS-251
Una de las características más importantes de cualquier microcontrolador o microprocesador reside en
el conjunto de instrucciones que incorpora. El conjunto de instrucciones es el único código que la
CPU es capaz de interpretar, decodificar y ejecutar. El desarrollo de programas para un
microprocesador determinado requiere que el programador tenga un conocimiento completo de su
conjunto de instrucciones y del modelo de programación que permite éste; además de un conocimiento
detallado del tamaño en código máquina y del tiempo de ejecución de cada una de las instrucciones,
puesto que este conocimiento es vital en la determinación de los tiempos de ejecución de las rutinas
generadas y para la reducción, en la medida de lo posible, del tamaño del código generado por el
programador.
Mediante el conjunto de instrucciones de las familias MCS-51 y MCS-251 es posible realizar
operaciones aritméticas y lógicas, como suma, resta, multiplicación, división, and, or, or-exclusiva y
© Los autores, 2001; © Edicions UPC, 2001.
74 Microcontroladores MCS-51 y MCS-251
negación, con datos de 8 bits. También se pueden ejecutar instrucciones de intercambio de bytes, de
salto, etc. Esta familia, además, está concebida para poder operar a nivel de bit, por lo que puede
realizar operaciones lógicas y de movimiento con bits.
El conjunto de instrucciones de la familia de microcontroladores MCS-251 incorpora nuevas
instrucciones que aprovechan las ventajas de la arquitectura de este microcontrolador manteniendo la
compatibilidad con el conjunto de instrucciones de la familia MCS-51. Muchas de las nuevas
instrucciones pueden operar con datos de 8 bits, 16 bits o 32 bits. Esta capacidad incrementa la
eficiencia y facilidad de programación de los microcontroladores de la familia MCS-251 en un
lenguaje de alto nivel como el C.
El conjunto de instrucciones que ejecutan las familias de microcontroladores MCS-51 y MCS-251 se
dividen en tres grupos: instrucciones que operan con datos de 8 bits y con datos de 16 y 32 bits (sólo
para la familia MCS-251), instrucciones que operan con bits e instrucciones de control que permiten
realizar saltos en la ejecución del programa.
Para poder comprender de forma correcta tanto el conjunto de instrucciones como los ejemplos
empleados a lo largo de este capítulo, es preciso explicar previamente el formato de las instrucciones,
algunas directivas comunes del programa ensamblador y la definición y uso de etiquetas dentro de un
programa.
4.3.1 Formato de una instrucción
En lenguaje ensamblador una instrucción puede esta formada por cuatro partes diferentes: una
etiqueta, un mnemónico o palabra clave que identifica el tipo de instrucción, un operando fuente, y un
operando destino. En las instrucciones las etiquetas son opcionales y son definidas por el
programador. Las etiquetas se utilizan para distinguir una instrucción dentro del programa realizado, y
para que la instrucción a la que se adjunta una etiqueta se pueda referenciar en cualquier instrucción de
salto del programa. Para ello, cuando el programa ensamblador detecta una etiqueta le asigna, de
manera automática, la dirección de la instrucción a la que hace referencia. De esta forma, cualquier
instrucción que contenga una dirección de salto puede emplear cualquier etiqueta definida dentro del
programa.
A modo de ejemplo se proponen las siguientes instrucciones:
Etiqueta Mnemónico 1er Operando , 2º Operando
Retardo: MOV R0 , #70H
Suma: ADD A , 70H
MOV 20H , @R0
INC A
DJNZ R2 , Bucle
SJMP Salir
PUSH A
© Los autores, 2001; © Edicions UPC, 2001.
4 Programación de las familias MCS-51 y MCS-251 75
Por ejemplo, en el caso de una etiqueta, la instrucción “DJNZ R2, Bucle” decrementa en una unidad el
registro R2 y, si R2 es distinto de cero, realiza un salto a la dirección donde se halla la etiqueta
“Bucle”; es decir, si se cumple la condición R2 [ 0, se coloca la dirección asignada a “Bucle” en el
contador de programa PC, de forma que la CPU pasa a ejecutar el programa por la dirección que
representa la etiqueta.
Las etiquetas también se emplean para referenciar el inicio de una subrutina. Las etiquetas pueden
definirse tan sólo una vez dentro de un mismo programa, sin embargo, pueden usarse tantas veces
como sea necesario cuando se referencian por otra instrucción. El programador tiene libertad de
emplear cualquier conjunto de caracteres para definir una etiqueta, salvo las limitaciones propias del
programa ensamblador, por lo que se debe evitar la duplicación de etiquetas con el mismo nombre
dentro de un mismo programa. Las etiquetas se deben colocar en el extremo izquierdo de cada línea de
programa, y se debe guardar al menos un espacio entre la etiqueta y el resto de la instrucción. La
etiqueta debe terminarse con dos puntos o sin ninguna puntuación, dependiendo del programa
ensamblador que se utilice. En este libro se emplean dos puntos al final de cada etiqueta a lo largo de
toda la obra.
El mnemónico de una instrucción es una palabra abreviada que indica la función que realiza la
instrucción, como MOV, ADD, INC, JMP, etc. La familia MCS-51 dispone de 111 instrucciones en
total y la familia MCS-251 de 213 instrucciones.
Los operandos pueden ser registros, constantes o posiciones de memoria accedidas mediante los
distintos tipos de direccionamientos que soporta el microcontrolador. Un operando también puede ser
una dirección de salto en el caso de instrucciones de salto condicional o incondicional. En el caso de
que una instrucción contenga dos operandos, se introduce una coma para hacer de separación entre
ambos. Las instrucciones operan de varias maneras diferentes sobre los operandos. Existen
instrucciones con un único operando donde éste constituye el origen y el destino de la operación,
como “INC A”, que primero lee el contenido del acumulador, lo incrementa en una unidad y deja el
resultado en el mismo acumulador. Otras instrucciones operan con ambos operandos, dejando el
resultado de la operación en el primer operando: por ejemplo, la instrucción “ADD A, #70H” suma el
contenido del acumulador con la constante 70H, dejando el resultado en el mismo acumulador.
Por último, si el programador quiere poner comentarios en una instrucción, basta con que añada un
punto y coma al final de la instrucción, colocando el comentario a continuación. Por ejemplo:
MOV R0, A ; Salva el contenido del acumulador en R0
4.3.2 Directivas de ensamblador
En la realización de un programa en lenguaje ensamblador, es habitual utilizar una serie de directivas
que no generan código máquina y que ayudan al programa ensamblador a dirigir y controlar el proceso
de ensamblado. De todas las directivas existentes en lenguaje ensamblador se describirán sólo las que
se suelen emplear con mayor frecuencia. Las directivas principales son: ORG, EQU, DB y END.
© Los autores, 2001; © Edicions UPC, 2001.
76 Microcontroladores MCS-51 y MCS-251
La directiva ORG es una abreviación de la palabra inglesa origin y permite especificar el valor de la
dirección de memoria donde va a ser cargada la próxima instrucción o dato a ensamblar, o sea,
inicializa el contador de programa con el valor que acompaña a la directiva. La sintaxis de esta
directiva es la siguiente:
ORG <dirección>
Esta directiva pone en el contador de programa, PC, la dirección indicada por <dirección>, de manera
que la primera instrucción en ejecutarse es la primera que aparece tras esta directiva.
La directiva ORG puede aparecer en cualquier parte del programa y el programador puede colocar
tantas como crea conveniente. Esta directiva se puede utilizar para asignar una dirección concreta a
una subrutina, para definir una posición determinada de salto o para asignar una dirección a una tabla
de datos.
Ejemplo:ORG 0100H ;Determina la dirección 0100H
Inicio: MOV R0,#09H ;Pone 09H en R0
ADD A, R0 ;Suma el acumulador con el valor 09H
A la etiqueta “Inicio”, al ir precedida de la directiva ORG, el ensamblador le asignará el valor de
0100H, de forma que las dos instrucciones del programa irán almacenadas en memoria a partir de la
dirección 0100H. Si se desea asignar una dirección determinada a una subrutina basta con emplear la
directiva ORG al inicio de la misma. Por ejemplo, si se desea que la subrutina de conversión de
números binarios a números en formato ASCII comience en la dirección 2400H, se debe incluir la
siguiente directiva:
ORG 2400H
Bin_ASCII: MOV A, R0 ; Salva R0 en A
........
RET ; Fin de la subrutina
La directiva EQU se utiliza para asignar a un símbolo alfanumérico un valor numérico o un string(cadena de caracteres). Es importante resaltar que esta directiva no reserva espacio en memoria, por lo
que los valores que se definan mediante EQU los mantiene el ensamblador y los emplea en el proceso
de ensamblado. La sintaxis de la directiva EQU es la siguiente:
<símbolo> EQU <expresión>
Ejemplo:
num EQU 20H ; Asigna el valor 20H al símbolo “num”área EQU num*num ; Área de un cuadrado
reg EQU “A” ; Asigna al símbolo “reg” el nombre de un registro
© Los autores, 2001; © Edicions UPC, 2001.
4 Programación de las familias MCS-51 y MCS-251 77
La directiva DB reserva espacios de memoria de 8 bits (1 byte) a partir de la ubicación de dicha
directiva. El espacio reservado se llena con el valor, la lista de datos o la expresión que acompaña a la
directiva. Si el dato que acompaña a la directiva va entre comillas se interpreta como constantes
alfanuméricas (caracteres), y el espacio reservado se carga con el código ASCII asociado a dichas
constantes. Si el dato no va entrecomillado se interpreta como valor numérico. Los caracteres
numéricos deben ir acompañados por comas. La sintaxis de esta directiva es:
DB [[<espacio de datos>]] <dato> [ [[<espacio reservado>]]<dato>…]
Ejemplo:
DB “Ensamblador” ; Reserva e inicializa 11 bytes con los valores de código ASCII
; correspondientes a los caracteres de la palabra ensambladorDB 1,2 ; Reserva 2 bytes. Al primer byte le asigna el número 1 y al segundo el 2
DB [10]1,[10]2 ; Reserva 20 bytes. Los 10 primeros se ponen a 1 y los 10 restantes a 2
La directiva END indica el final del programa, por tanto, siempre es la última sentencia de un
programa. El ensamblador termina el proceso de ensamblado cuando se encuentra con esta directiva.
4.3.3 Los registros de estado PSW y PSW1
La función de los registros de estado en las familias de microcontroladores MCS-51 y MCS-251 es
diversa: incorporan bits o flags (banderas) que proporcionan información acerca del resultado de las
operaciones aritméticas y lógicas realizadas por el microcontrolador, incorporan los bits de selección
del banco de registros e incorporan bits cuya función es definible por el usuario.
Los microcontroladores de la familia MCS-51 disponen de un único registro de estado: el ProgramStatus Word (PWS), mientras que los microcontroladores de la familia MCS-251 disponen de este
mismo registro más otro registro de estado adicional: el PSW1.
Los registros PSW y PSW1 contienen cuatro tipos diferentes de bits:
- Los bits CY, AC, OV, N y Z, que son indicadores que se ponen a 1 lógico
automáticamente como respuesta al resultado de una operación.
- El bit P que indica la paridad del acumulador.
- Los bits RS0 y RS1, cuyo estado determina la selección del banco de registros activo
que ubica los registros R0-R7.
- Los bits F0 y UD, que son bits de propósito general definibles por el usuario.
En las tablas 4.6 y 4.7 están representados el contenido de los bits de los registros de estado PSW y
PSW1. Hay que indicar que cinco bits del registro PSW están repetidos en el registro PSW1. En estos
casos la función de estos bits es la misma.
En la tabla 4.8 se muestran las instrucciones cuya ejecución afecta al valor de los bits CY, AC, OV, N
y Z.
© Los autores, 2001; © Edicions UPC, 2001.
78 Microcontroladores MCS-51 y MCS-251
Tabla 4.6 Registro PSW
Númerode bit
Mnemónico Función
7 CY o C Bit de acarreo. CY se pone a 1 lógico si en las instrucciones de suma o
resta se produce acarreo en el bit séptimo. CY también está afectado por las
instrucciones RRC, RLC, MUL, DA, JBC y CJNE.
6 AC Bit de acarreo auxiliar. AC se activa si en las instrucciones de suma o resta
se produce acarreo en el bit tercero.
5 F0 Bit F0. Este bit es de propósito general y definible por el usuario.
4:3 RS1:0 Estos dos bits permiten seleccionar el banco de registros que soportan los
registros R0-R7.
RS1 RS0 Banco Direcciones 0 0 0 00H - 07H
0 1 1 08H - 0FH
1 0 2 10H - 17H
1 1 3 18H - 1FH
2 OV Bit de rebasamiento o overflow. Este bit se pone a 1 lógico cuando se
produce un error de overflow en operaciones de suma o resta. OV también
se pone a 1 cuando el resultado de una multiplicación es mayor de un byte,
o cuando se realiza una división por cero.
1 UD Bit UD. Este bit es de propósito general y definible por el usuario.
0 P Bit de paridad. Indica la paridad del acumulador. Se pone a 1 cuando el
número de unos de A es impar, y a 0 cuando es par.
Tabla 4.7 Registro PSW1
Númerode bit
Mnemónico Función
7 CY o C Bit de acarreo.
Su función es idéntica a la del bit CY del PSW.
6 AC Bit de acarreo auxiliar.
Función idéntica a la del bit AC del PSW.
5 N Bit negativo.
Este indicador se pone a 1 cuando el resultado de la última operación
aritmética o lógica es negativo, o sea, cuando el bit de mayor peso del
resultado está a 1. En caso contrario se pone a cero.
4:3 RS1:0 Tienen la misma función que en el registro PSW.
2 OV Bit de rebasamiento.
Tiene la misma función que en el registro PSW.
1 Z Bit de cero.
Se pone a 1 cuando el resultado de la última operación aritmética o lógica
es cero. En caso contrario, el bit Z se pone a cero.
0 - Bit reservado.
© Los autores, 2001; © Edicions UPC, 2001.
4 Programación de las familias MCS-51 y MCS-251 79
Tabla 4.8 Activación de los bits de los registros PSW y PSW1
Tipo de Instrucción Bits afectadosinstrucción CY OV AC N Z
ADD, ADDC, SUB, SUBB, CMP X X X X X
Aritmética INC, DEC X X
MUL, DIV 0 X X X
DA X X X
Lógica ANL, ORL, XRL, CLR A, CPL A, RL, RRL, SWAP X X
RLC, RRC, SRL, SLL, SRA X X X
Control de CJNE X X X
programa DJNE X X
4.3.4 Instrucciones aritméticas
Las instrucciones aritméticas de la familia MCS-51, se pueden diferenciar en tres tipos distintos: a)
instrucciones de suma y resta, b) instrucciones de incremento y decremento, y c) instrucciones de
multiplicación y división. La familia MCS-251 tiene los mismo tipos de instrucciones aritméticas que
la MCS-51, y un tipo más: la instrucción de comparación. La tabla 4.9 muestra el conjunto de
instrucciones aritméticas que posee la familia MCS-51, donde se realiza una breve descripción de cada
instrucción, mientras que la tabla 4.10 muestra las instrucciones aritméticas para la MCS-251. Se debe
tener en cuenta que todas las instrucciones de la MCS-51 también se pueden ejecutar en la familia
MCS-251, puesto que es compatible, en modo binario, con la MCS-51.
Tabla 4.9 Instrucciones aritméticas comunes a las familias MCS-51 y MCS-251
Mnemónico <dest>,<src> DescripciónA, Rn A=A+ Rn
ADD A, dir8 A=A+ (dir8)
A, @Ri A=A+ (@Ri )
A, #dato A=A+ dato
A, Rn A=A ] Rn
ADDC A, dir8 A=A ] (dir8) ] C
SUBB A, @Ri A=A ] (@Ri ) ] C
A, #dato A=A ] dato ] C
A A=A ] 1
INC Rn Rn=Rn ] 1
DEC dir8 (dir8) = (dir8) ] 1
@Ri (@Ri ) = (@Ri ) ] 1
INC DPTR DPTR = DPTR +1
MUL AB Multiplica A por B.
Deja el byte alto del resultado en B y el byte bajo en A
DIV AB Divide A por B
Deja el cociente en A y el resto en B
DA A Ajuste decimal del acumulador
© Los autores, 2001; © Edicions UPC, 2001.
80 Microcontroladores MCS-51 y MCS-251
Tabla 4.10 Instrucciones aritméticas de la familia MCS-251
Mnemónico <dest>,<src> DescripciónADD
SUB
Rmd,Rms
WRjd,WRjs
DRkd,DRks
Rm,#dato
WRj,#dato16
DRk,#0dato16
Rm,dir8
WRj,dir8
Rm,dir16
WRj,dir16
Rm,@WRj
Rm,@DRk
Rmd = Rmd ± Rms
WRjd = WRjd ± WRjs
DRkd = DRkd ± DRks
Rm = Rm ± dato
WRj = WRj ± dato16
DRk = DRk ± 0dato16
Rm = Rm ± (dir8)
WRj = WRj ± (dir8, dir8+1)
Rm = Rm ± (dir16)
WRj = WRj ± (dir16,dir16+1)
Rm = Rm ± (@WRj)
Rm = Rm ± (@DRk)
CMP Rmd,Rms
WRjd,WRjs
DRkd,DRks
Rm,#dato
WRj,#dato16
DRk,#0dato16
DRk,#1dato16
Rm,dir8
WRj,dir8
Rm,dir16
WRj,dir16
Rm,@WRj
Rm,@DRk
Rmd - Rms
WRjd - WRjs
DRkd - DRks
Rm - #dato
WRj - #dato16
DRk - #0dato16
DRk - #1dato16
Rm - (dir8)
WRj - (dir8, dir8+1)
Rm - (dir16)
WRj - (dir16,dir16+1)
Rm - (@WRj)
Rm - (@DRk)
INC
DEC
Rm,#short
WRj,#short
DRj,#short
Rn = Rn ± #short†
WRj = Wrj ± #short†
DRj = DRj ± #short†
MUL Rmd,Rms
WRjd,WRjs
Multiplica Rmd y Rms
Multiplica WRjd y WRjs
DIV Rmd,Rms
WRjd,WRjs
Divide Rmd por Rms
Divide WRjd por WRjs† #short puede ser 1, 2 ó 4.
4.3.4.1 Instrucciones de suma y de resta
En la familia MCS-51, para realizar la suma de dos bytes se pueden emplear dos instrucciones: ADD y
ADDC. La ejecución de estas instrucciones afecta a los bits de acarreo (CY), de acarreo auxiliar (AC)
y de rebasamiento (OV), que son útiles para detectar determinadas situaciones.
Las instrucciones de suma ponen a 1 lógico el bit CY cuando el resultado de la suma es mayor que
FFH; en caso contrario permanece a 0. En cuanto al bit de acarreo auxiliar, AC, se pone a 1 si en la
suma se produce un acarreo entre el nibble bajo y el nibble alto, es decir, si se produce acarreo entre el
bit 3 y el bit 4.
© Los autores, 2001; © Edicions UPC, 2001.
4 Programación de las familias MCS-51 y MCS-251 81
El bit de rebasamiento, OV, es un indicador útil cuando se realiza la suma de dos números enteros con
signo en formato de complemento a dos. En este caso, el bit OV se pone a 1 en los siguientes
supuestos:
a) Si la suma de dos números positivos en complemento a dos genera un resultado
negativo. En este caso, el resultado de la suma debe estar comprendido entre 80H y
FFH, de forma que el bit de signo sea igual a 1.
b) Si la suma de dos números negativos en complemento a dos genera un resultado
positivo. En este caso, el resultado de la suma debe estar comprendido entre 00H y 7FH,
de forma que el bit de signo sea igual a 0.
En ambos supuestos el resultado de la suma es erróneo, de manera que el bit de OV se pone a 1 para
que el programador pueda considerar este error. En el siguiente ejemplo se suman dos números
positivos y dos números negativos, de manera que se cumplen los supuestos a) y b).
59H
+ 3AH
0 101 1001
0 011 1010
Bit de signo
1 001 001193H
- 59H
-3AH
1 010 0111 (A7H en compl. a 2)
1 100 0110 (C6H en compl. a 2)
0 110 1101
(6DH)
0 1C C
En este ejemplo se observa cómo en ambos casos el bit de signo del resultado no coincide con el bit de
signo de los operandos, y el bit OV se pone a 1. Esta situación se da cuando en la suma se produce un
acarreo entre los bits 6 y 7 de los operandos, pero no se produce entre el bit 7 y el bit C. Lo mismo
ocurre cuando el acarreo se da entre el bit 7 y el bit C, pero no entre el bit 6 y el bit 7.
La instrucción ADDC es idéntica a la instrucción ADD, salvo que, además, suma el bit C al resultado.
Con esta instrucción se pueden sumar números enteros con un tamaño mayor que 1 byte (precisión
múltiple). Los ejemplos que utilizan esta instrucción se tratarán en el capítulo siguiente.
La resta de dos números se realiza mediante la instrucción SUBB. Esta instrucción incluye el bit C en
la resta. El bit de acarreo C se pone a 1 cuando se produce un desbordamiento, de manera que se
puede emplear para realizar la resta con precisión múltiple. El bit de acarreo auxiliar, AC, se pone a 1
al producirse un acarreo entre el nibble bajo y el nibble alto (entre el bit 3 y el bit 4). El bit OV realiza
la misma función que en las instrucciones de suma cuando se opera con números en complemento a
dos, de manera que se pone a 1 en los supuestos mencionados anteriormente.
En la familia MCS-251 las instrucciones ADD y SUB permiten sumar y restar operandos de 8, 16 y 32
bits. El resultado de la suma se guarda en la ubicación del operando destino. La instrucción ADDC es
idéntica a la instrucción ADD, salvo que, además, suma el bit C al resultado. La instrucción SUBB
resta los dos operandos que se especifican en la propia instrucción y, además, resta el bit de acarreo C.
La ejecución de las instrucciones de suma y resta afecta, de la misma forma que la indicada para la
familia MCS-51, a los bits del registro de estado CY, OV y AC; no obstante, también afecta a los bits
Z y N del registro PSW1.
© Los autores, 2001; © Edicions UPC, 2001.
82 Microcontroladores MCS-51 y MCS-251
Ejemplo:
ADD A,#3AH ; Suma del contenido del acumulador con el dato 34H
Si se supone que el contenido del acumulador es 59H el resultado de la suma será:
59H
+ 3AH
0 101 1001
0 011 1010
1 001 001193H 0C
En esta suma el bit de cero Z se pone a cero, puesto que el resultado es distinto de cero, mientras que
el bit de signo N se pone a uno, para indicar con ello que el bit de mayor peso del resultado es 1.
4.3.4.2 Instrucciones de multiplicación y de división
Las instrucciones de multiplicación (MUL) y división (DIV) permiten multiplicar y dividir dos
operandos sin signo. En la familia MCS-51 sólo es posible multiplicar o dividir el contenido del
registro A por el contenido del registro B. La instrucción MUL AB realiza la multiplicación sin signo
del contenido del acumulador con el contenido del registro B, depositando el byte alto del resultado en
el registro B y el byte bajo en el acumulador. El bit de acarreo C se pone siempre a 0 y el bit OV se
pone a 1 sólo cuando el resultado es superior a FFH; se pone a 0 en caso contrario.
La instrucción DIV AB realiza la división sin signo entre el acumulador y el registro B. Tras la
ejecución de la instrucción el acumulador contiene el cociente de la división y el registro B contiene el
resto de la división. El bit de acarreo C se pone siempre a 0. El bit de rebasamiento se activa cuando se
ha producido una división por cero. Tras una división por cero el valor del cociente y del resto de la
división resulta indeterminado.
Para la familia MCS-251 las instrucciones de multiplicación y de división permiten multiplicar o
dividir cualquier par de registros tipo byte o Word. En multiplicaciones de registros de 8 bits el
resultado de 16 bits se guarda en el registro tipo Word que contiene al registro destino. Por ejemplo, el
producto de la instrucción MUL R3,R8 se guardaría en el registro Word que contiene al registro R3, o
sea, se guardaría en WR2. En el caso de productos entre datos de 16 bits el resultado de 32 bits se
guardaría en el registro Dword que contiene al registro Word destino. Por ejemplo, el producto de la
instrucción MUL WR6,WR14 se guardaría en el registro DR4 que contiene al registro WR6.
En divisiones de datos de 8 bits el resultado se guarda en el registro Word que contiene al registro
destino. El cociente se guarda en el byte bajo mientras que el resto se guarda en el byte alto. Por
ejemplo, el resultado de la instrucción “DIV R5,R0” se guardaría en el registro WR4. Concretamente
en R4 se guardaría el resto y en R5 el cociente. En divisiones de 16 bits el resultado se guarda en el
registro Dword que contiene al registro Word destino. Por ejemplo, el resultado de la instrucción DIV
WR8,WR16 se guardaría en el registro DR8 (en la parte alta el resto y en la parte baja el cociente).
© Los autores, 2001; © Edicions UPC, 2001.
4 Programación de las familias MCS-51 y MCS-251 83
4.3.4.3 Instrucciones de incremento y decremento
En la familia MCS-51 las instrucciones de incremento y de decremento son INC y DEC,
respectivamente. Estas instrucciones tienen como función incrementar o decrementar en una unidad el
operando indicado en la instrucción. Es importante observar cómo el registro DPTR se puede
incrementar directamente mediante la instrucción INC, mientras que no se puede decrementar de la
misma manera, puesto que la instrucción DEC no opera con este registro. La instrucción INC DPTR es
de gran utilidad para la lectura de tablas en memoria externa.
Las instrucciones de incremento y de decremento de la familia MCS-251 permiten, además,
incrementar o decrementar el contenido de registros tipo byte, Word o Dword en 1, 2 o 4 unidades.
4.3.4.4 Instrucción de comparación
La instrucción de comparación CMP es exclusiva de la familia MCS-251 y calcula la diferencia entre
dos operandos. El resultado generado por esta diferencia no se almacena pero sí que se activan los
flags CY, OV, AC, N y Z en los registros PSW y PSW1. La utilidad de la instrucción CMP estárelaciona con las instrucciones de salto condicional.
4.3.4.5 Instrucción de ajuste decimal
La instrucción de ajuste decimal, DA A, es útil cuando se realizan sumas de números en formato BCD
con el registro acumulador como destino. En el formato BCD cada nibble de un byte representa un
número decimal en base 10, por lo que su valor está comprendido entre 0 y 9. Cuando se desean sumar
dos números en formato BCD mediante las instrucciones ADD y ADDC, la suma que realizan es
binaria, de manera que el resultado de ésta puede no estar en formato BCD. Por tanto, en el caso de
sumar números en formato BCD, se debe emplear la instrucción DA A, que convierte el resultado de
la suma al formato BCD. Por ejemplo, si se suman los números BCD 19H y 22H mediante la
instrucción ADD, el resultado es 3BH, mientras que el resultado esperado en BCD es 41H.
La instrucción DA A realiza las siguientes operaciones:
- Si los 4 bits bajos del acumulador (nibble bajo) tienen un valor mayor que 9 o si el bit
AC está a 1, le suma el valor 6 a este nibble para hacer la conversión a BCD.
- Si los 4 bits altos del acumulador tienen un valor mayor que 9 o si el bit C está a 1, le
suma el valor 6 a estos bits para hacer la conversión a BCD.
Por tanto, en la suma de los números 19H y 22H en BCD, la instrucción DA suma 06H al acumulador,
dando lugar al resultado de 41H en BCD. La suma de 85H y 25H en BCD, da como resultado el valor
AAH; para ajustar este valor la instrucción DA le suma 66H, por lo que el valor en el acumulador es
de 10H y el bit C está a 1; el resultado final es 110H.
4.3.5 Instrucciones lógicas
La tabla 4.11 muestra la lista de instrucciones lógicas de la familia MCS-51 y la tabla 4.12 muestra las
instrucciones lógicas de la familia MCS-251. Las operaciones lógicas que pueden realizar las familias
MCS-51 y MCS-251 son: AND, OR, XOR y NOT.
© Los autores, 2001; © Edicions UPC, 2001.
84 Microcontroladores MCS-51 y MCS-251
Tabla 4.11 Instrucciones lógicas comunes a las familias MCS-51 y MCS-251
Mnemónico <dest>,<src> DescripciónANL
ORL
XRL
A,Rn
A,dir8
A,@Ri
A,#dato
dir8,A
dir8,#dato
A = A AND ó OR ó XOR Rn
A = A AND ó OR ó XOR (dir8)
A = A AND ó OR ó XOR (@Ri)
A = A AND ó OR ó XOR #dato
(dir8) = (dir8) AND ó OR ó XOR A
(dir8) = (dir8) AND ó OR ó XOR #dato
CLR A A = 0
CPL A Complementa el acumulador.
RL A Rotación a la izquierda del acumulador.
RLC A Rotación a la izquierda con acarreo del acumulador.
RR A Rotación a la derecha del acumulador.
RRC A Rotación a la derecha con acarreo del acumulador.
SWAP A Intercambia los nibbles del acumulador.
Tabla 4.12 Instrucciones lógicas de la familia MCS-251
Mnemónico <dest>,<src> DescripciónANL
ORL
XRL
Rmd,Rms
WRjd,WRjs
Rm,#dato
WRj,#dato16
Rm,dir8
WRj,dir8
Rm,dir16
WRj,dir16
Rm,@WRj
Rm,@DRk
Rmd = Rmd AND ó OR ó XOR Rms
WRjd = WRjd AND ó OR ó XOR WRjs
Rm = Rm AND ó OR ó XOR #dato
WRj = WRj AND ó OR ó XOR #dato16
Rm = Rm AND ó OR ó XOR (dir8)
WRj = WRj AND ó OR ó XOR (dir8, dir8+1)
Rm = Rm AND ó OR ó XOR (dir16)
WRj = WRj AND ó OR ó XOR (dir16, dir16+1)
Rm = Rm AND ó OR ó XOR (@WRj)
Rm = Rm AND ó OR ó XOR (@DRk)
SLL Rm
WRj
Desplazamiento lógico a la izquierda de Rm.
Desplazamiento lógico a la izquierda de WRj.
SRA Rm
WRj
Desplazamiento aritmético a la derecha de Rm.
Desplazamiento aritmético a la derecha de WRj.
SRL Rm
WRj
Desplazamiento lógico a la derecha de Rm.
Desplazamiento lógico a la derecha de WRj.
4.3.5.1 Instrucciones ANL, ORL, XRL y CLP
Las instrucciones lógicas ANL y ORL se pueden utilizar para realizar máscaras, cambiando el estado
de bits específicos de algún registro. Por ejemplo, si se desea forzar a cero, de forma simultánea, los
bits de acarreo CY y de acarreo auxiliar AC del registro de estado PSW, se puede realizar de la
siguiente forma:
ANL A, #00111111b
Así sólo se afecta a los bits mencionados mientras que se respeta el estado de los restantes bits del
registro. En caso de querer forzar los mismos bits a 1 lógico se debe utilizar la instrucción ORL:
ORL A, #11000000b
© Los autores, 2001; © Edicions UPC, 2001.
4 Programación de las familias MCS-51 y MCS-251 85
La instrucción XRL se puede emplear para realizar la comparación de un registro con una constante
determinada. Por ejemplo, la siguiente instrucción:
XRL A, #19H
pone a cero el acumulador si éste es igual a 19H; en caso contrario el acumulador tendrá un valor
distinto de cero. De esta forma es posible realizar comparaciones con constantes numéricas, utilizando
el acumulador como indicador de la comparación.
Por último, la instrucción CPL realiza el complemento de cada uno de los bits del acumulador. Si el
acumulador tiene por valor 35H, la ejecución de CPL A pone el acumulador al valor CAH.
Las instrucciones adicionales que posee la familia MCS-251 permiten realizar operaciones lógicas
entre cualquier par de registros tipo byte o Word, o bien entre el contenido de un registro tipo byte o
Word y un operando almacenado en la memoria.
4.3.5.2 Instrucciones de rotación
Las instrucciones de rotación RL, RR, RLC y RRC desplazan el acumulador 1 bit hacia la izquierda o
hacia la derecha. La instrucción RL A rota el acumulador un bit hacia la izquierda, por lo que el bit
más significativo (MSB) queda en la posición del bit menos significativo (LSB). La instrucción RR A
rota el acumulador un bit hacia la derecha; por tanto, el bit menos significativo (LSB) queda en la
posición del bit más significativo (MSB). Las instrucciones RLC A y RRC A, efectúan el mismo tipo
de rotación que el descrito, pero incluyendo el valor del bit de acarreo C. La figura 4.3 ilustra de
manera clara el efecto de las rotaciones.
a)
C
Carry
bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
Acumulador
b)
C
Carry
bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
Acumulador
c)
C
Carry
bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
Acumulador
d)
bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
Acumulador
C
Carry
Fig. 4.3 a) RL A, b) RR A, c) RLC A, d) RRC A
La familia MCS-251 incorpora, además, tres instrucciones de desplazamiento que operan con registros
tipo byte y Word. La instrucción de desplazamiento lógico a la izquierda (SLL) desplaza un bit a la
izquierda el contenido del registro indicado en la instrucción reemplazando el bit de menor peso del
registro por un cero. La instrucción de desplazamiento lógico a la derecha (SRL) desplaza un bit a la
derecha el contenido del registro indicado en la instrucción reemplazando el bit de mayor peso del
registro por un cero. El desplazamiento aritmético a la derecha es similar a la instrucción SRL con la
única diferencia de que el bit de mayor peso no cambia de valor (figura 4.4).
© Los autores, 2001; © Edicions UPC, 2001.
86 Microcontroladores MCS-51 y MCS-251
a)C
Carry
bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
Rm
0
b)C
Carry
bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
Rm
0
c)C
Carry
bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
Rm
Fig. 4.4 a) SLL Rm, b) SRL Rm, c) SRA Rm
4.3.5.3 Instrucciones SWAP y CLR
La instrucción SWAP A intercambia el valor de los nibbles alto y bajo del acumulador. Por ejemplo,
si el acumulador vale 35H, tras la ejecución de SWAP A pasa a valer 53H. La instrucción CLR A
pone a cero el contenido del acumulador y ocupa un byte de código.
4.3.6 Instrucciones de transferencia de datos
Las instrucciones de transferencia de datos tienen como función copiar un dato de un registro o
posición de memoria a otro registro o posición de memoria. Este conjunto de instrucciones incluye la
instrucción MOV, las instrucciones de intercambio y las instrucciones de carga y descarga de la pila.
Tabla 4.13 Instrucciones de transferencia de datos comunes a las familias MCS-51 y MCS-251
Mnemónico <dest>,<src> DescripciónMOV A,Rn
A,dir8
A,@Ri
A,#dato
Rn,A
Rn,dir8
Rn,#dato
dir8,A
dir8,Rn
dir8,dir8
dir8,@Ri
dir8,#dato
@Ri,A
@Ri,dir8
@Ri,#dato
DPTR,#dato16
A = Rn
A = (dir8)
A = (@Ri)
A = #dato
Rn = A
Rn = (dir8)
Rn = #dato
(dir8) = A
(dir8) = Rn
(dir8) = (dir8)
(dir8) = (@Ri)
(dir8) = #dato
(@Ri) = A
(@Ri) = (dir8)
(@Ri) = #dato
DPTR = #dato16
© Los autores, 2001; © Edicions UPC, 2001.
4 Programación de las familias MCS-51 y MCS-251 87
4.3.6.1 La instrucción MOV
La instrucción MOV, Move, (tablas 4.13 y 4.14) es la instrucción más versátil para realizar
transferencia de datos por los diferentes tipos de direccionamiento que soporta. En la familia MCS-51
las instrucciones MOV transfieren datos de tipo byte entre dos registros o bien entre un registro y una
posición de memoria (tabla 4.17), mientras que la familia MCS-251 incorpora nuevas instrucciones
MOV que le permiten realizar transferencias de bytes, Words o Dwords entre registros o bien entre
posiciones de memoria y registros (tabla 4.18).
Tabla 4.14 Instrucciones de transferencia de datos de la familia MCS-251
Mnemónico <dest>,<src> DescripciónMOV Rmd,Rms
WRjd,WRjs
DRkd,DRks
Rm,#dato
WRj,#dato16
DRk,#0dato16
DRk,#1dato16
DRk,dir8
DRk,dir16
Rm,dir8
WRj,dir8
Rm,dir16
WRj,dir16
Rm,@WRj
Rm,@DRk
WRjd,@WRjs
WRj,@DRk
dir8,Rm
dir8,WRj
dir16,Rm
dir16,WRj
@WRj,Rm
@DRk,Rm
@WRjd,WRjs
@DRk,WRj
dir8,DRk
dir16,DRk
Rm,@WRj+dis16
WRj,@WRj+dis16
Rm,@DRk+dis24
WRj,@DRk+dis24
@WRj+dis16,Rm
@WRj+dis16,WRj
@DRk+dis24,Rm
@DRk+dis24,WRj
Rmd = Rms
WRjd = WRjs
DRkd = DRks
Rm = #dato
WRj = #dato16
DRk = #0dato16
DRk = #1dato16
DRk = (dir8, dir8+1, dir8+2, dir8+3)
DRk = (dir16, dir16+1, dir16+2, dir16+3)
Rm = dir8
Wrj = (dir8, dir8+1)
Rm = (dir16)
Wrj = (dir16, dir16+1)
Rm = (@WRj)
Rm = (@DRk)
WRjd = (@WRjs, @WRjs+1)
WRj = (@DRk, @DRk+1)
(dir8) = Rm
(dir8, dir8+1) = WRj
(dir16) = Rm
(dir16, dir16+1) = WRj
(@WRj) = Rm
(@DRk) = Rm
(@WRjd , @WRjd +1) = Wrjs
(@DRk, @Drk+1) = WRj
(dir8, dir8+1, dir8+2, dir8+3) = DRk
(dir16, dir16+1, dir16+2, dir16+3) = DRk
Rm = (@WRj+dis16)
WRj = (@WRj+dis16, @WRj+dis16+1)
Rm = (@DRk+dis24)
WRj = (@Drk+dis24, @DRk+dis24+1)
(@WRj+dis16) = Rm
(@WRj+dis16, @WRj+dis16+1) = Rm
(@DRk+dis24) = Rm
(@DRk+dis24, @DRk+dis24+1) = Rm
4.3.6.2 Instrucciones MOVH, MOVS y MOVZ
Las instrucciones MOVH, MOVS y MOVZ (tabla 4.15) son instrucciones propias de la familia MCS-
251. La instrucción MOVH, Move to High Word, carga en la parte alta del registro DRk, e indica en la
instrucción el valor de 16 bits que acompaña a la instrucción. La instrucción MOVS, Move with Sign
© Los autores, 2001; © Edicions UPC, 2001.
88 Microcontroladores MCS-51 y MCS-251
Extension, carga en la parte baja del registro Word destino el valor almacenado en el registro Rm
fuente, conservando el signo del valor transferido.
Tabla 4.15 Instrucciones de transferencia de datos de la familia MCS-251
Mnemónico <dest>,<src> Descripción
MOVH DRk(hi), #dato16 Carga el dato #dato16 en la parte alta de DRk.
MOVS WRj,Rm Carga el dato de Rm en WRj conservando el signo.
MOVZ WRj,Rm Carga el dato de Rm en WRj con signo positivo.
Ejemplo:MOVS WR0, R3 ; Con R3 = 49H
El valor 49H es positivo por ser cero su bit de mayor peso; por tanto, después de ejecutarse la
instrucción queda WR0 = 0049H.
MOVS WR0, R5 ; Con R5 = 95H
El valor 95H es negativo ya que su bit de mayor peso es uno. Para conservar en este caso el
signo del valor transferido se cargará en la parte alta de WR0 el valor FFH. Por tanto, al
ejecutarse la instrucción queda WR0 = FF95H.
La instrucción MOVZ, Move with Zero Extension, transfiere el contenido de un registro tipo byte a la
parte baja de un registro tipo Word, y se carga en la parte alta el valor 00H.
4.3.6.3 Instrucciones MOVX y MOVC
La familia MCS-51 dispone de instrucciones MOVX, Move External, y MOVC, Move Code,
específicas para direccionar la memoria de datos externa (tabla 4.16).
Tabla 4.16 Instrucciones de transferencia de datos comunes a las familias MCS-51 y MCS-251
Mnemónico <dest>,<src> DescripciónMOVX A,@Ri
A,@DPTR
@Ri,A
@DPTR,A
A = (@Ri)
A = (@DPTR)
(@Ri) = A
(@DPTR) = A
MOVC A,@A+DPTR
A,@A+PC
A = (A + DPTR)
A = (A + PC)
En la instrucción MOVX siempre interviene el acumulador, ya sea como fuente o como destino. Con
esta instrucción sólo puede usarse direccionamiento indirecto a través del registro Ri (@Ri, con i = 0 ó1), o a través del registro DPTR. Mediante el registro @Ri sólo se puede acceder a direcciones de 8
bits, mientras que con el DPTR se puede acceder a cualquier posición del espacio de memoria externa
de datos de la familia MCS-51.
En los microcontroladores de la familia MCS-251 la instrucción MOVX también direcciona la
memoria externa en la región especificada por el registro DPXL, que se inicializa con el valor 01H
después de hacer un reset del microcontrolador.
© Los autores, 2001; © Edicions UPC, 2001.
4 Programación de las familias MCS-51 y MCS-251 89
La instrucción MOVC permite leer datos en la memoria de programa mediante el direccionamiento
indexado y el registro acumulador como destino del dato transferido. El registro DPTR o el registro
PC se emplean como dirección base de la instrucción, mientras que el acumulador se utiliza como
valor añadido, offset, para situarse en una determinada posición respecto de la dirección base. La
utilidad principal de la instrucción MOVC es para leer el contenido de tablas almacenadas en la
memoria de programa de los microcontroladores de la familia MCS-51. En este caso los registros
DPTR y PC almacenan la dirección de inicio de las tablas.
Ejemplo:
MOV A, #03H ; Pone en A el número 03H para leer el DATO_3 de la tabla
CALL TABLA;
La subrutina tabla tendría el siguiente aspecto y estaría situada en cualquier parte del programa:
TABLA: MOVC A, @A+PC ; Al ejecutarse pone en A el dato DATO_3
RET ; PC apunta a la dirección de la instrucción RET en memoria
DB DATO_1 ; Este dato se obtiene para A = 1
DB DATO_2 ; Este dato se obtiene para A = 2
DB DATO_3 ; Este dato se obtiene para A = 3
DB DATO_4 ; Este dato se obtiene para A = 4
........ ........
DB DATO_n ; Este dato se obtienen para A = n+1
En este ejemplo, la base de la tabla es el contador de programa PC, pero al no ser éste accesible de
forma directa por el programador, se toma como base la instrucción de retorno de la subrutina, RET.
Luego, en el momento en que se ejecuta la instrucción MOVC, el PC contiene la dirección de la
siguiente instrucción a ejecutar, por lo que lee uno de los datos que están por debajo de la instrucción
RET, dependiendo del valor del acumulador en el momento de ejecutar la instrucción MOVC. Este
tipo de tablas puede tener un máximo de 255 elementos (máxima capacidad del acumulador, puesto
que es un registro de 8 bits). En la instrucción MOVC el acumulador no puede ser igual a 0, ya que
durante la ejecución de MOVC el PC contiene la dirección de la instrucción RET, por lo que se
devolvería el código de la instrucción RET.
En la familia MCS-251 la instrucción MOVC permite leer posiciones de memoria de la región FF:.
4.3.6.4 Instrucciones PUSH y POP
Las instrucciones PUSH y POP se utilizan para introducir y extraer datos de la pila. El control de la
pila se realiza a través del registro SP, Stack Pointer, en la familia MCS-51 (tabla 4.17), y a través del
registro SPX, Extended Stack Pointer, en la familia MCS-251 (tabla 4.18). La instrucción PUSH
incrementa el Stack Pointer en una unidad (SP=SP+1) y copia el byte indicado en la pila. La
instrucción POP realiza el proceso inverso, extrayendo, de la posición apuntada por SP, un byte de la
pila, para luego decrementar en una unidad el Stack Pointer (SP=SP-1).
© Los autores, 2001; © Edicions UPC, 2001.
90 Microcontroladores MCS-51 y MCS-251
Tabla 4.17 Instrucciones de transferencia de datos en la pila comunes a las familias MCS-51 y MCS-251
Mnemónico <dest>,<src> DescripciónPUSH dir8 Mete el dato (dir8) en la pila.
POP dir8 Mete en (dir8) un dato de la pila.
Tabla 4.18 Instrucciones de transferencia de datos en la pila de la familia MCS-251
Mnemónico <dest>,<src> DescripciónPUSH #dato
#dato16
Rm
WRj
DRk
Mete el dato #dato en la pila.
Mete el dato #dato16 en la pila.
Mete el contenido de Rm en la pila.
Mete el contenido de WRj en la pila.
Mete el contenido de DRk en la pila.
POP Rm
WRj
DRk
Mete en Rm un dato de la pila.
Mete en WRj un Word de la pila.
Mete en DRk un Dword de la pila.
Con los microcontroladores de la familia MCS-51, que disponen de sólo 128 posiciones de memoria
RAM interna, se debe procurar que el puntero SP no sobrepase los 128 bytes, puesto que los datos
introducidos por encima de esta posición se perderían al no estar esta zona implementada físicamente
en el microcontrolador. La ejecución de la instrucción POP con el SP apuntando a una dirección de
memoria RAM interna no implementada, obtiene un valor indeterminado. Para las versiones de la
MCS-51 con 256 bytes de memoria RAM interna, el SP puede llegar hasta el valor FFH.
En todos los dispositivos de la familia MCS-51 la memoria reservada para la pila reside en la RAM
interna. En la familia MCS-251 la pila está ubicada en la región 00.
4.3.6.5 Las instrucciones de intercambio XCH y XCHD
Las instrucciones de intercambio XCH, Exchange, producen un intercambio de datos entre el
acumulador y el contenido de un registro o posición de memoria. La instrucción XCHD A, @Ri es
similar a la anterior, pero sólo se intercambia el nibble bajo del acumulador con el de una posición de
memoria. Estas instrucciones son de gran utilidad en el desplazamiento de dígitos en formato BCD. En
la tabla 4.19 están indicadas las instrucciones de intercambio.
Tabla 4.19 Instrucciones de intercambio comunes a las familias MCS-51 y MCS-251
Mnemónico <dest>,<src> DescripciónXCH A,Rn
A,dir8
A,@Ri
Intercambia A y Rn.
Intercambia A y (dir8).
Intercambia A y (@Ri).
XCHD A, @Ri Intercambia el nibble bajo de A y (@Ri ).
4.3.7 Instrucciones booleanas
Las instrucciones booleanas procesan la información a nivel de bit. Los bits que pueden direccionar
estas instrucciones están ubicados en la memoria RAM interna y en el área SFR. Las familias MCS-51
© Los autores, 2001; © Edicions UPC, 2001.
4 Programación de las familias MCS-51 y MCS-251 91
y MCS-251 comparten el mismo conjunto de instrucciones booleanas, con la única diferencia de que
sus áreas de direccionamiento a nivel de bit son diferentes. Las instrucciones booleanas (tabla 4.20) se
pueden agrupar dentro de cuatro categorías:
- Instrucciones que fuerzan un bit a 1 ó 0 lógico.
- Instrucciones lógicas.
- Instrucciones de transferencia de bits.
- Instrucciones de salto condicional.
Tabla 4.20 Instrucciones booleanas
Mnemónico <dest>,<src> DescripciónCLR CY
bit
Pone a cero el bit de acarreo.
Pone a cero el bit direccionado.
SETB CY
bit
Pone a uno el bit de acarreo.
Pone a uno el bit direccionado.
CPL CY
bit
Complementa el bit de acarreo.
Complementa el bit direccionado.
ANL CY, bit
CY, /bit
CY = CY AND (bit)
CY = CY AND (/bit)
ORL CY, bit
CY,/bit
CY = CY OR (bit)
CY = CY AND (/bit)
MOV CY, bit
bit, CY
CY = bit
bit = CY
JB bit, rel Salta si (bit) es 1.
JNB bit, rel Salta si (bit) no es 1.
JBC bit, rel Salta si (bit) es 1 y borra el bit.
Las instrucciones que fuerzan un bit a 1 o a 0 lógico son la instrucción SETB y la instrucción CLR. La
instrucción SETB, Set bit, pone a 1 lógico el bit direccionado, mientras que la instrucción CLR, Clearbit, pone a cero el bit direccionado.
Las instrucciones lógicas están formadas por las instrucciones ANL, ORL y CPL. La instrucción ANL
realiza la función and lógica, la instrucción ORL realiza la función or lógica y la instrucción CPL
realiza la función de negación lógica. En las instrucciones ANL y ORL también es posible tomar el bit
direccionado de forma complementada, utilizando para ello la notación /bit.
A nivel de transferencia de bits se utiliza la instrucción MOV. Esta instrucción se transfiere el valor de
cualquier bit (de las áreas direccionables a nivel de bit) hacia el bit de acarreo o viceversa. Por
ejemplo, el estado del bit 20H.0 de la memoria interna se puede poner en la patilla 0 de puerto P1,
mediante las siguientes instrucciones:
MOV CY, 20H.0 ;20H.0 es el bit 0 de la dirección 20H
MOV P1.0,CY ;Coloca el bit de acarreo en P1.0
En este ejemplo, el bit de acarreo realiza las funciones de acumulador, pues contiene uno de los
operandos que intervienen en la instrucción y guarda el resultado.
© Los autores, 2001; © Edicions UPC, 2001.
92 Microcontroladores MCS-51 y MCS-251
Las instrucciones de salto condicional ejecutan un salto de tipo relativo si el bit especificado en la
instrucción tiene un determinado estado. En la instrucción JB, Jump on bit, efectúa el salto si el bit
direccionado vale uno, mientras que la instrucción JNB, Jump on not bit, realiza el salto si el bit
direccionado vale cero. Con la instrucción JBC, Jump on bit then clear it, se produce el salto si el bit
vale uno y, tras el salto, el bit direccionado se fuerza a cero.
Se debe destacar que las instrucciones lógicas no incluyen la operación XRL (or exclusiva). Una
forma de realizar esta instrucción mediante software es la siguiente, donde se hace la función orexclusiva entre los bits 1 y 5 del puerto P1:
MOV CY, P1.1
JNB P1.5, continua ; Salta a continua si P1.5=0
CPL CY
continua: MOV… ; Continuación del programa
4.3.8 Instrucciones de control
Las instrucciones de control permiten cambiar la secuencia de ejecución de un programa y se pueden
agrupar en instrucciones de salto incondicional, instrucciones de salto condicional e instrucciones de
llamada y retorno de subrutina. Las instrucciones de control proporcionan al microcontrolador la
dirección de la siguiente instrucción a ejecutar. Esta dirección puede ser proporcionada de forma
explícita en la propia instrucción, o bien de forma implícita, como es el caso de la instrucción de
retorno de subrutina.
4.3.8.1 Instrucciones de salto incondicional
En la familia MCS-51 existen cinco tipos de salto incondicional: AJMP, LJMP, JMP @A+DPTR,
NOP y SJMP. La familia MCS-251 tiene estos cinco tipos de salto y, además, incorpora un tipo más:
EJMP. El conjunto de instrucciones de salto incondicional se muestra en la tabla 4.21, para la MCS-
51, y en la tabla 4.22, para la MCS-251.
Las instrucciones AJMP, LJMP, EJMP y JMP @A+DPTR realizan un salto a la dirección indicada en
la propia instrucción, mientras que en las instrucciones NOP y SJMP el salto que realizan es relativo al
valor del contador de programa.
Tabla 4.21 Instrucciones de salto incondicional comunes a las familias MCS-51 y MCS-251
Mnemónico <dest>,<src> DescripciónAJMP dir11 Salto absoluto.
LJMP dir16 Salto largo.
SJMP rel Salto relativo.
JMP @A+DPTR Salto indirecto a la dirección A + DPTR.
NOP Salto a la siguiente instrucción.
© Los autores, 2001; © Edicions UPC, 2001.
4 Programación de las familias MCS-51 y MCS-251 93
Tabla 4.22 Instrucciones de salto incondicional de la familias MCS-251
Mnemónico <dest>,<src> DescripciónEJMP addr24
@DRk
Salto extendido.
Salto extendido indirecto.
LJMP @WRj Salto largo indirecto.
La instrucción AJMP, Absolute Jump, cambia los 11 bits de menor peso del contador de programa por
la dirección de 11 bits especificada en la instrucción (de forma directa o a través de un registro). De
esta manera se puede saltar a cualquier dirección dentro del bloque de 2kbytes de memoria, donde estáubicada la instrucción de salto.
La instrucción LJMP, Long Jump, para la familia MCS-51, cambia los 16 bits del contador de
programa por la dirección que acompaña a la instrucción, mientras que para la familia MCS-251,
cambia los 16 bits de menor peso del contador de programa por la dirección que acompaña a la
instrucción. El rango del salto en este caso abarca los 64kbytes de la región donde está ubicada la
instrucción.
La instrucción EJMP, Extended Jump, cambia los 24 bits del contador de programa por la dirección
que acompaña a la instrucción. Esta instrucción permite saltar a cualquier dirección del espacio de
memoria de la familia MCS-251.
La instrucción JMP @A+DPTR realiza un salto a la dirección obtenida de la suma del contenido del
acumulador con el contenido del registro DPTR.
Ejemplo:MOV DPTR, #TABLA ; Pone en DPTR la dirección de comienzo de una tabla de saltos
MOV A, INDICE ; Pone acumulador el valor del CASO al que se desea saltar
RL A ; Se multiplica por dos el contenido del Acc
JMP @A+DPTR ; Salta a la tabla de saltos
TABLA: AJMP CASO_0 ; Si INDICE = 0 salta a CASO_0
AJMP CASO_1 ; Si INDICE = 1 salta a CASO_1
AJMP CASO_2 ; Si INDICE = 2 salta a CASO_2
AJMP CASO_3 ; Si INDICE = 3 salta a CASO_3
AJMP CASO_4 ; Si INDICE = 4 salta a CASO_4
4.3.8.2 Instrucciones de salto condicional
Todas las instrucciones de salto condicional son instrucciones de salto relativo. La tabla 4.23 muestra
el conjunto de instrucciones de salto condicional comunes a las familias MCS-51 y MCS-251,
mientras que la tabla 4.24 muestra las instrucciones de salto condicional que incorpora exclusivamente
la familia MCS-251.
En las instrucciones JC y JNC la condición de salto hace referencia al valor del bit de acarreo, y en las
instrucciones JZ y JNZ la condición de salto está relacionada con el contenido del acumulador.
La instrucción CJNE, Compare and jump if not equal, realiza la comparación de los dos operandosindicados en la instrucción y salta si no son iguales. El salto es de tipo relativo.
© Los autores, 2001; © Edicions UPC, 2001.
94 Microcontroladores MCS-51 y MCS-251
La instrucción DJNZ, Decrement and jump if not zero, decrementa el registro o posición de memoria
indicado en la instrucción y salta si el resultado no es cero. La instrucción DJNZ es muy útil en el
control de bucles. Para ejecutar un bucle N veces, se carga un contador con el valor N y se termina el
bucle con la instrucción DJNZ. El siguiente ejemplo ejecuta cuatro veces el bucle marcado con la
etiqueta INICIO.
Tabla 4.23 Instrucciones de salto condicional comunes a las familias MCS-51 y MCS-251
Mnemónico <dest>,<src> DescripciónJC rel Salta si el bit de acarreo es 1.
JNC rel Salta si el bit de acarreo es 0.
JZ rel Salta si el acumulador es 0.
JNZ rel Salta si el acumulador es distinto de 0.
CJNE A, dir8, rel
A, #dato, rel
Rn, #dato, rel
@Ri, #dato, rel
Compara A con el dato (dir8) y salta si no son iguales.
Compara A con #dato y salta si no son iguales.
Compara Rn con #dato y salta si no son iguales.
Compara (@Ri) con #dato y salta si no son iguales.
DJNZ Rn,rel
dir8,rel
Decrementa Rn y salta si no es 0.
Decrementa (dir8) y salta si no es 0.
Tabla 4.24 Instrucciones de salto condicional para la familia MCS-251
Mnemónico <dest>,<src> DescripciónJE rel Salta si es igual (si Z=1).
JNE rel Salta si no es igual (si Z=0).
JG rel Salta si es mayor que (si CY=Z=0).
JLE rel Salta si es menor o igual que (si Z=1 o CY=1).
JSL rel Salta si es menor que (con signo). (si N[OV).
JSLE rel Salta si es menor o igual que (con signo). (si Z=1 ó si N[OV.
JSG rel Salta si es mayor que (con signo). (si Z=0 y N=OV).
JSGE rel Salta si es mayor o igual que (con signo). (si N=OV).
Ejemplo:MOV R4,#04H ; Registro que determina el número de veces que se va a ejecutar el bucle
INICIO: MOV… ; Dirección de comienzo del bucle
........ ; Instrucciones del bucle
DJNZ R4,INICIO ; Si R4[0 salta a INICIO
MOV … ;Si R4=0 continúa con la instrucción siguiente. El bucle se ejecuta 4 veces
Las condiciones de salto de las instrucciones JE, JNE, JG, JLE, JSL, JSLE, JSG y JSGE, son
exclusivas de la familia MCS-251, y están relacionadas con el valor que toman los indicadores de los
registros de estado después de ejecutar una instrucción de comparación (CMP). Los bits de los
registros de estado que intervienen son el bit de acarreo, el bit de cero y el bit de signo.
Cuando se ejecuta una instrucción de comparación “CMP <des>,<src>” de dos números positivos se
puede obtener diversos resultados:
- Si <des> = <src> entonces el bit Z = 1
- Si <des> [ <src> entonces el bit Z = 0
© Los autores, 2001; © Edicions UPC, 2001.
4 Programación de las familias MCS-51 y MCS-251 95
- Si <des> > <src> entonces Z = 0 y CY = 0
- Si <des> ∑ <src> entonces Z = 1 o CY = 1
Cuando los números comparados tienen signo (son positivos o negativos) se deben analizar los bits de
estado Z, N y OV para determinar la relación existente entre los operandos:
- Si <des> < <src> entonces el bit N [ OV
- Si <des> ∑ <src> entonces el bit Z = 1 o N [ OV
- Si <des> > <src> entonces Z = 0 y N = OV
- Si <des> � <src> entonces N = OV
Existen instrucciones de salto condicional cuya condición de salto se corresponde con el valor que
adquieren los bits del registro de estado en los casos anteriormente considerados. En la tabla 4.25 se
indica la relación entre las instrucciones de salto condicional y el resultado de la comparación de dos
operandos.
Tabla 4.25 Instrucciones de salto condicional
Tipo de Relaciónoperando = > <
Positivo JE JNE JG JL JGE JLE
Con signo JSG JSL JSGE JSLE
4.3.8.3 Instrucciones de llamada y de retorno a subrutina
En la tabla 4.26 se muestran las instrucciones de salto y retorno de subrutinas para las familias MCS-
51 y MCS-251. Las instrucciones que son exclusivas de la familia MCS-251 se muestran en la tabla
4.27.
Tabla 4.26 Instrucciones de llamada y retorno de subrutina, comunes a las familias MCS-51 y MCS-251
Mnemónico <dest>,<src> DescripciónACALL dir11 Llamada a subrutina de tipo absoluto.
LCALL dir16 Llamada a subrutina tipo long.
RET Retorno de subrutina.
RETI Retorno de la rutina de servicio a la interrupción.
Tabla 4.27 Instrucciones de llamada y retorno de subrutina de la familia MCS-251
Mnemónico <dest>,<src> DescripciónLCALL @WRj Llamada a subrutina tipo long.ECALL @DRk
dir24
Llamada a subrutina tipo extendido.
ERET Retorno extendido de subrutina.
La instrucción ACALL, Absolute call, utiliza 11 bits para indicar la dirección de comienzo de la
subrutina. Mediante ACALL la subrutina debe comenzar dentro del mismo bloque de memoria de
2kbytes donde está ubicada la instrucción de llamada.
© Los autores, 2001; © Edicions UPC, 2001.
96 Microcontroladores MCS-51 y MCS-251
La instrucción LCALL, Long call, hace una llamada a subrutina con una dirección de 16 bits: la
subrutina puede encontrarse en cualquier lugar dentro del espacio de 64kbytes de memoria de
programa en la familia MCS-51 y dentro de la misma región de memoria para la familia MCS-251.
La instrucción ECALL, Extended Call, es exclusiva de la familia MCS-251 y permite realizar saltos a
subrutinas ubicadas en cualquier posición del espacio de memoria.
Al ejecutarse una instrucción de llamada a subrutina se guarda, de forma automática, en la pila la
denominada dirección de retorno, que es la dirección donde se encuentra ubicada la siguiente
instrucción del programa principal. El nombre de pila se le asigna a la zona de memoria donde el
microcontrolador almacenará la dirección de retorno. Para la MCS-51 la memoria de la pila es la zona
de memoria que está por encima del puntero de la pila SP. Por defecto el SP está inicializado a 07H,
por lo que, tras un reset, la zona de la pila es la zona de la memoria interna situada a partir de la
posición 07H (de la 08H a la 7FH, o de la 08H a la FFH). Sin embargo, el valor de SP se puede
modificar en cualquier momento mediante una instrucción MOV, y se puede definir cuál va a ser la
zona de la memoria interna que se utilizará como pila.
En el caso de las instrucciones ACALL y LCALL, para la familia MCS-51, la dirección de retorno es
de 2 bytes, correspondientes al registro PC, Program Counter; en el caso de la MCS-251, los dos
bytes que se guardan son los de menor peso del PC. Con la instrucción ECALL se guardan en la pila
los tres bytes del PC de la familia MCS-251.
Con las instrucciones ACALL y LCALL, para almacenar la dirección de retorno en la memoria de la
pila la CPU, se efectúa el siguiente proceso:
1. Interpreta el código de instrucción y se actualiza el valor de PC. PC=PC+3.
2. Incrementa el puntero de la pila, SP=SP+1, y se guarda el byte bajo de PC, PCLOW, en la
posición de memoria interna apuntada por SP.
3. Incrementa el puntero de la pila, SP=SP+1, y se guarda el byte alto de PC, PCHIGH, en la
posición de memoria interna apuntada por SP.
4. Pone en el contador de programa la dirección de salto de la subrutina. PC=Dir. subrutina.
Las subrutinas deben finalizar con la instrucción RET, Return, que recupera el valor de la dirección de
retorno guardada en la pila. Si el salto a la subrutina se ha realizado con la instrucción ECALL, seránecesario acabar la subrutina con la instrucción ERET, que permite recuperar los tres bytes del
contador de programa almacenados en la pila. Con la instrucción RET la CPU efectúa el siguiente
proceso:
1. Lee la posición de memoria que es apuntada por SP y pone el dato leído en el byte alto de
PC, PCHIGH.
2. Decrementa el puntero de la pila, SP=SP-1.
3. Lee la posición de memoria que es apuntada por SP y pone el dato leído en el byte bajo de
PC, PCLOW.
4. Salta a la dirección que apunta el contador de programa PC.
La instrucción RETI se utiliza para retornar desde una rutina de servicio de interrupción. La única
diferencia entre RET y RETI, consiste en que RETI comunica al sistema de control de interrupciones
que la interrupción en curso ha finalizado. Por lo demás, RETI actúa igual que la instrucción RET.
© Los autores, 2001; © Edicions UPC, 2001.
5 El modelo de programación 97
5 El modelo de programación
Bajo la definición de modelo de programación se agrupa el uso combinado de las instrucciones y del
conocimiento de la arquitectura interna del microcontrolador para formar rutinas de programa que den
solución a problemas que son comunes en la mayor parte de los diseños, como son la transferencia de
bloques de datos en la memoria externa de datos, la realización y consulta de tablas de datos, la
conversión de datos entre distintos formatos, rutinas aritméticas, etc.
En este capítulo se expondrán varias rutinas en lenguaje ensamblador que dan solución a distintos
problemas; pero debido al tratamiento simultáneo de las dos familias de microcontroladores que se
hace en esta obra, en primer lugar se expondrán las rutinas para la familia MCS-51, y en segundo
lugar se expondrán las rutinas derivadas para la MCS-251, considerando, para ello, los nuevos tipos
de direccionamiento y la flexibilidad en el acceso a los registros que tiene esta última familia.
5.1 Creación y consulta a tablas
En la programación de microcontroladores es frecuente utilizar tablas de datos en ciertos casos, como
en la conversión entre distintos formatos de datos, como de hexadecimal a ASCII, de binario a 7-
segmentos, etc. En estos casos se genera una tabla específica, donde cada elemento de la tabla esté
relacionado con el dato de entrada que se quiere convertir, de forma que el mismo dato de entrada se
emplea como índice para obtener el resultado de la conversión.
Mediante tablas se puede también obtener números primos según un índice o evitar el cálculo de
funciones matemáticas no lineales como las funciones trigonométricas o de cualquier otro tipo.
Como ejemplo se muestra la rutina de conversión de hexadecimal (00H-0FH) al formato ASCII; para
ello la tabla 5.1 muestra la correspondencia entre ambos formatos.
Tabla 5.1 Correspondencia entre un número hexadecimal (de 00H a 0FH) y su formato en ASCII
Binario 00H 01H 02H 03H 04H 05H 06H 07H 08H 09H 0AH 0BH 0CH 0DH 0EH 0FH
ASCII 30H 31H 32H 33H 34H 35H 36H 37H 38H 39H 41H 42H 43H 44H 45H 46H
;*******************************************************
;Subrutina Bin_ASCII
;Convierte un nº hexadecimal en ASCII
;Entrada y salida: A
;*******************************************************
Bin_ASCII: INC A
MOVC A,@A+PC
RET
DB 30H, 31H, 32H, 33H, 34H, 35H, 36H, 37H
DB 38H, 39H, 41H, 42H, 43H, 44H, 45H, 46H
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-25198
El núcleo de esta subrutina es la instrucción MOVC A, @A+PC. Cuando se ejecuta esta instrucción el
contador de programa se actualiza para apuntar a la instrucción siguiente, RET, pues la tabla de datos
está situada a continuación de la instrucción RET. El acumulador es un índice que apunta al dato en
concreto dentro de la tabla. Si A vale 0H, la subrutina retornará el dato 30H, puesto que en primer
lugar se ha incrementado en una unidad (instrucción INC A) y, por tanto, la suma del puntero
indexado, A+PC, apunta al primer dato de la tabla; si A vale 01H la subrutina retorna 31H, si vale
02H retorna 32H, etc.
5.2 Transferencia de bloques de datos
Resulta frecuente tener que trasladar bloques de datos entre distintas zonas de la memoria. De estos
bloques se suele tener su dirección base y su tamaño, aunque la dirección de destino puede ser fija o
variable, dependiendo del tipo de aplicación.
La solución a este problema es distinta según sea la familia de que se trate, pues el número de
punteros disponibles es diferente para la MCS-51 y para la MCS-251. Para la MCS-51 la transferencia
del bloque de datos se realiza en la memoria externa de datos, y tiene un único puntero de 16 bits que
consiste en el registro @DPTR. Con este puntero la solución del problema resulta difícil, puesto que
para trasladar un bloque de datos se necesitan al menos dos punteros de 16 bits, uno de origen y otro
de destino. Para salvar este obstáculo, se puede tratar de recurrir al uso de cualquiera de los dos
punteros restantes de 8 bits, @R0 y @R1, que se pueden emplear con la instrucción MOVX. Estos
punteros sitúan su valor en el puerto P0, byte bajo del bus de direcciones, cuando se ejecutan las
instrucciones de lectura y de escritura en la memoria de datos, (MOVX A,@Ri y MOVX @Ri,A).
Mientras tanto, en el puerto P2, byte alto del bus de direcciones, se sitúa el contenido del registro P2
del área de SFR. Por tanto, basta con colocar el byte alto de la dirección de destino del bloque de
memoria en el registro P2 para que salga por el puerto P2. A continuación se muestra una rutina que
transfiere un bloque de 50 bytes desde la dirección origen 1200H a la dirección destino 3500H.
;*************************************************
;Rutina TRANS (transferencia de datos)
;Punteros: DPTR, R0
;Tamaño: R7
;Modifica: DPTR, R0, R7, P2, A
;************************************************
TRANS: MOV DPTR, #1200H ;Dirección inicio
MOV R0,#00H ;Dirección destino
MOV P2,#35H
MOV R7,#50
B_TR: MOVX A,@DPTR ;Lee en origen
MOVX @R0,A ;Escribe en destino
INC DPTR ;Incrementa punteros
INC R0
DJNZ R7,B_TR ;Bucle R7 veces
La transferencia de datos, según el ejemplo mostrado, está limitada a una misma página, es decir, a
todas aquellas direcciones de 16 bits que tienen el mismo valor del byte alto de dirección, pues en el
puerto P2 se mantiene este valor mientras se ejecuta la rutina. Si en esta rutina el primer byte a
transferir del origen tiene como byte bajo de dirección el valor 00H, entonces el tamaño máximo de
datos que se pueden transferir es de 256 bytes; en caso contrario el tamaño máximo que se puede
transferir vendrá delimitado por el inicio de la página siguiente.
© Los autores, 2001; © Edicions UPC, 2001.
5 El modelo de programación 99
A continuación se muestra la misma rutina de transferencia solucionada con instrucciones de la
familia MCS-251. En este caso se ha utilizado un único registro tipo Word que combinado con
instrucciones de direccionamiento indexado permite acceder a las direcciones origen y destino. Se
puede observar cómo esta rutina es más compacta y funcional que la anterior.
;*****************************************************
;Rutina TRANS para la familia MCS-251
;Puntero: WR0
;Tamaño: R7
;Modifica: WR0, R3 y R7
;*****************************************************
TRANS: MOV WR0,#1200H ;Dirección origen
MOV R7,#50 ;Número de datos a transferir
B_TR: MOV R3,@WR0 ;Lee dato en origen
MOV @WR0+2300H,R3 ;Escribe en destino
INC WR0 ;Incrementa el puntero
DJNZ R7,B_TR ;Bucle R7 veces
RET
5.3 Funciones booleanas
Los microcontroladores de las familias MCS-51 y MCS-251 están capacitados para realizar funciones
booleanas, tanto a nivel de bit como a nivel de byte, y tienen en común el mismo juego de
instrucciones booleanas. A nivel de bit, el microcontrolador puede realizar funciones lógicas y realizar
otras tareas como leer el estado de un teclado, activar un relé, etc.
A continuación se expone un ejemplo de aplicación de las instrucciones booleanas que consiste en la
evaluación de las funciones lógicas Y0 e Y1 (figura 5.1), con tres variables de entrada cada una, X0,
X1 y X2. Las entradas se han conectado a los terminales P1.0, P1.1 y P1.2, y las funciones de salida
se han conectado a P1.3 y P1.4.
;***********************************
;Rutina F_BOL
;Entradas: P1.0, P1.1, P1.2
;Salidas: P1.3, P1.4
;Modifica: C, B.0
;*********************************
X0 EQU P1.0 ;entradas
X1 EQU P1.1
X2 EQU P1.2
Y0 EQU P1.3 ;salidas
Y1 EQU P1.4
F_BOL: MOV C,/X0
ANL C,X1
ORL C,X0;
MOV Y0,C ;obtiene Y0
MOV C,X0
ORL C,X1
MOV B.0,C
MOV C,X0
ORL C,X2
ANL C,B.0
MOV Y1,C ;obtiene Y1
SJMP F_BOL
y0
y1
x0
x3
x1
Funciones lógicas
P1.0
P1.1
P1.2
P1.3
P1.4
x0x1x3y0y1
Fig. 5.1 Funciones lógicas y conexionado con elmicrocontrolador
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251100
5.4 Retardos de tiempo
La realización de retardos es una de las tareas más comunes en el desarrollo de aplicaciones, puesto
que en muchos casos se deben activar dispositivos durante un tiempo determinado. Para realizar
retardos de manera precisa se pueden emplear recursos del hardware del microcontrolador, como los
temporizadores Timer0, Timer1 y Timer2, o el dispositivo PCA; en este caso se deben configurar y
utilizar interrupciones de manera adecuada. Por otro lado, también se pueden realizar retardos
mediante rutinas de software, para aquellos casos en los que no se requiere de precisión en los tiempos
generados; pueden entonces destinarse los temporizadores y la PCA a otras tareas más relevantes. De
todas formas, se debe mencionar que el uso de retardos mediante software implica una explotación
poco eficiente del microcontrolador, puesto que éste pasa una buena parte de su tiempo realizando el
retardo.
Un retardo por software se hace básicamente a través de uno o varios bucles anidados, donde el
número de anidamientos depende del tiempo de retardo requerido. Como ejemplo se propone una
rutina de retardo con dos anidamientos, donde el número de veces que se ejecuta cada bucle depende
de los registros R7 y R6. Este ejemplo es válido tanto para la familia MCS-51 como para la MCS-251.
;*************************************************
;Subrutina RETARDO
;Registros afectados: R7, R6
;************************************************
RETARDO: MOV R7,#10
L1: MOV R6,#100
L2: DJNZ R6,L2 ;Bucle interno
DJNZ R7,L1 ;Bucle externo
RET
El bucle interno formado por el registro R6 está dentro del bucle externo formado por el registro R7;
luego a cada vuelta del bucle externo le corresponden 100 ejecuciones del bucle interno. De esta
manera, sabiendo que para la MCS-51 el tiempo de ejecución de las instrucciones MOV y DJNZ es de
uno y dos ciclos máquina, respectivamente, y que un ciclo máquina equivale a 1÷s con una frecuencia
de reloj de 12MHz, se puede determinar el tiempo exacto que tardará en ejecutarse la subrutina de
retardo. La figura 5.2 muestra el diagrama de tiempos de la subrutina e indica también el cómputo del
tiempo resultante -eq. (5.1).
MOV (1 ÷s)
MOV (1 ÷s)
DJNZ (2 ÷s)
DJNZ (2 ÷s)
RET (2 ÷s)
R6
veces
R7
veces
Fig. 5.2 Diagrama de tiempos de la rutina de retardo
[ ] s2.03327R26R211t R ÷∑�θ�θ��∑ (5.1)
( )
( ) s16,009.1s1s2
1s17R
7Rs2
1s16Rs
3
1s
3
1t R
÷∑÷�÷�÷≅�
�θ4.
÷�÷≅�÷�÷∑
(5.2)
© Los autores, 2001; © Edicions UPC, 2001.
5 El modelo de programación 101
Para la familia MCS-251 el cálculo del tiempo realizado es diferente (eq. (5.2)), puesto que trabajando
en el modo fuente, la instrucción “MOV Rn,#data” tarda cuatro períodos de reloj en ejecutarse, la
instrucción “DJNZ Rn,rel” posee dos tiempos de ejecución distintos: 12 períodos de reloj si se cumple
la condición de salto y 6 períodos en caso contrario; y, por último, el microcontrolador invierte 12
períodos de reloj en ejecutar la instrucción RET.
El tiempo máximo que se puede obtener con una rutina de dos bucles anidados es de 130.818÷s para
la MCS-51, que equivale a unos 0.13 segundos, y de 65.238,33÷s para la MCS-251, poniendo a FFH
los registros R6 y R7. Si se desean obtener tiempos mayores es necesario realizar más anidamientos.
Una alternativa a la rutina anterior consiste en la siguiente rutina:
;************************************************
;Subrutina RETARDO2
;Registros afectados: R7, R6
;************************************************
RETARDO2: MOV R7,#0
MOV R6,#0
L1: DJNZ R6,L1 ;Bucle interno
DJNZ R7,L1 ;Bucle externo
RET
A primera vista da la impresión de que los bucles de esta rutina dan cero vueltas, pues R6 y R7 valen
cero. Pero si se observa en detalle la ejecución de la instrucción DJNZ, resulta que esta instrucción
primero decrementa el registro indicado, y luego examina la condición de salto. Por tanto, si el
registro vale cero, al decrementarse pasa a valer FFH, (00H-01H=FFH), y se ejecuta el bucle FFH+1 o
256 veces. Realizando el diagrama de tiempos para esta rutina, el tiempo que se obtiene es de
13.1588÷s para la MCS-51 y de 65.665,16÷s para la MCS-251, para una frecuencia de reloj de
12MHz.
5.5 Suma y resta de datos
La suma y resta de datos es sencilla de hacer mediante las instrucciones ADD, ADDC y SUBB,
cuando los datos que intervienen son de 1 byte, pero resulta más complicada cuando el tamaño de los
datos es mayor de 1 byte, es decir, cuando se tienen que sumar datos de 2, 3 ó 4 bytes de tamaño.
;************************************************
;Subrutina SUMA_N (Suma de números de N bytes)
;Entrada: Punteros: R0 a X, R1 a Y. R7: Tamaño
;Salida: El resultado sustituye al operando X
;Modifica: A, R0, R1, R7, C
;************************************************
SUMA_N: CLR C ;Borra acarreo
BUC_SUM: MOV A,@R0 ;Lee operando X
ADDC A,@R1 ;Suma X con Y
MOV @R0,A ;Resultado sustituye a X
INC R0 ;Incrementa punteros
INC R1
DJNZ R7,BUC_SUM ;Repite 7 veces
RET
99H
69H
02H1
Carry
+
ABH
2CH
D8H0
Carry
+
3DH
5EH
9BH0
Carry
+
1ª Suma2ª Suma3ª Suma
Fig. 5.3 Suma de dos datos de 3 bytes de tamaño
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251102
Para resolver este problema se realiza una subrutina que es capaz de sumar datos de cualquier tamaño
en bytes, aunque, para este caso, será suficiente con que sume datos de 3 bytes de tamaño. Los datos
que se deberán sumar son X=2DAB99H y Y=5E2C69H en formato hexadecimal y están almacenados
a partir de las posiciones de la memoria interna 60H y 70H, respectivamente; es decir, el byte de
menor peso del dato X (99H) estará ubicado en la dirección 60H, su byte intermedio (ABH) en la 61H
y su byte más significativo (2DH) en la 62H; lo mismo se hace con el dato Y a partir de la dirección
70H de la memoria interna.
Para ejecutar esta subrutina se tienen primero que poner las direcciones 60H y 70H en los registros R0
y R1; ello se debe efectuar antes de llamar a la subrutina, por ejemplo
MOV R0,#60H ;Pone dirección de X en R0
MOV R1,#70H ;Pone dirección de Y en R1
MOV R7,#3 ;Pone tamaño del dato en R7
LCALL SUMA_N ;Llama a la subrutina
La manera de operar de la subrutina se muestra claramente en la figura 5.3. La subrutina hace tres
sumas consecutivas y obtiene los datos en cada una de ellas a través de los punteros @R0 y @R1, que
se actualizan con la instrucción INC. Esta subrutina es capaz de sumar datos de 4, 8 ó 16 bytes, con la
condición previa de situar los datos en la memoria interna y poner en R0, R1 y R7 los valores
adecuados.
La razón de que el resultado generado en las operaciones sustituya a uno de los operandos, estriba en
que para la MCS-51 tan sólo se dispone de los punteros @R0 y @R1; se carece de un tercer puntero
necesario para dejar el resultado en otras direcciones. El resto de los registros no pueden ser
empleados como punteros, pero sí como variables intermedias, pasando su contenido a R0 o R1, y
conseguir, así, que hagan de punteros por medio de estos registros. Cabe resaltar que para la MCS-251
este tipo de problemas no existe, pues cualquiera de sus registros puede hacer de puntero.
Las instrucciones de la familia MCS-251 permiten ejecutar la rutina de suma con un mayor rango de
direcciones y guardar el resultado en direcciones distintas a las de ubicación de los operandos. El
ejemplo anterior de suma de dos datos de 3 bytes se puede resolver empleando las instrucciones de la
familia MCS-251 que pueden sumar datos de hasta 4 bytes:
;*****************************************************************
;Rutina SUM_4 (Suma de datos de 4 bytes para la familia MCS-251)
;Puntero: WR8
;Datos: DR0 y DR4
;*****************************************************************
SUM_4: MOV WR0,@WR8 ;Carga el dato en el registro DR0
MOV WR2,@WR8+2H
B_TR: MOV WR4,@WR8+10d ;Carga el otro dato en el registro DR4
MOV WR6,@WR8+12d
ADC DR0,DR4 ;Suma los dos datos
MOV @WR8+20d,WR0 ;Carga el resultado en memoria
MOV @WR8+22d,WR2
RET
El anterior programa suma dos datos de 4 bytes almacenados en las direcciones 60H y 70H a las que
se accede con el registro WR8 utilizando el direccionamiento indexado. El mismo registro permitirá
© Los autores, 2001; © Edicions UPC, 2001.
5 El modelo de programación 103
guardar el resultado de la suma a partir de la dirección 80H. Para ejecutar esta subrutina previamente
se debe colocar la dirección inicial del dato en WR8.
MOV WR8,#0060H ;Carga el puntero con la dirección inicial del dato
LCALL SUM_4bytes ;Llamada a la subrutina de suma de 4 bytes
Si el formato de los números que se quiere sumar es BCD, basta con añadir la instrucción de ajuste
decimal, DA A, tras la instrucción de suma ADDC, para obtener el resultado también en formato
BCD, lo que se muestra en la siguiente subrutina. En este caso, si X=1969H y Y=1050H dará por
resultado Z=0919H.
;************************************************
;Subrutina SUMA_N (Para datos en formato BCD)
;Entrada: Punteros: R0 a X, R1 a Y. R7: Tamaño
;Salida: El resultado sustituye al operando X
;Modifica: A, R0, R1, R7, C
;************************************************
SUMA_N: CLR C ;Borra Carry
BUC_SN: MOV A,@R0 ;Lee dato X
ADDC A,@R1 ;Suma X con Y
DA A
MOV @R0,A ;Resultado sustituye a X
INC R0 ;Incrementa punteros
INC R1
DJNZ R7,BUC_SN ;Repite R7 veces
RET
En cuanto a la resta de datos de longitud mayor que un byte, se puede realizar una subrutina con este
propósito simplemente reemplazando la instrucción de suma por la instrucción de resta, SUBB, en las
subrutinas anteriores.
5.6 Contador en BCD
Es habitual en muchas aplicaciones realizar rutinas que hagan la función de contador en formato
binario o BCD. Estas rutinas tienen por objetivo contabilizar objetos, eventos, pulsos de una señal
cuadrada, etc. Los contadores en formato binario son sencillos de realizar, ya que hay instrucciones
específicas para ello como INC, DEC, ADD, ADDC y SUBB; por el contrario, los contadores en
formato BCD no son tan evidentes de hacer, pues la ALU del microcontrolador contiene un sumador
binario, pero no un sumador en base decimal. Por otro lado, debe tenerse en cuenta que en aquellas
aplicaciones donde el resultado de la cuenta se muestra a un operario, éste debe aparecer en formato
decimal, para que se pueda interpretar de manera conveniente.
El siguiente ejemplo muestra una subrutina para realizar un contador en BCD de cuatro cifras, es
decir, que el máximo valor que puede alcanzar es 999. Cada cifra del contador está contenida en un
registro: las unidades están en el registro R0, las decenas en R1 y las centenas en R2. De esta forma,
para visualizar posteriormente el valor del contador, sólo se ha de volcar cada uno de los registros en
el visualizador1
numérico correspondiente, ya sea de tipo LED o LCD.
1
Un visualizador numérico suele estar formado por varios dígitos tipo LED de 7 segmentos o de 16 segmentos, o por una
pantalla de cristal de cuarzo (LCD).
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251104
;************************************************
;Subrutina CONTA
;Registros afectados: R0, R1, R2
;************************************************
CONTA: CJNE R0,#9,UNIDAD ;Compara unidad
CJNE R1,#9,DECENA ;Compara decena
CJNE R2,#9,CENTENA ;Compara centena
MOV R0,#0 ;Al ser 999 pone a 000
MOV R1,#0
MOV R2,#0
RET
UNIDAD: INC R0 ;Incrementa unidades
RET
DECENA:MOV R0,#0 ;Pone a 0 las unidades
INC R1 ;Incrementa decenas
RET
CENTENA: MOV R0,#0 ;Pone a 0 unidades y decenas
MOV R1,#0
INC R2 ;Incrementa centenas
RET
R0=9 R1=9 R2=9
CONTA
R0=R0+1R0=0
R1=R1+1
R0=0
R1=0
R2=R2+1
RET
SI SI SI
NONO NO
R0=0
R1=0
R2=0
Fig. 5.4 Flujograma de la subrutina CONTA
El flujograma de la subrutina CONTA (figura 5.4), se observa cómo primero se comprueba si las
unidades han llegado a 9; de no ser así se incrementa R0. En caso afirmativo, se incrementan las
decenas y las unidades se ponen a cero. Procediendo de esta manera con el resto de dígitos, se
completa la subrutina del contador, que se puede extender fácilmente a un mayor número de dígitos.
A la hora de hacer una subrutina para descontar, el proceso es idéntico al mostrado en la figura 5.4,
pero cambiando la condición existente por la de comprobar si las unidades, decenas y centenas son
iguales a cero; los registros, en lugar de ponerse a cero, se ponen a 9, tal y como se indica en la figura
5.5. A continuación se muestra la subrutina para descontar:
;************************************************
;Subrutina DECRE
;Registros afectados: R0, R1, R2
;************************************************
DECRE: CJNE R0,#0,D_UNI ;Compara unidad
CJNE R1,#0,D_DECE ;Compara decena
CJNE R2,#0,D_CENT ;Compara centena
MOV R0,#9; ;Al ser 000 pone a 999
MOV R1,#9
MOV R2,#9
RET
D_UNI: DEC R0 ;Decrementa unidad
RET
D_DECE: MOV R0,#9 ;Pone a 9 unidad
DEC R1 ;Decrementa decena
RET
D_CENT: MOV R0,#9 ;Pone a 9 unidad
MOV R1,#9 ;Pone a 9 decena
DEC R2 ;Decrementa centena
RET
R0=0 R1=0 R2=0
DECRE
R0=R0-1R0=9
R1=R1-1
R0=9
R1=9
R2=R2-1
RET
SI SI SI
NONO NO
R0=9
R1=9
R2=9
Fig. 5.5 Flujograma de la subrutina DECRE
En el caso de producirse un rebasamiento de los valores máximo y mínimo en las subrutinas CONTA
y DECRE, respectivamente, se ha optado por actualizar el valor de todos los registros al valor inicial
000 y 999, respectivamente.
Otra manera de realizar un contador en formato BCD, consiste en emplear de manera hábil la
© Los autores, 2001; © Edicions UPC, 2001.
5 El modelo de programación 105
instrucción de ajuste decimal DA A. Para ello, supóngase que se desea realizar un contador de cuatro
cifras en formato BCD, y que las posiciones de memoria interna 40H y 41H harán de contador; los
cuatro bits bajos de 40H serán las unidades y sus cuatro bits altos, las decenas, los cuatro bits bajos de
41H serán las centenas y sus cuatro bits altos la unidad de millar del contador. Con un contador de
cuatro cifras en las posiciones 40H y 41H, se puede llegar hasta un valor de 9999, es decir, ambas
posiciones contienen el valor 99H. A continuación se muestra la rutina CONTA que hace esta
función:
;********************************************************
;Subrutina CONTA
;Registros afectados: A, R0, R7, C, (40H), (41H)
;********************************************************
CONTA: MOV R7,#2 ;R7 controla el bucle
MOV R0,#40H ;Pone dirección en puntero
SETB C ;Pone C=1
BUC_CT: MOV A,@R0 ;Lee
ADDC A,#0 ;Suma con acarreo
DA A ;Ajuste decimal
MOV @R0,A ;Guarda
INC R0 ;Incrementa puntero
DJNZ R7,BUC_CT ;Repite R7 veces
RET
Esta rutina incrementa en una unidad el valor de las posiciones 40H y 41H. La rutina, al principio,
incrementa 40H de 00H a 01H, de 01H a 02H, y así sucesivamente hasta llegar a 09H, pues la
instrucción de ajuste decimal no modifica el valor del acumulador tras la instrucción de suma.2
En el
siguiente incremento el valor de 40H pasa de 09H a 0AH, por lo que la instrucción DA A transforma
este dato en 10H, al ser el nibble bajo mayor que 9. En los siguientes incrementos la instrucción DA A
no modificará el acumulador, al menos hasta que llegue al valor de 1AH, momento en el cual lo
transformará en 20H. Así, la instrucción de ajuste decimal actúa en los instantes en que el acumulador
vale 1AH, 2AH, 3AH, …, 9AH; este último caso lo transforma en 00H y pone el bit de acarreo a uno,
C=1, de manera que incrementa en una unidad el contenido de la posición de 41H, pasando el
contador a valer 0100H.
La rutina CONTA basada en la instrucción de ajuste decimal tiene un menor tamaño que la anterior y,
además, permite extender el máximo valor del contador a cualquier tamaño; basta, para ello, con
aumentar el número de bytes del contador, aumentado el número de posiciones de memoria que
ocupa. Por el contrario, no es posible realizar del mismo modo una rutina que decremente el valor del
contador, debido a que la instrucción de ajuste decimal no puede ir asociada a la instrucción SUBB de
resta.
5.7 Multiplicación y división de datos de 16 bits
Para llevar a cabo la multiplicación de dos números de 16 bits se deben realizar primero dos
multiplicaciones de un número de 8 bits por otro de 16 bits (XL por YH-YL, y XH por YH-
YL)(figura 5.6a), que proporcionan dos resultados intermedios de 24 bits, ZN2-ZN0 al multiplicar XL
2
Consultar la instrucción de ajuste decimal en el apartado 4.3.4.5.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251106
por YH-YL y ZM2-ZM0 al multiplicar XH por YH-YL. Estos resultados intermedios se suman para
obtener un resultado final de 32 bits (ZS3-ZS0)(figura 5.6b). En consecuencia, la multiplicación de
dos números de 16 bits estará basada en una subrutina, MUL8_16, que multiplica un número de 8 bits
con un número de 16 bits.
La subrutina MUL8_16 tiene un primer operando XL de 8 bits almacenado en R1 y un segundo
operando de 16 bits; el byte alto está almacenado en R2 y el byte bajo en R3. La subrutina genera un
resultado de 24 bits que se sitúa en los registros R5, R6 y R7, donde se almacenan los resultados ZT2,
ZT1 y ZT0, respectivamente.
;**********************************************
;Subrutina MUL8_16 (8bits x 16 bits, XL x YH-YL)
;Entrada: R1=XL, R2=YH, R3=YL.
;Salida: 24 bits. R7=ZT0, R6=ZT1 y R5=ZT2.
;Modifica: A, B, C
;**********************************************
MUL8_16: MOV A,R1 ;Lee XL
MOV A,R3 ;Lee YL
MUL AB ;(XL x YL)
MOV R7,A ;Salva ZT0
MOV R6,B ;Salva ZN1
MOV A,R1 ;Lee XL
MOV B,R2 ;Lee YH
MUL AB ;(XL x YH)
ADD A,R6 ;(ZM0+ZN1)
MOV R6,A ;Salva ZT1
CLR A ;Borra A
ADDC A,B ;(ZM1+acarreo)
MOV R5,A ;Salva ZT2
RET
XL
YH YL
ZM0ZM1
(x)
(+)
ZN0ZN1
a)
ZT0ZT1ZT2
XH XL
YH YL
ZM0ZM1ZM2
(x)
(+)
ZN0ZN1ZN2
ZS0ZS1ZS2ZS3
b)
Fig. 5.6 a) Multiplicación de un dato de 8 bits (XL)por otro de 16 bits (YH-YL). b) Multiplicación de dos
datos de 16bits (XH-XL y YH-YL)
La subrutina MUL16 multiplica dos datos de 16 bits cada uno. El primer y el segundo operandodeben estar ubicados en los registros R0, R1, R2 y R3, donde se sitúan XH, XL, YH e YL,
respectivamente. La subrutina genera un resultado de 32 bits, ZS0, ZS1, ZS2 y ZS3, que se coloca en
los registros R7, R6 , R5 y R4, respectivamente.
;************************************************
;Subrutina MUL16 (16bits x 16 bit, YH-YL x XH-XL)
;Entrada: R0=XH, R1=XL, R2=YH, R3=YL
;Salida: 32 bits. R7=ZS0, R6=ZS1, R5=ZS2, R4=ZS3
;Modifica: A, B, Registros R7 a R1 del banco 1
;************************************************
MUL16: LCALL MUL8_16 ;(XL x YH-YL)
SETB RS0 ;Cambia al banco 1
MOV R1,00H ;Lee XH
MOV R2,02H ;Lee YH
MOV R3,03H ;Lee YL
LCALL MUL8_16 ;(XH x YH-YL)
CLR C ;Borra acarreo
CLR RS0 ;Cambia a banco 0
MOV A,R6 ;Lee ZN1
ADD A,0FH ;(ZN1+ZM0)
MOV R6,A ;Salva ZS1
MOV A,R5 ;Lee ZN2
ADDC A,0EH ;(ZN2+ZM1+C)
MOV R5,A ;Salva ZS2
CLR A ;Borra A
ADDC A,0DH ;(ZM2+C)
MOV R4,A ;Salva ZS3
RET
© Los autores, 2001; © Edicions UPC, 2001.
5 El modelo de programación 107
La subrutina MUL16 utiliza el banco 0 y el banco 1 de registros para almacenar los resultados
intermedios de la subrutina MUL8_16. La primera multiplicación, XL x YH-YL, utiliza el banco 0 de
registros y la segunda multiplicación, XH x YH-YL, utiliza el banco 1 de registros. Se cambia de
banco de registros con el bit RS0 del registro de estado PSW. Al final de la subrutina MUL16 se
trabaja con los registros del banco 0 y se accede a los registros del banco 1 mediante direccionamiento
directo.
Para usar la subrutina MUL16 se debe inicializar el puntero de la pila, SP, al menos con una dirección
superior a la dirección más alta del banco 1 de registros, ya que las instrucciones CALL, PUSH y POP
escriben en las posiciones apuntadas por este puntero. Se trata de evitar, en consecuencia, que las
instrucciones mencionadas escriban accidentalmente sobre el banco 1. El valor del SP se puede
modificar fácilmente con la siguiente instrucción: MOV SP,#0FH.
La familia MCS-251 dispone de instrucciones de multiplicación de datos de 2 bytes, de forma que la
subrutina MUL16 queda reducida, en la MCS-251, a una simple instrucción:
MUL WR0,WR2
Esta instrucción multiplica el contenido de los registros R1 y R0 por el contenido de los registros R3 y
R2, y guarda el resultado de 32 bits en los registros R3, R2, R1 y R0.
De la misma forma que la expuesta, se pueden realizar subrutinas de multiplicación de 24x16 bits,
24x24 bits, 32x16 bits y 32x32 bits, dependiendo de las necesidades de la aplicación que se quiera
realizar.
La división de datos numéricos sin signo de 16 bits de longitud se puede efectuar mediante un proceso
iterativo en el cual de debe multiplicar el dividendo por 2-i, donde i está comprendido entre 0 y 15, y
se debe restar el resultado del divisor (figura 5.7). La primera multiplicación se realiza para i=15, por
lo que desplazan XH y XL 16 bits hacia la derecha, -inicialmente XH está en R0 y XL en R1; luego se
copia XH en R2 y XL en R3, y se pone R0 y R1 a cero, con lo que el dividendo pasa a estar formado
por los registros R0, R1, R2 y R3, 32 bit en total, o sea, es una multiplicación por 2-16
-, y se rota el
dividendo obtenido una posición hacia la izquierda, consiguiendo que la multiplicación sea por 2-15
.
Posteriormente, se restan los 16 bits altos del dividendo, R0 y R1, con el divisor, es decir:
divisor)2 x (dividendo altos bits 16
-i ≅
Esta operación se efectúa para comprobar si los 16 bits altos del dividendo son mayores, menores o
iguales que los 16 bits del divisor, hecho que se refleja en el valor del bit de acarreo, pues en la resta
se pueden dar dos casos:
1. El bit C se pone a 1, lo que implica: divisor)2 x (dividendo altos bits 16
-i
2. El bit C de pone a 0, lo que implica: divisor)2 x (dividendo altos bits 16
-i
En el primer caso se complementa el bit de acarreo y se introduce en el cociente, CH y CL, mediante
una rotación con acarreo hacia la izquierda. En el segundo caso se sustituye XH y XL por el resultado
de la resta, en ZH y ZL, se complementa el bit de acarreo y se introduce éste en los registros del
cociente.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251108
Este proceso se itera 16 veces hasta que i=0, entonces el resto de la división, que se halla situado en
los mismos registros XH y XL, se coloca en los registros R2 y R3, respectivamente, y el cociente de la
división (registros CH y CL), se coloca en los registros R0 y R1, respectivamente.
;******************************************************
;Subrutina DIV16 División de 16 bits (XH-XL)/(YH-YL)
;Entrada: Dividendo: XH=R0 y XL =R1. Divisor: YH=R4 y YL=R5.
;Salida: Cociente: CH=R0 y CL=R1. Resto: ZH=R2 y ZL=R3
;Modifica: A, R0, R1, R2, R3, R7. Direcc. 08H, 09H, 0AH y 0BH.
;******************************************************
;Variables temporales:
XL EQU 01H ;XL en R1 (dir. directo)
XH EQU 00H ;XH en R0
YL EQU 05H ;YL en R5
YH EQU 04H ;YH en R4
CL EQU 09H
CH EQU 08H
ZL EQU 0BH
ZH EQU 0AH
DIV16: MOV A,YL ;Lee dividendo
ORL A,YH ;Comprueba si éste es cero
JNZ DIV_ON ;Si es cero retorna
SETB OV ;Pone ante bit OV a 1
RET
DIV_ON: MOV R3,XL ; -(XH-XL) x 2-16 -
MOV R2,XH
MOV XL,#0 ;XH=XL=00H
MOV XH,#0
MOV CL,#0 ;Cociente
MOV CH,#0 ;CH=CL=00H
MOV ZL,#0 ;Resto
MOV ZH,#0 ;ZH=ZL=00H
MOV R7,#16 ;Itera 16 veces
BUC_DIV: CLR C
LCALL ROTA ;Rota 1 pos. izquierda (2-i )
LCALL SUB16 ;(dividendo x 2-i)16 bits - divisor
JC XmenorqY ;si (dividendo x 2-i)16 bits < divisor
MOV XL,ZL ;En caso contrario
MOV XH,ZH ;XH=ZH, XL=ZL
XmenorqY: LCALL ROTAC
DJNZ R7,BUC_DIV ;Hasta 16 veces
MOV R3,XL ;División finalizada
MOV R2,XH ;Pone Resto en R2 y R3.
MOV R0,CH ;Pone cociente en R0 y R1.
MOV R1,CL
CLR OV
RET
;******************************************************
; ROTAC
;******************************************************
ROTAC: CPL C ;Complementa acarreo
MOV A,CL ;Rota cociente 1 bit
RLC A ;hacia la izquierda
MOV CL,A
MOV A,CH
RLC A
MOV CH,A
RET
R7=0
DIV16
(dividendo x 2-16
)
R7=16
R7=R7-1
RET
divisor=0OV=1
RET
C=0. Rota dividendo 1
posición izquierda
(dividendo x 2-i )16 bits altos
<divisor
XH=ZH
XL=ZL
Rota Cociente
1 pos. izquierda
SI
SI
SI
NO
NO
NO
Fig. 5.7 Flujograma de la subrutina DIV16
© Los autores, 2001; © Edicions UPC, 2001.
5 El modelo de programación 109
;******************************************************************
;SUB16 -Resta de 16 bits (XH-XL)-(YH-YL)
;Entrada: XH=R0, XL=R1, YH=R2, YL=R3.
;Salida: ZH en 0AH y ZL en 0BH
;******************************************************************
SUB16: CLR C ;Subrutina de resta
MOV A,XL ;(XH-XL) - (YH-YL)
SUBB A,YL ;Resultado en ZH y ZL
MOV ZL,A
MOV A,XH
SUBB A,YH
MOV ZH,A
RET
;******************************************************
; ROTA
;******************************************************
ROTA: MOV A,R3 ;Subrutina de rotación del
RLC A ;dividendo 1 bit hacia la derecha
MOV R3,A
MOV A,R2
RLC A
MOV R2,A
MOV A,XL
RLC A
MOV XL,A
MOV A,XH
RLC A
MOV XH,A
RET
La familia MCS-251 puede realizar una división de 16 bits tan sólo con una instrucción: DIV
WR0,WR4. Esta instrucción divide el contenido de WR0 por el contenido de WR4, poniendo el
cociente resultante en WR2 y el resto en WR0.
5.8 Suma y resta de datos con signo
La suma y resta de números con signo se realiza de forma similar a la suma y resta de números sin
signo. La única diferencia estriba en que el bit de overflow, OV, se pone a 1 cuando el resultado de las
operaciones está fuera de rango.3
En la suma y resta de datos de 16 bits el bit OV se pone a 1 si la
operación con los bytes altos de los operandos el resultado está fuera de rango. En consecuencia, las
rutinas realizadas de suma y resta de números sin signo se pueden emplear para el caso de números
con signo, con la salvedad que tras la operación hecha se ha de comprobar el estado del bit de
overflow, por si el resultado está fuera de rango.
5.9 Multiplicación y división de 16 bits con signo
La multiplicación y división de datos con signo resulta más fácil de llevar a cabo si los datos están en
un formato de valor absoluto y signo, de manera que la operación se pueda realizar utilizando los
algoritmos del apartado 5.7, obteniendo el signo del resultado a partir del signo de los operandos.
3
Véase el apartado 4.3.4.1, instrucciones de suma y resta.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251110
Luego, si el formato de los datos está en complemento a dos, éstos se deben pasar al formato módulo-
signo, se debe realizar la multiplicación o división de los operandos y pasar el resultado a
complemento a dos.
Al considerar el bit de signo de los operandos se observa que el resultado binario de la multiplicación
coincide con la función booleana XOR (figura 5.8). La función XOR a nivel de bit no existe en las
familias MCS-51 y MCS-251; no obstante, esta función se puede realizar sencillamente teniendo en
cuenta que si a las entradas de la función XOR se las denomina a y b, y z a su salida, z es igual a b,
z=b, si a es cero y z es igual a b negado, z=/b, si a vale 1 lógico.
+θ+ = +
+θ- = -
-θ+ = -
-θ- = +
Multiplicación de signos Multiplicación binaria de signos
0θ0 = 0
0θ1 = 1
1θ0 = 1
1θ1 = 0
Fig. 5.8 Multiplicación binaria de signos
A continuación se muestra la subrutina MUL16S que realiza la multiplicación de dos números de 16
bits con signo. Esta subrutina utiliza la subrutina anterior MUL16 para multiplicar en valor absoluto
los dos operandos, por lo que MUL16S tendrá los mismo registros de entrada y de salida que MUL16.
Para determinar el bit de signo resultante de la multiplicación se utilizan los bits de propósito general
F0 y UD del registro de estado PSW, es decir, los bits PSW.5 y PSW.1, que son definibles por el
usuario.
;*****************************************************
;Subrutina MUL16S
;Multiplica 16bitsx16bits con signo, (YH-YL)x(XH-XL)
;Entrada: R0=XH, R1=XL, R2=YH, R3=YL.
;Salida: 32 bits. R7=ZS0, R6=ZS1, R5=ZS2, R4=ZS3.
;Modifica: A, B, Registros R7 a R1 del banco 1.
;*****************************************************
MUL16S: MOV A,R0 ;Lee XH
RLC A ;Rota
MOV PSW.5,C ;Guarda bit de signo de X
MOV A,R2 ;Lee YH
RLC A ;Rota
MOV PSW.1,C ;Guarda bit de signo de Y
JNB PSW.5,MOD_Y ;¿X es negativo?
CLR C ;Borra acarreo
CLR A ;Borra A
SUBB A,R1 ;Complemento a 2 XL
MOV R1,A ;Guarda XL
CLR A ;Borra A
SUBB A,R0 ;Complemento a 2 XH
MOV R0,A ;Guarda XH
MOD_Y: JNB PSW.1,M_ABS ;¿Y es negativo?
CLR C ;Borra acarreo
CLR A ;Borra A
SUBB A,R3 ;Compl. a 2 de YL
MOV R3,A ;Guarda YL
CLR A ;Borra A
SUBB A,R2 ;Compl. a 2 de YH
MOV R2,A ;Guarda YH
© Los autores, 2001; © Edicions UPC, 2001.
5 El modelo de programación 111
M_ABS: LCALL MUL16 ;Multiplica en valor absoluto
MOV C,PSW.5 ;Función XOR de los signos
JNB PSW.1,ES_0
CPL C
ES_0: JC CPL4 ;Resultado negativo
RET
CPL4: MOV 08H,#07 ;Carga direcc. ZS0
SETB RS0 ;Cambia a banco 1
MOV R7,#4 ;Nº de bytes de ZS
LCALL COMPL2_N ;Compl. a 2 de ZS
CLR RS0 ;Cambia a banco 0
RET
La subrutina MUL16S hace uso además de la subrutina COMPL2_N que realiza el complemento a
dos del resultado ZS de 4 bytes, generado por la multiplicación. Esta subrutina es genérica y utiliza la
dirección del operando (puntero @R0) y el tamaño del operando (R7) como datos de entrada.
;**********************************************
;Subrutina COMPL2_N
;Realiza el complemento a 2 de un número de N bytes
;Entrada: R0 (Puntero a X), R7 (Tamaño)
;Salida: Resultado sustituye al operando X
;Modifica: C, A, R0, R7
;**********************************************
COMPL2_N: CLR C
BUC_CP: CLR A
SUBB A,@R0
MOV @R0,A
DEC R0
DJNZ R7,BUC_CP
RET
Para la familia MCS-251 la subrutina MUL16S puede ser más compacta. En este caso, los operandos
se sitúan dentro de la zona accesible bit a bit, de la 20H a la 2FH de la memoria RAM interna, para
poder así acceder fácilmente a los bits de signo de los operandos.
;********************************************************************************
;Subrutina MUL16S para la familia MCS-251
;Entrada: XH en 20H, XL en 21H.YH en 22H, YL en 23H.
;Salida: 32 bits. R7=ZS0, R6=ZS1, R5=ZS2, R4=ZS3. Modifica: A, B, Reg. R7 a R1 del banco 1.
;*********************************************************************************
MUL16S: JNB 20H.7,SAL1
SUB WR0,20H
JMP SIGUE0
SAL1: MOV WR0,20H
SIGUE0: JNB 22H.7,SAL2
SUB WR2,22H
CPL 20H.7
SAL2: JMP SIGUE1
MOV WR2,22H
SIGUE1: MUL WR0,WR2
JNB 20H.7,SIGUE2
SUB DR4,DR0
RET
SIGUE2: MOV DR4,DR0
RET
La subrutina siguiente DIV16s realiza división con signo de dos números de 16 bits, utilizando para
ello la subrutina DIV16; por tanto, tiene los mismos parámetros de entrada y de salida que esta
subrutina. En cuanto al resultado, en el caso que el dividendo sea positivo y el divisor sea negativo, y
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251112
viceversa, el cociente deberá ser negativo; si ambos, dividendo y divisor, son positivos o negativos,
entonces el cociente debe ser positivo. En cualquier caso, el resto se deja siempre positivo.
;**************************************************************
;Subrutina DIV16S División de 16 bits con signo (XH-XL)/(YH-YL)
;Entrada: Dividendo: XH=R0 y XL =R1. Divisor: YH=R4 y YL=R5
;Salida: Cociente: CH=R0 y CL=R1. Resto: ZH=R2 y ZL=R3
;Modifica: A, R0, R1, R2, R3, R7. Direcc. 08H, 09H, 0AH, 0BH, 20H y 21H
;**************************************************************
DIV16S: MOV 20H,R0 ;Pone XH en 20H
MOV 21H,R4 ;Pone YH en 21H
JNB 20H.7,MOD_Y ;¿X es negativo?
SETB RS0 ;Cambio a banco 1
MOV R0,#01H ;Carga dir. XL en puntero R0
MOV R7,#2 ;Nº de bytes
LCALL COMPL2_N ;Complementa a 2
MOD_Y: JNB 21H.7,M_ABS ;¿Y es negativo?
MOV R0,#03H ;Carga dir. YL en puntero R0
MOV R7,#2 ;Nº de bytes
CLR RS0 ;Cambio a banco 0
M_ABS: LCALL DIV16 ;División en valor absoluto
JB OV,SALIR
JB 20H.7,DIVDN ;Si dato X es negativo
JB 21H.7,CPLDIV ;Si dato Y es negativo
SALIR: RET ;Dato X y dato Y son positivos
DIVDN: JNB 21H.7,CPLDIV ;Si dato Y es positivo
RET ;Dato X y dato Y son negativos
CPLDIV: SETB RS0 ;Cambio a banco 1
MOV R0,#01H ;Carga dir. cociente
MOV R7,#2 ;Nº de bytes
LCALL COMPL2_N ;Complementa a 2
CLR RS0 ;Cambio a banco 0
RET
La subrutina DIV16S para la familia MCS-251 es la siguiente:
;*******************************************************************
;Subrutina DIV16S Para la familia MCS-251
;Entrada: Dividendo: XH en 20H y XL en 21H. Divisor: YH en 22H y YL en 23H
;Salida: Cociente en WR6 y resto en WR4
;*******************************************************************
DIV16S: JNB 20H.7,SAL1
SUB WR0,20H
JMP SIGUE
SAL1: MOV WR0,20H
SIGUE: JNB 22H.7,SAL2
SUB WR2,22H
CPL 20H.7
SAL2: JMP SIGUE1
MOV WR2,22H
SIGUE1: DIV WR0,WR2
JNB 20H.7,SIGUE2
SUB WR6,WR2
MOV WR4,WR0
RET
SIGUE2: MOV DR4,DR0
RET
© Los autores, 2001; © Edicions UPC, 2001.
5 El modelo de programación 113
5.10 Ejemplos de aplicación
A continuación se describen una serie de ejemplos resueltos donde se aplican parte de las rutinas
expuestas en este capítulo. Los ejemplos descritos se pueden realizar, de forma más efectiva y con una
mejor explotación de los recursos del microcontrolador, utilizando interrupciones, por lo que para
algunos de los ejemplos se propondrá su solución alternativa en capítulos posteriores, teniendo ya un
mejor conocimiento del proceso de interrupciones y de los recursos internos de los microcontroladores
de las familias MCS-51 y MCS-251.
La estructura del programa, realizada en los ejemplos, en general será parecida a lo largo de este libro.
El programa tendrá una rutina inicial, rutina “Inicio”, en la cual se configuran los recursos internos del
microcontrolador y el modo de operar de éste. De esta rutina se pasa a una rutina “Principal”, que se
encarga de llevar a cabo las funciones requeridas por la aplicación. La rutina principal será una rutina
que forme un bucle infinito, pues las aplicaciones a resolver necesitan que el microcontrolador estéconstantemente pendiente de las tareas que debe efectuar. La rutina “Inicio” en algunos ejemplos no
aparecerá, pues, las soluciones adoptadas son sencillas, y no será necesario poner un valor inicial a las
variables empleadas.
5.10.1 Generación de una señal cuadrada
En un sistema es frecuente tener que generar una señal periódica de frecuencia determinada y lo más
simétrica posible. En este ejemplo, se propone la creación de una señal cuadrada de 5kHz de
frecuencia, que se extraerá por la patilla P1.0 de un microcontrolador 8031 (figura 5.9).
Para generar una frecuencia de 5kHz se precisa de un periodo de 200 ÷s y, por tanto, cambiar el
estado de la patilla P1.0 cada 100÷s. Para cambiar el estado de P1.0 se utilizará la instrucción CPL de
complemento de un bit, y para generar un retardo de 100 ÷s se utilizará una rutina de retardo como la
descrita en el apartado 5.4.
P1.0
8031
T (200÷S)
T/2
Fig. 5.9 Generación de una señal cuadradacon el microcontrolador
;***************************************************
; Programa de generación de una señal cuadrada
;***************************************************
ORG 0H
LJMP Principal
;***************************************************
; Rutina Principal
;***************************************************
ORG 0100H
Principal: CPL P1.0 ;Complementa el estado lógico de P1.0
CALL Retardo ;Llama a la rutina de retardo
SJMP Principal ;Bucle infinito a principal
Retardo: MOV R7, #46 ;Pone 46 en R7
L1: DJNZ R7, L1 ;Bucle sobre L1
RET ;Retorno de subrutina
Para que la instrucción CPL se ejecute cada 100 ÷s, se debe determinar de forma precisa el valor de
carga del registro R7 de la subrutina de retardo. Para ello, si se considera que la frecuencia de reloj del
microcontrolador es de 12MHz y que, entonces, un ciclo máquina tarda en efectuarse 1 ÷s, y que la
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251114
instrucción CPL se ejecuta en 1 ciclo máquina, indicado como CM, la instrucción CALL se ejecuta en
2 CM, SJMP en 2 CM, “MOV R7, #46” en 1CM, DJNZ en 2CM y RET en 2 CM. El tiempo de
ejecución de la rutina de retardo viene dado por:
CM 27R21t tRe �θ�∑
Y el tiempo total en que se ejecuta la instrucción CPL a cada vuelta del bucle principal es:
s100 ó CM100t221t tReCPL ÷∑���∑
Se deduce que tRet debe valer 95 ÷s, y que el registro R7 debe valer 46.
El programa realizado se puede modificar para efectuar el parpadeo de un diodo led conectado por
medio de un transistor al microcontrolador (fig 5.10). La resistencia R1 debe calcularse para limitar la
corriente del diodo led a unos 20mA, valor más que suficiente para mantener al diodo encendido de
manera adecuada.
P1.0
80C31
Vcc
R1
VTH
VCE
LEDR2
Fig. 5.10 Circuito de conexión de un diodo led al microcontrolador
La resistencia R2 se debe determinar para que el transistor entre en saturación cuando la salida de P1.0
está a 1 lógico. La rutina modificada se muestra a continuación:
;*****************************************
; Programa de parpadeo de un diodo led
;*****************************************
ORG 0H
LJMP Principal
;*****************************************
; Rutina Principal
;*****************************************
ORG 0100H
Principal: CPL P1.0
MOV R6, #0
MOV R7, #0
Retardo: DJNZ R6, Retardo
DJNZ R7, Retardo
SJMP Principal
El tiempo que tarda en ejecutarse la rutina de retardo, bucle formado por L1, deber ser suficiente para
que el parpadeo del led sea perceptible. Este tiempo es:
[ ] s13,0s131584)1255(2)1255(2t 1L ≈÷∑�θ��θ∑
La frecuencia de la señal cuadrada será en este caso de 3,8Hz, aproximadamente.
© Los autores, 2001; © Edicions UPC, 2001.
5 El modelo de programación 115
5.10.2 Conexión de teclas al microcontrolador
Las teclas o pulsadores son elementos que aparecen en la mayor parte de los sistemas basados en un
microcontrolador, por lo que en este ejemplo se propone la conexión de teclas a cada uno de los
puertos del microcontrolador, tal y como indica la figura 5.11.
P1.0
P1.1
P2.0
P2.1
87C31T1
T2
T3
T4
T5
Colector
abierto
RVcc74LS05/06
P3.0
T6P0.0
R
Vcc
R
VTH
VCE
i
Vcc
LED
P1.2
P1.3
P1.4
P1.5
P1.6
P1.7
LED
Fig. 5.11 Conexión de 4 teclas al microcontrolador
En la figura 5.11 se emplea el circuito integrado 74LS05, o el 74LS06, que contiene hasta 6 puertas
inversoras en colector abierto. El terminal de salida de la puerta inversora es el colector de un
transistor interno, cuyo emisor está conectado a masa, tal y como se ve en el detalle de esta figura. La
puerta inversora puede soportar una corriente máxima de 25mA, para el 74LS05, y de 30mA a 40mA,
para el 74LS06, valores más que suficientes para encender de manera adecuada el diodo led que tiene
conectado.
La resistencia R se debe calcular de forma adecuada para que, considerando el valor de Vcc, de la
tensión umbral del diodo led, VTH, y de la tensión colector-emisor del transistor en saturación, VCE, la
corriente i esté limitada a unos 20mA, valor más que suficiente para iluminar adecuadamente el diodo
led. El valor de la resistencia R se puede determinar a partir de la siguiente ecuación:
i
VVVR CETHCC ≅≅
∑ (5.1)
Los puertos P1, P2 y P3 (figura 3.4 del capítulo 3) tienen una resistencia interna de pull-up conectada
a cada una de las salidas, por lo que una tecla se puede conectar directamente a la patilla de uno de
estos puertos. Debido a la resistencia de pull-up, el estado de una tecla no pulsada será de 1 lógico y el
estado de una tecla pulsada será de 0 lógico (conexión directa a masa -fig. 5.12-), por lo que basta con
leer el estado lógico del terminal del puerto para saber si la tecla está siendo pulsada o no.
El puerto P0 de la MCS-51 no tiene resistencia interna de pull-up y en su lugar hay un transistor
NMOS, debido a que este puerto debe tener la característica de triestado. Por ello, para conectar una
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251116
tecla se debe poner una resistencia externa de pull-up, que proporcione un estado 1 lógico, cuando no
se pulsa la tecla, y un estado 0 lógico, cuando se pulsa la tecla.
Vcc
Puertos P1,
P2 y P3
VDD
Puerto P0
R
i i
Pull-up
Vcc
Fig. 5.12 Conexión de una tecla al terminal de los puertos de la MCS-51
El programa deberá leer el estado de las teclas y encender un diodo led asociado a la tecla, en el caso
de que se pulse. El diodo led se mantendrá encendido mientras la tecla permanezca pulsada.
Las instrucciones CLR que se utilizan para borrar los leds pueden sustituirse por una única instrucción
que escriba en todo el puerto P1. Para ello, se debe tener en cuenta que hay dos teclas conectadas a
P1.0 y P1.1, respectivamente; deben ponerse estos terminales a 1 lógico, de forma que sea posible leer
si la tecla ha sido pulsada o no.
;******************************************************************
; Programa para la lectura de la teclas del circuito de la figura 5.11
;******************************************************************
ORG 0H
MOV P1, #0000 0011b ;Leds apagados. P1.0 y P1.1 como entradas
LJMP Principal
;******************************************************************
; Rutina Principal (Testeo de teclas y encendido/ apagado de leds)
;******************************************************************
ORG 0100H
Principal: JNB P1.0, Tecla_T1 ;Comprueba si se ha pulsado T1
JNB P1.1, Tecla_T2 ;Comprueba si se ha pulsado T2
JNB P2.0, Tecla_T3 ;Comprueba si se ha pulsado T3
JNB P2.1, Tecla_T4 ;Comprueba si se ha pulsado T4
JNB P3.0, Tecla_T5 ;Comprueba si se ha pulsado T5
JNB P0.0, Tecla_T6 ;Comprueba si se ha pulsado T6
CLR P1.2 ;Apaga led conectado a P1.2
CLR P1.3 ;Apaga led conectado a P1.3
CLR P1.4 ;Apaga led conectado a P1.4
CLR P1.5 ;Apaga led conectado a P1.5
CLR P1.6 ;Apaga led conectado a P1.6
CLR P1.7 ;Apaga led conectado a P1.7
SJMP Principal
Tecla_T1: MOV P1, #0000 0111b ;Enciende led de P1.2 y apaga el resto
SJMP Principal ;Regresa a Principal
Tecla_T2: MOV P1, #0000 1011b ;Enciende led de P1.3 y apaga el resto
SJMP Principal ;Regresa a Principal
Tecla_T3: MOV P1, #0001 0011b ;Enciende led de P1.4 y apaga el resto
SJMP Principal ;Regresa a Principal
Tecla_T4: MOV P1, #0010 0011b ;Enciende led de P1.5 y apaga el resto
SJMP Principal ;Regresa a Principal
Tecla_T5: MOV P1, #0100 0011b ;Enciende led de P1.6 y apaga el resto
SJMP Principal ;Regresa a Principal
© Los autores, 2001; © Edicions UPC, 2001.
5 El modelo de programación 117
Tecla_T6: MOV P1, #1000 0011b ;Enciende led de P1.7 y apaga el resto
SJMP Principal ;Regresa a Principal
Se puede escribir sobre todo el puerto P1, sustituyendo a las instrucciones CLR P1.X, con la siguiente
instrucción MOV:
MOV P1, #0000 0011b ;Bits P1.0 y P1.1 a 1 lógico
La rutina principal lee el estado de cada tecla y apaga los leds conectados al puerto P1. Si se pulsa una
tecla, se enciende el diodo led asociado y se salta a la etiqueta Principal, de forma que el led se
mantiene encendido mientras se pulse la tecla. Al dejar de pulsar la tecla el programa apaga todos los
leds.
5.10.3 Conexión de un dígito de 7 segmentos
Los dígitos de visualización se usan de manera frecuente para indicar al usuario una determinada
información. Los dígitos suelen estar formados por 7 segmentos o por 16 segmentos (hexadecimales),
aunque existen en el mercado una gran variedad y gama de dígitos a disposición del diseñador. Los
dígitos de 7 segmentos son adecuados para visualizar números y algunas letras y símbolos, estos
últimos con poca definición (figura 5.13). Los dígitos hexadecimales están formados por 16 diodos
led, por lo que tienen una mejor definición para números, letras y símbolos.
a
b
c
d
e
f
g
DP
7 segmentos 16 segmentos
a b dc e f g DP
Ánodo común
a b dc e f g DP
Cátodo común
Fig. 5.13 Dígitos de 7 y de 16 segmentos
En este ejemplo se conectan tres teclas y un dígito de 7 segmentos al microcontrolador (figura 5.14).
El programa debera leer el estado de las teclas y poner en el dígito la letra “A” si se pulsa la tecla T1,
la letra “b” si se pulsa la tecla T2, y la letra “C” si se pulsa la tecla T3.
P1.0
P1.1
P1.2
87C31
T1
T2
T3
a
b
c
d
e
f
g
DP
P2.0
P2.1
P2.7
R
Dígito 7 segmentos
ánodo común Vcc74LS05/06
Colector
abierto
a
b
DP R
VCE
Vcc
b cVTH
i
LED
Fig. 5.14 Conexión de un dígito de 7 segmentos al microcontrolador
En la conexión se utiliza, del mismo modo que el ejemplo anterior, un par de circuitos integrados
74LS05 ó 74LS06 que contienen hasta 6 puertas inversoras en colector abierto. El dígito utilizado es
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251118
de ánodo común, el ánodo está conectado a la tensión de alimentación, Vcc, y cada diodo a una
resistencia y a un colector del circuito integrado. La resistencia se debe calcular para que limite la
corriente a un valor máximo de 20mA. El programa de este ejemplo se muestra a continuación:
;********************************************************
; Programa para la conexión de un dígito de 7-segmentos
;********************************************************
ORG 0H
MOV P2, #0 ;Apaga todos los leds del dígito
LJMP Principal
;*******************************************************
; Rutina Principal
;*******************************************************
ORG 0100H
Principal: JNB P1.0, Tecla_T1 ;Comprueba si se ha pulsado T1
JNB P1.1, Tecla_T2 ;Comprueba si se ha pulsado T2
JNB P2.0, Tecla_T3 ;Comprueba si se ha pulsado T3
MOV P2, #0 ;Borra el dígito
SJMP Principal
Tecla_T1: MOV P2, #0111 0111b ;Pone letra A en el dígito
SJMP Principal ;Regresa a Principal
Tecla_T2: MOV P2, #0111 1100b ;Pone la letra b en el dígito
SJMP Principal ;Regresa a Principal
Tecla_T3: MOV P2, #0011 1001b ;Pone la letra C en el dígito
SJMP Principal ;Regresa a Principal
5.10.4 Conexión de un teclado matricial de 4 x 4 teclas
Los teclados son un elemento imprescindible en un sistema debido a que posibilitan la relación entre
éste y el usuario al permitir la introducción de datos y la selección de diferentes modos de operación
del programa, cuando la aplicación es compleja.
La figura 5.15 muestra la conexión de un teclado matricial de 4x4 teclas al puerto P1 de un 87C31.
Existe una enorme variedad y diferentes tipos de teclados en el mercado; no obstante la disposición de
las teclas en éstos suele ser matricial, disposición del tipo fila/columna, de manera que una serie de
teclas comparten una misma columna y otra serie de teclas comparte la misma fila (figura 5.15).
87C31
P1.0
P1.4
P1.5
P1.6
P1.7
P1.1
P1.2
P1.3
P2.0
P2.7
a
DP
R
R
74LS05/06Ánodo
común
1 2 3
4 5 6
7 8 9
0A B
C
D
E
F
a
b
c
d
e
fg
DP
Vcc
Fig. 5.15 Conexión de un teclado matricial al microcontrolador
© Los autores, 2001; © Edicions UPC, 2001.
5 El modelo de programación 119
La conexión del teclado con el microcontrolador resulta sencilla, pues utiliza los cuatro bits bajos de
P1 como salidas conectadas a las columnas del teclado, y los cuatro bits altos como entradas
conectadas a las filas del teclado. En este ejemplo se conecta un dígito de 7 segmentos para que se
muestre un carácter determinado, correspondiente a la tecla pulsada.
El programa deberá efectuar la lectura del teclado matricial de manera continua. Cuando se pulse una
tecla, se mostrará el carácter que tiene asociado la tecla en el dígito de 7 segmentos. En el dígito
siempre se mostrará el código de la última tecla pulsada.
La detección de una tecla pulsada en el teclado matricial se realizará columna a columna, de forma
secuencial, es decir, se pondrá un dato en las columnas del teclado (patillas P1.0, P1.1, P1.2 y P1.3),
que habilite sólo una de las columnas, y se leerá a continuación el estado lógico de las filas del teclado
(patillas P1.4, P1.5, P1.6 y P1.7), de manera que si se ha pulsado una tecla se detectará mediante el
dato leído en la filas. Tras haberse comprobado la columna, ésta se inhabilitará y se procederá a
habilitar la siguiente columna; este proceso se repetirá hasta que se hayan testeado todas las columnas
del teclado. Este procedimiento se debe repetir de forma continuada, comprobando cada una de las
columnas del teclado matricial.
Tal y como se ha conectado el teclado matricial al microcontrolador, la habilitación de una columna se
hace poniendo un 0 lógico en una de las patillas de salida de P1, o sea, P1.0, P1.1, P1.2 ó P1.3, y se
inhabilita poniendo un 1 lógico. Luego, una columna estará habilitada, mientras el resto no. Si se
pulsa una tecla de la columna habilitada, el estado lógico de la columna, 0 lógico, pasará a una de las
filas, dependiendo de cuál haya sido la tecla pulsada. En cambio, si no se pulsa ninguna tecla, el
estado lógico que se lee es un 1 lógico, puesto que los terminales P1.4, P1.5, P1.6 y P1.7 están
configurados como entradas, es decir, su transistor NMOS (figura 3.4 del capítulo 3) está en corte y el
estado lógico que se lee corresponde al que proporciona la resistencia interna de pull-up. Sin embargo,
en esta situación, si se pulsa una tecla correspondiente de una columna inhabilitada, en la fila
correspondiente se lee un 1 lógico, debido a que el estado de la columna es 1 lógico por estar
inhabilitada.
En definitiva, para habilitar la primera columna (teclas 1, 4, 7 y A) y inhabilitar el resto de columnas,
se debe escribir en el puerto el dato 1111 1110b y configurar, además, las patillas conectadas a las
filas como entradas (estado 1 lógico, transistor NMOS en corte). Para habilitar la segunda columna,
(teclas 2, 5, 8 y 0) e inhabilitar el resto, se debe poner 1111 1101b en P1. Para habilitar la tercera
columna (teclas 3, 6, 9 y B) e inhabilitar el resto, se debe poner 1111 1011b en P1. Y, por último, para
habilitar la cuarta columna (teclas C, D, E y F) e inhabilitar el resto, se debe poner 1111 0111b en P1.
El programa deberá llevar a cabo la secuencia descrita de testeo por medio de un bucle infinito.
Además, también se utilizará una tabla para hacer la conversión a 7 segmentos del carácter que se
quiere visualizar.
;******************************************************************
; Programa de lectura de teclado matricial
;******************************************************************
ORG 0H
MOV P2, #0 ;Apaga todos los leds del dígito
MOV B, #0 ;Borra registro B
LJMP Principal
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251120
;******************************************************************
; Rutina Principal
;******************************************************************
ORG 0100H
Principal: MOV P1, #1111 1110b ;Habilita la primera columna
CALL Det_tecla ;Subrutina de detección de tecla pulsada
JNZ A, Colum_1 ;A�0 si se pulsa tecla
MOV P1, #1111 1101b ;Habilita la segunda columna
CALL Det_tecla
JNZ A, Colum_2 ; A�0 si se pulsa tecla
MOV P1, #1111 1011b ;Habilita la tercera columna
CALL Det_tecla
JNZ A, Colum_3 ; A�0 si se pulsa tecla
MOV P1, #1111 0111b ;Habilita la cuarta columna
CALL Det_tecla
JNZ A, Colum_4 ; A�0 si se pulsa tecla
Prin2: CALL Display
MOV B, #0 ;Borra el registro B
SJMP Principal ;Bucle infinito
Colum_1: JNB P1.4, Tecla_1 ;¿Se ha pulsado la tecla 1?
JNB P1.5, Tecla_4 ;¿Se ha pulsado la tecla 4?
JNB P1.6, Tecla_7 ;¿Se ha pulsado la tecla 7?
SJMP Tecla_A ;Si no es ninguna de la anteriores, es la tecla A
Colum_2: JNB P1.4, Tecla_2 ;¿Se ha pulsado la tecla 2?
JNB P1.5, Tecla_5 ;¿Se ha pulsado la tecla 5?
JNB P1.6, Tecla_8 ;¿Se ha pulsado la tecla 8?
SJMP Tecla_0 ;Si no es ninguna de la anteriores, es la tecla 0
Colum_3: JNB P1.4, Tecla_3 ;¿Se ha pulsado la tecla 3?
JNB P1.5, Tecla_6 ;¿Se ha pulsado la tecla 6?
JNB P1.6, Tecla_9 ;¿Se ha pulsado la tecla 9?
SJMP Tecla_B ;Si no es ninguna de la anteriores, es la tecla B
Colum_4: JNB P1.4, Tecla_C ;¿Se ha pulsado la tecla C?
JNB P1.5, Tecla_D ;¿Se ha pulsado la tecla D?
JNB P1.6, Tecla_E ;¿Se ha pulsado la tecla E?
SJMP Tecla_F ;Si no es ninguna de la anteriores, es la tecla F
Tecla_0: MOV B, #1 ;Pone en B código para la lectura de tabla
LJMP Prin2
Tecla_1: MOV B, #2 ;Pone en B código para la lectura de tabla
LJMP Prin2
Tecla_2: MOV B, #3 ;Pone en B código para la lectura de tabla
LJMP Prin2
Tecla_3: MOV B, #4 ;Pone en B código para la lectura de tabla
LJMP Prin2
Tecla_4: MOV B, #5 ;Pone en B código para la lectura de tabla
LJMP Prin2
Tecla_5: MOV B, #6 ;Pone en B código para la lectura de tabla
LJMP Prin2
Tecla_6: MOV B, #7 ;Pone en B código para la lectura de tabla
LJMP Prin2
Tecla_7: MOV B, #8 ;Pone en B código para la lectura de tabla
LJMP Prin2
Tecla_8: MOV B, #9 ;Pone en B código para la lectura de tabla
LJMP Prin2
Tecla_9: MOV B, #10 ;Pone en B código para la lectura de tabla
LJMP Prin2
Tecla_A: MOV B, #11 ;Pone en B código para la lectura de tabla
LJMP Prin2
Tecla_B: MOV B, #12 ;Pone en B código para la lectura de tabla
LJMP Prin2
Tecla_C: MOV B, #13 ;Pone en B código para la lectura de tabla
LJMP Prin2
© Los autores, 2001; © Edicions UPC, 2001.
5 El modelo de programación 121
Tecla_D: MOV B, #14 ;Pone en B código para la lectura de tabla
LJMP Prin2
Tecla_E: MOV B, #15 ;Pone en B código para la lectura de tabla
LJMP Prin2
Tecla_F: MOV B, #16 ;Pone en B código para la lectura de tabla
LJMP Prin2
;**********************************************************************
; Subrutina para la deteccción de una tecla pulsada
; Lee el puerto P1 y retorna A=0 si no se pulsa una tecla y A�0 si se pulsa
;**********************************************************************
Det_tecla: MOV A, P1 ;Lee puerto P1 (filas)
ORL A, #0FH ;Fuerza 4 bits bajos a 1 lógico
CPL A ;Complementa acumulador
RET ;Si no se pulsan teclas A=0, A=1 en caso contrario
;**********************************************************************
; Subrutina de visualización de un caracter en el dígito de 7-segmentos
;**********************************************************************
Display: MOV A, B ;Lee registro B
CALL Vis_7seg ;Llama a la subrutina que pone el carácter de 7 segmentos
MOV P2, A ;Pone el en P2, visualiza
RET
Vis_7seg: INC A ;Incrementa acumulador
MOVC A, @A+PC ;Lectura de tabla de conversión
RET
DB 0000 0000b ;(A=1) dígito apagado.
DB 0011 1111b ;(A=2) leds a, b, c, d, e y f encendidos, caracter 0
DB 0000 0110b ;(A=3) leds a y b encendidos, caracter 1.
DB 0101 1011b ;(A=4) leds a, b, d, e y g encendidos, caracter 2.
DB 0100 1111b ;(A=5) leds a, b, c, d y g encendidos, caracter 3 (A=0).
DB 0110 0110b ;(A=6) leds b, c, f y g encendidos, caracter 4.
DB 0110 1101b ;(A=7) leds a, c, d, f, y g encendidos, caracter 5.
DB 0111 1101b ;(A=8) leds a, c, d, e, f y g encendidos, caracter 6.
DB 0000 0111b ;(A=9) leds a, b y c encendidos, caracter 7.
DB 0111 1111b ;(A=10) leds a, b, c, d, e, f, y g encendidos, caracter 8.
DB 0110 0111b ;(A=11) leds a, b, c, f y g encendidos, caracter 9.
DB 0111 0111b ;(A=12) leds a, b, c, e, f y g encendidos, caracter A.
DB 0111 1100b ;(A=13) leds c, d, e, f y g encendidos, caracter b.
DB 0011 1001b ;(A=14) leds a, d, e y f encendidos, caracter C
DB 0101 1110b ;(A=15) leds b, c, d, e y g encendidos, caracter d
DB 0111 1001b ;(A=16) leds a, d, e, f y g encendidos, caracter E
DB 0111 0001b ;(A=17) leds a, e, f y g encendidos, caracter F.
5.10.5 Conexión de varios dígitos de 7 segmentos, aplicación de “Su turno”
La figura 5.16 muestra la forma de conectar varios dígitos de 7 segmentos a un 87C51 para una
aplicación donde se desea controlar el turno de atención a un cliente, que es tan común en tiendas y
locales comerciales. Debido al tipo de aplicación donde se ha de visualizar el número de orden del
cliente, los dígitos se pueden controlar mediante el circuito integrado 4511, que es un conversor de
formato BCD a 7 segmentos, de forma que colocando el número en BCD a la entrada del 4511, A0-
A3, éste activa los leds necesarios (salidas a, b, c, d, e, f, g y dp) para que el número aparezca en el
dígito.
El 4511 es capaz de suministrar hasta 25mA de corriente, valor más que suficiente para tener un diodo
led encendido de forma adecuada. Este circuito integrado tiene un latch interno que le permite
almacenar el valor del último número almacenado. El latch está gobernado por la entrada /EL, de
manera que cuando /EL está a 0 lógico habilita el 4511 y activa los leds correspondientes al número
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251122
de entrada (A0-A3), y cuando en /EL se produce un flanco positivo (paso de 0 a 1 lógico), el latchalmacena el último dato presente en la entrada y mantiene encendidos los leds correspondientes.
87C51
P1.4
P1.5
P1.6
P1.1
P1.2
P1.3
P1.0
Cátodo común
R
R
a
b
dp
a
dp
4511
(BCD-7seg)
A0
A1
A2
A3
Vcc
Cuenta
Reset
P2.0
P2.1
T1
T2
Rb
Rb
Rb
/EL
Centenas Decenas Unidades
Tr1 Tr2 Tr3
Fig. 5.16 Conexión de varios dígitos de 7 segmentos al microcontrolador
El 4511 dispone de dos entradas de control adicionales, /ILT y /IB. La entrada /ILT enciende todos los
leds del dígito conectado, para hacer así un chequeo del estado de los leds. La entrada /IB borra todos
los leds del dígito conectado.
En esta aplicación se usará un microcontrolador 8751, el 4511, tres dígitos de 7 segmentos y tres
transistores para controlar el encendido de cada uno de los dígitos. Por sencillez, las entradas /ILT y
/IB del 4511 no se usarán, y la entrada /EL se conectará directamente a tierra, de forma que estésiempre habilitado.
El circuito formado por el 4511, un dígito conectado a éste (centenas) y el transistor de control de
encendido del dígito, Tr1, se muestran en la figura 5.17. El 4511 tiene un transistor bipolar de salida,
Tr0, conectado a la tensión de alimentación Vcc. El 4511 enciende un diodo led, por ejemplo el led
“a” de la figura 5.17, cuando el transistor bipolar Tr0 está en saturación, de forma que la corriente
circula a través de la resistencia R, del diodo led “a” y del transistor Tr1. El diodo se encenderásiempre y cuando el transistor Tr1 esté en saturación.
P1.4
R
R
a
b
dp
a
dp
4511
(BCD-7seg)
A0
A1
A2
A3
Rb
/EL
Centenas
a b
Vcc
R
i
i
a
a
ib
Tr1Tr1
Tr0
Fig. 5.17 Detalle del circuito para la activación del diodo led “a”
© Los autores, 2001; © Edicions UPC, 2001.
5 El modelo de programación 123
Las salidas del 4511 están conectadas a los diodos de cada segmento, es decir, la salida que activa el
diodo led “a” del dígito de las centenas, también está conectada al led “a” del dígito de las decenas y
del dígito de las unidades. De esta forma, se simplifica el circuito y se reduce el número de terminales
necesarios para los tres dígitos.
En cuanto al consumo, debe considerarse que un dígito puede llegar a consumir hasta 160mA (8
diodos led y 20mA por diodo), por tanto, con tres dígitos se puede llegar a un consumo de 480mA, y
si el número de dígitos es mayor el consumo de corriente se dispara considerablemente.
Para evitar el consumo excesivo por parte de los dígitos y para utilizar el circuito realizado, los dígitos
se deben encender de manera secuenciada, es decir, primero se enciende el dígito de las centenas,
luego el dígito de las decenas y, por último, el dígito de las unidades. Esta secuencia se puede llevar a
cabo por medio de la activación de los transistores conectados al cátodo común de cada dígito
(transistores Tr1, Tr2 y Tr3, respectivamente -fig. 5.18-). Esta secuencia se debe repetir con una
frecuencia de 25Hz, como mínimo, para que el parpadeo no sea perceptible por una persona y que la
imagen se visualice de manera correcta.
Dígito 1
Dígito 2
Dígito 3
T/3
T/3
T/3
T/3
T/3
T/3
T
Dígito 2
Dígito 2
Dígito 3
P1.4
P1.5
P1.6
Fig. 5.18 Secuencia de encendido de los dígitos del circuito de la figura 5.16
Los transistores TR1, Tr2 y Tr3 pueden ser cualquier tipo de transistor capaz de soportar como
mínimo 200mA. Para el caso de un número elevado de dígitos se pueden emplear arrays de
transistores dárlintongs como los disponibles en los circuitos integrados de las series ULN2800A y
ULN2980A, capaces de soportar corrientes de 350mA y 500mA.
Las funciones básicas que deberá realizar el programa son:
1. Controlar hasta un máximo de 199 peticiones. Cuando la cuenta exceda esta cantidad se
deberá poner a 000.
2. Se tienen 2 pulsadores, uno de cuenta y otro de reset (de puesta a cero). El pulsador de cuenta
siempre incrementará en uno el turno actual. El pulsador de reset pondrá a 000 el valor de la
cuenta.
La manera más sencilla de hacer este programa consiste en realizar una rutina de cuenta en formato
BCD, como la rutina CONTA descrita en el apartado 5.6. En esta rutina intervienen los registros R0,
R1 y R2. El registro R0 se emplea para las unidades, R1 para las decenas y R2 para las centenas. El
flujograma del programa se muestra en la figura 5.19.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251124
;*********************************************
; Programa para la gestión del turno de espera
;*********************************************
ORG 0H
MOV P1, #0 ;Pone a cero la entrada del 4511
MOV R0, #0 ;Pone en corte Tr1, Tr2 y Tr3
MOV R1, #0
MOV R2, #0
;**********************************************
; Rutina Principal
;**********************************************
Principal: JNB P2.0, Cuenta
JNB P2.1, PaCero
Prin2: CALL Display
SJMP Principal
Cuenta: CALL CONTA
SJMP Prin2
PaCero: MOV R0, #0
MOV R1, #0
MOV R2, #0
SJMP Prin2
;************************************************
;Subrutina CONTA
;Registros afectados: R0, R1, R2
;************************************************
CONTA: CJNE R0, #9, UNIDAD ;Compara unidad
CJNE R1, #9, DECENA ;Compara decena
CJNE R2, #1, CENTENA ;Compara centena
MOV R0, #0 ;Al ser 199 pone a 000
MOV R1, #0
MOV R2, #0
RET
UNIDAD: INC R0 ;Incrementa unidades
RET
DECENA: MOV R0, #0 ;Pone a 0 las unidades
INC R1 ;Incrementa decenas
RET
CENTENA: MOV R0, #0 ;Pone a 0 unidades y decenas
MOV R1, #0
INC R2 ;Incrementa centenas
RET
SUTURNO
Inicialización
P2.0=0
P2.1=0
Refresca
dígitos
Rutina
contador
Rutina
puesta a cero
SI
SI
NO
NO
Fig. 5.19
;***********************************
;Subrutina de retardo RETA
;(Retardo de 2+(2*256+2)*12+2= 6172 ÷s)
;***********************************
RETA: MOV R7, #12
Buc2: MOV R6, #0
Buc1: DJNZ R6, Buc1
DJNZ R7, Buc2
RET
;**************************************************************************
;Subrutina Display (Muestra en los dígitos el valor de la cuenta
;Registros afectados: R0, R1, R2
;**************************************************************************
Display: MOV P1, R2 ;Pone centenas en P1 (4 bits altos de R2 son cero)
SETB P1.4 ;Enciende dígito centenas. Tr1 en conducción
CALL RETA ;Realiza un retardo (tiempo de encendido de dígito)
CLR P1.4 ;Apaga dígito centenas. Tr1 en corte
MOV P1, R1 ;Pone decenas en P1 (4 bits altos de R1 son cero)
SETB P1.5 ;Enciende dígito decenas. Tr2 en conducción
CALL RETA ;Realiza un retardo (tiempo de encendido de dígito)
CLR P1.5 ;Apaga dígito decenas. Tr2 en corte
MOV P1, R0 ;Pone unidades en P1 (4 bits altos de R0 son cero)
SETB P1.6 ;Enciende dígito unidades. Tr3 en conducción
CALL RETA ;Realiza un retardo (tiempo de encendido de dígito)
CLR P1.6 ;Apaga dígito unidades. Tr3 en corte
RET
Cada uno de los dígitos se enciende durante un tiempo de 6172÷s, aproximadamente (suponiendo un
reloj de 12MHz). Por tanto, el número se muestra cada 6172*3÷s, lo que supone una frecuencia de
© Los autores, 2001; © Edicions UPC, 2001.
5 El modelo de programación 125
refresco del número visualizado de 54Hz, aproximadamente. Esta frecuencia puede ser superior,
puesto que se tiene una limitación de frecuencia mínima, pero no en cuanto a frecuencia máxima.
Luego, la frecuencia de refresco de todos los dígitos puede ser de 100Hz o de 1kHz, con la única
limitación del ancho de banda de los transistores Tr1, Tr2 o Tr3 y del 4511.
5.10.6 Contador de piezas
Con una pequeña modificación del circuito y del programa anterior se puede realizar un contador de
piezas para una máquina en un proceso industrial (figura 5.20). En esta aplicación se dispone de dos
sensores que se simbolizan por una caja con un conmutador. Un sensor indica cuándo se ha producido
una pieza y el otro indica cuándo el proceso posterior de control de calidad descarta una pieza
defectuosa. Por tanto, el contador muestra siempre el número neto de piezas fabricadas.
87C51
P1.4
P1.5
P1.6
P1.1
P1.2
P1.3
P1.0
Cátodo común
R
R
a
b
dp
a
dp
4511
(BCD-7seg)
A0
A1
A2
A3
Vcc
Reset
P2.0
P2.2
Rb
Rb
Rb
/EL
Centenas Decenas Unidades
Tr1 Tr2 Tr3
P1.7
Millares
Tr4
Rb
Vcc
Vcc
Sensor
Cuenta
Sensor
Descuenta
P2.1
P2.4Alarma
Fig. 5.20 Circuito del ejemplo del contador de piezas
Al circuito anterior se le ha añadido un dígito más, por lo que la cuenta puede llegar hasta 9999
piezas. Si el número de piezas llega a su máximo valor y se rebasa éste, por un pulso más recibido, el
contador debe mostrar el número máximo de 9999 y activar la señal de alarma conectada a la patilla
P2.4 del microcontrolador. Si el contador está a 0000 y recibe un pulso del sensor de descuenta, se
activará también la señal de alarma conectada a P2.4, para indicar un mal funcionamiento del sensor o
al error en el proceso de control de calidad.
;**********************************************************************
; Programa para el contador de piezas
;**********************************************************************
ORG 0H
MOV P1, #0 ;Pone a cero la entrada del 4511. Pone en corte Tr1, Tr2, Tr3 y Tr4
MOV R0, #0 ;Pone a cero los registros de cada dígito
MOV R1, #0
MOV R2, #0
MOV R3, #0
CLR P2.4 ;Pone P2.4 a cero, para no activar la alarma
;**********************************************************************
; Rutina Principal
;**********************************************************************
Principal: JNB P2.0, Cuenta
JNB P2.1, Descuenta
JNB P2.2, PaCero
Prin2: CALL Display
SJMP Principal
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251126
Cuenta: CALL CONTA
SJMP Prin2
Descuenta: CALL DECRE
SJMP Prin2
;***********************************************************
;Rutina PaCero
;***********************************************************
MOV R0, #0 ;Borra unidades
MOV R1, #0 ;Borra decenas
MOV R2, #0 ;Borra centenas
MOV R3, #0 ;Borra millares
CLR P2.4 ;Borra alarma
SJMP Prin2
;***********************************************************
;Rutina CONTA
;Registros afectados: R0, R1, R2, R3
;***********************************************************
CONTA: CJNE R0, #9, Unidad ;Compara unidad
CJNE R1, #9, Decena ;Compara decena
CJNE R2, #9, Centena ;Compara centena
CJNE R3, #9, Millar ;Compara millar
SETB P2.4 ;Activa la alarma
RET
Unidad: INC R0 ;Incrementa unidades
RET
Decena: MOV R0, #0 ;Pone a 0 las unidades
INC R1 ;Incrementa decenas
RET
Centena: MOV R0, #0 ;Pone a 0 unidades y decenas
MOV R1, #0
INC R2 ;Incrementa centenas
RET
Millar: MOV R0, #0 ;Pone a 0 unidades, decenas y centenas
MOV R1, #0
MOV R2, #0
INC R3 ;Incrementa millares
RET
;**********************************************************
;Rutina DECRE
;Registros afectados: R0, R1, R2 y R3
;**********************************************************
DECRE: CJNE R0, #0, D_uni ;Compara unidad
CJNE R1, #0, D_dece ;Compara decena
CJNE R2, #0, D_cent ;Compara centena
CJNE R3, #0, D_mill ;Compara millar
SETB P2.4 ;Activa la alarma
RET
D_uni: DEC R0 ;Decrementa unidad
RET
D_dece: MOV R0, #9 ;Pone a 9 unidad
DEC R1 ;Decrementa decena
RET
D_cent: MOV R0, #9 ;Pone a 9 unidad
MOV R1,#9 ;Pone a 9 decena
DEC R2 ;Decrementa centena
RET
D_mill: MOV R0, #9 ;Pone a 9 unidad
MOV R1,#9 ;Pone a 9 decena
MOV R2,#9 ;Pone a 9 centena
DEC R3 ;Decrementa millar
RET
© Los autores, 2001; © Edicions UPC, 2001.
5 El modelo de programación 127
;*******************************************************************
;Subrutina Display (Muestra en los dígitos el valor de la cuenta
;Registros afectados: R0, R1, R2 y R3
;*******************************************************************
Display: MOV P1, R3 ;Pone millares en P1 (4 bits altos de R3 son cero)
SETB P1.4 ;Enciende dígito millares. Tr1 en conducción
CALL RETA ;Realiza un retardo (tiempo de encendido de dígito)
CLR P1.4 ;Apaga dígito millares. Tr1 en corte
MOV P1, R2 ;Pone centenas en P1 (4 bits altos de R2 son cero)
SETB P1.5 ;Enciende dígito centenas. Tr2 en conducción
CALL RETA ;Realiza un retardo (tiempo de encendido de dígito)
CLR P1.5 ;Apaga dígito centenas. Tr2 en corte
MOV P1, R1 ;Pone decenas en P1 (4 bits altos de R1 son cero)
SETB P1.6 ;Enciende dígito decenas. Tr3 en conducción
CALL RETA ;Realiza un retardo (tiempo de encendido de dígito)
CLR P1.6 ;Apaga dígito decenas. Tr3 en corte
MOV P1, R0 ;Pone unidades en P1 (4 bits altos de R0 son cero)
SETB P1.7 ;Enciende dígito unidades. Tr4 en conducción
CALL RETA ;Realiza un retardo (tiempo de encendido de dígito)
CLR P1.7 ;Apaga dígito unidades. Tr4 en corte
RET
;*************************************************************
;Subrutina de retardo RETA (Retardo de 1+2*123+2= 251 ÷s)
;*************************************************************
RETA: MOV R7,#125
Buc1: DJNZ R7, Buc1
RET
En este caso cada dígito se enciende durante 251÷s, aproximadamente, lo que supone una frecuencia
de refresco del número visualizado de 996Hz. Las rutinas “Conta” y “Decre” son una modificación de
las subrutinas iniciales explicadas en este capítulo.
5.10.7 Control de un ascensor
Esta aplicación consiste en el diseño del sistema de control, basado en el ÷C 8XC251, de un ascensor
de carga de una mina de carbón. La tarea del ascensor consiste en elevar hasta la superficie las
vagonetas cargadas de carbón. El ascensor se pone en funcionamiento cuando se coloca en su interior
una vagoneta, a continuación asciende hasta que llega a la superficie, donde descarga de forma
automática la vagoneta, y baja otra vez al interior de la mina con la vagoneta vacía (figura 5.21).
8XC251
P1.2
P0.0
P0.1
P1.1
S2
Ascensor
S1Motor
M0M1
S3
P1.3
Fig. 5.21 Diagrama del sistema de control de un ascensor
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251128
Una vez que el ascensor llega abajo se detiene y los operarios sacan la vagoneta del ascensor, la llenan
de carbón y la vuelven a colocar dentro del ascensor; se repite de nuevo la secuencia.
El sistema de control del ascensor incorpora tres sensores, S1, S2 y S3, activos a nivel alto, cuyo
funcionamiento se describe a continuación:
� S1: Este sensor está colocado dentro del ascensor y detecta la presencia de la vagoneta, en
cuyo caso se pone a 1 lógico. Si no hay vagoneta, el sensor se pone a 0 lógico.
� S2: Este sensor está colocado en la exterior de la mina y detecta que el ascensor ha llegado
hasta la superficie.
� S3: Este sensor está colocado en el interior de la mina y detecta que el ascensor ha llegado al
fondo de la mina.
Por otra parte, el sistema dispone de un motor que permite elevar o descender el ascensor. El motor
está controlado mediante dos señales binarias, M1 y M0, que funcionan tal y como se indica en la
tabla 5.2. En la figura 5.21 se detalla la conexión entre los sensores, los actuadores y el
microcontrolador 8XC251.
;************************************************************
; Control del ascensor
;************************************************************
ORG FF:0000H ; El programa está almacenado a partir de la
; dirección FF:0000H de la memoria
;Inicialización de los puertos
SETB P0.0 ; Se inicializan P0.0 y P0.1 del puerto a 1
SETB P0.1 ; con lo que el motor estará detenido
MOV P1,#FFH ; Los pines que trabajan como entrada, deben
; inicializarse a 1 lógico
; Programa de control
SIGUE: JNB P1.1,SIGUE ; Detecta si coloca la vagoneta en el ascensor
CLR P0.1 ; El ascensor sube
SIGUE1: JNB P1.2,SIGUE2 ; Detecta si el ascensor llega a la superficie
SETB P0.1 ; El ascensor baja
CLR P0.0 ;
SIGUE2: JNB P1.3,SIGUE3 ; Se detecta que el ascensor llega abajo
SETB P0.0 ; El ascensor se detiene
SIGUE4: JB P1.1,SIGUE4 ; Detecta si sacan la vagoneta del ascensor
JMP SIGUE ; El programa vuelve al inicio
SI
NO
¿VAGONETAEN EL ASCENSOR?
EL ASCENSOR SUBE
¿EL ASCENSOR LLEGAA LA SUPERFICIE?
NO
SI
SI
INICIO
SE INICIALIZAN LASENTRADAS A 1 LOGICO
SE INHIBENLAS SALIDAS
NO
EL ASCENSOR SE PARA
NO
SI
SI
EL ASCENSOR BAJA
SI
¿EL ASCENSORLLEGA ABAJO?
¿VAGONETAEN EL ASCENSOR?
NO
SINO
Fig. 5.22 Diagrama de flujo delprograma de control del ascensor
© Los autores, 2001; © Edicions UPC, 2001.
5 El modelo de programación 129
Tabla 5.2 Condiciones de funcionamiento del motor
M1 M0 Funcionamiento del motor0 0
0 1
1 0
1 1
El motor está parado.
El motor gira a la derecha y el ascensor sube.
El motor gira a la izquierda y el ascensor baja.
El motor está parado.
El programa que controla la secuencia de funcionamiento del ascensor debe detectar, mediante
instrucciones de salto condicional, que se coloca una vagoneta en el interior del ascensor para, a
continuación, activar el motor con el fin de subir el ascensor. Mientras el ascensor sube, el programa
debe detectar cuándo llega a la superficie, testeando para ello el valor lógico de la entrada conectada al
sensor S2. Cuando S2 se activa, se debe colocar en las salidas M0 y M1 el valor lógico 0 y 1,
respectivamente, para que el ascensor baje. A continuación, se debe detectar que el ascensor ha
llegado abajo, testeando el sensor S3 con una instrucción de salto condicional. Por último se detecta
que se saca la vagoneta del ascensor, para seguidamente retornar al inicio del programa.
En la figura 5.22 se muestra el diagrama de flujo del programa de control y el listado del programa.
5.10.8 Control de un calefactor
Esta aplicación trata del diseño de un sistema de control de un calefactor, basado en el
microcontrolador 8XC251. Para controlar el calefactor se disponen de 3 sensores de
temperatura activos a nivel alto: T1, T2 y T3; de un selector de temperatura ambiente S y de un
actuador M que enciende o apaga el calefactor. El funcionamiento de los sensores de temperatura se
describe a continuación:
� T1: se activa a 1 lógico cuando la temperatura es igual o mayor que 20ºC.
� T2: se activa a 1 lógico cuando la temperatura es igual o mayor que 25ºC.
� T3: se activa a 1 lógico cuando la temperatura es igual o mayor que 30ºC.
El selector de temperatura S es una entrada binaria que permite seleccionar entre dos rangos de
temperatura ambiente: cuando S es igual a 0 lógico, la temperatura debe mantenerse entre 20 y 25ºC.
Cuando S es igual a 1 lógico, la temperatura debe mantenerse entre 25 y 30ºC.
El microcontrolador 8XC251 encenderá el calefactor y pondrá la salida M a 1 lógico, cuando la
temperatura sea inferior al valor mínimo del rango seleccionado con S. El calefactor debe permanecer
encendido hasta que la temperatura supere el valor máximo del rango seleccionado, en cuyo caso, se
debe apagar hasta que la temperatura sea de nuevo inferior al valor mínimo del rango seleccionado.
En la figura 5.23 se detalla la conexión de los sensores y actuadores al microcontrolador 8XC251.
8XC251
P1.0
P1.1
P1.2
P1.3
P1.4
CALEFACTOR
M
T1
T2
T3
S
Fig. 5.23 Esquema conexión de los sensores/actuadores al microcontrolador 8XC251
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251130
El programa de control del calefactor debe detectar, en primer lugar, qué rango de temperatura estáseleccionado. Esto se realiza testeando el valor lógico del pin P3.1. Si este bit está a 0 lógico, se salta a
la rutina que mantiene la temperatura entre 20 y 25ºC, y si vale 1 lógico se ejecuta a la rutina que
mantiene la temperatura entre 25 y 30ºC.
NO
RANGO = 25/30ºC ?
SE ENCIENDE
EL CALEFACTOR
TEMPERATURA
> 25 ºC ?
SI
NO
SI
INICIO
SI
SE APAGA
EL CALEFACTOR
NO
SI
TEMPERATURA
< 20 ºC ?
RANGO = 25/30ºC ?SI
NO
RANGO = 25/30ºC ?SI
NO
1 2
NO
RANGO = 20/25ºC ?
SE ENCIENDE
EL CALEFACTOR
TEMPERATURA
> 30 ºC ?
SI
NO
SI
SI
SE APAGA
EL CALEFACTOR
NO
SI
TEMPERATURA
< 25 ºC ?
RANGO = 20/25ºC ?SI
NO
RANGO = 20/25ºC ?SI
NO
2 1
Fig. 5.24 Diagrama de flujo del programa de control del calefactor
Comprobando el valor lógico de los distintos sensores de temperatura y teniendo en cuenta el rango de
temperatura seleccionado se decide si el calefactor debe estar activo o no. En la figura 5.24 se presenta
el flujograma de esta aplicación; a continuación se presenta el listado del programa.
;***********************************************************************
; Control del calefactor
;***********************************************************************
ORG FF:0000H ; El programa está almacenado en memoria a partir de la
; dirección FF:0000H
MOV C,P1.3 ; En primer lugar se lee el valor del selector S para conocer en
; que rango de temperatura debe mantenerse la habitación
JC T25_30 ; Si S es igual a 1 lógico se salta a la dirección T25_30
© Los autores, 2001; © Edicions UPC, 2001.
5 El modelo de programación 131
En el caso de que S sea igual a 0 lógico, se enciende el calefactor hasta que se activa el sensor T2, lo
cual quiere decir que la temperatura ha superado los 25°C, en cuyo caso se desactiva el calefactor. El
calefactor permanece apagado hasta que se desactiva T1; entonces se vuelve a encender. En todo
momento se comprueba la entrada S para saltar a la dirección T25_30 en el caso que valga 1 lógico.
;************************************************************************
; Rutina del rango 20-25ºC;************************************************************************
T20_25: SETB P1.4 ; Se activa el calefactor
SIGUE1: JB P1.3,T25_30 ; Se comprueba si está seleccionado el rango 20/25ºCJNB P1.1,SIGUE1 ; Si la temperatura es menor que 25ºC, el calefactor
; seguirá encendido
CLR P1.4 ; Se apaga el calefactor
SIGUE2: JB P1.3,T25_30 ; Se comprueba si está seleccionado el rango 20/25ºCJB P1.0,SIGUE2 ; Si la temperatura es mayor que 20ºC, el calefactor
; seguirá apagado
JMP T20_25 ; Se vuelve al comienzo de la rutina
Cuando S es igual a 1 lógico, la temperatura de la habitación debe mantenerse entre 25 y 30°C. En
este caso se debe encender el calefactor, y apagarse cuando se active el sensor T3. El calefactor
permanecerá apagado hasta que se desactive T2, repitiéndose nuevamente la secuencia. Como en el
caso anterior, en todo momento se sensa la variable S para saltar a la rutina T20_25 en el caso que
valga 0 lógico.
;*****************************************************************************
; Rutina del rango 25-30ºC;*****************************************************************************
T25_30: SETB P1.4 ; Se activa el calefactor
SIGUE3: JNB P1.3,T20_25 ; Se comprueba si está seleccionado el rango 25/30ºCJNB P1.2,SIGUE3 ; Si la temperatura es menor que 30ºC, el calefactor
; seguirá encendido
CLR P1.4 ; Se apaga el calefactor
SIGUE4: JNB P1.3,T20_25 ; Se comprueba si está seleccionado el rango 25/30ºC.
JB P1.1,T25_30 ; Si la temperatura es mayor que 20ºC, el calefactor
; seguirá apagado
JMP T25_30 ; Se vuelve al comienzo de la rutina
5.10.9 Control de una cinta elevadora
En esta aplicación se debe diseñar un sistema de control de un elevador de una cinta transportadora
basado en el microcontrolador 8XC251. La tarea del elevador es la llevar una caja de un determinado
producto, que llega por la cinta A, hasta la cinta B o C. El sistema incorpora los siguientes detectores
(figura 5.25):
� D1: Este detector está colocado junto a la cinta A. Cuando llega una caja a la plataforma
elevadora, este sensor decide si hay que llevarla a la cinta B o a la cinta C. Si D1 es igual a 0
lógico, hay que llevar el producto a la cinta B, fig. 5.26, y si D1 es igual a 1 lógico, a la cinta
C (figura 5.27).
� D2: Este sensor se activa (1 lógico) cuando la plataforma está a la altura de la cinta A.
� D3: Este sensor se activa (1 lógico) cuando llega un producto a la plataforma elevadora.
� D4: Este sensor se activa (1 lógico) cuando la plataforma elevadora ha llegado a la cinta B.
� D5: Este sensor se activa (1 lógico) cuando la plataforma elevadora ha llegado a la cinta C.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251132
Motor
Cinta A
Cinta C
Cinta B
M0
D1
M1
D4
D5
P1.1
P1.2
P1.3
P1.5
P1.4
P3.0
P3.1
8XC251
CAJA
D2 D3
Fig. 5.25 Diagrama del sistema de control
Motor
Cinta C
Cinta B
CAJA
Cinta A
D1=0
Fig. 5.26 Elevación de la caja a la cinta B, D1 igual a 0lógico
Motor
Cinta C
Cinta B
Cinta A
D1=1
CAJA
Fig. 5.27 Descenso de la caja a la cinta C, D1 iguala 1 lógico
Por otra parte, el sistema dispone de un motor que permite ascender o descender la plataforma
elevadora. El motor está controlado mediante dos señales binarias, M1 y M0, que funcionan tal y
como se indica en la tabla 5.3.
Tabla 5.3 Condiciones de funcionamiento del motor.
M1 M0 Funcionamiento del motor 0 0
0 1
1 0
1 1
El motor está parado.
El motor gira a la derecha y la plataforma sube.
El motor gira a la izquierda y la plataforma baja.
El motor está parado.
El programa que controla el funcionamiento de la plataforma elevadora debe cumplir las siguientes
indicaciones: cuando llegue un producto a la plataforma elevadora (D3 igual a 1 lógico) la plataforma
deberá subir hasta la cinta B o bajar hasta la cinta C, dependiendo del valor que adquiera el detector
D1. Una vez que la plataforma ha llegado a la cinta B o C, debe volver a la posición original, junto a
la cinta A, para esperar a que llegue un nuevo producto; entonces se vuelve a repetir el proceso.
Inicialmente la plataforma elevadora se encuentra a la altura de la cinta A.
© Los autores, 2001; © Edicions UPC, 2001.
5 El modelo de programación 133
En una primera parte del programa se deben inicializar los puertos con el valor lógico adecuado. Los
pines de los puertos que actúan como entradas de datos, han de estar inicializados a 1 lógico y los
pines que trabajan como salida han de inicializarse por defecto con el nivel inactivo. En la figura 5.28
se presenta el diagrama de flujo del programa de control de la plataforma elevadora y a continuación
se detalla el listado.
SI
NO
¿PRODUCTO
EN LA PLATAFORMA?
¿PLATAFORMAEN CINTA B?
NO
SI
SI
INICIO
SE INICIALIZAN LAS
ENTRADAS A 1 LOGICO
SE INHIBENLAS SALIDAS
EL MOTOR SE PARA
SI
LA PLATAFORMA BAJA
NO
D1 = 1?SI
NO
LA PLATAFORMA SUBE
¿PLATAFORMA
EN CINTA A?
12
SI
NO ¿PLATAFORMAEN CINTA C?
SI
EL MOTOR SE PARA
SI
LA PLATAFORMA SUBE
NO
LA PLATAFORMA BAJA
¿PLATAFORMAEN CINTA A?
12
Fig. 5.28 Diagrama de flujo del programa de control de la plataforma elevadora
;***********************************************************************************
; Control de la plataforma elevadora
;***********************************************************************************
ORG FF:0000H ; El programa comienza a partir de la dirección FF:0000H de memoria
; Inicialización de las entradas y salidas
CLR P3.0 ; Los pines de salida se inicializan a cero lógico que es el
CLR P3.1 ; nivel inactivo en este caso
SETB P1.1 ; Los pines correspondientes a los puertos de entrada, como
SETB P1.2 ; son los que están conectados a los sensores, se inicializan
SETB P1.3 ; con un uno lógico, para evitar que no se dañe el transistor de
SETB P1.4 ; salida
SETB P1.5 ;
; Programa de control
SAL1: JNB P1.3,SAL1 ; Se espera a que llegue un producto a la plataforma
JB P1.1,SAL2 ; Si D1=1 la plataforma baja, en caso contrario sube
SETB P3.0 ; La plataforma sube
CLR P3.1 ;
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251134
SAL3: JNB P1.4,SAL3 ; Se espera a que la plataforma llegue arriba
CLR P3.0 ; La plataforma baja
SETB P3.1 ;
SAL4: JNB P1.2,SAL4 ; Se espera a que la plataforma llegue a la cinta A
CLR P3.1 ; Paramos el motor
SAL2: CLR P3.0 ; La plataforma baja
SETB P3.1 ;
SAL5: JNB P1.5,SAL5 ; Se espera a que la plataforma baje hasta la altura de la cinta C
CLR P3.1 ; La plataforma sube
SETB P3.0 ;
SAL6: JNB P1.1,SAL6 ; Se espera a que la plataforma llegue a la cinta A
CLR P3.0 ; Se para el motor
JMP SAL1 ; Vuelta al inicio
5.10.10 Control de la temperatura de un horno de cocción
Se plantea, en este caso, una aplicación donde se controla la temperatura de un horno de cocción,
mediante un microcontrolador 8XC251Sx. Para poder controlar la temperatura del horno de cocción,
el microcontrolador debe recibir la información del estado del sistema que le llega a través de los
puertos, procesar esa información mediante el algoritmo de control correspondiente y actuar sobre el
sistema, también a través de los puertos, para que el comportamiento del horno se mantenga dentro de
los límites fijados. En concreto, la acción de control a la que se somete el horno, tiene como objetivo
mantener su temperatura dentro del margen comprendido entre los 275ºC y los 300ºC. El horno de
cocción, cuyo esquema está representado en la figura 5.29, contiene los siguientes elementos:
� Un tanque de fuel-oil, que almacena el combustible que alimenta el quemador.
� Una bomba P, que impulsa el fuel-oil hacia el quemador B1 instalado en el horno, o bien hacia
el tanque.
� Dos electroválvulas V1 y V2. La electroválvula V1 se encarga de controlar el paso del fuel-oilal quemador B1. La electroválvula V2 se encarga de controlar el retorno del fuel-oil al tanque.
� Un horno de cocción, calentado por el quemador B1, que incorpora dos sensores de
temperatura.
Horno
T2
Sensores de
temperatura
B1P
Tanque
V1
V2
T1
Fig. 5.29 Esquema del horno de cocción
Para realizar el control del sistema se dispone de una serie de sensores y actuadores electromecánicos
que permiten obtener información sobre el estado del sistema y actuar convenientemente sobre él.
Todos los sensores y actuadores son activos a 1 lógico y presentan el siguiente funcionamiento:
© Los autores, 2001; © Edicions UPC, 2001.
5 El modelo de programación 135
1. Sensores
� T1: Detector de temperatura del horno que se activa cuando la temperatura del horno
aumenta por encima de 275ºC.
� T2: Detector de temperatura del horno que se activa cuando la temperatura del horno
aumenta por encima de 300ºC.
� NL: Detector de nivel del tanque, que se activa cuando el nivel del tanque disminuye por
debajo de un valor determinado.
2. Actuadores
� PP: Accionador de la bomba P. Cuando se activa este actuador, la bomba P se pone en
funcionamiento.
� XV1, XV2: Son los actuadores que abren o cierran las electroválvulas V1 y V2,
respectivamente. Cuando se activan, la válvula correspondiente se abre y permite el paso del
fuel-oil al quemador o al tanque.
� LR: Además de los detectores y activadores antes descritos, el sistema dispone de un
indicador rojo cuya activación, a 1 lógico, indica que el horno se halla fuera de servicio.
La estrategia de control, que debe implementar el sistema de control del horno, se puede resumir en
tres puntos:
1. Si el nivel del tanque disminuye por debajo del nivel indicado por el sensor NL, se debe parar
la bomba, abrir la electroválvula V2, cerrar V1 y señalizar que el sistema está fuera de
servicio activando el indicador rojo.
2. Si la temperatura del horno desciende por debajo de 275ºC, debe alimentarse el quemador
con combustible abriéndose la electroválvula V1, cerrándose la electroválvula V2, y
activándose la bomba.
3. Si la temperatura del horno supera el valor de 300ºC, se debe suspender la alimentación del
quemador cerrándose la electroválvula V1, abriéndose la electroválvula V2 y activándose la
bomba.
En la figura 5.30 está representado el esquema eléctrico de la conexión del microcontrolador
8XC251Sx con los diferentes sensores y actuadores que intervienen en esta aplicación.
8XC251Sx
T1 P0.0
T2 P0.1
NL P0.2
P1.3 LR
P1.2 PP
P1.1 XV2
P1.0 XV1
Fig. 5.30 Conexión de los sensores y actuadores con el microcontrolador 8XC251Sx
En la figura 5.31 está representado el diagrama de flujo de esta aplicación. Están reflejadas las tres
opciones posibles, planteadas por la estrategia de control y la actuación que se debe llevar a cabo en
cada caso.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251136
INICIO
NL = 1?
T2 = 1?
T1 = 0?
Cerrar V1
Abrir V2
Parar la bomba
Activar luz roja
Abrir V1
Cerrar V2
Encender la bomba
Cerrar V1
Abrir V2
Encender la bomba
SI
SI
SI
NO
NO
NO
Fig. 5.31 Organigrama del control del horno
Las primeras instrucciones del programa de control deben colocar, por motivos de seguridad, todos los
pines de salida a su nivel inactivo, ya que las salidas sólo se deben activar después de procesar los
datos de entrada, mediante el programa de control correspondiente. De igual modo, todos los pines de
entrada deberán ponerse a 1 lógico para evitar la destrucción del driver de salida correspondiente. A
continuación se detalla el listado del programa resultante.
;******************************************************************
; Control del horno
;******************************************************************
ORG FF:0000H ; Dirección de inicio del programa
MOV P1,#00H ; Se inicializan todas las salidas a su nivel inactivo
SETB P0.0 ; Se inicializan todos los pines de entrada a 1 lógico
SETB P0.1 ;
SETB P0.2 ;
INICIO: JNB P0.2,SALT1 ; Si el nivel del depósito está por debajo del valor
CLR P1.2 ; permitido se para la bomba,
CLR P1.0 ; se cierra la electroválvula V1,
SETB P1.1 ; se abre la electroválvula V2,
SETB P1.3 ; y se enciende la luz roja
JMP INICIO ; Salto al INICIO
SALT1: JB P0.0,SALT2 ; Si el sensor T1 está inactivo:
SETB P1.0 ; se abre la electroválvula V1,
SETB P1.2 ; se activa la bomba,
CLR P1.1 ; se cierra la electroválvula V2,
CLR P1.3 ; y se apaga la luz roja
JMP INICIO ; Salto al INICIO
SALT2: JNB P0.1,INICIO ; Si el sensor T2 está activo:
CLR P1.0 ; Se cierra la electroválvula V1,
SETB P1.2 ; se activa la bomba,
SETB P1.1 ; se abre la electroválvula V2,
CLR P1.3 ; y se apaga la luz roja
JMP INICIO ; Salto al INICIO
© Los autores, 2001; © Edicions UPC, 2001.
6 Las interrupciones 137
6 Las interrupciones
6.1 Introducción
Las interrupciones juegan un papel de suma importancia dentro de cualquier sistema basado en
microprocesador o microcontrolador, pues estos deben habitualmente gestionar y controlar distintos
periféricos asociados que, de forma continua, requieren la dedicación de la CPU para llevar a buen
término las tareas que tienen asignadas.
Una interrupción la realiza de forma asíncrona un periférico1
o un dispositivo conectado físicamente al
microcontrolador (figura 6.1), cuando requiere a la CPU el desvío del flujo de ejecución del programa
para gestionar y controlar los diversos sucesos que no se encuentran bajo su supervisión directa. De
esta manera se mejora la eficiencia de la CPU, ya que ésta no tiene que estar continuamente pendiente
de si acontece o no un suceso en un instante de tiempo determinado, y puede realizar otras tareas de
mayor interés, atendiendo a los sucesos tan sólo cuando éstos se producen. Los sucesos acontecidos
pueden ser externos al sistema, como la activación de un nivel lógico o un flanco en un terminal del
microcontrolador, por parte de un periférico, o bien internos, como el desbordamiento de un
temporizador interno del microcontrolador al llegar éste a su máxima capacidad de cuenta.
÷ C
Módems
Discos magnéticos
Terminal de vídeo
Teclado y visualizador
Impresora
Sensores y actuadores
Fig. 6.1 Diagrama de bloques del microcontrolador con distintos periféricos
Cuando se produce una interrupción el microcontrolador ejecuta un proceso de atención a la
interrupción (figura 6.2). En este proceso la CPU deja de ejecutar la secuencia de instrucciones en la
que se encuentra y pasa a ejecutar la rutina de servicio a la interrupción (RSI), que se encarga de
efectuar la gestión del periférico. Una vez terminada esta rutina, la CPU regresa a la secuencia donde
se produjo la interrupción, y sigue con el rumbo que tenía. En el proceso de atención a la interrupción
1
Un periférico es un dispositivo conectado al microcontrolador con una función específica. Un periférico puede ser una
impresora, un módem, un teclado alfanumérico, un terminal de vídeo, un sensor, un actuador, etc.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251138
se realizan los siguientes pasos:
1. Termina de ejecutar la instrucción en curso.
2. Salva el valor del contador de programa, PC, en la pila, de manera que la CPU, al
terminar el proceso, pueda seguir ejecutando el programa a partir de la instrucción
siguiente a la última ejecutada.
3. La CPU salta a la dirección donde está almacenada la rutina de servicio de interrupción
(RSI) y ejecuta esta rutina, que tiene como finalidad atender al periférico o dispositivo
que ha generado la interrupción.
4. La rutina RSI debe terminar con una instrucción de retorno de interrupción, RETI. La
CPU al ejecutar esta instrucción lee la dirección almacenada en la pila y la asigna al
contador de programa, de manera que la CPU reanuda la ejecución del programa a partir
de la instrucción siguiente a la instrucción donde se produjo la interrupción.
Interrupción - Terminar instrucción en curso
- Salvar el PC en la pila
- Saltar a RSI
RSI
RETI- Recuperar PC de pila
- Saltar a dirección del PC
Programa
principal
Programa
principal
Fig. 6.2 Proceso de atención a una interrupción
A la dirección de salto a partir de la cual se almacena la rutina de RSI2
se la denomina vector deinterrupción. Según el tipo de microcontrolador o microprocesador, las direcciones del vector de
interrupción pueden ser fijas, es decir, especificadas por el fabricante, o bien pueden ser definidas por
el programador. Los vectores de interrupción de las familias MCS-51 y MCS-251 son fijos y su valor
viene predeterminado por el fabricante.
Otro factor importante que se debe considerar en el proceso de interrupciones consiste en la
habilitación de máscaras y en el establecimiento de prioridades. Una máscara no es más que un
indicador de tipo bit que gobierna el estado de una puerta de transmisión3
conectada entre la entrada
en interrupción y la CPU. Al bit que realiza la función de máscara se le denomina bit de habilitación
2
Se debe considerar que el microcontrolador puede tener varias fuentes de interrupción, por lo que a cada fuente de
interrupción le corresponde una rutina especifica de RSI.3
Una puerta de transmisión se realiza con puertas lógicas o bien con transistores bipolares o MOS. Tiene una entrada, una
salida y una línea de control. La activación de la línea de control deja pasar el estado lógico presente en su entrada a su
salida; su desactivación hace que la puerta esté desconectada para evitar que el estado lógico de la entrada pase a la salida.
© Los autores, 2001; © Edicions UPC, 2001.
6 Las interrupciones 139
de interrupción. La activación de un bit de habilitación de interrupción permite que la interrupción
pase de la línea de entrada hacia la CPU, mientras que la desactivación de este bit hace que la
interrupción no pueda pasar hacia la CPU, e inhiba la interrupción; es decir, la interrupción no es
atendida a menos que su bit de habilitación correspondiente esté activado. Los bits de habilitación de
interrupciones permiten, pues, que el programador pueda activar o desactivar ciertas interrupciones, en
las circunstancias que sean de su consideración.
Generalmente todas las entradas de interrupción suelen tener un bit de habilitación de interrupción
asociado; no obstante, puede haber alguna entrada de interrupción que adolezca de este bit, lo que se
denomina interrupción no mascarable, en cuyo caso el programador no tiene control sobre la
interrupción y la CPU está obligada siempre a atenderla. Las interrupciones no mascarables se
reservan para aquellos periféricos o sucesos de suma importancia, como, por ejemplo, la caída de
tensión de la red eléctrica, en que la CPU dispone de los pocos milisegundos en los que los
condensadores de la fuente de alimentación son capaces de sostener la tensión de alimentación para
salvar los registros que se consideren imprescindibles en una memoria estable, como una memoria
E2PROM o una memoria RAM con una batería externa.
El establecimiento de prioridades dentro del proceso de interrupción se considera cuando existe la
posibilidad de que varias interrupciones se produzcan de manera simultánea, por lo que es necesario
estipular un orden de atención a las interrupciones producidas. Para ello, las entradas de interrupción
suelen tener uno o varios bits asociados con los que el programador puede establecer un orden de
prioridad en la atención de las interrupciones.
6.2 Las interrupciones en la familia MCS-51
La familia MCS-51 puede llegar a tener hasta siete fuentes de interrupción distintas (figura 6.3), todas
ellas con un bit de habilitación de interrupción situado en el registro IE, Interrupt Enable -dirección
A8H del SFR-, de forma que el programador puede habilitarlas o deshabilitarlas cuando sea necesario.
Respecto a las prioridades, todos los componentes de la familia tienen dos niveles de prioridad que se
determinan con un único bit, para cada entrada de interrupción, situado en el registro IP, InterruptPriority -dirección B8H del SFR-, con excepción de las versiones 8XC51Fx y 8XX52/54/58, que
tienen hasta cuatro niveles de prioridad; incorporan, para ello, un segundo registro de prioridad
denominado IPH, Interrupt Priority High -dirección B7H del SFR-. En este último caso, el nivel de
prioridad de una entrada de interrupción se determina mediante sus bits correspondientes de los
registros IP y IPH.
Tres de las seis fuentes de interrupción son externas al microcontrolador: /INT0, /INT1 y el puerto
serie, RI y TI; las fuentes de interrupción restantes son internas y corresponden a los tres
temporizadores, Timer 0, Timer 1 y Timer 2, y al array de contadores programable PCA de la familia
MCS-51. La interrupción de los temporizadores se produce por un desbordamiento en su valor
máximo; entonces se activan los bits de desbordamiento correspondientes: TF0, TF1 o TF2. La
interrupción de la PCA se genera mediante cualquiera de los bits EF, CCF0, CCF1, CCF2, CCF3,
CCF4 y CCF5 del registro CCON, PCA Counter Control Register; cada uno de estos bits de
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251140
interrupción tiene asociado un bit de habilitación de interrupción, bits ECF y ECCFn de los registros
CMOD, PCA Counter Mode Register y CCAPMn, PCA Compare/Capture Modules.
El Timer 2 tiene un bit adicional de interrupción, EXF2, que realiza una petición de interrupción si se
detecta un flanco de bajada en el terminal T2 del microcontrolador.
Tal y como muestra la figura 6.3, las interrupciones externas /INT0 y /INT1 se pueden activar tanto
por nivel lógico (cero lógico), como por flanco descendente, mediante la programación de los bits IT0
y IT1 del registro TCON, Timer Control (tabla 6.2), respectivamente. Poner uno de estos bits a cero
lógico hace que la interrupción se active por nivel lógico, mientras que a uno lógico se activa por
flanco descendente.
IT0 IE0
TF1
0
1
IT1
0
1
IE1
INT0
INT1
TF0
RI
TI
TF2
EXF2
ES
ET2
ET1
EX1
ET0
EX0
Registro IE
( * )
CF
CCFn
ECF
ECCFn
0
1
0
1 5
EC
EAInhibición global
( † )
* En las versiones con 3 temporizadores† En las versiones con PCA
Fig. 6.3 Fuentes de interrupción de la familia MCS-51
© Los autores, 2001; © Edicions UPC, 2001.
6 Las interrupciones 141
Al producirse una interrupción en una de las entradas externas de interrupción, /INT0 o /INT1, ya sea
por nivel lógico o por flanco descendente, el bit correspondiente, IE0 o IE1 del registro TCON, se
activa a uno lógico, indicando de esta manera que se ha realizado una petición de interrupción, y la
CPU pone en marcha el proceso de atención a la interrupción, siempre y cuando la interrupción estéhabilitada de antemano. En este proceso, los bits IE0 e IE1 se ponen a cero lógico de forma automática
cuando la interrupción se ha activado por flanco descendente. Sin embargo, si la interrupción se ha
activado por nivel lógico, los bits IE0 y IE1 se deben borrar por software dentro de la rutina de RSI.
El estado de las interrupciones externas /INT0 e /INT1 se comprueba una vez cada ciclo máquina, de
forma que la entrada de interrupción, para el caso de que esté activada por flanco descendente, se debe
sostener a nivel lógico alto al menos un ciclo máquina, y sostener a nivel lógico bajo al menos otro
ciclo máquina más, para que el flanco descendente sea detectado y se active el bit IE0 o IE1,
correspondiente. En el caso de que la interrupción esté activada por nivel lógico, la entrada de
interrupción se debe sostener a nivel lógico bajo al menos durante 1 ciclo máquina, para que la
interrupción sea detectada por la CPU.
En las interrupciones internas producidas por los temporizadores Timer 0 o Timer 1, se activan los bits
TF0 o TF1, según corresponda, del registro TCON a uno lógico, al realizar la petición de interrupción.
Estos bits se mantienen en este estado hasta que la CPU atiende la petición, momento en el cual los
pone a cero lógico de forma automática.
El temporizador Timer 2 puede producir una interrupción a través de la activación a uno lógico de los
bits TF2 o EXF2. Estos bits no se ponen a cero lógico de manera automática, sino que los debe poner
el programador por software.
Las interrupciones producidas por el puerto serie activan a uno lógico los bits TI o RI del registro
SCON, cuando el microcontrolador transmite un dato o cuando recibe un dato, respectivamente. Estos
bits los debe poner a cero lógico el programador mediante software.
La tabla 6.1 muestra los bits de petición de interrupción asociados a cada una de las fuentes de
interrupción.
Tabla 6.1 Fuentes de interrupción, bits activados y tabla de vectores de salto para la MCS-51
Fuente deinterrupción
Bit que activa Borrado por hardware Registro Vector desalto
/INT0
Timer 0/INT1
Timer 1Puerto serie
Timer 2PCA
IE0
TF0
IE1
TF1
RI, TI
TF2, EXF2
CF, CCFn†
No, por nivel. Si, por flanco.
Si.
No, por nivel. Si, por flanco.
Si.
No.
No.
No.
TCON
TCON
TCON
TCON
SCON
T2CON
CCON
0003H
000BH
0013H
001BH
0023H
002BH
0033H†n=0, 1, 2, 3, 4.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251142
Tabla 6.2 Registro TCON para la familia MCS-51
IT0IE0IT1IE1TR0TF0TF1
(LSB)(MSB) Registro TCON
TR1
Bit Comentario
TF1 Bit de rebasamiento del Timer 1. Se pone a 1 por hardware en el rebasamiento. La CPU lo pone a 0 cuando
procesa la interrupción y salta a la rutina de RSI.
TR1 Bit de marcha/paro del Timer 1. Se pone a 1 ó 0 por software para poner en marcha o parar el Timer 1TF0 Bit de rebasamiento del Timer 0. Se pone a 1 por hardware en el rebasamiento. La CPU lo pone a 0 cuando
procesa la interrupción y salta a la rutina de RSI.
TR0 Bit de marcha/paro del Timer 1. Se pone a 1 ó 0 por software para poner en marcha o parar el Timer 1IE1 Bit de interrupción del terminal /INT1. Se pone a 1 en una petición de interrupción, se pone a 0 por
hardware si /INT1 está activada por flanco descendente.
IT1 Bit de selección de interrupción por nivel o por flanco descendente de /INT1. A 0 la interrupción se activa
por nivel, a 1 se activa por flanco descendente.
IE0 Bit de interrupción del terminal /INT0. Se pone a 1 en una petición de interrupción, se pone a 0 por
hardware si /INT0 está activada por flanco descendente.
IT0 Bit de selección de interrupción por nivel o por flanco descendente de /INT0. A 0 la interrupción se activa
por nivel, a 1 se activa por flanco descendente.
6.2.1 Vectorización de interrupciones en la MCS-51
Cuando se produce una interrupción la CPU desvía el flujo de ejecución de instrucciones hacia las
rutinas de atención de interrupciones, RSI, definidas por el programador. En la MCS-51 las
direcciones de salto hacia las rutinas de RSI son fijas y están predefinidas por el fabricante en lo que
se denomina tabla de vectores de salto (tabla 6.1). En esta tabla, se observa cómo la interrupción
/INT0 provoca un salto a la dirección 03H de la memoria de programas, la TIMER0 a la 0BH, la
/INT1 a la 013H, etc. A partir de estas direcciones debe situarse la rutina de RSI que corresponda.
En la tabla 6.1 también se observa que el espacio existente entre los vectores de interrupción es de tan
sólo 8 bytes. Este espacio suele ser insuficiente para albergar una rutina de RSI, por lo que, en estas
posiciones, se suele insertar una instrucción de salto, LJMP, AJMP o SJMP, hacia la rutina de RSI que
atienda a la interrupción; así, se puede situar esta rutina en cualquier zona del espacio de memoria
disponible por el microcontrolador.
El retorno de una rutina de RSI se debe realizar con la instrucción RETI, para que la CPU diferencie
este retorno, del retorno de subrutina (instrucción RET).;**************************************************************
;Vectorización de interrupciones
;**************************************************************
ORG 03H ;Posiciona la instrucción siguiente en 03H
LJMP RSI_INT0 ;Salto a la rutina de RSI
ORG 0BH ;Posiciona instrucción siguiente en 0BH
LJMP RSI_TIMER0 ;Salto a la rutina de RSI
ORG 013H ;Posiciona instrucción siguiente en 013H
LJMP RSI_INT1 ;Salto a la rutina de RSI
RSI_INT0: MOV ..... ;Rutina de RSI para /INT0
:
RETI
RSI_TIMER0: MOV ..... ;Rutina de RSI para TIMER0
:
RETI
© Los autores, 2001; © Edicions UPC, 2001.
6 Las interrupciones 143
RSI_INT1: MOV ..... ;Rutina de RSI para INT1
:
RETI
La estructura del programa cuando se utilizan interrupciones estará formada por una rutina de
vectorización, como la mostrada en este apartado. El registro PC se inicializa a 0000H tras un reset ola puesta en marcha del microcontrolador, por lo que la primera instrucción que se ejecuta es la
contenida en la dirección 0000H. La estructura de un programa, también, en general contempla una
rutina “Inicio”, donde se determinan los valores de las variables que se van a utilizar y el modo de
operar del microcontrolador, y una rutina “Principal”, donde se llevan a cabo la mayor parte de las
tareas que debe gestionar la CPU, aunque, parte de estas tareas puedan solventarse mediante
interrupciones. En conclusión, la rutina de vectorización anterior debe, además, incluir en la dirección
0000H una instrucción de salto hacia la rutina “Inicio”, tal y como se muestra en la rutina siguiente:
;****************************************************
;Vectorización de interrupciones
;****************************************************
ORG 0H
LJMP Inicio ;Salto a la rutina Inicio
ORG 03H
LJMP RSI_INT0
ORG 0BH
LJMP RSI_TIMER0
ORG 013H
LJMP RSI_INT1
6.2.2 Habilitación de interrupciones y establecimiento de prioridades en la MCS-51
Cada una de las fuentes de interrupción de la MCS-51 dispone de un bit de
habilitación/deshabilitación en el registro IE, Interrupt Enable, del área de SFR (tabla 6.3). En el
registro IE el bit de mayor peso, IE.7 o también EA, es el bit de inhibición global y afecta de forma
directa a todos los bits de habilitación de interrupciones establecidos dentro del mismo registro IE.
Poniendo el bit EA a cero lógico se inhabilitan todas las interrupciones del microcontrolador, aunque
existan bits de habilitación de interrupción activados; por contra, poniendo el bit EA a uno lógico, se
habilitan sólo las interrupciones que tienen su bit de habilitación activado.
La mayor parte de los componentes de la MCS-51 tienen dos niveles de prioridad, con excepción de
las versiones 8XC51Fx y 8XC52/54/58, que tienen hasta cuatro niveles de prioridad. El nivel de
prioridad se determina con el registro de prioridades IP, Interrupt Priority, del área de SFR (tabla 6.4).
Poniendo un bit de este registro a uno lógico se fija la prioridad a nivel alto y a cero lógico se fija a
nivel bajo.
Para el caso de que dos o más interrupciones tengan el mismo nivel de prioridad y se produzca una
petición simultánea de interrupción, el fabricante asigna un nivel de prioridad por defecto a cada una
de las fuentes de interrupción del microcontrolador (tabla 6.5), de forma que en una petición
simultánea de interrupción, la CPU atienda primero a la interrupción con mayor prioridad según la
tabla 6.5.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251144
Tabla 6.3 Registro IE de habilitación de interrupciones para la MCS-51
EX0ET0EX1ET1ESET2EA
(LSB)(MSB) Registro IE
EC† *
BIT COMENTARIO
EX0 EX0 = 1 habilita la interrupción en INT0. EX0 = 0 la inhabilita
ET0 ET0 = 1 habilita la interrupción del Timer 0. ET0 = 0 la inhabilita.
EX1 EX1 = 1 habilita la interrupción en INT1. EX1 = 0 la inhabilita.
ET1 ET1 = 1 habilita la interrupción del Timer 1. ET1 = 0 la inhabilita.
ES ES = 1 habilita la interrupción del puerto serie. ES = 0 la
inhabilita.
ET2* ET2 = 1 habilita la interrupción del Timer 2. ET2 = 0 la inhabilita.
EC† EC =1 habilita la interrupción de la PCA. EC = 0 la inhabilita.
EA EA = 1 permite todas las habilitaciones o inhabilitaciones anteriores.
EA = 0 no reconoce ninguna interrupción.
* En las versiones con 3 temporizadores† En las versiones con PCA
Tabla 6.4 Registro de prioridades IP
PX0PT0PX1PT1PSPT2
(LSB)(MSB) Registro IP
PPC† *
BIT COMENTARIO
PX0 Bit de prioridad de /INT0.
PT0 Bit de prioridad del Timer 0.
PX1 Bit de prioridad de /INT1.
PT1 Bit de prioridad del Timer 1PS Bit de prioridad del puerto serie.
PT2* Bit de prioridad del Timer 2.
PPC† Bit de prioridad de la PCA.
- Bit reservado.
* En las versiones con 3 temporizadores† En las versiones con PCA
Tabla 6.5 Nivel de prioridad asignado por defecto en la MCS-51
Prioridad Fuente
(más alta).......1 /INT0
2 Timer 03 /INT1
4 Timer 15 PCA†
6 Puerto Serie
(más baja).......7 Timer 2*
* En las versiones con 3 temporizadores† En las versiones con PCA
Las versiones 8XC51Fx y 8XC52/54/58 tienen cuatro niveles de prioridad que se determinan por
medio de los registros IP y IPH (tabla 6.6). En la tabla 6.7 se indica el nivel de prioridad según el
estado de los bits correspondientes a cada una de las fuentes de interrupción.
© Los autores, 2001; © Edicions UPC, 2001.
6 Las interrupciones 145
Tabla 6.6 Registro de prioridades IPH para las versiones 8XX52/54/58 y 8XC51Fx de la MCS-51
PX0HPT0HPX1HPT1HPSHPT2H
(LSB)(MSB) Registro IPH
PPCH † *
BIT COMENTARIO
PX0H Bit alto de prioridad de /INT0.
PT0H Bit alto de prioridad del Timer 0.
PX1H Bit alto de prioridad de /INT1.
PT1H Bit alto de prioridad del Timer 1.
PSH Bit alto de prioridad del puerto serie.
PT2H Bit alto de prioridad del Timer 2.
PPCH† Bit alto de prioridad de la PCA.
- Bit reservado.† Sólo en las versiones 8XC51Fx.
Tabla 6.7 Niveles de prioridad para las versiones 8XX52/54/58 y 8XC51Fx de la MCS-51
Bits de prioridad Nivel de prioridadIPH.x IP.x
0 0 Nivel 0 (Menor)
0 1 Nivel 1
1 0 Nivel 2
1 1 Nivel 3 (Mayor)
6.2.3 Tiempos de respuesta del proceso de interrupción
Las fuentes de interrupción en la MCS-51 se comprueban en la fase 2 del estado 5 de cada ciclo
máquina, denominado S5P2 (figura 6.4), y se evalúa su estado en el siguiente ciclo máquina del
microcontrolador. En consecuencia, si la CPU encuentra que una de las fuentes está activa, entonces
genera un salto automático hacia la rutina de RSI correspondiente. Aunque, este salto puede ser
abortado por cualquiera de las condiciones siguientes:
1. Se halla en proceso una interrupción de mayor o igual prioridad.
2. El ciclo máquina en el que se ha producido la interrupción no es el último de la
instrucción en curso de ejecución por parte de la CPU, por lo que debe esperar a que se
termine de ejecutar la instrucción.
3. La instrucción actual en curso es una instrucción RETI o cualquier otra que escriba en
los registros IE o IP.
La lectura de las peticiones de interrupción realizadas por el microcontrolador carece de memoria, por
lo que si una petición de interrupción resulta abortada por una de las condiciones anteriores, en un
ciclo máquina determinado, y esta petición no se sostiene por parte del periférico de manera que
vuelva a detectarse en el ciclo maquina siguiente, entonces la interrupción no es atendida; es decir, en
caso de rechazo de la interrupción, ésta debe ser sostenida por el periférico el tiempo necesario hasta
que la CPU la atienda.
La CPU reconoce la petición de una interrupción cuando vectoriza la interrupción, es decir, cuando
salta a la rutina de RSI correspondiente. Según el tipo de interrupción, la CPU, además, borra el bit
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251146
activado en la petición de interrupción (tabla 6.1), como es el caso de los bits TF0 y TF1, o de los bits
IE0 e IE1, sólo cuando la interrupción ha sido activada por flanco descendente. En otros casos el bit
activado por la interrupción se debe borrar por software.
S5P2 S6
Ciclo C1 Ciclo C2 Ciclo C3 Ciclo C4 Ciclo C5
Comprobación de
interrupcionesConsulta de
interrupciones
activas
Salto a la
rutina de RSI
Rutina de
RSI
Fig. 6.4 Diagrama de tiempos del salto a la rutina de RSI en el proceso de interrupciones
La CPU guarda en la memoria interna de la pila el contenido del registro PC (dos bytes) y, luego, salta
a la rutina RSI correspondiente. La CPU ejecuta la rutina de RSI hasta que encuentra una instrucción
RETI, que le indica que se ha llegado al final del proceso de interrupción; recupera entonces los dos
bytes almacenados en la pila y los asigna al registro PC, por lo que la ejecución del programa regresa
al punto de partida donde se inició la interrupción.
El tiempo transcurrido (figura 6.4), desde que se produce la interrupción (S5P2 del ciclo C1), hasta
que la CPU comienza a ejecutar la rutina de RSI (ciclo C5), es de como mínimo tres ciclos máquina.
El tiempo de respuesta es mayor si el salto resulta abortado por una de las condiciones mencionadas.
En el primer caso, si una interrupción de mayor o igual prioridad está en proceso, el tiempo de espera
dependerá de la rutina de RSI en ejecución. En el segundo caso, cuando la CPU debe esperar a que se
finalice la ejecución de la instrucción actual, el tiempo de espera, en el peor caso4
, no puede ser
superior a tres ciclos máquina. En el tercer caso, si una instrucción RETI, o la escritura del registro IE
o IP, está en progreso, el tiempo adicional de espera no puede ser superior a cinco ciclos máquina. En
definitiva, el tiempo de respuesta de una interrupción estará comprendido entre tres y nueve ciclos
máquina.
Ejemplo 6.1 Conexión de teclas al microcontrolador
Se conectan cuatro teclas al puerto P1 de un microcontrolador 80C31 (figura 6.5). Las entradas
del puerto P1 tienen una resistencia interna de pull-up (figura 3.4), por lo que un terminal del
puerto, por ejemplo P1.0, estará en el estado 1 lógico (Vcc) cuando no se pulsa la tecla T1, y a
0 lógico (masa) cuando se pulsa T1. Luego, la detección de si una tecla ha sido pulsada o no,
consiste en leer el estado lógico del puerto P1, y ver si hay algún cero en una de sus patillas. En
la figura 6.5 cada una de las teclas está conectada a una puerta AND, de manera que la
pulsación de cualquiera de las cuatro teclas causará un 0 lógico en la entrada de interrupción
/INT0, y provocará una interrupción en el caso de que esté habilitada.
4
El peor caso corresponde a las instrucciones MUL y DIV que tardan en ejecutarse cuatro ciclos máquina.
© Los autores, 2001; © Edicions UPC, 2001.
6 Las interrupciones 147
P1.0
P1.1
P1.2
P1.3
/INT0
80C31
T1
T2
T3
T4
Fig. 6.5 Conexión de cuatro teclas a un microcontrolador en el ejemplo 6.1
En este ejemplo se debe habilitar la interrupción /INT0 y crear una rutina RSI capaz de detectar
la tecla que ha sido pulsada. Para ello, se utilizará el registro B como registro indicador de la
pulsación de una tecla, y se le asignará el valor 00H cuando no se haya pulsado ninguna tecla, y
los valores 01H, 02H, 03H y 04H, cuando se pulsen las teclas T1, T2, T3 y T4,
respectivamente. La interrupción /INT0, en este ejemplo, se establecerá por nivel lógico (bit
IT0 del registro TCON a 0 lógico). Se debe tener en cuenta que todos los bits accesibles de los
registros TCON, IE y IP quedan a 0 lógico tras un reset del microcontrolador.
;**********************************************************************
; Rutina de vectorización (ejemplo 6.1)
;**********************************************************************
ORG 0H
LJMP Inicio
ORG 03H
LJMP RSI_INT0
;**********************************************************************
; Rutina de Inicio. (Se habilita las interrupciones y /INT0 por flanco descendente)
;**********************************************************************
Inicio: SETB PX0 ;Prioridad alta para la interrupción /INT0 (Registro IP)
SETB EX0 ;Activa el bit de habilitación de /INT0 (Registro IE)
SETB EA ;Activa el bit de habilitación general (Registro IE)
LJMP Principal
;**********************************************************************
; Programa Principal
;**********************************************************************
ORG 0300H
Principal: SJMP Principal ;Bucle infinito sin propósito definido
;**********************************************************************
; Rutina de RSI de /INT0
;**********************************************************************
RSI_INT0: JNB P1.0, Tecla_1 ;¿Es la tecla T1?
JNB P1.1, Tecla_2 ;¿Es la tecla T2?
JNB P1.2, Tecla_3 ;¿Es la tecla T3?
SJMP Tecla_4 ;Si no es ninguna de las anteriores, es la tecla T4
Tecla_1: MOV B, #01H ;Pone 01H en el registro B
SJMP Salir ;Ir a Salir
Tecla_2: MOV B, #02H ;Pone 02H en el registro B
SJMP Salir ;Ir a Salir
Tecla_3: MOV B, #03H ;Pone 03H en el registro B
SJMP Salir ;Ir a Salir
Tecla_4: MOV B, #04H ;Pone 04H en el registro B
Salir: CLR IE0 ;Se pone a cero para que /INT0 pueda interrumpir de nuevo.
RETI ;Final de interrupción
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251148
La ejecución de las instrucciones del programa empieza por la dirección 0H, pues, en la puesta
en marcha del microcontrolador, se ejecuta un reset interno que sitúa el registro PC a 00H. La
primera instrucción, entonces, es una instrucción de salto a la rutina “Inicio”, donde se
configura la forma de operar de la interrupción /INT0, mediante los registros TCON, IE y IP.
De esta rutina, la CPU pasa a ejecutar la rutina “Principal”, que sólo consiste en un bucle
infinito, sin ningún objetivo específico. Esto es así, por el funcionamiento casi exclusivo del
programa mediante interrupciones, de manera que la CPU está siempre ejecutando
instrucciones de la rutina “Principal”, a la espera de que las interrupciones se produzcan, lo que
causa el salto automático hacia las rutinas de RSI.
En el momento que se pulsa una tecla, se provoca la interrupción /INT0 y se ejecuta la rutina
“RSI_INT0”. Esta rutina comprueba de forma secuencial, mediante la instrucción JNB, cuál ha
sido la tecla pulsada, colocando en el registro B el valor adecuado, según los objetivos
marcados en este ejemplo. Al final de la rutina, el bit IE0, debido a que la interrupción /INT0
se ha habilitado por nivel lógico, se borrará por software para que se produzca una nueva
interrupción en /INT0.
La lectura de las teclas, en el programa realizado, se hace de manera secuencial, por lo que el
programa es incapaz de detectar una pulsación simultánea de varias teclas, y da por válida la
tecla que lee primero; es decir, en el caso de pulsarse las teclas conectadas T1 y T2, en el
registro B se colocaría el código correspondiente a la tecla T1. Este problema se solventa en el
siguiente ejemplo que consiste en una modificación del actual.
Ejemplo 6.2 Conexión de teclas y de un dígito de siete segmentos
Este ejemplo se basa en el anterior, con las siguientes modificaciones:
- Se incorporan un dígito de siete segmentos conectado al puerto P2 y una tecla
adicional, T5, conectada a la entrada de interrupción /INT1 (figura 6.6).
- El microcontrolador empleado es el 87C51 y utiliza exclusivamente su memoria de
programa interna.
- El programa debe ser capaz de detectar la pulsación de varias teclas al mismo tiempo,
e indica esta situación a través del encendido de todos los leds del dígito conectado.
- La pulsación de una tecla, T1, T2, T3 o T4, se indicará poniendo el número 1, 2, 3 o 4,
en el dígito, respectivamente. En el dígito siempre se mostrará la última tecla pulsada.
- La pulsación de T5 apagará todos los leds del dígito T5.
En la figura 6.6 se emplea el circuito integrado 7405 que contiene hasta 6 puertas inversoras en
colector abierto. La puerta inversora está formada por un único transistor, del cual se dispone
de su colector, tal y como se ve en el detalle de la figura. La puerta inversora puede soportar
una corriente máxima de 25mA, valor más que suficiente para encender de manera adecuada el
diodo LED que tiene asociado.
© Los autores, 2001; © Edicions UPC, 2001.
6 Las interrupciones 149
P1.0
P1.1
P1.2
P1.3
/INT0
87C51
T1
T2
T3
T4
a
b
c
d
e
f
g
DP
P2.0
P2.1
P2.7
R
/INT1T5
Ánodo comúnVcc
74LS05/06a
b
DP
Fig. 6.6 Circuito del ejemplo 6.2
La resistencia R se debe calcular de forma que, considerando el valor de Vcc, de la tensión
umbral del diodo LED, VTH, y la tensión colector-emisor del transistor en saturación, VCE, la
corriente esté limitada a unos 20mA. Su valor se puede determinar a partir de la siguiente
ecuación:
i
VVVR CETHCC [[
]
La interrupción /INT1 se habilita por flanco descendente, mientras que la interrupción /INT0 se
habilita por nivel lógico, de manera que en la rutina RSI de /INT0 se debe borrar el bit IE0. Sin
embargo, en la rutina RSI de /INT1 el bit IE1 se borra de forma automática.
;************************************************************************
;Rutina de vectorización (ejemplo 6.2)
;************************************************************************
ORG 0H
LJMP Inicio
ORG 03H
LJMP RSI_INT0
ORG 013H
LJMP RSI_INT1
;************************************************************************
; Rutina de Inicio
; Se habilita las interrupciones y /INT0 por flanco descendente
;************************************************************************
Inicio: SETB IT1 ;Interrupción /INT1 activa por flanco descendente
SETB PX1 ;Prioridad alta para /INT1
SETB EX0 ;Activa el bit de habilitación de /INT0
SETB EX1 ;Activa el bit de habilitación /INT1
SETB EA ;Activa el bit de habilitación general
;************************************************************************
; Programa Principal
;************************************************************************
Principal: MOV A, B ;Lee el registro B
CALL Siete_seg ;Codifica en 7 segmentos para mostrar en dígito
MOV P2, A ;Carga en dígito
SJMP Principal ;Bucle infinito a Principal
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251150
Siete_seg: INC A
MOVC A, @A+PC
RET
DB 0000 0000b ;Todos los leds apagados
DB 0000 0110b ;leds b y c encendidos, caracter 1, tecla T1
DB 0101 1011b ;leds a, b, d, e y g encendidos, caracter 2, tecla T2
DB 0100 1111b ;leds a, b, c, d y g encendidos, caracter 3, tecla T3
DB 0110 0110b ;leds b, c, f y g encendidos, caracter 4, tecla T4
DB 1111 1111b ;Todos los leds encendidos, varias teclas pulsadas
;************************************************************************
; Rutina de RSI de /INT0
;************************************************************************
RSI_INT0: MOV A,P1 ;Lee el puerto P1
ORL A,#F0H ;Máscara, fuerza los 4 bits altos de P1 a 1 lógico
CJNE A, #11111110b, Dif_1 ;¿Es tecla T1?
MOV B, #01H ;Pone 01H en el registro B
SJMP Salir ;Ir a Salir
Dif_1: CJNE A, #11111101b, Dif_2
MOV B, #02H ;Pone 02H en el registro B
SJMP Salir ;Ir a Salir
Dif_2: CJNE A, #11111011b, Dif_3
MOV B, #03H ;Pone 03H en el registro B
SJMP Salir ;Ir a Salir
Dif_3: CJNE A, #11110111b, Varias_tec
MOV B, #04H ;Pone 04H en el registro B
SJMP Salir ;Ir a Salir
Varias_tec: MOV B, #05H ;Pone 05H en el registro B
Salir: CLR IE0 ;Se pone a cero para que /INT0 pueda interrumpir de nuevo.
RETI ;Final de interrupción
;************************************************************************
; Rutina de RSI de /INT1
;************************************************************************
RSI_INT1: MOV B, #0 ;Borra el registro B
RETI ;No es necesario borrar el bit IE1, ya que es por flanco
La rutina “Principal” de este ejemplo se encarga de leer el contenido del registro B y de poner
en el dígito el carácter correspondiente según sea el valor de B. El registro B puede valer 00H
al principio, si no se ha pulsado ninguna tecla, o tras pulsar la tecla T5; puede valer 01H, 02H,
03H o 04H, al pulsar las teclas T1, T2, T3 o T4, respectivamente; y puede valer 05H en el caso
de que se pulsen varias teclas al mismo tiempo. Con el valor del registro B se lee la tabla
“Siete_seg”, que proporciona el código en siete segmentos, correspondiente al carácter que se
quiere mostrar en el dígito del ejemplo. De todas formas, la tabla “Siete_seg” se puede suprimir
colocando en el registro B, directamente, el código del carácter que deberá mostrar en el dígito,
según sea el caso.
Ejemplo 6.3 Conexión de teclas al microcontrolador mediante el 74LS148
El 74LS148 es un circuito integrado codificador con prioridad que se puede emplear para
conectar varios periféricos a una misma línea de interrupción, o bien, como en este caso, a la
conexión de hasta 8 teclas al microcontrolador, empleando para ello el sistema de
interrupciones.
© Los autores, 2001; © Edicions UPC, 2001.
6 Las interrupciones 151
Según el circuito de la figura 6.7, el codificador con prioridad codifica en binario la tecla
pulsada, sacando el código por las tres líneas de salida: A1, A2 y A3. Con el 74LS148, si se
pulsan varias teclas a la vez, aparece a su salida el código correspondiente a la entrada con
mayor prioridad (la entrada 7 es la de mayor prioridad, y la entrada 0 la de menor prioridad).
Cuando se pulsa una tecla la línea de salida /GS del codificador se pone a cero lógico, de
manera que puede generar una interrupción conectándola a la entrada /INT0 del
microcontrolador. La entrada /EI del 74LS148 es de habilitación del circuito integrado.
/EI se conecta directamente a masa para que el codificador esté siempre habilitado. La tabla de
verdad del codificador se puede ver en la tabla 6.15.
T9
P1.0
P1.1
P1.2
P1.4
/INT0
87C51
a
b
c
d
e
f
g
DP
P2.0
P2.1
P2.7
RÁnodo común
Vcc7405
a
b
DP
T1
T2
T3
T4
T5
T6
T7
T8
4
3
2
1
0
5
6
7
/EI
A1
A2
A3
/GS
74LS148
Fig. 6.7 Circuito del ejemplo 6.3
El programa que se debe realizar en este ejemplo ha de mostrar el número de la última tecla
pulsada en el dígito de siete segmentos, mientras que la pulsación de la tecla T9 debe borrar el
dígito. La interrupción /INT0 se debe activar por nivel lógico.
;************************************************************************
;Rutina de vectorización (ejemplo 6.3)
;************************************************************************
ORG 0H
LJMP Inicio
ORG 03H
LJMP RSI_INT0
;************************************************************************
; Rutina de Inicio (Habilitación de interrup., /INT0 por nivel)
;************************************************************************
ORG 0200H
Inicio: SETB PX0 ;Prioridad alta para /INT0
SETB EX0 ;Activa el bit de habilitación de /INT0
SETB EA ;Activa el bit de habilitación general
LJMP Principal
;************************************************************************
; Programa Principal
;************************************************************************
ORG 0300H
Principal: JB P1.4, Rut_ok ;Salta a Rut_ok si no se pulsa T9
MOV B,#0 ;Borra B (por tanto dígito) si se pulsa T9
Rut_ok: MOV A, B ;Lee el registro B
MOV P2, A ;Carga en dígito
SJMP Principal ;Bucle infinito a Principal
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251152
;************************************************************************
; Rutina de RSI de /INT0
;************************************************************************
ORG 0400H
RSI_INT0: MOV A,P1 ;Lee el puerto P1
ANL A,#07H ;Máscara, fuerza P1 a 0, excepto P1.0, P1.1 y P1.2
CALL Tecla_in ;Ejecuta subrutina Tecla_in
MOV B,A ;Guarda código en B
CLR A ;Borra A
CLR IE0 ;Borra bit IE0, para una posterior interrupción
RETI ;Retorno de interrupción
Tecla_in: INC A
MOVC A,@A+PC
RET
DB 0111 1111b ;leds a, b, c, d, e, f y g encendidos, caracter 8, tecla T8
DB 0000 0111b ;leds a, b y c encendidos, caracter 7, tecla T7
DB 0111 1101b ;leds a, c, d, e, f y g encendidos, caracter 6, tecla T6
DB 0110 1101b ;leds a, c, d, f, y g encendidos, caracter 5, tecla T5
DB 0110 0110b ;leds b, c, f y g encendidos, caracter 4, tecla T4
DB 0100 1111b ;leds a, b, c, d y g encendidos, caracter 3, tecla T3
DB 0101 1011b ;leds a, b, d, e y g encendidos, caracter 2, tecla T2
DB 0000 0110b ;leds b y c encendidos, caracter 1, tecla T1
La rutina de RSI de /INT0 lee directamente el valor del puerto P1, aplica una máscara al valor
leído, puesto que sólo interesa el valor de las patillas P1.0, P1.1 y P1.2 del puerto, y pone el
código del carácter en siete segmentos, correspondiente a la tecla pulsada, en el registro B. La
rutina “Principal” comprueba el estado de la tecla T9 con la instrucción “JB P1.4, Rut_ok”, y
sitúa el valor del registro B, procedente de la rutina “RSI_INT0”, en el puerto P2, para su
visualización. El registro B se pone a cero cuando se pulsa la tecla T9.
6.3 El sistema de interrupciones en la familia MCS-251
Los microcontroladores de la familia MCS-251, como otros microcontroladores y microprocesadores
de propósito general, incorporan un circuito gestionador de interrupciones. Este circuito puede recibir
peticiones de interrupción de ocho fuentes: siete fuentes que pueden ser habilitadas o inhibidas
mediante programa, y que por ese motivo se denominan mascarables, y la instrucción TRAP, que
permanece siempre habilitada. Las interrupciones mascarables están formadas por dos interrupciones
externas (/INT0 y /INT1), tres interrupciones correspondientes a los temporizadores (Timer 0, Timer 1y Timer 2), una interrupción del array de contadores programables (PCA) y una interrupción del
puerto de comunicación serie. En la figura 6.8 están representadas las distintas fuentes de interrupción.
Las interrupciones pueden ocurrir como resultado de la actividad interna del µC (por ejemplo el
rebasamiento de un Timer) o por la activación de señales eléctricas externas al µC, como, por ejemplo,
la recepción de un dato por el puerto de comunicación serie. Las interrupciones pueden ser habilitadas
o inhibidas individualmente, excepto la instrucción TRAP, y pueden programarse en uno de cuatro
niveles de prioridad.
Cada fuente de interrupción (excepto la instrucción TRAP) dispone de uno o varios flags, o banderas
de petición de interrupción, que pueden ser activados por programa o por hardware; su nivel activo es
uno lógico.
© Los autores, 2001; © Edicions UPC, 2001.
6 Las interrupciones 153
CPU
Timer 0
Timer 1
Timer 2
PCAPuerto
serie
Controlador de
interrupciones
INT0 INT1
8XC251Sx
Instrucción
TRAP
Fig. 6.8 Fuentes de interrupción del microcontrolador 8XC251Sx
Una fuente de interrupción activa su flag de interrupción cuando desea realizar una petición de
interrupción a la CPU. En la tabla 6.8 se muestran los flags de interrupción asociados a cada una de las
fuentes de interrupción, y su ubicación. Para algunas interrupciones el flag se borra por hardwarecuando la CPU atiende a la interrupción. Los flags de interrupción también pueden ser borrados por
programa, mediante una instrucción, por ejemplo, del tipo CLR bit.
Tabla 6.8 Flags de petición de interrupción
Fuente de interrupción Flag que activa Ubicación de los flags
/INT0
Timer 0/INT1
Timer 1Puerto Serie
Timer 2PCA
IE0
TF0
IE1
TF1
RI, TI
TF2, EXF2
CF, CFX†
bit 1 TCON
bit 5 TCON
bit 3 TCON
bit 7 TCON
bits 0 y 1 SCON
bit 7 y 6 T2CON
bit 7, 0,.., 4 CCON†X=0,.., 4
En líneas generales, el proceso de interrupción de los microcontroladores de la familia MCS-251 sigue
las pautas comentadas en el apartado de introducción. Este proceso comienza cuando el circuito
gestionador de interrupciones recibe una petición de interrupción. La CPU termina de ejecutar la
instrucción en curso y almacena en la pila el contador de programa (PC) para, a continuación, realizar
un salto a la RSI de la interrupción activa (figura 6.9).
Oscilador
Estados
Petición
interrupción
externa
Finalización de la instrucción en curso Push PC Call ISR RSI
Tiempo de respuesta
Fig. 6.9 Proceso de atención a una interrupción externa
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251154
Existen dos causas que pueden bloquear el salto a la RSI:
1. Se está ejecutando una interrupción de igual o mayor nivel de prioridad. En este caso el sistema de
interrupción deberá esperar a que finalice la ejecución de la RSI de la interrupción más prioritaria.
2. La instrucción que se está ejecutando en ese momento es la instrucción RETI o se está escribiendo
en los registros IE0, IPH0 o IPL0. En este caso se deberá ejecutar, al menos, una instrucción más
antes de que el sistema salte a la RSI.
El número de bytes almacenados en la pila depende del valor del bit INTR ubicado en el byte de
configuración, CONFIG1. Si este bit está a uno lógico, se guardarán en la pila cuatro bytes, los tres
bytes del contador de programa y el registro de estado PSW1. Si el bit INTR está a cero, se guardan en
la pila, únicamente, los dos bytes de menor peso del contador de programa.
Cada una de las fuentes de interrupción de la familia MCS-251 tiene asociada una dirección diferente
de comienzo de la RSI, denominada vector de interrupción. En la tabla 6.9 están indicados los
vectores de interrupción para cada una de las fuentes de interrupción.
Tabla 6.9 Vectores de interrupción
Direcciones de comienzo de la RSIFuente Dirección/INT0
Timer 0
/INT1
Timer 1
Puerto serie
Timer 2
PCA
TRAP
FF:0003H
FF:000BH
FF:0013H
FF:001BH
FF:0023H
FF:002BH
FF:0033H
FF:007BH
La rutina de servicio a la interrupción finaliza con la instrucción RETI. La función de esta instrucción
es la de indicar a la CPU que ha sido completada la ejecución de la RSI y extraer de la pila la
dirección de retorno y colocarla en el PC.
Cabe destacar, según la tabla 6.8, que entre la dirección de comienzo de la RSI de una fuente de
interrupción y la siguiente hay tan sólo ocho posiciones de memoria, que en la mayoría de los casos es
insuficiente para albergar la RSI. Por este motivo, si se utilizan interrupciones consecutivas, por
ejemplo /INT0 y Timer 0, la RSI deberá comenzar con un salto incondicional hacia una dirección de
memoria situada en una zona del espacio de memoria disponible para almacenar las instrucciones de la
RSI. A continuación se presenta, a modo de ejemplo, un listado de instrucciones cuya función es
reubicar la localización de las RSI de las fuentes de interrupción del Timer 0, Timer 1 y PCA.
;******************************************************************************************
; REUBICACION DE LAS RSI DE LAS FUENTES DE INTERRUPCION Timer 0, Timer 1 y PCA
;******************************************************************************************
RSI _TIMER0 EQU 2000H ; Dirección de comienzo de la RSI del Timer 0
RSI _TIMER1 EQU 2200H ; Dirección de comienzo de la RSI del Timer 1
RSI _PCA EQU 2400H ; Dirección de comienzo de la RSI del PCA
ORG FF:000BH ; Vector de interrupción del Timer 0
JMP RSI_TIMER0
© Los autores, 2001; © Edicions UPC, 2001.
6 Las interrupciones 155
ORG FF:001BH ; Vector de interrupción del Timer 1
JMP RSI_TIMER1
ORG FF:0033H ; Vector de interrupción del PCA
JMP RSI_PCA
RSI_TIMER0: ; Código de la RSI del Timer 0
. . . . .
RETI
RSI_TIMER1: ; Código de la RSI del Timer 1
. . . . .
RETI
RSI_PCA: ; Código de la RSI del PCA
. . . . .
RETI
6.3.1 Habilitación de las interrupciones
Cada una de las fuentes de interrupción de los microcontroladores de la familia MCS-251, con
excepción de la instrucción TRAP, puede ser individualmente habilitada o inhibida poniendo a uno o a
cero lógico el bit correspondiente del registro de habilitación de interrupciones IE0. Este registro estáubicado en el área de registros de función específica, SFR, en la dirección S:0A8H. En la tabla 6.10
aparecen los bits que componen el registro IE0. Cabe destacar que este registro contiene un bit de
habilitación global de interrupciones: EA. Si EA está a uno lógico, las interrupciones pueden ser
habilitadas o inhibidas individualmente por los bits del registro IE0. Si EA está a cero lógico, todas las
interrupciones, excepto la TRAP, estarán inhibidas.
Tabla 6.10 Registro habilitador de interrupciones IE0
IE0 Dirección: S:0A8H Valor de reset: 0000 0000b
b7 b6 b5 b4 b3 b2 b1 b0
EA EC ET2 ES ET1 EX1 ET0 EX0
Númerode bit
Nombredel bit
Función
7 EA Bit de habilitación general de interrupciones:
poniendo a uno lógico este bit se habilitan todas las interrupciones que están
individualmente habilitadas por los bits 0-6. Poniendo a cero este bit se inhiben
todas las interrupciones excepto la interrupción TRAP, que no puede inhibirse.
6 EC Bit de habilitación de la interrupción del PCA:
poniendo a uno lógico este bit se habilita la interrupción del PCA.
5 ET2 Bit de habilitación de la interrupción del Timer 2:
poniendo a uno lógico este bit se habilita la interrupción del Timer 2.
4 ES Bit de habilitación de la interrupción del puerto serie :
poniendo a uno lógico este bit se habilita la interrupción del puerto serie.
3 ET1 Bit de habilitación de la interrupción del Timer 1:
poniendo a uno lógico este bit se habilita la interrupción del Timer 1.
2 EX1 Bit de habilitación de la interrupción externa 1:
poniendo a uno lógico este bit se habilita la interrupción externa 1.
1 ET0 Bit de habilitación de la interrupción del Timer 0:
poniendo a uno lógico este bit se habilita la interrupción del Timer 0.
0 EX0 Bit de habilitación de la interrupción externa 0:
poniendo a uno lógico este bit se habilita la interrupción externa 0.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251156
6.3.2 Niveles de prioridad de las interrupciones
Cada una de las siete fuentes de interrupción de la familia MCS-251 puede programarse
individualmente en uno de cuatro niveles de prioridad. La programación de los niveles de prioridad
permite establecer el orden en que se deben atender las interrupciones en caso de una activación
simultánea.
El establecimiento de las prioridades se consigue poniendo a uno o cero lógico el bit correspondiente
en dos registros de prioridad de interrupciones: Interrupt Priority High Register, IPH0, e InterruptPriority Low Register, IPL0 (tablas 6.11 y 6.12 respectivamente). Por tanto, cada fuente de
interrupción tiene asociados dos bits de programación de prioridad, un bit en el registro IPH0 y otro en
el registro IPL0. El bit ubicado en el registro IPH0 es el bit más significativo (MSB), mientras que el
bit ubicado en el registro IPL0 es el bit menos significativo (LSB). El valor de estos dos bits define el
nivel de prioridad de la fuente de interrupción. Los niveles posibles son cuatro: nivel 0, 1, 2 o 3: el
nivel 0 es el de menor prioridad y el nivel 3 el de mayor prioridad (tabla 6.13).
Tabla 6.11 Interrupt Priority High Register (IPH0)
IPH0 Dirección: S:0B7H Valor de reset: 0000 0000b
b7 b6 b5 b4 b3 b2 b1 b0
---- IPH0.6 IPH0.5 IPH0.4 IPH0.3 IPH0.2 IPH0.1 IPH0.0
Númerode bit
Nombredel bit
Función
7 --- Reservado.
6 IPH.6 Bit alto de prioridad de interrupción del PCA.
5 IPH.5 Bit alto de prioridad de interrupción del Timer 2.
4 IPH.4 Bit alto de prioridad de interrupción del puerto serie.
3 IPH.3 Bit alto de prioridad de interrupción del Timer 1.
2 IPH.2 Bit alto de prioridad de la interrupción externa 1, /INT1.
1 IPH.1 Bit alto de prioridad de interrupción del Timer 0.
0 IPH.0 Bit alto de prioridad de la interrupción externa 0, /INT0.
Tabla 6.12 Interrupt Priority Low Register (IPL0)
IPL0 Dirección: S:0B8H Valor de reset: 0000 0000b
b7 b6 b5 b4 b3 b2 b1 b0
---- IPL0.6 IPL0.5 IPL0.4 IPL0.3 IPL0.2 IPL0.1 IPL0.0
Númerode bit
Nombredel bit
Función
7 --- Reservado.
6 IPL.6 Bit bajo de prioridad de interrupción del PCA.
5 IPL.5 Bit bajo de prioridad de interrupción del Timer 2.
4 IPL.4 Bit bajo de prioridad de interrupción del Puerto Serie.
3 IPL.3 Bit bajo de prioridad de interrupción del Timer 1.
2 IPL.2 Bit bajo de prioridad de la interrupción externa 1, /INT1.
1 IPL.1 Bit bajo de prioridad de interrupción del Timer 0.
0 IPL.0 Bit bajo de prioridad de la interrupción externa 0, /INT0.
© Los autores, 2001; © Edicions UPC, 2001.
6 Las interrupciones 157
Tabla 6.13 Niveles de prioridad de las interrupciones
IPH0.X (MSB) IPL0.X (LSB) Nivel de prioridad0 0 0 Menor prioridad
0 1 1
1 0 2
1 1 3 Mayor prioridad
El funcionamiento del mecanismo de niveles de prioridad está sujeto a unas reglas muy sencillas:
1. Una interrupción programada en un nivel bajo puede ser interrumpida por una
interrupción programada en un nivel de prioridad mayor, pero no por una interrupción de
nivel igual o menor.
2. Si una interrupción está programada en el nivel tres no podrá ser interrumpida por
ninguna fuente de interrupción.
3. Si dos o más interrupciones se activan al mismo tiempo la CPU atenderá en primer lugar a
la interrupción de mayor nivel de prioridad. Una vez ejecutada la rutina de la interrupción
más prioritaria, la CPU atenderá al resto de fuentes de interrupción siguiendo un orden
decreciente de prioridades.
4. Si se reciben peticiones de interrupción simultáneas correspondientes a fuentes
programadas en un mismo nivel de prioridad, el orden de respuesta seguirá una secuencia
preestablecida indicada en la tabla 6.14.
Tabla 6.14 Prioridades dentro del mismo nivel
Prioridad Fuente de interrupción1 (Prioridad mayor) /INT0
2 Timer 03 /INT1
4 Timer 15 Puerto serie
6 Timer 27 (Prioridad menor) PCA
Ejemplo 6.4 Atención a múltiples interrupciones
Seguidamente se plantea un caso práctico de programación de varias fuentes de interrupción en
distintos niveles de prioridad. En concreto se consideran cuatro fuentes de interrupción
programadas en los siguientes niveles: Timer 0 en nivel 3, /INT1 en nivel 2, puerto serie en
nivel 2 y PCA en nivel 1.
Para realizar esta asignación de niveles de prioridad se deben programar los registros de
prioridad de interrupción con los siguientes valores: IPH0 = 16H (0001 0110), IPL0 = 42H
(0100 0010).
Si en estas condiciones se produce en primer lugar una petición de interrupción del PCA, la
CPU pasará a ejecutar la RSI del PCA. Si mientras se ejecuta la RSI del PCA, ocurre una
petición simultánea de interrupción de las fuentes /INT1 y puerto serie, la CPU dejará de
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251158
ejecutar la RSI del PCA para ejecutar las RSI de las interrupciones que se han activado, dado
que poseen un nivel de prioridad mayor.
Las interrupciones /INT1 y puerto serie poseen el mismo nivel de prioridad pero, teniendo en
cuenta el orden establecido en la tabla 6.14, se ejecutará primero la RSI de la interrupción
/INT1 y, a continuación, la RSI del puerto serie.
Si, por ejemplo, se activa la interrupción Timer 0 mientras se está ejecutando la RSI del puerto
serie, la CPU pasa a ejecutar la RSI del Timer 0, porque posee un nivel de prioridad mayor que
el puerto serie. Una vez ejecutada la RSI del Timer 0, la CPU finalizará la ejecución de la RSI
del puerto serie y, a continuación, acabará de ejecutar la RSI del PCA para, finalmente,
continuar ejecutando el programa “Principal”. En la figura 6.10 se representa, de forma
esquemática, la secuencia que sigue la CPU en la atención a las distintas fuentes de
interrupción de este ejemplo.
RSI_PCA
RETI
RSI_/INT1
RETI
RSI_PUERTO_ SERIE
RETI
PROGRAMA
PRINCIPAL
RSI_T0
RETI
Int. PCA Int. /INT1
y PS
Int. T0
Fig. 6.10 Esquema de la secuencia de atención a las interrupciones del ejemplo 6.4
6.3.3 Interrupciones externas /INT0 e /INT1
Las interrupciones /INT0 e /INT1 posibilitan el control de periféricos externos mediante el mecanismo
de interrupciones. En la figura 6.11 está representada, a modo de ejemplo, la conexión de dos
periféricos externos a las entradas de interrupción /INT0 e /INT1.
© Los autores, 2001; © Edicions UPC, 2001.
6 Las interrupciones 159
El periférico externo interrumpe al µC y activa la entrada de interrupción. El µC responderá saltando a
la dirección de comienzo de la RSI asociada a la interrupción activada.
Las interrupciones externas /INT0 e /INT1 se pueden programar para ser activas por flanco
descendente o por nivel bajo, dependiendo del valor de los bits IT0 e IT1 del registro TCON. Con el
bit IT0 a cero lógico, la interrupción /INT0 se activa por nivel, mientras que con IT0 a uno lógico, la
interrupción /INT0 se activa por flanco descendente. La misma relación se produce entre el bit IT1 y
la interrupción /INT1.
Cuando se genera una interrupción externa del tipo /INT0 o /INT1, se activa el correspondiente flagde petición de interrupción, bits IE0 o IE1, del registro TCON (tabla 6.15). Si la interrupción se ha
activado por flanco descendente, los flags de petición de interrupción se borran por hardware cuando
la CPU salta a la rutina de atención a la interrupción para proceder a su ejecución. Si la interrupción se
activa por nivel, el flag de interrupción se deberá borrar mediante una instrucción dentro de la RSI.
Para este caso, la causa que ha generado la interrupción externa /INT0 o /INT1 debe desactivarse
antes de que acabe la RSI o se generará una nueva petición de interrupción.
8XC251
INT0
(P3.2)
INT1
(P3.3)
Periférico 1
INT
Periférico 2
INT
Fig. 6.11 Conexión de periféricos externos a las entradas de interrupción del µC 8XC251Sx
Para detectar la petición de interrupción, la CPU lee el estado de los pines asociados a las
interrupciones externas /INT0 e /INT1 una vez cada ocho períodos de reloj. Tanto si la interrupción
externa está programada por nivel como por flanco, será necesario mantener un nivel bajo durante al
menos diez períodos para garantizar la detección de la interrupción.
Tabla 6.15 Interrupciones externas
Fuente de interrupción Flag Bit de configuración por flanco o nivel Vector de interrupción/INT0 IE0 IT0 FF:0003H
/INT1 IE1 IT1 FF:0013H
Si la aplicación diseñada requiere el control de más de dos periféricos externos, se deberá incluir en el
diseño algún sistema, hardware y/o software, que permita determinar qué periférico o periféricos han
interrumpido, y en el caso que haya interrumpido más de uno, en qué orden se deben atender.
El establecimiento del orden de prioridad se puede hacer externamente, utilizando un controlador de
prioridad de interrupciones (PIC), o bien, mediante software, programando en la RSI el orden de
atención a los distintos periféricos.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251160
Ejemplo 6.5 Control de múltiples periféricos externos mediante un codificador de prioridad
A continuación se presenta un ejemplo de sistema de gestión de múltiples fuentes de
interrupción externas mediante un codificador de prioridad 74LS148 (figura 6.12), cuyo
funcionamiento se detalla en la tabla 6.16. En este ejemplo, se han considerado 8 periféricos
cuyas salidas de interrupción están conectadas a las entradas del codificador de prioridad. Las
salidas de datos A2, A1 y A0 del codificador de prioridad están a su vez conectadas a las tres
líneas de menor peso del puerto P1 del microcontrolador 8XC251Sx.
E1
GS
A1
2A
3A
74LS148
7
6
5
4
3
2
1
0
Periférico 7 INT
Periférico 6 INT
Periférico 5 INT
Periférico 4 INT
Periférico 3 INT
Periférico 2 INT
Periférico 1 INT
Periférico 0 INT
8XC251
P1.0
P1.1
P1.2
INT0
EO
Fig. 6.12 Establecimiento de prioridades mediante el codificador de prioridad 74LS148
Tabla 6.16 Tabla de verdad del codificador de prioridad 74LS148
ENTRADAS SALIDASEI 0 1 2 3 4 5 6 7 A2 A1 A0 /GS /EOH
L
L
L
L
L
L
L
L
L
X
H
X
X
X
X
X
X
X
L
X
H
X
X
X
X
X
X
L
H
X
H
X
X
X
X
X
L
H
H
X
H
X
X
X
X
L
H
H
H
X
H
X
X
X
L
H
H
H
H
X
H
X
X
L
H
H
H
H
H
X
H
X
L
H
H
H
H
H
H
X
H
L
H
H
H
H
H
H
H
H
H
L
L
L
L
H
H
H
H
H
H
L
L
H
H
L
L
H
H
H
H
L
H
L
H
L
H
L
H
H
H
L
L
L
L
L
L
L
L
H
L
H
H
H
H
H
H
H
H
Si uno o varios periféricos activan las entradas del codificador 74LS148, éste pondrá a cero su
salida /GS, y se realizará una petición de interrupción al µC 8XC251Sx a través de la entrada
/INT0. Al mismo tiempo, en las salidas de datos A2, A1 y A0, aparece la combinación binaria
correspondiente a la entrada activa de mayor peso. Por tanto, la prioridad en la atención a los
periféricos se establece mediante el orden en que se conectan éstos a las entradas del
codificador, de forma que el periférico que está conectado a la entrada siete es el de mayor
prioridad, y el que está conectado a la entrada cero el de menor prioridad.
En la rutina de servicio a la interrupción /INT0, se deberá determinar cuál de los periféricos ha
interrumpido, mediante la lectura del puerto P1, y saltar a la rutina específica que lo atiende.
© Los autores, 2001; © Edicions UPC, 2001.
6 Las interrupciones 161
Por otro lado, se debe establecer una tabla de vectores de salto, donde se adjudique una
dirección de comienzo de la RSI de cada uno de los periféricos (tabla 6.17). Lógicamente, las
rutinas de atención a los periféricos se deben colocar en zonas de memoria que no se utilicen
para otro fin.
Tabla 6.17 Direcciones de comienzo de las rutinas de atención a los periféricos
Periférico Valor de P1 Dirección inicio RSI7
6
5
4
3
2
1
0
00 H
01 H
02 H
03H
04H
05H
06 H
07H
FF:1100 H
FF:1180 H
FF:1200 H
FF:1280 H
FF:1300 H
FF:1380 H
FF:1400 H
FF:1480 H
;***********************************************************************************
; RUTINA DE SERVICIO A LA INTERRUPCION INT0
;***********************************************************************************
ORG FF:0003H
JMP SRI_INT0 ; La RSI comienza en la dirección FF:1000H para tener más espacio de memoria.
ORG FF:1000H
SRI_INT0: MOV A,P1 ; Se lee la combinación binaria que proporciona el codificador.
ANL A,#07H ; Unicamente se toman los 3 bits significativos de P1.
RL A ; Se multiplica por dos.
MOV DPTR,#JMP_TBL ; En función de la combinación leída se salta a la rutina
JMP @A+DPTR ; que atiende al periférico que ha interrumpido.
JMP_TBL: AJMP RUT7 ; Salto a la rutina que atiende al periférico siete.
AJMP RUT6 ; Salto a la rutina que atiende al periférico seis.
AJMP RUT5 ; Salto a la rutina que atiende al periférico cinco.
AJMP RUT4 ; Salto a la rutina que atiende al periférico cuatro.
AJMP RUT3 ; Salto a la rutina que atiende al periférico tres.
AJMP RUT2 ; Salto a la rutina que atiende al periférico dos.
AJMP RUT1 ; Salto a la rutina que atiende al periférico uno.
AJMP RUT0 ; Salto a la rutina que atiende al periférico cero.
ORG FF:1100H
RUT7: ; Instrucciones de la rutina que atiende al periférico siete.
........
RETI
ORG FF:1180H
RUT6: ; Instrucciones de la rutina que atiende al periférico seis.
........
RETI
ORG FF:1200H
RUT5: ; Instrucciones de la rutina que atiende al periférico cinco.
........
RETI
ORG FF:1280H
RUT4: ; Instrucciones de la rutina que atiende al periférico cuatro.
........
RETI
ORG FF:1300H
RUT3: ; Instrucciones de la rutina que atiende al periférico tres.
........
RETI
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251162
ORG FF:1380H
RUT2: ; Instrucciones de la rutina que atiende al periférico dos.
........
RETI
ORG FF:1400H
RUT1: ; Instrucciones de la rutina que atiende al periférico uno.
........
RETI
ORG FF:1480H
RUT0: ; Instrucciones de la rutina que atiende al periférico cero.
........
RETI
Ejemplo 6.6 Control de múltiples periféricos externos mediante chequeo
En este ejemplo se utiliza una secuencia de chequeo para determinar la prioridad de atención a
ocho periféricos externos conectados a la entrada de interrupción /INT0 (figura 6.13). Las
salidas de interrupción de cada periférico se han conectado a la entrada /INT0 a través de un
driver de salida en colector abierto. Basta que un periférico active su salida de interrupción
para que la entrada de interrupción /INT0 pase a cero lógico. El periférico que interrumpe
activa al mismo tiempo un bit del puerto P1.
Cuando ocurre una interrupción, la RSI se encarga de leer el puerto P1 y averiguar por chequeo
qué periférico o periféricos han interrumpido y atenderlos siguiendo un orden establecido en la
propia RSI.
En la figura 6.14 está representado el flujograma correspondiente a este ejemplo. La prioridad
de cada periférico se establece con el orden de chequeo de los bits del puerto P1. En este
ejemplo, se verifica en primer lugar el bit P1.7, de forma que es el periférico 7 el más
prioritario. El periférico 0 es el menos prioritario porque se verifica en último lugar.
8XC251
P1.7
P1.6
P1.5
P1.4
P1.3
P1.2
P1.1
P1.0
INT0
+5V
Periférico 7 INT
Periférico 6 INT
Periférico 5 INT
Periférico 4 INT
Periférico 2 INT
Periférico 1 INT
Periférico 0 INT
Periférico 3 INT
Colector
Abierto
Fig. 6.13 Conexión de ocho periféricos a la entrada de interrupción /INT0
© Los autores, 2001; © Edicions UPC, 2001.
6 Las interrupciones 163
;*****************************************************************
; RUTINA DE SERVICIO A LA INTERRUPCION INT0
;*****************************************************************
ORG FF:0003H
JMP SRI_INT0 ; La rutina comienza en la dirección FF:1000H
ORG FF:1000H ; para tener más espacio de memoria
SRI_INT0: JB P1.7,SIG6 ; Si P1.7 (bit MSB) es cero salta a la
CALL SRI_7 ; rutina de atención del periférico 7
SIG6: JB P1.6,SIG5 ; Si P1.6 es cero salta a la rutina
CALL SRI_6 ; de atención del periférico 6
SIG5: JB P1.5,SIG4 ; Si P1.5 es cero salta a la rutina
CALL SRI_5 ; de atención del periférico 5
SIG4: JB P1.4,SIG3 ; Si P1.4 es cero salta a la rutina
CALL SRI_4 ; de atención del periférico 4
SIG3: JB P1.3,SIG2 ; Si P1.3 es cero salta a la rutina
CALL SRI_3 ; de atención del periférico 3
SIG2: JB P1.2,SIG1 ; Si P1.2 es cero salta a la rutinala rutina
CALL SRI_2 ; de atención del periférico 2
SIG1: JB P1.1,SIG0 ; Si P1.1 es cero salta a la rutina
CALL SRI_1 ; de atención del periférico 1
SIG0: JB P1.0,FIN ; Si P1.0 es cero salta a la rutina
CALL SRI_0 ; de atención del periférico 0
FIN: RETI
SRI_7: ; Instrucciones de la rutina de atención del periférico 7
.......
RET
SRI_6: ; Instrucciones de la rutina de atención del periférico 6
.......
RET
SRI_5: ; Instrucciones de la rutina de atención del periférico 5
.......
RET
SRI_4: ; Instrucciones de la rutina de atención del periférico 4
.......
RET
SRI_3: ; Instrucciones de la rutina de atención del periférico 3
.......
RET
SRI_2: ; Instrucciones de la rutina de atención del periférico 2
.......
RET
SRI_1: ; Instrucciones de la rutina de atención del periférico 1
.......
RET
SRI_0: ; Instrucciones de la rutina de atención del periférico 0
.......
RET
P1.7 = 0?SI
NO
RUTINA DELPERIFÉRICO 7
P1.5 = 0?SI
NO
RUTINA DELPERIFÉRICO 5
P1.0 = 0?SI
NO
RUTINA DELPERIFÉRICO 0
P1.1 = 0?SI
NO
RUTINA DELPERIFÉRICO 1
P1.6 = 0?SI
NO
RUTINA DELPERIFÉRICO 6
P1.4 = 0?SI
NO
RUTINA DELPERIFÉRICO 4
P1.3 = 0?SI
NO
RUTINA DELPERIFÉRICO 3
P1.2 = 0?SI
NO
RUTINA DELPERIFÉRICO 2
RSI /INT0
LEER ELPUERTO P1
RETI
Fig. 6.14 Flujograma de la RSI delejemplo 6.6
6.3.4 Interrupción de los Timers
Los flags de petición de interrupción de los Timers 0 y 1, TF0 y TF1, se activan por rebasamiento del
Timer correspondiente, excepto cuando el Timer 0 está programado en modo 3, en cuyo caso se
activan exclusivamente por rebasamiento de los registros TH0 y TL0 del Timer 0. Cuando el Timer 0
ó 1 genera una interrupción, el flag de petición de interrupción se borra automáticamente cuando la
CPU ejecuta la rutina de servicio a la interrupción.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251164
El Timer 2 posee dos flags de interrupción, TF2 y EXF2, ubicados en el registro T2CON (tabla 6.7).
La activación de cualquiera de estos bits genera una petición de interrupción a la CPU y su borrado
debe realizarse por software. Por tanto, la rutina de servicio a la interrupción deberá determinar cuál
de los dos bits ha generado la interrupción y borrarlo.
A continuacuión se presenta el flujograma (figura 6.15) y el listado de un ejemplo de RSI del Timer 2.
Este programa incorpora las instrucciones que permiten detectar cuál de los dos flags de interrupción
del Timer 2 se ha activado, y actuar en consecuencia, de forma que si el flag activo es TF2, se ejecuta
la rutina RUTINA_TF2, y si el flag activo es EXF2, se ejecuta la rutina RUTINA_EXF2.
;****************************************************************
; RUTINA DE SERVICIO A LA INTERRUPCION TIMER 2
;****************************************************************
ORG FF:002BH ; Dirección de comienzo de la RSI del Timer 2 como origen del
programa
JMP FF:0300H ;Salto a la dirección FF:0300H donde comienza la rutina del Timer 2
ORG FF:0300H ; Programa de inicio de la RSI del Timer 2
JBC TF2, RUTINA_TF2 ;Si el flag activo es TF2 se pone a 0 lógico y se salta a
;la rutina que debe ejecutarse en caso de activación del flag TF2
CLR EXF2 ; Si el flag TF2 no esta activo se borra el flag EXF2 y se
; ejecuta la rutina RUTINA_EXF2
;Instrucciones de la rutina RUTINA_EXF2
. . . . . .
RETI
;Instrucciones de la rutina RUTINA_TF2
RUTINA_TF2: . . . . . . .
RETI
TF2=1?
RSI Timer 2
SI
NO
TF2=0
RUTINA_TF2
EXF2=0
RUTINA_EXF2
RETI
Fig. 6.15 Flujograma de la RSIdel Timer 2
6.3.5 Interrupción del array de contadores programables (PCA)
El array de contadores programables tiene asociados seis flags de interrupción: el flag de
rebasamiento del Timer del PCA, CF, y cinco flags pertenecientes a los cinco módulos de
comparación y captura de que dispone el PCA, CCF0, CCF1, CCF2, CCF3 y CCF4. La activación de
cualquiera de estos flags genera una petición de interrupción a la CPU por parte del PCA. Los flags no
se borran automáticamente cuando la CPU ejecuta la rutina de servicio a la interrupción del PCA, por
lo que, normalmente, la rutina deberá resolver cuál, o cuáles de los seis flags se han activado, y
borrarlos.
En la figura 6.16 se representa el flujograma y, a continuación, el listado de la RSI del PCA. En esta
rutina se comprueban de forma secuencial todos los flags de interrupción asociados al PCA. Si se
detecta un flag activo se borra y se ejecuta una rutina específica asociada a ese flag. Mediante el orden
de comprobación de los flags de interrupción se puede establecer el orden de prioridad de atención a
los distintos módulos que componen el PCA.
© Los autores, 2001; © Edicions UPC, 2001.
6 Las interrupciones 165
;*************************************************************
; RUTINA DE SERVICIO A LA INTERRUPCION DEL PCA
;*************************************************************
PCA EQU FF:0400H ;Etiqueta a la dirección de la RSI del PCA
ORG FF:0033H ;Dirección vector de interrupción del PCA
JMP PCA ;Salto a la rutina de la RSI del PCA
ORG FF:0400H ;Programa de RSI del PCA
JBC CF, RUTINA_CF ;Salta si CF=1 y borra el flag.
POL_CCF0: JBC CCF0,RUTINA_CCF0 ;Salta si CCF0=1 y borra el flagPOL_CCF1: JBC CCF1,RUTINA_CCF1 ;Salta si CCF1=1 y borra el flagPOL_CCF2: JBC CCF2,RUTINA_CCF2 ;Salta si CCF2=1 y borra el flagPOL_CCF3: JBC CCF3,RUTINA_CCF3 ;Salta si CCF3=1 y borra el flagPOL_CCF4: JBC CCF4,RUTINA_CCF4 ;Salta si CCF4=1 y borra el flag
;
;Instrucciones de la RUTINA_CF
. . . . . .
JMP POL_CCF0 ; Cuando termina la ejecución de RUTINA_CF
; salto a comprobar el siguiente bit
; Instrucciones de la RUTINA_CCF0
. . . . . . .
JMP POL_CCF1 ;Cuando termina la ejecución de RUTINA_CCF0
; salto a comprobar el siguiente bit
. . . . . . .
; Instrucciones de la RUTINA_CCF4
. . . . . . .
RETI ; Cuando termina la ejecución de RUTINA_CCF4
; termina la ejecución de la RSI.
RSI PCA
RETI
CF=1? RUTINA_CF
CCF0=1? RUTINA_CCF0
RUTINA_CCF1CCF1=1?
RUTINA_CCF2CCF2=1?
RUTINA_CCF3CCF3=1?
RUTINA_CCF4CCF4=1?
SI
SI
SI
SI
SI
SI
NO
NO
NO
NO
NO
NO
Fig. 6.16 Flujograma de la RSI del PCA
6.3.6 Interrupción del puerto serie
El puerto serie tiene asociado dos flags de interrupción: el flag de interrupción para recepción, RI, y el
flag de interrupción para transmisión, TI. Ambos flags están ubicados en el registro SCON (tabla 6.7).
La activación de cualquiera de estos dos flags genera una petición de interrupción a la CPU por parte
del puerto serie. Tal y como ocurre con la interrupción del Timer 2 y del PCA, el borrado de los flagsTI y RI debe realizarse por programa. Por tanto, en la RSI del puerto serie se deben incluir
instrucciones que determinen cuál de estos flags se ha activado, y lo borren.
A continuación se representa el flujograma (figura 6.17) y el listado de un ejemplo de RSI del puerto
serie. Este programa incorpora las instrucciones que permiten detectar el flag de interrupción que se ha
activado y actuar en consecuencia, de forma que si el flag activo es TI, se ejecuta la rutina RUT_TI, y
si el flag activo es RI, se ejecuta la rutina RUT_RI.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251166
;******************************************************************
; RUTINA DE SERVICIO A LA INTERRUPCION TIMER 2
;******************************************************************
ORG FF:0023H ; Dirección de comienzo de la RSI del puerto serie
JMP FF:0400H ; Salto a la dirección de la rutina del puerto serie
ORG FF:0400H ; Programa de inicio de la RSI del Timer 2JBC TF2, RUT_TI ; Si el flag activo es TI se pone a 0 lógico y
; salta a la rutina correspondiente
CLR RI ; Si el flag TI no está activo se borra el flag RI y
; se ejecuta la rutina RUT_RI
;Instrucciones de la RUT_RI
. . . . . .
RETI
;Instrucciones de la RUT_TI
RUT_TI: . . . . . . .
RETI
TI = 1?
RSI puerto serie
SI
NO
TI = 0
RUT_TI
RI = 0
RUT_RI
RETI
Fig. 6.17 Flujograma de la RSI delpuerto serie
Ejemplo 6.7 Control del índice de acidez (pH) del agua de un depósito
Se plantea a continuación, como ejemplo ilustrativo de la utilización del sistema de
interrupciones del microcontrolador 8XC251Sx, un caso práctico de control de una planta de
tratamiento de aguas residuales. El objetivo de este ejemplo es mostrar el funcionamiento de las
interrupciones por lo que respecta a la habilitación, los niveles de prioridad, el manejo de los
flags de interrupción, etc.
La planta que se debe controlar dispone de un sistema que neutraliza la acidez de las aguas
residuales provenientes de una planta de fabricación de papel (figura 6.18). El sistema posee un
depósito donde se mezcla el agua residual con la cantidad adecuada del componente
neutralizador, cuya función es disminuir la acidez del agua, de forma que el agua de salida del
depósito posea un pH superior a 5.5.
El sistema de control incorpora dos sensores activos a nivel alto:
∑ Un detector de rebosamiento, S1, que se activa cuando el agua contenida en el
depósito supera la altura máxima permitida.
∑ Un detector de pH, M, que se activa cuando el pH del agua es inferior a 5.5.
El sistema de control dispone además de dos actuadores V1 y V2, activos a nivel alto, cuya
función es realizar la apertura de dos válvulas. Cuando se activa el actuador V1 se abre la
válvula que permite la entrada de las aguas residuales al depósito. Cuando se activa el actuador
V2 se abre la válvula que permite el vertido de neutralizador en el depósito. Por último, existen
dos indicadores luminosos, A1 y A2, activos a nivel alto, cuya función es la de monitorizar la
apertura de las válvulas V1 y V2.
© Los autores, 2001; © Edicions UPC, 2001.
6 Las interrupciones 167
Entrada
de aguas
residuales
Descarga
Neutralizador
Medidor
pH
S1
Sistemade control
V1V2
M
A1
A2
Fig. 6.18 Esquema de la planta que se desea controlar
En la figura 6.19 está representado el esquema eléctrico donde se detalla la conexión del µC
8XC251Sx con los diferentes sensores y actuadores que intervienen en esta aplicación. Cabe
destacar que los sensores S1 y M están conectados a las entradas de interrupción /INT0 e /INT1
a través de sendas puertas inversoras, debido a que las interrupciones externas se activan a
nivel bajo, mientras que estos sensores son activos a nivel alto.
A2
A1
8XC251
P1.2
P1.3
S1 V1P1.0INT0
M V2P1.1INT1
Fig. 6.19 Conexión de sensores y actuadores con el µC 8XC251Sx
La estrategia que debe llevar a cabo el sistema de control para gestionar el funcionamiento de
la planta de tratamiento de aguas residuales se puede resumir en dos puntos:
∑ La válvula V1 debe permanecer abierta hasta que el sensor S1 se active; entonces se
cerrará durante treinta segundos. Si una vez pasado este tiempo el sensor S1 sigue activo,
se repetirá la operación de cierre de la válvula V1. Mientras V1 esté abierta, el indicador
A1 permanecerá encendido; en caso contrario el indicador parpadeará.
∑ La válvula V2 debe estar cerrada hasta que se active el sensor M y entonces abrirse durante
cinco segundos. Una vez transcurrido ese tiempo, si el sensor M continua activo, se
repetirá la operación de apertura de la válvula V2. El indicador A2 se activa cuando la
válvula V2 está abierta y parpadea cuando está cerrada.
Los recursos utilizados para resolver esta aplicación son cuatro:
∑ La interrupción externa /INT0, que se encarga de detectar la activación del sensor S1. La
interrupción se activa por nivel para que pueda ser atendida por la CPU mientras el
sensor S1 se encuentre a uno lógico.
∑ La interrupción externa /INT1, cuya función es detectar la activación del medidor de pH.
Esta interrupción también se programa por nivel por el mismo motivo que la /INT0.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251168
∑ El Timer 0, que se encarga de temporizar el intervalo de 30 s, tiempo que debe
permanecer abierta la válvula V1 cuando se active S1.
∑ El Timer 1, que se encarga de temporizar los 5 s de apertura de la válvula V2.
∑ El programa esta compuesto de una rutina principal y de cuatro rutinas de atención a la
interrupción, una por cada fuente de interrupción utilizada en la aplicación.
La función del programa principal será básicamente la de habilitar y programar los niveles de
prioridad de las diversas fuentes de interrupción utilizadas, así como la de ejecutar la secuencia
de parpadeo de los indicadores luminosos A1 y A2.
Para habilitar las cuatro fuentes de interrupción se ponen a uno lógico los bits correspondientes
del registro habilitador de interrupciones IE0: EX0, ET0, EX1 y ET1. Esto se consigue
cargando en el registro IE0 el valor 8FH (10001111b).
Por otra parte, se deben poner a uno lógico los bits IT0 e IT1 del registro TCON, con el
objetivo de que las interrupciones externas /INT0 e /INT1 se activen por nivel. Esto se
consigue almacenando en el registro TCON el valor 0AH (0000 1010b).
A continuación se debe establecer la prioridad de las interrupciones. En principio se adjudica a
las interrupciones /INT0 y Timer 0 una prioridad mayor que a las interrupciones /INT1 y Timer1, dado que la situación de rebasamiento requiere una actuación más urgente que la superación
del nivel de pH. Las fuentes /INT0 y Timer 0 se programan con nivel de prioridad tres,
mientras que las fuentes de interrupción /INT1 y Timer 1 se programan con un nivel de
prioridad menor, por ejemplo con nivel cero. Por tanto, los registros de nivel de prioridad IPH0
e IPL0 quedan: IPH0 = 03H y IPL0 = 03H.
Por último, se debe poner el bit INTR del byte de configuración CONFIG1 a uno lógico. De
esta forma, cuando la CPU ejecute una interrupción, se cargarán en la pila, automáticamente,
los tres bytes del contador de programa, PC, y el registro de estado, PSW1.
En cuanto a la rutina de retardo, que se utiliza para temporizar el parpadeo de los indicadores
luminosos, estará compuesta de dos bucles anidados, basados en decrementar los registros R0 y
R1. Modificando el valor de los registros R0 y R1 se puede variar el tiempo de ejecución de la
rutina y, por tanto, la frecuencia de parpadeo. Para calcular el tiempo de retardo hay que
determinar el número de veces que se ejecuta cada instrucción, así como el tiempo que tarda en
ejecutarse cada una de ellas.
En la figura 6.20 se muestran los flujogramas correspondientes al programa principal y a la
rutina de retardo. En la figura 6.21 se muestran los flujogramas de las rutinas de atención a las
interrupciones /INT0 y Timer 0. Las tareas que debe realizar la rutina de atención a la
interrupción /INT0 son:
∑ Cerrar la válvula V1.
∑ Inicializar el Timer 0 para que temporice 30 s.
∑ Inhibir la interrupción /INT0 para impedir que se ejecute de forma repetida la RSI de la
/INT0 mientras el sensor S1 se encuentra activo y no ha finalizado la temporización de 30s.
© Los autores, 2001; © Edicions UPC, 2001.
6 Las interrupciones 169
Si consideramos que la frecuencia de reloj es de 1.2 MHz, se puede determinar, mediante un
cálculo sencillo, que el Timer 0 debe rebasar varias veces para temporizar 30 s.
En la RSI del Timer 0 se debe contar el número de rebasamientos que sufre este temporizador.
Cuando el Timer 0 rebasa un número de veces equivalente a 30 s se abre la válvula V1, se
detiene el funcionamiento del Timer 0 y se habilita de nuevo la interrupción /INT0, de forma
que si el sensor S1 continúa activo se repite de nuevo la secuencia de cierre de V1.
PRINCIPAL
INICIALIZAR:
IE0 = 8FH
TCON = 0AH
IPH0 = 03H
IPL0 = 03H
P1.2 = 1
P1.3 = 1
RETARDO
P1.2 = 0
P1.3 = 0
RETARDO
RETARDO
R0 = 10H
DECREMENTA R1
R1 = FFH
R0 = 0?
R1 = 0?
DECREMENTA R0
RET
NO
SI
SI
NO
Fig. 6.20 Flujograma del programa principal y de la rutina de retardo
INT0
INICIALIZAR T0
CERRAR VÁLVULA V1
RETI
ACTIVACIÓN T0
INHIBIR INT0
T0
BORRAR IE0
ABRIR VÁLVULA V2
HABILITAR INT0
PARAR T0
RETI
T = 30s?NO
SI
Fig. 6.21 Flujogramas de las rutinas de servicio a las interrupciones /INT0 y Timer 0
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251170
Las rutinas de atención a las interrupciones /INT1 y Timer 1 tienen funciones similares a las
interrupciones /INT0 y Timer 0. En la figura 6.22 se presentan los flujogramas
correspondientes a ambas rutinas.
INT1
INICIALIZAR T1
ABRIR VÁLVULA V2
RETI
ACTIVACIÓN T1
INHIBIR INT1
T1
BORRAR IE1
CERRAR VÁLVULA V2
HABILITAR INT1
PARAR T1
RETI
T = 5s?NO
SI
Fig. 6.22 Flujogramas de las rutinas de servicio a las interrupciones /INT1 y Timer1
A continuación se presentan el listado del programa principal y de la rutina de retardo.
;****************************************************************************
; VECTORIZACION INTERRUPCIONES
;****************************************************************************
ORG FF:0003H ; Vector de interrupción de /INT0
JMP RSI_INT0
ORG FF:000BH ; Vector de interrupción del Timer 0JMP RSI_T0
ORG FF:0013H ; Vector de interrupción de /INT1
JMP RSI_INT1
ORG FF:001BH ; Vector de interrupción del Timer 1JMP RSI_T1
;******************************************************************************
; PROGRAMA PRINCIPAL
;******************************************************************************
ORG FF:0000H
JMP PRINCIP
ORG FF:0100H
; Programación del nivel de prioridad de las interrupciones externas 0 y 1
PRINCIP: MOV IE0,#8FH ; Habilitación de las interrupciones
MOV TCON,#0AH ; Se programa /INT0 e /INT1 por nivel
MOV IPL0,#03H ; Programación de los niveles de prioridad
MOV IPH0,#03H
SETB INTR ; Cuando la CPU vectorice una interrupción cargará en la pila
; los 3 bytes del PC y el registro de estado PSW1
;Secuencia de parpadeo de los indicadores luminosos A1 y A2
SALTO0: SETB P1.2
SETB P1.3
CALL RETARDO
CLR P1.2
CLR P1.3
CALL RETARDO
JMP SALTO0
© Los autores, 2001; © Edicions UPC, 2001.
6 Las interrupciones 171
;************************************************************************
; RUTINA DE RETARDO
;*************************************************************************
ORG FF:0200H
RETARDO: MOV R0,#10H ; R0 = 10H
SALT2: MOV R1,#FFH ; R1 = FFH
SALT1: DJNZ R1,SALT1 ; Decrementa R1 y si es distinto de 0 salta a SALT1
DJNZ R0,SALT2 ; Decrementa R2 y si es distinto de 0 salta a SALT2
RET
;************************************************************************
; RUTINA DE SERVICIO A LA INTERRUPCION INT0
;*************************************************************************
ORG FF:0300H
RSI_INT0: CLR P1.0 ; Se cierra la válvula V1
SETB TMOD.0 ; Se programa el Timer 0 en modo 1
MOV TH0,#3CH ; Se inicializa el Timer 0 para temporizar 0.5 s
MOV TL0,#AFH ;
MOV R3,#00H ; El registro R3 contará los rebasamientos del Timer 0SETB TR0 ; Puesta en marcha del Timer 0CLR EX0 ; Se inhibe la interrupción /INT0
RETI
Cálculo del valor inicial del Timer 0
Para temporizar los treinta segundos se inicia el Timer 0 para que tarde 0.5 s en rebasar (de
forma que se deben contabilizar 60 rebasamientos en la RSI del Timer 0 para abrir de nuevo la
válvula V1). Para temporizar 0.5 s, con una frecuencia de reloj de 1.2 MHz, el Timer 0 debe
incrementarse 50.000 veces (C350H); luego se ha de cargar dicho Timer con la combinación
resultante de restar a FFFFH el valor C350H:
FFFFH - C350H = 3CAFH
;**************************************************************************
; RUTINA DE SERVICIO A LA INTERRUPCION TIMER 0
;***************************************************************************
ORG FF:0400H
RSI_T0: INC R3 ; Se incrementa el contador de rebasamientos
CMP R3,59d ; Se compara el número de rebasamientos con 59
JNC SIGUE ; Si el número de rebasamientos es menor o igual que 59 continua temporizando
CLR TR0 ; En caso contrario se detiene el Timer 0 y
CLR P1.0 ; se abre la válvula V1
SETB EX0 ; Se habilita de nuevo la interrupción /INT0
CLR IE0 ; Se borra el flag de la interrupción /INT0
SIGUE: RETI ; Retorno al programa principal
;****************************************************************************
; RUTINA DE SERVICIO A LA INTERRUPCION INT1
;*****************************************************************************
ORG FF:0500H
RSI_INT1: SETB P1.1 ; Se abre la válvula V2.
SETB TMOD.4 ; Se programa el Timer 1 en modo 1
MOV TH1,#3CH ; Se inicializa el Timer 1 para temporizar 0.5 s
MOV TL1,#AFH ;
MOV R4,#00H ; El registro R4 contará los rebasamientos del Timer 1SETB TR1 ; Puesta en marcha del Timer 1CLR EX1 ; Se inhibe la interrupción /INT1
RETI
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251172
;**************************************************************************
; RUTINA DE SERVICIO A LA INTERRUPCION TIMER 1
;**************************************************************************
ORG FF:0600H
RSI_T1: INC R4 ; Se incrementa el contador de rebasamientos
CMP R4,09d ; Se compara el número de rebasamientos con 9
JNC SIGUE1 ; Si el número de rebasamientos es menor o igual que 9 continua temporizando.
CLR TR1 ; Se detiene el Timer 1
SETB P1.1 ; Se abre la válvula V2
SETB EX1 ; Se habilita la interrupción /INT1
CLR IE1 ; Se borra el flag de la interrupción /INT1
SIGUE1: RETI ; Retorno al programa principal
© Los autores, 2001; © Edicions UPC, 2001.
7 Temporizadores/contadores internos y watchdog 173
7 Temporizadores/contadores internos y watchdog
7.1 Introducción
Los microcontroladores de las familias MCS-51 y MCS-251 disponen de hasta tres contadores
internos de 16 bits, denominados Timer 0, Timer 1 y Timer 2, que pueden ser configurados de forma
individual para operar en diversos modos de trabajo. Estos contadores, en general, se incrementan en
una unidad cada vez que les entra un pulso de reloj, el cual puede provenir de la frecuencia de reloj del
microcontrolador o bien de un terminal externo, por lo que, en el primer caso, al Timer se le denomina
temporizador y, en el segundo caso, se le denomina contador.
Por otra parte hay microcontroladores que incorporan un contador adicional, cuya misión consiste en
hacer de dispositivo de watchdog (“perro guardián”). Este contador se emplea para reiniciar la CPU
cuando ésta, por problemas de interferencia electromagnética, o por algún fallo interno, pierde el
rumbo habitual de ejecución de las instrucciones, fenómeno que resulta fácil de distinguir por la
gestión caótica que hace la CPU de sus periféricos. El Timer de watchdog es un contador que se
incrementa con cada pulso del reloj de la CPU; genera entonces un reset interno que inicializa el
microcontrolador cuando llega a desbordamiento.
Con el Timer de watchdog, para que se active este reset interno, deben pasar unos pocos milisegundos,
que es el tiempo necesario para que el contador de watchdog llegue al desbordamiento. De manera
que, cuando el watchdog está activado, el programador debe insertar instrucciones de refresco o de
inicialización del Timer cada cierto intervalo de instrucciones. Se trata, pues, de que el watchdog no
llegue desbordarse, mientras el flujo de ejecución de instrucciones por parte de la CPU sea correcto. Si
la CPU pierde el control del sistema, las instrucciones se ejecutan de forma caótica, por lo que la serie
de instrucciones de refresco del watchdog no se ejecutan con la regularidad prevista, lo que causa el
desbordamiento del Timer y un auto-reset de la CPU para inicializar el sistema.
El Timer de watchdog está presente en los microcontroladores de la familia MCS-251 y sólo en la
versión 87C51GB de la familia MCS-51, versión que no se explica en este libro, pues se explica tan
sólo para la familia MCS-251.
Se debe tener en cuenta que la homologación de muchos productos basados en microcontroladores se
somete a pruebas con intensas interferencias electrostáticas y electromagnéticas, con el propósito de
que la CPU pierda el rumbo habitual de ejecución. En este caso, el sistema debe inicializarse.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251174
7.2 Temporizadores/contadores para la MCS-51
7.2.1 Timer 0 y Timer 1
El Timer 0 y el Timer 1 son contadores de 16 bits que están presentes en todos los microcontroladores
de la MCS-51. El valor de estos contadores se refleja en los registros TH0 y TL0, para el Timer 0, y en
los registros TH1 y TL1, para el Timer 1. El registro THx constituye el byte alto del contador y el
registro TLx el byte bajo.
El Timer 0 y el Timer 1 pueden funcionar con cuatro modos de trabajo distintos, seleccionables
mediante el registro TMOD, Timer Mode. Los modos de trabajo son: modo 0, temporizador/contador
de 13 bits; modo 1, temporizador/contador de 16 bits; modo 2, temporizador/contador de 8 bits con
autorrecarga; y modo 3, varios contadores.
La figura 7.1 muestra el esquema funcional del Timer 0 y del Timer 1, para los modos 0 y 1 de
funcionamiento, con temporizador de 13 y 16 bits, respectivamente. En esta figura se resaltan, con un
cuadro de puntos, dos bloques: el bloque de selección de temporizador/contador y el bloque de la
lógica de control. Estos bloques son comunes al Timer 0 y al Timer 1 y a los modos de funcionamiento
0, 1 y 2 de los Timers.
÷12
(8 ó 5 bits)
TLx
(8 bits)
TFxTx
XTAL1
Interrupción
Modo 0: Temporizador/contador de 13 bits
Modo 1: Temporizador/contador de 16 bits
x = 0 ó 1
0
1
TRx
GATE
INTx
† *
†
*
Lógica de control
Temporizador/contador
C/T
Puerta de transmisión
THx
Fig. 7.1 Esquema funcional para los Timers 0 y 1 en los modos 0 y 1 de funcionamiento
El bloque de selección de temporizador/contador, mediante el bit T/C del registro TMOD, Timer
Mode, selecciona la fuente de entrada de pulsos del Timer, que puede provenir directamente de la
señal de reloj del microcontrolador dividida por 12, para T/C a 0 lógico, o de una entrada de pulsos
externa a través del terminal Tx del microcontrolador, para T/C a 1 lógico.
El bloque de lógica de control utiliza una puerta de transmisión para dejar pasar, o no, los pulsos de
reloj hacia el contador (figura 7.1). En este bloque intervienen el bit TRx, Timer Run, del registro
TCON, el bit GATE del registro TMOD y el terminal de entrada /INTx, con el propósito de controlar
el paso de pulsos de reloj hacia el contador, lo que a partir de este momento se definirá como puestaen marcha o parada del contador. Con los bits TRx y GATE se puede poner en marcha o parar el
Timer de forma directa, por software, o bien, por medio del estado lógico del terminal /INTx, por
hardware.
© Los autores, 2001; © Edicions UPC, 2001.
7 Temporizadores/contadores internos y watchdog 175
Observando el circuito de la lógica de control, se deduce que si el bit GATE se pone a 0 lógico, en la
entrada de la puerta OR (figura 7.1), habrá un 1 lógico y, por tanto, un 0 lógico en la entrada de la
puerta AND; en esta situación queda claro que la puerta está gobernada por el estado lógico del bit
TRx. Entonces, si TRx vale 0 lógico, la puerta queda abierta y el Timer parado, y si TRx vale 1 lógico,
la puerta queda cerrada y el Timer en marcha, y se incrementa a cada pulso de entrada. En esta
situación, con el bit GATE a 0 lógico, la puesta en marcha o la parada del Timer depende del estado
del bit TRx, y queda, en consecuencia, gobernado por software.
Si GATE se pone a 1 lógico, a la entrada de la puerta OR, tras la puerta inversora (figura 7.1), habráun 0 lógico; luego, el estado lógico de la puerta OR dependerá directamente del estado lógico del
terminal /INTx. Si al mismo tiempo, el bit TRx se pone a 1 lógico, queda claro que el gobierno de la
puerta de transmisión dependerá del terminal /INTx, que pondrá en marcha el Timer cuando /INTx
esté a 1 lógico, y parará el Timer cuando /INTx esté a 0 lógico, lo que se mencionará, a partir de
ahora, como puesta en marcha o parada del contador por hardware, es decir, por el estado lógico de
/INTx.
La determinación del modo de funcionamiento del Timer 0 y del Timer 1 se realiza con los bits M0 y
M1 del registro TMOD: existen, en efecto, en este registro un par de bits para cada Timer (tabla 7.1).
El contenido del registro TCON se muestra en la tabla 6.2.
Tabla 7.1 Registro TMOD
M0M1C/TGATEM0M1GATE
(LSB)(MSB) Registro TMOD
C/T
Timer 1 Timer 0
Bit Comentario
GATE GATE a 0 lógico hace que el Timer se gobierne mediante TRx, con TRx a 1
lógico se pone en macha el Timerx y con TRx a 0 lógico se detiene (x=0 ó 1).
GATE a 1 lógico, junto con TRx a 1, hace que el Timer se gobierne por
hardware, mediante el estado lógico de la entrada /INTx.
C/T Selecciona entre pulsos de la señal de reloj o pulsos del terminal Tx. Si C/T está a
0 se toman los pulsos de la señal de reloj y si C/T está a 1 se toman de Tx.
M1 M00 0
0 1
1 0
1 1
Selección del modo de trabajoModo 0. Temporizador/contador de 13 bits.
Modo 1. Temporizador/contador de 16 bits.
Modo 2. Temporizador/contador de 8 bits con autorrecarga.
Modo 3. Varios contadores.
7.2.1.1 Modo 0. Temporizador/contador de 13 bits
En el modo 0, el Timer 0 y el Timer 1 operan como temporizadores/contadores de 13 bits (figura 7.1),
empleando, en realidad, el registro TLx como un divisor previo de 5 bits, que puede dividir la
frecuencia de la señal de entrada de los Timers hasta por 32; y el registro THx como un contador de 8
bits conectado a la salida de TLx. Los tres bits altos de TLx están en un estado indeterminado, que
debe ser ignorado.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251176
El sentido del contador es siempre ascendente y se incrementa con cada pulso de entrada. El
rebasamiento del Timer se produce cuando pasa de tener todos los bits de uno lógico a cero lógico;
entonces se activa el bit correspondiente de rebasamiento, TFx, y se genera una interrupción a la CPU.
7.2.1.2 Modo 1. Temporizador/contador de 16 bits
En el modo 1 el Timer 0 y el Timer 1 operan como un temporizador/contador de 16 bits (figura 7.1).
En este modo los registros TLx y THx son dos contadores de 8 bits que están conectados en cascada
para formar el contador de 16 bits.
Al igual que en el modo 0, en el modo1 el sentido del contador es ascendente, y el rebasamiento se
produce al pasar el contenido de los registros TLx y THx de todos los bits de uno lógico a cero lógico.
El rebasamiento entonces activa el bit TFx y genera una interrupción a la CPU.
7.2.1.3 Modo 2. Temporizador/contador de 8 bits con autorrecarga
En el modo 2 el Timer 0 y el Timer 1 funcionan como un temporizador/contador de 8 bits con
autorrecarga (figura 7.2). El contador está formado por el registro TLx, mientras que el registro THx
hace la función de registro de recarga. En este modo de trabajo, cuando se produce un desbordamiento
en el contador, el bit TFx se activa de manera automática, causa una interrupción a la CPU y hace, al
mismo tiempo, que el contenido de THx se cargue en el registro TLx, por lo que el contador comienza
a contar pulsos a partir del valor cargado. Este proceso de recarga no modifica el valor del registro
THx, mediante el cual se pueden generar períodos de tiempo precisos a partir del valor situado en
THx.
÷12
TLx TFxTx
XTAL1Interrupción
x = 0 ó 1
0
1
TRx
GATE
INTx
C/T
THx
Fig. 7.2 Esquema funcional para los Timers 0 y 1 en el modo 2 de funcionamiento
Ejemplo 7.1 Generación de una señal periódica
Es habitual en un sistema tener que generar señales periódicas: en el caso de la MCS-51 se
pueden llevar a cabo empleando uno o varios de sus temporizadores. En este ejemplo se usa el
Timer 0 en el modo 2 de 8 bits con autorrecarga, para generar una señal binaria de 5kHz de
frecuencia. Para determinar el período de la señal se empleará el registro TH0 del Timer 0. La
señal generada se extraerá a través de la patilla P1.0 del microcontrolador (figura 7.3).
© Los autores, 2001; © Edicions UPC, 2001.
7 Temporizadores/contadores internos y watchdog 177
;***************************************************************
; Generación de una señal periódica
; Rutina de Vectorización
;***************************************************************
ORG 0H
LJMP Inicio
ORG 0BH
LJMP RSI_Timer0
;***************************************************************
; Rutina de Inicio
;***************************************************************
Inicio: SETB PT0 ;Asigna prioridad alta al Timer 0SETB ET0 ;Habilita interrupción del Timer 0SETB EA ;Habilita bit de interrupción general
MOV TMOD,#02H ;M1=1 y M0=0 (Modo 2),
; GATE=0 y C/T=0 del Timer 0MOV TL0, #156 ;Pone valor 156 en TL0 (256-100)
MOV TH0, #156 ;Pone valor de recarga en TH0 (256-100)
SETB TR0 ;Pone marcha el contador
;***************************************************************
; Rutina de Principal
;***************************************************************
Principal: SJMP Principal ;Bucle infinito sin una tarea concreta
;***************************************************************
; Rutina de servicio del Timer0;***************************************************************
RSI_Timer0:CPL P1.0 ;Complementa P1.0. Pasa de 1 a 0, y de 0 a 1
RETI ;Fin de rutina. El bit TF0 se borra automáticamente
P1.0
MCS-51
Fig. 7.3 Generación de señal en elejemplo 7.1
En el programa realizado se habilita la interrupción del Timer 0 (ET0=1, EA=1), se le da
prioridad alta a la interrupción del Timer 0 (PT0=1), y se configura el Timer 0 en el modo 2 de
8 bits con autorrecarga (M1=1 y M0=0, registro TMOD). La puesta en marcha del Timer 0 es
por software (GATE=0, registro TMOD), el Timer 0 cuenta pulsos procedentes del reloj del
microcontrolador (C/T=0, registro TMOD), y, al final de la rutina Inicio, se pone en marcha el
Timer (TR0=1).
El Timer 0 está gestionado completamente por interrupciones, de manera que cada vez que
llega a desbordamiento se activa el bit TF0, TF0=1, se produce una interrupción a la CPU y se
recarga el valor del registro TH0 en el registro TL0. En la rutina de atención a la interrupción
del Timer 0, RSI_Timer0, basta con complementar el estado lógico de la patilla P1.0, para
generar la frecuencia requerida. Con esta instrucción el microcontrolador lee el estado de la
patilla, lo complementa (pasa de 0 lógico a 1 lógico, y viceversa) y escribe el nuevo estado en
la patilla.
El bit de rebasamiento se activa con la petición de interrupción y se borra, de forma automática,
cuando la CPU atiende a la interrupción ejecutando la rutina RSI_Timer0.
Para determinar el valor de recarga del registro TH0, se debe considerar que el período
necesario para generar frecuencia de 5 kHz es de 200 [s, por lo que la patilla P1.0 se debe
complementar cada 100 [s, es decir, la mitad del período. Además, desde que se produce la
interrupción (estado S5P2 del ciclo máquina), hasta que se vectoriza la interrupción del Timer0, transcurren tres ciclos máquina en el mejor de los casos, y la instrucción CPL P1.0 se ejecuta
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251178
en un ciclo máquina. Por tanto, el estado lógico de la patilla P1.0 cambiará, al menos, cuatro
ciclos máquina después de que se halla activado el bit TF0.
El valor de recarga de TH0 debe ser de 156, es decir, el valor de la diferencia entre 256 (valor
de rebasamiento) y el tiempo deseado, 100 [s. Se debe tener en cuenta que para un reloj de
12MHz, el Timer 0 se incrementa cada microsegundo y que un ciclo máquina tiene la duración
de 1 [s.
Ejemplo 7.2 Generación de diversas frecuencias
En este ejemplo se generarán distintas frecuencias por la patillas P1.6 y P1.7 del
microcontrolador, en función del estado de las teclas T1, T2, T3, T4, T5 y T6. Las cuatro
primeras teclas están conectadas a la entrada de interrupción /INT0 mediante puertas AND
lógico, de forma que su pulsación causará una interrupción a la CPU.
P1.0
P1.1
P1.2
P1.3
/INT0
80C31
T1
T2
T3
T4
T5
T6P1.4
P1.5
P1.7
P1.6 f1
f2
Fig. 7.4 Generación de diversas frecuencias del ejemplo 7.2
En este ejemplo el microcontrolador debe generar en la patilla P1.6 una frecuencia de 4kHz,
5kHz, 10kHz y 20kHz, si se pulsan las teclas T1, T2, T3 o T4, respectivamente. Las teclas T5 y
T6 afectarán a la frecuencia de la patilla P1.7. Al pulsar T5 se generará en P1.7 una frecuencia
de 25kHz; al pulsar T6 la frecuencia será de 50kHz. Inicialmente, por defecto, en P1.6 y en
P1.7 se generará una frecuencia de 2kHz. Cuando se pulse una tecla se generará la frecuencia
correspondiente, y cuando no se pulse ninguna se volverá a generar la frecuencia inicial de
2kHz.
;********************************************************************
; Generación de una señal periódica
;********************************************************************
ORG 0H ; Vectorización de interrupciones
LJMP Inicio
ORG 03H
LJMP RSI_Int0
ORG 0BH
LJMP RSI_Timer0
ORG 01BH
LJMP RSI_Timer1
;********************************************************************
; Rutina de Inicio
;********************************************************************
Inicio: SETB IT0 ;Interrupción /INT0 activa por flanco descendente
SETB PT0 ;Asigna prioridad alta al Timer 0
© Los autores, 2001; © Edicions UPC, 2001.
7 Temporizadores/contadores internos y watchdog 179
SETB PT1 ;Asigna prioridad alta al Timer 1SETB EX0 ;Habilita interrupción de /INT0
SETB ET0 ;Habilita interrupción del Timer 0SETB ET1 ;Habilita interrupción del Timer 1SETB EA ;Habilita bit de interrupción general
MOV TMOD, #22H ;Timer 0 y 1 en Modo 2, con GATE=0 y C/T=0
MOV TL0, #6 ;(256-250) carga valor inicial para frec. de 2kHz
MOV TH0, #6 ;carga valor inicial para frec. de 2kHz
MOV TL1, #6 ;carga valor inicial para frec. de 2kHz
MOV TH1, #6 ;carga valor inicial para frec. de 2kHz
SETB TR0 ;Pone marcha el Timer 0SETB TR1 ;Pone marcha el Timer 1LJMP Principal ;Ir hacia rutina principal
;********************************************************************
; Rutina de servicio de /INT0
;********************************************************************
RSI_Int0: JNB P1.0, Tecla_T1 ;¿Ha pulsado la tecla T1?
JNB P1.1, Tecla_T2 ;¿Ha pulsado la tecla T2?
JNB P1.1, Tecla_T3 ;¿Ha pulsado la tecla T3?
SJMP Tecla_T4 ;Tiene que ser la tecla T4
Tecla_T1: MOV TH0, #131 ;(256-125) valor de recarga para 4kHz
RETI
Tecla_T2: MOV TH0, #156 ;(256-100) valor de recarga para 5kHz
RETI
Tecla_T3: MOV TH0, #206 ;(256-50) valor de recarga para 10kHz
RETI
Tecla_T4: MOV TH0, #231 ;(256-25) valor de recarga para 20kHz
RETI
;********************************************************************
; Rutina de servicio del Timer0;********************************************************************
RSI_Timer0:CPL P1.6 ;Complementa P1.6
RETI ;Fin de subrutina. El bit TF0 se borra automáticamente
;********************************************************************
; Rutina de servicio del Timer1;********************************************************************
RSI_Timer1:CPL P1.7 ;Complementa P1.7
RETI ;Fin de subrutina. El bit TF0 se borra automáticamente
;********************************************************************
; Rutina de Principal
;********************************************************************
Principal: JNB P1.4, Tecla_T5
JNB P1.5, Tecla_T6
MOV TH0, #6 ;frecuencia por defecto de 2kHz en Timer 0MOV TH1, #6 ;frecuencia por defecto de 2kHz en Timer 1SJMP Principal ;Bucle infinito
Tecla_T5: MOV TH1, #236 ;(256-20) valor de recarga para 25kHz
SJMP Principal
Tecla_T6: MOV TH1, #246 ;(256-10) valor de recarga para 50kHz
SJMP Principal
En la rutina de inicio se ha activado la interrupción /INT0 por flanco descendente, por lo que la
interrupción sólo se producirá una vez, cuando se pulse una tecla, al detectar la CPU un flanco de
bajada. En la rutina de inicio se le asigna prioridad alta al Timer 0 y al Timer 1, por ser el núcleo de
este ejemplo. El Timer 0 y el Timer 1 se configuran en el modo 2 de autorrecarga contando pulsos del
reloj.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251180
Para determinar el valor de los registros TH0 y TH1, de acuerdo con la frecuencia especificada, se
debe tener en cuenta que la frecuencia se genera a través de la instrucción CPL en la rutina de RSI de
cada Timer. La instrucción CPL complementa el valor del terminal del puerto cada vez que un
temporizador llega a rebasamiento, por lo que para generar una frecuencia se debe emplear la mitad
del período de ésta. Con una frecuencia de reloj de 12 MHz, el período de cada pulso de reloj es de 1
[s, los temporizadores, pues, se incrementan cada microsegundo. Luego, para generar una frecuencia
determinada en el Timer 0 ó 1, el valor del registro TH0 o TH1 debe ser:
2
reloj Período-torebasamien de Valor1,0TH ]
En este ejemplo, para generar una frecuencia de 2 kHz el valor de TH0 es de 236, para 4 kHz el valor
es de 131, etc. El Timer 0 llega a rebasamiento cuando TL0 pasa de FFH a 00H, por lo que el valor de
rebasamiento, es decir, el valor máximo del Timer, es de 256 o FFH+1.
La pulsación de las teclas T5 y T6 se detecta mediante software en la rutina principal, donde
continuamente se lee el estado de estas teclas, y se asigna al registro TH1 el valor de 236 para generar
una frecuencia de 25 kHz, o el valor 246 para generar una frecuencia de 50 kHz.
7.2.1.4 Modo 3. Varios contadores
En el modo 3 los registros TL0 y TH0 del Timer 0 trabajan como dos contadores independientes de 8
bits cada uno (figura 7.5); de manera que se empleará en aquellas aplicaciones que requieren de un
temporizador o contador de 8 bits adicional.
En el modo 3 el contador formado por TL0 utiliza todos los bits de control propios del Timer 0, para
llevar a cabo el mismo tipo de funcionamiento que el descrito para los otros modos; o sea, usa los bits
C/T, GATE, TR0 y /INT0. No obstante, para el contador formado por el registro TH0 sólo se dispone
del bit de control TR1, por lo que este contador tiene su funcionamiento restringido: sólo puede
ponerse en marcha y pararse mediante el bit TR1. El contador TH0, además, sólo puede contar pulsos
procedentes del reloj del microcontrolador.
A nivel de desbordamiento, el contador formado por TL0 afecta al bit TF0, mientras que el contador
formado por TH0 afecta al bit TF1, que en los otros modos pertenece al Timer 1.
En cuanto al Timer 1, para el modo 3, es obvio que no puede utilizar los bits TR1 y TF1 en su
funcionamiento usual, lo que significa que, cuando el Timer 1 se desborde, no se activará el bit TF1, y
que tampoco se podrá usar el bit TR1 para activar o para parar el Timer. La forma de arrancar y parar
el Timer 1 consiste en entrar y salir de su propio modo 3; es decir, entrando en el modo 3 se pone en
marcha el Timer 1, y saliendo del modo 3 se detiene el Timer 1. De todos modos, el Timer 1 puede ser
utilizado por el puerto serie como base para la generación de la velocidad de transmisión en baudios o
en cualquier otra aplicación en donde no se necesite producir una interrupción.
© Los autores, 2001; © Edicions UPC, 2001.
7 Temporizadores/contadores internos y watchdog 181
÷12
TL0 TF0T0
XTAL1
Interrupción0
1
TR0
GATE
INT0
C/T
TH0 TF1
TR1
1/12 Fosc
1/12 Fosc
Interrupción
Fig. 7.5 Esquema funcional en el modo 2 de funcionamiento
7.2.2 Timer 2
El Timer 2 es un contador de 16 bits que está formado a partir de los registros TL2 y TH2, de 8 bits
cada uno, conectados en cascada. Este Timer está presente en todas las versiones de la MCS-51 con
tres temporizadores internos, y puede trabajar hasta con cuatro modos distintos de funcionamiento:
modo autorrecarga, modo captura, modo Baud Rate y modo Clock-out. La forma de trabajar con el
Timer 2 se determina a partir de los registros T2MOD y T2CON, (tablas 7.2 y 7.3, respectivamente).
Estos registros permiten determinar el modo de funcionamiento del Timer 2, controlar su puesta en
marcha, programar su modo de operación (contador o temporizador) y detectar el desbordamiento.
En la tabla 7.4 se indican los cuatro modos de operación en los que puede funcionar el Timer 2,
dependiendo del estado de los bits RCLK, TCLK, CP/RL2 y T2OE.
Tabla 7.2 Registro T2MOD para el control del Timer 2
DCENT2OE--
(LSB)(MSB) Registro T2MOD
---- ------
Bit Comentario
-- Bit reservado.
T2OE Bit de habilitación del Timer 2.
En el modo Clock-out, T2OE conecta la salida de desbordamiento con el terminal T2.
DCEN Bit de sentido de cuenta.
DECEN=0 hace que el sentido de la cuenta sea ascendente. DCEN=1 hace que el
sentido pueda ser ascendente o descendente.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251182
Tabla 7.3 Registro T2CON para el control del Timer 2
CP/RL2C/T2TR2EXEN2TCLKRCLKTF2
(LSB)(MSB) Registro T2CON
EXF2
Bit Comentario
TF2 Bit de desbordamiento. TF2=1 al producirse un desbordamiento. Este bit no se
activa si RCLK=1 o TCLK=1. Debe borrarse por software.
EXF2 Bit de entrada externa. EXF2 se pone a 1 lógico al producirse un flanco
descendente en el terminal T2EX, siempre y cuando EXEN2 esté habilitado.
RCLK Bit de reloj en recepción. RCLK se pone a 1 lógico cuando se produce un
desbordamiento en el Timer 0.
TCLK Bit de reloj en transmisiónEXEN2 Bit de habilitación de entrada externa. En general, si EXEN2=1 permite la
activación de EXF2 con un flanco de descendente en T2EX. También realiza
funciones específicas en todos los modos de funcionamiento del Timer.
TR2 Bit de puesta en marcha y parada. TR2=1 pone en marcha el Timer 2. TR2=0
detiene el Timer 2.
C/T2 Bit de selección de temporizador/contador. Con C/T2=0 el Timer cuenta pulsos
de reloj (÷12). Con C/T2=1 el Timer cuenta pulsos de la entrada T2.
CP/RL2 Bit de captura/recarga. Con CP/RL2=1 se produce una captura al aplicar un
flanco negativo en T2EX, si EXEN2=1. Con CP/RL2=0 se produce una recarga al
aplicar un flanco negativo en T2EX, si EXEN2=1.
Si RCLK=1 o TCLK=1 se ignora CP/RL2 y se fuerza la recarga del Timer 2 al
producirse un desbordamiento en su valor.
Tabla 7.4 Modos de trabajo del Timer 2
Modo RCLK o TCLK CP/RL2 T2OEModo autorrecarga 0 0 0
Modo captura 0 1 0
Modo Baud Rate 1 X X
Modo Clock-out X 0 1
X= Estado indeterminado
7.2.2.1 Modo captura
El Timer 2 en el modo captura funciona como un temporizador o contador de 16 bits (figura 7.6).
Cuando se produce un desbordamiento, al pasar todos los bits de TL2 y TH2 de uno a cero lógico, se
activa el bit de rebasamiento TF2 del registro T2CON y se genera una interrupción automática.
En este modo, si el bit EXEN2 del registro T2CON se pone a 1 lógico y se produce un flanco de
bajada en el terminal T2EX del microcontrolador, el valor actual de los registros TH2 y TL2 se copia
en los registros RCAP2H y RCAP2L del área de SFR, hecho al que se le denomina captura. Al mismo
tiempo, el flanco de bajada producido hace que el bit EXF2 del registro T2CON se ponga a 1 lógico y
se genera una interrupción automática. Así pues, en este modo las fuentes de interrupción hacia la
CPU pueden ser por medio del bit de rebasamiento TF2, o bien por medio del bit EXF2. En este
último caso, se puede considerar al terminal T2EX como una nueva fuente de interrupción externa, al
igual que /INT0 y /INT1. En el caso de que produzca una interrupción, la rutina de RSI que se ejecuta
© Los autores, 2001; © Edicions UPC, 2001.
7 Temporizadores/contadores internos y watchdog 183
es la misma, tanto para el bit TF2, como para el bit EXF2, de forma que la rutina de RSI debe
comprobar cuál de las dos posibles interrupciones se ha activado.
La puesta en marcha y la parada del Timer 2 se realiza con el bit TR2 del registro T2CON. Con TR2 a
1 lógico se pone en marcha el Timer, que queda habilitado para contar pulsos; con TR2 a 0 lógico se
detiene el Timer.
÷12
TL2 TF2T2
XTAL1
Interrupción
0
1
TR2C/T2
TH2
RCAP2H RCAP2L
EXF2
EXEN2
T2EX
Fig. 7.6 Modo captura del Timer 2
7.2.2.2 Modo autorrecarga
El modo autorrecarga configura al Timer 2 como un temporizador o contador de 16 bits, con recarga
automática del valor contenido en los registros RCAP2L y RACP2H hacia los registros TL2 y TH2,
respectivamente (figuras 7.7 y 7.8). En este modo de funcionamiento, el Timer 2 puede operar de dos
formas diferentes: como un contador ascendente, o bien como un contador ascendente ó descendente,
según sea el valor del bit DCEN, Down counter enable bit del registro T2MOD. Para este último caso,
si DCEN está a 0 lógico el sentido de la cuenta es ascendente, y si DCEN está a 1 lógico el sentido de
la cuenta es descendente. Se debe tener en cuenta que el bit DCEN por defecto, tras un reset o al
iniciar el microcontrolador, se pone a 0 lógico.
a) Contador ascendente (DCEN=0)
Cuando DCEN se pone a 0 lógico, el Timer 2 opera como un contador ascendente de 16 bits (figura
7.7). En este caso, la recarga del Timer 2, es decir, la copia de los registros RCAP2H y RCAP2L en
los registros TH2 y TL2, respectivamente, se puede hacer por el desbordamiento del Timer, al
activarse el bit TF2, o bien, al producirse un flanco de bajada en el terminal T2EX, siempre y cuando
el estado del bit EXEN2 lo permita. En este último caso, el flanco de bajada también puede causar la
activación del bit EXF2 y provocar una interrupción.
El bit DCEN, tras un reset del microcontrolador, se pone a 0 lógico, así que, por defecto el Timer 2 en
el modo autorrecarga funciona como un contador ascendente de 16 bits.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251184
÷12
TH2 TL2
T2
XTAL1
Interrupción
TR2
RCAP2H RCAP2L
EXF2
TF2
T2EX
EXEN2
1
C/T2
0
Fig. 7.7 Modo autorrecarga del Timer 2 con DCEN=0
b) Contador ascendente/descendente (DCEN=1)
Cuando DCEN se pone a 1 lógico, el Timer 2 opera como un contador ascendente/descendente (figura
7.8), donde el sentido de la cuenta se determina mediante el estado lógico aplicado del terminal T2EX
del microcontrolador.
Cuando T2EX está a 1 lógico, el Timer 2 cuenta de forma ascendente, en cuyo caso, el Timer puede
llegar a desbordamiento; se activa entonces el bit TF2, se produce una recarga del valor de los
registros RCAP2H y RCAP2L hacia TH2 y TL2, respectivamente, y se genera una interrupción
automática siempre y cuando se haya habilitado de forma previa.
Cuando T2EX está a 0 lógico, el Timer 2 cuenta en sentido descendente, es decir, se decrementa su
valor con cada pulso de entrada. En este sentido de la cuenta, el Timer 2 también puede llegar a un
rebasamiento, que se produce cuando el contenido de los registros TH2 y TL2 llega a ser igual al valor
almacenado en los registros RCAP2H y RCAP2L, respectivamente. En este caso, se activa el bit TF2,
y se produce una petición de interrupción y una recarga del valor FFH en cada uno de los registros,
TH2 y TL2.
Al mismo tiempo, cuando se produce cualquiera de los dos tipos de desbordamiento mencionados, el
bit EXF2 complementa su valor; es decir, si EXF2 está a 1 lógico, cambia su valor a 0 lógico, y
viceversa. El bit EXF2 no genera petición de interrupción al microcontrolador, y se puede utilizar
como el bit 17 del contador, es decir, se contempla el contador como un Timer de 17 bits (donde
EXF2 es el bit 17).
© Los autores, 2001; © Edicions UPC, 2001.
7 Temporizadores/contadores internos y watchdog 185
TH2 TL2Interrupción
RCAP2H RCAP2L
EXF2
TF2
T2EX
FFH FFH
Valor de recarga para lacuenta hacia abajo
Valor de recarga para lacuenta hacia arriba
Complemento
Sentido de la cuenta1 = ascendente
0 = descendente
÷12
T2
XTAL1
TR2
1
C/T2
0
Fig. 7.8 Modo autorrecarga del Timer 2 con DCEN=0
7.2.2.3 Modo generador de baudios para el puerto serie (Baud Rate Generator Mode)
En este modo, el Timer 2 queda configurado como generador de baudios para fijar la velocidad de
transmisión del puerto de comunicación serie del microcontrolador. Este modo se selecciona al activar
los bits RCLK y/o TCLK de registro T2CON (tabla 7.4).
7.2.2.4 Modo Clock-out
En el modo Clock-out el Timer 2 genera una señal de reloj por el terminal T2 del microcontrolador de
frecuencia variable y simétrica (figura 7.9). El Timer 2 se incrementa con una frecuencia de valor
FOSC/2 (la mitad de la frecuencia de reloj del microcontrolador), hasta que sufre un desbordamiento, y
causa la recarga automática de los registros TH2 y TL2 con el valor contenido en los registros
RCAP2H y RCAP2L, respectivamente.
En este modo el desbordamiento del Timer no genera petición de interrupción, como ocurre con los
otros modos. La interrupción, sin embargo, sí que se genera al detectar un flanco de bajada en la
entrada T2EX, siempre y cuando el bit EXEN2 esté activado (figura 7.9).
La frecuencia de la señal de reloj generada se establece modificando el valor de los registros RCAP2H
y RCAP2L, según la siguiente ecuación:
∑ �L2RCAP,H2RCAP655354
F reloj_Frec OSC
θ(]
El rango de frecuencias que se puede generar está comprendido entre los 61Hz y los 4MHz, para una
frecuencia de reloj de 16MHz.
A modo de resumen, para que el Timer 2 trabaje en modo Clock-out, el bit T2OE del registro T2MOD
se debe poner a 1 lógico, el bit C/T2 del registro T2CON se debe poner a 0 lógico, y el bit TR2 debe
estar a 1 lógico.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251186
El Timer 2 se puede usar como generador de baudios para el puerto serie y, también de forma
simultánea, como generador de reloj, aunque las frecuencias generadas no se pueden determinar de
forma independiente, pues comparten los mismos registros de recarga.
÷12
TH2 TL2
T2
XTAL1
TR2
RCAP2H RCAP2L
EXF2T2EX
EXEN2
1
C/T2
0
÷2
T2OE
Interrupción
Fig. 7.9 Modo Clock-out para el Timer 2
7.2.3 Timer 0, 1 y 2 como contador
Los Timers 0, 1 y 2 pueden contar pulsos procedentes de los terminales T0, T1 y T2, respectivamente.
Para ello los bits T/C del registro TMOD, en el caso de los Timers 0 y 1, y el bit 2T/C para el
Timer 2, deben estar a 1 lógico. Los registros de los Timers se incrementan cada vez que se detecta, en
los terminales T0, T1 y T2, una transición de 1 a 0 lógico.
El estado lógico de cada uno de estos terminales de entrada se comprueba en la fase 2 del estado 5,
S5P2, de cada ciclo máquina. El valor de los registros de los Timers se incrementa cuando en un ciclo
máquina se detecta un 1 lógico y un 0 lógico en el siguiente ciclo. El nuevo valor de los registros se
muestra en el estado S3P1 del ciclo máquina siguiente al que se ha detectado la transición.
La máxima frecuencia del terminal de entrada es fclok/24, puesto que se tarda dos ciclos máquina en
reconocer una transición de 1 a 0 lógico. Para una frecuencia de reloj de 12MHz la máxima frecuencia
de terminal T0, T1 o T2 es de 500kHz.
Ejemplo 7.3 Refresco de cuatro dígitos de siete segmentos y teclado matricial
En el capítulo 5 se explicaba un ejemplo en el que se efectuaba la lectura de un teclado
matricial (apartado 5.10.4), y también un ejemplo de un contador de piezas para una máquina
de un proceso industrial (apartado 5.10.6). Estos dos ejemplos se pueden combinar en uno solo:
es decir, un contador de piezas con un teclado matricial que da capacidad de configuración al
usuario. La figura 7.10 muestra el circuito, en el cual se adjunta al contador de piezas un
teclado matricial de 8 teclas, formado por dos filas con cuatro teclas cada una.
© Los autores, 2001; © Edicions UPC, 2001.
7 Temporizadores/contadores internos y watchdog 187
87C51
P0.4
P0.5
P0.6
P0.1
P0.2
P0.3
P0.0
Ánodo común
R
R
a
b
dp
a
dp
4511(BCD-7seg)
A0
A1
A2
A3
Vcc
Reset
P1.2
/INT0
/EL
Centenas Decenas Unidades
Tr1 Tr2 Tr3
P0.7
Millares
Tr4Vcc
Vcc
Sensor
Cuenta
Sensor
Descuenta
P1.3
/INT1
P1.0
P1.1
Up Right Enter F1
Down Left Clear F2
P2.0
P2.7
7405
a
dp
Cátodo comúnVccR
R
Fig. 7.10 Circuito del contador de piezas con teclado matricial del ejemplo 7.3
Los cuatro dígitos de la figura 7.10 se deben encender de manera secuenciada para que el
número se distinga correctamente, tal y como se explicaba en el apartado 5.10.6. Al mismo
tiempo, la lectura del teclado matricial también precisa de una secuencia de escrutinio, en la
cual se comprueba, columna a columna, si se han pulsado las teclas asociadas. En
consecuencia, en el circuito de la figura 7.10, se desea utilizar la secuencia de refresco de los
cuatro dígitos de siete segmentos, para efectuar, a la vez, la secuencia de escrutinio de las
columnas del teclado matricial. Esta secuencia se llevará a cabo automáticamente mediante las
interrupciones del Timer 2.
Las filas del teclado matricial pueden activar la entrada de interrupción /INT1 mediante la
puerta AND de la figura 7.10. La secuencia situará un 0 lógico en la patilla P0.7, mientras las
patillas P0.4, P0.5 y P0.6 permanecen a 1 lógico, pondrá el transistor Tr4 en saturación y
encenderá el dígito correspondiente a las unidades. Si en este momento se pulsan las teclas F1 o
F2, se provocará una interrupción en /INT1. Transcurrido un tiempo determinado, el 0 lógico
se sitúa en el terminal P0.5, mientras los otros terminales están a 1 lógico; se pone, así, el
transistor Tr3 en saturación y se enciende el dígito de las decenas. De esta manera se procede
hasta que se pone un 0 lógico en la patilla P0.7 y se enciende el dígito correspondiente a los
millares. En este caso, la secuencia se repetirá con una frecuencia de 1 kHz, que establecerán
las interrupciones del Timer 2.
Cada vez que llega un pulso de “cuenta” se debe incrementar el valor del contador, y cuando se
activa el sensor de “descuenta” se debe decrementar el contador. Si el valor del contador
sobrepasa el valor 9999, éste no se incrementará, y si llega un pulso de “descuenta” cuando el
valor es de 0000, el contador no se decrementará. La tecla “reset” activa la interrupción /INT0
y pone a cero el valor del contador.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251188
Cuando se detecte que una tecla ha sido pulsada se mostrará un carácter determinado que
indique, en el dígito conectado al puerto P2, la tecla pulsada. Para la tecla “Up” se mostrará el
carácter “U”, para la tecla “Rigth” se mostrará el carácter “r”, para “Enter” el carácter “E”, para
“F1” el carácter “1.”, para “Down” el carácter “d”, para “Left” el carácter “L”, para “Clear” el
carácter “C” y para “F2” el carácter “2.”. El dígito conectado al puerto P2 mostrará siempre el
carácter correspondiente a la última tecla pulsada.
;**********************************************************************
; Refresco de 4 dígito de siete segmentos y de teclado matricial
;**********************************************************************
ORG 0H ; Vectorización de interrupciones
LJMP Inicio
ORG 03H
LJMP RSI_Int0
ORG 013H
LJMP RSI_Int1
ORG 02BH
LJMP RSI_Timer2
;**********************************************************************
; Rutina de Inicio
;**********************************************************************
Inicio: MOV P2, #0 ;Apaga el dígito conectado a P2
SETB IT0 ;Interrupción /INT0 activa por flanco descendente
SETB IT1 ;Interrupción /INT1 activa por flanco descendente
SETB PX1 ;Asigna prioridad alta a /INT1
SETB EX0 ;Habilita interrupción de /INT0
SETB EX1 ;Habilita interrupción de /INT1
SETB ET2 ;Habilita interrupción del Timer 2MOV T2CON, #0 ;Timer 2 funcionando en 16 bits con autorrecarga
MOV T2MOD, #0 ;Timer 2 (DCEN=0)
MOV RCAP2L, #05H ;Carga recarga para interrumpir cada 250 [s
MOV RCAP2H, #0FFH ; en RCAP2L y RCAP2H
MOV TL2, #05H
MOV TH2, #0FFH
SETB EA ;Habilita bit de interrupción general
SETB TR2 ;Pone en marcha el Timer 2;**********************************************************************
; Rutina Principal
;**********************************************************************
Principal: JNB P1.2, Conta ;Comprueba si se ha pulsado “Cuenta”JNB P1.3, Decre ;Comprueba si se ha pulsado “Descuenta”MOV P2, B ;Carga B en P2, para mostrar en dígito
SJMP Principal ;Bucle infinito
;**********************************************************************
; Rutina de servicio de /INT0
;**********************************************************************
RSI_Int0: MOV R0, #0 ;Borra unidades
MOV R1, #0 ;Borra decenas
MOV R2, #0 ;Borra centena.
MOV R3, #0 ;Borra millares
MOV P2, #0 ;Apaga dígito conectado a P2
MOV B, #0 ;Borra registro B
RETI
;**********************************************************************
; Rutina de servicio de /INT1
;**********************************************************************
RSI_Int1: JNB P1.0, Fila_0 ;¿Ha pulsado una tecla de la fila 0?
SJMP Fila_1 ;Si no, debe ser la fila 1
© Los autores, 2001; © Edicions UPC, 2001.
7 Temporizadores/contadores internos y watchdog 189
Fila_0: JNB P0.4, Tec_Up
JNB P0.5, Tec_Rigth
JNB P0.6, Tec_Enter
SJMP Tec_F1
Fila_1: JNB P0.4, Tec_Down
JNB P0.5, Tec_Left
JNB P0.6, Tec_Clear
SJMP Tec_F2
Tec_Up: MOV B, #0011 1110b ;Leds b, c, d, e y f encendidos, carácter “U”RETI
Tec_Rigth: MOV B, #0101 0000b ;Leds e y g encendidos, carácter “r”RETI
Tec_Enter: MOV B,#0111 1001b ;Leds a, d, e, f y g encendidos, carácter “E”RETI
Tec_F1: MOV B, #1000 0110b ;Leds b, c y dp encendidos, carácter “1.”RETI
Tec_Down: MOV B, #0101 1110b ;Leds b, c, d, e y g encendidos, carácter “d”RETI
Tec_Left: MOV B, #0011 1000b ;Leds d, e y f encendidos, carácter “L”RETI
Tec_Clear: MOV B, #0011 1001b ;Leds b, c, d, e y f encendidos, carácter “U”RETI
Tec_F2: MOV B, #1101 1011b ;Leds a, b, d, e, g y dp encendidos, carácter “2.”RETI
;**********************************************************************; Rutina de servicio del Timer 2;**********************************************************************
RSI_Timer2:ORL P0, #0F0H ;Apaga todos los dígitos
T_Uni: CJNE R5, #0, T_Dece
INC R5
SJMP T2_Uni
T_Dece: CJNE R5, #1, T_Cent
INC R5
SJMP T2_Dec
T_Cent: CJNE R5, #2, T_Millar
INC R5
SJMP T2_Cent
T_Millar: MOV R5, #0
SJMP T2_Millar
T2_Uni: MOV A, R0 ;Carga en A
ORL A, #0F0H ;Fuerza los 4 bits altos a 1 lógico
MOV P0, A ;Pone unidades en P0 (4 bits altos de R0 son cero)
CLR P0.7 ;Enciende dígito unidades. Tr4 en saturación
SJMP T2_Salir
T2_Dec: MOV A, R1 ;Carga en A
ORL A, #0F0H ;Fuerza los 4 bits altos a 1 lógico
MOV P0, A ;Pone decenas en P0 (4 bits altos de R0 son cero)
CLR P0.6 ;Enciende dígito decenas. Tr3 en saturación
SJMP T2_Salir
T2_Cent: MOV A, R2 ;Carga en A
ORL A, #0F0H ;Fuerza los 4 bits altos a 1 lógico
MOV P0, A ;Pone centenas en P0 (4 bits altos de R0 son cero)
CLR P0.5 ;Enciende dígito centenas. Tr2 en saturación
SJMP T2_Salir
T2_Millar: MOV A, R3 ;Carga en A
ORL A, #0F0H ;Fuerza los 4 bits altos a 1 lógico
MOV P0, A ;Pone millares en P0 (4 bits altos de R0 son cero)
CLR P0.4 ;Enciende dígito millares. Tr1 en saturación
T2_Salir: CLR TF2 ;Borra TF2
RETI
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251190
;**********************************************************************
;Rutina Conta
;**********************************************************************
Conta: CJNE R0, #9, Unidad ;Compara unidad
CJNE R1, #9, Decena ;Compara decena
CJNE R2, #9, Centena ;Compara centena
CJNE R3, #9, Millar ;Compara millar
SJMP Principal
Unidad: INC R0 ;Incrementa unidades
SJMP Principal
Decena: MOV R0, #0 ;Pone a 0 las unidades
INC R1 ;Incrementa decenas
SJMP Principal
Centena: MOV R0, #0 ;Pone a 0 unidades y decenas
MOV R1, #0
INC R2 ;Incrementa centenas
SJMP Principal
Millar: MOV R0, #0 ;Pone a 0 unidades, decenas y centenas
MOV R1, #0
MOV R2, #0
INC R3 ;Incrementa millares
SJMP Principal
;**********************************************************************
;Rutina Decre
;**********************************************************************
Decre: CJNE R0, #0, D_uni ;Compara unidad
CJNE R1, #0, D_dece ;Compara decena
CJNE R2, #0, D_cent ;Compara centena
CJNE R3, #0, D_mill ;Compara millar
LJMP Principal
D_uni: DEC R0 ;Decrementa unidad
LJMP Principal
D_dece: MOV R0, #9 ;Pone a 9 unidad
DEC R1 ;Decrementa decena
LJMP Principal
D_cent: MOV R0, #9 ;Pone a 9 unidad
MOV R1, #9 ;Pone a 9 decena
DEC R2 ;Decrementa centena
LJMP Principal
D_mill: MOV R0, #9 ;Pone a 9 unidad
MOV R1, #9 ;Pone a 9 decena
MOV R2, #9 ;Pone a 9 centena
DEC R3 ;Decrementa millar
LJMP Principal
En la rutina de “Inicio” el puerto P2 se pone a cero, debido a que inicialmente está a FFH (o
sea, todos sus terminales a 1 lógico); por tanto, debe ponerse a cero para que ninguno de los
leds del dígito esté encendido. En la rutina, las entradas /INT0 y /INT1 se configuran activas
por flanco descendente y se habilitan las interrupciones de /INT0, de /INT1 y del Timer 2. El
Timer 2 se configura para que funcione como un temporizador de 16 bits con autorrecarga;
para ello se colocan los bits RCLK, TCLK y CP/RL2, del registro T2CON, a 0 lógico. El Timercuenta pulsos internos del reloj del microcontrolador, por lo que el bit C/T2 del registro
T2CON se pone a 0 lógico. En el Timer 2 es necesario inhibir las interrupciones procedentes
del terminal T2EX (figura 7.7); por tanto, el bit EXEN2 también se pone a 0 lógico. Por último,
para que el temporizador funcione sólo en sentido ascendente, el bit DCEN del registro
T2MOD se pone a 0 lógico.
© Los autores, 2001; © Edicions UPC, 2001.
7 Temporizadores/contadores internos y watchdog 191
Para que la secuencia de refresco de los dígitos sea de 1kHz, el valor de recarga del Timer ha
de ser de FF05H, pues el período de la secuencia es de 1ms y, al haber cuatro dígitos, el tiempo
que debe permanecer encendido cada dígito es de 0.250 ms. FF05H es el resultado de restar
250 (o FAH) de 64k (o FFFFH).
El puerto P0 inicialmente también tiene todos sus terminales en estado 1 lógico, lo que no
supone ningún inconveniente, pues las puertas inversoras conectadas a los transistores Tr1, Tr2,
Tr3 y Tr4, aseguran que los transistores estén en corte y los dígitos permanezcan apagados.
La rutina de RSI del Timer 2 utiliza el registro R5 como contador en base 3, y determina el
dígito que se va a encender, según sea el valor de R5. Si vale cero se enciende el dígito
correspondiente a las unidades, si vale 1 se enciende el dígito de las decenas, si vale 2 se
enciende el dígito de las centenas y si vale 3 se enciende el dígito de los millares. El valor de
R5 se actualiza con la instrucción INC, de forma que cada vez que la rutina de RSI se ejecuta,
el registro se incrementa en una unidad, excepto cuando vale 3, que se pone a cero. El
contenido de los registros R0, R1, R2 o R3 se carga en el acumulador y se fuerzan sus cuatro
bits altos a 1 lógico mediante una instrucción ORL, de manera que todos los dígitos estén
apagados y se encienda el dígito que corresponda con la instrucción CLR.
La rutina principal está formada por un bucle infinito en el cual se comprueba el estado de los
sensores “cuenta” y “descuenta”, y donde se pone, en el dígito conectado a P2, el carácter de la
tecla pulsada en el teclado matricial.
7.3 Temporizadores para la MCS-251
Los microcontroladores de la familia MCS-251 disponen de 3 temporizadores/contadores de 16 bits,
denominados Timer 0, Timer 1 y Timer 2. Estos periféricos pueden ser configurados de forma
individual para operar en diversos modos de trabajo, bien como temporizadores o bien como
contadores.
Cuando operan como temporizadores, cada Timer se incrementa una vez cada cierto intervalo de
tiempo; cuando funcionan como contadores se incrementan cada vez que ocurre una transición
negativa en un pin concreto del microcontrolador.
Por otra parte, el microcontrolador incorpora un temporizador watchdog que permite generar un resetpor software, si se produce alguna anomalía en la ejecución del programa.
Cada Timer está compuesto por dos registros de 8 bits ubicados en el área de registros de función
específica, SFR. En concreto, el Timer 0 está formado por los registros TH0 y TL0, el Timer 1 por los
registros TH1 y TL1 y el Timer 2 por los registros TH2 y TL2 (tabla 7.1).
También se dispone de cuatro registros ubicados en el área SFR que permiten controlar y programar
adecuadamente las prestaciones de funcionamiento de los Timers. Los registros de programación
asociados al Timer 0 y al Timer 1 son: TMOD, registro de control de modo del temporizador/contador,
y TCON, registro de control del temporizador/contador.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251192
Los registros de programación para el Timer 2 son: T2MOD, registro de control de modo del Timer 2,
y T2CON, registro de control del Timer 2.
Tabla 7.5 Registros asociados a los Timers 0, 1 y 2 y al timer watchdog de la familia MCS-251
Mnemónico Descripción DirecciónTL0
TH0
Registros del Timer 0 S:08AH
S:08CH
TL1
TH1
Registros del Timer 1 S:08BH
S:08DH
TL2
TH2
Registros del Timer 2 S:0CCH
S:0CDH
TCON Registro de control de los Timers 0 y 1 S:088H
TMOD Registro de control de modo de los Timers 0 y 1 S:089H
T2CON Registro de control del Timer 2 S:0C8H
T2MOD Registro de control de modo del Timer 2 S:0C9H
RCAP2L
RCAP2H
Registros de recarga y captura del Timer 2 S:0CAH
S:0CBH
WDTRST Registro de Timer watchdog S:0A6H
7.4 Funcionamiento de los Timers
En la figura 7.11 está representado el esquema funcional básico de los Timers 0, 1 y 2. La parte central
del Timer está constituida por dos registros de 8 bits: THx y TLx (x = 0, 1 y 2), conectados en cascada
para formar un temporizador de 16 bits.
÷12
THx(8 bits)
TLx(8 bits)
TFx0
1
Tx
XTAL1
x = 0, 1 ó 2C/Tx
TRx
DesbordamientoPetición de
interrupción
Fig. 7.11 Estructura básica de los Timers 0, 1 y 2
Los Timers pueden ser programados para que trabajen como temporizador o como contador, mediante
el bit C/Tx, con x = 0, 1 ó 2, dependiendo del Timer de que se trate. En la tabla 7.6 se indica la
ubicación de cada uno de estos bits.
Tabla 7.6 Ubicación de los bits C/Tx
Bit UbicaciónC/T0 TMOD.2
C/T1 TMOD.6
C/T2 T2CON.1
© Los autores, 2001; © Edicions UPC, 2001.
7 Temporizadores/contadores internos y watchdog 193
7.4.1 Funcionamiento como temporizador
Cuando se pone el bit C/Tx a cero, el Timer correspondiente trabaja como temporizador. En este caso,
el Timer se incrementa en una unidad cada doce períodos de señal de reloj o, lo que es lo mismo, cada
6 estados. Las únicas excepciones a este comportamiento están en dos modos de funcionamiento del
Timer 2, Baud Rate y Clock-out, donde el incremento es cada dos períodos de reloj. Este modo de
operación se utiliza básicamente para medir intervalos temporales de forma relativamente fácil.
Ejemplo 7.4 Diseño de una rutina de retardo con el Timer 0
Se desea diseñar una rutina de retardo de 1 ms de duración utilizando el Timer 0, con una
frecuencia de reloj de 12MHz.
En este caso el Timer se incrementa en una unidad cada microsegundo, luego, para temporizar
1ms, el Timer 0 se deberá incrementar 1.000 veces. De esta forma, controlando el número de
incrementos que sufre el Timer se obtiene la rutina de retardo deseada.
;****************************************************************************
; RUTINA DE RETARDO
;****************************************************************************
ORG FF:0000H ;
. . .
CALL RETARDO ;
ORG FF:0100H ; La rutina de retardo empieza en la dirección FF:1000H
RETARDO: MOV R0,TH0 ; Se carga el valor del Timer en el registro WR0
MOV R1,TL0 ;
MOV WR2,#1000D ; Se carga en el registro WR2 el valor 1.000 decimal
CMP WR2,WR0 ; Se compara el contenido del Timer 0 con 1.000
JG RETARDO ; Si el contenido del Timer 0 es menor o igual a 1.000
; continuamos en la rutina de retardo
RET ; En el momento que el contenido del Timer 0 sea mayor a 1.000 se termina la rutina de retardo
7.4.2 Funcionamiento como contador
Para que un Timer funcione como contador se debe programar su bit C/Tx a 1 lógico. En este caso, el
Timer se incrementa en una unidad cada vez que se aplica un flanco de bajada en un pin determinado.
En la tabla 7.7 se especifica el pin asociado a cada Timer.
Tabla 7.7 Entradas externas de cuenta de los Timers 0, 1 y 2
Pin Tipo Descripción UbicaciónT0 I Entrada externa de reloj del Timer 0. P3.4
T1 I Entrada externa de reloj del Timer 1. P3.5
T2 I/O Entrada/salida externa de reloj del Timer 2. P1.0
La CPU comprueba el estado de las entradas externas de los Timers en cada ciclo de periférico1
, en
concreto en el segundo período del estado 5. Cuando la CPU detecta un 1 lógico en un ciclo y un cero
lógico en el siguiente ciclo, el Timer correspondiente se incrementa en una unidad (figura 7.12). El
1
Un ciclo de periférico equivale a 12 períodos de reloj agrupados en 6 estados, cada uno de ellos compuesto por dos
períodos.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251194
valor del Timer se actualiza en el primer período del estado 3 del ciclo de periférico que viene después
de detectar el flanco de bajada.
Ciclo de periférico Ciclo de periférico
1
0
S5P5 S5P5
T2, T1, T0
Fig. 7.12 Proceso de incremento de un Timer programado como contador
Teniendo en cuenta que un ciclo de periférico tiene una duración de 12 períodos de reloj, se necesitan,
como mínimo, 24 períodos de reloj para reconocer un flanco de bajada, por lo que la máxima
velocidad de cuenta es de fclock/24.
7.5 Timer 0 y Timer 1
Para controlar el funcionamiento de los Timers 0 y 1 se utilizan los registros TMOD y TCON (tablas
7.8 y 7.9). Los cuatro bits de menor peso del registro TMOD están asociados al Timer 0 y los cuatro
bits de mayor peso controlan el funcionamiento del Timer 1. Por otra parte, los bits 4 y 5 del registro
TCON están relacionados con el Timer 0, y los bits 6 y 7 con el Timer 1. Estos bits permiten
programar el modo de funcionamiento de los Timers, controlar su puesta en marcha, programar su
modo de operación, como contador o como temporizador, y detectar su desbordamiento.
7.5.1 Habilitación de los Timers 0 y 1
Para habilitar el funcionamiento de los Timers 0 o 1, se debe poner a 1 lógico el bit TR0 o el bit TR1,
respectivamente (tabla 7.9). Para que el Timers 0 o el Timer 1 funcionen se debe cumplir, además, una
segunda condición. En el caso del Timer 0 se debe cumplir que el bit GATE0 (tabla 7.8) esté a 0
lógico, o bien, que la entrada de interrupción externa cero /INT0, que está ubicada en el pin P3.2, estéa 1 lógico. Por otra parte, el Timer 1 funciona cuando el bit GATE1 (tabla 7.8) está a 0 lógico, o se ha
puesto a 1 lógico el pin correspondiente a la entrada de interrupción externa uno /INT1, que estáubicada en el pin P3.3. Esta segunda condición permite controlar el funcionamiento del Timermediante dos estrategias diferentes:
) Control por software: programando el valor lógico del bit GATEx (con x = 0 ó 1).
) Control por hardware: aplicando un nivel de tensión adecuando al pin /INTx (con x = 0 ó 1).
© Los autores, 2001; © Edicions UPC, 2001.
7 Temporizadores/contadores internos y watchdog 195
Tabla 7.8 Registro de control de modo, TMOD, de los Timers 0 y 1
TMOD Dirección: S:089H Valor de reset: 0000 0000b
b7 b6 b5 b4 b3 b2 b1 b0
GATE1 C/T1 M11 M01 GATE0 C/T0 M10 M00
Númerode bit
Nombredel bit
Función
7 GATE1 Bit GATE del Timer 1. Con GATE1 = 0, el Timer 1 se pone en marcha si TR1=1. Si
GATE1 = 1 y TR1 = 1, el Timer 1 se pone en marcha colocando un 1 lógico en el pin
/INT1 (P3.3).
6 C/T1 Selección de temporizador/contador del Timer 1. C/T1 = 0: el Timer 1 funciona como
temporizador. C/T1 = 1: el Timer 1 funciona como contador.
5, 4 M11, M01 Selector de modo del Timer 0.M11 M01
0 0 Modo 0: El Timer 0 funciona como un Timer de 13 bits.
0 1 Modo 1: El Timer 0 funciona como un Timer de 16 bits.
1 0 Modo 2: El Timer 0 funciona como un Timer de 8 bits (TL0) y se
recarga con el valor que hay en TH0 cuando sufre desbordamiento.
1 1 Modo 3: El Timer se para.
3 GATE0 Bit GATE del Timer 0Cuando GATE0 = 0, el Timer 1 se pone en marcha con TR0=1. Si GATE0 = 1 y TR0
= 1, el Timer 0 se pone en marcha colocando un 1 lógico en el pin /INT0 (P3.2).
2 C/T0 Selección de temporizador/contador del Timer 0. C/T0 = 0: el Timer 0 funciona como
temporizador. C/T0 = 0: el Timer 0 funciona como contador.
1, 0 M10, M00 Selector de modo del Timer 0.M10 M00
0 0 Modo 0: El Timer 0 funciona como un Timer de 13 bits.
0 1 Modo 1: El Timer 0 funciona como un Timer de 16 bits.
1 0 Modo 2: El Timer 0 funciona como un Timer de 8 bits (TL0) y se
recarga con el valor que hay en TH0 cuando sufre desbordamiento.
1 1 Modo 3: El Timer 0 funciona como dos Timers de 8 bits: TL0 y TH0.
Tabla 7.9 Registro de control, TCON, de los Timers 0 y 1
TCON Dirección: S:088H Valor de reset: 0000 0000b
b7 b6 b5 b4 b3 b2 b1 b0
TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
Númerode bit
Nombredel bit
Función
7 TF1 Flag de desbordamiento del Timer 1.Se pone a 1 cuando el Timer 1 sufre desbordamiento, o sea cuando pasa de la
combinación todo unos a la combinación todo ceros.
6 TR1 Flag de puesta en marcha del Timer 1. Cuando está a 1 lógico el Timer 1 está habilitado
para funcionar, en caso contrario esta parado.
5 TF0 Flag de desbordamiento del Timer 0. Se pone a 1 cuando el Timer 0 sufre
desbordamiento, o sea cuando pasa de la combinación todo unos a la combinación todo
ceros.
4 TR0 Flag de puesta en marcha del Timer 0. Cuando está a 1 lógico el Timer 0 está habilitado
para funcionar; en caso contrario esta parado.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251196
Dependiendo de las características de la aplicación que se quiera desarrollar, se debe realizar un
control del Timer por software, o bien por hardware.
Ejemplo 7.5 Control por hardware del Timer 0
En este ejemplo se trata de realizar con el microcontrolador 8XC251Sx una de las pruebas del
control de calidad de una producción de baterías de plomo-ácido para coches. Esta prueba
consiste en someter a la batería a una descarga de alta intensidad, al mismo tiempo que se mide
el tiempo durante el cual la batería es capaz de suministrar más de 400A manteniendo una
tensión superior a 12 voltios. Si este tiempo está entre los 20ms y los 30ms, la batería se
considera en buen estado; en caso contrario, se considera defectuosa.
Este tiempo se puede medir utilizando uno de los Timers del microcontrolador, por ejemplo el
Timer 0. Para realizar esta medida se monta el dispositivo mostrado en la figura 7.13 que
incorpora un sensor de corriente, un sensor de tensión y una puerta AND cuya salida se ha
conectado al pin P3.2, /INT0, para poder controlar mediante hardware el Timer 0. El sensor de
corriente se activa cuando la corriente es mayor o igual a 400A. Por otra parte, el sensor de
tensión se activa para una tensión mayor o igual a 12V. El nivel activo de ambos sensores es 1
lógico, de forma que, cuando los dos están activos, la salida de la puerta AND es 1 lógico.
La prueba del control de calidad exige medir el tiempo en que ambos detectores están activos
en una situación de descarga brusca. Esta aplicación requiere un control por hardware del
Timer 0, de forma que se incremente durante todo el tiempo que los dos sensores permanezcan
simultáneamente activos, o sea, durante todo el tiempo que la entrada P3.2 esté a 1 lógico.
P3.28XC251
- +
Detector de
tensión
Detector de
corriente
12V
RP3.2, INT0
Fig. 7.13 Dispositivo de control de calidad de la batería
Cuando alguno de los dos sensores pase a cero lógico, la salida de la puerta AND pasará a cero
y el Timer 0 detendrá su funcionamiento. A partir del número de incrementos que ha sufrido el
Timer 0 durante el tiempo que ha estado funcionando, se puede determinar si la batería es
válida, o si, por el contrario, está defectuosa.
En concreto, el intervalo temporal que se desea medir está comprendido entre 20ms y 30ms. Si,
por ejemplo, la frecuencia de la señal de reloj es de 12MHz, el temporizador se incrementa una
vez cada 1µs. Por tanto, 20ms se corresponden con 20.000 incrementos y 30ms se
corresponden con 30.000 incrementos. La batería pasará de forma positiva el control de calidad
siempre que el número de incrementos que haya sufrido el Timer 0, durante el tiempo en que
los dos sensores están activos, esté comprendido entre 20.000 y 30.000.
En la figura 7.14 está representado el diagrama de flujo del programa que controla el
© Los autores, 2001; © Edicions UPC, 2001.
7 Temporizadores/contadores internos y watchdog 197
funcionamiento de esta aplicación. Básicamente, el programa comienza con instrucciones que
inicializan a cero los registros del Timer 0, TH0 y TL0. A continuación se programan
adecuadamente los registros TMOD y TCON para que el Timer 0 trabaje en modo 1, como
temporizador, y controlado por hardware (figura 7.15).
El programa continúa con un par de instrucciones de salto condicional que tienen como
objetivo detectar el intervalo de activación simultánea de los dos sensores. Una vez que ha
finalizado la prueba, se compara el contenido de los registros del Timer 0, TH0 y TL0, con los
valores 20.000 y 30.000, para determinar si el estado de la batería es correcto.
INICIO
TIMER 0
TEMPORIZADOR
CONTROL HARDWARE
P3.2=0?
P3.2=1?
TIMER 0<20.000?
TIMER 0>30.000?
BATERÍACORRECTA
BATERÍADEFECTUOSA
NO
NO
SI
SI
SI
SI
NO
NO
Fig. 7.14 Diagrama de flujo de la aplicación
GATE1 C/T1 M11 M10 GATE0 C/T0 M10 M00
0 0 0 0 1 0 0 1
TMOD
Timer 0 programado como temporizador
Timer 0 programado en modo 1
Habilitación del funcionamiento delTimer 0 por hardware
TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
0 0 0 1 0 0 0 0
TCON
Habilitación del funcionamiento del Timer 0
Puesta a cero del flag de interrupción del Timer 0
Fig. 7.15 Programación y habilitación del Timer 0
;*******************************************************************************
; PROGRAMA DE CONTROL CALIDAD DE BATERÍAS
;*******************************************************************************
ORG FF:0000H ; El programa comienza en la dirección FF:0000H
MOV TH0,#00H ; Se inicializa los registros del Timer 0 a cero .
MOV TL0,#00H ;
MOV TMOD,#0AH ; Se programa el Timer 0 en modo 1 como temporizador y
MOV TCON,#10H ; controlado por hardware.
SALT1: JNB P3.2, SALT1 ; Se espera la activación de la salida de la puerta AND.
SALT2: JB P3.2, SALT2 ; Se espera durante el tiempo que está activa la salida de la puerta AND.
MOV R0,TH0 ;
MOV R1,TL0 ;
CMP WR0,#20000D ; Se compara el contenido del Timer 0 con 20.000.
JC DEFEC ; Salta si es menor que 20.000.
CMP WR0,#30000D ; Salta si el contenido del Timer es mayor que 30.000.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251198
JLE CORRECTA ; Salta si es menor o igual que 30.000.
DEFEC: SETB P0.0 ; Si la batería está defectuosa se pone a 1 el pin P0.0.
CORRECTA: NOP
Por otra parte, un ejemplo clásico de control del Timer mediante programa es la realización de rutinas
de retardo como la explicada en el apartado 7.4.1.
7.5.2 Desbordamiento de los Timers 0 y 1
Los Timers 0 y 1 se incrementan desde el valor inicial que se ha cargado en sus registros, THx y TLx,
hasta que se produce un desbordamiento de los mismos. El desbordamiento tiene lugar cuando el
contenido de los registros THx y TLx llega al valor máximo posible, combinación todo unos, y se
incrementa una vez más. El desbordamiento de un Timer se detecta fácilmente mediante los flags de
desbordamiento del registro TCON, TF0 para el Timer 0 y TF1 para el Timer 1 (tabla 7.9).
Detectar el desbordamiento de los Timers es muy importante para que la aplicación funcione
correctamente.
Ejemplo 7.6 Temporización de 0.1s mediante el Timer 1
En este ejemplo se debe temporizar 0.1s utilizando el Timer 1 de un microcontrolador
8XC251Sx que funciona con un reloj de 12MHz. Con esta frecuencia de reloj el Timer 1 se
incrementa en una unidad cada microsegundo. Por tanto, para temporizar 0.1s el Timer 1 debe
incrementarse 100.000 veces. Si el Timer se programa en modo 1 y se ha cargado con el valor
inicial cero, sufre desbordamiento cuando se incrementa 216
= 65.536 veces. Una vez sufrido
desbordamiento, el Timer 1 se debe incrementar 34.464 veces más para llegar a contabilizar los
100.000 incrementos necesarios.
En la figura 7.16 está representado el diagrama de flujo del programa que controla esta
temporización. El programa comienza con instrucciones que inicializan a cero los registros del
Timer 1, TH1 y TL1. A continuación se programa adecuadamente el registro TMOD para que
el Timer 1 trabaje en modo 1, como temporizador y controlado por software (figura 7.17).
También se programa el registro TCON para poner a cero el flag de desbordamiento del Timer1, TF1, y para habilitar su funcionamiento.
Una vez puesto en marcha el Timer, se debe detectar el momento en el que éste sufre
desbordamiento. Esto se consigue fácilmente mediante una instrucción de salto condicional: la
condición de salto debe ser el valor del flag de desbordamiento TF1. Mientras este flag está a
cero el programa ejecuta el salto de forma continuada. Cuando el Timer 1 rebasa, el flag se
pone a 1, la condición de salto ya no se cumple y por lo tanto no se efectúa dicho salto.
Llegados a este punto el Timer 1 deberá incrementarse 34.464 veces más para contabilizar los
100.000 incrementos correspondientes a un intervalo de 0.1s.
Las siguientes instrucciones del programa colocan a cero el flag de desbordamiento, detienen el
funcionamiento del Timer 1 e inicializan su contenido con el valor adecuado para que al
incrementarse 34.464 veces llegue a desbordamiento. Este valor es 216 – 34.464 =31.072d =
7960H.
© Los autores, 2001; © Edicions UPC, 2001.
7 Temporizadores/contadores internos y watchdog 199
INICIO
TIMER 1TEMPORIZADOR
CONTROL SOFTWARE
INICIALIZAR EL
TIMER 1 CON 31.072d
DETENER
EL TIMER 1
TF1=0?
TF1=0?SI
SI
NO
NO
Fig. 7.16 Diagrama de flujo de la aplicación
Habilitación del funcionamiento del Timer 1
Puesta a cero del flag de interrupción del Timer 1
GATE1 C/T1 M11 M10 GATE0 C/T0 M10 M00
0 0 0 1 0 0 0 0
TMOD
Timer 1 programado como temporizador
Timer 1 programado en modo 1
Habilitación del funcionamiento del
Timer 1 por software
TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
0 1 0 0 0 0 0 0
TCON
Fig. 7.17 Programación y configuración del Timer 1
;******************************************************************************
; PROGRAMA DE TEMPORIZACIÓN DE 0.1s
;******************************************************************************
ORG FF:0000H ; El programa comienza en la dirección FF:0000H
MOV TH1,#00H ; Se inicializa los registros del Timer 1 a cero.
MOV TL1,#00H ;
MOV TMOD,#10H ; Se programa el Timer 1 en modo 1 como temporizador y
MOV TCON,#40H ; controlado por hardware.
SALT1: JNB TF1, SALT1 ; Se espera la activación del flag de desbordamiento TF1.
CLR TF1 ; Se pone a cero el flag TF1.
MOV TH0,#79H ; Se inicializan los registros del Timer 1 con el valor
MOV TL0,#60H ; adecuado para que rebase al incrementarse 34.464 veces.
SALT1: JNB TF1, SALT1 ; Se espera la activación del flag de desbordamiento TF1.
NOP ; Ha finalizado la temporización de 0.1s.
7.5.3 Modos de funcionamiento de los Timers 0 y 1
Los Timers 0 y 1 pueden funcionar en cuatro modos de trabajo distintos, que se seleccionan
programando adecuadamente los bits M00 y M10 para el Timer 0, y los bits M01 y M11 para el Timer1 del registro TCON (tabla 7.8).
a) Modo 0: Temporizador/contador de 13 bits
En este modo de trabajo los Timers 0 y 1 funcionan como un contador de 13 bits, implementado
mediante los 8 bits del registro THx y los 5 bits de menor peso del registro TLx. En este modo de
trabajo se ignoran los tres bits de mayor peso del registro TLx.
En la figura 7.18 se presenta el esquema de funcionamiento de los Timers 0 y 1 para los modos de
funcionamiento 0 y 1.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251200
÷12
THx(8 bits)
TLx(8 bits)
TFx0
1
Tx
XTAL1
C/Tx
DesbordamientoPetición de
interrupción
TRx
GATEx
INTx
Modo 0: Temporizador/contador de 13 bits
Modo 1: Temporizador/contador de 16 bits
x = 0 ó 1
Fig. 7.18 Modos 0 y 1 para los Timers 0 y 1
Ejemplo 7.7 Generación de una señal cuadrada
En este ejemplo se trata de generar una señal cuadrada utilizando el Timer 0 programado en
modo cero, con una frecuencia de la señal de reloj de 12MHz. La función del Timer, en esta
aplicación, será la de controlar la duración del período de la onda cuadrada. La idea es
inicializar el Timer con el valor cero, ponerlo en funcionamiento y, cada vez que rebase,
complementar el valor lógico del pin P0.0, de forma que, con los sucesivos desbordamientos
del Timer 0, se genere la onda cuadrada en el pin P0.0 (figura 7.19).
P0.0
8XC251
Fig. 7.19 Esquema del generador de onda cuadrada
Si la frecuencia de reloj es de 12MHz, el Timer 0 se incrementa una vez cada microsegundo,
por lo que tarda en rebasar 213
µs, o sea, 8.192ms. Esto significa que cada semiperiodo de la
onda cuadrada tiene una duración aproximada de 8.2ms.
En la figura 7.20 está representado el diagrama de flujo del programa que controla la
generación de la onda cuadrada. El programa comienza con instrucciones que inicializan a cero
los registros del Timer 0, TH0 y TL0. Seguidamente se programa adecuadamente el registro
TMOD para que el Timer 0 trabaje en modo 0, como temporizador y controlado por software.
También se programa el registro TCON para poner a cero el flag de desbordamiento del Timer0, TF0, y para habilitar el funcionamiento del Timer 0.
Una vez puesto en marcha el Timer, se debe detectar el momento en el que sufre
desbordamiento. Esto se consigue fácilmente mediante una instrucción de salto condicional,
donde la condición de salto es el valor del flag de desbordamiento TF0. Mientras este flag estéa cero, el programa ejecuta el salto de forma continuada. Cuando el Timer 0 rebasa, el flag se
pone a 1, la condición de salto ya no se cumple y, por tanto, el programa continúa su ejecución
por la siguiente instrucción.
© Los autores, 2001; © Edicions UPC, 2001.
7 Temporizadores/contadores internos y watchdog 201
INICIO
TIMER 0
TEMPORIZADOR
CONTROL SOFTWARE
TF0=0?
COMPLEMENTAR
P0.0
NO
SI
PONER A CERO TF0
Fig. 7.20 Diagrama de flujo de la aplicación
A continuación se debe complementar el pin P0.0, poner a cero el flag de desbordamiento y
saltar de nuevo al inicio para repetir la secuencia de forma indefinida.
;******************************************************************************
; PROGRAMA DE TEMPORIZACIÓN DE GENERACIÓN DE ONDA CUADRADA
;******************************************************************************
ORG FF:0000H ; El programa comienza en la dirección FF:0000H
MOV TH0,#00H ; Se inicializa los registros del Timer 0 a cero .
MOV TL0,#00H ;
MOV TMOD,#00H ; Se programa el Timer 0 en modo 0 como temporizador y
MOV TCON,#10H ; controlado por software.
SALT1: JNB TF0, SALT1 ; Se espera la activación del flag de desbordamiento TF0.
CPL P0.0 ; Se complementa el pin P0.0
CLR TF0 ; Se pone a cero el flag TF0.
JMP SALT1 ; Se salta al inicio para repetir la secuencia.
b) Modo 1: Temporizador/contador de 16 bits
Cuando los Timers 0 o 1 están programados en modo 1, actúan como un Timer de 16 bits
implementado por los registros THx y TLx.
Ejemplo 7.8 Generador de onda cuadrada con el Timer 1 controlado por interrupciones
En el ejemplo 7.7 se utiliza el Timer 0 controlado mediante la técnica de testeo para temporizar
el período de la onda generada. En este ejemplo se va a desarrollar la misma aplicación pero
con el Timer 1 controlado mediante interrupciones, para poder comparar qué diferencias, a
nivel de diseño del programa, supone el control de periféricos por interrupciones con respecto
al control por testeo. El programa deberá constar de dos partes:
) Un programa principal que incluya las instrucciones necesarias para habilitar las fuentes
de interrupción utilizadas en la aplicación, así como las instrucciones de programación
e inicialización de los periféricos.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251202
) Una rutina de servicio a la interrupción del Timer 1 que deberá incluir las instrucciones
necesarias para atender a este Timer 1 cuando interrumpa.
El programa principal deberá incluir una instrucción que habilite la fuente de interrupción del
Timer 1, poniendo a 1 lógico los bits adecuados del registro IE0 (figura 7.21). Asimismo, se
incluirányen instrucciones para programar el Timer 1 como temporizador en modo 1, para
inicializar los registros TH1 y TL1 a cero, y para habilitar su funcionamiento (figura 7.22).
EA EC ET2 ES ET1 EX1 ET0 EX0
1 0 0 0 1 0 0 0
IE0
Habilita las interrupciones
que están a 1Habilita la interrupción del Timer 1
Fig. 7.21 Habilitación de la interrupción del Timer 1
GATE1 C/T1 M11 M10 GATE0 C/T0 M10 M00
0 0 0 1 0 0 0 0
TMOD
Timer 1 programado como temporizador
Timer 1 programado en modo 1
Habilitación del funcionamiento del
Timer 1 por programa
TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
0 1 0 0 0 0 0 0
TCON
Habilitación del funcionamiento del Timer 1
Puesta a cero del flag de interrupción del Timer 1
Fig. 7.22 Programación y habilitación del Timer 1
A continuación se presenta el flujograma (figura 7.23) y el listado del programa principal.
;************************************************************************
; PROGRAMA PRINCIPAL
;************************************************************************
ORG FF:0000H ; El programa principal se ubica a partir de
JMP PRINCIP ; la dirección FF:0100H.
ORG FF:0100H
PRINCIP: MOV IE0,#88H ; Habilitación de la fuente de interrupción Timer 1.
MOV TMOD,#20H ; Configuración del Timer 1 en modo 1 como
; temporizador.
MOV TH1,#00H ; Inicialización del Timer 1 a cero lógico.
MOV TL1,#00H
MOV TCON,#40H ; Habilitación del funcionamiento del Timer 1 y
; borrado del flag de interrupción.
PROGRAMA
PRINCIPAL
PROGRAMACIÓN
Y PUESTA EN
MARCHA DEL
TIMER 1
HABILITACIÓN
INTERRUPCIÓN
TIMER 1
Fig. 7.23 Flujograma delprograma principal
Una vez habilitado el Timer 1, éste se incrementa automáticamente cada 12 períodos de reloj.
Cuando el Timer sufre rebasamiento, se activa el flag de interrupción TF1 y el
microcontrolador salta a ejecutar la rutina de servicio de la interrupción que está ubicada a
partir de la dirección FF:001BH. En la rutina se debe incluir una instrucción que complemente
el pin P0.0. Seguidamente se presenta el listado de la RSI del Timer 1.
© Los autores, 2001; © Edicions UPC, 2001.
7 Temporizadores/contadores internos y watchdog 203
;*******************************************************************************
; RUTINA DE SERVICIO A LA INTERRUPCION TIMER 1
;*******************************************************************************
ORG FF:001BH
CPL P0.0 ; Se complementa el pin P0.0.
RETI ; Retorno de RSI.
Para mejorar el diseño del ejemplo 7.8 se puede añadir un pulsador externo que controle el
funcionamiento del generador, de forma que cuando se active el pulsador, el microcontrolador
detenga la generación de la onda cuadrada, inhiba la interrupción del Timer 1 y ponga a cero el
pin P0.0. Si se aprieta de nuevo el pulsador, el microcontrolador vuelve a generar la onda
cuadrada. Si el pulsador se conecta a la entrada de interrupción /INT0, permite controlar su
activación mediante el mecanismo de interrupción (figura 7.24).
8XC251
P0.0
Tp
+5V
10 k≅
4.[F
INT01k≅
Fig. 7.24 Esquema eléctrico de la conexión del pulsador al microcontrolador 8XC251
Para poder llevar a cabo esta mejora del diseño es necesario modificar algunas instrucciones
del programa principal y diseñar una rutina de atención a la interrupción /INT0.
En concreto, se debe modificar el contenido del registro IE0 para habilitar la fuente de
interrupción /INT0, y el registro TCON para programar la interrupción /INT0 por flanco de
bajada (figura 7.25).
EA EC ET2 ES ET1 EX1 ET0 EX0
1 0 0 0 1 0 0 1
IE0
Habilita las interrupciones
que están a 1
Habilita la interrupción del Timer 1
Habilita la interrupción /INT0
TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
0 1 0 0 0 0 0 1
TCON
Habilitación del funcionamiento del Timer 1
Puesta a cero del flag de interrupción del Timer 1
Programación de /INT0 por flanco de bajada
---
0
0
0
0
0
0
0
IPH0
---
0
0
0
0
0
0
1
IPL0
b7
b6
b5
b4
b3
b2
b1
b0
Bits de prioridad de la interrupción PCA
Bits de prioridad de la interrupción Timer 2
Bits de prioridad de la interrupción puerto serie
Bits de prioridad de la interrupción Timer 1
Bits de prioridad de la interrupción INT1
Bits de prioridad de la interrupción Timer 0
Bits de prioridad de la interrupción INT0
Fig. 7.25 Habilitación de /INT0 y programación de los niveles de prioridad
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251204
Por otra parte, se puede considerar que la fuente de interrupción /INT0 es más prioritaria que la
interrupción Timer 1, puesto que su activación habilita o inhibe la interrupción del Timer 1. Por
este motivo, se programa la interrupción /INT0 con un nivel de prioridad mayor que la
interrupción Timer 1. Por ejemplo, se puede programar la interrupción /INT0 con el nivel 1 y la
interrupción Timer 1 con el nivel 0.
Teniendo en cuenta estas modificaciones, el listado del programa principal quedará de la
siguiente manera:
;*******************************************************************************
; PROGRAMA PRINCIPAL
;*******************************************************************************
ORG FF:0000H
JMP PRINCIP
ORG FF:0100H ; El programa principal se ubica a partir de la dirección FF:0100H.
PRINCIP: MOV IE0,#89H ; Habilitación de las fuentes de interrupción Timer 1 y /INT0.
MOV TMOD,#20H ; Programación del Timer 1 en modo 1 como temporizador.
MOV TH0,#00H ; Inicialización del Timer 1 a cero lógico.
MOV TL0,#00H
MOV TCON,#41H ; Habilitación del Timer 1 y borrado del flag de interrupción
; Programación de la interrupción /INT0 activa por flanco de bajada.
MOV IPH0,#00H ; Se programa la interrupción /INT0 con nivel 1 y la
MOV IPL0,#01H ; interrupción Timer 1 con nivel 0.
Por otra parte, la RSI de la interrupción /INT0 debe incluir instrucciones que controlen la
habilitación de la interrupción del Timer 1 y pongan a cero el pin P0.0 si es necesario. En la
figura 7.26 está representado el flujograma de la RSI de la interrupción /INT0.
;********************************************************
; RUTINA DE SERVICIO A LA INTERRUPCION INT0
;********************************************************
ORG FF:0003H
JNB ET1,HAB ; Si la int. del Timer 1 está inhibida se habilita.
CLR ET1 ; Si la int. del Timer 1 está activa se inhibe.
CLR P0.0 ; Se pone a cero el pin P0.0.
RETI ; Retorno de RSI.
HAB: SETB ET1 ; Se habilita la interrupción Timer 1.
RETI ; Retorno de RSI.
RSI /INT0
¿INTERRUPCIÓN
TIMER 1 ACTIVA?
SE INHIBE INT.
TIMER 1
NO
SI
SE PONE A CERO
P0.0
SE HABILITA INT.
TIMER 1
RETI
Fig. 7.26 Flujograma de la RSI de lainterrupción /INT0
Ejemplo 7.9 Control del índice de acidez (pH) del agua de un depósito
Se plantea a continuación, como ejemplo ilustrativo de la utilización del sistema de
interrupciones del microcontrolador 8XC251Sx, un caso práctico de control de una planta de
tratamiento de aguas residuales. El objetivo de este ejemplo es mostrar el funcionamiento de las
interrupciones en lo que respecta a la habilitación, los niveles de prioridad, el manejo de los
flags de interrupción, etc.
© Los autores, 2001; © Edicions UPC, 2001.
7 Temporizadores/contadores internos y watchdog 205
La planta que se debe controlar dispone de un sistema que neutraliza la acidez de las aguas
residuales provenientes de una planta de fabricación de papel (figura 7.27). El sistema posee un
depósito donde se mezcla el agua residual con la cantidad adecuada del componente
neutralizador, cuya función es disminuir la acidez del agua, de forma que el agua de salida del
depósito posea un pH superior a 5.5.
El sistema de control incorpora dos sensores activos a nivel alto:
) Un detector de rebosamiento, S1, que se activa cuando el agua contenida en el depósito
supera la altura máxima permitida.
) Un detector de pH, M, que se activa cuando el pH del agua es inferior a 5.5.
El sistema de control dispone además de dos actuadores, V1 y V2, activos a nivel alto, cuya
función es realizar la apertura de dos válvulas. Cuando se activa el actuador V1 se abre la
válvula que permite la entrada de las aguas residuales al depósito. Cuando se activa el actuador
V2 se abre la válvula que permite el vertido de neutralizador en el depósito. Por último, existen
dos indicadores luminosos, A1 y A2, activos a nivel alto, cuya función es la de monitorizar la
apertura de las válvulas V1 y V2.
Entrada
de aguas
residuales
Descarga
Neutralizador
Medidor
pH
S1
Sistemade control
V1V2
M
A1
A2
Fig. 7.27 Esquema de la planta
En la figura 7.28 está representado el esquema eléctrico en que se detalla la conexión del µC
8XC251Sx con los diferentes sensores y actuadores que intervienen en esta aplicación. Cabe
destacar que los sensores S1 y M están conectados a las entradas de interrupción /INT0 e
/INT1 a través de sendas puertas inversoras, debido a que las interrupciones externas se
activan a nivel bajo, mientras que estos sensores son activos a nivel alto.
A2
A1
8XC251
P1.2
P1.3
S1 V1P1.0INT0
M V2P1.1INT1
Fig. 7.28 Conexión sensores y actuadores con el µC 8XC251Sx
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251206
La estrategia que debe llevar a cabo el sistema de control para gestionar el funcionamiento de
la planta de tratamiento de aguas residuales se puede resumir en dos puntos:
) La válvula V1 debe permanecer abierta hasta que el sensor S1 se active, en cuyo caso se
cerrará durante treinta segundos. Si una vez pasado este tiempo el sensor S1 sigue
activo, se repetirá la operación de cierre de la válvula V1. Mientras V1 esté abierta, el
indicador A1 permanecerá encendido; en caso contrario el indicador parpadeará.
) La válvula V2 debe estar cerrada hasta que se active el sensor M, en cuyo caso se abrirádurante cinco segundos. Una vez transcurrido ese tiempo, si el sensor M continúa activo,
se repetirá la operación de apertura de la válvula V2. El indicador A2 se activa cuando
la válvula V2 está abierta y parpadea cuando está cerrada.
Los recursos utilizados para resolver esta aplicación son cuatro:
) La interrupción externa /INT0, que se encarga de detectar la activación del sensor S1.
La interrupción se activa por nivel para que pueda ser atendida por la CPU mientras el
sensor S1 se encuentre a uno lógico.
) La interrupción externa /INT1, cuya función es detectar la activación del medidor de
pH. Esta interrupción también se programa por nivel por el mismo motivo que la /INT0.
) El Timer 0, que se encarga de temporizar el intervalo de 30s, tiempo que debe
permanecer abierta la válvula V1 cuando se active S1.
) El Timer 1, que se encarga de temporizar los 5s de apertura de la válvula V2.
) El programa está compuesto de una rutina principal y de cuatro rutinas de atención a la
interrupción, una para cada fuente de interrupción utilizada en la aplicación.
La función del programa principal será básicamente la de habilitar y programar los niveles de
prioridad de las diversas fuentes de interrupción utilizadas, así como la de ejecutar la secuencia
de parpadeo de los indicadores luminosos A1 y A2.
Para habilitar las cuatro fuentes de interrupción utilizadas, se ponen a uno lógico los bits
correspondientes del registro habilitador de interrupciones IE0: EX0, ET0, EX1 y ET1. Esto se
consigue cargando en el registro IE0 el valor 8FH (10001111b).
Por otra parte, se deben poner a uno lógico los bits IT0 e IT1 del registro TCON, con el
objetivo de que las interrupciones externas /INT0 e /INT1 se activen por nivel. Esto se
consigue almacenando en el registro TCON el valor 0AH (0000 1010b).
A continuación se debe establecer la prioridad de las interrupciones. En principio se adjudica a
las interrupciones /INT0 y Timer 0 una prioridad mayor que a las interrupciones /INT1 y Timer1, dado que la situación de rebasamiento requiere una actuación más urgente que la superación
del nivel de pH. Las fuentes /INT0 y Timer 0 se programan con nivel de prioridad tres,
mientras que las fuentes de interrupción /INT1 y Timer 1 se programan con un nivel de
prioridad menor, por ejemplo con nivel cero. Por tanto, los registros de nivel de prioridad IPH0
e IPL0 quedan: IPH0 = 03H y IPL0 = 03H.
Por último, se debe poner el bit INTR del byte de configuración CONFIG1 a uno lógico. De
esta forma, cuando la CPU ejecute una interrupción, se cargarán en la pila, automáticamente,
© Los autores, 2001; © Edicions UPC, 2001.
7 Temporizadores/contadores internos y watchdog 207
los tres bytes del contador de programa, PC, y el registro de estado, PSW1.
En cuanto a la rutina de retardo, que se utiliza para temporizar el parpadeo de los indicadores
luminosos, estará compuesta de dos bucles anidados basados en decrementar los registros R0 y
R1. Modificando el valor de los registros R0 y R1 se puede variar el tiempo de ejecución de la
rutina y, por tanto, la frecuencia de parpadeo. Para calcular el tiempo de retardo hay que
determinar el número de veces que se ejecuta cada instrucción, así como el tiempo que tarda en
ejecutarse cada una de ellas.
En la figura 7.29 se muestran los flujogramas correspondientes al programa principal y a la
rutina de retardo. En la figura 7.30 se muestran los flujogramas de las rutinas de atención a las
interrupciones /INT0 y Timer 0. Las tareas que debe realizar la rutina de atención a la
interrupción /INT0 son:
) Cerrar la válvula V1.
) Inicializar el Timer 0 para que temporice 30s.
) Inhibir la interrupción /INT0 para impedir que se ejecute de forma repetida la RSI de la
/INT0 mientras el sensor S1 se encuentra activo y no ha finalizado la temporización de 30s.
Si consideramos que la frecuencia de reloj es de 1.2MHz, se puede determinar, mediante un
cálculo sencillo, que el Timer 0 debe rebasar varias veces para temporizar 30s.
PRINCIPAL
INICIALIZAR:
IE0 = 8FH
TCON = 0AH
IPH0 = 03H
IPL0 = 03H
P1.2 = 1
P1.3 = 1
RETARDO
P1.2 = 0
P1.3 = 0
RETARDO
RETARDO
R0 = 10H
DECREMENTA R1
R1 = FFH
R0 = 0?
R1 = 0?
DECREMENTA R0
RET
NO
SI
SI
NO
Fig. 7.29 Flujograma del programa principal y de la rutina de retardo
En la RSI del Timer 0 se debe contar el número de rebasamientos que sufre este temporizador. Cuando
el Timer 0 rebase un número de veces equivalente a 30s se abrirá la válvula V1, se detendrá el
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251208
funcionamiento del Timer 0 y se habilitará de nuevo la interrupción /INT0, de forma que si el sensor
S1 continúa activo se repetirá de nuevo la secuencia de cierre de V1.
INT0
INICIALIZAR T0
CERRAR VÁLVULA V1
RETI
ACTIVACIÓN T0
INHIBIR INT0
T0
BORRAR IE0
ABRIR VÁLVULA V2
HABILITAR INT0
PARAR T0
RETI
T = 30s?NO
SI
Fig. 7.30 Flujogramas de las rutinas de servicio a las interrupciones /INT0 y Timer 0
Las rutinas de atención a las interrupciones /INT1 y Timer 1 tienen funciones similares a las
interrupciones /INT0 y Timer 0. En la figura 7.31 se presentan los flujogramas
correspondientes a ambas rutinas.
INT1
INICIALIZAR T1
ABRIR VÁLVULA V2
RETI
ACTIVACIÓN T1
INHIBIR INT1
T1
BORRAR IE1
CERRAR VÁLVULA V2
HABILITAR INT1
PARAR T1
RETI
T = 5s?NO
SI
Fig. 7.31 Flujogramas de las rutinas de servicio a las interrupciones /INT1 y Timer 1.
A continuación se presentan el listado del programa principal y de la rutina de retardo.
;****************************************************************************
; VECTORIZACION INTERRUPCIONES
;****************************************************************************
ORG FF:0003H ; Vector de interrupción de /INT0.
JMP RSI_INT0
ORG FF:000BH ; Vector de interrupción del Timer 0.
JMP RSI_T0
© Los autores, 2001; © Edicions UPC, 2001.
7 Temporizadores/contadores internos y watchdog 209
ORG FF:0013H ; Vector de interrupción de /INT1.
JMP RSI_INT1
ORG FF:001BH ; Vector de interrupción del Timer 1.
JMP RSI_T1
;******************************************************************************
; PROGRAMA PRINCIPAL
;******************************************************************************
ORG FF:0000H
JMP PRINCIP
ORG FF:0100H
; Programación del nivel de prioridad de las interrupciones externas 0 y 1
PRINCIP: MOV IE0,#8FH ; Habilitación de las interrupciones
MOV TCON,#0AH ; Se programa /INT0 e /INT1 por nivel
MOV IPL0,#03H ; Programación de los niveles de prioridad
MOV IPH0,#03H
SETB INTR ; Cuando la CPU vectorice una interrupción cargará en la pila
; los 3 bytes del PC y el registro de estado PSW1.
;Secuencia de parpadeo de los indicadores luminosos A1 y A2
SALTO0: SETB P1.2
SETB P1.3
CALL RETARDO
CLR P1.2
CLR P1.3
CALL RETARDO
JMP SALTO0
;************************************************************************
; RUTINA DE RETARDO
;*************************************************************************
ORG FF:0200H
RETARDO: MOV R0,#10H ; R0 = 10H.
SALT2: MOV R1,#FFH ; R1 = FFH.
SALT1: DJNZ R1,SALT1 ; Decrementa R1 y si es distinto de 0 salta a SALT1.
DJNZ R0,SALT2 ; Decrementa R2 y si es distinto de 0 salta a SALT2.
RET
;************************************************************************
; RUTINA DE SERVICIO A LA INTERRUPCION INT0
;*************************************************************************
ORG FF:0300H
RSI_INT0: CLR P1.0 ; Se cierra la válvula V1.
SETB TMOD.0 ; Se programa el Timer 0 en modo 1.
MOV TH0,#3CH ; Se inicializa el Timer 0 para temporizar 0.5 s.
MOV TL0,#AFH ;
MOV R3,#00H ; El registro R3 contará los rebasamientos del Timer 0.
SETB TR0 ; Puesta en marcha del Timer 0.
CLR EX0 ; Se inhibe la interrupción /INT0.
RETI
Cálculo del valor inicial del Timer 0
Para temporizar los treinta segundos se inicia el Timer 0 para que tarde 0.5s en rebasar, de
forma que se deben contabilizar 60 rebasamientos en la RSI del Timer 0 para abrir de nuevo la
válvula V1. Para temporizar 0.5s, con una frecuencia de reloj de 1.2MHz, el Timer 0 debe
incrementarse 50.000 veces (C350H); luego se ha de cargar dicho Timer con la combinación
resultante de restar a FFFFH el valor C350H:
FFFFH - C350H = 3CAFH
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251210
;*****************************************************************************
; RUTINA DE SERVICIO A LA INTERRUPCION TIMER 0
;*****************************************************************************
ORG FF:0400H
RSI_T0: INC R3 ; Se incrementa el contador de rebasamientos.
CMP R3,59d ; Se compara el número de rebasamientos con 59.
JNC SIGUE ; Si el número de rebasamientos es menor o igual que 59 continúa temporizando.
CLR TR0 ; En caso contrario se detiene el Timer 0 y
CLR P1.0 ; se abre la válvula V1.
SETB EX0 ; Se habilita de nuevo la interrupción /INT0.
CLR IE0 ; Se borra el flag de la interrupción /INT0.
SIGUE: RETI ; Retorno al programa principal.
;****************************************************************************
; RUTINA DE SERVICIO A LA INTERRUPCION INT1
;*****************************************************************************
ORG FF:0500H
RSI_INT1: SETB P1.1 ; Se abre la válvula V2.
SETB TMOD.4 ; Se programa el Timer 1 en modo 1.
MOV TH1,#3CH ; Se inicializa el Timer 1 para temporizar 0.5 s.
MOV TL1,#AFH
MOV R4,#00H ; El registro R4 contará los rebasamientos del Timer 1.
SETB TR1 ; Puesta en marcha del Timer 1.
CLR EX1 ; Se inhibe la interrupción /INT1
RETI
;**************************************************************************
; RUTINA DE SERVICIO A LA INTERRUPCION TIMER 1
;**************************************************************************
ORG FF:0600H
RSI_T1: INC R4 ; Se incrementa el contador de rebasamientos
CMP R4,09d ; Se compara el número de rebasamientos con 9
JNC SIGUE1 ; Si el número de rebasamientos es menor o igual que 9
; continua temporizando.
CLR TR1 ; Se detiene el Timer 1SETB P1.1 ; Se abre la válvula V2
SETB EX1 ; Se habilita la interrupción /INT1
CLR IE1 ; Se borra el flag de la interrupción /INT1
SIGUE1: RETI ; Retorno al programa principal
c) Modo 2: Temporizador/contador de 8 bits con autorrecarga
El modo 2 configura a los Timers 0 o 1 como temporizador/contador de 8 bits, implementado con el
registro TLx (con x = 0 ó 1).
÷12
THx(8 bits)
TLx(8 bits)
TFx0
1
Tx
XTAL1
C/Tx
Desbordamiento
Petición de
interrupción
TRx
GATEx
INTx x = 0 ó 1
Recarga
Fig. 7.32 Modo 2 de autorrecarga de los Timers 0 y 1
© Los autores, 2001; © Edicions UPC, 2001.
7 Temporizadores/contadores internos y watchdog 211
En este modo de trabajo cuando el Timer sufre desbordamiento se activa el flag TFx y
automáticamente se carga el contenido del registro THx en el registro TLx, de forma que el Timercomienza a contar a partir del valor cargado en el registro THx. El proceso de recarga no modifica el
contenido del registro THx. En la figura 7.32 está representado el esquema del Timer 0 o de Timer 1funcionando en modo 2.
Ejemplo 7.10 Contador módulo 12 con el Timer 1
Este ejemplo consiste en la realización de un contador módulo 12 con el Timer 1 programado
en modo 2. El contador cuenta desde el valor inicial 3 hasta el 15. En la figura 7.33 se muestra
el esquema general de un contador módulo 12, que incluye las salidas de cuenta, una entrada de
reloj y una entrada de habilitación del contador.
Contador de 4 bits
Habilitador
del contador
Entrada
de cuenta
Salida de
cuenta: 3-15
Señal de reloj
Señal de
habilitación
Fig. 7.33 Esquema general de un contador módulo 12
En la figura 7.34 se muestra cómo se puede realizar este contador utilizando el
microcontrolador 8XC251Sx. Basta con conectar la señal de reloj a la entrada de cuenta del
Timer 1 (pin P3.5), conectan la señal de habilitación del contador a la entrada de control por
hardware del Timer 1 (pin P3.3); las salidas del contador pueden tomarse de los cuatro bits de
menor peso del puerto 0.
8XC251
Entrada
de cuenta
Salida de
cuenta: 3-15
P0.0
P0.1
P0.2
P0.3
+5V
T1
INT1
8XC251
Entrada
de cuenta
Salida de
cuenta: 3-15
P0.0
P0.1
P0.2
P0.3
+5V
T1
INT1
Fig. 7.34 Contador módulo 12 con el microcontrolador 8XC251Sx
El programa comienza configurando el Timer 1 como contador en modo 2 y controlado por
hardware. Seguidamente se deben inicializar los registros TH1 y TL1 con el valor adecuado
para esta aplicación. A continuación se vuelca el contenido del registro TL0 sobre el puerto P0
de forma continuada, con el objetivo de visualizar sobre este puerto los incrementos que sufre
el contador a medida que va recibiendo los pulsos aplicados en la entrada de cuenta.
El valor elegido para inicializar los registros del Timer 1 es el F3H, de forma que al volcar este
contenido sobre el puerto P0, en los cuatro bits de menor peso aparece el valor 3H (valor inicial
de cuenta). A medida que el Timer 1 se incrementa se puede seguir el incremento a través del
puerto P0. Cuando se llega al valor FH (15d) y se recibe un nuevo pulso se produce
desbordamiento y el registro TL1 se carga de nuevo con F3H (figura 7.35).
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251212
F3H F4H F5H FFHFEH TL0
P0:3=3H P0:3=4H P0:3=5H P0:3=EH P0:3=FH P0
Desbordamiento
Fig. 7.35 Evolución del contador módulo 12
En la figura 7.36 está representado el diagrama de flujo del programa que controla el
funcionamiento del contador módulo 12.
INICIO
TIMER 1
CONTADOR
CONTROL HARDWARE
TH1 = TL1 = F3H
CARGAR TL1 EN P0
Fig. 7.36 Diagrama de flujo del contador módulo 12
Seguidamente se presenta el listado del programa.
;****************************************************************************************
; PROGRAMA DE TEMPORIZACIÓN DE GENERACIÓN DE ONDA CUADRADA
;****************************************************************************************
ORG FF:0000H ; El programa comienza en la dirección FF:0000H
MOV TH1,#F3H ; Se inicializa los registros del Timer 0 a cero .
MOV TL1,#F3H
MOV TMOD,#E0H ; Timer 0 en modo 0 como temporizador y controlado por software.
SETB TR1
SALT1: MOV P0,TL1 ; Se copia el contenido del registro TL0 en el puerto cero.
JMP SALT1
d) Modo 3: Timer 0: dos temporizadores/contadores de 8 bits; Timer 1: parado
Cuando el Timer 0 se programa en modo 3, los registros TL0 y TH0 operan como dos temporizadores
independientes de 8 bits (figura 7.37). Este modo se utiliza en aquellas aplicaciones que requieren un
temporizador o contador adicional.
En este modo de funcionamiento, el registro TL0 utiliza todos los bits de control del Timer 0 para su
funcionamiento normal: C/T0, GATE0, TR0 y TF0.
En cambio, las prestaciones de funcionamiento del registro TH0 se ven muy reducidas debido a que
los únicos flags que controlan su funcionamiento son el TR1 y el TF1. El flag TR1 permite habilitar el
funcionamiento del registro TH0 y el flag TF1 se activa cuando este registro sufre desbordamiento.
© Los autores, 2001; © Edicions UPC, 2001.
7 Temporizadores/contadores internos y watchdog 213
Por otra parte, el registro TH0 sólo puede operar como temporizador y no como contador (figura
7.37).
TH0
(8 bits)1/12 Fosc TF1
DesbordamientoPetición de
interrupción
TR1
÷12
TL0
(8 bits)TF0
0
1
T0
XTAL1
C/T0
DesbordamientoPetición de
interrupción
TR0
GATE0
INT0
1/12 Fosc
Fig. 7.37 Modo 3 del Timer 0, dos Timers de 8 bits
Por este motivo, cuando el Timer 0 está programado en modo 3, el Timer 1 no puede utilizar los flagsTR1 y TF1 para su normal funcionamiento. Esto significa que cuando el Timer 1 desborde no se
activará el flag TF1; igualmente, no se puede utilizar el bit TR1 para habilitar el funcionamiento de
este Timer.
Por otra parte, cuando el Timer 1 se programa en modo 3 se detiene su funcionamiento. Este modo
puede utilizarse para detener el Timer 1 cuando el Timer 0 esté programado en modo 3 y el bit TR1 no
esté disponible.
7.6 Timer 2
El Timer 2 es un temporizador/contador de 16 bits implementado mediante dos registros de 8 bits
conectados en cascada: TH2 y TL2. Para controlar su funcionamiento se dispone de 2 registros:
T2MOD y T2CON (tablas 7.10 y 7.11).
Tabla 7.10 Registro de control de modo del Timer 2
T2MOD Dirección: S:0C9H Valor de reset: XXXX XX00b
b7 b6 b5 b4 b3 b2 b1 b0
-- -- -- -- -- -- T2OE DCEN
Númerode bit
Nombredel bit
Función
7:2 -- Reservado.
Estos bits están reservados para futuras aplicaciones y no se pueden utilizar.
1 T2OE Bit de habilitación del Timer 2.
Cuando el Timer 2 trabaja en modo Clock-out, este bit conecta la salida de reloj con el
pin T2.
0 DCEN Bit de cuenta atrás.
Este bit configura al Timer 2 como un contador ascendente o descendente.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251214
Tabla 7.11 Registro de control del Timer 2
T2CON Dirección: S:0C8H Valor de reset: 0000 0000b
b7 b6 b5 b4 b3 b2 b1 b0
TF2 EXF2 RCLK TCLK EXEN2 TR2 C/T2 CP/RL2
Númerode bit
Nombredel bit
Función
7 TF2 Flag de desbordamiento del Timer 2.
Este flag se pone a 1 cuando el Timer 2 sufre desbordamiento, o sea, cuando pasa de
la combinación todo unos a la combinación todo ceros. Este bit no se activa si
RCLK=1 o TCLK=1.
6 EXF2 Flag externo del Timer 2.
Este flag se pone a 1 cuando se produce un flanco negativo en el pin T2EX con el flagEXEN2=1.
5 RCLK Bit de reloj en recepción.
Este flag se pone a 1 cuando el Timer 0 sufre desbordamiento, o sea cuando pasa de la
combinación todo unos a la combinación todo ceros.
4 TCLK Bit de reloj en transmisión.
3 EXEN2 Bit de habilitación externa del Timer 2.
Cuando este bit está a 1 y se produce una transición negativa en el pin T2EX, se
produce una recarga o captura, a menos que el Timer 2 se utilice como generador de
Baud Rate del puerto de comunicación serie. Si el bit EXEN2 está a cero se ignoran
las transiciones en el pin T2EX.
2 TR2 Bit de puesta en marcha del Timer 2.
Cuando está a 1 lógico el Timer 2 está habilitado para funcionar; en caso contrario
esta parado.
1 C/T2 Bit de selección de contador/temporizador:
C/T2 = 0: el Timer 2 funciona como temporizador.
C/T2 = 1: el Timer 2 funciona como contador.
0 CP/RL2 Bit de captura/recarga.
Cuando este bit está a 1 se produce una captura al aplicar un flanco negativo en la
entrada T2EX con EXEN2=1. Cuando este bit está a cero se produce un recarga al
aplicar un flanco negativo en la entrada T2EX con EXEN2=1. Si RCLK=1 o
TCLK=1, se ignora el bit CP/RL2 y se fuerza la recarga del Timer 2 cuando sufre
desbordamiento.
Los bits de los registros T2MOD y T2CON permiten programar el modo de funcionamiento de los
Timers, controlar su puesta en marcha, programar su modo de operación (contador o temporizador) y
detectar el desbordamiento. En la tabla 7.12 se indican los cuatro modos de operación en los que
puede funcionar el Timer 2.
Tabla 7.12 Modos de operación del Timer 2
Modo RCLK o TCLK CP/RL2 T2OEModo autorrecarga 0 0 0
Modo captura 0 1 0
Modo Baud Rate 1 X X
Clock-out programable X 0 1
© Los autores, 2001; © Edicions UPC, 2001.
7 Temporizadores/contadores internos y watchdog 215
7.6.1 Modo captura
En el modo captura, el Timer 2 funciona como un temporizador o contador de 16 bits (figura 7.38).
Cuando el Timer 2 sufre desbordamiento se activa el flag TF2, con lo que se genera una petición de
interrupción al microcontrolador.
Si el bit EXEN2 está a 1 lógico, un flanco de bajada en el pin T2EX captura el valor actual de los
registros del Timer 2, TH2 y TL2, en los registros RCAP2H y RCAP2L respectivamente. Al mismo
tiempo, el flanco de bajada en el pin T2EX produce la activación del bit EXF2, lo cual genera una
petición de interrupción al microcontrolador.
÷12 0
1
T2
XTAL1
C/T2
Desbordamiento
Petición de
interrupción
T2EX
TR2
RCAP2H RCAP2L
EXF2
TF2
EXEN2
TH2
(8 bits)
TL2
(8 bits)
Fig. 7.38 Modo captura del Timer 2
7.6.2 Modo autorrecarga
El modo autorrecarga configura al Timer 2 como un temporizador o contador de 16 bits con recarga
automática. En este modo de funcionamiento el Timer opera como un contador ascendente o
ascendente/descendente, según sea el valor del bit DCEN (Down Counter Enable Bit). Cuando se
realiza un reset del microcontrolador, el bit DCEN se pone automáticamente a cero, de forma que si se
programa el Timer 2 en modo autorrecarga, éste funcionará como contador ascendente.
a) Contador ascendente (DCEN=0)
Cuando DCEN=0, el Timer 2 opera como un contador ascendente (figura 7.39). El valor del bit
EXEN2 permite dos posibilidades de funcionamiento dentro de este modo. Si EXEN2=0, el Timer 2cuenta hacia arriba hasta el valor FFFFH y activa el flag TF2 cuando sufre desbordamiento. Con el
desbordamiento se recarga, en los registros del Timer 2, TH2 y TL2, el valor contenido en los
registros de recarga/captura, RCAP2H y RCAP2L, respectivamente.
Si EXEN2=1, los registros del Timer se recargan por dos motivos distintos: cuando se produce
desbordamiento y cuando se aplica un flanco de bajada en el pin T2EX. El flanco de bajada en T2EX
también activa el bit EXF2, que realiza una petición de interrupción al microcontrolador.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251216
÷12TH2
(8 bits)
TL2
(8 bits)
0
1
T2
XTAL1
C/T2
Desbordamiento
Petición de
interrupción
TR2
RCAP2H RCAP2L
EXF2
TF2
T2EX
EXEN2
Recarga
Fig. 7.39 Modo autorecarga del Timer 2 con DCEN = 0
b) Contador ascendente/descendente (DCEN=1)
Cuando DCEN=1, el Timer 2 opera como un contador ascendente/descendente (figura 7.40). La
dirección de cuenta se puede controlar mediante el valor lógico aplicado al pin T2EX. Cuando este pin
está a nivel alto, 1 lógico, el Timer 2 cuenta de forma ascendente. En este caso, cuando el Timer llega
a FFFFH y se incrementa otra vez, se produce desbordamiento y se activa el flag TF2, lo que genera
una petición de interrupción al microcontrolador. El desbordamiento también produce la recarga
automática de los registros del Timer 2, TH2 y TL2, con el valor almacenado en los registros de
recarga/captura, RCAP2H y RCAP2L, respectivamente.
÷12
TH2
(8 bits)
TL2
(8 bits)T2
XTAL1
C/T2
Desbordamiento
Petición de
interrupción
TR2
RCAP2H RCAP2L
EXF2
TF2
T2EX
0
1
FFH FFH
Valor de recarga para
cuenta hacia abajo
Valor de recarga para
cuenta hacia arriba
Complemento
Dirección de cuenta
1 = ascendente
0 = descendente
Fig. 7.40 Timer 2: modo autorecarga con DCEN = 1
© Los autores, 2001; © Edicions UPC, 2001.
7 Temporizadores/contadores internos y watchdog 217
Cuando T2EX vale 0 lógico, el Timer 2 cuenta hacia abajo. El desbordamiento del Timer 2 ocurre, en
este caso, cuando el contenido de los registros TH2 y TL2 es igual al valor cargado en los registros
RCAP2H y RCAP2L, respectivamente. El desbordamiento provoca la activación del flag TF2 y
recarga los registros del Timer con el valor FFFFH.
Por otra parte, cuando el Timer sufre desbordamiento, en la cuenta ascendente o descendente, el bit
EXF2 cambia de valor. En este modo de funcionamiento el bit EXF2 no genera ninguna petición de
interrupción al microcontrolador y puede utilizarse como bit 17 del Timer 2.
7.6.3 Modo de generador de baudios (Baud Rate Generator Mode)
En este modo el Timer 2 queda configurado como generador de baudios para fijar la velocidad de
transmisión del puerto de comunicación serie. Para seleccionar este modo es necesario activar los bits
RCLK y/o TCLK de registro T2CON (tabla 7.12).
7.6.4 Modo Clock-out
En este modo de funcionamiento, el Timer 2 funciona como un reloj de frecuencia variable con un
ciclo de trabajo del 50% (figura 7.41) y se incrementa con una frecuencia FOSC/2 hasta que sufre
desbordamiento; entonces se recarga automáticamente los registros TH2 y TL2 con el valor contenido
en los registros RCAP2H y RCAP2L, respectivamente. En el modo Clock-out, el desbordamiento del
Timer 2 no genera petición de interrupción.
÷2TH2
(8 bits)
TL2
(8 bits)
0
1
T2
XTAL1
C/T2
Desbordamiento
Petición de
interrupción
T2EX
TR2
RCAP2H RCAP2L
EXF2
EXEN2
÷2
T2OE
Fig. 7.41 Timer 2: modo generación de reloj
La frecuencia de la señal de reloj que se genera con este modo se puede programar adecuadamente
fijando el valor de los registros RCAP2H y RCAP2L:
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251218
∑ �Frecuencia reloj
F
RCAP H RCAP LOSC
]( θ4 65535 2 2,
(7.1)
Si el microcontrolador funciona con un reloj de 16MHz, se podrá programar un rango de frecuencias
de 61Hz a 4MHz. La señal de reloj, generada en este modo, está disponible en el pin T2.
Para programar el Timer 2 en el modo Clock-out se debe poner a 1 lógico el bit T2OE del registro
T2MOD. También se debe poner a cero lógico el bit C/T2, para que el Timer 2 funcione como
temporizador y para habilitar al mismo tiempo el pin T2 como salida de reloj. Los registros RCAP2H
y RCAP2L se inicializan adecuadamente, según la expresión 7.1, para fijar la frecuencia de la señal
generada. Por otra parte, los registros TH2 y TL2 se cargan con el mismo valor, o con otro distinto,
dependiendo de la aplicación. Finalmente, se activa el bit TR2 para poner en marcha el Timer 2.
Es posible utilizar el Timer 2 como generador de baudios y como generador de reloj de forma
simultánea.
Ejemplo 7.11 Control de llenado de un garaje
Esta aplicación consiste en contar el número de coches que hay en un garaje mediante el
microcontrolador 8XC251Sx. La cuenta está controlada por el Timer 2, que debe trabajar como
contador bidireccional: incrementándose cada vez que entra un coche y decrementándose
cuando sale. Por tanto, se debe programar el Timer 2 en modo autorrecarga con DCEN=1. Para
detectar la presencia de vehículos y su dirección, entrada o salida, se dispone de tres sensores
de presencia, S1, S2 y S3, activos a nivel alto (figura 7.42).
G ARA
JE
Sistema
de control
S1S2
S3
Fig. 7.42 Esquema de la entrada al garaje
Para realizar esta aplicación se conecta el sensor S3 a la entrada de cuenta del Timer 2: T2.
Cada vez que un coche entra o sale del garaje, el sensor S3 genera un pulso en esta entrada, de
forma que el Timer se incrementa o decrementa, dependiendo del valor lógico aplicado en el
pin T2EX (figura 7.43).
Los sensores S1 y S2 controlan la dirección de cuenta a través de la báscula RS conectada a la
entrada T2EX. Si el vehículo entra en el garaje se activa, en primer lugar, el sensor S2 y, por
tanto, se aplica un pulso a la entrada S de la báscula RS. Como resultado, la salida Q de la
báscula se pone a 1, T2EX=1, lo que permite al Timer 2 incrementarse cuando el vehículo
genera un pulso en la entrada T2. Igualmente, si el vehículo sale del garaje, se activa el sensor
S1 que pone a cero la báscula RS, y el Timer 2 se decrementa al activarse el sensor S3.
© Los autores, 2001; © Edicions UPC, 2001.
7 Temporizadores/contadores internos y watchdog 219
8XC251
S1
S2
R
S
Q T2EX
S3 T2
R S Q
0 0 Q
0 1 1
1 0 0
1 1 X
+
Fig. 7.43 Conexión de los sensores al [C 8XC251Sx y tabla de funcionamiento de una báscula RS
En esta aplicación, el Timer 2 debe trabajar como contador bidireccional; se deberá programar,
por tanto, en modo autorrecarga con DCEN=1. Para ello se deben inicializar los siguientes bits:
RCLK = TCLK = 0, CP/RL2 = 0, T2OE = 0 y el bit DCEN = 1. Los bits RCLK, TCLK y
CP/RL2 están ubicados en el registro T2CON, mientras que el bit T2OE y DCEN están
ubicados en el registro T2MOD. Seguidamente se deben inicializar los registros del Timer 2 a
cero, y ponerlo en marcha.
;********************************************************************************
; PROGRAMA DE CONTROL DEL GARAJE
;********************************************************************************
ORG FF:0000H ; El programa está almacenado a partir de la dirección de memoria FF:0000H
CLR RCLK ; Se pone a cero el bit RCLK del registro T2CON.
CLR TCLK ; Se pone a cero el bit TCLK del registro T2CON.
CLR CP/RL2 ; Se pone a cero el bit CP/RL2 del registro T2CON.
CLR T2OE ; Se pone a cero el bit T2OE del registro T2MOD.
SETB C/T2 ; Se programa el Timer 2 como contador.
SETB DCEN ; El Timer 2 trabaja como contador Up/Down
SETB TR2 ; Se habilita el funcionamiento del Timer 2.
MOV TL2,#00H ; Se inicializa el contador a cero.
MOV TH2,#00H ;
7.7 Timer watchdog
Los microcontroladores de la serie 8XC251Sx contienen un Timer watchdog, WDT, que genera un
reset automático del microcontrolador si pasa un cierto tiempo sin recargar el contenido de este Timer.
La utilidad del WDT es la de posibilitar el reset del microcontrolador en casos de funcionamiento
inadecuado del programa.
7.7.1 Descripción de funcionamiento
El WDT es un Timer de 14 bits que se incrementa automáticamente cada ciclo de periférico, o sea,
cada 12 períodos de reloj, y su funcionamiento está controlado por el registro WDTRST, ubicado en la
dirección S:0A6H del área de registros de función específica.
El Timer WDT se gestiona básicamente a través de dos operaciones:
) Un reset del microcontrolador borra e inhibe el funcionamiento del Timer WDT.
) Escribiendo una secuencia específica de dos bytes en el registro WDTRST se borra y habilita
el Timer WDT.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251220
Una vez habilitado para funcionar, el Timer WDT se incrementa cada 12 períodos de señal de reloj y,
si no se borra, sufre desbordamiento cuando llega a la combinación 3FFFH+1; entonces genera,
además, un reset al microcontrolador 8XC251Sx.
Si, por ejemplo, la frecuencia de reloj del microcontrolador es de 16MHz, el ciclo de periférico es de
750ns y el Timer WDT desborda en 750ns x 16384 = 12,288ms.
7.7.2 Utilización del Timer WDT
Se puede utilizar el Timer WDT para que, en caso de funcionamiento erróneo del programa, se realice
un reset del microcontrolador. La idea es que desde el programa de la aplicación se borre
periódicamente el Timer WDT, antes de que desborde. Si el programa entra en secuencia de
funcionamiento errónea, el Timer WDT no se borrará y cuando sufra desbordamiento se efectuará el
reset el Timer WDT quedará automáticamente inhibido.
Para borrar el Timer WDT se debe escribir en el registro WDTRST una secuencia de dos bytes: 1EH y
1EH. Esta operación habilita y borra el Timer WDT, de forma que comienza de nuevo a incrementarse
a partir del valor inicial 0000H. A lo largo del programa se deberá escribir la secuencia de dos bytes
para borrar y habilitar de nuevo el Timer WDT antes de que desborde.
7.7.3 Timer WDT durante el modo Idle
El Timer WDT continúa su funcionamiento mientras el microcontrolador está en modo de operación
Idle. Esto significa que el usuario debe controlar el funcionamiento de este Timer durante el modo
Idle. Por ejemplo, se puede utilizar el Timer 0 programado convenientemente para desbordar antes que
el Timer WDT. Cuando el Timer 0 desborda, genera una interrupción al microcontrolador. En la rutina
de interrupción del Timer 0 se pone a cero el Timer WDT, se inicializa el Timer 0 y se coloca de
nuevo el microcontrolador en modo Idle.
7.7.4 Timer WDT durante Power Down
Cuando el microcontrolador está en el modo Power Down se paran todos los relojes del
microcontrolador. Esto detiene automáticamente el funcionamiento del Timer WDT y mantiene su
valor de cuenta. Cuando el microcontrolador sale de este modo de funcionamiento, mediante la
activación de las entradas /INT0 o /INT1, el Timer WDT continúa su cuenta por donde la dejó. Para
asegurarse de que el Timer WDT no llega a desbordamiento en un tiempo corto después de que el
microcontrolador sale del modo Power Down, se debe inicializar justo antes de entrar en dicho modo
de funcionamiento.
© Los autores, 2001; © Edicions UPC, 2001.
8 Memoria externa 221
8 Memoria externa
8.1 Introducción
Muchas aplicaciones realizadas con microcontroladores de las familias MCS-51 y MCS-251 se pueden
resolver con versiones que disponen de memoria interna de programa, por lo que no es necesario, en
estas versiones, el uso de circuito integrados de memoria adicionales. Las versiones con memoria
interna EPROM son útiles para elaborar prototipos, pero más aún son viables las versiones con
memoria EPROM del tipo OTP, One-Time Programmable, y las versiones con memoria EEPROM
tipo flash de Atmel, ya que las primeras carecen de la ventana de cuarzo para borrar las memorias
EPROM, lo que simplifica su encapsulado y reduce considerablemente su coste, y las segundas
disponen de una tecnología que permite un coste reducido.
De toda maneras, según la aplicación, puede ser necesario ampliar la capacidad de memoria de los
microcontroladores, o emplear versiones que carezcan de memoria interna; en estos casos resulta
imprescindible usar circuitos integrados de memoria externa para resolver la aplicación. Entonces, es
importante conocer correctamente la forma de conectar los circuitos de memoria al microcontrolador y
saber determinar si las memorias son compatibles a nivel temporal con el microcontrolador.
8.2 Memorias semiconductoras
En un sistema basado en microprocesador o microcontrolador es necesario conocer los distintos tipos
de memoria que se pueden utilizar, así como la formar de realizar el acceso a éstas. Las memorias que
más se emplean son memorias no volátiles de sólo lectura, ROM, destinadas a almacenar el código de
programa generado en la aplicación. Estas memorias mantienen la información almacenada en
ausencia de tensión de alimentación. Las memorias volátiles de lectura/escritura, RAM, se emplean
para contener las variables temporales utilizadas en el mismo programa de la aplicación.
Los tipos de memoria ROM más usuales se clasifican en función de la forma de grabar los datos:
-ROM, Read Only Memory: esta memoria se graba mediante la configuración interna del
circuito integrado durante el proceso de fabricación. Luego, se debe proporcionar el programa
de la aplicación al fabricante y resulta adecuada para largas series de fabricación.
-PROM, ROM Programmable: la memoria PROM incorpora fusibles en la constitución de cada
celda interna de memoria, por lo que puede programarse por el usuario. La forma de grabar un
dato en esta memoria suele consistir en aplicar una sobrecorriente al fusible de una celda de
forma que cause su destrucción; en consecuencia, tan sólo puede grabarse una vez.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251222
-EPROM, Erasable Programmable ROM: esta memoria emplea un transistor MOS de puerta
flotante como elemento básico de cada una de sus celdas. Puede grabarse eléctricamente y
borrarse mediante su exposición a una fuente de rayos ultravioleta, para lo cual dispone de un
encapsulado especial cerámico con una ventana de cristal de cuarzo que encarece su coste. Esta
memoria es adecuada para realizar prototipos y para series cortas de fabricación, aunque, en su
versión OTP, One Time Programmable, se reduce considerablemente su costo debido a que se
elimina la ventana de cuarzo del encapsulado, por lo que sólo puede programarse una vez y no
se puede borrar.
-EEPROM o E2PROM, Electrically Erasable and Programmable ROM: esta memoria utiliza
el mismo transistor MOS de puerta flotante que la memoria EPROM, pero con una
modificación tecnológica que permite grabar y borrar el transistor MOS eléctricamente
mediante efecto túnel1
. La memoria EEPROM no tiene ventana de cuarzo, por lo que tiene un
coste más reducido que la memoria EPROM. El tiempo de lectura de esta memoria es parecido
al tiempo de lectura de las memorias RAM; no obstante, su tiempo de escritura, del orden de
milisegundos, es demasiado elevado, lo que fuerza a establecer estados de espera en el proceso
de escritura. Esta memoria es adecuada para aquellos sistemas que necesitan tener datos
almacenados de forma estable, pero que pueden modificarse con cierta frecuencia.
-FLASH: este tipo de memoria es de reciente aparición y son memorias EEPROM que tienen
una configuración interna estructurada, a nivel de circuito, en bloques de bits, lo que permite
reducir de manera considerable el área de silicio respecto a su homóloga EEPROM, lo que
reduce, por tanto, su coste e incrementa su capacidad. El tiempo de escritura y de lectura de
estas memorias es comparable con el requerido para las memorias RAM. Estas memorias se
proporcionan con capacidades considerables, del orden del megabit, lo que hace que se
apliquen para el almacenamiento de imágenes en cámaras digitales y en la sustitución de la
cinta magnética de los contestadores telefónicos. El problema que presentan estas memorias es
que pueden soportar un número bastante menor de ciclos de lectura/escritura que las memorias
EEPROM.
Las memorias del tipo RAM, Ramdom Access Memory, de lectura/escritura, se utilizan básicamente
para grabar datos y resultados relacionados con el programa que ejecuta la aplicación, y son volátiles,
es decir, pierden la información contenida cuando se interrumpe la tensión de alimentación del circuito
integrado. Existen dos tipos de memorias RAM:
-SRAM, Static RAM: esta memoria suele tener por base un biestable del tipo RS formado por
cuatro transistores que almacenan el bit concreto, y un par de transistores adicionales que se
usan para efectuar las operaciones de lectura/escritura.
-DRAM, Dynamic RAM: existen muchos tipos de memorias DRAM en el mercado y se utilizan
de forma masiva dentro del mercado de ordenadores destinados a la computación y el
procesamiento de datos. La célula básica de esta memoria consiste en un único transistor y un
condensador implementado en silicio de manera que su tamaño es sumamente reducido, por lo
1
El efecto túnel requiere de una capa muy delgada de óxido aislante, SiO2, de alta calidad, para evitar que los electrones
que atraviesan el óxido entre la puerta flotante y el drenador del transistor MOS queden atrapados en esta capa por los
defectos del óxido.
© Los autores, 2001; © Edicions UPC, 2001.
8 Memoria externa 223
que suelen ser memorias de alta capacidad de almacenamiento. La información se almacena en
el condensador de celda de la memoria, utilizando para ello la carga y descarga del
condensador, factor que hace que sean memorias de bajo consumo. Tienen el inconveniente de
que deben regrabarse cada pocos milisegundos, debido a que se producen pequeñas fugas en
las cargas de los condensadores que causan la pérdida del estado lógico almacenado, lo que
hace que tengan una circuitería interna compleja para el refresco de la memoria.
8.3 Estructura externa de las memorias
En la figura 8.1 se presenta el esquema genérico de cualquier tipo de memoria y se indican cuáles son
las entradas/salidas más comunes de este tipo de dispositivos.
Memoria
Entradas
de control
Entradas de
direcciones
A0,...,An-1
n
Entradas/salidas
de datos
Fig. 8.1 Esquema general de un circuito integrado de memoria
Las memorias que se emplean para sistemas basados en un microcontrolador, suelen tener una
estructura interna de celdas de tipo matricial, organizada en filas y columnas, donde cada celda
contiene un bit de información, el número de columnas agrupa 8 bits (que forman un byte), y donde el
número de filas determina la capacidad de la memoria. El tamaño de estas memorias es de 256x8bits o
256bytes, 1kx8bits o 1kbyte, 2kbytes, 4kbytes, 8kbytes y así sucesivamente en potencias de 2.
En estos sistemas también se utilizan memorias serie con un único bit de entrada/salida. El dato a leer
o escribir en estas memorias puede tener varios tamaños: es común que sea de 8bits, de 16bits o de
32bits. Estas memorias suelen tener un encapsulado reducido y unas pocas líneas de control.
Para acceder a cada posición de memoria se dispone de un número determinado de líneas de dirección,
dependiendo del tamaño de la memoria que se desea emplear, de manera que se cumple la siguiente
relación: m = 2n, donde m es el tamaño de la memoria en bytes y n el número de líneas de dirección.
Las memorias (figura 8.1) también suelen tener 8 líneas de entrada/salida de datos, en las que se
introducen los bytes que se quieren escribir o grabar. Se efectúa su escritura o lectura, según sea el
caso, por medio de la activación de las líneas de control que tienen asociadas.
En líneas generales las memorias ROM, PROM y EPROM suelen tener una o más señales del tipo CS,
Chip Select, o CE, Chip Enable, y OE, Output Enable, para seleccionar y realizar la lectura de la
memoria, respectivamente.
En el caso de las memorias EPROM, éstas suelen tener dos señales de control: /CE, habilitación o
selección del circuito integrado, y /OE, habilitación de la salida. La tabla 8.1 resume los modos de
funcionamiento de la memoria EPROM, considerando todos los posibles valores /CE y /OE.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251224
Tabla 8.1 Líneas de control de una memoria EPROM
/OE /CE Salidas ModoL
H
X
L
L
H
Dato
Triestado
Triestado
Lectura
Salidas inhibidas
Bajo consumo
L=Low, 0 lógico. H=High, 1 lógico. X= indeterminado, 0 ó 1 lógicos.Triestado= salidas en alta impedancia.
En la tabla 8.1 se observa cómo las salidas presentan un estado triestado en el cual cada línea se pone
en estado de alta impedancia, esta situación se da en la mayor parte de las memorias semiconductoras,
cuando la señal CE es inactiva, ya que la memoria entra un estado de bajo consumo, con un consumo
al menos un 25% menor de lo habitual.
En cuanto a las memorias del tipo RAM, suelen tener como señales de control /CS o /CE, que habilita
el funcionamiento del circuito integrado, y RD/(/WR), Read/Write (lectura/escritura), que determina si
se va a leer o escribir en la memoria; aunque, en lugar de esta señal combinada lectura/escritura, puede
tener una línea propia, /OE, para la lectura, y otra, /WE, Write Enable, para la escritura. La tabla 8.2
resume el funcionamiento de esta memoria considerando las líneas /CS y RD/(/WR), y la tabla 8.3
muestra su funcionamiento considerando las líneas /CE, /OE y /WE.
Tabla 8.2 Líneas de control de una memoria RAM
/CS WERD/ E/S de datos Modo de funcionamientoH
L
L
X
H
L
Triestado
Salida dato
Entrada dato
Inhabilitada
Lectura
Escritura
L=Low, 0 lógico. H=High, 1 lógico. X= indeterminado, 0 ó 1 lógicos.Triestado= salidas en alta impedancia
Tabla 8.3 Líneas de control de una memoria RAM con las entradas de lectura/escritura separadas
/CE /OE /WE E/S de datos ModoH
L
L
L
L
X
L
H
L
H
X
H
L
L
H
Tri-estado
Salida dato
Entrada dato
Entrada dato
Tri-estado
Standby
Lectura
Escritura
Escritura
Inhabilitada
L=Low, 0 lógico. H=High, 1 lógico. X= indeterminado, 0 ó 1 lógicos.Triestado= salidas en alta impedancia. Standby= estado de espera
8.4 Ciclos de fetch, de lectura y de escritura
El acceso a la memoria por parte del microcontrolador se puede efectuar de tres formas distintas,
denominadas ciclos, donde se lleva a cabo, en cada una de ellas, una secuencia determinada de
tiempos. Estos ciclos son:
-Ciclo de fetch o de lectura de código de operación: el ciclo de fetch es una operación de
lectura de la memoria externa, donde la información leída es el código de operación de las
instrucciones que debe ejecutar el microcontrolador.
© Los autores, 2001; © Edicions UPC, 2001.
8 Memoria externa 225
-Ciclo de lectura: el ciclo de lectura efectúa una lectura sobre la memoria externa para leer un
operando de una instrucción, que puede ser un dato o una dirección.
-Ciclo de escritura: el ciclo de escritura escribe un dato sobre la memoria.
La duración de estos ciclos es diferente dependiendo del tipo de ciclo y es distinto para las familias
MCS-51 y MCS-251. La duración habitual de estos ciclos para la MCS-251 es de dos o tres estados,
mientras que para la MCS-51 suele ser al menos de un ciclo máquina. Durante este tiempo se activan
las señales involucradas en el acceso a la memoria externa de forma adecuada.
8.5 Conexión entre la MCS-51 y la memoria externa
En la conexión entre un microcontrolador de la MCS-51 y la memoria externa intervienen el bus de
direcciones, el bus de datos y las líneas de control para gestionar la lectura/escritura en la memoria
externa. El bus de direcciones para la MCS-51 es de 16 líneas y está soportado por los puertos P0 y P2
del microcontrolador. El bus de datos es de 8 bits y está ubicado en el puerto P0.
El puerto P0 soporta, pues, el byte bajo del bus de direcciones y el bus de datos, de forma simultánea,
mediante una multiplexación temporal que se indica con la señal ALE. Esta multiplexación temporal
se puede deshacer con un latch externo de 8 bits (figura 8.2) conectando el puerto P0 al latch y la
señal ALE a la entrada de reloj de éste.
MCS-51
P0
P2
LatchA7÷A0
A15÷A8
D7÷D0
Memoria
RAM/ EPROM
ALECLK
Fig. 8.2 Conexión del bus de direcciones y de datos con una memoria externa, para la MCS-51
Además de la señal ALE, en la MCS-51 existen más líneas de control: /EA, /PSEN, /RD y /WR. /EA
External Access inhibe, a 0 lógico, el acceso a la memoria interna de programas del microcontrolador.
/PSEN se activa cuando se accede a la memoria externa de programa. /RD se activa cuando el
microcontrolador procede a la lectura de la memoria externa de datos (RAM). Y /WR se activa al
escribir en la memoria externa de datos.
8.5.1 Diagramas de tiempos para la MCS-51
Las figuras 8.3, 8.4 y 8.5 muestran los diagramas de tiempos del ciclo de fetch, de lectura y de
escritura para la MCS-51. En las tablas 8.4 y 8.5 se indica el valor de los tiempos asociados para una
frecuencia de reloj de 16MHz.
Tabla 8.4 Valores mínimos en nanosegundos de los tiempos indicados en los ciclos de fetch, de lectura y deescritura para la MCS-51, con una frecuencia de reloj de 16MHz
tLL tAL tLA tLC tCC tCI tRR tWW tDR tLW tAW tWHLH tDWX tDW tWD
85 8 28 23 143 0 275 275 0 138 120 23 3 288 13
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251226
Tabla 8.5 Valores máximos de los tiempos en nanosegundos de los tiempos indicados en los ciclos de fetch, delectura y de escritura para la MCS-51, con una frecuencia de reloj de 16MHz
tLIV tCIV tCIF tAIV tCC tAFC tRD tDFR tLD tAD tLW tWHLH tAFR
150 83 38 208 143 10 148 55 350 398 238 103 0
t LL t LIV
t CIV
t LC
t CY
t CC
t AL
t LA
t CI
t CIF
t AIV
t AFC
AD8..AD15AD8..AD15
AD0..AD7P0
P2
PSEN
ALE
AD0..AD7INSTRUC INSTRUC
Fig. 8.3 Diagrama de tiempos de un ciclo fetch en memoria externa para la MCS-51
t LDt WHLH
t LW t RR
t AL t LA
t AW t RD t DR
t DFR
t AFRt AD
AD8..AD15
AD0..AD7 ENTRADA DEL DATOP0
P2
PSEN
ALE
RD
Fig. 8.4 Diagrama de tiempos de un ciclo de lectura en memoria externa para la MCS-51
P2
P0
t ALt LA
t WHLH
AD8..AD15
AD0..AD7 SALIDA DEL DATO
WDt AW
t LW
t WW
t DW
t WDt DWX
PSEN
ALE
Fig. 8.5 Diagrama de tiempos de un ciclo escritura en memoria externa para la MCS-51
© Los autores, 2001; © Edicions UPC, 2001.
8 Memoria externa 227
En la ejecución del ciclo de fetch para la MCS-51 se realizan los siguientes pasos:
1. Colocar el byte alto y el byte bajo del bus de direcciones en el puerto P2, líneas A8,…, A15,
y P0, líneas A0,…, A7, respectivamente.
2. Forzar a que la señal ALE tenga un flanco de bajada para que el contenido del puerto P0,
líneas A0,…, A7, se almacenen en el latch.
3. Una vez que la dirección está presente a la entrada de la memoria, se activa la señal /PSEN
para realizar la lectura de la memoria.
4. La memoria coloca el código de operación en el bus de datos, puerto P0; el
microcontrolador lee este dato coincidiendo con el flanco de subida de /PSEN.
8.6 Ejemplos de conexión para la MCS-51
Ejemplo 8.1 Conexión de memorias EPROM y RAM
La figura 8.6 muestra un ejemplo de conexión de una memoria EPROM 27C256 de 32kbytes y
una memoria RAM 6164 de 8kbytes a un microcontrolador 80C31. Según esta figura, la señal
de habilitación de la memoria EPROM, /CE, está conectada directamente a línea A15 del bus
de direcciones, de forma que cuando A15=0 la memoria está seleccionada, y cuando A15=1, no
lo está. Este hecho implica que siempre que el código de las instrucciones del programa estéubicado dentro de las primeras 32k direcciones, de las 64k direcciones posibles, la memoria
EPROM quedará seleccionada, pues en el bus de direcciones aparece una dirección
correspondiente a este rango. Estos rangos de direcciones donde se seleccionan las memorias
EPROM, RAM o cualquier otro dispositivo que tenga que seleccionarse por medio de una
dirección concreta, se denominan Mapa de memoria. El mapa de memoria donde se indican los
rangos de direcciones de selección de las memorias EPROM y RAM de este ejemplo se
muestran en la figura 8.7.
En el circuito de la figura 8.7 se utiliza el circuito integrado 74LS373, constituido por 8
básculas D con salida triestada, para deshacer la multiplexación temporal en el puerto P0 entre
las 8 líneas del bus de datos y las 8 líneas bajas del bus de direcciones. La señal de reloj de las
básculas está conectada a la señal ALE, de manera que cuando ALE está a 1 lógico, el estado
lógico presente a la entrada de las 8 básculas D pasa a la salida, y cuando la señal ALE pasa a 1
lógico, las básculas mantienen el último estado lógico presente en sus entradas.
La lectura de la memoria EPROM se realiza a través de la señal /PSEN (activa a 0 lógico y
conectada a la entrada /OE de la memoria), para ello la memoria se debe seleccionar
previamente con A15.
La selección de la memoria RAM se realiza por medio de la señal /CS, que selecciona la
memoria cuando está a 0 lógico. La señal /CS se ha conectado directamente a la línea de
dirección A13, de manera que la memoria se selecciona siempre que el microcontrolador
realiza una lectura o escritura en los primeros 8kbytes de los 64kbytes posibles para la MCS-
51. No obstante, la memoria RAM se selecciona cada vez que la señal /CS está a 0 lógico, lo
que ocurre cuando las direcciones del bus están dentro de uno de los siguientes rangos de
direcciones: 0000H-0FFFH, 2000H-2FFFH, 4000H-4FFFH, 6000H-6FFFH, 8000H-8FFFH,
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251228
A000H-AFFFH, C000H-CFFFH y E000H-EFFFH. Fuera de estas zonas la memoria no estáseleccionada, tal y como se indica en la figura 8.7.
80C31
P0
P2
A13
/PSEN/WR
/EA
Latch
/OE /WE
A7÷A0
A12÷A8
D7÷D0
/CS
RAM 6164
(8 kbytes)
(32 kbytes)
A7÷A0
A14÷A8
D7÷D0
/OE /CE
ALE
74LS373
D7÷D0 Q7÷Q0
A15/RD
CLK
EPROM
27C256
Fig. 8.6 Conexión de una memoria RAM de 8kbytes y una memoria EPROM de 32kbytes al 80C31
Memoria de programas Memoria de datos
0000H
7FFFH
8000H
FFFFH
EPROM
(32 kbytes)
Sin memoria
0000H
1FFFH
2000H
FFFFH
Sin memoria
RAM (8 kbytes)
Memoria de datos
1FFFH
0000H
RAM (8 k)1FFFH
2000H
Zona Imagen (8k)
2FFFH
8000H
Zona Imagen (8k)
8FFFH
6000HZona Imagen (8k)
6FFFH
4000H
Zona Imagen (8k)
4FFFH
A000H
Zona Imagen (8k)
AFFFH
C000HZona Imagen (8k)
CFFFH
E000H
Zona Imagen (8k)
EFFFH
a) b)
c)
Fig. 8.7 Mapa de memoria del circuito de la figura 8.6. a) Mapa de la memoria de programas. b) Mapade la memoria de datos. c) Mapa de la memoria de datos considerando imágenes
© Los autores, 2001; © Edicions UPC, 2001.
8 Memoria externa 229
80C31
P0
P2
A13
/PSEN/WR
/EA
Latch
(32 kbytes)
A7÷A0
A14÷A8
D7÷D0
/OE /CE
ALE
74LS373
D7÷D0 Q7÷Q0
A15/RD
CLK
EPROM27C256
/OE /WE
A7÷A0
A12÷A8
D7÷D0
/CS
RAM1 6164
(8 kbytes)
/OE /WE
A7÷A0
A12÷A8
D7÷D0
/CS
RAM2 6164
(8 kbytes)
Fig. 8.8 Conexión de dos memorias RAM de 8kbytes y una memoria EPROM de 32kbytes al 80C31
Según el mapa de memoria de la figura 8.7, la capacidad de memoria RAM del sistema puede
ampliarse en 8kbytes más conectando un circuito integrado de memoria RAM 6164 adicional,
como se muestra en la figura 8.8. La memoria RAM2 se sitúa en las zonas del mapa de
memoria de datos que no es imagen; para ello se conecta la línea A13 mediante una puerta
lógica NOT a la señal /CS de la memoria. Con el circuito de la figura 8.8, la memoria RAM1 se
selecciona cuando la línea A13 está a 0 lógico, mientras que la memoria RAM2 se selecciona
cuando la línea A13 está a 1 lógico. La memoria RAM2 ocupa las zonas sombreadas que hay
en el mapa de memoria de la figura 8.7, y se selecciona cuando las direcciones del bus están
dentro de uno de los siguientes rangos de direcciones: 1000H-1FFFH, 3000H-3FFFH, 5000H-
5FFFH, 7000H-7FFFH, 9000H-9FFFH, B000H-BFFFH, D000H-DFFFH y F000H-FFFFH.
Para utilizar más circuitos integrados de memoria se necesita emplear una lógica de selección
de la memoria algo más compleja, que garantice la conexión de más memorias y de otros
dispositivos al microcontrolador; para ello en el siguiente ejemplo se propone el uso de un
decodificador en la selección de las memorias.
Ejemplo 8.2 Selección de memorias mediante el 74LS138
La figura 8.9 muestra el circuito de conexión de dos memorias EPROM 27C128 de 16kbytes
cada una, y de dos memorias RAM 6164 de 8kbytes cada una. La selección de las memorias se
efectúa con el decodificador de 3 a 8 líneas 74LS138.
Las salidas Y0-Y7 del 74LS138 se activan a 0 lógico cuando en las entradas, C, B y A, aparece
el código correspondiente de la salida, según la tabla de verdad del decodificador de la figura
6.18. Las entradas G1, /G2A y /G2B son las líneas de habilitación del decodificador y deben
estar a 1, 0 y 0 lógicos, respectivamente, para que el decodificador funcione correctamente. El
decodificador queda inhabilitado si la entrada G1 está a 0 lógico o cualquiera de las entradas
/G2A o /G2B está a 1 lógico, es decir, si cualquiera de estas entradas está inhabilitada.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251230
80C31
P0
P2
A13
/PSEN
/WR
/EA
Latch
ALE
74LS373
D7÷D0Q7÷Q0
A15
/RD
CLK
/OE /WE
A7÷A0
A12÷A8
D7÷D0
/CS
RAM1 6164
(8 kbytes)
/OE /WE
A7÷A0
A12÷A8
D7÷D0
/CS
RAM2 6164
(8 kbytes)
(16 kbytes)
A7÷A0
A13÷A8
D7÷D0
/OE /CE
EPROM127C128
(16 kbytes)
A7÷A0
A13÷A8
D7÷D0
/OE /CE
EPROM227C128
A14
74LS138
Y0
Y1
Y2
Y3
Y4
Y5
Y6Y7
/G2B
/G2AG1
A
B
C
Vcc
G1 G2 C B A Y0 Y1 Y2 Y3 Y4 Y5 Y6 Y7
X H X X X H H H H H H H H
L X X X X H H H H H H H H
H L L L L L H H H H H H H
H L L L H H L H H H H H H
H L L H L H H L H H H H H
H L L H H H H H L H H H H
H L H L L H H H H L H H H
H L H L H H H H H H L H H
H L H H L H H H H H H L H
H L H H H H H H H H H H L
SelecciónHabilit.Entradas
Salidas
*
*G2=G2A+G2B
Fig. 8.9 Conexión de dos memorias RAM y de dos memorias EPROM con el 74LS138
Conectando la línea A15 a la entrada C del 74LS138, la línea A14 a la entrada B y la línea A13
a la entrada A, la salida Y0 del decodificador se activa siempre y cuando las líneas A15, A14 y
A13 estén a 0 lógico, lo que ocurre en el rango de direcciones comprendido entre 0000H y
1FFFH, es decir, las primeras 8k posiciones del mapa de memoria. De la misma forma, cada
una de las restantes entradas se activa con un rango de 8k posiciones del mapa de memoria,
según la tabla 8.6.
Tabla 8.6 Espacio de memoria en el cual se activan las salidas del 74LS138 en la figura 8.9
Salida activa Espacio de memoria Memoria habilitadaY0 0000H-1FFFH RAM1 y EPROM1
Y1 2000H-3FFFH RAM2 y EPROM1
Y2 4000H-5FFFH EPROM2
Y3 6000H-7FFFH EPROM2
Y4 8000H-9FFFH -
Y5 A000H-BFFFH -
Y6 C000H-DFFFH -
Y7 E000H-FFFFH -
Las líneas de selección de las memorias RAM1 y RAM2, al tener una capacidad de 8kbytes, se
conectan directamente a las salidas Y0 y Y1 del decodificador, respectivamente. La memoria
EPROM1 tiene una capacidad de 16kbytes, por lo que su línea de selección, /CE, estáconectada a las salidas Y0 e Y1 por medio de una puerta AND. Esta memoria se habilita
siempre y cuando el microcontrolador efectúe una lectura en los primeros 16kbytes del mapa de
© Los autores, 2001; © Edicions UPC, 2001.
8 Memoria externa 231
memoria. De la misma forma, la entrada /CE de la memoria EPROM2 se conecta a las salidas
Y2 y Y3; se habilita cuando el microcontrolador realiza una lectura en el espacio comprendido
entre 4000H y 7FFFH del mapa de memoria.
8.7 Conexión con la memoria externa para la familia MCS-251
La interfaz de acceso a la memoria externa comprende todas las líneas del microcontrolador que
intervienen en la conexión con la memoria externa. Estas líneas están agrupadas en tres buses: bus de
direcciones, bus de datos y bus de control.
El bus de direcciones puede ser de 16, 17 ó 18 líneas, configurable por el usuario. En cualquier caso,
independientemente de la opción elegida, los 16 bits de menor peso del bus de direcciones están
implementados por los puertos P0 y P2. Si se configura el microcontrolador para tener 17 líneas de
bus de direcciones, el bit de mayor peso del bus, A16, está ubicado en el pin P3.7. Si se utilizan 18
líneas de bus de direcciones, la línea de mayor peso, A17, está ubicada en el pin P1.7. En la tabla 8.7
se indica la localización de las diferentes líneas del bus de direcciones.
Tabla 8.7 Ubicación del bus de direcciones
Bus de direcciones UbicaciónA0,…,A7
A8,…,A15
A16
A17
P0.0,…,P0.7
P2.0,…,P2.7
P3.7
P1.7
El bus de datos es de 8 bits y su ubicación es configurable por el usuario, quien debe elegir entre dos
opciones: modo paginado y modo no paginado (tabla 8.8).
Tabla 8.8 Posibilidades de ubicación del bus de datos
Bus de datos Ubicación CaracterísticasModo no paginado
Modo paginado
P0.0,…,P0.7
P2.0,…,P2.7
Compatible con el 8XC51
Acceso óptimo a la memoria externa
El modo paginado es más eficiente en el acceso a la memoria externa, ya que reduce el tiempo
invertido por el microcontrolador para leer los códigos de operación de las instrucciones, pero no es
compatible con los microcontroladores de la familia MCS-51.
En cuanto a las conexiones externas, la diferencia entre ambos modos radica en la ubicación del bus de
datos. En el modo no paginado el bus de datos está implementado por el puerto P0, que al mismo
tiempo implementa las 8 líneas de menor peso del bus de direcciones, de la A0 a la A7. Debido a esta
duplicidad de tareas, el puerto P0 debe conectarse a un registro, o latch, de 8 bits, cuya carga estácontrolada por la señal ALE, a fin de almacenar la parte baja de la dirección (figura 8.10). En cambio,
si el microcontrolador está configurado en modo paginado, es el puerto P2 el que realiza la función de
bus de datos, al mismo tiempo que implementa las 8 líneas del bus de direcciones que van de la A8 a
la A15. En este caso el latch se conecta al puerto P2, a fin de almacenar los bits de direcciones
A8,..,A15.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251232
8XC251Sx
P2
P0
Latch A15:8
A7:0
D7:0
RAM/
EPROM
ALE
8XC251Sx
P0
P2
Latch A7:0
A15:8
D7:0
RAM/
EPROM
ALE
Modo no paginado Modo paginado
Fig. 8.10 Estructura del bus en modo no paginado y modo paginado
El bus de control está compuesto por todas aquellas señales que permiten controlar qué tipo de
operación, de lectura o escritura se realiza sobre la memoria externa. El microcontrolador 8XC251Sxdispone de dos señales de control de lectura, /RD y /PSEN, y una de escritura, /WR (tabla 8.9). El
rango de direcciones asociadas a estas señales de control depende del valor de los bits de
configuración RD1 y RD0.
Tabla 8.9 Señales de acceso a la memoria externa
Nombre Tipo Descripción Multiplexado con
A17 O Línea de dirección A17. P1.7/CEX4
A16 O Línea de dirección A16. P3.7/RD
A15:8 O Parte alta del bus de direcciones. P2.0,..,P2.7
AD7:0 I/O Bus de datos y parte baja del bus de direcciones (nodo no paginado). P0.0,..,P0.7
ALE O Address Latch Enable. Controla la carga del registro de 8 bits que estáconectado al puerto que realiza las funciones de bus de datos.
/PROG
/EA I External Access. Esta entrada inhibe, si esta a cero lógico, el acceso a
la memoria OTPROM/ROM interna del microcontrolador.
/PSEN O Program Store Enable. Esta señal controla las operaciones de lectura
en la memoria externa. El rango de direcciones para las que opera esta
señal de control depende de los bits de configuración RD1 y RD0.
/RD O Señal de lectura o línea A16 del bus de direcciones. Dependiendo del
valor de los bits de configuración RD1 y RD0 esta línea controla la
lectura de memoria externa en las direcciones [ 7F:FFFFH, o bien
implementa la línea de mayor peso del bus de direcciones.
P3.7/A16
/WR O Señal de escritura. Esta señal controla las operaciones de escritura en
la memoria externa.
P3.6
Existen otras señales de control auxiliar que intervienen en el acceso a la memoria externa, como son
la señal ALE (Address Latch Enable) y /EA (External Access). La señal ALE está ubicada en el pin 30
del microcontrolador (encapsulado DIP) y controla la carga del registro que está conectado al bus de
datos. El pin /EA se corresponde con el pin 31 del microcontrolador (encapsulado DIP) e inhibe,
cuando está a 0 lógico, el acceso a la memoria interna del tipo ROM. En la tabla 8.9 se resume la
totalidad de señales que intervienen, por parte del microcontrolador, en el acceso a la memoria
externa.
© Los autores, 2001; © Edicions UPC, 2001.
8 Memoria externa 233
8.8 Configuraciones de acceso a la memoria externa
Como ya se ha comentado en los apartados anteriores, el usuario puede escoger entre diversas
opciones de configuración de acceso a la memoria externa, que básicamente consisten en elegir el
número de líneas del bus de direcciones y la ubicación del bus de datos. En los apartados siguientes se
estudiarán algunas de estas configuraciones a través de ejemplos prácticos.
8.8.1 18 bits de bus de direcciones (RD1, RD0 = 00)
Se va ha considerar, en primer lugar, la configuración que permite tener 18 líneas de bus de
direcciones: RD1 = 0 y RD0 = 0. Con 18 líneas de bus de direcciones se pueden direccionar hasta
256Kbytes de memoria externa. Para esta configuración las señales que controlan las operaciones de
lectura/escritura en la memoria externa son dos:
] /PSEN: controla las operaciones de lectura en la memoria externa para cualquier dirección, de
la 00:0000H a la FF:FFFFH.
] /WR: controla las operaciones de escritura en la memoria externa para cualquier dirección, de
la 00:0000H a la FF:FFFFH.
Ejemplo 8.3 Conexión de una memoria RAM de 256Kbytes
En la figura 8.11 se presenta un ejemplo de conexión de una memoria RAM de 256Kbytes de
capacidad al microcontrolador 8XC251Sx: se puede observar cómo el registro está conectado
al puerto P0, al igual que las entradas de datos de la memoria RAM. Esto significa que el bus
de datos está ubicado en el puerto P0, por tanto, el microcontrolador está trabajando en modo
no paginado.
8XC251Sx
P0
P2
A16
WR PSEN
EA
Latch
OE WE
A16
A7:0
A15:8
D7:0
RAM
256Kbytes
ALE
CEA17 A17
Fig. 8.11 Conexión de una memoria RAM de 256Kbytes al microcontrolador 8XC251Sx en modo paginado
La señal ALE controla la carga del registro y se activa cuando en el puerto P0 está disponible la
parte baja de la dirección (A0, …, A7). Esta parte baja quedará almacenada en el registro,
cuyas salidas están conectadas a las 8 líneas de direcciones de menor peso de la memoria
RAM.
El puerto P2 está conectado a las líneas de direcciones A8, ..., A15 de la memoria RAM. Las
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251234
dos últimas líneas de direcciones del microcontrolador, A16 y A17, están conectadas a las dos
entradas de direcciones de mayor peso de la memoria RAM.
Para controlar las operaciones de lectura y escritura se han conectado las salidas /WR y /PSEN
del microcontrolador a las entradas de control de la memoria RAM, /WE (Write Enable) y /OE
(Output Enable), respectivamente.
Por otra parte, la entrada /CE de la memoria RAM está conectada a masa, de forma que el
integrado de memoria RAM está permanentemente habilitado.
También se puede observar en la figura 8.11 que el pin /EA del microcontrolador estáconectado a masa, lo que significa que la memoria ROM interna está inhibida y no es accesible.
El microcontrolador puede realizar tres tipos de operaciones, denominadas ciclos, sobre la memoria
externa:
1. Ciclo de lectura: el microcontrolador ejecuta un ciclo de lectura sobre la memoria externa para
leer un operando, que puede ser un dato o una dirección, almacenado en una posición de la
memoria externa.
2. Ciclo de escritura: el microcontrolador ejecuta un ciclo de escritura sobre la memoria externa
para escribir el contenido de una posición de memoria.
3. Ciclo de fetch o de lectura de código de operación: el ciclo de fetch es una operación de lectura
de la memoria externa, donde la información leída es el código de operación de la siguiente
instrucción que debe ejecutar el microcontrolador.
Estas operaciones tienen una duración de dos o tres estados, durante los cuales se activan las señales
involucradas en el acceso a la memoria externa, en el momento y orden adecuado, como se puede
observar en los cronogramas correspondientes. En la figura 8.12 está representado el cronograma del
ciclo de fetch para el modo no paginado, que tiene una duración de dos estados, o sea, cuatro períodos
de reloj.
En la ejecución del ciclo de fetch se realizan los siguientes pasos:
1. Al comienzo del ciclo de fetch se coloca la parte alta de la dirección, donde está almacenado el
código de operación que va a leer el microcontrolador, en el puerto P2 (A8, …, A15). Si se utiliza
un bus de direcciones de 17 ó 18 líneas también aparece en ese momento su valor correspondiente
en sus respectivas ubicaciones (P3.7 y P1.7).
2. A continuación el microcontrolador coloca la parte baja de la dirección (A0, …, A7) en el puerto
P0.
3. El microcontrolador hace pasar la señal ALE por un flanco de bajada de forma que se carga en el
registro el contenido del puerto P0, o sea, las líneas A0, …, A7 del bus de direcciones.
4. Una vez que la dirección está disponible en las entradas de direcciones de la memoria, el
microcontrolador activa la señal de lectura, indicando con ello a la memoria que ya puede colocar
un dato válido en el bus de datos.
5. Si todo va bien la memoria RAM responde a la activación de la señal de lectura colocando el
código de operación en el bus de datos. El microcontrolador lee este código coincidiendo con el
flanco de subida de /PSEN.
© Los autores, 2001; © Edicions UPC, 2001.
8 Memoria externa 235
XTAL
ALE
/RD, /PSEN
P0
A17, A16, P2
A7:0 D7:0
A17,A16,A15:8
Estado 1 Estado 2
1
2
3
4
5
Fig. 8.12 Ciclo de fetch en modo no paginado
En la figura 8.13 está representado el cronograma del ciclo de lectura en modo no paginado. Este ciclo
tiene una duración de 6 períodos de reloj. La secuencia de un ciclo de lectura es similar a la del ciclo
de fetch, con la única diferencia que tiene una duración mayor.
XTAL
ALE
/RD, /PSEN
P0
A17, A16, P2
A7:0
A17, A16, A15:8
Estado 1 Estado 2 Estado 3
D7:0
Fig. 8.13 Ciclo de lectura en modo no paginado
En la figura 8.14 está representado el cronograma correspondiente al ciclo de escritura en modo no
paginado, cuya duración también es de 6 períodos de reloj. La secuencia de activación de las señales
de control también es similar a la del ciclo de lectura, con la única diferencia que, en este caso, el
microcontrolador activa la señal de escritura /WR en lugar de la señal de lectura.
Si se opta por trabajar en modo paginado, se deberá conectar el registro, o latch, de 8 bits a la salida
del puerto P2 (figura 8.15). Trabajar en modo paginado tiene como principal ventaja un ahorro de
tiempo en el acceso a la memoria externa. Esto es debido a que el ciclo de fetch, en determinadas
circunstancias, se ejecuta en tan sólo un estado en lugar de dos. En efecto, cuando el microcontrolador
debe leer el siguiente código de operación en una dirección donde los bits A8, …, A15 del bus de
direcciones han cambiado con respecto al valor que tenían para la instrucción anterior, la lectura dura
dos estados. Ahora bien, la lectura de los siguientes códigos de operación dura un solo estado, siempre
y cuando los bits A8, …, A15 del bus de direcciones no cambien.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251236
XTAL
ALE
/WR
P0
A17, A16, P2
A7:0
A17, A16, A15:8
Estado 1 Estado 2 Estado 3
D7:0
Fig. 8.14 Ciclo de escritura en modo no paginado
8XC251Sx
P2
P0
A16
WR PSEN
EA
Latch
OE WE
A16
A15:8
A7:0
D7:0
RAM
256Kbytes
ALE
CEA17 A17
Fig. 8.15 Conexión de una memoria RAM de 256Kbytes al microcontrolador 8XC251Sx en modo paginado
En la figura 8.16 se presenta el cronograma para estas dos situaciones. El primer ciclo de fetch tiene
una duración de 2 estados, porque hay un cambio de los bits A8, …, A15, con respecto a la dirección
anterior. En el segundo ciclo de fetch se mantiene el valor de los bits A8, …, A15 y, por tanto, la
duración es de solo 1 estado.
XTAL
ALE
/PSEN
A17, A16, P0
P2
Estado 1 Estado 2 Estado 1
A17, A16, A7:0
A15:8 D7:0
A17, A16, A7:0
D7:0
Ciclo 1, cambio de páginaCiclo 2
misma página
Fig. 8.16 Ciclo de fetch en modo paginado
© Los autores, 2001; © Edicions UPC, 2001.
8 Memoria externa 237
Finalmente, en las figuras 8.17a) y 8.17b) se presenta el cronograma de los ciclos de lectura y escritura
en modo paginado. La única diferencia con respecto a los cronogramas del modo no paginado (figuras
8.13 y 8.14) es que el bus de datos está ubicado en el puerto P2.
XTAL
ALE
/RD, /PSEN
A17, A16, P0
P2
A17, A16, A7:0
Estado 1 Estado 2 Estado 3
A15:8 D7:0
XTAL
ALE
/WR
A17, A16, P0
P2
A17, A16, A7:0
Estado 1 Estado 2 Estado 3
A15:8 D7:0
a) b)Fig. 8.17 a) Ciclo de lectura y b) ciclo de escritura en modo paginado
Hay diseños en los que la memoria externa utilizada tiene un retardo importante y no puede responder
al microcontrolador con la rapidez necesaria. En estos casos, para que no se produzcan lecturas o
escrituras erróneas se deben introducir ciclos de espera. Los ciclos de espera resuelven este problema,
ya que alargan el ciclo de fetch, el ciclo de lectura y el de escritura, el tiempo suficiente para que la
memoria externa responda adecuadamente.
Configurando convenientemente el microcontrolador es posible introducir 0, 1, 2 ó 3 ciclos de espera
para las señales /RD, /WR y /PSEN. En la figura 8.18 está representado el cronograma del ciclo de
fetch con un estado de espera adicional que proporciona a la memoria externa un tiempo
suplementario, equivalente a dos periodos de reloj, para que coloque el código de operación en el bus
de datos. En la figura 8.19 está representado el ciclo de lectura con un estado de espera adicional.
También es posible introducir un estado de espera en la señal ALE para poder cargar adecuadamente
el registro cuando éste es excesivamente lento. En la figura 8.20 se muestra un ciclo de fetch donde se
ha introducido un estado de espera en la señal ALE.
XTAL
ALE
/RD, /PSEN
P0
A17, A16, P2 A17, A16, A15:8
Estado 1 Estado 2 Estado 3
A7:0 D7:0
Fig. 8.18 Ciclo de fetch en modo no paginado con un estado de espera adicional
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251238
XTAL
ALE
/WR
P0
A17, A16, P2 A17, A16, A15:8
Estado 1 Estado 2 Estado 3 Estado 4
A7:0 D7:0
Fig. 8.19 Ciclo de escritura en modo no paginado con un estado de espera
XTAL
ALE
/RD, /PSEN
P0
A17, A16, P2 A17, A16, A15:8
Estado 1 Estado 2 Estado 3
A7:0 D7:0
Fig. 8.20 Ciclo de fetch en modo no paginado con un estado de espera en la señal ALE
Ejemplo 8.4 Conexión de una memoria EPROM y otra RAM de 128Kbytes cada una
En la figura 8.21 se presenta un ejemplo de conexión de la memoria externa al
microcontrolador para una configuración de 18 líneas de bus de direcciones y modo no
paginado. En este caso se ha conectado al microcontrolador una memoria RAM de 128Kbytes
de capacidad y una memoria EPROM de la misma capacidad.
8XC251S x
P0
P2
A17
A16
WR PSEN
EA
Latch
OE WE
A16
A7:0
A15:8
D7:0
CE
RAM
128Kbytes
EPROM
128Kbytes
A16
A7:0
A15:8
D7:0
OE CE
ALE
Fig. 8.21 Esquema de conexión en modo no paginado (RD1, RD0 = 00)
© Los autores, 2001; © Edicions UPC, 2001.
8 Memoria externa 239
En la figura 8.22 se muestra cómo queda distribuido el espacio de direcciones del
microcontrolador entre los integrados de memoria considerados en este ejemplo. En esta figura
se puede observar que la memoria RAM está vinculada a las direcciones de las regiones 00:,
01:, FC: y FD:, mientras que la memoria EPROM está vinculada a las direcciones de las
regiones FE:, FF:, 02: y 03:.
A cada posición física de la memoria RAM se puede acceder a través de dos direcciones
distintas, una perteneciente a las regiones 00: ó 01:, y la otra perteneciente a las regiones FC: o
FD: que se denominan zonas imagen. Igualmente se puede acceder a cualquier posición de la
memoria EPROM utilizando dos direcciones distintas: una perteneciente a las regiones FE: o
FF:, y la otra perteneciente a las regiones 02: o 03: (zonas imagen).
En la figura 8.23 se puede observar las direcciones de memoria externa asociadas a cada uno de
los circuitos integrados de la figura 8.21, junto con las regiones del mapa de memoria del
microcontrolador al que están vinculadas esas direcciones.
00:0000H
Espacio de memoria
(512Kbytes)
FF:
FE:
FD:
FC:
03:
02:
01:
00: 0420H
FFFFH
1056 Bytes de memoria RAM interna
Memoria RAM externa
128Kbytes
Memoria EPROM externa128Kbytes
FFFFH
0000H
Memoria RAM externa128Kbytes
(imagen)
Memoria EPROM externa
128Kbytes(imagen)
0000H
Fig. 8.22 Espacio de memoria para el ejemplo 8.2
A17 A16
Memoria externa
256Kbytes
1 1
1 0
0 1
0 0
03:, FF:
02:, FE:
01:, FD:
00:, FC:
RAM
EPROM
Fig. 8.23 Regiones asociadas a las memoriasRAM y EPROM
8.8.2 17 bits de bus de direcciones (RD1, RD0 = 01)
Con esta configuración se dispone de 17 líneas de bus de direcciones externo: las 16 primeras líneas,
A0-A15, implementadas mediante los puertos P0 y P2, y la línea A16 implementada en el pin P3.7.
Esta configuración permite direccionar hasta 128Kbytes de memoria externa. La línea A16 del bus de
direcciones externo selecciona entre las dos regiones de 64Kbytes de memoria externa. En este caso
las direcciones de las regiones 00:, 02:, FC: y FE: (todas ellas con el bit A16 =0) permiten acceder a la
primera región de 64Kbytes de memoria externa. Por otra parte, las direcciones de las regiones 01:,
02:, FD: y FF: (todas ellas con el bit A16=1) posibilitan el acceso a la otra región de 64Kbytes de
memoria externa (figura 8.24).
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251240
A16
Memoria externa
128Kbytes
1
0
01:, 03:, FD:, FF:
00:, 02:, FC:, FE:64Kbytes
64Kbytes
Fig. 8.24 Regiones asociadas a las direcciones de memoria externa para RD1, RD0 = 01
Ejemplo 8.5 Conexión de una memoria RAM de 128Kbytes
En la figura 8.25 está representada la conexión de una memoria RAM de 128Kbytes de
capacidad al microcontrolador 8XC251Sx, configurado con 17 líneas de bus de direcciones en
modo no paginado.
8XC251Sx
P0
P2
A16
WR PSEN
EA
Latch
OE WE
A16
A7:0
A15:8
D7:0
RAM
128Kbytes
ALE
CE
Fig. 8.25 Esquema de conexión modo no paginado
8.8.3 16 bits de bus de direcciones (RD1, RD0 = 10)
Esta configuración permite tener un total de 16 líneas de bus de direcciones, de la A0 a la A15,
implementadas con los puertos P0 y P2, lo que posibilita direccionar hasta 64Kbytes de memoria
externa. Para esta configuración todas las regiones de memoria interna (00:, 01:, 02:, 03:, FC:, FD:,
FE: y FF:) están ubicadas en la misma región de memoria externa de 64Kbytes (figura 8.26).
Memoria externa
64Kbytes
00:, 01:, 02:, 03:, FC:, FD:, FE:, FF:64Kbytes
Fig. 8.26 Regiones asociadas a las direcciones de memoria externa para RD1, RD0 = 10
8.8.4 16 bits de bus de direcciones (RD1, RD0 = 11)
Esta configuración es la única compatible con los microcontroladores de la familia MCS-51. Por este
motivo, dispone de 16 líneas de bus de direcciones y de tres señales de control de acceso a la memoria
externa:
] /PSEN: señal de control de lectura de la memoria externa para las regiones FC:, FD:, FE: y FF:.
] /RD: señal de control de lectura de la memoria externa para las regiones 00:, 01:, 02: y 03:.
] /WR: señal de control de escritura de la memoria externa para las regiones 00:, 01:, 02: y 03:.
© Los autores, 2001; © Edicions UPC, 2001.
8 Memoria externa 241
Para que la compatibilidad con la familia MCS-51 sea completa, se debe configurar al
microcontrolador 8XC251Sx para que trabaje en modo no paginado.
Ejemplo 8.6 Conexión de una memoria RAM de 64Kbytes en modo paginado
En la figura 8.27 está representado un ejemplo de conexión de una memoria RAM de
64Kbytes al microcontrolador 8XC251Sx configurado en modo paginado. En esta aplicación el
código del programa se almacena en la memoria interna ROM/OTPROM/EPROM.
8XC251Sx
P2
P0
WR PSEN
EA
Latch
OE WE
A15:8
A7:0
D7:0
RAM
64 Kbytes
ALE
CE
Fig. 8.27 Ejemplo de conexión para modo paginado (RD1, RD0 = 10)
Ejemplo 8.7 Conexión de una memoria RAM de 64Kbytes en modo no paginado
En la figura 8.28 se muestra el esquema de un ejemplo de conexión, para esta configuración, de
un microcontrolador 8XC251Sx con una memoria RAM de 64Kbytes. En este caso, se ha
conectado la entrada de escritura de la memoria RAM, /WE, a la salida de escritura del
microcontrolador, /WR. Por otra parte, se ha conectado la entrada de habilitación de lectura,
/OE, a la salida de una puerta lógica que realiza la operación AND entre las dos señales de
control de lectura del microcontrolador, /PSEN y /RD. De esta forma, siempre que se ejecute
una lectura en la memoria externa, para cualquier región del mapa de memoria disponible (00:,
01:, 02:, 03:, FC:, FD:, FE: y FF:), se activará la entrada de lectura de la memoria RAM.
8XC251Sx
P0
P2
WR PSEN
EA
Latch
WE
A7:0
A15:8
D7:0
OE
RAM
64 Kbytes
ALE
RD
CE
Fig. 8.28 Ejemplo de conexión en modo no paginado (RD1, RD0 = 11)
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251242
A pesar de que sólo se dispone de 16 líneas de bus de direcciones en esta configuración, es posible
direccionar hasta un total de 128Kbytes de memoria externa utilizando de forma separada las señales
de control /PSEN, /WR y /RD (ejemplo 8.8).
Ejemplo 8.8 Conexión de dos memorias de 64Kbytes con RD1, RD0 = 11
En la figura 8.29 se muestra la conexión de dos integrados de memoria, de 64Kbytes cada uno,
al microcontrolador 8XC251Sx, configurado con RD1, RD0 = 11. La memoria RAM se
controla exclusivamente con las señales /WR y /RD, de forma que se habilitará su
funcionamiento para aquellas direcciones correspondientes a las regiones 00:, 01:, 02: y 03:.
Por otra parte, el integrado de memoria EPROM se controla con la señal /PSEN; esto significa
que sólo se habilita cuando se efectúan lecturas en direcciones correspondientes a las regiones
FC:, FD:, FE: y FF:.
8XC251Sx
P0
P2
WR
PSEN
EA
LatchA7:0
A15:8
D7:0
OECE
WE
RAM
64 Kbytes
EPROM
64 Kbytes
A7:0
A15:8
D7:0
OE CE
ALE
RD
Fig. 8.29 Ejemplo de conexión en modo no paginado (RD1, RD0 = 11)
Ejemplo 8.9 Diseño de la decodificación de memoria de un sistema microprocesador
Se pretende diseñar un sistema basado en el microcontrolador 8XC251 que se ajuste al mapa de
memoria de la figura 8.30, estando el microcontrolador configurado para ser compatible con la
familia MCS-51: modo no paginado y 16 líneas de bus de direcciones (RD1, RD0 = 11).
0000H
1FFFH
2000H
9FFFH
A000H
BFFFH
EPROM
VACÍO
RAM
Mapa de memoria
controlado por /PSEN
0000H
BFFFH
C000H
FFFFH
VACÍO
RAM
Mapa de memoria
controlado por /WR y /RD
C000H
FFFFHVAC ÍO
4000H
5FFFH
6000H
EPROM
3FFFHVACÍO
Fig. 8.30 Mapa de memoria del sistema microcontrolador
© Los autores, 2001; © Edicions UPC, 2001.
8 Memoria externa 243
Para realizarlo se dispone de un circuito integrado de memoria EPROM de 32Kbytes y de un
circuito integrado de memoria RAM de 32Kbytes (figura 8.31).
EPROM
OE
CE
DO
D7
A0
A14
8
15
RAM
OE
CE
DO
D7
A0
A14
WE15
8
Fig. 8.31 Integrados de memoria utilizados
En la decodificación del mapa de memoria se ha utilizado el decodificador 74138 cuyo
esquema eléctrico y tabla de verdad aparecen en la figura 8.32.
G1 G2 C B A Y0 Y1 Y2 Y3 Y4 Y5 Y6 Y7
X H X X X H H H H H H H H
L X X X X H H H H H H H H
H L L L L L H H H H H H H
H L L L H H L H H H H H H
H L L H L H H L H H H H H
H L L H H H H H L H H H H
H L H L L H H H H L H H H
H L H L H H H H H H L H H
H L H H L H H H H H H L H
H L H H H H H H H H H H L
SelecciónHabilit.Entradas
Salidas
*
*G2=G2A+G2B
74LS138
Y0
Y1Y2Y3
Y4
Y5
Y6Y7
G2B
G2AG1
A
B
C
Fig. 8.32 Decodificador octal 74138
En la figura 8.33 está representado el esquema eléctrico correspondiente a la decodificación de
la memoria externa.
8XC251
P0
P2
WR
PSEN
LATCH8 BITS
ALE
RAM
D0,...,D7
A0,...,A14
OE
CE
WE
EPROM
D0,...,D7
A0,...,A12
OE
CE
A13
A14
A15
74138
Y0Y1
Y2Y3Y4
Y5Y6Y7
G2A
G2B
G1
A
B
C
0V
0V
5V
RD
PSEN
WR
RD
PSEN
RD
Fig. 8.33 Esquema eléctrico de la decodificación de memoria
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251244
Ejemplo 8.10 Decodificación de memoria de un sistema microprocesador con RD1, RD0=10
Se desea diseñar un sistema basado en el microcontrolador 8XC251Sx que se ajuste al mapa de
memoria de la figura 8.34. El microcontrolador está configurado para trabajar en modo no
paginado con 16 líneas de bus de direcciones (RD1, RD0 = 10). Para realizarlo se disponen de
integrados de memoria PROM de 4Kbytes e integrados de memoria RAM de 4K x 4 bits cuyos
esquemas eléctricos aparecen en la figura 8.35.
0000H
0FFFH
1000H
8FFFH
9000H
AFFFH
PROM
VACÍO
RAM
B000H
FFFFHVAC ÍO
Fig. 8.34 Mapa de memoria del sistema µC
Fig. 8.35 Esquema eléctrico de las memorias RAM y PROM
Para implementar los 4Kbytes de memoria PROM, de la dirección 0000H a la 0FFFH, sólo es
necesario un circuito integrado. En la tabla 8.10 se indican los valores de las líneas del bus de
direcciones que habilitan el integrado de memoria PROM.
Tabla 8.10 Direcciones asociadas a la memoria PROM
A15 A14 A13 A12 A11 . . . . . . .A0 Direcciones
0 0 0 0 0 . . . . . . . 0
0 0 0 0 X . . . . . . . X
0 0 0 0 1 . . . . . . . 1
0000H
......
0FFFH
Se accede a la memoria PROM cuando las cuatro líneas de mayor peso del bus de direcciones
valen 0 lógico, A15=A14=A13=A12=0; por tanto, la función que habilita o selecciona el
funcionamiento de la memoria PROM es:
CSPROM = A A A A15 14 13 12
Esta función se implementa mediante una puerta NOR de cuatro entradas (figura 8.36).
PSEN
Fig. 8.36 Decodificación de la memoria PROM
© Los autores, 2001; © Edicions UPC, 2001.
8 Memoria externa 245
La salida de esta puerta NOR estará conectada a una de las entradas de habilitación de la
memoria, CS2, mientras que la otra entrada de habilitación, CS1, está conectada a la señal de
lectura de memoria externa, /PSEN.
Por otra parte, para implementar la zona de memoria RAM de 8Kbytes se divide ésta en dos
zonas de 4Kbytes cada una (figura 8.37), ya que los integrados de memoria RAM disponibles
son de 4Kbytes.
RAM 1
RAM 2
9000 H
9FFF H
A000 H
AFFF H
Fig. 8.37 Ubicación de las memorias RAM
Para cubrir cada zona de memoria RAM (RAM 1 y RAM 2) necesitamos utilizar dos
integrados de memoria RAM de 4K x 4 bit: uno se encargará de almacenar los 4 bits de menor
peso del dato y el otro almacenará los 4 bits de mayor peso.
En la tabla 8.11 se indican los valores de las líneas del bus de direcciones que permiten el
acceso a la zona RAM 1.
Tabla 8.11 Direcciones asociadas a la memoria RAM 1
A15 A14 A13 A12 A11 . . . . . . .A0 Direcciones
1 0 0 1 0 . . . . . . . 0
0 0 0 0 X . . . . . . . X
1 0 0 1 1 . . . . . . . 1
9000 H
......
9FFF H
Vemos, pues, que para acceder a la zona de memoria RAM 1, las cuatro líneas de mayor peso
del bus de direcciones deben adquirir los siguientes valores: A15=1, A14=0, A13=0 y A12=1. Por
tanto, la función que selecciona la zona de memoria RAM 1 es:
CSRAM1 = A A A A15 14 13 12
En la tabla 8.12 se indican los valores del bus de direcciones que permiten acceder a la
memoria RAM 2.
Tabla 8.12 Direcciones asociadas a la memoria RAM 2
A15 A14 A13 A12 A11 . . . . . . .A0 Direcciones
1 0 1 0 0 . . . . . . . 0
0 0 0 0 X . . . . . . . X
1 0 1 0 1 . . . . . . . 1
A000 H
......
AFFF H
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251246
Para acceder a la zona de memoria RAM 2, las cuatro líneas de mayor peso del bus de
direcciones deben adquirir los siguientes valores: A15=1, A14=0, A13=1 y A12=0. La función que
selecciona la zona de memoria RAM 2 es:
CSRAM2 = A A A A15 14 13 12
Podemos implementar ambas funciones mediante puertas NAND de cuatro entradas y puertas
NOT. En la figura 8.38 aparece el esquema eléctrico de conexión de los integrados de memoria
RAM.
WR
PSEN
WR
PSENWR
PSEN
WR
PSEN
Fig. 8.38 Conexión de las memorias RAM
En la figura 8.39 aparece el esquema eléctrico del decodificador 74138 conectado
adecuadamente para generar las señales de habilitación de las memorias PROM y RAM.
74138Y0
Y1
Y2
Y3
Y4
Y5
Y6
Y7
G2A
G2B
G1
A
B
C
A12
A13
A15
0V
A14
5V
CSPROM
CSRAM2
CSRAM1
Fig. 8.39 Circuito de habilitación de las memorias
© Los autores, 2001; © Edicions UPC, 2001.
9 Puerto de comunicación serie 247
9 Puerto de comunicación serie
9.1 Introducción
Es frecuente que un sistema basado en microprocesador tenga que transmitir datos hacia otro sistema,
o hacia un periférico, o un terminal del sistema. La información se puede enviar en serie a través de
una simple línea, o canal de comunicación; o en paralelo, lo que requiere de un número considerable
de líneas. La transmisión serie es adecuada para largas distancias por su simplicidad, y la transmisión
paralelo es adecuada en distancias relativamente cortas, debido a que el número de líneas hace que sea
una solución con un elevado costo.
Para transmitir datos por la línea telefónica a largas distancias es conveniente emplear un módem, que
transforme las señales digitales a un formato analógico y que, así, haga ocupar un ancho de banda
menor, debido a que la transmisión digital directa resulta inapropiada por el enorme ancho de banda
que supone. No obstante, cuando las líneas de comunicación son propias del sistema, la transmisión se
puede hacer íntegramente en formato digital, para lo cual existen varios estándares de comunicación,
como el RS-232, el RS-422, el RS-485 y otros.
El formato de la información a transmitir en una comunicación serie puede ser de 7 ó 8 bits,
coincidiendo con los empleados por la tabla de caracteres ASCII. La transmisión puede ser síncrona o
asíncrona y puede efectuarse en varios sentidos: simplex, half-duplex y full-duplex.
Cuando la comunicación serie es síncrona se envía una señal de reloj en la transmisión que marca las
pautas de la comunicación. Esta señal se puede proporcionar a través de una línea adicional entre los
sistemas que se quiere comunicar, o bien, se puede extraer de alguna forma especifica de codificación:
en ese caso el receptor obtiene la señal de reloj de la propia señal recibida.
En el caso de que la comunicación sea asíncrona tanto el transmisor como el receptor deben
secuenciar la comunicación de acuerdo con una base de tiempos, pues la transmisión o la recepción
pueden ocurrir en cualquier momento. En este tipo de comunicación la inactividad en la transmisión
se indica mediante un nivel lógico alto.
El inicio de la transmisión de un carácter, en una comunicación serie asíncrona, se indica mediante
una transición brusca entre un nivel lógico alto y un nivel lógico bajo, a partir del cual se extrae cada
uno de los bits hacia la línea, con intervalos fijos de tiempo t (figura 9.1): los intervalos de tiempo en
la comunicación determinan la velocidad de transmisión en bits por segundo, bits/seg, o baudios. El
primer bit de la transmisión consiste en un bit de inicio (start), que es un cero lógico. Luego le siguen
los bits del dato, comenzando por el bit menos significativo y finalizando con un bit, o dos, de parada
(stop).
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251248
Al principio de establecer las bases de la comunicación serie, se utilizaban dos bits de stop por
cuestiones tecnológicas del momento. No obstante, en la actualidad es suficiente con emplear un solo
bit de stop. El bit de stop (figura 9.1) se indica manteniendo un nivel lógico alto durante un intervalo t,
tras el cual, puede procederse a transmitir el siguiente dato. Así, la inclusión del bit de start y el de
stop, en la comunicación serie asíncrona, resulta imprescindible para separar y distinguir los datos
transmitidos.
(LSB)
0
0 1 32 4 65
(MSB)
7
1 0 10 1 00
t
Bit
start
Bit
stop InactivoInactivo
Estado
Fig. 9.1
Generalmente, el dato en una comunicación serie es de 8 bits, a los que se puede añadir un noveno bit
de paridad, con el fin de detectar errores en la transmisión.
El sentido de la transmisión es simplex cuando se realiza en una única dirección, del emisor al
receptor, es haf-duplex cuando se puede realizar en ambas direcciones, emisor-receptor y receptor-
emisor (pero no en ambas direcciones simultáneamente), y full-duplex cuando se pueden enviar datos
en ambas direcciones de forma simultánea.
En la transmisión asíncrona se puede dar el caso de que un sistema sea lento a la hora de procesar los
datos que recibe, por lo que éste debe ser capaz de indicarle al transmisor su incapacidad de procesar
más datos y que, por tanto, se espere hasta una nueva transmisión. Este problema se suele solventar
mediante el protocolo XON/XOFF, en el cual se dispone de dos caracteres ASCII de control, DC1
(XON) y DC3 (XOFF), para detener y para reanudar la comunicación, respectivamente. Cuando el
receptor no puede procesar más datos envía un carácter XOFF al emisor, tras el cual el emisor deja de
transmitir hasta que recibe un carácter XON.
9.2 La comunicación serie en la MCS-51
El puerto de comunicación serie de la MCS-51 permite realizar transmisiones de datos en serie en los
modos síncrono y asíncrono. Para la transmisión síncrona dispone de un único modo de
funcionamiento, modo 0, y para la transmisión asíncrona full-duplex con velocidad de transmisión
programable dispone de los modos 1, 2 y 3 de funcionamiento. La generación de la velocidad de
transmisión del puerto serie se puede basar tanto en el Timer 1 como en el Timer 2, y utiliza sus
recursos para determinar la base de tiempos de la transmisión.
El puerto serie, además, tiene un sistema automático que es capaz de detectar un error en el bit de
stop. Además, el bit de paridad se puede emplear en la transmisión para poder detectar un error de 1
bit en la comunicación; para ello el bit de paridad se transmite con el dato como noveno bit de
transmisión. El puerto también tiene un sistema de reconocimiento de direcciones, el cual permite la
conexión de varios microcontroladores entre sí.
La determinación de la velocidad de transmisión depende del modo en que se esté operando. Por
ejemplo, para el Timer 1, en el modo 0 tan sólo se permite una velocidad de transmisión, mientras que
© Los autores, 2001; © Edicions UPC, 2001.
9 Puerto de comunicación serie 249
en el modo 2 pueden programarse dos velocidades de transmisión, y en los modos 1 y 3 se pueden
programar distintas velocidades de transmisión.
Los terminales asociados al puerto serie son TXD, terminal P3.1, y RXD, terminal P3.0. En el modo
0, el terminal TXD soporta la señal de reloj de la transmisión síncrona.
Los registros asociados al puerto de comunicación serie son SBUF, SCON en toda la familia MCS-51,
y los registros SADDR y SADEN para las versiones 8XC52/54/58, 8XC51FX y 87C51GB. El registro
SBUF, Serial Buffer, es el buffer del puerto serie, que almacena el dato recibido o enviado por el
puerto. El registro SCON, Serial Control (tabla 9.1), es el registro de control que permite programar
las características de funcionamiento del puerto. El registro SADDR se utiliza para definir la dirección
del microcontrolador que hace la función de esclavo, cuando éste se encuentra en un entorno de
comunicación multiprocesador. Finalmente, el registro SADEN especifica el byte de máscara para el
microcontrolador esclavo, en la comunicación multiprocesador.
Tabla 9.1 Registro SCON para la MCS-51
RITIRB8TB8RENSM2FE/SM0
(LSB)(MSB) Registro SCON
SM1SM0*
†
Bit Comentario
FE/SM0 Frame Error o bit 0 de selección de modo del puerto serie. Esta opción sólo es valida para las
versiones 8XC51Fx de la MCS-51. Este bit actúa como FE o SM0 según sea el estado del registro
SMOD0 (bit 6 del registro PCON), si SMOD0=1 actúa como FE y si SMOD=0 actúa como SM0.
El bit FE se activa a 1 lógico cuando se detecta un bit de stop inválido en la recepción de un dato.
Una vez activo, este bit no se borra por otros datos recibidos y se debe borrar por software.
SM0 es el bit de selección del puerto serie; su modo de funcionamiento se selecciona junto con SM1.
SM0 Bit 0 de selección de modo del puerto serie. Aparece con este formato en la MCS-51, excepto para
las versiones 8XC51Fx.. SM0 junto con SM1, determina el modo de funcionamiento del puerto serie.
SM1 Bit 1 de selección de modo del puerto serie. SM1 SM0 Modo 0 0 0
0 1 1
1 0 2
1 1 3
SM2 Bit 2 de modo del puerto serie. Permite habilitar, o no, la comunicación serie, en entornos
multiprocesador.
REN Bit de habilitación de la recepción. REN=1 habilita la recepción de un dato y REN=0 la inhabilita.
TB8 Bit noveno de transmisión. Es el décimo bit en la transmisión de un dato para los modos 2 y 3.
RB8 Bit noveno de recepción. Obtiene el valor del décimo bit del dato transmitido en los modos 2 y 3.
TI Bit de interrupción en transmisión. Se pone a 1 cuando finaliza la transmisión del dato. Debe
borrarse por software.
RI Bit de interrupción en recepción. Se pone a 1 cuando se recibe un dato. Debe borrarse por software.
* Para la MCS-51, excepto para la versión 8XC51Fx.† Sólo para la versión 8XC51Fx.
En el puerto de comunicación serie el registro SBUF está duplicado, de manera que uno de los
registros está conectado al terminal TXD y el otro registro está conectado al terminal RXD. Esta
duplicidad del registro SBUF permite poder transmitir y recibir datos simultáneamente (comunicación
full-duplex). Sin embargo, con el registro SBUF se trabaja de una manera sencilla, pues se trata a éste
como a un único registro: se transmite un dato al cargarlo en SBUF, y se lee un dato de SBUF cuando
éste se ha recibido.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251250
9.3 Modos de funcionamiento del puerto serie
El puerto de comunicación serie de la MCS-51 puede funcionar con cuatro modos distintos de
funcionamiento: modos 0, 1, 2 y 3. El modo 0 se emplea para la comunicación síncrona y los modos
1, 2 y 3 en la comunicación asíncrona.
En cualquiera de los modos de funcionamiento del puerto serie, la transmisión se efectúa en el
momento que se carga el registro SBUF con un dato mediante una instrucción de escritura. La
recepción de un dato debe habilitarse de antemano, poniendo a 1 lógico el bit REN del registro SCON
y poniendo a cero el bit RI. Cuando se recibe un dato el bit RI se pone a 1 lógico y activa el proceso
de interrupción del puerto, en el cual debe realizarse la lectura del registro SBUF por medio de la
rutina de RSI.
9.3.1 Modo 0. Modo síncrono
Este modo se determina mediante la puesta a cero lógico de los bits SM0 y SM1 del registro SCON.
La velocidad de transmisión de datos es de FOSC/12, donde FOSC es la frecuencia de reloj del
microcontrolador. El terminal TXD genera la señal de reloj que sincroniza la comunicación, y la
transmisión y recepción de datos se lleva a cabo a través del terminal RXD.
9.3.2 Modos 1, 2 y 3. Modos asíncronos
En los modos 1, 2 y 3 se pueden enviar datos a través de la línea TXD y recibirlos a través de la línea
RXD de forma simultánea (full-duplex). En la figura 9.2 se muestra la trama del dato en la transmisión
de estos modos.
D0 D1 D2 D3 D4 D5 D6 D7 TB8
Bit de start Dato de 8 bits
Noveno bit
(Sólo modos 2 y 3)
Bit de stop
Bit 1
Fig. 9.2 Trama de datos para los modos 1, 2 y 3
a) Modo 1
En el modo 1, la trama de datos está formada por 10 bits. El primer bit de la trama es el bit de start, a0 lógico, le siguen los 8 bits del dato, y finaliza con un décimo bit que consiste en el bit de stop, a 1
lógico.
La base de tiempos se puede generar, en este modo, por medio del Timer 1, del Timer 2 (en aquellas
versiones que disponen de tres Timers) o de ambos Timers. La velocidad de transmisión del puerto
serie, en baudios, depende del tiempo de desbordamiento de los Timers. Por defecto, la velocidad de
transmisión la establece el Timer 1, y viene dada en baudios por la fórmula siguiente:
32
deltorebasamien Frec2ón transmisiFrec.
X 1Timer.÷[ (9.1)
© Los autores, 2001; © Edicions UPC, 2001.
9 Puerto de comunicación serie 251
donde X puede valer 0 ó 1 lógico. Para la MCS-51, excepto las versiones 8XC51Fx, el bit X se
corresponde con el bit SMOD del registro PCON. Para las versiones 8XC51Fx el bit X se corresponde
con el bit SMOD1 del registro PCON. En realidad el bit SMOD y SMOD1 son el mismo bit con
distintos nombres, y corresponden al bit 7 del registro PCON.
En la comunicación serie se debe evitar que el Timer provoque una interrupción cada vez que llega a
desbordamiento; para ello debe de inhibirse la interrupción del Timer mediante el bit ET del registro
IE. El Timer 1 se suele configurar en el modo 2, como temporizador de 8 bits con autorrecarga (modo
2), aunque puede también configurarse en los modos 0, 2 y 3. Para este caso, la velocidad de
transmisión dependerá del valor cargado el registro TH1 del Timer 1:
] ∑1TH2561232
F2ón transmisiFrec. OSCX
�÷÷÷[ (9.2)
donde FOSC es la frecuencia de reloj del microcontrolador. El bit X, al igual que para la ecuación (9.1),
es el séptimo bit del registro PCON. La tabla 9.2 muestra distintas frecuencias de transmisión que se
pueden obtener con el Timer 1 en el modo 2 de funcionamiento.
Tabla 9.2 Timer 1 como generador de baudios para el modo 2 de funcionamiento
Timer 1Frecuencia(Baudios)
FrecuenciaOscilador
SMODC/T Valor recarga TH1
62.5 Kbaud (Max) 12.0 MHz 1 0 FFH
19.2 Kbaud 11.059 MHz 1 0 FDH
9.6 Kbaud 11.059 MHz 0 0 FDH
4.8 Kbaud 11.059 MHz 0 0 FAH
2.4 Kbaud 11.059 MHz 0 0 F4H
1.2 Kbaud 11.059 MHz 0 0 E8H
137.5 Baud 11.059 MHz 0 0 1DH
110.0 Baud 6.0 MHz 0 0 72H
b) Modo 2
En el modo 2, la trama de bits del puerto serie está compuesta de 11 bits. El primer bit es el bit de
start, le siguen los 8 bits del dato más un noveno bit definible por el usuario, y termina con un bit de
stop. El noveno bit del dato transmitido se corresponde con el estado del bit TB8 del registro SCON.
En la recepción, este noveno bit se ubica en el bit RB8 del registro SCON.
Para transmitir en este modo se debe poner el noveno bit a transmitir en el bit TR8, antes de realizar la
escritura del dato en el registro SBUF. La recepción se debe habilitar antes que se produzca, poniendo
para ello el bit REN a 1 lógico y el bit RI a 0 lógico.
En el modo 2 sólo se permiten dos velocidades de comunicación para el puerto serie, dependiendo del
valor del bit X:
64
F2ón transmisiFrec. OSCX
÷[ (9.3)
El bit X tiene la misma correspondencia que la definida para el resto de modos de funcionamiento.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251252
c) Modo 3
El modo 3 del puerto serie es similar al modo 2, con la única diferencia que la velocidad de la
comunicación del puerto serie se obtiene de la misma manera que en el modo 1.
9.3.3 El Timer 2 como base para el puerto serie
El Timer 2 tiene un modo de funcionamiento específico utilizado para fijar la velocidad de
comunicación de datos por el puerto serie, Baud Rate Generator Mode (figura 9.3). Para seleccionar
este modo se deben programar adecuadamente los bits RCLCK y TCLCK del registro T2CON, como
se muestra en la tabla 9.3.
θ 2
TH2 TL2
T2
XTAL1
C/T2
Petición de
interrupciónT2EX
TR2
RCAP2H RCAP2L
EXF2
EXEN2
θ2Rebasamiento
del Timer 1
X
θ16
θ16
RX
Clock
TX
Clock
RCLCK
TCLCK
1
0
0
1
0
1
1
0
X=SMOD para la MCS-51, excepto para la versión 8XC51Fx.X=SMOD1 para la versión 8XC51Fx.
Fig. 9.3 Diagrama de bloques del Timer 2 funcionando en el modo generador de Baud Rate
Tabla 9.3 Selección del Timer 2 como generador de baudios
RCLCK TCLCK Generador de baudios enrecepción
Generador de baudios entransmisión
0 0 Timer 1 Timer 10 1 Timer 1 Timer 21 0 Timer 2 Timer 11 1 Timer 2 Timer 2
Cuando el Timer 2 se selecciona como generador de baudios funciona de forma similar al modo
autorrecarga. Los registros TH2 y TL2 se recargan con el valor de los registros RCAP2H y RCAP2L,
en cada desbordamiento. La velocidad de comunicación depende del valor puesto en estos registros:
( )] ∑L2RCAPH2RCAP6553632
Fón transmisiFrec. OSC
,�÷[ (9.4)
En la figura 9.3 se muestra el diagrama de bloques del Timer 2 configurado en modo generador de
© Los autores, 2001; © Edicions UPC, 2001.
9 Puerto de comunicación serie 253
baudios. En la tabla 9.4 se indican las distintas velocidades de comunicación y el valor a cargar en los
registros RCAP2H y RCAP2L para conseguir distintas velocidades de transmisión.
Tabla 9.4 Timer 2 como generador de baudios para los modos 1 y 3 del puerto serie
Baudios Frecuencia oscilador RCAP2H RCAP2L375.0 Kbaud 12.0 MHz FFH FFH
9.6 Kbaud 12.0 MHz FFH D9H
4.8 Kbaud 12.0 MHz FFH B2H
2.4 Kbaud 12.0 MHz FFH 64H
1.2 Kbaud 12.0 MHz FEH C8H
300.0 baud 12.0 MHz FBH 1EH
110.0 baud 12.0 MHz F2H AFH
300.0 baud 6.0 MHz FDH 8FH
110.0 baud 6.0 MHz F9H 57H
9.4 Detección de errores
En las versiones 8XC51Fx es posible detectar errores en la recepción del bit de stop para los modos de
trabajo 1, 2 y 3, para lo cual se debe poner a 1 lógico el bit SMOD0 del registro PCON.
Con esta opción habilitada, el puerto serie comprueba el bit de stop de cada dato recibido y si es
erróneo se pone a 1, de manera automática, el bit FE del registro SCON. En consecuencia, para
emplear este recurso, se debe examinar el estado del bit FE cada vez que se recibe un dato. El bit FE
no es modificado por datos posteriores recibidos en el puerto serie, y se debe borrar por software, por
lo que se deberá incluir una instrucción que lo borre cada vez que se active.
Ejemplo 9.1 Control de una impresora de 40 columnas
En los equipos de tipo comercial, como una balanza electrónica o un terminal punto de venta,
se utilizan impresoras de 40 columnas para la impresión del tiquet de la compra del usuario.
Estas impresoras se conectan al sistema basado en microcontrolador mediante el bus RS-232C,
que es un bus de comunicación para distancias cortas y velocidades de comunicación
moderadas.
Con el bus RS-232C sólo se pueden conectar un emisor y un receptor, y las velocidades de
comunicación más comunes son: 300, 1.200, 2.400, 4.800, 9.600 y 19.200. Los niveles de
tensión del bus son bipolares, el transmisor debe generar un nivel de tensión entre -5 y -15V
para un 1 lógico, y entre +5 y +15V para un 0 lógico. El receptor responde con una tensión más
negativa que -3V para un 1 lógico, y con una tensión más positiva que +3V para un 0 lógico.
Para realizar la interfaz con el bus existen distintos circuitos integrados de interfaz entre niveles
TTL y RS-232, y viceversa. Los circuitos integrados más comunes son el MC1488, que tiene
cuatro transmisores, y el MC1489A, que tiene cuatro receptores. Estos circuitos integrados los
realizan distintos fabricantes y son de bajo coste. El MC1488 necesita una tensión de
alimentación entre ≅9V y ≅15V. Para niveles CMOS se pueden usar el DS14C88 y el
DS14C89A de National Semiconductor, para la interfaz entre CMOS y RS-232, y viceversa.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251254
El número mínimo de señales con el que se puede realizar la comunicación bidireccional entre
dos equipos es: TXD para la transmisión, RXD para la recepción y una línea de masa (figura
9.4).
MC1488
MC1489
MC1489
MC1488
TXD
RXD TXD
RXD
Equipo A Equipo B
Fig. 9.4 Conexión de dos equipos distantes mediante RS-232
En este ejemplo se desea conectar una impresora de 40 columnas a un 87C51 mediante el bus
RS-232 (figura 9.5). El microcontrolador se utiliza en una aplicación de etiquetaje, donde se
imprime un número asignado al producto y un texto determinado según el tipo de producto.
Las etiquetas son autoadhesivas y se pegan al producto mediante un aplicador automático.
P2.0P2.1
P2.5
6
Tipo de producto
TXD
RXD
/INT0
87C51
MC1488
MC1489
Impresora
RXD
TXD
GND
RS-232
Entrada de producto
Fig. 9.5 Conexión de una impresora vía RS-232
El control de la impresora se realiza mediante caracteres ASCII reservados para ello. El
microcontrolador iniciará la comunicación con la impresora enviándole el carácter ASCII STX
Start of text, que se corresponde con el número hexadecimal 02H. Tras este carácter se le puede
enviar un carácter de comando como LF, Line feed, (0AH); CAN, Cancel, (18H); ESC,
Escape, (1BH); carácter de impresión en negrita, cursiva, etc. Tras este comando, se le envía el
texto que se quiere imprimir en ASCII, y por último el comando de impresión CR, Carriagereturn, (0DH), por lo que se imprimirá el texto transmitido.
En este ejemplo se trata tan sólo de imprimir el texto “PRODUCTO Nº:” seguido de cuatro
cifras que identifican el tipo de producto. La aplicación tiene un interruptor de final de carrera
como sensor de la llegada del producto conectado a la entrada de interrupción /INT0. El
© Los autores, 2001; © Edicions UPC, 2001.
9 Puerto de comunicación serie 255
interruptor proporciona un 0 lógico cuando hay un producto a etiquetar y un 1 lógico cuando
no hay producto. La empresa tiene 64 tipos de productos diferentes, codificados con cuatro
cifras cada uno. Los códigos de estos productos se han almacenado en la memoria de
programas. El microcontrolador recibe en el puerto P2 seis líneas de entrada que identifican el
tipo de producto, al mismo tiempo que se activa el interruptor final de carrera conectado a
/INT0.
El programa de este ejemplo se muestra a continuación
;**************************************************************************
; Programa para la comunicación y control de una impresora de 40 columnas
;**************************************************************************
ORG 0H ; Vectorización
LJMP Inicio
ORG 03H
LJMP RSI_INT0
ORG 023H ;Vectorización del puerto de comunicación serie
LJMP RSI_RS
;**************************************************************************
; Rutina de Inicio
;**************************************************************************
Inicio: MOV SP, #30H ;Sitúa SP en la 30H
SETB IT0 ;Interrupción INT0 por flanco descendente
SETB EX0 ;Habilita interrupción INT0
SETB ES ;Habilita interrupción del puerto de comunicación serie
SETB SM1 ;Configura la comunicación serie en el modo 1
SETB REN ;Habilita la recepción de un dato por el puerto serie
MOV TMOD, #20H ;Timer 1 en Modo 2, GATE=0 y C/T=0
MOV TL1, #0FDH ;Valor de TL1, para velocidad de 9600 baudios
MOV TH1, #0FDH ;Valor de recarga de Timer 1, para velocidad de 9600 baudios
SETB EA ;Habilita bit de interrupción general
SETB TR1 ;Pone marcha el Timer 1 (Genera la base de tiempos de la RS-232).
MOV R6, #01H ;R6 se utiliza para indicar que se puede transmitir
LJMP Principal ;Ir hacia rutina principal
;**************************************************************************
; Rutina de servicio de INT0
;**************************************************************************
RSI_INT0: MOV R7, #01 ;R7=1 para indicar inicio de transmisión
RETI
;**************************************************************************
; Rutina de servicio del puerto serie
;**************************************************************************
RSI_RS: JNB TI, Recibe ;Si no interrumpe TI, entonces es RI
CLR TI ;Borra bit TI
RETI
Recibe: CLR RI ;Borra bit RI
RETI
;***************************************************************************
; Rutina Principal (R7 se emplea como indicador de final de conversión. R7=1 Conversión finalizada)
;***************************************************************************
Principal: CJNE R7, #01, Principal ;Bucle de espera a que R7 sea igual a 01H
MOV R7, #0 ;Borra R6
MOV R1, P2 ;Lee P2 para saber el tipo de producto
MOV A, R1
ANL A, #3FH ;Máscara con 3FH
MOV R1, A
ACALL Imprime_cod ;Realiza la lectura del A/D
SJMP Principal ;Bucle infinito
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251256
;**************************************************************************
; Subrutina de Impresión
;**************************************************************************
Imprime_cod: MOV R5, #14 ;Número de caracteres del texto
MOV R0, #10H ;Pone dirección 10H en puntero
Imp_buc: CLR C ;Borra acarreo
MOV A, #14 ;Pone dato 14 en A
SUBB A, R5 ;Resta de 14-R5, contador de 0 a 14.
LCALL Tab_tex ;Toma un caracter del texto
MOV A, @R0 ;Pone caracter leído en memoria interna
INC R0 ;Incrementa puntero
DJNZ R5, Imp_buc ;Realiza bucle hasta final de texto (14 caracteres)
Lee_cod: MOV A, R1 ;Situado el texto, falta situar código en la memoria
MOV B, #2 ;Multiplica A por 2
MUL AB
PUSH A ;Guarda A en la pila
LCALL Tabla_cod ;Lee byte alto del código
LCALL Bin_ASCII ;Llama a la rutina de conversión de binario a ASCII
MOV @R0, B ;Guarda B en la memoria
INC R0 ;Incrementa puntero
MOV @R0, A ;Guarda A en la memoria
INC R0 ;Incrementa puntero
POP A ;Recupera la situación de producto en la tabla
INC A ;Posición de byte bajo del código en la tabla
LCALL Tabla_cod ;Lee byte bajo del código
LCALL Bin_ASCII ;Llama a la rutina de conversión de binario a ASCII
MOV @R0, B ;Guarda B en la memoria
INC R0 ;Incrementa puntero
MOV @R0, A ;Guarda A en la memoria
LCALL Print ;Salta a la subrutina de impresión
LJMP Principal
Tab_text: INC A ;Tabla con el texto a imprimir
MOVC A, @A+PC
RET
DB “ PRODUCTO Nº: ”Tabla_cod: INC A ;Tabla con los códigos de los productos
MOVC A, @A+PC ;Lee tabla de códigos
RET
DB 10H, 15H ;Código del producto nº 1DB 25H, 46H ;Código del producto nº 2DB 1AH, 1FH ;Código del producto nº 3DB 78H, 22H ;Código del producto nº 1........... ; ....................
........... ; ....................
DB 99H, 56H ;Código del producto nº 64
Print: MOV R0, #10H ;Pone puntero con dirección de buffer de impresión
MOV R5, #18 ;Pone tamaño de caracteres a imprimir
MOV A, #02H ;Pone caracter STX en A
LCALL Transmite ;Transmite dato
Print_buc: MOV A, @R0 ;Lee texto del buffer de memoria
LCALL Transmite ;Transmite dato
INC R0 ;Incrementa puntero
DJNZ R5, Print_buc ;Realiza bucle hasta enviar el buffer entero
MOV A, #0DH ;Pone caracter CR en A
LCALL Transmite ;Transmite caracter
LJMP Principal ;Regresa al bucle principal
Bin_ASCII: PUSH A ;Guarda A en la pila
ANL A, #0F0H ;Máscara. Borra los 4 bits bajos, mantiene los altos
SWAP A
LCALL Tab_BinASCII
MOV B, A
POP A ;Recupera A de la pila
© Los autores, 2001; © Edicions UPC, 2001.
9 Puerto de comunicación serie 257
ANL A, #0FH ;Máscara. Borra los 4 bit bajos
LCALL Tab_BinACSII
RET
Transmite: MOV SBUF, A ;Transmite dato contenido en A
RET
Tab_BinASCII: INC A ;Tabla de conversión de binario a ASCII
MOVC A, @A+PC
RET
DB 30H, 31H, 32H, 33H, 34H, 35H, 36H, 37H
DB 38H, 39H, 41H, 42H, 43H, 44H, 45H, 46H
En este programa se utiliza el registro R7 como indicativo de que ha entrado un producto. La
transmisión consiste en ir colocando los datos contenidos a partir de la posición 10H de
memoria interna que se utiliza como buffer de datos para la transmisión. En total se transmiten
cada vez 18 caracteres: 14 caracteres correspondientes al texto y 4 caracteres correspondientes
al código de cuatro cifras del producto.
El código del producto se ha situado en la subrutina “Tab_cod” y está formado por dos bytes.
En el programa primero se lee el byte alto del código en la tabla, que se desglosa en dos bytes
en formato ASCII: el primero corresponde a los 4 bits altos y el otro a los 4 bits bajos. Luego
se lee el byte bajo del código, que se convierte a ASCII de la misma manera que el primer byte.
A la impresora se transmite primero el carácter STX (02H), seguido de 18 bytes, almacenados
en el buffer de memoria a partir de la posición 10H y que corresponden al texto y al código de
producto, y por último el carácter CR (0DH), que hace que se impriman los datos transmitidos.
Para realizar la comunicación se ha seleccionado una velocidad de 9.600 baudios; para ello se
configura el puerto serie en el modo 1, en el que se transmiten 10 bits: 1 bit de start, 8 bits del
dato y 1 bit de stop. El Timer 1 del microcontrolador se utiliza como base de tiempos para la
transmisión, por lo que debe estar configurado en el modo 2 de 8 bits con autorrecarga, con el
bit C/T a 0 lógico, con el bit SMOD a 0 lógico, con el valor FDH de recarga en el registro
TH1, y con una frecuencia de reloj de 11.059MHz.
Ejemplo 9.2 Comunicación multipunto mediante RS-485
En la industria de la alimentación es frecuente tener múltiples cámaras frigoríficas en distintos
puntos de una nave industrial, o bien dentro de una misma área comercial. La regulación y la
monitorización de la temperatura en cada una de las cámaras frigoríficas es de suma
importancia, especialmente en el sector de los congelados, donde es imprescindible controlar
en todo momento el estado de conservación y la calidad de un producto.
En la figura 9.6 se propone una red de comunicación basada en la norma RS-485, para realizar
el control y la monitorización entre un ordenador central que hace la función de “maestro” y las
cámaras frigoríficas que hacen la función de “esclavos”. En esta aplicación se ha escogido la
norma RS-485 porque es un sistema de transmisión diferencial que permite la comunicación
bidireccional de hasta 32 equipos en un bus de datos común, permite la transmisión a gran
distancia y a gran velocidad, y los emisores deben incorporar autoprotección contra la
sobrecarga de acceso (es decir, la situación de tener múltiples emisores intentando acceder al
mismo tiempo a la línea de transmisión). Las principales características de la RS-485 son:
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251258
- La máxima longitud de cable es de 1.200 metros.
- La velocidad máxima de transmisión es de 10Mbits/seg.
- Impedancia de entrada del receptor de 12k4.
- Margen de modo común de la entrada del receptor de -7V a +12V.
- Sensibilidad de la entrada diferencial de ≅200mV en un margen de modo
común de -7V a +12V.
La interfaz con el bus RS-485 se implementa con el circuito integrado DS3695 o el DS75176
de National Semiconductor, que tiene un transmisor y un receptor diferencial, cuyo estado se
controla con las entradas DE y /RE, respectivamente.
Cada una de las cámaras frigoríficas tiene un circuito electrónico formado por un
microcontrolador 87C51, cuatro dígitos de siete segmentos donde se visualiza la temperatura
en grados centígrados de la cámara, un DS1620 de Dallas Semiconductor que hace de sensor
de temperatura y de acondicionador de señal, y un DS3695 para la interfaz RS-485 (figura 9.7).
DE /RE
+
_RO
DID
R
DE/RE+
_ RO
DID
R
DE/RE+
_ RO
DID
R
DE/RE+
_ RO
DID
R
RT
RT
Dirección
TXD
RXD
Maestro
Dirección
Dirección
Dirección
Esclavo 1
Esclavo 2
Esclavo N
TXD
TXD
TXD
RXD
RXD
RXDNodo 1
Nodo 2
Nodo N
Nodo 0
DS3695
DS3695
DS3695
DS3695
Fig. 9.6 Red de comunicación basada en la RS-485
Para realizar la comunicación en la red se debe establecer un protocolo, en el que se definen
una serie de reglas con las que se gestionará la comunicación entre las cámaras frigoríficas y el
© Los autores, 2001; © Edicions UPC, 2001.
9 Puerto de comunicación serie 259
equipo maestro. Cada una de las conexiones en la red RS-485 se denomina nodo. Cada nodo
puede, mediante un protocolo, enviar o recibir mensajes o bloques de datos de la red.
RXD
TXDRS-485
DS3695
87C51
DS1620
P1.1 DE
/REDirección
Fig. 9.7 Componentes del circuito de una cámara frigorífica
Las funciones que deberá realizar el circuito electrónico de cada una de las cámaras son
monitorizar la temperatura de la cámara en el visualizador de cuatro dígitos de siete segmentos
y transmitir la temperatura de la cámara al equipo maestro cada vez que éste se lo pida.
Para comprobar el estado de la red y de la interfaz con cada nodo, el equipo maestro enviará un
comando y un dato a cada uno de los esclavos, lo que forzará al esclavo a transmitir el dato
recibido al maestro. De esta forma el equipo maestro puede comprobar si hay alguna anomalíaen la red o en la interfaz de un nodo determinado.
La red estará formada por un equipo central que hará de maestro y por veinticinco esclavos. El
protocolo estará formado por tres bytes. El primer byte se corresponderá con el número del
nodo destino de la transmisión. A cada nodo se le asignará un número: el nodo 0 se
corresponderá con el nodo maestro y los nodos esclavos se numerarán consecutivamente como
nodo 1, nodo 2, …, nodo 25. El segundo byte del protocolo será el número del nodo que
origina el mensaje. Y, por último, el tercer byte se corresponderá con un comando ejecutable
por el nodo esclavo, que podrá ser el carácter ASCII DC1 (11H) o DC2 (12H). El comando
DC1 indicará al nodo esclavo que debe transmitir los datos correspondientes a la temperatura al
nodo maestro, y el comando DC2 indicará que se va a hacer un chequeo de la línea por parte
del nodo maestro.
La lectura de la temperatura en cada microcontrolador estará almacenada en las posiciones 20H
y 21H de la memoria interna. La posición 20H contendrá el byte de menor peso y la posición
21H el byte de mayor peso. En consecuencia, cuando un nodo esclavo reciba el comando DC1,
le transmitirá al nodo maestro estos dos bytes correspondientes a la temperatura de la cámara
frigorífica. El nodo esclavo, en este caso, transmitirá un primer byte correspondiente al número
del nodo maestro (00H), un segundo byte que corresponde con el número del nodo esclavo y
los dos bytes correspondientes al valor de la temperatura de la cámara.
En el caso que un nodo esclavo reciba el comando DC2 de chequeo de la red, éste pasará a la
espera de un dato concreto que le debe transmitir el nodo maestro. Para ello, el nodo maestro
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251260
transmite un primer byte correspondiente al número del esclavo y un segundo byte que consiste
en la constante AAH.
A continuación se muestra el programa que realiza la comunicación de un microcontrolador
87C51 como el nodo esclavo número 2 de la red. En este programa no se considera el control
del DS1620 ni la visualización en los cuatro dígitos de siete segmentos de la figura 9.7. La
velocidad de comunicación se ha configurado para 19.200 baudios, y se ha programado el
puerto serie en el modo asíncrono 1, al igual que en el ejemplo anterior. El Timer 1 estáconfigurado en el modo 2 de 8 bits con autorrecarga, con el bit C/T a 0 lógico, con el bit
SMOD a 1 lógico, con el valor FDH de recarga en el registro TH1 y con 11.059MHz de
frecuencia de reloj.
;**************************************************************************
; Programa para la comunicación del bus RS-485 del segundo módulo esclavo
;**************************************************************************
; Declaración de constantes y de variables
;**************************************************************************
ID_MOD EQU #02H ;Número de identificación de este módulo
ID_Master EQU #00H ;Número de identificación del maestro
DC1 EQU #11H ;Valor del comando DC1
DC2 EQU #12H ;Valor del comando DC2
Orden_in EQU 10H ;Variable que indica el nº de byte recibido
Haz_Eco EQU 13H ;Variable que indica el la acción de eco
Dato_Eco EQU 14H ;Variable que contendrá el dato enviado por el maestro
Temp_bajo EQU 20H ;Variable que contiene el byte bajo de la temperatura
Temp_alto EQU 21H ;Variable que contiene el byte bajo de la temperatura
;**************************************************************************
; ; Rutina de Vectorización
;**************************************************************************
ORG 0H
LJMP Inicio
ORG 023H ;Vectorización del puerto de comunicación serie
LJMP RSI_RS
;**************************************************************************
; Rutina de Inicio (Configuración de la comunicación a 19200 baudios)
;**************************************************************************
Inicio: MOV Orden_in, #0 ;Pone a 0
MOV Orden_out, #0 ;Pone a 0
MOV Orden_tx, #0 ;Pone a 0
MOV SP, #30H ;Reubica el Stack Pointer
CLR P1.1 ;Establece el sentido RS-485 en recepción
SETB ES ;Habilita interrupción del puerto de comunicación serie
ORL PCON, #80H ;Pone el bit 7 de PCON, bit SMOD, a 1 lógico
SETB SM1 ;Configura la comunicación serie en el modo 1
SETB REN ;Habilita la recepción de un dato por el puerto serie
MOV TMOD, #20H ;Timer 1 en Modo 2, GATE=0 y C/T=0
MOV TL1, #0FDH ;Valor de TL1, para velocidad de 19200 baudios
MOV TH1, #0FDH ;Valor de recarga de Timer 1, para velocidad de 19200 baudios
SETB EA ;Habilita bit de interrupción general
SETB TR1 ;Pone marcha el Timer 1 (Genera la base de tiempos de la RS-485)
LJMP Principal ;Ir hacia rutina principal
;**************************************************************************
; Rutina de servicio del puerto serie
;**************************************************************************
RSI_RS: JNB TI, Recibe ;Si no interrumpe TI, entonces es RI
CLR TI ;Borra bit TI
RETI
© Los autores, 2001; © Edicions UPC, 2001.
9 Puerto de comunicación serie 261
Recibe: MOV A, SBUF ;Lee dato recibido
CJNE Orden_in, #0, Es_byte2 ;Identifíca si se recibe el 1º, el 2º o el 3º byte
SJMP S_byte1
Es_byte2: CJNE Orden_in, #01, S_byte3 ;Si no es el byte1 ni el byte2, entonces es el byte3
SJMP S_byte2
S_byte1: CJNE A, ID_MOD, Salir ;Comprueba que sea este módulo, si no es sale
INC Orden_in ;Incrementa contador. Pasa a la espera del siguiente byte
SJMP Salir
S_byte2: CJNE A, ID_Master, Salir ;Comprueba que le envía el mensaje el mod. maestro
INC Orden_in ;Incrementa contador. Pasa a la espera del siguiente byte
SJMP Salir
S_byte3: CJNE A, DC1, Es_DC2 ;Comprueba que sea el comando DC1 o DC2
MOV Orden_in, #0 ;Inicializa contador
MOV Orden_tx, #01H ;Da la orden de transmitir la temperatura de la cámara
SJMP Salir
Es_DC2: CJNE A, DC2, Es_Eco ;Comprueba que sea el comando DC2. Si no, aborta
MOV Orden_in, #0 ;Inicializa contador
MOV Haz_Eco, #01H ;Activa el eco. Pasa a la espera del caracter de eco
SJMP Salir
Es_Eco: CJNE Haz_Eco, #01H, Abortar ;Aborta la recepción
MOV Dato_Eco, A ;Guarda dato recibido en memoria, para transmitirlo
MOV Orden_tx, #02H ;Da la orden de transmitir el dato recibido
Abortar: MOV Haz_Eco, #0 ;Borra indicador de eco
MOV Orden_in, #0 ;Inicializa contador
Salir: CLR RI
RETI
;***************************************************************************
; Rutina Principal
;***************************************************************************
Principal: CJNE Orden_tx, #0, Es_trans_1 ;Comprueba si se debe transmitir la
SJMP Principal ;temperatura
Es_trans_1: CJNE Orden_tx, #01H, Es_trans_2 ;Comprueba si debe transmitir Eco
MOV Orden_tx, #0 ;Borra variable
LCALL Trans_temp ;Transmite la temperatura
SJMP Principal
Es_trans_2: MOV Orden_tx, #0 ;Borra variable
LCALL Trans_Eco ;Transmite el dato recibido
SJMP Principal
;***************************************************************************
; Subrutina “Trans_temp” para la transmisión de la temperatura
;***************************************************************************
Trans_Temp: MOV A, ID_Master ;Carga nº de identificación del maestro
LCALL Transmite
MOV A, ID_MOD ;Carga el nº de identificación de este módulo
LCALL Transmite
MOV A, Temp_alto ;Carga el byte alto de la temperatura leída por el .C
LCALL Transmite
MOV A, Temp_bajo ;Carga el byte bajo de la temperatura leída por el .C
LCALL Transmite
RET
;***************************************************************************
; Subrutina “Trans_Eco” para Eco con el dato enviado por el .C
;***************************************************************************
Trans_Eco: MOV A, ID_Master ;Carga nº de identificación del maestro
LCALL Transmite
MOV A, ID_MOD ;Carga el nº de identificación de este módulo
LCALL Transmite
MOV A, Dato_Eco ;Carga el dato a enviar de Eco
LCALL Transmite
RET
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251262
Transmite: SETB P1.1 ;Establece el sentido RS-485 en transmisión
MOV SBUF, A ;Transmite dato contenido en A
CLR P1.1 ;Establece el sentido RS-485 en recepción
RET
La rutina principal está continuamente pendiente de la operación con el nodo maestro, que
viene indicada por la variable Orden_tx. Esta variable puede valer 01H cuando se debe
transmitir la temperatura leída por el microcontrolador, o bien 02H cuando debe transmitir el
dato recibido por parte del nodo maestro.
Las entradas DE y /RE del DS3695 determinan el sentido de la comunicación con la red, y
ambas están conectadas a la patilla P1.1 (figura 9.7), de manera que cuando P1.1 está a 0
lógico el DS3596 está configurado para recibir datos y a 1 lógico para transmitir datos. El
terminal P1.1 establece el sentido de la comunicación.
En la rutina de RSI del puerto serie se utiliza la variable Orden_in como contador de 0 a 2 que
indica el orden del byte recibido por parte del nodo maestro. El protocolo establece que, para
dirigirse al microcontrolador del ejemplo (nodo 2), el nodo maestro debe transmitir el dato 02H
(destino del mensaje), el dato 00H (origen del mensaje) y un comando de orden que puede ser
DC1 o DC2. En el caso de recibir el carácter DC2, la rutina de RSI inicializa la variable
Orden_in y pasa a la espera del dato que se debe transmitir como eco. En el caso de que el
destino de la comunicación no sea este nodo, o bien que el origen de la comunicación no sea el
nodo maestro, el proceso obviará los datos recibidos, y pasará a la espera de un mensaje del
nodo maestro.
9.5 La comunicación serie en la MCS-251
El puerto de comunicación serie permite realizar comunicaciones en serie en modo síncrono y
asíncrono. En concreto dispone de un modo de operación síncrono, el modo 0, y de tres modos de
comunicación asíncronos full-duplex, los modos 1, 2 y 3, con velocidades de transmisión
programables. Asimismo, implementa un sistema de detección de errores y de reconocimiento de
direcciones, que permite la comunicación, a través del canal serie, entre varios microcontroladores.
En el modo 0, sólo se permite una velocidad de transmisión, mientras que en el modo 2 es posible
programar dos velocidades de transmisión. En cambio, en los modos 1 y 3 se pueden programar
distintas velocidades de transmisión, generadas por los Timers 1 y 2.
En la tabla 9.5 se muestran las señales asociadas al puerto de comunicación serie. Básicamente
consiste en dos pines: TXD para transmitir datos y RXD para recibir datos.
Tabla 9.5 Señales asociadas al puerto de comunicación serie
Nombre pin Tipo Descripción UbicaciónTXD O Transmisión de datos. En modo 0, TXD genera la señal de reloj que
sincroniza la transmisión. En los modos 1, 2 y 3, es el pin de transmisión
de datos serie.
P3.1
RXD I/O Recepción de datos. En modo 0, RXD transmite y recibe los datos en
serie. En los modos 1, 2 y 3, es el pin de recepción de datos en serie.
P3.0
© Los autores, 2001; © Edicions UPC, 2001.
9 Puerto de comunicación serie 263
En la tabla 9.6 se muestran los registros asociados al puerto de comunicación serie. El registro SBUF
almacena el dato recibido o enviado por el puerto serie. El registro SCON permite programar las
características de funcionamiento del puerto serie y los registros SADDR y SADEN están
relacionados con la configuración de la dirección del puerto serie en el caso de que se trabaje en
entornos multiprocesador.
Tabla 9.6 Registros asociados al puerto de comunicación serie
Mnemónico Descripción DirecciónSBUF Buffer del puerto serie. Este registro está compuesto por dos registros: en uno se
carga el dato recibido y en el otro se almacena el dato enviado.
S:099H
SCON Registro de control del puerto serie. Este registro permite programar las
prestaciones de funcionamiento del puerto serie.
S:098H
SADDR Dirección del puerto serie. Define la dirección individual del dispositivo esclavo. S:0A8H
SADEN Habilitación de la dirección del puerto serie. Especifica el byte de máscara que se
utiliza para definir la dirección de un dispositivo esclavo.
S:0B8H
En la tabla 9.7 se indica brevemente la función de cada uno de los bits del registro SCON.
Tabla 9.7 Registro de control del puerto de comunicación serie
SCON Dirección: S:098H Valor de Reset: 0000 0000b
b7 b6 b5 b4 b3 b2 b1 b0
FE/SM0 SM1 SM2 REN TB8 RB8 TI RI
Bit Mnemónico Función7 FE
SM0
Bit de Frame Error. Para seleccionar esta opción de funcionamiento se debe colocar a
1 lógico el bit SMOD0 del registro PCON. En este caso, el bit FE se pone a 1 cuando
se detecta un error en el bit de stop del dato recibido.
Bit 0 del modo del puerto serie. Para seleccionar esta opción se debe poner a 0 el bit
SMOD0. Los bits SM0 y SM1 permiten seleccionar el modo de trabajo del puerto.
6 SM1 Bit 1 de modo del puerto serie. Programando adecuadamente los bits SM0 y SM1 se
puede seleccionar el modo de trabajo del puerto serie.
SM0 SM1 Modo
0 0 0
0 1 1
1 0 2
1 1 3
5 SM2 Bit 2 de modo del Puerto Serie. Este bit permite habilitar, o no, la comunicación serie
en entornos multiprocesador.
4 REN Bit de habilitación de recepción. Este bit se pone a 1 lógico para habilitar la
recepción, y se pone a 0 lógico, para habilitar la transmisión.
3 TB8 Bit 8 del dato transmitido.En los modos 2 y 3, se escribe en este bit el valor del noveno bit que se transmite.
2 RB8 Bit 8 del dato recibido. En el modo 1 este bit adquiere, automáticamente, el valor del
bit de stop recibido, si SM2=0. En los modos 2 y 3, este bit adquiere automáticamente
el valor del noveno bit recibido si SM2=0.
1 TI Flag de interrupción en transmisión. Este bit se pone a 1 lógico cuando finaliza la
transmisión del dato. Se debe borrar por programa.
0 RI Flag de interrupción en recepción. Este bit se pone a 1 lógico después de recibir un
dato. Debe ponerse a cero por programa.
En la figura 9.8 se observa el esquema del puerto de comunicación serie. Este periférico incorpora un
registro denominado SBUF que almacena el dato a transmitir o el dato recibido. Físicamente este
registro está compuesto por dos registros distintos, un registro conectado al pin TXD, que almacena el
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251264
dato a transmitir, y otro registro conectado al pin RXD, a través de un registro de desplazamiento, que
almacena el dato recibido por el puerto serie. Esta duplicidad de registros permite poder transmitir y
recibir datos al mismo tiempo (comunicación full-duplex).
SBUF
transmisión
SBUF
recepción
TxD
RxDSBUF
Registro de
desplazamiento
Cargar SBUFModo 0
transmisión
IB bus
Leer SBUFEscribir SBUF
SCON
Control del
puerto serie
RI TI
Petición de
interrupción
Fig. 9.8 Diagrama de bloques del puerto de comunicación serie
9.6 Modos de operación
El puerto de comunicación serie soporta cuatro modos de operación distintos: uno síncrono, el modo
0, y tres asíncronos, los modos 1, 2 y 3.
9.6.1 Modo 0 o síncrono
Para programar el puerto de comunicación serie en modo cero hay que colocar los bits SM0 y SM1
del registro SCON, a cero lógico. En este modo la velocidad de transmisión de datos es FOSC/12 y la
transmisión-recepción de datos se produce a través del pin RXD, mientras que por el pin TXD se
genera la señal de reloj que sincroniza la transmisión. Los ocho bits del dato se transmiten y se reciben
comenzando por el bit de menor peso, LSB, y acabando por el bit de mayor peso, MSB.
Para transmitir un dato hay que poner a cero el bit REN del registro SCON y escribir en el registro
SBUF el dato a transmitir. La transmisión se inicia cuando se ejecuta la instrucción de escritura en el
registro SBUF.
En la figura 9.9 se muestra el cronograma correspondiente a la transmisión de un dato. La transmisión
comienza por el bit de menor peso del dato a transmitir, D0, en el estado S6P2 del ciclo de periférico
que viene a continuación de la ejecución de la instrucción SBUF. En el estado S3P1 del siguiente ciclo
de periférico, la salida TXD pasa a cero para generar el primer pulso de la señal de reloj que
sincroniza la transmisión. Este flanco de bajada en TXD se utiliza para comunicar al receptor que ya
© Los autores, 2001; © Edicions UPC, 2001.
9 Puerto de comunicación serie 265
hay un bit válido en el pin RXD. En cada ciclo de periférico se transmite un nuevo bit hasta acabar
con el bit de mayor peso, D7. Al finalizar la transmisión, la línea RXD se queda con el valor 1 lógico
y se activa el flag de interrupción TI.
S3P1 S6P1
S6P2
Escribir
en SBUF
RXD
TI
Registro
TXD
S6P2 S6P2 S6P2 S6P2
D0 D1 D2 D6 D7
S1P1
S6P2 S6P2
Fig. 9.9 Temporización del puerto serie transmitiendo en modo cero
En la figura 9.10 se muestra el cronograma correspondiente a la recepción de un dato. El proceso de
recepción comienza cuando se escribe en el registro SCON la combinación binaria que pone los bits
SM0, SM1 y RI a cero y el bit REN a 1 lógico. Un ciclo de periférico después de ejecutada esta
instrucción, en el estado S3P1, la salida TXD pasa a 0 lógico para generar el primer pulso de la señal
de reloj que sincroniza la recepción. Este flanco de bajada avisa al dispositivo transmisor para que
coloque en la entrada RXD el primer bit, D0, del dato a transmitir. El microcontrolador lee el bit
suministrado por el transmisor en el estado S5P2 de ese mismo ciclo de periférico e introduce el bit
leído en el registro de recepción en el estado S6P2. Después de haber leído los ocho bits del dato se
activa el flag de interrupción RI del registro SCON. El dato recibido se puede leer ejecutando una
instrucción de lectura del registro SBUF.
S3P1 S6P1
S6P2
Escribir
en SCON
RXD
RI
Registro
TXD
S6P2 S6P2 S6P2 S6P2
D0 D1 D6 D7
S1P1
S6P2 S6P2
REN = 1, RI = 0
S5P2
Fig. 9.10 Temporización del puerto serie recibiendo en modo cero
Ejemplo 9.3 Comunicación vía serie entre un 8XC251Sx y un periférico en modo 0
En este ejemplo se trata de diseñar una rutina que controle la transmisión a un periférico, a
través del puerto serie, de los datos almacenados entre las direcciones 50H y 60H de la
memoria del microcontrolador 8XC251Sx.
El periférico dispone de un registro de desplazamiento con entrada serie y salida paralelo, para
recibir los datos que le envía el puerto serie programado en modo cero. La entrada serie del
registro de desplazamiento se conecta a la salida de datos del puerto serie (pin P3.0 o RXD),
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251266
mientras que la entrada de reloj se conecta al pin P3.1, para poder sincronizar la carga de datos
en el registro de desplazamiento con la señal de reloj del puerto serie (figura 9.11).
8XC251Sx
P3.0 TXD
Registro de desplazamiento
Entrada serie
Reloj Salida paralelo
Periférico
P3.1Señal de reloj
Fig. 9.11 Conexión del microcontrolador al periférico a través del puerto serie
El programa debe comenzar con instrucciones que configuren el puerto de comunicación serie
en modo 0 y habilitado para transmitir.
Si se realiza el control del puerto serie mediante interrupciones, se debe habilitar la
interrupción de este periférico y diseñar una rutina de servicio de interrupción del puerto serie
que envíe un dato cada vez que se active el flag TI. Para recorrer el margen de posiciones de
memoria que contienen los datos a transmitir se utiliza un registro como puntero de memoria
inicializado con el valor 50H. Si la frecuencia de la señal de reloj del microcontrolador es, por
ejemplo, de 12MHz, la velocidad de transmisión en este modo es de 1Mbaud.
A continuación se presenta el listado del programa principal y de la rutina de servicio a la
interrupción del puerto serie.
;-------------------------------------------------------------------------------------------------------------
; PROGRAMA PRINCIPAL DE LA TRANSMISION SERIE
;-------------------------------------------------------------------------------------------------------------
ORG FF:0000H ; Se salta a una zona de memoria con espacio suficiente
JMP INICIO ; para almacenar las instrucciones del programa principal.
ORG FF:0500H
; Programación del puerto serie
INICIO: CLR SM1 ; Se programa el puerto serie en modo 0.
CLR SM0 ;
CLR REN ; Se habilita la transmisión por el puerto serie.
SETB ES ; Se habilita la interrupción del puerto serie.
SETB EA ; Se activa el bit habilitador de interrupciones.
SETB INTR ; Cuando la CPU vectorice una interrupción cargará en
; la pila los 3 bytes del PC y el registro de estado.
; Inicialización del puntero
MOV R0, #50H ; Se inicializa el registro R0 con el valor 50H.
MOV SBUF,R0 ; Se envía el primer dato de la zona de memoria por el puerto serie.
;-------------------------------------------------------------------------------------------------------------
; RUTINA DE SERVICIO A LA INTERRUPCION DEL PUERTO SERIE
;-------------------------------------------------------------------------------------------------------------
ORG FF:0023H ; Vector de interrupción del puerto serie.
JMP RSI_PS ; Se salta a una zona de memoria con espacio suficiente
; para almacenar las instrucciones de la rutina.
ORG FF:1000H
RSI_PS: CLR TI ; Se borra el flag TI.
INC R0 ; Se incrementa el puntero R0.
MOV SBUF,R0 ; Se envía el dato por el puerto serie.
CMP R0,#60H ; Se compara el contenido del puntero con la última
; posición de memoria de la zona a transmitir.
© Los autores, 2001; © Edicions UPC, 2001.
9 Puerto de comunicación serie 267
JNE CONT ; Si todavía no se han enviado todos los datos se retorna
; al programa principal.
CLR ES ; Si se ha terminado la transmisión se borra el flag de
; interrupción del puerto serie.
RETI ; Se retorna al programa principal.
9.6.2 Modos 1, 2 y 3. Modos asíncronos
Cuando se programa el puerto de comunicación serie en alguno de los modos asíncronos, se pueden
enviar datos, a través de la línea TXD, y recibir datos, a través de la línea RXD, de forma simultánea.
En la figura 9.12 está representada la trama del dato que se transmite en los modos asíncronos, los
modos 1, 2 y 3.
D0 D1 D2 D3 D4 D5 D6 D7 D8
Bit de Start
Bit de Stop
Noveno bit (sólo modos 2 y 3)
Dato
Fig. 9.12 Trama de datos para los modos 1, 2 y 3
a) Modo 1
En el modo 1, la trama de datos está compuesta de 10 bits: hay un primer bit de start o comienzo del
dato, que vale cero lógico, e indica el comienzo de la transmisión del dato; a continuación vienen los 8
bits del dato a transmitir y finalmente el bit de stop, que siempre vale 1 lógico.
Para enviar un dato en modo 1 basta con poner a cero el bit REN, bit 4 del registro SCON y, a
continuación, escribir en el registro SBUF el dato que se desea enviar. La transmisión comienza una
vez escrito el dato en el registro SBUF.
Para recibir un dato en modo 1, en primer lugar se debe habilitar la recepción poniendo a 1 lógico el
bit REN. La recepción comienza cuando se detecta un flanco de bajada en el pin RXD.
La velocidad de transmisión en el modo 1 depende de la velocidad de desbordamiento del Timer 1 y/o
del Timer 2. Se puede seleccionar cualquiera de ellas o ambos Timers para fijar la velocidad de
transmisión y/o recepción. El Timer que fija por defecto la velocidad de transmisión es el Timer 1, y
ésta viene dada por la fórmula siguiente, en baudios o bits/s:
Velocidad de transmisión: 32
12
1 TimerdeltorebasamiendeVelocidadSMOD ÷ [baudios]
Si se desea utilizar el Timer 1 como generador de baudios, se debe inhibir la interrupción del Timer 1,
poniendo a cero el bit ETI del registro IE0 y se debe configurar como contador o como temporizador
en el modo de trabajo que se desee. En muchas aplicaciones se configura el Timer 1 como
temporizador en el modo 2. En este caso, la velocidad de transmisión dependerá del valor cargado
inicialmente en el registro del Timer 1, TH1:
Velocidad de transmisión: ] ∑1TH2561232
F2 OSC1SMOD
�÷÷÷ [baudios]
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251268
Tabla 9.8 Timer 1 como generador de baudios para los modos 1 y 3 del puerto serie
Timer 1Baudios FrecuenciaOscilador
SMOD1C/T Modo Valor recarga
62.5 Kbaud (Max) 12.0 MHz 1 0 2 FFH
19.2 Kbaud 11.059 MHz 1 0 2 FDH
9.6 Kbaud 11.059 MHz 0 0 2 FDH
4.8 Kbaud 11.059 MHz 0 0 2 FAH
2.4 Kbaud 11.059 MHz 0 0 2 F4H
1.2 Kbaud 11.059 MHz 0 0 2 E8H
137.5 Baud 11.059 MHz 0 0 2 1DH
110.0 Baud 6.0 MHz 0 0 2 72H
110.0 Baud 12.0 MHz 0 0 1 FEEBH
Se pueden obtener velocidades de transmisión bajas configurando el Timer 1 en modo 1, habilitando
su interrupción e inicializándolo, adecuadamente, en la rutina de servicio a la interrupción. Si por
ejemplo, la frecuencia de reloj es de 12MHz y se recarga el Timer 1 en la rutina de interrupción con el
valor FEEBH, se consigue fijar la velocidad de transmisión en 110.0 Baudios. Con otros valores de
recarga se pueden conseguir velocidades más bajas.
El Timer 2 tiene un modo de funcionamiento específico, denominado Baud Rate Generator Mode,
utilizado para fijar la velocidad de transmisión o de recepción de datos por el puerto serie. Para
seleccionar el Timer 2 como generador de baudios, en transmisión y/o recepción, se deben programar
adecuadamente los bits RCLCK y TCLCK del registro T2CON, tal y como se muestra en la tabla 9.9.
Tabla 9.9 Selección del Timer 2 como generador de baudios
RCLCK TCLCK Generador de baudiosen recepción
Generador de baudiosen transmisión
0 0 Timer 1 Timer 10 1 Timer 1 Timer 21 0 Timer 2 Timer 11 1 Timer 2 Timer 2
Cuando el Timer 2 se selecciona como generador de baudios funciona de forma similar al modo
autorrecarga. Al sufrir desbordamiento, los registros TH2 y TL2 se recargan con el valor de los
registros RCAP2H y RCAP2L, que se inicializan por programa. La velocidad de transmisión depende
de los valores cargados en estos registros:
Velocidad de transmisión: ( )] ∑LRCAPHRCAP
FOSC
2,26553632 �÷ [baudios]
En la figura 9.13 se muestra el esquema del Timer 2 configurado en modo generador de baudios. En la
tabla 9.10 se indican distintas velocidades de transmisión de acuerdo con los valores de los registros
RCAP2H y RCAP2L.
© Los autores, 2001; © Edicions UPC, 2001.
9 Puerto de comunicación serie 269
θ2TH2
(8 bits)
TL2
(8 bits)
0
1
T2
XTAL1
C/T2
Petición de
interrupciónT2EX
TR2
RCAP2H RCAP2L
EXF2
EXEN2
θ2 0
1
1
0
1
0
Rebasamiento
del Timer 1
SMOD1
θ16
θ16
RX
Clock
TX
Clock
RCLCK
TCLCK
Fig. 9.13 Esquema del Timer 2 trabajando en el modo generador de Baud Rate
Tabla 9.10 Timer 2 como generador de baudios para los modos 1 y 3 del puerto serie
Baudios Frecuencia oscilador RCAP2H RCAP2L375.0 Kbaud 12.0 MHz FFH FFH
9.6 Kbaud 12.0 MHz FFH D9H
4.8 Kbaud 12.0 MHz FFH B2H
2.4 Kbaud 12.0 MHz FFH 64H
1.2 Kbaud 12.0 MHz FEH C8H
300.0 baud 12.0 MHz FBH 1EH
110.0 baud 12.0 MHz F2H AFH
300.0 baud 6.0 MHz FDH 8FH
110.0 baud 6.0 MHz F9H 57H
Ejemplo 9.4 Comunicación vía serie entre dos microcontroladores 8XC251Sx en modo 1
En este ejemplo se trata de diseñar un canal de comunicación que transmita, vía serie entre dos
puntos remotos, datos de 8 bits. Para implementar este sistema se utilizan dos
microcontroladores de la serie 8XC251Sx. Uno de ellos, denominado emisor, recibe un dato de
entrada a través de un canal paralelo de 8 bits que está conectado al puerto P1 y lo envía a
través del puerto de comunicación serie a otro microcontrolador 8XC251Sx, denominado
receptor, que lo recibe y lo reenvía en formato paralelo por el puerto P1 (figura 9.14). Para
indicar que hay un nuevo dato en el puerto P1, listo para ser leído por el microcontrolador
emisor, se activa la entrada de interrupción externa cero con un flanco negativo.
8XC251SxP1.0
P1.1
P1.2
P1.3
P1.4
P1.5
P1.6
P1.7
P1.0
P1.1
P1.2
P1.3
P1.4
P1.5
P1.6
P1.7
P3.0P3.1TXD RXD
8XC251Sx
INT0Dato válido
de entrada P2.0Dato válido
de salida
Emisor Receptor
Fig. 9.14 Esquema del canal de comunicación
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251270
El microcontrolador receptor (figura 9.14) también dispone de una salida de dato válido
ubicada en el pin P2.0. Por esta salida se genera un pulso positivo para indicar que ya estádisponible en el puerto P1 un nuevo dato recibido por el puerto serie.
Para realizar la transmisión, se programa en modo 1 el puerto serie de los dos
microcontroladores, con una velocidad de transmisión/recepción de 9.600 baudios.
Esta aplicación requiere el diseño de dos rutinas, una rutina de envío de datos, para el
microcontrolador emisor, y una rutina de recepción para el microcontrolador receptor.
La rutina del emisor comienza programando el puerto serie en modo 1. A continuación se debe
habilitar la interrupción externa cero, programar el Timer 1 como temporizador en modo 2 e
inicializar adecuadamente los registros TH1 y TL1 para que la velocidad de transmisión sea de
9.600 baudios. Si consideramos que la frecuencia de la señal de reloj es de 11.059MHz y que el
bit SMOD1 está a 0 lógico, se debe cargar el valor FDH en TH1 y TL1 para obtener una
velocidad de transmisión de 9.600 baudios.
Por otra parte, la rutina de servicio a la interrupción /INT0 incluye instrucciones que ejecutan
el envío del dato leído en el puerto P1 por el puerto serie. En cualquier caso, se debe garantizar
que no se enviará un nuevo dato hasta que no finalice la transmisión del dato en curso. Por este
motivo, se chequea de forma reiterada el bit TI mientras éste valga 0 lógico. Cuando termine la
transmisión del dato, este bit pasará a 1 lógico, y finalizará la rutina de servicio a la
interrupción /INT0.
A continuación se presenta el listado del programa principal y de la rutina de servicio a la
interrupción externa cero del microcontrolador emisor.
;-------------------------------------------------------------------------------------------------------------
; PROGRAMA PRINCIPAL DE LA TRANSMISION SERIE
;-------------------------------------------------------------------------------------------------------------
ORG FF:0000H ;
JMP TRSER ; Salto al programa principal.
ORG FF:0100H
; Programación del puerto serie
TRSER: SETB SM1 ; Se programa el puerto serie en modo 1.
CLR SM0 ;
CLR REN ; Se habilita la transmisión por el puerto serie.
; Programación del Timer 1
MOV TMOD,#20H ; Se programa el Timer 1 en modo 2, como
MOV TL0,#FDH ; temporizador y se inicializa con el valor FDH para que
MOV TH0,#FDH ; la velocidad de transmisión sea de 9,6Kbaud.
CLR SMOD1 ; Se pone a cero el bit SMOD1.
; Programación de la interrupción /INT0
SETB EX0 ; Se habilita la interrupción /INT0.
SETB EA ; Se activa el bit habilitador de interrupciones.
SETB INTR ; Para cargar en la pila 3 bytes del PC y el registro de estado.
SETB IT0 ; Interrupción /INT0 activa por flanco descendente.
;-------------------------------------------------------------------------------------------------------------
; RUTINA DE SERVICIO A LA INTERRUPCION /INT0
;-------------------------------------------------------------------------------------------------------------
ORG FF:0003H ; Vector de interrupción de /INT0.
JMP RSI_INT0 ; Salto a la rutina de RSI.
ORG FF:2000H
RSI_INT0: MOV R0,P1 ; Se carga el dato del puerto P1 en el registro R0.
© Los autores, 2001; © Edicions UPC, 2001.
9 Puerto de comunicación serie 271
MOV SBUF,R0 ; Carga el dato en SBUF para comenzar la transmisión serie.
SIGUE: JNB TI,SIGUE ; Bucle de espera mientras dura la transmisión del dato.
CLR TI ; Se borra el flag TI.
RETI ; Se retorna al programa principal.
La rutina del receptor tiene en común con la del emisor la programación del Timer 1 y la
programación del puerto serie, excepto en el bit REN, que debe ponerse a 1 lógico para
habilitar la recepción. La rutina también incluye instrucciones que detectan cuándo se ha
recibido un nuevo dato mediante el chequeo continuo del bit RI. Cuando se active este bit, se
cargará el dato recibido, que está ubicado en el registro SBUF, en el puerto P1, al mismo
tiempo que se generará un pulso positivo en la salida P2.0.
A continuación se presenta el listado del programa que controla el funcionamiento del
microcontrolador receptor.
;-------------------------------------------------------------------------------------------------------------
; PROGRAMA PRINCIPAL DE LA TRANSMISION SERIE
;-------------------------------------------------------------------------------------------------------------
ORG FF:0000H
; Programación del puerto serie
SETB SM1 ; Se programa el puerto serie en modo 1.
CLR SM0 ;
SETB REN ; Se habilita la recepción por el puerto serie.
; Programación del Timer 1
MOV TMOD,#20H ; Se programa el Timer 1 en modo 2, como
MOV TL0,#FDH ; temporizador y se inicializa con el valor FDH para que
MOV TH0,#FDH ; la velocidad de transmisión sea de 9,6Kbaud.
CLR SMOD1 ; Se pone a cero el bit SMOD1.
; Control de la recepción de datos por el puerto serie.
SIGUE: JNB RI,SIGUE ; Bucle de espera hasta que no se reciba un nuevo dato por el puerto serie.
CLR RI ; Se borra el flag RI.
MOV R0,SBUF ; Se carga el dato recibido en el registro R0.
MOV P1,R0 ; Se carga el dato en el registro P1.
SETB P2.0 ; Se genera un pulso positivo por el pin P2.0 para
CLR P2.0 ; indicar que hay un nuevo dato en el puerto P1.
JMP SIGUE ; Salta a la instrucción de chequeo de RI para detectar la recepción de un nuevo dato.
b) Modo 2
Cuando el puerto serie está programado en el modo 2, la trama de bits que se transmite o se recibe estácompuesta por 11 bits: 1 bit de start, 8 bits de datos, comenzando siempre por el bit de menor peso, un
noveno bit programable por el usuario y un bit de stop. Los datos se transmiten por el pin TXD y se
reciben por el pin RXD. En la transmisión, el noveno bit transmitido se corresponde con el valor del
bit TR8 del registro SCON, mientras que en la recepción, el noveno bit se almacena en el bit RB8 del
dicho registro.
El procedimiento para transmitir en modo 2 comienza seleccionando el modo de trabajo; a
continuación se pone a 0 lógico el bit REN, se escribe el bit TR8 con el valor del noveno bit a
transmitir y se carga en el registro SBUF el dato que se desea enviar por el puerto serie. La
transmisión comienza justo después de escribir el registro SBUF.
La recepción se produce cuando se recibe un flanco descendente por el pin RXD, mientras el bit REN
está a 1 lógico. En este modo de trabajo, sólo se permiten dos velocidades de transmisión/recepción,
dependiendo del valor del bit SMOD1:
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251272
Velocidad puerto serie: 64
2 1 OSCSMOD F÷ [baudios]
c) Modo 3
El modo 3 del puerto serie es similar al modo 2, con la única diferencia que la velocidad de
transmisión/recepción se obtiene de la misma manera que en el modo 1.
9.7 Detección de errores
El puerto de comunicación serie permite detectar errores en la recepción del bit de stop para los
modos de trabajo 1, 2 y 3. Para ello, basta poner a 1 lógico el bit SMOD0, que está ubicado en el
registro PCON. Cuando esta opción está habilitada, el puerto serie verifica el bit de stop de cada dato
recibido: cuando este bit es erróneo se pone a 1 lógico, automáticamente, el bit FE del registro SCON.
Si se utiliza este recurso, se deben incluir en el programa instrucciones que examinen el bit FE cada
vez que se reciba una dato, para detectar posibles errores. Una vez activo, el bit FE sólo se puede
borrar por programa, por lo que se deben incluir instrucciones específicas que borren el bit FE cada
vez que se ponga a 1 lógico.
9.8 Comunicación multiprocesador
Los modos de trabajo 2 y 3 posibilitan la comunicación, en entornos multiprocesador, a través del
puerto serie. Esta prestación permite el control de la comunicación serie en un sistema donde varios
procesadores, que actúan como esclavos, comparten la misma línea de comunicación serie junto con
un procesador maestro que realiza el control de la comunicación. Para habilitar la opción de
comunicación multiprocesador, se debe poner a 1 lógico el bit SM2 del registro SCON.
En la figura 9.15 se muestra un ejemplo de entorno de comunicación multiprocesador, donde se puede
observar que el pin de transmisión serie, TXD, del microcontrolador que actúa de maestro, estáconectado al pin de recepción serie, RXD, de los microcontroladores esclavos, mientras que el pin
RXD del maestro está conectado al pin TXD de los esclavos. Por otra parte, cada microcontrolador
dispone de una dirección que lo identifica y que posibilita al microcontrolador maestro comunicarse
con un microcontrolador esclavo concreto.
8XC251
TXD RXD
Maestro
8XC251
TXD RXD
Esclavo
8XC251
TXD RXD
Esclavo
8XC251
TXD RXD
Esclavo
Fig. 9.15 Comunicación en entorno multiprocesador
© Los autores, 2001; © Edicions UPC, 2001.
9 Puerto de comunicación serie 273
Para que llevar a cabo la comunicación vía serie en un entorno multiprocesador, todos los
microcontroladores esclavos deben tener su bit SM2 a 1 lógico. En estas condiciones, cuando el
microcontrolador que actúa de maestro quiere comunicarse con algún esclavo debe, en primer lugar,
transmitir a través del puerto serie un dato con la dirección del esclavo. El noveno bit del dato
transmitido será un 1 lógico como indicativo de que se envía una dirección. Todos los esclavos leerán
esa dirección, pero sólo aquel que reconozca su propia dirección pondrá el bit RB8 a 1 lógico, al
mismo tiempo que activará su flag de interrupción RI para generar una interrupción. El
microcontrolador esclavo, que ha sido direccionado, pondrá a cero su bit SM2, preparándose, de este
modo, para recibir los bytes de datos enviados por el maestro. Los bytes de datos tienen el noveno bit
a 0 lógico; por tanto, son ignorados por todos los esclavos que tienen su bit SM2 a 1. De este modo, el
único microcontrolador esclavo que responde al maestro es el que ha reconocido su dirección.
9.9 Reconocimiento automático de direcciones
La dirección individual de cada microcontrolador se especifica en los registros SADDR y SADEN.
Por otra parte, el microcontrolador se identifica mediante dos tipos de direcciones denominadas
direcciones given y direcciones broadcast.
9.9.1 Direcciones given
La dirección individual del microcontrolador se almacena en el registro SADDR; por otra parte, el
registro SADEN contiene una máscara de bits que permiten tomar, indistintamente, como 0 ó 1 lógico,
aquellos bits del registro SADDR que en el registro SADEN estén a 0 lógico. De este modo se puede
direccionar más de un esclavo al mismo tiempo.
Por ejemplo, si en el registro SADDR está almacenado el valor 1001 0011 y en el registro SADEN el
valor 0101 1111, el microcontrolador responde a las direcciones: X0X1 0011. En este caso, las
combinaciones posibles de valores que pueden tomar los bits 5 y 7, dan lugar a 4 direcciones distintas
asociadas al mismo microcontrolador y denominadas direcciones given.
En los casos extremos, si el registro SADEN almacena el valor 0000 0000, el microcontrolador
responde a cualquier dirección, y si el registro SADEN está cargado con el valor 1111 1111, sólo
responde a la dirección almacenada en el registro SADDR.
Ejemplo 9.5 Direccionamiento de diferentes esclavos utilizando direcciones given
Se dispone de tres microcontroladores esclavos con las siguientes direcciones y máscaras:
Esclavo A: SADDR = 1111 0001
SADEN = 1111 1010
Given = 1111 0X0X
Esclavo B: SADDR = 1111 0011
SADEN = 1111 1001
Given = 1111 0XX1
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251274
Esclavo C: SADDR = 1111 0011
SADEN = 1111 1101
Given = 1111 00X1
Si nos fijamos en las direcciones anteriores, se puede comprobar que, para el esclavo A, el bit
de menor peso de la dirección es indeterminado, mientras que en los esclavos B y C vale 1
lógico. Entonces, para comunicarse exclusivamente con el esclavo A, la dirección deberá tener
el bit de menor peso a cero, como, por ejemplo, la dirección 1111 0000.
Por otra parte, para el esclavo A, el segundo bit vale 0 mientras que en los esclavos B y C es
indeterminado. Luego, para comunicarse con los esclavos B y C, pero no con el A, el
microcontrolador maestro deberá enviar una dirección que tenga el segundo bit a 1 lógico, por
ejemplo la dirección 1111 0011.
Para los esclavos A y B el tercer bit es indeterminado, mientras que para el esclavo C el tercer
bit de la dirección vale 0. Para comunicarse con los esclavos A y B, pero no con el C, el
maestro deberá enviar una dirección con el tercer bit a 1 lógico, por ejemplo la dirección 1111
0101.
Si el microcontrolador maestro debe comunicarse con los tres esclavos a la vez, envía una
dirección con el primer bit a 1 lógico, el segundo bit a 0 lógico y el tercero a 0 lógico, por
ejemplo la dirección 1111 0001.
9.9.2 Direcciones broadcast
Las direcciones broadcast se forman realizando la operación OR lógica entre el contenido del registro
SADDR y el contenido del registro SADEN, donde los ceros representan bits indeterminados, por
ejemplo:
SADDR = 0101 0110
SADEN = 1111 1100
Broadcast (SADDR) or (SADEN) = 1111 111X
Ejemplo 9.6 Direccionamiento de diferentes esclavos utilizando direcciones broadcast
Se dispone de tres microcontroladores esclavos con las siguientes direcciones y máscaras:
Esclavo A: SADDR = 1111 0001
SADEN = 1111 1010
Broadcast = 1111 1X11
Esclavo B: SADDR = 1111 0011
SADEN = 1111 1001
Broadcast = 1111 1X11
Esclavo C: SADDR = 1111 0010
SADEN = 1111 1101
Given = 1111 1111
© Los autores, 2001; © Edicions UPC, 2001.
9 Puerto de comunicación serie 275
Para los esclavos A y B, el bit tercero es indeterminado, mientras que para el esclavo C es igual
a 1 lógico. En este caso, para comunicarse con todos los esclavos el microcontrolador maestro
debe enviar la dirección FFH.
Si el maestro debe comunicarse con los esclavos A y B pero no con el C debe enviar la
dirección FBH.
Ejemplo 9.7 Comunicación multiprocesador en modo 2
Se dispone de un sistema que incorpora cinco microcontroladores, un maestro y cuatro
esclavos, denominados A, B, C y D, conectados entre sí a través del puerto serie para trabajar
en entorno multiprocesador (figura 9.16).
8XC251
TXD RXD
Maestro
8XC251
TXD RXD
Esclavo
D
8XC251
TXD RXD
Esclavo
C
8XC251
TXD RXD
Esclavo
A
8XC251
TXD RXD
Esclavo
B
Fig. 9.16 Comunicación en entorno multiprocesador
En la tabla 9.11 se especifica el contenido de los registros SADDR y SADEN de los distintos
esclavos, así como las direcciones given y broadcast resultantes.
Tabla 9.11 Direcciones de los microcontroladores esclavos.
Esclavo A Esclavo B Esclavo C Esclavo DSADDR 0000 0001 0000 0010 0000 0100 0000 1000
SADEN 1111 1100 1111 1010 1111 0101 1111 0011
Given 0000 00XX 0000 0X1X 0000 X1X0 0000 XX00
Broadcast 1111 11X1 1111 1X1X 1111 X1X1 1111 1X11
Para controlar esta aplicación, se debe diseñar un programa que gestione el envío de datos entre
el maestro y los esclavos. La secuencia de transferencia de datos es la siguiente:
En primer lugar el maestro transmite a los esclavos A y D, los datos contenidos entre las
direcciones de memoria 50H y 5FH.
A continuación, envía al esclavo C los datos almacenados en las posiciones de memoria
de la 60H a la 6FH.
Finalmente, el maestro transmite a todos los esclavos el contenido de la dirección 70H.
El programa del microcontrolador que realiza las funciones de maestro, incluye instrucciones
que programan el puerto serie en modo 2 y que lo habilitan para transmitir. A continuación,
vienen las instrucciones que realizan la transmisión de datos a los distintos esclavos. Para
mandar datos a los esclavos A y D se puede utilizar la dirección 0000 0000, que es común a
ambos esclavos. Para transmitir datos al esclavo C se utiliza la dirección 0000 1110, que es
exclusiva de este esclavo. Finalmente, para direccionar todos los esclavos simultáneamente se
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251276
puede emplear la dirección 1111 1111. A continuación se detalla el programa de control de
transmisión de datos del maestro.
;-------------------------------------------------------------------------------------------------------------
; PROGRAMA PRINCIPAL DEL MAESTRO
;-------------------------------------------------------------------------------------------------------------
ORG FF:0000H
; Programación del puerto serie
SETB SM0 ; Se programa el puerto serie en modo 2.
CLR SM1 ;
CLR REN ; Se habilita la transmisión por el puerto serie.
SETB SMOD1 ; Se pone el bit SMOD1 a 1 lógico.
; Envío de datos a los esclavos A y D.
SETB TB8 ; Se coloca el 9º bit a 1 para indicar a los esclavos que se envía una dirección.
MOV SBUF,#00H ; El maestro envía por el puerto serie la dirección de los esclavos A y D.
SIG1: JNB TI,SIG1 ; El maestro espera a que se acabe la transmisión.
CLR TI ; Se borra el flag TI.
CLR TB8 ; El maestro se dispone a enviar los datos.
MOV R0,#10H ; Se carga un contador con el número de datos a enviar.
MOV R1,#50H ; Se carga un puntero con la dirección de memoria
; donde están almacenados los datos.
SIG2: MOV SBUF,@R1 ; Se envía un dato.
INC R1 ; Se incrementa el puntero en una unidad.
SIG3: JNB TI,SIG3 ; El maestro espera a que se acabe la transmisión.
CLR TI ; Se borra el flag de interrupción en transmisión.
DJNZ R0,SIG2 ; Se decrementa el contador de datos transmitidos.
; Envío de datos al esclavo C.
SETB TB8 ; Se coloca el 9º bit a 1 para indicar a los esclavos que se envía una dirección.
MOV SBUF,#0EH ; El maestro envía por el puerto serie la dirección del esclavo C.
SIG4: JNB TI,SIG4 ; El maestro espera a que se acabe la transmisión.
CLR TI ; Se borra el flag TI.
CLR TB8 ; El maestro se dispone a enviar los datos.
MOV R0,#10H ; Se carga un contador con el número de datos a enviar.
MOV R1,#60H ; Se carga un puntero con la dirección de memoria donde están los datos.
SIG5: MOV SBUF,@R1 ; Se envía un dato.
INC R1 ; Se incrementa el puntero en una unidad.
SIG6: JNB TI,SIG6 ; El maestro espera a que se acabe la transmisión.
CLR TI ; Se borra el flag de interrupción en transmisión.
DJNZ R0,SIG5 ; Se decrementa el contador de datos transmitidos.
; Envío de datos a todos los esclavos.
SETB TB8 ; Se coloca el noveno bit a 1 lógico para indicar a los
; esclavos que se envía una dirección.
MOV SBUF,#FFH ; El maestro envía por el puerto serie una dirección común a todos los esclavos.
SIG7: JNB TI,SIG7 ; El maestro espera a que se acabe la transmisión.
CLR TI ; Se borra el flag TI.
CLR TB8 ; El maestro se dispone a enviar los datos.
MOV SBUF,70H ; Se envía el dato de la dirección 70H.
SIG8: JNB TI,SIG8 ; El maestro espera a que se acabe la transmisión.
CLR TI ; Se borra el flag de interrupción en transmisión.
© Los autores, 2001; © Edicions UPC, 2001.
10 El array de contadores programables (PCA) 277
10 El array de contadores programables (PCA)
10.1 Introducción
El array de contadores programable, PCA, está formado por un temporizador/contador de 16 bits y
por cinco módulos de comparación/captura. El temporizador/contador de 16 bits se utiliza como base
de tiempos de los módulos del PCA y su valor se distribuye a todos ellos a través de un bus interno de
16 líneas (figura 10.1). El array de contadores programable está disponible en las versiones 8XC51FX
de la familia MCS-51 y en toda la familia MCS-251. El modo de funcionamiento y la forma de operar
del PCA es el mismo para las dos familias, por lo que su explicación en este capítulo es válida para
ambas.
Cada uno de los módulos puede ser programado de forma independiente para realizar capturas de
flancos, comparación, generación de señal de modulación de anchura de pulsos PWM, etc. Además, el
módulo cuatro del PCA puede realizar la función de temporizador watchdog.
Los registros CMOD y CCON controlan el modo de operación del temporizador/contador del PCA,
mientras que los registros CCAPMx, con x = 0, …, 4, se encargan de controlar el modo de operación
de los módulos de comparación/captura del PCA.
En las tablas 10.1 y 10.2 se muestra el contenido de los registros CCON y CMOD, respectivamente, y
se indica el nombre y la función de cada uno de los bits que componen estos registros. En la tabla 10.3
están listados los registros relacionados con la programación y funcionamiento del PCA.
Tabla 10.1 Registro de control CCON del temporizador/contador del PCA
CCON Valor de reset: 00X0 0000B
b7 b6 b5 b4 b3 b2 b1 b0
CF CR --- CCF4 CCF3 CCF2 CCF1 CCF0
Bit Mnemónico Función7 CF Flag de desbordamiento del temporizador/contador del PCA. Este flag se activa
cuando el Timer del PCA sufre desbordamiento. Esto genera una interrupción al
microcontrolador si el bit ECF (registro CMOD) está activo. Este bit se borra por
programa.
6 CR Bit de control de puesta en marcha del temporizador/contador del PCA. Bit de puesta
en marcha del Timer del PCA. Debe estar a 1 lógico para que el Timer funcione.
5 --- Reservado.4:0 CCF4:0 Flags del módulo de comparación/captura. Se pone a 1 lógico, automáticamente,
cuando el comparador se activa, lo que genera una interrupción al microcontrolador si
el bit ECCFx correspondiente está activo. Debe ser borrado por programa.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251278
Tabla 10.2 Registro de modo CMOD del temporizador/contador del PCA
CMOD Valor de reset: 00XX X000B
b7 b6 b5 b4 b3 b2 b1 b0
CIDL WDTE --- --- --- CPS1 CPS0 ECF
Bit Mnemónico Función7 CIDL Bit de control del PCA temporizador/contador en modo Idle. Cuando CIDL=1 inhibe
al Timer del PCA durante el modo Idle. Si CIDL=0 el Timer del PCA funciona
durante el modo Idle.
6 WDTE Bit de habilitación del Timer watchdog.WDTE=1 habilita el Timer watchdog del módulo 4 del PCA.
WDTE=0 inhibe el Timer watchdog del PCA
5:3 --- Bits reservados. Los valores de estos bits son indeterminados. No deben utilizarse.
2:1 CPS1:0 Bits de selección de las entradas del PCA temporizador/contador.CPS1 CPS0
0 0 FOSC/12
0 1 FOSC/4
1 0 Desbordamiento del Timer 0 1 1 Reloj externo en el pin ECI (frecuencia máx. =FOSC/8)
0 ECF Bit de habilitación de la interrupción del PCA temporizador/contador.Cuando ECF=1 se habilita el bit CF en el registro CCON para generar una petición de
interrupción.
Tabla 10.3 Registros asociados al PCA
Mnemónico DescripciónCL
CH
Temporizador/contador del PCA. Estos dos registros de 8 bits implementan físicamente el
temporizador/contador de 16 bits del PCA.
CCON Registro de control del temporizador/contador del PCA. Contiene los bits de puesta en
marcha y desbordamiento del temporizador; y los flags de interrupción de los 5 módulos de
comparación/captura.
CMOD Registro de modo del temporizador/contador del PCA. Contiene los bits para habilitar el
temporizador/contador del PCA durante el modo de funcionamiento Idle, para habilitar el
temporizador watchdog, para seleccionar la entrada del temporizador/contador y para habilitar
la interrupción por desbordamiento del temporizador/contador del PCA.
CCAP0H
CCAP0L
Registros de comparación/captura del módulo 0 del PCA. Estos registros cargan el valor
comparado o capturado. Cuando el PCA trabaja en modo PWM, el registro de menor peso
controla el ciclo de trabajo de la onda de salida.
CCAP1H
CCAP1L
Registros de comparación/captura del módulo 1 del PCA. Idem
CCAP2H
CCAP2L
Registros de comparación/captura del módulo 2 del PCA. Idem
CCAP3H
CCAP3L
Registros de comparación/captura del módulo 3 del PCA. Idem
CCAP4H
CCAP4L
Registros de comparación/captura del módulo 4 del PCA. Idem
CCAPM0
CCAPM1
CCAPM2
CCAPM3
CCAPM4
Registros de modo de los módulos de comparación/captura del PCA. Contiene los bits que
permiten seleccionar el modo de operación de los módulos de comparación/captura y
habilitación del flag de comparación captura.
© Los autores, 2001; © Edicions UPC, 2001.
10 El array de contadores programables (PCA) 279
10.2 Temporizador/contador del PCA
En la figura 10.1 se muestra el esquema asociado al temporizador/contador del PCA, formado por los
registros CH y CL de 8 bits cada uno.
CH
(8 bits)
CL
(8 bits)
00
01
10
11P1.2/ECI
Petición de
interrupción
ECF
CF
Fosc /12
Fosc /4
Timer 0, desbordamiento
CPS1 CPS0 CIDL
CMOD.2 CMOD.1 CMOD.7
Temporizador/contador del PCA
CMOD.0
CCON.7
Rebasamiento
CRIDL
PCON.0
Modo IdleCCON.6
Run Control
Módulo 0 P1.3/CEX0
Módulo 1 P1.4/CEX1
Módulo 3 P1.5/CEX2
Módulo 2 P1.6/CEX3
Módulo 4 P1.7/CEX4/A17
Módulos de comparación y captura
Bus de
16 bits
16 bits
Fig. 10.1 Array de contadores programables
Los bits CPS1 y CPS0 del registro CMOD seleccionan una de las cuatro posibles fuentes de entrada
del temporizador/contador:
1. FOSC/12: para CPS1, CPS0 = 00, el temporizador/contador se incrementa cada ciclo de
periférico, en concreto en el período 2 del estado 5, S5P2.
2. FOSC/4: para CPS1, CPS0 = 01, el temporizador/contador se incrementa cada cuatro períodos
de señal de reloj.
3. Desbordamiento del Timer 0: para CPS1, CPS0 = 10, el temporizador/contador se
incrementa cada vez que desborda el Timer 0.
4. Pin P1.2/ECI: si se programan los bits CPS1, CPS0 = 11, el temporizador/contador se
incrementa cuando se aplica un flanco descendente en el pin P1.2/ECI. La frecuencia
máxima de incremento para este caso es de FOSC /8.
El PCA dispone de tres bits relacionados con la habilitación del funcionamiento del temporizador. El
bit CR, ubicado en el registro CCON, pone en marcha el temporizador si la salida de la puerta NAND
está a 1 lógico (figura 10.1). En caso de que el microcontrolador esté trabajando en el modo Idle de
bajo consumo (bit IDL del registro PCON a 1 lógico), el temporizador del PCA seguirá funcionando
mientras el bit CIDL, registro CMOD, esté a cero lógico.
Es posible leer el contenido de los registros CH y CL del temporizador/contador del PCA en cualquier
momento, pero no se puede escribir en estos registros mientras el temporizador esté funcionando.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251280
10.3 Módulos de comparación/captura del PCA
El PCA dispone de cinco módulos de comparación/captura: cada uno de ellos incorpora dos registros
de comparación/captura, registros CCAPxH/CCAPxL, con x = 0, …, 4, y un comparador de 16 bits.
Los registros de comparación/captura almacenan el valor del Timer del PCA cuando ocurre un evento
externo, captura, o bien, cuando se activa la salida del comparador del módulo. En el modo PWM, el
byte bajo, CCAPxL, controla el ciclo de trabajo de la señal generada.
Cada uno de los módulos puede ser programado mediante su correspondiente registro CCAPMx en
uno de estos modos de funcionamiento:
÷ Modo de captura de flanco positivo, flanco negativo o ambos.
÷ Modo de comparación. En este modo se consiguen diferentes funcionamientos: temporizador
controlado por software de 16 bits, salida de alta velocidad, temporizador watchdog de 16
bits, o bien, PWM de 8 bits.
÷ Sin operación.
10.3.1 Modo captura
El modo captura permite medir períodos, anchos de pulso, ciclos de trabajo y diferencia de fase entre
cinco señales. En la figura 10.2 se muestra el esquema correspondiente al modo captura.
CH(8 bits)
CL(8 bits)
CCAPxH CCAPxL
CEXxI/O Externa
X O CAPPx CAPNx O O O ECCFx
Registro de modo CCAPMx7 0
CCFx
Registro CCONEnable
Petición deinterrupción
Captura
Temporizador/contador del PCA
x = 0, 1, 2, 3 ó 4X = 0 ó 1
Entrada de cuenta
Fig. 10.2 Modo de captura de 16 bits
El microcontrolador verifica los pines de entrada CEX0, CEX1, CEX2, CEX3 y CEX4 para detectar
transiciones positivas y/o negativas en la señal binaria aplicada en estos pines (tabla 10.4).
Tabla 10.4 Señales externas asociadas al PCA
Nombre Tipo Descripción UbicaciónECI I Entrada externa del temporizador/contador del PCA. Esta señal es la entrada
de reloj externo para el temporizador/contador del PCA.
P1.2
CEX0
CEX1
CEX2
CEX3
CEX4
I/O Entradas/salidas externas de los módulos de comparación/captura.Cada módulo de comparación/captura tiene asociado como pin de
entrada/salida un pin del puerto P1.
P1.3
P1.4
P1.5
P1.6
P1.7/A17
© Los autores, 2001; © Edicions UPC, 2001.
10 El array de contadores programables (PCA) 281
Cuando un módulo de comparación/captura, que está programado en modo captura, detecta una
transición en su entrada CEXx, se carga en los registros CCAPxH/ CCAPxL el valor actual de los
registros del Timer del PCA. El objetivo de esta operación es registrar el momento en que se produjo la
transición de la señal de entrada, con una resolución equivalente a un período de reloj del Timer del
PCA. Al producirse la captura, también se activa el flag de comparación/captura CCFx del registro
CCON. Por otra parte, si el bit de habilitación de interrupción del registro CCAPMx, ECCFx, estáactivo, el PCA realiza una petición de interrupción al microcontrolador.
En la rutina de servicio a la interrupción del PCA se debe borrar el flag de interrupción activo y
guardar el valor capturado en los registros CCAPxH/CCAPxL en la memoria RAM, ya que con la
siguiente captura se reemplaza ese valor.
Para configurar un módulo del PCA en modo captura se debe programar adecuadamente el bit CAPPx(captura de flanco positivo), y CAPNx (captura del flanco negativo) del registro CCAPMx de dicho
módulo. En la tabla 10.5 se especifica el contenido de los registros CCAPMx y en la tabla 10.6 se
indica el valor que deben tomar estos bits para programar los módulos del PCA en las distintas
configuraciones posibles.
Por ejemplo, para capturar una transición positiva se debe activar el bit CAPPx y borrar el bit CAPNx.
Si se desea capturar una transición negativa, el bit activo debe ser CAPNx, mientras que el bit CAPPxdebe estar a cero. Si ambos bits están a 1 lógico, se capturan flancos positivos y negativos.
Tabla 10.5 Registros de comparación/captura del PCA
CCAPMx Valor de reset: X000 0000B
b7 b6 b5 b4 b3 b2 b1 b0
--- ECOMx CAPPx CAPNx MATx TOGx PWMx ECCFx
Bit Mnemónico Función7 --- Reservado. Este bit no se puede utilizar.
6 ECOMx Modos de comparación. Cuando este bit está a 1 lógico se habilita el comparador del
módulo. Este comparador se utiliza para generar un Timer, salidas de alta velocidad,
un modulador de anchura de pulso o un temporizador watchdog.
5 CAPPx Modo captura positiva. Cuando este bit está a 1 lógico, habilita la captura de flancos
positivos en la entrada externa CEXx.
4 CAPNx Modo captura negativa. Cuando este bit está a 1 lógico, habilita la captura de flancos
negativos en la entrada externa CEXx.
3 MATx Si se pone este bit a 1 lógico, se habilita el flag de interrupción del módulo cuando se
activa el comparador.
2 TOGx Conmutación. CuandoTOGx=1, estando el comparador habilitado, la salida CEXxconmuta de valor cada vez que se activa el comparador.
1 PWMx Modo PWM. Cuando PWMx=1 se configura el módulo como modulador de anchura
de pulsos con 8 bits de resolución y con salida por el pin CEXx.
0 ECCFx Habilitación de interrupciones. Este bit habilita las interrupciones generadas al
activarse el comparador del módulo.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251282
Tabla 10.6 Modos de trabajo del PCA
ECOMx CAPPx CAPNx MATx TOGx PWMx ECCFx Modo0 0 0 0 0 0 0 Sin operación
X 1 0 0 0 0 X Captura con el flanco positivo de la
entrada CEXxX 0 1 0 0 0 X Captura con el flanco negativo de la
entrada CEXxX 1 1 0 0 0 X Captura con el flanco positivo o negativo
de la entrada CEXx1 0 0 1 0 0 X Comparación: software Timer1 0 0 1 1 0 X Comparación: salida de alta velocidad
1 0 0 0 0 1 0 Comparación: PWM de 8 bits
1 0 0 1 X 0 X Comparación: watchdog en el módulo M4
Ejemplo 10.1 Funcionamiento del PCA en modo captura
En este ejemplo se trata de medir el desfase entre dos señales senoidales, Va(t) y Vb(t), de igual
frecuencia pero de distinta fase, utilizando dos módulos del PCA programados para capturar
flancos positivos. En la figura 10.3 se muestra el esquema del montaje propuesto para medir el
desfase. Este esquema incorpora dos comparadores que digitalizan dos señales senoidales con
una precisión de 1 bit. La salida de los comparadores se aplica a la entrada de los módulos 0 y
1 del PCA, CEX0 y CEX1, respectivamente. La salida del comparador vale 1 lógico cuando la
señal de entrada es positiva y 0 lógico cuando es negativa.
+
-
+
-
ComparadorVa(t)
Vb(t)
8XC251Sx
CEX0
CEX1
Desfase
Fig. 10.3 Detector de desfase
Los módulos 0 y 1 del PCA trabajan en modo captura de flanco positivo, de forma que
capturan el valor de los registros del Timer del PCA cuando la entrada correspondiente pasa por
un flanco positivo. Midiendo el tiempo transcurrido entre el flanco de subida en la entrada
CEX0 y el flanco de subida en la entrada CEX1 y, conociendo la frecuencia de la señal de reloj
y el período de las señales Va(t) y Vb(t), se puede determinar, en grados, el retardo entre ambas
señales. El período de la señal de entrada se obtiene realizando la diferencia entre los valores
capturados por el módulo 0 en dos flancos de subida consecutivos.
Para simplificar el programa que controla esta aplicación se puede considerar que el período de
las señales de entrada es inferior a la mitad del tiempo que tarda el Timer del PCA en sufrir
© Los autores, 2001; © Edicions UPC, 2001.
10 El array de contadores programables (PCA) 283
desbordamiento, teniendo en cuenta que el reloj de entrada del Timer es FOSC/4 y FOSC=16MHz.
El programa de control de la aplicación estará compuesto por un programa principal de
configuración e inicialización de periféricos y por una rutina de servicio a la interrupción del
PCA.
En el programa principal se incluye, en primer lugar, una instrucción que inicializa un contador
de capturas del módulo 0, que permite contabilizar las dos capturas necesarias para obtener el
período de la señal. Asimismo, se deben programar adecuadamente los registros CCAPM0 y
CCAPM1, para configurar los módulos 0 y 1 del PCA en modo captura del flanco positivo; se
deber inicializar el registro CMOD para seleccionar la entrada FOSC/4 como reloj del Timer del
PCA; se deben poner a cero los registros de los módulos 0 y 1 (CCAP0H/CCAP0L y
CCAP1H/CCAP1L); y se deben habilitar los flags de interrupción del Timer del PCA, y del
módulo 0, ubicados en el registro CCON.
El flag de interrupción de módulo 1 se habilita en la rutina RSI del PCA, después de que el
módulo 0 haya capturado el primer flanco.
Finalmente, se pone en marcha el Timer del PCA, activando el bit CR del registro CCON, y se
habilita la interrupción del PCA en el registro de habilitación de interrupciones.
En la figura 10.4 se muestra cómo se deben programar los registros CCON y CMOD, según las
especificaciones del enunciado.
CIDL WDTE --- --- --- CPS1 CPS0 ECF
0 0 0 0 0 0 1 0
CMOD
Selección de la entrada F OSC/4
CF CR --- CCF4 CCF3 CCF2 CCF1 CCF0
0 1 0 0 0 0 0 0
CCON
Borrado de los flags de interrupción de los módulos 0 y 1
Puesta en marcha del Timer del PCA
Fig. 10.4 Programación de los registros CCON y CMOD
En la figura 10.5 se muestran los bits que hay que activar en los registros CCAPM0 y
CCAPM1, para programar los módulos 0 y 1 en el modo captura de flanco positivo.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251284
--- ECOMx CAPPx CAPNx MATx TOGx PWMx ECCF0
0 0 1 0 0 0 0 1
CCAPM0, CCAPM1
Habilita la interrupción del módulo 0
Habilita el modo de captura de flanco positivo
Fig. 10.5 Programación de los registros CCAPM0 y CCAPM1
A continuación se detalla el programa principal del medidor de desfase.
;----------------------------------------------------------------------------------------------------------
; PROGRAMA PRINCIPAL DEL MEDIDOR DE DESFASE
;----------------------------------------------------------------------------------------------------------
ORG FF:0000H ; El programa comienza en la dirección FF:0000H
JMP FF:2000H ; Se salta a la dirección FF:2000H donde hay espacio de memoria
; suficiente para colocar el resto de instrucciones del programa.
ORG FF:2000H ;
MOV R6,#00H ; Se carga a cero un contador de capturas del módulo 0.
CLR CCF0 ; Se borra el flag de interrupción del módulo cero.
CLR CCF1 ; Se borra el flag de interrupción del módulo uno.
SETB ECCF0 ; Se habilita al módulo 0 para interrumpir.
SETB CPS0 ; Se selecciona como entrada de reloj del timer del PCA
CLR CPS1 ; la señal FOSC/4.
MOV CCAP0H,#0H ; Se inicializan a cero los registros de
MOV CCAP0L,#0H ; comparación/captura de los módulos 0 y 1.
MOV CCAP1H,#0H ;
MOV CCAP1L,#0H ;
MOV CL,#00H ; Se inicializa a cero el timer del PCA.
MOV CH,#00H ;
SETB CR ; Se pone en marcha el timer del PCA.
SETB EC ; Habilitación de la interrupción generada por el PCA.
SETB EA ;
En la rutina RSI del PCA se debe determinar cuál de los dos módulos ha interrumpido y
almacenar, en algún registro tipo Word, el valor capturado por ese módulo. La siguiente
interrupción está generada necesariamente por una captura de flanco positivo del otro módulo.
El valor capturado en este caso se cargará en otro registro tipo Word.
Finalmente, se deja que el primer módulo vuelva a capturar otro flanco positivo. Realizando la
diferencia entre ambos valores capturados, se determina el periodo de la señal (figura 10.6).
Período
Primer flanco
Segundo flanco
Fig. 10.6 Medida del período de la señal
Teniendo el período y los valores de captura del primer flanco de ambos módulos, es posible
calcular el desfase entre ambas señales, que en grados vendrá dado por:
[ ] [ ]º360
Periodo
tVaFPtVbFP∑
�(10.1)
© Los autores, 2001; © Edicions UPC, 2001.
10 El array de contadores programables (PCA) 285
donde FPVb(t) es el valor de captura del primer flanco positivo de la señal Vb(t) y FPVa(t) es
el valor de captura del primer flanco positivo de la señal Va(t).
A continuación se detalla el listado de la rutina de servicio a la interrupción del PCA.
;----------------------------------------------------------------------------------------------------------
; RUTINA DE SERVICIO A LA INTERRUPCIÓN DEL PCA
;----------------------------------------------------------------------------------------------------------
ORG FF:0033H ; La rutina comienza en la dirección FF:0033H
JMP FF:1000H ; Se salta a la dirección FF:1000H donde hay espacio de memoria
; suficiente para colocar el resto de instrucciones de la rutina.
ORG FF:1000H ;
JB CCF1,FP1 ; Si ha interrumpido el módulo 1 se salta a FP1.
CLR CCF0 ; Se borra el flag de interrupción del módulo cero.
SETB ECCF1 ; Se habilita al módulo 1 para interrumpir.
INC R6,#1H ; Se incrementa el contador de capturas.
CMP R6,#02H ; Si se han realizado dos capturas se inhibe la interrupción del
JE SAL1 ; módulo 1 y se pasa a calcular el desfase.
MOV R0,CCAP0H ; Se carga el contenido de los registros de comparación/captura del
MOV R1,CCAP0L ; módulo 0 del PCA en el registro WR0.
RETI ; Se retorna al programa principal
SAL1:MOV R2,CCAP0H ; Se carga la segunda captura del módulo 0 del PCA en el registro
MOV R3,CCAP0L ; WR2.
CLR ECCF0 ; Se inhiben futuras interrupciones del módulo 0.
MOV WR8,WR2 ;
SUB WR8,WR0 ; Se calcula el período.
MOV WR10,#360d ; Se carga el valor 360 en WR10.
DIV WR8,WR10 ; Se divide el periodo entre 360 para determinar a cuantos
; incrementos del timer equivale a un grado.
SUB WR4,WR2 ; Se obtiene el tiempo entre las dos capturas de las señales desfasadas.
DIV WR4,WR10 ; Se obtiene el desfase en grados
RETI ; Se retorna al programa principal.
FP1: CLR CCF1 ; Se borra el flag de interrupción del módulo 1.
CLR ECCF1 ; Se inhibe futuras interrupciones del módulo 1.
MOV R4,CCAP1H ; Se carga el contenido de los registros de comparación/captura del
MOV R5,CCAP1L ; módulo 1 del PCA en el registro WR4.
RETI ; Se retorna al programa principal.
Ejemplo 10.2 Medida del ancho de un pulso
El PCA puede medir el ancho de un pulso digital capturando los flancos positivo y negativo del
pulso (figura 10.7) y efectuando la diferencia entre el valor de las dos capturas. Si se conoce
cuál es el tipo de flanco que se produce primero, el PCA puede configurarse para capturar
cualquiera de los flancos del pulso, tanto positivo como negativo. Por contra, si se desconoce
este hecho se puede determinar qué flanco realizará la primera captura eligiendo el modo
adecuado de funcionamiento del PCA. En este ejemplo se supone que el primer flanco que se
produce es el flanco positivo.
87C51FA
P1.3/CEX0
1ª Captura 2ª Captura
Ancho = Tpo (2ª Captura)-Tpo (1ª Captura)
W
Fig. 10.7 Medida del ancho de un pulso con el 87C51FA
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251286
La rutina para efectuar la medida del ancho del pulso se muestra a continuación.
;************************************************************************
; Rutina para la lectura del ancho de un pulso mediante el PCA
;************************************************************************
CAPTL EQU 20H ;Posición para el byte bajo de la 1ª captura
CAPTH EQU 21H ;Posición para el byte alto de la 2ª captura
ANCHOL EQU 22H ;Posición para el byte bajo del ancho de pulso
ANCHOH EQU 23H ;Posición para el byte alto del ancho de pulso
Orden_captura EQU 24H.0 ;Indicador de si ha sido la 1ª o la 2ª captura
ORG 00H
LJMP Inicio
ORG 033H
LJMP RSI_PCA
;************************************************************************
; Inicio (En esta rutina sólo se configura el PCA para la lectura del ancho)
;************************************************************************
Inicio: MOV CMOD, #0 ;Inicializa el temporizador del PCA
MOV CL, #0 ;Se escoge una entrada de (1/12)xFosc
MOV CH, #0 ;Borra los registros CL y CH
MOV CCAPM0, #21H ;Configura el módulo 0 para capturar el flanco positivo
SETB EC ;Habilita la interrupción del PCA
SETB EA ;Activa el bit de habilitación general
SETB CR ;Pone en marcha el temporizador del PCA
CLR Orden:_captura ;Borra el bit de orden de captura. Esta es la primera captura
;************************************************************************
; Rutina de RSI del PCA
;************************************************************************
RSI_PCA: CLR CCF0 ;Borra el bit del módulo 0 de comparación/captura
JB Orden_captura, Captura_2 ;Comprueba si se trata de la primera o segunda captura
Captura_1: MOV CAPTL, CCAP0L ;Guarda el byte bajo de la captura
MOV CAPTH, CCAP0H ;Guarda el byte alto de la captura
MOV CCAPM0, #11H ;Configura el módulo 0 para capturar el flanco negativo
SETB Orden_captura
RETI
Captura_2: PUSH ACC ;Guarda el acumulador y el registro de estado en la pila
PUSH PSW
CLR C ;Borra el bit de acarreo para efectuar una resta de 16 bits
MOV A, CCAP0L ;Lee el byte bajo de la 2ª captura
SUBB A, CAPTL ;Efectúa la resta con el byte bajo de la 1ª captura
MOV ANCHOL ;Guarda resultado
MOV A, CCAP0H ;Lee el byte alto de la 2ª captura
SUBB A, CAPTH ;Efectúa la resta con el byte alto de la 1ª captura
MOV ANCHOH ;Guarda resultado
MOV CCAPM0, #21H ;Configura el módulo 0 para capturar el siguiente flanco +
CLR Orden_captura
POP PSW ;Recupera el PSW de la pila
POP ACC ;Recupera el acumulador de la pila
RETI
En esta rutina se utiliza el módulo 0 para realizar la captura de los flancos, positivo y negativo,
del pulso. Para ello, primero se pone el dato 21H en el registro CCAPM0, lo que configura al
módulo para una captura del flanco positivo, poniendo los bits CAPP0 y ECCF0, de captura
positiva y de habilitación de interrupción, respectivamente, a 1 lógico. Y, luego, al efectuarse
esta captura, se pone el dato 11H en CCAPM0, que configura al módulo para una posterior
captura del flanco negativo (bits CAPN0 y ECCF0 a 1 lógico).
© Los autores, 2001; © Edicions UPC, 2001.
10 El array de contadores programables (PCA) 287
Al producirse la primera captura del flanco positivo de la señal, en la rutina de atención a la
interrupción del PCA, RSI_PCA, los registros CCAP0L y CCAP0H del módulo se almacenan
en las posiciones 20H y 21H, respectivamente, de la memoria RAM interna. Cuando se realiza
la segunda captura, el valor de estos registros se recupera de la memoria interna para efectuar
una resta de 16 bits con el valor actual de la captura. De esta forma, el valor de la diferencia
entre las capturas es el valor de 16 bits del ancho del pulso a medir, y se guarda en las
posiciones 22H y 23H de la memoria RAM interna.
Para que la aplicación funcione correctamente en los registro CL y CH no debe producirse un
desbordamiento, puesto que el programa no considera esta posibilidad.
10.3.2 Modos de comparación
Los modos de comparación permiten a los módulos del PCA operar como temporizadores, como
contadores, o bien, como moduladores de anchura de pulsos, PWM. El funcionamiento del módulo, en
estos modos, está basado en el comparador de 16 bits que incorpora cada módulo, cuya función serábásicamente la de comparar el contenido de los registros de comparación/captura con los registros del
Timer del PCA, y activar su salida cuando los contenidos de ambos registros sean iguales.
En total hay cuatro modos de comparación: modo temporizador por software de 16 bits, modo de
salida de alta velocidad, modo de temporizador watchdog y modo PWM. Para que un módulo del
PCA funcione en alguno de los modos de comparación se debe llevar a cabo el siguiente
procedimiento general:
1. Poner a 1 lógico el bit ECOMx del registro CCAPMx, correspondiente al módulo que
deseamos programar en algún modo de comparación (tablas 10.3 y 10.4).
2. Programar adecuadamente el resto de bits del registro CCAPMx para seleccionar el modo
concreto de funcionamiento.
3. Seleccionar la señal de entrada del Timer del PCA.
4. Cargar el valor de comparación en los registros de comparación/captura del módulo.
5. Poner a 1 lógico el bit de puesta en marcha del Timer del PCA.
6. Poner a cero el flag de interrupción del módulo de comparación/captura una vez activo.
a) Modo temporizador de 16 bits
Para trabajar en este modo se ponen a 1 lógico los bits ECOMx y MATx del registro CCAPMx (tabla
10.6). En este modo de funcionamiento, el comparador que incorpora el módulo compara el contenido
de los registros de comparación/captura con el contenido de los registros del Timer del PCA. Cuando
el contenido de estos registros coincide, se activa el flag de interrupción del módulo, CCFx, ubicado
en el registro CCON. Si el bit de habilitación de interrupción del módulo está activo se produce una
petición de interrupción.
En la figura 10.8 se muestra el esquema de bloques, correspondiente a los modos de funcionamiento
de temporizador de 16 bits y de salida de alta velocidad.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251288
CH
(8 bits)
CL
(8 bits)CCAPxH CCAPxL
X ECOMx 0 0 MATx TOGx 0 ECCFx
Registro de modo CCAPMx7 0
CCFx
CCON Enable
Petición de
interrupción
Comparador
de 16 bitsCEXx
Entrada
de cuenta
“0”
“1”
Escribir CCAPxH
Reset
Escribir
CCAPxL
Módulo de
comparación y capturaTimer/ counter del PCA
X = 0 ó 1
x = 0, 1, 2, 3, 4
Fig. 10.8 Modos de trabajo temporizador de 16 bits y salida de alta velocidad
b) Modo de salida de alta velocidad
En este modo de funcionamiento, se genera una señal binaria de salida a través del pin CEXx,asociado al módulo, que conmuta de valor cada vez que se activa el comparador del módulo (figura
10.8). La conmutación de este pin es independiente de la atención a la interrupción. Esto permite dar
una respuesta más rápida y precisa a la activación del comparador. Para programar un módulo en este
modo de funcionamiento se deben poner a 1 lógico los bits ECOMx, MATx, y TOGx del registro
CCAPMx (tabla 10.6).
c) Modo temporizador watchdog
El temporizador watchdog, WDT, tiene como función generar un reset del microcontrolador si no se
inicializan de forma regular sus registros. El WDT se utiliza en aplicaciones sometidas a fenómenos
que pueden inducir al microcontrolador a ejecutar erróneamente el programa, como son el ruido
eléctrico, derivas instantáneas de la tensión de alimentación, descargas eléctricas, etc.
Los microcontrolador de la serie 8XC251Sx disponen de dos WDT: uno de 14 bits y otro de 16 bits,
que es una opción de funcionamiento del módulo 4 del PCA. Cuando el Timer del PCA alcanza el
valor cargado en los registros de comparación/captura del módulo 4, se genera un reset del
microcontrolador, que tiene el mismo efecto que un reset externo.
Para programar el módulo 4 como WDT, se ponen a 1 lógico los bits ECOM4 y MAT4 del registro
CCAPM4 y el bit WDTE del registro CMOD; también debe seleccionarse la entrada del Timer del
PCA, programando los bits CPS0 y CPS1 del registro CMOD. El valor de comparación se carga en
los registros CCAP4H/CCAP4L, aunque, si se desea, también se puede cargar un valor inicial distinto
de cero en los registros del Timer del PCA, CH/CL. La diferencia entre estos valores multiplicada por
© Los autores, 2001; © Edicions UPC, 2001.
10 El array de contadores programables (PCA) 289
el período de reloj de entrada del Timer del PCA, determina el tiempo que tarda el WDT en generar un
reset, si no se realiza ninguna acción que lo evite, como por ejemplo:
1. Cambiar periódicamente el valor de los registros CCAP4H/CCAP4L antes de que se active el
comparador.
2. Cambiar repetidamente el contenido del temporizador del PCA antes de que alcance el valor
del módulo 4.
3. Inhibir la salida del módulo 4 poniendo a cero el bit WDTE = 0 antes de que se active el
comparador y habilitarlo de nuevo después de que se halle activado.
La segunda opción no es recomendable cuando se utilizan otros módulos del PCA, pues el
temporizador del PCA es la base de tiempos de todos los módulos y su cambio afectaría al
funcionamiento del resto de los módulos. La tercera opción puede ser poco conveniente, pues podríaocurrir un error en la ejecución del programa cuando se tuviese inhibido el módulo 4, de manera que
el watchdog no intervendría y la situación no se solucionaría.
La primera opción es la más viable debido a que no se inhabilita el watchdog, pero se debe cambiar
periódicamente el contenido de CCAP4H/CCAP4L por el programa para actualizar el watchdog.
En la siguiente rutina se muestra la inicialización del PCA para utilizar el módulo 4 como watchdogen un microcontrolador 8XC51FX:
;************************************************************************
; Rutina de inicialización del módulo 4 en modo watchdog para 8XC51FX
;************************************************************************
INI_WATCHDOG:
MOV CCAPM4, #4CH ;Módulo en modo de comparación
MOV CCAP4L, #0FFH ;Se escribe primero en el byte bajo del módulo
MOV CCAP4H, #0FFH ;Los valores de comparación se deben cambiar
;antes de que el temporizador del PCA llegue a
;desbordamiento, es decir, a FFFFH
ORL CMOD, #40H ;Activa el bit WDTE para habilitar el watchdog
;sin tener que afectar al resto de bits de CMOD
A continuación se muestra la subrutina, para un microcontrolador 8XC51FX, que permite actualizar
los registros del módulo 4 del PCA:
;************************************************************************
; Subrutina de refresco del watchdog del PCA para 8XC51FX
;************************************************************************
WATCHDOG: CLR EA ;Inhabilita las interrupciones
MOV CCAP4L, #0 ;Borra el byte bajo, de forma que la próxima comparación
MOV CCAP4H, CH ;esté dentro de 255 incrementos del PCA
SETB EA ;Habilita las interrupciones
RETI
En la figura 10.9 se muestra el diagrama de bloques del módulo 4 cuando está programado como
WDT.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251290
CH
(8 bits)
CL
(8 bits)CCAP4H CCAP4L
X ECOM4 0 0 1 X 0 X
Registro de modo CCAPM47 0
WDTE
CMOD.6
Comparador
de 16 bits
Entrada
de cuenta
“0”
“1”
Escribir CCAP4H
Reset
Escribir
CCAP4L
Módulo de
comparación y capturaTimer/ counter del PCA
X = 0 ó 1
Reset PCA WDT
Fig. 10.9 Modo watchdog
c) Modo PWM
Los cinco módulos de comparación/captura pueden programarse independientemente en modo PWM.
La señal PWM está disponible en la salida CEXx, con una resolución de ancho de pulso de 8 bits. Para
programar un módulo del PCA en modo PWM se deben activar los bits ECOMx y PWMx del registro
CCAPMx.
En este modo de funcionamiento, se compara el registro CL del Timer del PCA con el registro
CCAPxL. Cuando CL es menor que CCAPxL, la salida CEXx es un 0 lógico. Para valores de CL
mayores o iguales que CCAPxH, la salida permanece a 1 lógico hasta que el registro CL sufre
desbordamiento y vuelve, automáticamente, a 0 lógico. En ese momento se recarga el registro
CCAPxL con el contenido del registro CCAPxH, empezando, así, un nuevo período de la señal PWM
(figura 10.10).
El ciclo de trabajo de la señal PWM se controla mediante el valor almacenado en el registro CCAPxL,
mientras que el valor del registro CCAPxH proporciona el ciclo de trabajo del siguiente período.
Cargando el valor adecuado en el registro CCAPxH se puede variar el ciclo de trabajo desde un 0.4%,
para un valor de 255, hasta el 100%, para un valor de 0. En la figura 10.11 se muestran las señales
PWM obtenidas para distintos valores del registro CCAPxL.
La frecuencia de la señal PWM generada en este modo de funcionamiento es igual a la frecuencia de
la señal de entrada del temporizador del PCA dividida por 256. La mayor frecuencia de entrada del
Timer es FOSC/4, que da lugar a una frecuencia de señal PWM de 15.6kHz, considerando una
frecuencia de reloj de 16MHz.
© Los autores, 2001; © Edicions UPC, 2001.
10 El array de contadores programables (PCA) 291
CL
(8 bits)
CCAPxL
CCAPxH
X ECOMx 0 0 0 0 PWMx 0
Registro de modo CCAPMx7 0
Comparador
de 8 bits
“0”
“1”
CEXx
CL < CCAPxL
CL θ CCAPxL
8
8
Habilitación
El rebasamiento de CL
carga el contenido de
CCAPxH en CCAPxL
X = 0 ó 1
x = 0, 1, 2, 3, 4
Fig. 10.10 Modo PWM 8 bits
Señal PWMCiclo
de trabajo
0.4%
10%
50%
90%
100%
CCAPxL
255
230
128
25
0
Fig. 10.11 Ciclo de trabajo variable
Ejemplo 10.3 Generador de señal programable
En este ejemplo se debe controlar la frecuencia de trabajo de un generador de señal realizado
mediante un oscilador controlado por tensión, VCO, y el módulo 0 del PCA trabajando en
modo PWM. El VCO genera en su salida un señal cuya frecuencia es proporcional a la tensión
de entrada, en concreto:
( )kHzVf io5
256∑≅ (10.2)
donde fo es la frecuencia de salida y Vi la tensión de entrada en voltios.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251292
En la figura 10.12 se muestra el esquema de esta aplicación: se observa que se ha conectado la
entrada de tensión del VCO a la salida CEX0 del módulo 0 a través de un filtro paso-bajo.
8XC251Sx
CEX0
R
C
VCO
Vi fo
Fig. 10.12 Esquema del generador de señal controlado por microcontrolador
La tensión de entrada del VCO es el resultado de filtrar la señal de salida PWM generada por el
módulo 0. Si la señal PWM tiene una frecuencia suficientemente alta respecto a la frecuencia
de corte del filtro paso-bajo, la tensión de salida del filtro, Vi, será prácticamente constante, y
su valor igual a la componente continua de la señal PWM generada (figura 10.13).
R
C
Vi=Va·Ta/TVa
Ta
T
Fig. 10.13 Señal PWM filtrada
Si se considera que el margen dinámico de la salida CEX0 está entre 0 y 5V, y teniendo en
cuenta que el ciclo de trabajo de la señal PWM oscila entre 0.004 y 1, la frecuencia generada
por el VCO estará comprendida entre 1kHz, para un ciclo de trabajo de 0.004, y 256kHz, para
un ciclo de trabajo de 1, con una resolución de 1kHz.
El programa asociado a la aplicación debe incluir instrucciones que configuren adecuadamente
el registro CCAPM0 para que el módulo 0 del PCA trabaje en modo PWM, que programen el
registro CMOD para seleccionar la entrada FOSC/4 como reloj del Timer del PCA, e
instrucciones que inicialicen los registros CCAP0H y CCAP0L para obtener el ciclo de trabajo
deseado. Teniendo en cuenta la expresión 10.2, el valor cargado en el registro CCAP0H es,
directamente, el valor de frecuencia en kHz, que se obtendrá a la salida del VCO. Finalmente,
se pone en marcha el Timer del PCA activando el bit CR del registro CCON.
A continuación se detallan las instrucciones del programa principal de esta aplicación.
;----------------------------------------------------------------------------------------------------------
; PROGRAMA DEL GENERADOR DE FRECUENCIA
;----------------------------------------------------------------------------------------------------------
ORG FF:0000H ; El programa comienza en la dirección FF:0000H
JMP FF:2000H ; Se salta a la dirección FF:2000H donde hay espacio de memoria
; suficiente para colocar el resto de instrucciones del programa.
ORG FF:2000H ;
SETB ECCM0 ; Se programan adecuadamente los bits del registro CCAPM0
SETB PWM0 ; para que el módulo cero trabaje en modo PWM.
CLR CAPP0 ;
© Los autores, 2001; © Edicions UPC, 2001.
10 El array de contadores programables (PCA) 293
CLR CAPN0 ;
CLR MAT0 ;
CLR TOG0 ;
CLR ECCF0 ;
MOV CCAP0L,#5H ; Se carga en los registros CCAP0H y CCAP0L el valor de la
MOV CCAP0H,#5H ; frecuencia que se desea generar (por ejemplo 5kHz).
MOV CL,#00H ; Se inicializa a cero el timer del PCA.
MOV CH,#00H ;
SETB CR ; Se pone en marcha el timer del PCA.
Ejemplo 10.4 Medida de frecuencia
La medida de la frecuencia de una señal digital (figura 10.14) se puede efectuar con el PCA del
microcontrolador. Para ello, es necesario medir el tiempo T de duración de un tren de N pulsos
de la señal digital. El módulo de captura del PCA se debe configurar para capturar los flancos
positivos, de forma que cada captura se producirá con cada nuevo pulso de la señal.
87C51FA
P1.3/CEX0
Captura 1 Captura N
T = Tpo (Captura 1)-Tpo (Captura N)
T
Fig. 10.14 Medida de la frecuencia de una señal con el 87C51FA
La frecuencia de la señal se obtiene dividiendo el número N de capturas por el tiempo T
transcurrido:
Tiempo
capturas de Número
T
NFrecuencia ≅≅ (10.3)
La rutina para la medida de la frecuencia se muestra a continuación, donde se supone que la
duración T del tren de N pulsos es menor que el tiempo de desbordamiento del temporizador
del PCA.
;************************************************************************
; Rutina para la medida de la frecuencia de una señal mediante el PCA
;************************************************************************
CAPTL EQU 20H ;Posición para el byte bajo de la 1ª captura
CAPTH EQU 21H ;Posición para el byte alto de la 2ª captura
PERIODOL EQU 22H ;Byte bajo del tiempo T
PERIODOH EQU 23H ;Byte alto del tiempo T
NUM_CAP EQU 24H ;Determina el número de capturas a realizar
FLANCO EQU 25H.0 ;Bit que indica si es la primera captura en efectuarse
ORG 00H
LJMP Inicio
ORG 033H ;Vectorización del PCA
LJMP RSI_PCA
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251294
;************************************************************************
; Inicio (En esta rutina sólo se configura el PCA para la medida de la frecuencia)
;************************************************************************
Inicio: MOV CMOD, #0 ;Inicializa el temporizador del PCA
MOV CL, #0 ;Se escoge una entrada de (1/12)xFosc
MOV CH, #0 ;Borra los registros CL y CH
MOV CCAPM0, #21H ;Configura el módulo 0 para capturar el flanco positivo
SETB EC ;Habilita la interrupción del PCA
SETB EA ;Activa el bit de habilitación general
SETB CR ;Pone en marcha el temporizador del PCA
MOV NUM_CAP, #10 ;Determina el número de capturas a efectuar = a 10 pulsos
CLR FLANCO ;Borra el bit de indicación de la primera captura
;************************************************************************
; Rutina de RSI del PCA
;************************************************************************
RSI_PCA: CLR CCF0 ;Borra el bit del módulo 0 del comparación/ captura
JB FLANCO, CAPT_SIG ;Comprueba si es la primera captura
CAPT_1: MOV CAPTL, CCAP0L ;Guarda el byte bajo de la primera captura
MOV CAPTH, CCAP0H ;Guarda el byte alto de la primera captura
SETB FLANCO ;Pone a 1 lógico para el resto de las capturas
RETI
CAPT_SIG: DJNZ NUM_CAP, Salir ;Mientras no llegue a 10 pulsos salir
PUSH ACC ;Guarda ACC y PSW en la pila
PUSH PSW
CLR C ;Borra el bit de acarreo
MOV A, CCAP0L ;Lee el byte bajo de la captura N, para resta de 16 bits
SUBB A, CAPTL ;Resta con el byte bajo de la primera captura
MOV PERIODOL, A ;Guarda el resultado
MOV A, CCAP0H ;Lee el byte alto de la captura N
SUBB A, CAPTH ;Resta con el byte alto de la primera captura
MOV PERIODOH, A ;Guarda el resultado
MOV NUM_CAP, #10 ;Nº de capturas a efectuar para la siguiente medida
CLR FLANCO ;Borra bit para la siguiente medida
POP PSW ;Recupera ACC y PSW
POP ACC
Salir: RETI
En esta rutina no se incluye la división de N por el valor T obtenido. Ésta es una división de 16
bits que se puede realizar mediante la rutina DIV16 del apartado 5.7.
Ejemplo 10.5 Medida del ciclo de trabajo de una señal PWM
El ciclo de trabajo de una señal de modulación de anchura de pulso, PWM, se determina por la
relación existente entre el tiempo que la señal permanece a 1 lógico, TON, y el período T de la
señal. Por tanto, para calcular el ciclo de trabajo deben medirse estos tiempos, por lo que se
debe configurar el módulo de captura del PCA para que capture tanto los flancos positivos
como los flancos negativos de la señal.
87C51FA
P1.3/CEX0
Captura 1
Captura 2
T T
Captura 3
TON
Fig. 10.14 Medida del ciclo de trabajo de una señal PWM mediante el 87C51FA
© Los autores, 2001; © Edicions UPC, 2001.
10 El array de contadores programables (PCA) 295
La señal PWM tiene un período T constante que determina su frecuencia (figura 10.14). El
ciclo de trabajo de la señal viene dado por la relación:
T
T trabajode Ciclo ON≅ (10.4)
Para efectuar la medida de TON y TOFF se deben realizar tres capturas dentro de un mismo
período (figura 10.14). Con la diferencia entre la captura 2 y la captura 1 se mide el tiempo
TON, y con la diferencia entre la captura 3 y la captura 1 se determina el período T de la señal,
de forma que para calcular el ciclo de trabajo se debe realizar la siguiente división:
)1 Captura(T)3 Captura(T
)1 Captura(T)2 Captura(T
T
T trabajode Ciclo
popo
popoON
�
�≅≅ (10.5)
;************************************************************************
; Rutina para la medida del ciclo de trabajo de una señal PWM
;************************************************************************
CAPTL EQU 20H ;Posición para el byte bajo de la 1ª captura
CAPTH EQU 21H ;Posición para el byte alto de la 2ª captura
ANCHOL EQU 22H ;Byte bajo del tiempo TON
ANCHOH EQU 23H ;Byte alto del tiempo TON
PERIODOL EQU 24H ;Byte bajo del periodo de la señal T
PERIODOH EQU 25H ;Byte alto del periodo de la señal T
FLANCO1 EQU 26H.0 ;Bits de indicación del tipo de captura (1ª, 2ª o 3ª)FLANCO2 EQU 26H.1
ORG 00H
LJMP Inicio
ORG 033H ;Vectorización del PCA
LJMP RSI_PCA
;************************************************************************
; Inicio (En esta rutina sólo se configura el PCA para la medida del ciclo de trabajo)
;************************************************************************
Inicio: MOV CMOD, #0 ;Inicializa el temporizador del PCA
MOV CL, #0 ;Se escoge una entrada de (1/12)xFosc
MOV CH, #0 ;Borra los registros CL y CH
MOV CCAPM0, #21H ;Configura el módulo 0 para capturar el flanco positivo
SETB EC ;Habilita la interrupción del PCA
SETB EA ;Activa el bit de habilitación general
SETB CR ;Pone en marcha el temporizador del PCA
CLR FLANCO0
CLR FLANCO1
;************************************************************************
; Rutina de RSI del PCA
;************************************************************************
RSI_PCA: CLR CCF0 ;Borra el bit del módulo 0 del comparación/ captura
JB FLANCO1, CAPT_2 ;Comprueba si es el primer flanco positivo
CAPT_1: MOV CAPTL, CCAP0L
MOV CAPTH, CCAP0H
SETB FLANCO1
MOV CCAPM0, #31H ;Bits CCAP0 y CCAPN a 1 lógico, captura
RETI ;flanco positivo y negativo
CAPT_2: PUSH ACC ;Guarda ACC y PSW en la pila
PUSH PSW
JB FLANCO2, CAPT_3 ;Comprueba si es la segunda captura
CLR C ;Si es la segunda captura pasa a hacer la resta de 16 bits
MOV A, CCAP0L ;Lee el byte bajo de la captura actual
SUBB A, CAPTL ;Resta con el byte bajo de la primera lectura
MOV ANCHOL, A ;Guarda resultado en ANCHOL
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251296
MOV A, CCAP0H ;Lee el byte alto de la captura actual
SUBB A, CAPTH ;Resta con el byte alto de la primera lectura
MOV ANCHOH, A ;Guarda resultado en ANCHOH
SETB FLANCO2 ;Configura para la tercera captura
POP PSW ;Recupera ACC y PSW de la pila
POP ACC
RETI
CAPT_3: CLR C ;Pasa a efectuar la resta entre la 3ª y la 1ª captura
MOV A, CCAP0L ;Lee el byte bajo de la captura actual (3ª captura)
SUBB A, CAPTL ;Resta con el byte bajo de la primera lectura
MOV PERIODOL, A ;Guarda resultado en PERIODOL
MOV A, CCAP0H ;Lee el byte alto de la captura actual (3ª captura)
SUBB A, CAPTH ;Resta con el byte alto de la primera lectura
MOV PERIODOH, A ;Guarda resultado en PERIODOH
MOV CCAPM0, #21H ;Configura el módulo para captura de flanco positivo
CLR FLANCO1 ;Borra bit
CLR FLANCO2 ;Borra bit
POP PSW ;Recupera ACC y PSW de la pila
POP ACC
RETI
En esta rutina falta efectuar la división de 16 bits entre las variables ANCHO y PERIODO, que
se puede realizar mediante la rutina DIV16 del apartado 5.7.
© Los autores, 2001; © Edicions UPC, 2001.
11 Entradas y salidas analógicas 297
11 Entradas y salidas analógicas
11.1 Introducción
En el control de procesos industriales se precisa tener el valor instantáneo de determinadas señales
analógicas, de forma que se pueda aplicar un algoritmo de control que gestione y dote de ciertas
características al sistema que se desea controlar. De la misma forma, en el procesado de señal también
es necesario tener el valor instantáneo de la señal analógica, sobre la que se aplican ciertos algoritmos
digitales como pueden ser filtros FIR1
o IIR2
, con el fin de extraer determinadas características de la
señal medida. En consecuencia, es habitual tener convertidores del tipo analógico/digital, A/D, y
digital/analógico, D/A, en un sistema basado en microcontrolador, para efectuar el control de sistemas,
monitorizar el estado de señales analógicas y efectuar el procesado digital de señales. Mediante los
convertidores A/D se obtiene el valor discreto de la señal analógica, mientras que con los
convertidores D/A se convierte un valor discreto en analógico, pues es necesario que un
microcontrolador intervenga de esta manera en determinados sistemas.
La familia MCS-51 de Intel no dispone de conversores A/D ni D/A, con la excepción de la versión
87C51GB, que tiene un conversor A/D de 8 bits de resolución con hasta 8 canales multiplexados de
entrada. De la misma forma, la familia MCS-251 tampoco tiene convertidores A/D y D/A. Por tanto,
en estas familias los convertidores A/D y D/A se deben conectar externamente al microcontrolador. En
este sentido, se pueden emplear los puertos del microcontrolador para enviar datos, recibir datos y
realizar el control de los conversores A/D y D/A. No obstante, la modulación de anchura de pulsos,
PWM, que se puede generar con los microcontroladores que disponen de PCA, se puede utilizar como
conversor D/A para las aplicaciones donde se requiere el control de un motor, debido a que la acción
de control de un motor se suele realizar mediante el ciclo de trabajo de una señal PWM.
Hay otros fabricantes de la familia MCS-51 que proporcionan versiones con convertidor A/D, como
por ejemplo el SAB80C515A de Siemens, que incorpora un conversor A/D de 10 bits. Por tanto, el
diseñador, en función de los costos de desarrollo, siempre puede optar por conectar conversores A/D y
D/A comerciales al microcontrolador, o bien, por emplear versiones que ya los tengan incorporados.
Este capítulo se centra en la conexión de convertidores A/D y D/A al microcontrolador, válida para la
MCS-51 y para la MCS-251, así como para otros microcontroladores del mercado. También, se
1
Los filtros FIR son filtros digitales no recursivos, ampliamente tratados en la teoría clásica del procesado de señal.2
A diferencia de los FIR, los filtros IIR son recursivos, es decir, con realimentación de la salida del filtro.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251298
expone la implementación de varias técnicas de conversión A/D de bajo coste, en las que se utilizan
algunos de los recursos internos del microcontrolador.
11.2 Conexión de un convertidor D/A
La figura 11.1 muestra la conexión del convertidor digital/analógico MC1408DAC de 8 bits de
Motorola, que es un convertidor sencillo y de bajo costo. El convertidor está basado en una estructura
en escalera de resistencias del tipo R-2R, que se muestra en la figura 11.2. Según esta figura, cada una
de las entradas binarias del convertidor controla directamente el estado de un conmutador del circuito,
de manera que controla la suma de las corrientes de cada rama al nodo de la entrada negativa del
amplificador operacional. La corriente en cada una de las ramas tiene un valor proporcional a
potencias sucesivas de 2, es decir, en la rama del bit D8 la corriente es la mitad de la corriente de
entrada, en la rama del bit D7 la corriente está dividida por 4, y así sucesivamente. De esta manera, la
corriente de salida es proporcional a la palabra digital de entrada del convertidor, D0-D8. La corriente
finalmente obtenida se convierte en tensión mediante el amplificador operacional de salida (figura
11.2), cuya ganancia puede ajustarse a fondo de escala, o sea, con todas las entradas a 1 lógico, con la
resistencia RT del amplificador, para que la tensión de salida tenga un valor determinado.
P1.0
P1.1
P1.2
P1.3
P1.4
P1.5
P1.6
P1.7
A8
A7
A6
A5
A4
A3
A2
A1
V (-)REF
V (+)REF
2mA
1.25k÷
1.25k÷
1k÷
+5V
2.5V
+
_
+
5k÷
+12V
-12V
Io
-12V
100pF
VEE
COMP
LM336
GNDRANGE
MCS-51 MC1408+5V
Vo[0-10V]
Fig. 11.1 Conexión del convertidor MC1408DAC a la MCS-51
En el circuito de la figura 11.1, el diodo zener de 2.5V y las resistencias de 1.25k÷ se emplean para
establecer una fuente de corriente precisa de 2mA. La corriente Io de salida del convertidor D/A se
convierte en tensión mediante el amplificador operacional, de manera que la tensión de salida de este
amplificador es:
÷[[] k5256
binaria EntradamA2Vo
Con esta fórmula, la corriente a fondo de escala, es decir, con la palabra binaria con todos los bits a 1
lógico, es de 2mA; por tanto, la tensión máxima a fondo de escala será de 10V. Este valor se puede
modificar mediante la resistencia RT de realimentación del amplificador operacional.
El tiempo de respuesta del convertidor D/A es un parámetro que determina su máxima velocidad de
© Los autores, 2001; © Edicions UPC, 2001.
11 Entradas y salidas analógicas 299
conversión; el MC1408DAC tiene un tiempo de establecimiento settling time de 300ns. Y, la
resolución del MC1408DAC, para el fondo de escala de 10V, es de 39.1mV, que equivale al
incremento de la tensión de salida que se produce cuando el bit de menor peso de entrada del DAC
cambia de valor.
R
_
+
RT
R R
2R2R 2R2R2R
I
I/2
I/2
I/4
I/4
I/128
I/128
I/256
I/256
0
1 1 1 1
0 0 0D0 D1 D7 D8
+V
Io
0,1,...,7i 2
IDiIo
ii8
][] ∑ �
RTIoVo []
Fig. 11.2 Estructura en escalera R-2R del convertidor MC1408DAC
Ejemplo 11.1 Generación de una senoide mediante el MC1408DAC
En este ejemplo, se trata de realizar un programa para la MCS-51 con el circuito de la figura
11.1, que sea capaz de sintetizar una señal senoidal de 1.25kHz de frecuencia. Para ello, se
debe tener en cuenta que la tensión de salida Vo del circuito es unipolar, y que se debe
especificar un número de muestras de salida para que la señal tenga una forma adecuada. En
este caso, se obtienen 32 muestras de la señal (figura 11.3), es decir, 16 muestras por cada
semiperíodo, para representar la señal senoidal.
0 4 8 12 16 20 24 28 32
0º 45º 90º 135º 180º 225º 270º 315º 360º
0
2.5
5
7.5
10
V
t
Fig. 11.3 Señal senoidal a generar, formada por 32 muestras
La señal senoidal tiene una componente continua de 5V, de manera que su valor oscilará entre
0V y 10V, según la siguiente expresión:
)(sinV5V5Vo θ[(]
donde θ es el ángulo de cada muestra de la senoide. En la tabla 11.1 se presenta el valor de
cada una de las muestras de salida del convertidor D/A, en voltios, y el valor binario
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251300
correspondiente a la entrada del convertidor. En el programa de este ejemplo se debe
implementar la tabla de datos, D7-D0, que debe extraer por el puerto del microcontrolador. El
Timer 1, mediante interrupción, determinará la base de tiempos de extracción de los datos por
el puerto P1.
Para generar una frecuencia de 1.25kHz el peíiodo de la señal debe ser de 0.8ms, y el de cada
muestra de salida de 0.8ms/32, es decir, cada muestra se debe extraer cada 25)s. Este período
se puede generar con el Timer 1, configurado en el modo 2 de 8 bits con autorrecarga. Con una
frecuencia de reloj de 12MHz, y con el Timer contando pulsos internos, bit C/T a 0 lógico, se
puede hacer que el Timer interrumpa cada 25)s, poniendo el registro TH1 al valor E7H, es
decir, a la diferencia entre el valor de rebasamiento del Timer y 25)s (256)s-25)s).
Tabla 11.1 Valores de las muestras para la generación de la señal senoidal formada por 32 muestras con unaseparación de 11.25º cada una
sin( ) Vo (V) D7-D0 sin( ) Vo (V) D0-D70º 0 5 80H 180º 0 5 80H
11.25º 0.195 5.975 99H 191.25º -0.195 4.024 67H
22.5º 0.382 6.913 B1H 202.5º -0.382 3.086 4FH
33.75º 0.555 7.777 C7H 213.75º -0.555 2.222 39H
45º 0.707 8.535 DAH 225º -0.707 1.464 25H
56.25º 0.831 9.157 EAH 236.25º -0.831 0.842 13H
67.5º 0.923 9.619 F6H 247.5º -0.923 0.380 08H
78.75º 0.980 9.904 FDH 258.75º -0.980 0.096 02H
90º 1 10 FFH 270º -1 0 00H
101.25º 0.980 9.904 FDH 281.25º -0.980 0.096 02H
111.5 0.923 9.619 F6H 292.5º -0.923 0.380 08H
123.75º 0.831 9.157 EAH 303.75º -0.831 0.842 13H
135º 0.707 8.535 DAH 315º -0.707 1.464 25H
146.25º 0.555 7.777 C7H 326.25º -0.555 2.222 39H
157.5º 0.382 6.913 B1H 337.5º -0.382 3.086 4FH
168.75º 0.195 5.975 99H 348.75º -0.195 4.024 67H
El programa para generar la señal senoidal en la MCS-51 se muestra a continuación:
;************************************************************************
; Generación de una señal senoidal periódica de 32 muestras para la MCS-51
;************************************************************************
ORG 0H ; Tabla de vectores de salto
LJMP Inicio
ORG 01BH
LJMP RSI_Timer1
;************************************************************************
; Rutina de Inicio
;************************************************************************
Inicio: SETB ET1 ;Habilita interrupción del Timer 1
SETB PT1 ;Asigna prioridad alta al Timer 1
SETB EA ;Habilita bit de interrupción general
MOV TMOD, #20H ;Timer 1 en el Modo 2, GATE=0 y C/T=0
MOV TL1, #E7H ;(256-25) carga valor inicial para frecuencia de 1.25kHz
MOV TH1, #E7H ;Carga valor inicial para frecuencia de 1.25kHz
SETB TR1 ;Pone marcha el Timer 1
;*************************************************************************
; Rutina de Principal
;*************************************************************************
Principal: SJMP Principal ;Bucle infinito sin ninguna función definida
© Los autores, 2001; © Edicions UPC, 2001.
11 Entradas y salidas analógicas 301
;************************************************************************
; Rutina de servicio del Timer1
;************************************************************************
RSI_Timer1:MOV A, R7 ;Pone R7 en A, (1)s).
CALL Tab_Seno ;LLamada a subrutina de tabla, (2)s).
MOV P1, A ;Pone dato leído en A, (1)s).
CJNE R7, #31, Borra ;Mira si el contador R7 supera su valor max., (2)s).
INC R7 ;Incrementa contador R7, (1)s).
RETI ;Fin de rutina. El bit TF1 se borra automáticamente, (2)s).
Borra: MOV R7, #0 ;Borra R7, (1)s).
RETI ;Fin de rutina. El bit TF1 se borra automáticamente, (2)s).
Tab_Seno: INC A ;Incrementa índice de lectura de la tabla, (1)s).
MOVC A, @A+PC ;Lectura indexada de la tabla, (2)s).
RET ;Retorno de subrutina, (2)s).
DB 80H, 99H, B1H, C7H, DAH, EAH, F6H, FDH ;Tabla de datos
DB FFH, FDH, F6H, EAH, DAH, C7H, B1H, 99H
DB 80H, 67H, 4FH, 39H, 25H, 13H, 08H, 02H
DB 00H, 02H, 08H, 13H, 25H, 39H, 4FH, 67H
La rutina principal de este ejemplo consiste en un bucle infinito sin ninguna función definida,
puesto que la señal senoidal se genera totalmente por interrupción. El registro R7 se utiliza
como un contador entre 0 y 31, que índica el orden del dato a leer en la tabla definida por la
subrutina Tab_seno. Este contador se borra cada vez que se ha extraído la última muestra de la
señal senoidal.
Para determinar el instante preciso en el cual se extrae por el puerto P1 una muestra de la señal
senoidal, se debe tener en cuenta el tiempo en que se genera la interrupción, el tiempo en que
tarda el microcontrolador en saltar a la rutina de RSI y el tiempo que tarda la rutina en poner el
dato correspondiente en el puerto P1. El Timer 1 causa una interrupción cada 31)s, el tiempo
mínimo en saltar a la rutina de RSI es de 3 ciclos máquina, o sea, de 3)s para una frecuencia de
reloj de 12MHz, y la rutina, para poner el dato leído en el puerto, debe ejecutar seis
instrucciones, lo que supone un tiempo de 8)s. En definitiva, desde que se produce la
interrupción hasta que la muestra aparece en el puerto P1 transcurren 11)s. Por tanto, cada
muestra aparecerá 11)s después de que se produzca la interrupción del Timer (figura 11.4).
Int. Timer 1 Int. T1
Int. T1
31)s
11)s
16)s Fin proceso int.Int. T1 Int. T1
Muestra 1Muestra 2
Muestra n
31)s
Fig. 11.4 Secuencia de tiempos de la señal y de la interrupción generada por el Timer 1
Una vez sacada la muestra por el puerto P1, la rutina de RSI puede tardar 2 ó 3 instrucciones
más en terminar de ejecutarse por completo, lo que, en el peor caso, supone un tiempo de 5)s
adicionales. En consecuencia, el tiempo en que se finaliza el proceso de interrupción es de
16)s, por lo que la interrupción del Timer 1 no puede producirse por debajo de este tiempo.
Este hecho supone que, si se quiere modificar la frecuencia de la señal senoidal, el período de
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251302
cada muestra de la señal no puede ser inferior al proceso de interrupción; es posible generar,
para este caso, una señal senoidal con una frecuencia máxima de 1.953Hz. No obstante, esta
frecuencia se puede disminuir reduciendo la cantidad de muestras de la señal, o bien
aumentando la frecuencia de la señal de reloj del microcontrolador.
11.3 Convertidor A/D de bajo coste mediante aproximaciones sucesivas
El convertidor digital/analógico anterior, MC1408DAC, se puede emplear, junto con un comparador y
con el microcontrolador, para realizar un convertidor analógico/digital de bajo coste (figura 11.5),
basándose en la técnica de aproximaciones sucesivas.
P1.0
P1.1
P1.2
P1.3
P1.4
P1.5
P1.6
P1.7
A8
A7
A6
A5
A4
A3
A2
A1
V (-)REF
V (+)REF
2mA
1.25k÷
1.25k÷
1k÷
+5V
2.5V
+
_
+
5k÷
+12V
-12V
Io
-12V
100pF
VEE
COMP
LM336
GNDRANGE
MCS-51 MC1408+5V
_
+
LM393
LF355
P3.4VIN
+5V
+5V
Vo
Fig. 11.5 Convertidor A/D de 8 bits de bajo coste mediante aproximaciones sucesivas
La técnica de aproximaciones sucesivas se centra en la búsqueda binaria, por parte del
microcontrolador, de un valor de tensión de entrada Vin desconocido, comparándolo, para ello, con
valores conocidos de tensión, obtenidos a partir de un convertidor D/A y de una tensión de referencia
Vref. Como el convertidor D/A y el circuito empleado en la figura 11.5 son los mismos,
prácticamente, que en el apartado anterior, las tensiones máxima y mínima que se pueden generar en la
salida Vo son 10V y 0V, respectivamente. El valor máximo se corresponde con la palabra digital
11111111 y el valor mínimo con 00000000 del puerto P1.
La búsqueda binaria se inicia poniendo Vo a la mitad del fondo de escala, o sea, a (Vmax-Vmin)/2,
por lo que en el puerto P1 se debe poner el bit más significativo a 1 lógico y el resto de bits a 0 lógico
(10000000)(figura 11.6). La tensión Vo generada por el D/A se compara con la señal Vin, de forma
que la salida del comparador es 0 lógico si Vin es mayor que Vo (Vin>Vo), y 1 lógico si Vin en menor
que Vo (Vin<Vo). El microcontrolador debe leer el estado de la comparación, y si Vin es mayor que
Vo, entonces le debe sumar a la tensión actual Vo la mitad del margen superior que queda hasta llegar
al fondo de escala, es decir, (Vmax+Vo)/2, lo que se consigue poniendo a 1 lógico el bit 6 del puerto
© Los autores, 2001; © Edicions UPC, 2001.
11 Entradas y salidas analógicas 303
P1 (P1=11000000). Si, al contrario, resulta que Vin es menor que Vo, entonces le debe restar a la
tensión actual Vo la mitad del margen inferior que queda hasta llegar al mínimo de tensión, 0V, es
decir, (Vo-Vmin)/2, lo que se consigue poniendo a 0 lógico el bit 7 y a 1 lógico el bit 6 del puerto P1
(P1=01000000). Este procedimiento se continúa de forma sucesiva, hasta llegar a determinar el estado
del bit 0 del puerto P1. La conversión de la señal se lleva a cabo de esta manera en tan sólo 8 pasos,
empezando por el bit más significativo y terminando por el bit menos significativo.
La figura 11.6 muestra el algoritmo que hay que realizar con la técnica de aproximaciones sucesivas.
En este algoritmo Vo(k) representa el valor de Vo actual y Vo(k+1) representa el valor de Vo futuro a
realizar. La conversión finaliza en 8 iteraciones, de forma que, partiendo del inicio, si tomamos el bit
más significativo (MSB) como bit b(i), con i=7, se pueden dar dos situaciones en el algoritmo,
dependiendo del resultado de la comparación entre Vin y Vo. En el caso de que Vin sea mayor que
Vo, Vin>Vo, se ejecuta la segunda ecuación del algoritmo (ecuación 2), que en realidad se lleva a
cabo simplemente forzando el bit b(i-1) a 1 lógico, es decir, para este caso, poniendo el bit b(6) a 1
lógico. Al contrario, si Vin es menor que Vo, Vin<Vo, se ejecuta la primera ecuación del algoritmo
(ecuación 1), que se lleva a cabo poniendo el bit b(i) a 0 lógico y el bit b(i-1) a 1 lógico, es decir,
poniendo en este caso el bit b(7) a 0 lógico y el bit b(6) a 1 lógico. Este algoritmo se iterará hasta
llegar a evaluar el bit b(0).
Poner bit MSB
(bit 7) a 1 lógico
Vin > Vo
2
)k(VomáxV)k(Vo)1k(Vo
�(](2
mínV)k(Vo)k(Vo)1k(Vo
��](
Es el bit
LSB (bit 0)
Inicio
Fin (Vo ≅ Vin)
SI
NO
SI
NO
Fig. 11.6 Flujograma del algoritmo de aproximaciones sucesivas
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251304
La subrutina que realiza la conversión para la MCS-51 se muestra a continuación:
;****************************************************************************
; Subrutina CONV de aproximaciones sucesivas para el circuito de la figura 11.5
;****************************************************************************
CONV: MOV P1, #0 ;Borra puerto P1, (2)s)
SETB P1.7 ;Pone a 1 lógico el bit 7, (1)s)
JNB P3.4, B1 ;Lee el estado de la comparación, (2)s)
CLR P1.7 ;Borra el bit 7, (1)s)
B1: SETB P1.6 ;Pone a 1 lógico el bit 6, (1)s)
JNB P3.4, B2 ;Lee el estado de la comparación, (2)s)
CLR P1.6 ;Borra el bit 6, (1)s)
B2: SETB P1.5 ;Pone a 1 lógico el bit 5, (1)s)
JNB P3.4, B3 ;Lee el estado de la comparación, (2)s)
CLR P1.5 ;Borra el bit 5, (1)s)
B3: SETB P1.4 ;Pone a 1 lógico el bit 4, (1)s)
JNB P3.4, B4 ;Lee el estado de la comparación, (2)s)
CLR P1.4 ;Borra el bit 4, (1)s)
B4: SETB P1.3 ;Pone a 1 lógico el bit 3, (1)s)
JNB P3.4, B5 ;Lee el estado de la comparación, (2)s)
CLR P1.3 ;Borra el bit 3, (1)s)
B5: SETB P1.2 ;Pone a 1 lógico el bit 2, (1)s)
JNB P3.4, B6 ;Lee el estado de la comparación, (2)s)
CLR P1.2 ;Borra el bit 2, (1)s)
B6: SETB P1.1 ;Pone a 1 lógico el bit 1, (1)s)
JNB P3.4, B7 ;Lee el estado de la comparación, (2)s)
CLR P1.1 ;Borra el bit 1, (1)s)
B7: SETB P1.0 ;Pone a 1 lógico el bit 0, (1)s)
JNB P3.4, B8 ;Lee el estado de la comparación, (2)s)
CLR P1.0 ;Borra el bit 0, (1)s)
B8: RET ;Conversión finalizada (2)s)
El tiempo de conversión de esta rutina, dependerá del valor de la señal analógica Vin. No obstante, se
pueden determinar el peor y mejor caso a ejecutar por la subrutina. El peor caso consistirá en un valor
de Vin que obligue la ejecución de todas las instrucciones de la subrutina. Teniendo en cuenta un reloj
de 12MHz para el microcontrolador, la subrutina tiene una primera instrucción que borra el puerto P1
y que tarda 2)s en ejecutarse. El resto de las instrucciones son una secuencia de puesta a 1 lógico,
lectura del comparador y borrado, que tarda 4)s, es decir, 1)s para la puesta a 1 lógico, 2)s para la
lectura del comparador y 1)s para el borrado. Esta secuencia se repite hasta ocho veces, por lo que el
tiempo de conversión, en el peor de los casos, es:
s4428)121(2tpeor )]([(((]
El mejor de los casos consiste en una señal Vin tal que no se ejecute ninguna de las instrucciones
CLR, por lo que el tiempo de conversión es:
s2828)21(2tmejor )]([((]
En consecuencia, con la subrutina mostrada y el circuito de la figura 11.5 el tiempo de conversión
estará comprendido entre 28)s y 44)s.
© Los autores, 2001; © Edicions UPC, 2001.
11 Entradas y salidas analógicas 305
11.4 Conexión de un convertidor A/D
La figura 11.7 muestra la conexión entre el convertidor analógico/digital ADC0809 de 8 bits de
National Instruments y un microcontrolador de la familia MCS-51. El ADC0809 puede leer la señal
procedente de hasta 8 canales de entrada, seleccionables mediante tres líneas de dirección, S2-S0, que
actúan sobre un multiplexor interno. Este convertidor está basado en la técnica de conversión por
aproximaciones sucesivas.
D0-D7
S0
CLOCK
74LS04
Canal 0
S1
S2
A10
A11
A12
IN0
IN1
IN2
IN3
IN4
IN5
IN6
IN7
a bc
1k÷1k÷
680pF
Canal 1
Canal 2
Canal 3
Canal 4
Canal 5
Canal 6
Canal 7
Bus datos
GND
START
ALE
EOCd
P0
/INT0
MCS-51
A15
A14
A13
A12
A11
A10
+
1.8k÷
LM336-5
+12V
+Vref
-Vref
A15
A14
A13
OE
Vcc
74LS08
a
cb
74LS04
74LS04
+5V
P2
Inicio y lectura de conversión
e
AD
C08
09
Fig. 11.7 Conexión del convertidor ADC0809 a la MCS-51
Las salidas del convertidor A/D son triestadas, D0-D7, por lo que se pueden conectar directamente al
bus de datos de un sistema microprocesador. El convertidor precisa de una tensión de referencia
externa de 5V y de una señal de reloj comprendida entre 10kHz y 1280kHz. El tiempo de conversión
del convertidor es de 64 períodos de reloj desde el momento en que se inicia la conversión, por lo que
para una frecuencia de 640kHz el tiempo de conversión es de unos 100)s, aproximadamente, y de 50
)s para una frecuencia de 1280kHz.
La figura 11.8 muestra el diagrama de bloques del convertidor, que está compuesto por un multiplexor
analógico de 8 canales, un comparador, un registro de aproximaciones sucesivas (SAR), una escalera
de resistencias R-2R y una serie de interruptores que actúan sobre la escalera de resistencias.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251306
Multiplexor
analógico
de
8 canales
Descodificador
ylatch de
direcciones
Control
y
sincronización
Registro de
aproximaciones
sucesivas (SAR)
Ramificación de
interruptores
Escalera de
resistencias (256R)
START CLOCK
COMPARADOR
+Vref -Vref OE
EOC
Interrupción
8 bits
de
salida
8 entradas
analógicas
3 bits de
dirección
ALE
A/D 8 bits
Vcc GND
Buffer-latchtriestado
de
salida
Fig. 11.8 Diagrama de bloques del ADC0809 de National Instruments
La figura 11.9 muestra el diagrama de tiempos del convertidor. El proceso de conversión del
convertidor empieza poniendo la línea de control ALE a 1 lógico, lo que hace que se carguen las
direcciones S2-S0 en el latch interno de direcciones, seleccionando el canal analógico de entrada.
Aplicando un pulso en la señal de START se inicia la conversión de la señal, se borran los registros
internos del convertidor en el flanco de subida, y se inicia la conversión en el flanco de bajada. La
señal EOC, End of Conversion, pasa a 0 lógico en los primeros 8 períodos de reloj desde el flanco de
subida de la señal START, lo que indica el final de la conversión en el flanco de subida de EOC. Una
vez producido este flanco, se puede leer el dato obtenido por la conversión, para lo cual debe aplicarse
un pulso positivo a la señal OE, Output Enable, de forma que el dato se sitúe en las 8 líneas del bus de
datos. Las salidas del convertidor permanecen en estado triestado hasta que se pone el dato convertido
en el bus de datos.
Según la figura 11.7, las salidas D0-D7 del convertidor se conectan directamente al bus de direcciones
del microcontrolador, puerto P0. El inicio de la conversión se realiza aplicando un pulso en las líneas
START y ALE del convertidor. Estas entradas (figura 11.7) están conectadas a las líneas A15, A14 y
A13 del bus de direcciones, mediante dos puertas AND, de forma que estarán a 1 lógico sólo cuando
A15, A14 y A13 estén a 1 lógico. Al mismo tiempo, las líneas A12, A11 y A10 del bus de direcciones,
están conectadas a las entradas de selección del canal analógico, I2, I1 y I0, respectivamente. De esta
forma, el inicio de la conversión en el convertidor y la selección del canal analógico pueden efectuarse
situando una dirección concreta en el bus de direcciones, que se corresponda con los rangos de
direcciones de la tabla 11.2.
© Los autores, 2001; © Edicions UPC, 2001.
11 Entradas y salidas analógicas 307
CLOCK
ALE
START
EntradaanalógicaIN0-IN7
ireccionesS0-S2
EOC
OE
SalidasD0-D7
50% 50%
50% 50%
Ts
Th
Tl Teoc
Tc
Th2
64 períodos de reloj
ESTABLE
TRIESTADODATO VÁLIDO
Fig. 11.9 Diagrama de tiempos del ADC0809.
Según la tabla 11.2, escribiendo cualquier dato en el bus de datos por medio de la instrucción MOVX
y escogiendo el canal analógico de entrada con una de las direcciones de la tabla, puede iniciarse el
proceso de conversión del convertidor. La señal EOC está conectada mediante una puerta inversora a
la entrada de interrupción /INT0 del microcontrolador; en consecuencia, el flanco de subida en EOC,
que indica el final de conversión del convertidor, aparece como un flanco de bajada a la entrada de
/INT0, que causará una interrupción si /INT0 está habilitada por flanco descendente.
Tabla 11.2 Rango de direcciones del mapa de memoria para iniciar la conversión, junto con la selección delcanal analógico de entrada y para la lectura del dato
Rango de direcciones FunciónC000H-DFFFH Lectura del dato convertido
E000H-E3FFH Inicio conversión, selección canal 0
E400H-E7FFH Inicio conversión, selección canal 1
E800H-EBFFH Inicio conversión, selección canal 2
EC00H-EFFFH Inicio conversión, selección canal 3
F000H-F3FFH Inicio conversión, selección canal 4
F400H-F7FFH Inicio conversión, selección canal 5
F800H-FBFFH Inicio conversión, selección canal 6
FC00H-FFFFH Inicio conversión, selección canal 7
La señal OE del convertidor está conectada también a dos puertas AND y a una puerta NOT, de
manera que OE estará a 1 lógico si se sitúa una dirección con la combinación 1, 1 y 0 lógicos, en las
líneas A15, A14 y A13, respectivamente. En definitiva, el dato convertido se puede leer, en la rutina
de RSI de /INT0, ejecutando una lectura en cualquiera de las direcciones comprendidas en el rango
C000H-DFFFH, mediante la instrucción MOVX.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251308
Ejemplo 11.2 Monitorización del estado de las baterías de un SAI
Los equipos de alimentación ininterrumpida, SAI, se utilizan para mantener la tensión de la red
eléctrica en los equipos informáticos, en el caso de que se produzcan cortes repentinos de la
red. Estos equipos tienen una serie de baterías que, en el caso de producirse un corte, aportan la
energía necesaria para que, durante un intervalo de tiempo, sea posible cerrar los sistemas y
guardar la información más importante. El estado de las baterías se debe comprobar
regularmente para poder detectar anomalías en el proceso de carga y descarga, e indicar el
momento en el cual una batería es defectuosa.
En este ejemplo se quiere utilizar un microcontrolador de la familia MCS-51 para monitorizar
el estado de las baterías, es decir, para leer su valor y proporcionárselo al sistema de control del
SAI, que suele llevarse a cabo por medio de un procesador digital de señal DSP. Según la
figura 11.10, el equipo SAI tiene un total de ocho baterías de 12V, que forman dos ramas de
cuatro baterías cada una conectadas en paralelo, y que entrega la energía necesaria para
mantener la tensión de la red eléctrica en los equipos informáticos.
El microcontrolador debe leer la tensión de cada una de las baterías cuando la DSP se lo
indique mediante la transmisión del carácter ASCII 05H vía RS-232C. Una vez finalizada la
lectura de todos los canales del A/D, el microcontrolador debe transmitir a la DSP la lectura
efectuada de cada batería vía RS-232C; para ello debe transmitir el carácter 11H (XON3
), que
se tomará por la DSP como carácter de inicio de la transmisión, los datos correspondientes a la
lectura efectuada en cada batería y el carácter 13H (XOFF) de final de transmisión.
En el circuito de la figura 11.10 tan sólo se utiliza una memoria EPROM de 2kbytes de
capacidad para albergar el programa. No es necesario utilizar ningún circuito integrado de
memoria RAM externa, pues se usa la memoria interna del microcontrolador.
La memoria EPROM se selecciona mediante las líneas A12, A13, A14 y A15 del bus de
direcciones, que están conectadas a una serie de puertas AND (figura 11.10), que hacen que la
memoria esté seleccionada en el rango de direcciones comprendido entre 0000H y 0FFFH, o
sea, en las primeras 4kdirecciones del mapa de memoria (figura 11.11); aparece, por tanto, una
zona imagen en el rango [0800H-0FFFH] de 2kdirecciones. El convertidor A/D utiliza los
mismos rangos de direcciones para el inicio de la conversión y para la selección del canal que
los mostrados en la tabla 11.2.
La rutina de monitorización utiliza el registro R7 como indicador del final de conversión del
convertidor A/D. El tiempo de conversión del convertidor es de unos 100)s. La salida E0C del
convertidor A/D (figura 11.10) está conectada a la entrada de interrupción /INT0 del
microcontrolador a través de una puerta NOT. El final de la conversión se indica con un flanco
3
Para controlar el flujo en la comunicación entre dos sistemas que procesan la información a distinta velocidad, es
frecuente emplear el protocolo XON/XOFF, en el cual se utilizan los caracteres ASCII 11H (XON) y 13H (XOFF), para
iniciar y para detener la transmisión, respectivamente. En este caso, XON y XOFF se usan para indicar el inicio y el final
de la transmisión por parte del microcontrolador.
© Los autores, 2001; © Edicions UPC, 2001.
11 Entradas y salidas analógicas 309
de subida en EOC, que aparece en /INT0 como un flanco de bajada y provoca una interrupción.
La rutina de RSI de /INT0 se limita a poner R7 al valor 01H, indicando de esta manera que la
conversión ha terminado.
MCS-51
P0
P2
A13
/PSEN/EA
Latch
/OE
/CE
A74A0
A104A8
D74D0
EPROM
27C16(2 kbytes)
ALE
74LS373
D74D0 Q74Q0
CLK
IN0
IN1
IN2
IN3
IN4
IN5
IN6
IN7
+
_V1
+
_V2
+
_V3
+
_V4
+
_V5
+
_V6
+
_V7
+
_V8
Sensado y
acondicio-
namiento
de señal
S0
S1
S2
A10
A11
A12
GND CLOCK
74LS04
1k÷1k÷
680pF
EOC
START
ALE A15
A14
A13
OE
74LS08
a
cb
+
1.8k÷
LM336-5V
+12V
+Vref
-Vref
Vcc
+5V
D0-D7
74LS04
A12d
74LS08
c ba
e
74LS04
d
/INT0
AD
C08
09
TXD
RXD
SAI
MC1488
MC1489
RS-232C A la DSP
Fig. 11.10 Convertidor ADC0809 y microcontrolador para la monitorización de las baterías de un equipo SAI
De la misma forma que R7, el registro R6 se emplea por la rutina de RSI del puerto serie para
indicar que se ha recibido, vía RS-232C, el carácter ASCII 05H, que corresponde a la orden de
lectura del A/D. La rutina de RSI, al recibir este carácter, pone el registro R6 al valor 01H, para
que en la rutina principal se proceda a la lectura de todos los canales del convertidor A/D.
La rutina principal tiene un bucle de espera de recepción, de la orden de lectura del convertidor
A/D, que está pendiente del valor del registro R6. Cuando la rutina detecta que R6 se ha puesto
a 01H, ésta pasa a leer cada uno de los canales del convertidor A/D. Para ello, inicia la
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251310
conversión mediante la escritura con MOVX de cualquier dato en una de las direcciones de
inicio y de selección de canal que aparece en la tabla 11.2. Luego, la rutina pasa a la espera del
final de la conversión mediante un bucle que examina continuamente el estado del registro R7.
Finalmente, la rutina pasa a leer el dato obtenido por el convertidor efectuando una lectura en
la dirección C000H con la instrucción MOVX. Terminada la lectura de todos los canales, la
rutina principal pasa a transmitir cada uno de los datos obtenidos a la DSP vía RS-232C.
Memoria de programas
Memoria de datos
0000H
07FFH
FFFFH
EPROM
(2 kbytes)
Sin memoria
a)
b)
0800H
0FFFH
Imagen
(2 kbytes)
1000H
0000H
BFFFH
Sin memoria
FC00HIni. y Canal 7 (1k)
FFFFH
F800HIni. y Canal 6 (1k)
FBFFH
F400HIni. y Canal 5 (1k)
F7FFH
F000HIni. y Canal 4 (1k)
F3FFH
EC00HIni. y Canal 3 (1k)
EFFFH
E800HIni. y Canal 2 (1k)
EBFFH
E400HIni. y Canal 1 (1k)
E7FFH
E000HIni. y Canal 0 (1k)
E3FFH
C000HLectura dato (1k)
DFFFH
Fig. 11.11 Mapa de memoria del circuito de la figura 11.10. a) Mapa de la memoria de programas.b) Mapa de la memoria de datos
La velocidad de transmisión de los datos es de 9.600 baudios; para ello se realiza la
comunicación asíncrona del puerto serie en el modo 1, en el que se transmiten 10 bits: 1 bit de
start, 8 bits del dato y 1 bit de stop. El Timer 1 del microcontrolador se utiliza como base de
tiempos para la transmisión, por lo que debe estar configurado en el modo 2 de 8 bits con
autorrecarga, con el bit C/T a 0 lógico, con el valor FDH de recarga en el registro TH1 y con
11.059MHz de frecuencia de reloj.
El programa que realiza la monitorización de las baterías para la MCS-51 se muestra a
continuación:
;**************************************************************************
; Monitorización de las baterías de un SAI para la MCS-51
;**************************************************************************
; Declaración de variables
;**************************************************************************
Conv_Canal_0 EQU #E000H ;Inicio de conversión y selección del canal 0
Conv_Canal_1 EQU #E400H ;Inicio de conversión y selección del canal 1
Conv_Canal_2 EQU #E800H ;Inicio de conversión y selección del canal 2
Conv_Canal_3 EQU #EC00H ;Inicio de conversión y selección del canal 3
© Los autores, 2001; © Edicions UPC, 2001.
11 Entradas y salidas analógicas 311
Conv_Canal_4 EQU #F000H ;Inicio de conversión y selección del canal 4
Conv_Canal_5 EQU #F400H ;Inicio de conversión y selección del canal 5
Conv_Canal_6 EQU #F800H ;Inicio de conversión y selección del canal 6
Conv_Canal_7 EQU #FC00H ;Inicio de conversión y selección del canal 7
Lectura_AD EQU #C000H ;Lectura del A/D
CA0 EQU 20H ;Dirección 20H de la memoria RAM interna
CA1 EQU 21H ;Dirección 21H de la memoria RAM interna
CA2 EQU 22H ;Dirección 22H de la memoria RAM interna
CA3 EQU 23H ;Dirección 23H de la memoria RAM interna
CA4 EQU 24H ;Dirección 24H de la memoria RAM interna
CA5 EQU 25H ;Dirección 25H de la memoria RAM interna
CA6 EQU 26H ;Dirección 26H de la memoria RAM interna
CA7 EQU 27H ;Dirección 27H de la memoria RAM interna
;**************************************************************************
; Rutina de Vectorización
;**************************************************************************
ORG 0H
LJMP Inicio
ORG 03H
LJMP RSI_INT0
ORG 023H ;Vectorización del puerto de comunicación serie
LJMP RSI_RS
;**************************************************************************
; Rutina de Inicio
;**************************************************************************
Inicio: SETB IT0 ;Interrupción INT0 por flanco descendente
SETB EX0 ;Habilita interrupción INT0
SETB ES ;Habilita interrupción del puerto de comunicación serie
SETB SM1 ;Configura la comunicación serie en el modo 1
SETB REN ;Habilita la recepción de un dato por el puerto serie
MOV TMOD, #20H ;Timer 1 en Modo 2, GATE=0 y C/T=0
MOV TL1, #0FDH ;Valor de TL1, para velocidad de 9600 baudios
MOV TH1, #0FDH ;Valor de recarga de Timer 1, para velocidad de 9600 baudios
SETB EA ;Habilita bit de interrupción general
SETB TR1 ;Pone marcha el Timer 1
;***************************************************************************
; Rutina de Principal
; R7 se emplea como indicador de final de conversión. R7=1 Conversión finalizada.
;***************************************************************************
Principal: CJNE R6, #01, Principal ;Bucle de espera a que R6 sea igual a 01H
MOV R6, #0 ;Borra R6
ACALL Lectura_AD ;Realiza la lectura del A/D
SJMP Principal ;Bucle infinito
;**************************************************************************
; Rutina de servicio de INT0
;**************************************************************************
RSI_INT0: MOV R7, #01H ;Indica mediante R7 el final de la conversión
RETI
;**************************************************************************
; Rutina de servicio del puerto serie
;**************************************************************************
RSI_RS: JNB TI, Recibe ;Si no interrumpe TI, entonces es RI
CLR TI ;Borra bit TI
RETI
Recibe: MOV A, SBUF ;Lee puerto serie
CJNE A, #05H, Noesorden
MOV R6, #01H ;Da la orden de lectura del A/D
Noesorden: CLR RI ;Borra bit RI
RETI
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251312
;***************************************************************************; Subrutinas;***************************************************************************Lectura_AD:MOV R7, #0 ;Borra R7 para la lectura del canal 0
MOV DPTR, #Conv_Canal_0 ;Carga dirección canal en DPTRMOVX @DPTR, A ;Inicio conversión Canal 0
Espera_C0: CJNE R7, #01H, Espera_C0 ;Bucle de espera hasta final de conversiónMOV DPTR, #Lectura_AD ;Carga dirección lectura en DPTRMOVX A, @DPTR ;Lee dato del A/DMOV CA0, A ;Guarda en la memoria interna, pos. 20H
Canal_1: MOV R7, #0 ;Borra R7 para la lectura del canal 1MOV DPTR, #Conv_Canal_1 ;Carga dirección canal en DPTRMOVX @DPTR, A ;Inicio conversión Canal 1
Espera_C1: CJNE R7, #01H, Espera_C1 ;Bucle de espera hasta final de conversiónMOV DPTR, #Lectura_AD ;Carga dirección lectura en DPTRMOVX A, @DPTR ;Lee dato del A/DMOV CA1, A ;Guarda en la memoria interna, pos. 21H
Canal_2: MOV R7, #0 ;Borra R7 para la lectura del canal 2MOV DPTR, #Conv_Canal_2 ;Carga dirección canal en DPTRMOVX @DPTR, A ;Inicio conversión Canal 2
Espera_C2: CJNE R7, #01H, Espera_C2 ;Bucle de espera hasta final de conversión
MOV DPTR, #Lectura_AD ;Carga dirección lectura en DPTR
MOVX A, @DPTR ;Lee dato del A/D
MOV CA2, A ;Guarda en la memoria interna, pos. 22H
Canal_3: MOV R7, #0 ;Borra R7 para la lectura del canal 3
MOV DPTR, #Conv_Canal_3 ;Carga dirección canal en DPTR
MOVX @DPTR, A ;Inicio conversión Canal 3
Espera_C3: CJNE R7, #01H, Espera_C3 ;Bucle de espera hasta final de conversión
MOV DPTR, #Lectura_AD ;Carga dirección lectura en DPTR
MOVX A, @DPTR ;Lee dato del A/D
MOV CA3, A ;Guarda en la memoria interna, pos. 23H
Canal_4: MOV R7, #0 ;Borra R7 para la lectura del canal 4
MOV DPTR, #Conv_Canal_4 ;Carga dirección canal en DPTR
MOVX @DPTR, A ;Inicio conversión Canal 4
Espera_C4: CJNE R7, #01H, Espera_C4 ;Bucle de espera hasta final de conversión
MOV DPTR, #Lectura_AD ;Carga dirección lectura en DPTR
MOVX A, @DPTR ;Lee dato del A/D
MOV CA4, A ;Guarda en la memoria interna, pos. 24H
Canal_5: MOV R7, #0 ;Borra R7 para la lectura del canal 5
MOV DPTR, #Conv_Canal_5 ;Carga dirección canal en DPTR
MOVX @DPTR, A ;Inicio conversión Canal 5
Espera_C5: CJNE R7, #01H, Espera_C5 ;Bucle de espera hasta final de conversión
MOV DPTR, #Lectura_AD ;Carga dirección lectura en DPTR
MOVX A, @DPTR ;Lee dato del A/D
MOV CA5, A ;Guarda en la memoria interna, pos. 25H
Canal_6: MOV R7, #0 ;Borra R7 para la lectura del canal 6
MOV DPTR, #Conv_Canal_6 ;Carga dirección canal en DPTR
MOVX @DPTR, A ;Inicio conversión Canal 6
Espera_C6: CJNE R7, #01H, Espera_C6 ;Bucle de espera hasta final de conversión
MOV DPTR, #Lectura_AD ;Carga dirección lectura en DPTR
MOVX A, @DPTR ;Lee dato del A/D
MOV CA6, A ;Guarda en la memoria interna, pos. 26H
Canal_7: MOV R7, #0 ;Borra R7 para la lectura del canal 7
MOV DPTR, #Conv_Canal_7 ;Carga dirección canal en DPTR
MOVX @DPTR, A ;Inicio conversión Canal 7
Espera_C7: CJNE R7, #01H, Espera_C7 ;Bucle de espera hasta final de conversión
MOV DPTR, #Lectura_AD ;Carga dirección lectura en DPTR
MOVX A, @DPTR ;Lee dato del A/D
MOV CA7, A ;Guarda en la memoria interna, pos. 27H
ACALL Trans_datos
RET
© Los autores, 2001; © Edicions UPC, 2001.
11 Entradas y salidas analógicas 313
Trans_datos:MOV SBUF, #11H ;Caracter XON de inicio de transmisión
MOV SBUF, CA0 ;Transmite dato canal 0
MOV SBUF, CA1 ;Transmite dato canal 1
MOV SBUF, CA2 ;Transmite dato canal 2
MOV SBUF, CA3 ;Transmite dato canal 3
MOV SBUF, CA4 ;Transmite dato canal 4
MOV SBUF, CA5 ;Transmite dato canal 5
MOV SBUF, CA6 ;Transmite dato canal 6
MOV SBUF, CA7 ;Transmite dato canal 7
MOV SBUF, #13H ;Caracter XOFF de final de transmisión
RET
Ejemplo 11.3 Control de la velocidad de un motor
En esta aplicación se debe controlar, mediante un sistema basado en el microcontrolador
8XC251, la velocidad de un motor de corriente continua de pequeña potencia. En la figura
11.12 aparece el esquema general del sistema de control y de la planta a controlar. El
microcontrolador 8XC251 está configurado con 16 líneas de bus de datos: RD1, RD0 = 10.
DAC
ADC
8XC251Motor Tacómetro
Vo
Vi
Fig. 11.12 Diagrama del sistema de control del motor DC
El objetivo del control es mantener constante la velocidad del motor, independientemente de
las condiciones de carga del mismo.
Mediante un convertidor digital/analógico, DAC, de 8 bits se fija la tensión de alimentación del
motor. Conectado al eje del motor se encuentra otro motor que realiza funciones de tacómetro,
generando una tensión proporcional a la velocidad de giro. A través de un convertidor
analógico/digital, ADC, de 8 bits, el microcontrolador adquiere la tensión que genera el
tacómetro, determinando de este modo la velocidad de giro real del motor. El proceso de
control que realiza el microcontrolador 8XC251 consiste en comparar la velocidad real del
motor con la deseada, y modificar convenientemente la combinación binaria aplicada al DAC
para que ambas velocidades, la real y la deseada, se aproximen lo más posible.
a) Conexión del DAC al microcontrolador 8XC251
El DAC utilizado es el AD557 de Analog Devices (figura 11.13). El AD557 es un DAC de 8
bits que incorpora todos los elementos necesarios para conectarlo directamente a un
microcontrolador.
El AD557 dispone de un registro donde se escribe el dato de 8 bits que se debe convertir. Para
escribir en este registro, basta aplicar el dato a las entradas de datos del convertidor (D0,...,D7),
al mismo tiempo que se activan, a 0 lógico, las entradas /CS y /CE.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251314
DACAD557
D0,..,D7
VoCE
CS
8
Fig. 11.13 Conversor AD557
Para ahorrar pines de entrada/salida se puede conectar el convertidor DAC al microcontrolador
como si de un integrado de memoria se tratase, adjudicándole una dirección o rango de
direcciones dentro del mapa de memoria del sistema microcontrolador. En este caso, se
direcciona el convertidor en la posición de memoria externa 0032H. Para realizar la conversión
de un dato, basta grabarlo en la dirección de memoria XX:0032H, donde XX simboliza
cualquier región del mapa de memoria disponible para el usuario: 00:, 01:, 02:, 03:, FC:, FD:,
FE: o FF:. Teniendo en cuenta estas consideraciones, la conexión entre el microcontrolador y el
DAC quedará como aparece en la figura 11.14.
8XC251
LATCH
8 BITS
D0,...D7
CS
CE
DAC
AC 557
P0
ALE
P28
A0
A1A2A3A4A5A6A7
WR
Fig. 11.14 Esquema eléctrico de la conexión microcontrolador - DAC
En el esquema de la figura 11.14 se observa que se ha conectado la salida de escritura, /WR,
del microcontrolador 8XC251, a la entrada de habilitación del convertidor, /CE. Esto se ha
hecho así, para que se active dicha entrada cuando el microcontrolador realice una operación de
escritura, y no de lectura. Por otra parte, se ha conectado la entrada de selección de integrado,
/CS, a la salida de una puerta NAND, cuyas entradas, a su vez, están conectadas a las líneas del
bus de direcciones del microcontrolador. Tal y como se ha realizado la conexión, la salida de
esta puerta NAND se activa, a 0 lógico, cuando en el bus de direcciones aparece la dirección
0032H, o sea, cuando el microcontrolador 8XC251 direcciona, para leer o escribir, la posición
de memoria 0032H. En definitiva, con la conexión realizada, para que se activen las entradas
/CE y /CS del convertidor será necesario que el microcontrolador realice una operación de
escritura en la dirección de memoria 0032H.
Las siguientes instrucciones tienen como objetivo cargar un dato cualquiera denominado “X”,
de 8 bits, en el DAC, escribiendo dicho dato en la dirección 0032H:
MOV R11,#XH
MOV WR0,#0032H
MOV @WR0,R11
© Los autores, 2001; © Edicions UPC, 2001.
11 Entradas y salidas analógicas 315
b) Conexión del ADC al microcontrolador 8XC251
Para realizar la conversión analógico-digital de la tensión generada por el tacómetro se utiliza
el ADC modelo AD673 de Analog Devices (figura 11.15). El AD673 es un convertidor de 8
bits que incorpora todos los elementos necesarios para conectarlo a un microcontrolador. Este
dispositivo dispone de las siguientes señales:
- D0,..,D7: Salidas de datos triestadas. A través de estas salidas podemos leer la
combinación binaria resultado de realizar la conversión de la tensión de entrada Vi
procedente del tacómetro.
- /OE: Habilitación de salida. La activación de esta señal, a 0 lógico, nos permite leer el
dato resultado de la conversión analógico-digital.
- C: Entrada de inicio de conversión. Para iniciar la conversión debemos aplicar un pulso a
esta entrada, o sea, primero un 0 lógico, luego un 1 y, seguidamente, otro 0 lógico.
- /DR: Salida de Data Ready o dato válido. Esta salida se activa, a 0 lógico, cuando el ADC
finaliza la conversión. La activación de esta salida indica al microcontrolador que ya ha
terminado el proceso de conversión y que el dato válido está disponible para ser leído por
el microcontrolador.
ADC AD673
D0,..,D7
ViOE
DR
8
C
Fig. 11.15 Convertidor AD673
En la figura 11.16 aparece el esquema eléctrico simplificado de la conexión del 8XC251 al
ADC. Las líneas de datos y la línea /OE del AD673 están conectadas convenientemente, a las
líneas del microcontrolador 8XC251, para que la lectura del dato se realice cuando se ejecute
una instrucción de lectura de la posición 00:0200H de la memoria externa. Para realizar el
control del ADC por interrupciones, se ha conectado la salida /DR del convertidor a la entrada
/INT0 del microcontrolador, de forma que cuando finaliza la conversión se realiza una petición
de interrupción al microcontrolador. En el programa principal de la aplicación se incluyen
instrucciones que configuran la interrupción /INT0 para que sea activa por flanco descendente
con un nivel de prioridad alto.
8XC251
P1.0
INT0
LatchP0
ALE
P2P2.1
ADC
AD673
Vi
C
DR
OE7
1
Fig. 11.16 Conexión del microcontrolador 8XC251 con el AD673
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251316
En la rutina de servicio a la interrupción /INT0 se incluyen las instrucciones que implementan
el algoritmo de control de la velocidad de giro del motor. En el diseño de esta rutina se han
considerado los siguientes aspectos:
1. El valor de la velocidad deseada está almacenado en la posición 20H de la memoria RAM
interna del microcontrolador.
2. El dato que proporciona el convertidor ADC es la velocidad real. Ambos valores,
velocidad deseada y real, están expresados en binario con 8 bits de precisión.
3. El valor que se graba en el convertidor DAC, y que fija la velocidad real actual del motor,
está almacenado, inicialmente, en la posición 30H de la memoria RAM interna.
La RSI diseñada debe leer el dato válido que le proporciona el convertidor ADC, comparar ese
dato a velocidad real con el valor de la velocidad ideal que está almacenado en la posición 20H
de la memoria RAM interna, y modificar el valor grabado en el DAC según la siguiente
estrategia:
Si la velocidad real es mayor, como mínimo en dos unidades, que la velocidad ideal, se
decrementará en una unidad la combinación binaria aplicada al DAC.
Si la velocidad real es menor, como mínimo en dos unidades, que la velocidad ideal, se
incrementará en una unidad la combinación binaria aplicada al DAC.
En caso contrario no se modificará la combinación binaria escrita en el DAC.
La RSI también debe generar las señales adecuadas para que el convertidor ADC comience una
nueva conversión. A continuación se detallan las instrucciones del programa principal y de la
RSI de la interrupción /INT0:
;********************************************************************************
; Control de la velocidad del motor DC
;********************************************************************************
;Programa principal
ORG FF:0000H ; El programa principal comienza en la dirección FF:0000H.
JMP 0200H ; Para no interferir con la RSI de la interrupción /INT0 se reubica a partir
ORG FF:0200H ; de la dirección FF:0200H
MOV TCON,#01H ; Configura /INT0 para que sea activa por flanco descendente.
MOV IE,#81H ; Habilita la interrupción externa cero.
MOV IPH0,#01H ; Estas instrucciones programan la interrupción INT0
MOV IPL0,#01H ; con nivel de prioridad máximo, nivel 3.
;********************************************************************************
; RSI de la interrupción /INT0
;********************************************************************************
ORG FF:0003H ; La rutina de RSI de /INT0 comienza en la dirección FF:0003H.
JMP FF:0100H ; Debido al tamaño de la rutina de RSI se realiza salto a la
; dirección FF:0100H, donde se dispone de memoria libre.
MOV WR0,#0200H ; Se carga en el registro palabra WR0 la dirección 0200H.
MOV R11,@WR0 ; Pone en R11 el contenido de la dirección 0200H, que es dato convertido.
CJNE A,20H,SIGUE ; Compara la velocidad real con la deseada (almacenada en dir. 20H)
JMP FIN ; Si las velocidades son iguales salta a FIN y va al programa principal.
SIGUE: JNC RESTA ; Salto a RESTA si la velocidad real es mayor que la deseada.
MOV 22H,A ; Si la velocidad real es menor que la deseada, realizo la
MOV A,20H ; diferencia entre la velocidad deseada y la velocidad real.
CLR C ;
SUB A,22H ;
CJNE A,#02H,SIGUE2 ; Se compara la diferencia de velocidades con 2.
JMP FIN ; Si la diferencia es igual a dos salta a FIN y va al programa principal.
© Los autores, 2001; © Edicions UPC, 2001.
11 Entradas y salidas analógicas 317
SIGUE2: JC FIN ; Si la diferencia es menor que dos salta a FIN y retorna al programa principal,
; en caso contrario se debe aumentar la combinación binaria aplicada al DAC
; (direc. 32H) y se salta a FIN para volver al programa principal.
INC 30H ; Se incrementa la posición de memoria 30H
JMP CARGA ; Se salta a CARGA donde se cargará el incremento en la dirección 32H
RESTA: SUB A,20H ; Se hace la resta entre la velocidad real y la deseada.
SIGUE2: CJNE A,#02H,SIGUE3 ; Se compara la diferencia con dos.
JMP FIN ; Si la diferencia es igual a 2 el programa acaba
SIGUE3 JC FIN ; Si la diferencia es menor que dos el programa acaba.
DEC 30H ; Se decrementa el contenido de la posición 30H.
CARGA: MOV A,30H ; Se carga el resultado del decremento en el Acumulador.
MOV DR0,#0032H ; Se carga el resultado en la posición de memoria
MOVH DR0,#0001H ; 01:0032H.
MOV @DR0,R11 ;
FIN: RETI ; Se retorna al programa principal.
En la figura 11.17 se presenta el diagrama de flujo de la rutina de servicio a la interrupción externa
cero, /INT0.
¿DIFERENCIA>2 ?NO
SÍ
INICIO DE LA
ISR DE INT0
SE LEE LA
VELOCIDAD REAL
REAL>DESEADA?SÍ
NO
DIFERENCIA = DESEADA-REAL
RETI
SE INCREMENTA
COMBINACIÓN DAC
¿DIFERENCIA>2 ?NO
SI
DIFERENCIA = REAL-DESEADA
SE CARGA EL NUEVO
VALOR EN EL DAC
SÍ
RETI
SE DECREMENTA
COMBINACIÓN DAC
SE CARGA EL NUEVO
VALOR EN EL DAC
Fig. 11.17 Organigrama de la RSI de la interrupción /INT0
11.5 Conversión A/D utilizando los temporizadores del microcontrolador
Los temporizadores de la MCS-51 se pueden utilizar para medir el ancho de un pulso digital de forma
precisa. El valor de una señal analógica, en un momento determinado, se puede hacer proporcional al
ancho de un pulso digital, comparando la señal analógica con una señal en forma triangular o en forma
de diente de sierra (figura 11.18). En consecuencia, es posible tener una lectura digital del valor de la
señal usando los temporizadores del microcontrolador.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251318
Diente de sierra
_
+Vin, señal analógica
Vin
Vo
w
T
Vmáx
Vo
k k+1 k+2 k+3 k+4 k+5
Fig. 11.18 Obtención de una señal discreta Vo cuyo ancho de pulso w es proporcional al valor en un momentodado de la señal analógica Vin
Utilizando la señal en diente de sierra, la relación entre el ancho de pulso w a medir y el valor de la
señal analógica se puede deducir, fácilmente, de la figura 11.18, y viene dado por la expresión:
�]
T
w1V)k(Vin máx (11.1)
donde Vin(k) es el valor de la señal analógica en el instante k, Vmáx es el máximo valor de tensión
que puede tomar la señal en diente de sierra, T es el período de la señal de diente de sierra y w es el
ancho del pulso obtenido de la señal analógica.
El ancho del pulso de la señal Vo se puede medir de forma precisa con el Timer 0 o con el Timer 1,
debido a que la puesta en marcha y la parada de estos temporizadores puede efectuarse por medio de
las entradas de interrupción /INT0 y /INT1, respectivamente. Por ejemplo, para el Timer 0 poniendo el
bit GATE del registro TMOD a 1 lógico y el bit TR0 del registro TCON a 1 lógico, el temporizador se
pone en marcha cuando /INT0 está a 1 lógico y se detiene cuando está a 0 lógico (figura 7.1). De la
misma forma, se puede gobernar al Timer 1 mediante la entrada /INT1, poniendo los bits GATE y
TR1 a 1 lógicos.
MCS-51
/INT0
W
Fig. 11.19 Lectura de ancho de un pulso a través de /INT0 y del Timer 0 para la MCS-51
Las entradas /INT0 y /INT1 se pueden, además, utilizar para generar una interrupción que indique el
final de la conversión, activando, para ello, las interrupciones por flanco descendente. Por ejemplo,
para el Timer 0 (figura 11.19), el temporizador se pone en marcha cuando /INT0 está a 1 lógico y se
detiene cuando /INT0 pasa a 0 lógico; pero, además, el flanco descendente de /INT0 puede generar
una interrupción que se puede aprovechar como indicativo de final de conversión.
El Timer puede llegar a desbordamiento cuando el ancho de los pulsos a medir sea de una valor
considerable. En este caso, es conveniente que el Timer genere una interrupción cuando llegue a
desbordamiento, que permita contabilizar el número de desbordamientos producidos en la rutina de
© Los autores, 2001; © Edicions UPC, 2001.
11 Entradas y salidas analógicas 319
RSI del Timer. La figura 11.20 muestra un pulso cuyo ancho causa varios desbordamientos en el
Timer, hecho que determina la manera de calcular el valor medido.
Desbordamientos
interrupción del TimerPuesta en marcha ParadaInterrupción
/INT0
64 k 64 k 64 k último lectura
del Timer
Fig. 11.20 Pulso con un ancho que provoca varios desbordamientos del Timer
En este caso, considerando que el Timer tiene el bit C/T a 0 lógico, que está configurado en el modo 1
como temporizador/contador de 16 bits y que la frecuencia de reloj del microcontrolador es de
12MHz, el ancho de un pulso se puede determinar mediante la siguiente ecuación:
s V65536MW )([] (11.2)
donde M es el número de desbordamientos producidos en el Timer, V es el valor de la última lectura
del Timer y 65.536 o FFFFH es el valor de desbordamiento del Timer.
La precisión en la medida del ancho del pulso dependerá de la base de tiempos empleada por los
Timers. Con C/T a 0 lógico (figura 7.1), y con una frecuencia de reloj de 12MHz, la precisión del
temporizador es de un microsegundo. Con C/T a 1 lógico la precisión del Timer dependerá de la señal
de reloj externa (terminales T0 para el Timer 0 y T1 para el Timer 1).
Las rutinas de RSI del Timer 0 y de /INT0 se muestran a continuación, para el caso de la figura 11.19,
donde se desea medir el ancho w de un pulso que puede causar varios desbordamientos. En la rutina
de RSI del Timer 0 se utiliza el registro R7 como contador del número de desbordamientos cometidos
por este.
;************************************************************************
; Rutina de Inicio
;************************************************************************
SETB IT0 ;Activa /INT0 por flanco descendente
SETB EX0 ;Habilita interrupción de /INT0
SETB ET0 ;Habilita interrupción del Timer 0SETB EA ;Habilita bit de interrupción general
MOV TMOD, #09H ;M1=0 y M0=1 (Modo 1), GATE=1 y C/T=0, para Timer 0.
SETB TR0 ;Pone marcha el Timer 0;************************************************************************
; Rutina de servicio del Timer 0
;************************************************************************
RSI_Timer0:INC R7 ;Incrementa contador del nº de desbordamientos
RETI
;************************************************************************
; Rutina de servicio de /INT0
;************************************************************************
RSI_INT0: MOV R6, TH0 ;Lee byte alto del Timer 0MOV R5, TL0 ;Lee byte bajo del Timer 0MOV B, R7 ;Guarda R7 en registro B
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251320
MOV TH0, #0 ;Pone a cero el TimerMOV TL0, #0
MOV R7, #0 ;Borra R7
RETI
La rutina de inicio configura el Timer 0 en el modo 1 como temporizador/contador de 16 bits,
contando pulsos internos de reloj (C/T = 0), y con el bit GATE a 1 lógico. La rutina de RSI del Timer0tan sólo contabiliza el número de desbordamientos de éste. La rutina de RSI de /INT0 guarda la última
lectura del Timer en los registros R5 y R6 (figura 11.20), y a continuación borra los registros del
Timer. El valor del ancho del pulso W se debe obtener de la ecuación (11.2); para ello, se debe
multiplicar el registro B de 1 byte por el dato FFFFH de 2 bytes, y luego sumar al resultado el valor
leído de los registros TH0 y TL0 del Timer. Este cálculo se puede hacer en la rutina de RSI de /INT0 o
en cualquier otra parte del programa.
Ejemplo 11.4 Conversión A/D por modulación de anchura de pulsos utilizando los Timers 0 y 1
En la figura 11.21 se muestra un circuito de conversión analógico/digital con un
microcontrolador de la familia MCS-51, que utiliza el Timer 0 para generar la forma periódica
de la señal en diente de sierra, con un período Tm, y el Timer 1 para medir el ancho del pulso
recibido a través de la entrada de interrupción /INT1.
_
+
R
C
_
+
Diente de sierra
Señal
analógica
Vcc
Vi
Control
interruptor S
/INT1
P1.0
Rt
MCS-51
S
Vo
-Vr Vin
Fig. 11.21 Circuito de conversión A/D mediante modulación de anchura de pulsos con una señal en forma dediente de sierra, empleando un microcontrolador de la MCS-51
La señal en forma de diente de sierra se genera por medio del amplificador operacional, que
hace de circuito integrador con reset, y por medio de la patilla P1.0 del microcontrolador que
controla el cierre y la apertura del interruptor S. El integrador tiene una tensión negativa de
entrada constante, -Vr, por lo que produce a la salida una tensión Vo positiva en forma de
rampa (figura 11.22), cuya pendiente es proporcional a los valores de Vr, R, C y del tiempo de
integración Tm.
RC
Vim ]
T
TRC
ViVo ]
Fig. 11.22
RC
TVrVo
[] (11.3)
© Los autores, 2001; © Edicions UPC, 2001.
11 Entradas y salidas analógicas 321
La señal analógica Vin de entrada proviene de un sensor de temperatura ambiente cuyo margen
de tensión está comprendido entre 0.1V, para -15ºC, y 5V, para 55ºC. El valor máximo de la
tensión de salida del integrador, para adecuarse al margen de la señal analógica, debe ser algo
mayor que 5V; en este caso se toma el valor de 5.1V. La señal analógica tiene una variación
temporal lenta, por lo que se toma una frecuencia de muestreo de 5 muestras por segundo, que
es más que suficiente para tener una representación temporal adecuada de la señal. Para obtener
esta frecuencia, el período de muestreo Tm ha de ser de 0.2s, por lo que, teniendo en cuenta
que el Timer 0 llega a desbordamiento cada 64k pulsos de entrada, es decir, cada 65.536)s, el
número de desbordamientos que debe tener el Timer es de:
051.3s65536
s2,0
s65536
TiempoentosdesbordamiºN ]
)]
)]
Luego, es suficiente con hacer que el Timer 0 desborde tres veces para generar, de forma
aproximada, la frecuencia de muestreo requerida. A partir de la ecuación (11.3) se determina
que con una tensión Vr negativa de 5V, una resistencia de 200k÷ y un condensador de 980nF,
la tensión máxima alcanzada por la rampa en 0.2s es de 5.1V, aproximadamente.
El programa que realiza la conversión A/D por modulación de anchura de pulsos para la MCS-
51 se muestra a continuación:
;**************************************************************************
; Conversión A/D por modulación de anchura de pulsos para la MCS-51
;**************************************************************************
; Rutina de Vectorización
;**************************************************************************
ORG 0H
LJMP Inicio
ORG 0BH
LJMP RSI_Timer0
ORG 013H
LJMP RSI_INT1
ORG 01BH
LJMP RSI_Timer1
;**************************************************************************
; Rutina de Inicio
;**************************************************************************
Inicio:SETB IT1 ; Activa la interrupción /INT1 por flanco descendente
SETB EX1 ; Habilita interrupción /INT1
SETB ET0 ; Habilita la interrupción del Timer 0SETB ET1 ; Habilita la interrupción del Timer 1SETB EA ; Habilita bit de interrupción general
MOV TMOD, #91H ; Timer 1 (Modo 1, GATE=1, C/T=0).Timer 0 (Modo 1, GATE=0, C/T=0)
SETB TR0 ; Pone en marcha el Timer 0SETB TR1 ; Pone en marcha el Timer 1
;***************************************************************************
; Rutina de Principal
;***************************************************************************
Principal: CJNE R3, #01, Principal ;Bucle de espera a que R6 sea igual a 01H
MOV R3, #0 ;Borra R6
ACALL Calcula_w ;Realiza el cálculo del ancho W del pulso
SJMP Principal ;Bucle infinito
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251322
;**************************************************************************
; Rutina de servicio de INT1
;**************************************************************************
RSI_INT1: MOV R6, TH1 ;Pone TH1 en R6
MOV R5, TL1 ;Pone TL1 en R5
MOV B, R7 ;Pone R7 en B
MOV TH1, #0 ;Pone a cero el Timer 1MOV TL1, #0
MOV R7, #0 ;Borra R7
MOV R3,#1 ;Indica con R3 el final de la lectura
RETI
;**************************************************************************
; Rutina de servicio de Timer 0 (Cierra el interruptor S cada 3 desbordamientos del Timer 0)
;**************************************************************************
RSI_Timer0: CJNE R4, #02H, Cont_S ;Si distinto a 02H va a Cont_S
MOV R4, #0 ;Pone a cerro contador de desbordamientos
SETB P1.0 ;Cierra el interruptor S (reset rampa)
CLR P1.0 ;Abre interruptor S
RETI
Cont_S: INC R4 ;Incrementa contador (contador de 0 a 2)
RETI
;**************************************************************************
; Rutina de servicio de Timer 1
;**************************************************************************
RSI_Timer1: INC R7
RETI
;***************************************************************************
; Subrutina de cálculo del ancho del pulso
; entrada: B=Nº de rebasamientos del Timer 1, R6=TH1 y R5=TL1
;Salida: W= FFFFH x B + (TH1,TL1), R0=byte alto, R1=byte intermedio, R0=byte bajo
;***************************************************************************
Calcula_w: MOV A, B ;Pone B (rebasamientos Timer 1) en A
MOV B, #FFH ;Pone FFH en B
MUL AB ;Multiplica
MOV R2, A ;Guarda A en R0
CLR C ;Borra bit de acarreo
ADD A, B ;Suma A y B
MOV R1, A ;Guarda resultado en R1
CLR A ;Borra A
ADDC A, B ;Suma el acarreo anterior a B
MOV R0, A ;Resultado R0=byte alto, R1=byte intermedio y
;R2=byte bajo
CLR C ;Borra acarreo
MOV A, R5 ;R6=TL1, pone TL1 en A
ADD A, R2 ;Suma TL1 y R2
MOV R2, A ;Guarda resultado en R2
MOV A, R6 ;R6=TH1, pone TH1 en A
ADDC A, R1 ;Suma TH1 y R1 con acarreo
MOV R1, A ;Guarda resultado en R1
CLR A ;Borra A
ADDC A, R0 ;Suma el acarreo a R0
MOV R0, A ;Guarda resultado en R0
RET
La rutina de RSI de /INT1 utiliza el registro R3 como indicativo de final de lectura del ancho
del pulso w. El registro R3 se pone al valor 01H cuando se ha finalizado la lectura. La rutina
principal está formada por un bucle de espera del final de la lectura. Este bucle, si detecta que
R3 es igual a 01H, borra el registro y ejecuta la subrutina Calcula_w que efectúa el cálculo del
ancho del pulso. La subrutina implementa la ecuación (11.2) y tiene por entrada el número de
© Los autores, 2001; © Edicions UPC, 2001.
11 Entradas y salidas analógicas 323
rebasamientos del Timer 1 en el registro B, el último valor de TH1 en el registro R6 y el último
valor de TL1 en el registro R5. Las operaciones que efectúa la subrutina Calcula_w se muestran
en la figura 11.23.
La subrutina Calcula_w, de acuerdo con la ecuación (11.2), debe multiplicar el contenido del
registro B por 65.536, o FFFFH. Esta multiplicación se lleva a cabo en dos partes: una primera
multiplicación de B por FFH y una suma posterior de los resultados. La instrucción MUL AB
sólo se ejecuta una vez, puesto que el byte alto y el byte bajo del dato FFFFH son los mismos.
El resultado de la suma, M0, M1 y M2 (figura 11.23), se almacena en los registros R0, R1 y
R2, respectivamente.
FFFFH
x B
C1 C2
C3 C4
M0 M1 M2
+ TH1 TL1
S0 S1 S2
Fig. 11.23 Operaciones que realiza la subrutina Calcula_w
Al resultado de la multiplicación se le suma el valor de los registros del Timer 1, que están
almacenados en los registros R6 y R5. El resultado final de la suma, S0, S1 y S2, se sitúa en los
registros R0, R1 y R2, respectivamente.
Para efectuar el reset del circuito integrador es suficiente con poner a 1 lógico la patilla P1.0
con la instrucción SETB en la rutina de RSI del Timer 0, cerrando el interruptor S y forzando la
salida Vo a cero voltios. La siguiente instrucción pone a 0 lógico la patilla P1.0, abriendo el
interruptor S y dejando actuar al integrador como tal. En el programa realizado no se contempla
ningún uso posterior del valor de temperatura leído por el microcontrolador. Este valor se
puede visualizar en una serie de dígitos de siete segmentos y se puede utilizar para realizar una
regulación de la temperatura del sistema medido.
Ejemplo 11.5 Sistema de adquisición de temperatura con el sensor MAX6576
En la figura 11.24 se presenta el esquema de un sistema de adquisición de temperatura donde se
utiliza un sensor de temperatura MAX6576, de la compañía MAXIM, que suministra una señal
binaria cuyo período es proporcional a la temperatura absoluta:
Período = C · T(ºK) (11.1)
donde C es una constante de proporcionalidad que puede tener cuatro posibles valores entre
10µs/ºK y 640µs/ºK, seleccionables mediante las entradas TS0 y TS1.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251324
MAX6576
TS0
TS1OUT
8XC251
P0.0
VDD
+2.7 a +5.5V
Fig. 11.24 Sistema de adquisición de temperatura con el sensor MAX6576
En esta aplicación, la función del microcrontrolador es la de calcular la temperatura de acuerdo
con el período medido de la onda cuadrada, mediante uno de los temporizadores del µC. Con
las entradas TS0 y TS1 conectadas a masa, la constante de proporcionalidad período/
temperatura, C, adquiere el valor 10µs/ºK, por lo que el período viene dado por:
Período = 10µs/ºK · T(ºK) (11.2)
El programa que controla esta aplicación debe configurar el Timer 0 para que trabaje como
temporizador en modo 1, e inicializar su valor a cero. Seguidamente se pone en marcha durante
el tiempo equivalente a un período de la onda cuadrada. A partir del valor que tiene el Timer 0,
una vez detenido su funcionamiento, se calcula la temperatura.
Si la frecuencia de la señal de reloj del microcontrolador es de 12MHz, el Timer 0 se
incrementa una vez cada microsegundo, por lo que la relación entre la temperatura y el número
de incrementos sufrido por el Timer 0 vendrá dado por:
Temperatura (ºC) = (N –2731)/10 (11.3)
donde N es el número de incrementos sufrido por el Timer 0.
A continuación se detalla el programa que controla el funcionamiento del sistema de
adquisición de temperatura del ejemplo 11.5.
;*************************************************************
; Control de la sistema de adquisión del ejemplo 11.5
;*************************************************************
;Programa principal
ORG FF:0000H ; El programa principal comienza en la dirección FF:0000H.
MOV TMOD,#01H ; Se configura el Timer 0 como temporizador en modo 1.
MOV TH0,#00H ; Se inicializa el Timer 0 con el valor 0.
MOV TL0,#00H ;
SIG1: JB P0.0,SIG1 ; Se espera a que comience un período con un 1 lógico
SIG2: JNB P0.0,SIG2 ;
SETB TR0 ; Se pone en marcha el Timer 0.
SIG3: JB P0.0,SIG3 ; Se espera a que pase el período.
SIG4: JNB P0.0,SIG4 ;
CLR TR0 ; Se detiene el Timer 0.
© Los autores, 2001; © Edicions UPC, 2001.
11 Entradas y salidas analógicas 325
MOV R2,#TH0 ; Se carga en el registro WR2 el contenido del Timer 0.
MOV R3,#TL0 ;
MOV WR0,#2731D ;
MOV WR4,#10D ;
SUB WR2,WR0 ; Se resta del contenido del Timer 0 el valor 2731 y se divide entre 10
DIV WR2,WR4 ; para obtener la temperatura en grados centígrados en el registro WR2.
Ejemplo 11.6 Adquisición de temperatura con el sensor MAX6577
La compañía MAXIM dispone de otro sensor de temperatura, el MAX6577, que genera una
onda cuadrada cuya frecuencia es proporcional a la temperatura en ºK:
Frecuencia = F · T(ºK) (11.4)
donde F es el coeficiente de proporcionalidad, que puede adquirir uno de entre cuatro posibles
valores entre 0.0675Hz/ºK y 4Hz/ºK, seleccionables mediante las entradas TS0 y TS1.
En la figura 11.25 se muestra el esquema eléctrico de un sistema de adquisición y visualización
de temperatura basado en el microcontrolador 8XC251 y en el sensor MAX6577.
MAX6577
TS0TS1
OUT
8XC251
T0
VDD
+2.7 a +5.5V
P1.0
P1.1
P1.2
P1.3
P1.4
P1.5
P1.6
P1.7
+5V
Fig. 11.25 Esquema eléctrico del ejemplo 11.6
En este ejemplo la entrada TS0 del sensor MAX6577 está conectada a la tensión de
alimentación, mientras que la entrada TS1 está conectada a masa, de modo que el factor de
escala F vale 1Hz/ºK. La señal de salida del sensor se introduce en la entrada de cuenta del
Timer 0. La temperatura medida se muestra en binario y en grados centígrados a través de los
leds conectados al puerto P1. La estrategia de control de esta aplicación consiste en medir la
frecuencia de la señal de salida del sensor de temperatura, contando los pulsos que genera
durante un segundo. Para ello se utiliza el Timer 0 para contar los pulsos, y el Timer 1,
controlado mediante interrupción, para temporizar 1 segundo. Si se considera que la frecuencia
de funcionamiento del microcontrolador es de 12MHz, el Timer 1 se incrementa en una unidad
cada mocrosegundo. Si se incializa este Timer con el valor 3CB0H, tarda 50ms en llegar a
rebasamiento, por lo que debe rebasar 20 veces para temporizar un segundo.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251326
Una vez transcurrido 1s, se resta el número 273 al valor contenido en el Timer 0 para obtener la
temperatura en grados centígrados. Este valor de temperatura se carga posteriormente en el
puerto P1 para ser visualizado a través de los leds.
A continuación se muestra el listado del programa que controla el sistema de adquisión de
temperatura.
;*************************************************************
; Control de la sistema de adquisión del ejemplo 11.6
;*************************************************************
;Programa principal
ORG FF:0000H ; El programa principal comienza en la dirección FF:0000H., pero se
; reubica en la dirección FF:1000H para no interferir con la RSI del Timer 1.
JMP 1000H
ORG FF:1000H ; Comienzo del programa principal.
MOV TMOD,#15H ; Se programa el Timer 1 como temporizador y el Timer 0 como
; contador.
MOV TH0,#00H ; Se inicializa el Timer 0 a cero.
MOV TL0,#00H ;
MOV TH1,#3CH ; Se incializa el Timer 1 para temporizar 20ms.
MOV TL1,#B0H ;
MOV TCON,#50H ; Se pone en marcha los Timers 0 y 1.
MOV R0,#20D ; Se inicializa el contador R0 con 20.
MOV IE,#88H ; Habilita la interrupción del Timer 1 y se activa el bit EA.
CLR F0 ;
ESPERA:JNB F0,ESPERA;
; RSI del Timer 1
ORG FF:001BH ; Dirección de comienzo de la RSI del Timer 1.
MOV TH1,#3CH ;
MOV TL1,#B0H ;
DJNZ TICKS,FIN ;
MOV R10,TH0 ; Se carga el valor del Timer 0 en el registro WR0
MOV R11,TL0 ;
SUB WR10,#273D ; Se resta 273 al valor del Timer 0 para obtener la temperatura
; en grados centígrados.
CPL A ; Se complementa el valor de la temperatura para activar los leds a nivel
MOV P1,R11 ; bajo.
MOV TH0,#00H ; Se inicializa de nuevo el Timer 0 a cero.
MOV TL0,#00H ;
MOV R0,#20D ; Se inicializa el contador R0 con 20.
FIN: RETI
© Los autores, 2001; © Edicions UPC, 2001.
12 Modos especiales de funcionamiento 327
12 Modos especiales de funcionamiento
12.1 Introducción
Los modos especiales de funcionamiento Idle y Power Down se utilizan principalmente en aquellas
aplicaciones donde el consumo es un factor crítico, como por ejemplo los equipos portátiles, los
equipos de comunicaciones móviles, etc. El modo ONCE, On-Circuit Emulation, se utiliza para
realizar el test de las aplicaciones. Estos modos se pueden encontrar en microcontroladores de las
familias MCS-51 y MCS-251.
12.2 Registro de control de potencia (PCON)
El registro de función específica PCON tiene dos bits de control del puerto de comunicación serie,
varios bits para seleccionar los modos de funcionamiento Idle y Power Down, un bit de Power Off,que detecta fallos en la tensión de alimentación, y dos bits de propósito general (tabla 12.1).
12.2.1 Bits de control del puerto serie
El bit SMOD1 del registro PCON permite doblar la velocidad de transmisión del puerto de
comunicación serie. Por otra parte, el bit SMOD0 del registro PCON determina la función del bit 7 del
registro SCON. En el caso que SMOD0 esté a 1 lógico, el bit SCON.7 permite leer o escribir el bit
Framing Error (FE). Cuando SMOD0 está a cero el bit SCON.7 trabaja como bit SM0 del puerto de
comunicación serie.
12.2.2 Bit de Power Off (POF)
El bit de Power Off se pone automáticamente a 1 lógico cuando la tensión de alimentación del
microcontrolador, Vcc, aumenta desde Vcc<3V hasta Vcc>3V. Con la activación de este bit se pone
de manifiesto que el contenido de la memoria RAM interna es indeterminado, circunstancia que
ocurre, por ejemplo, cuando se aplica la tensión de alimentación al integrado. Este bit puede ser
puesto a uno o a cero por programa.
En general, este bit se verifica después de un reset del microcontrolador, para determinar si el reset se
ha realizado por una puesta en marcha de la aplicación, por un fallo de la alimentación, o bien ha sido
un reset efectuado con el microcontrolador en funcionamiento normal. En los dos primeros casos, este
bit se pone a 1 para indicar que el contenido de la memoria volátil interna es indeterminado; en este
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251328
caso lo habitual es borrar el bit mediante una instrucción. En el tercer caso, este bit permanece a 0
lógico. Si se detecta que el bit POF se pone a 1 por otro motivo, por ejemplo, si se produce una deriva
en la tensión de alimentación que provoca que Vcc baje por debajo de 3V, se deberá realizar un resetpor software para reinicializar el microcontrolador.
Tabla 12.1 Registro de control de potencia
PCON Valor de Reset: 00XX 0000b
b7 b6 b5 b4 b3 b2 b1 b0
SMOD1 SMOD0 -- POF GF1 GF0 PD IDL
Bit Mnemónico Función7 SMOD1 Bit de doble velocidad de transmisión.
Cuando este bit está a uno se dobla la velocidad de transmisión de datos del
puerto de comunicación serie, cuando se utiliza el Timer 1 y el puerto serie
está trabajando en el modo 1, 2 o 3.
6 SMOD0 Selección de SCON.7.Cuando este bit está a 1 lógico, el bit SCON.7 permite leer o escribir el bit
Framing Error. Cuando este bit está a cero, el bit SCON.7 realiza la función
de SM0.
5 -- Reservado.Este bit está reservado y no puede ser utilizado por el usuario.
4 POF Bit de Power Off.
Este bit se pone a uno lógico cuando la tensión de alimentación baja por
debajo de los 3 voltios o cuando se aplica la alimentación al
microcontrolador. Con esta activación se indica que el contenido de la
memoria RAM interna es indeterminado. Este bit se puede borrar por
software.
3 GF1 Bit de propósito general.2 GF0 Bit de propósito general.1 PD Bit de modo Power Down.
Cuando este bit está a 1 lógico se activa el modo Power Down. Este bit se
pone a cero cuando se realiza un reset del microcontrolador, o bien, cuando
se realiza una petición de interrupción.
0 IDL Bit de modo Idle.Cuando este bit está a 1 lógico se activa el modo Idle. Este bit se pone a cero
cuando se realiza un reset del microcontrolador, o bien, cuando se realiza una
petición de interrupción.
12.3 Modo Idle
El modo Idle es un modo de consumo reducido que permite reducir la potencia consumida por el
microcontrolador cerca del 40% de la potencia de consumo nominal. En este modo se impide que la
señal de reloj llegue a la CPU, deteniéndose la ejecución del programa (figura 12.1), aunque los
periféricos del microcontrolador siguen recibiendo la señal de reloj, lo que permite su normal
funcionamiento.
© Los autores, 2001; © Edicions UPC, 2001.
12 Modos especiales de funcionamiento 329
Durante el modo Idle el contenido de los registros de la CPU permanece intacto, así como el
contenido de la memoria RAM interna y de los registros del área SFR.
Para entrar en el modo de funcionamiento Idle se debe poner a uno lógico el bit IDL del registro
PCON.
Existen dos formas de salir del modo Idle:
÷ Generando una interrupción que esté habilitada. Cuando se activa una fuente de
interrupción que está habilitada se pone a cero automáticamente el bit IDL. Después de
ejecutar la rutina de servicio a la interrupción, el microcontrolador continúa ejecutando el
programa principal por la instrucción siguiente a aquella que puso el bit IDL a uno lógico.
÷ Realizando un reset del microcontrolador. Cuando se aplica un nivel alto al pin de reset del
microcontrolador, se borra automáticamente el bit IDL. El microcontrolador continúa
ejecutando de forma momentánea el programa principal por la instrucción siguiente a la que
activó el bit IDL, hasta que el algoritmo de reset interno toma el control e inicializa el
contador de programa con la dirección FF:0000H.
12.4 Modo Power Down
El modo Power Down coloca al microcontrolador 8XC251Sx en modo de consumo muy reducido. En
este modo de trabajo se para completamente la actividad del reloj, de forma que tanto la CPU como
los periféricos detienen su funcionamiento. El contenido de todos los registros, así como de la
memoria RAM interna, se mantienen invariables en este modo de trabajo.
Para entrar en este modo de trabajo se debe poner a 1 lógico el bit PD del registro PCON. La
instrucción que pone a 1 el bit PD es la última que se ejecuta antes de que el microcontrolador entre en
el modo Power Down.
XTAL1
XTAL2
C1
C2
PD
OSC
Clock
Gen
IDL
CPU
Interrupciones
Puerto serie
Timers
Fig. 12.1 Control del reloj mediante los bits Idle y Power Down
Hay dos maneras de salir del modo Power Down:
÷ Generando una interrupción externa. Cuando se activa una fuente de interrupción externa
que está habilitada para interrumpir, el bit PD se pone a cero automáticamente, de forma que
la CPU y los periféricos vuelven a recibir la señal de reloj. Inmediatamente después, la CPU
ejecuta la rutina de servicio a la interrupción y, a continuación, sigue ejecutando el programa
principal por la instrucción siguiente a la que activó el bit PD.
© Los autores, 2001; © Edicions UPC, 2001.
Microcontroladores MCS-51 y MCS-251330
÷ Realizando un reset del microcontrolador. Cuando se aplica un nivel alto al pin de reset del
microcontrolador se pone a cero el bit PD, lo que permite a la CPU y los periféricos continuar
con su funcionamiento normal. El microcontrolador continúa ejecutando de forma
momentánea el programa principal por la instrucción siguiente a la que activó el bit IDL,
hasta que el algoritmo de reset interno toma el control e inicializa el contador de programa
con la dirección FF:0000H.
12.5 Modo ONCE (On-Circuit Emulation)
El modo ONCE permite realizar el test del sistema sin extraer el microcontrolador 8XC251Sx de la
placa de circuito impreso, lo que facilita el proceso de depuración y comprobación del programa. En
este modo, el microcontrolador permanece aislado eléctricamente del sistema.
En la MCS-251, para entrar en el modo ONCE se debe seguir la siguiente secuencia:
1. Aplicar un nivel alto en el pin de reset (RST).
2. Mientras se mantiene el pin de reset a 1 lógico se debe aplicar y mantener los pines /PSEN,
P0.7, P0.6, P0.5, P0.3, P0.2, P0.1 y P0.0 a nivel bajo y el pin P0.4 a nivel alto.
3. Se deja de aplicar la señal de reset, para a continuación dejar de aplicar los niveles lógicos
indicados en el puerto P0 y el pin /PSEN.
En la MCS-51, para entrar en el modo ONCE se debe:
1. Poner a 0 lógico la patilla ALE mientras el microcontrolador está en la fase de reset y el
terminal /PSEN está a 1 lógico.
2. Mantener ALE a 0 lógico mientras el reset (terminal RST) es desactivado.
Para la MCS-51, cuando el microcontrolador está en el modo ONCE, el puerto P0 permanece flotante
en estado de alta impedancia, y el resto de los puertos, junto con el terminal ALE y /PSEN, están
conectados débilmente a 1 lógico.
Para salir del modo ONCE basta con efectuar un reset del microcontrolador.
© Los autores, 2001; © Edicions UPC, 2001.
Apéndice Juego de instrucciones de la familia MCS-51 y MCS-251 331
JUEGO DE INSTRUCCIONES DE LA FAMILIA MCS-51Mnemónico Descripción de los símbolos empleados
dir8 Dirección directa de 8 bits. Posiciones de memoria interna o área de SFR.
dir16 Dirección 16 bits de memoria empleada en direccionamientos directos.
dir11 Dirección de 11 bits.
#dato Constante de 8 bits.
#dato16 Constante de 16 bits.
Rn Registro de tipo byte, R0 a R7.
@Ri Direccionamiento indirecto a través de R0 o R1. Se accede a las posiciones (00H-FFH) de la memoria interna.
bit Bit de la memoria RAM interna o de un registro del área de SFR accesible bit a bit.
rel Dirección de salto. Puede ser un salto incondicional, condicional o de llamada a subrutina.
Mnemónico <dest>,<src> Descripción Bytes Tpo*Instrucciones de transferencia de datos
MOV
A, Rn
A, dir8
A, @Ri
A, #dato
Rn, A
Rn, dir8
Rn, #dato
dir8, A
dir8, Rn
dir8, dir8
dir8, @Ri
dir8, #dato
@Ri, A
@Ri, dir8
@Ri, #dato
DPTR,#dato16
A = Rn. Copia el valor de Rn en A
A = (dir8) Copia el contenido de la dirección dir8 en A
A = (@Ri) Copia el valor direccionado por @Ri en A
A = #dato Pone el dato en A
Rn = A Copia el valor de A en Rn
Rn = (dir8) Copia el contenido de la dirección dir8 en Rn
Rn = #dato Pone el dato en Rn
(dir8) = A Copia el valor de A en la dirección dir8
(dir8) = Rn Copia el valor de Rn en la dirección dir8
(dir8) = (dir8) Copia de la dirección src a la dirección dest(dir8) = (@Ri) Copia la posición direccionada por @Ri en la dirección dir8
(dir8) = #dato Copia el dato en la dirección dir8
(@Ri) = A Copia A en la posición direccionada por @Ri
(@Ri) = (dir8) Copia la dirección dir8 en la posición direccionada por @Ri
(@Ri) = #dato Copia el dato en la posición direccionada por @Ri
DPTR = #dato16 Pone el dato de 16 bits en el DPTR
1
2
1
2
1
2
2
2
2
3
2
3
1
2
2
3
1
1
1
1
1
2
1
1
2
2
2
2
1
2
1
2
MOVXA, @Ri
A, @DPTR
@Ri, A
@DPTR, A
A = (@Ri) Copia en A el byte de la RAM externa apuntada por @Ri
A = (@DPTR) Copia en A el byte de la RAM externa apuntada por @DPTR
(@Ri) = A Copia A en posición de RAM externa apuntada por @Ri
(@DPTR) = A Copia A en posición de RAM externa apuntada por @DPTR
1
1
1
1
2
2
2
2
MOVC A, @A+DPTR
A, @A+PC
A = (A + DPTR) Pone en A el byte de código apuntado por @A+DPTR
A = (A + PC) Pone en A el byte de código apuntado por @A+PC
1
1
2
2
PUSH dir8 Mete el byte de la dirección dir8 en la pila 2 2
POP dir8 Mete el byte de la dirección dir8 en al pila 2 2
XCHA, Rn
A, dir8
A, @Ri
Intercambia A y Rn
Intercambia A y el byte de la dirección dir8
Intercambia A y el byte apuntado por @Ri
1
2
1
1
1
1
XCHD A, @Ri Intercambia los cuatro bits bajos de A y del byte apuntado por @Ri 1 1
Instrucciones aritméticas
ADDA, Rn
A, dir8
A, @Ri
A, #dato
A=A+ Rn Suma A con Rn, pone el resultado en A
A=A+ (dir8) Suma A con el byte de la dirección dir8, pone el resultado en A
A=A+ (@Ri) Suma A con el byte apuntado por @Ri, pone el resultado en A
A=A+ dato Suma A con el dato, pone el resultado en A
1
2
1
2
1
1
1
1
ADDCSUBB
A, Rn
A, dir8
A, @Ri
A, #dato
A=A÷ Rn Suma (+) para ADDC y resta (-) para SUBB
A=A ÷ (dir8) ÷ C Suma (+) para ADDC y resta (-) para SUBB
A=A ÷ (@Ri ) ÷ C Suma (+) para ADDC y resta (-) para SUBB
A=A ÷ dato ÷ C Suma (+) para ADDC y resta (-) para SUBB
1
2
1
2
1
1
1
1
INCDEC
A
Rn
dir8
@Ri
A=A ÷ 1 Signo + para INC. Signo - para DEC
Rn=Rn ÷ 1 Signo + para INC. Signo - para DEC
(dir8) = (dir8) ÷ 1 Signo + para INC. Signo - para DEC
(@Ri ) = (@Ri ) ÷ 1 Signo + para INC. Signo - para DEC
1
1
2
1
1
1
1
1
INC DPTR DPTR = DPTR +1 Incremento del DPTR 1 2
MUL AB Multiplica A por B. Deja el byte alto del resultado en B y el byte bajo en A 1 4
DIV AB Divide A por B. Deja el cociente en A y el resto en B 1 4
DA A Ajuste decimal del acumulador 1 1
© Los autores, 2001; © Edicions UPC, 2001.
Apéndice 1 Juego de instrucciones de la familia MCS-51332
Mnemónico <dest>,<src> Descripción Bytes Tpo*Instrucciones lógicas
ANLORLXRL
A, Rn
A, dir8
A, @Ri
A, #dato
dir8, A
dir8, #dato
A = A AND o OR o XOR Rn Función AND, OR o XOR lógica
A = A AND o OR o XOR (dir8) Función AND, OR o XOR lógica
A = A AND o OR o XOR (@Ri) Función AND, OR o XOR lógica
A = A AND o OR o XOR #dato Función AND, OR o XOR lógica
(dir8) = (dir8) AND o OR o XOR A Función AND, OR o XOR lógica
(dir8) = (dir8) AND o OR o XOR #dato Función AND, OR o XOR lógica
1
2
1
2
2
3
1
1
1
1
2
CLR A A = 0 Borra el acumulador 1 1
CPL A Complementa el acumulador 1 1
RL A Rotación a la izquierda del acumulador 1 1
RLC A Rotación a la izquierda con acarreo del acumulador 1 1
RR A Rotación a la derecha del acumulador 1 1
RRC A Rotación a la derecha con acarreo del acumulador 1 1
SWAP A Intercambia los 4 bits bajos del acumulador con sus 4 bits altos 1 1
Instrucciones booleanas
CLR C
bit
Pone a cero el bit de acarreo
Pone a cero el bit direccionado
1
2
1
1
SETB C
bit
Pone a uno el bit de acarreo
Pone a uno el bit direccionado
1
2
1
1
CPL C
bit
Complementa el bit de acarreo
Complementa el bit direccionado
1
2
1
1
ANL C, bit
C, /bit
C = C AND (bit) AND lógica entre C y el bit, resultado lo pone en C
C = C AND (/bit) AND lógica entre C y el bit complementado, resultado en C
2
2
2
2
ORL C, bit
C, /bit
C = C OR (bit) OR lógica entre C y el bit, resultado lo pone en C
C = C AND (/bit) OR lógica entre C y el bit complementado, resultado en C
2
2
2
2
MOV C, bit
bit, C
C = bit Pone el valor del bit en el bit de acarreo C
bit = C Pone el valor del bit de acarreo en el bit indicado
2
2
1
2
Instrucciones de salto incondicionalAJMP dir11 Salto absoluto. Salta a una dirección de 11 bits 2 2
LJMP dir16 Salto largo. Salta a cualquier dirección del espacio de memoria 3 2
SJMP rel Salto corto con direccionamiento relativo 2 2
JMP @A+DPTR Salto indirecto a la dirección A + DPTR 1 2
NOP Salto a la siguiente instrucción 1 1
Instrucciones de salto condicionalJC rel Salta si el bit de acarreo está a 1 lógico 2 2
JNC rel Salta si el bit de acarreo está a 0 lógico 2 2
JB bit, rel Salta si el bit direccionado está a 1 lógico 3 2
JNB bit, rel Salta si el bit direccionado está a 0 lógico 3 2
JBC bit, rel Salta si el bit direccionado está a 1 lógico y luego lo pone a 0 lógico 3 2
JZ rel Salta si el acumulador vale cero 2 2
JNZ rel Salta si el acumulador es distinto de cero 2 2
CJNEA, dir8, rel
A, #dato, rel
Rn, #dato, rel
@Ri,#dato,rel
Compara A con el valor de la dirección dir8 y hace un salto relativo si son distintos
Compara A con el dato y hace un salto relativo si son distintos
Compara Rn con el dato y hace un salto relativo si son distintos
Compara el byte apuntado por @Ri y hace un salto relativo si son distintos
3
3
3
3
2
2
2
2
DJNZ Rn, rel
dir8, rel
Decrementa Rn en una unidad y hace un salto relativo si Rn es distinto de cero
Decrementa el byte de dir8 y hace un salto relativo si es distinto de cero
2
3
2
2
Instrucciones de llamada y retorno a subrutinasACALL dir11 Llamada a subrutina de tipo absoluto, dirección de 11 bits 2 2
LCALL dir16 Llamada a subrutina tipo long, dirección de 16 bits 3 2
RET Retorno de subrutina 1 2
RETI Retorno de la rutina de servicio a la interrupción 1 2
*El tiempo de ejecución, Tpo, viene dado en ciclos máquina
© Los autores, 2001; © Edicions UPC, 2001.
Apéndice Juego de instrucciones de la familia MCS-51 y MCS-251 333
JUEGO DE INSTRUCCIONES ADICIONALES DE LA FAMILIA MCS-251Notación de los
registros Descripción
Rm
Rms
Rmd
Registro tipo byte de R0 a R15
Registro fuente
Registro destino
WRj
WRjd
WRjs
@WRj+dis16
Registro de tipo Word WR0, WR2, …., WR30
Registro destino
Registro fuente
Dirección de memoria (00:0000H-00:FFFFH) direccionada indirectamente a través de un registro de
tipo Word (WR0-WR30) más un valor de desplazamiento comprendido entre 0 y 64 Kbytes
DRk,
DRkd
DRks
@DRk+dis24
Registro de tipo DR (Double Word) DR0, DR4, …, DR28 DR56, DR60.
Registro de destino
Registro fuente.
Dirección de memoria (00:0000H-00:FFFFH) direccionada indirectamente a través de un registro
Double Word (DR0, DR4, …, DR56, DR60) más un valor de desplazamiento de 0 a 64 Kbytes.
Dato inmediato Descripción#0dato16
#1dato16
Un valor de 32 bits que se direcciona de forma inmediata en una instrucción. Los 16 bits de mayor peso
del dato deben ser 0 (#0data16) ó 1 (#1data16).
#short Un valor igual a 1, 2 ó 4, que es direccionado de forma inmediata en una instrucción.
Direcciones Descripciónrel Dirección relativa de 8 bits expresada en complemento a 2.
addr11 Dirección de 11 bits.
addr16 Dirección de 16 bits.
addr24 Dirección de 24 bits. Permite acceder a cualquier dirección de los 16 Mbyte del espacio de memoria de
la familia MCS-251.
Mnemónico <dest>,<src> Descripción Bytes Tclock
Instrucciones aritméticasADDSUB
Rmd,Rms
WRjd,WRjs
DRkd,DRks
Rm,#data
WRj,#data16
DRk,#0data16
Rm,dir8
WRj,dir8
Rm,dir16
WRj,dir16
Rm,@WRj
Rm,@DRk
Rmd = Rmd ± Rms
WRjd = WRjd ± WRjs
DRkd = DRkd ± DRks
Rm = Rm ± data
WRj = WRj ± data16
DRk = DRk ± 0data16
Rm = Rm ± (dir8)
WRj = WRj ± (dir8, dir8+1)
Rm = Rm ± (dir16)
WRj = WRj ± (dir16,dir16+1)
Rm = Rm ± (@WRj)
Rm = Rm ± (@DRk)
2
2
2
3
4
4
3
3
4
4
3
3
2
4
8
4
6
10
4
6
4
6
4
6
CMP Rmd,Rms
WRjd,WRjs
DRkd,DRks
Rm,#data
WRj,#data16
DRk,#0data16
DRk,#1data16
Rm,dir8
WRj,dir8
Rm,dir16
WRj,dir16
Rm,@WRj
Rm,@DRk
Rmd - Rms
WRjd - WRjs
DRkd - DRks
Rm - #data
WRj - #data16
DRk - #0data16
DRk - #1data16
Rm - (dir8)
WRj - (dir8, dir8+1)
Rm - (dir16)
WRj - (dir16,dir16+1)
Rm - (@WRj)
Rm - (@DRk)
2
2
2
3
4
4
4
3
3
4
4
3
3
2
4
8
2
6
10
10
4
6
4
6
2
6
INCDEC
Rm,#short
WRj,#short
DRj,#short
Rn = Rn ± #short†
WRj = Wrj ± #short†
DRj = DRj ± #short†
2
2
2
2
2
6
MUL Rmd,Rms
WRjd,WRjs
Multiplica Rmd y Rms
Multiplica WRjd y WRjs
2
2
10
22
© Los autores, 2001; © Edicions UPC, 2001.
Apéndice 1 Juego de instrucciones de la familia MCS-51334
Mnemónico <dest>,<src> Descripción Bytes Tclock
Instrucciones aritméticas (continuación)DIV Rmd,Rms
WRjd,WRjs
Divide Rmd por Rms
Divide WRjd por WRjs
2
2
20
40
Instrucciones lógicasANLORLXRL
Rmd,Rms
WRjd,WRjs
Rm,#data
WRj,#data16
Rm,dir8
WRj,dir8
Rm,dir16
WRj,dir16
Rm,@WRj
Rm,@DRk
Rmd = Rmd AND ó OR ó XOR Rms
WRjd = WRjd AND ó OR ó XOR WRjs
Rm = Rm AND ó OR ó XOR #data
WRj = WRj AND ó OR ó XOR #data16
Rm = Rm AND ó OR ó XOR (dir8)
WRj = WRj AND ó OR ó XOR (dir8, dir8+1)
Rm = Rm AND ó OR ó XOR (dir16)
WRj = WRj AND ó OR ó XOR (dir16, dir16+1)
Rm = Rm AND ó OR ó XOR (@WRj)
Rm = Rm AND ó OR ó XOR (@DRk)
2
2
3
4
3
3
4
4
3
3
2
4
4
6
4
6
4
6
4
6
SLL Rm
WRj
Desplazamiento lógico a la izquierda de Rm
Desplazamiento lógico a la izquierda de WRj
2
2
2
2
SRA Rm
WRj
Desplazamiento aritmético a la derecha de Rm
Desplazamiento aritmético a la derecha de WRj
2
2
2
2
SRL Rm
WRj
Desplazamiento lógico a la derecha de Rm
Desplazamiento lógico a la derecha de WRj
2
2
2
2
Instrucciones de transferencia de datos
MOV Rmd,Rms
WRjd,WRjs
DRkd,DRks
Rm,#data
WRj,#data16
DRk,#0data16
DRk,#1data16
DRk,dir8
DRk,dir16
Rm,dir8
WRj,dir8
Rm,dir16
WRj,dir16
Rm,@WRj
Rm,@DRk
WRjd,@WRjs
WRj,@DRk
dir8,Rm
dir8,WRj
dir16,Rm
dir16,WRj
@WRj,Rm
@DRk,Rm
@WRjd,WRjs
@DRk,WRj
dir8,DRk
dir16,DRk
Rm,@WRj+dis16
WRj,@WRj+dis16
Rm,@DRk+dis24
WRj,@DRk+dis24
Rmd = Rms
WRjd = WRjs
DRkd = DRks
Rm = #data
WRj = #data16
DRk = #0data16
DRk = #1data16
DRk = (dir8, dir8+1, dir8+2, dir8+3)
DRk = (dir16, dir16+1, dir16+2, dir16+3)
Rm = dir8
Wrj = (dir8, dir8+1)
Rm = (dir16)
Wrj = (dir16, dir16+1)
Rm = (@WRj)
Rm = (@DRk)
WRjd = (@WRjs, @WRjs+1)
WRj = (@DRk, @DRk+1)
(dir8) = Rm
(dir8, dir8+1) = WRj
(dir16) = Rm
(dir16, dir16+1) = WRj
(@WRj) = Rm
(@DRk) = Rm
(@WRjd , @WRjd +1) = Wrjs
(@DRk, @Drk+1) = WRj
(dir8, dir8+1, dir8+2, dir8+3) = DRk
(dir16, dir16+1, dir16+2, dir16+3) = DRk
Rm = (@WRj+dis16)
WRj = (@WRj+dis16, @WRj+dis16+1)
Rm = (@DRk+dis24)
WRj = (@Drk+dis24, @DRk+dis24+1)
2
2
2
3
4
4
4
3
4
3
3
4
4
3
3
3
3
3
3
4
4
3
3
3
3
3
4
4
4
4
4
2
2
4
4
4
8
8
10
10
4
6
4
6
4
6
6
8
6
8
6
8
6
8
8
10
12
12
10
12
12
14
© Los autores, 2001; © Edicions UPC, 2001.
Apéndice Juego de instrucciones de la familia MCS-51 y MCS-251 335
Mnemónico <dest>,<src> Descripción Bytes Tclock
Instrucciones de transferencia de datos (continuación)MOV @WRj+dis16,Rm
@WRj+dis16,WRj
@DRk+dis24,Rm
@DRk+dis24,WRj
(@WRj+dis16) = Rm
(@WRj+dis16, @WRj+dis16+1) = Rm
(@DRk+dis24) = Rm
(@DRk+dis24, @DRk+dis24+1) = Rm
4
4
4
4
10
12
12
14
MOVH DRk(hi),#data16 DRk(hi) = data16 4 4
MOVS WRj,Rm WRj = MSB, Rm 2 2
MOVZ WRj,Rm WRj = 0, Rm 2 2
Instrucciones de transferencia de datos en la pilaPUSH #data
#data16
Rm
WRj
DRk
Mete el dato #data en la pila
Mete el dato #data16 en la pila
Mete el contenido de Rm en la pila
Mete el contenido de WRj en la pila
Mete el contenido de DRk en la pila
3
4
2
2
2
6
10
6
10
18
POP Rm
WRj
DRk
Mete en Rm un dato de la pila
Mete en WRj un Word de la pila
Mete en DRk un Dword de la pila
2
2
2
4
8
16
Instrucciones booleanasCLR CY
bit
Pone a cero el bit de acarreo
Pone a cero el bit direccionado
1
3
2
6
SETB CY
bit
Pone a uno el bit de acarreo
Pone a uno el bit direccionado
1
3
2
6
CPL CY
bit
Complementa el bit de acarreo
Complementa el bit direccionado
1
3
2
6
ANL CY, bit
CY, /bit
CY = CY AND (bit)
CY = CY AND (/bit)
3
3
4
4
ORL CY, bit
CY,/bit
CY = CY OR (bit)
CY = CY AND (/bit)
3
3
4
4
MOV CY, bit
bit, CY
CY = bit
bit = CY
3
3
4
6
JB bit, rel Salta si (bit) es 1 4 6/12
JNB bit, rel Salta si (bit) no es uno 4 6/12
JBC bit, rel Salta si (bit) es uno y borran el bit 4 12/18
Instrucciones de salto incondicionalEJMP addr24
@DRk
Salto extendido
Salto extendido indirecto
4
2
10
12
LJMP @WRj Salto largo indirecto 2 10
Instrucciones de salto condicionalJE rel Salta si es igual (si Z=1) 2 2/8
JNE rel Salta si no es igual (si Z=0) 2 2/8
JG rel Salta si es mayor que. (si CY=Z=0) 2 2/8
JLE rel Salta si es menor o igual que. (si Z=1 o CY=1) 2 2/8
JSL rel Salta si es menor que (con signo). (si N[OV) 2 2/8
JSLE rel Salta si es menor o igual que (con signo). (si Z=1 ó si N[OV) 2 2/8
JSG rel Salta si es mayor que (con signo). (si Z=0 y N=OV) 2 2/8
JSGE rel Salta si es mayor o igual que (con signo). (si N=OV) 2 2/8
Instrucciones de llamada y retorno de subrutinaLCALL @WRj Llamada a subrutina tipo long 2 16
ECALL @DRk
dir24
Llamada a subrutina tipo extendido 2
4
22
26
ERET Retorno extendido de subrutina 2 18
© Los autores, 2001; © Edicions UPC, 2001.