PUERTOS DE ENTRADA/SALIDA PARALELA
1 - Objetivos 2 - Introducción 3 - Características 4 - Programación 5 - Bibliografía 6 - Apéndice
Resumen de contenidos
1 - Objetivos
1 - Objetivos
• Comprender la arquitectura de los puertos
• Dominar las técnicas de programación que hacen uso de los puertos
• Saber aprovechar los dispositivos conectados a los puertos
2 - Introducción
2 - Introducción
Sistema Informático basado en
? C
Interfaz operador
Interfaz proceso Imagen
Proceso Sistema Industrial
Proceso Sistema Industrial Actuadores
digitales Sensores
digitales
• Los puertos de E/S en un ? C permite la interfaz con el proceso para
Lectura/Escritura de señales digitales
• Los puertos de un microcontrolador se pueden usar para:
– Conocer el estado de señales digitales
– Generar señales digitales
2 - Introducción
válvula (ON/OFF)
pin P1.0
+5V
2k 7405
interruptor (ON/OFF)
3 - Características
3 - Características
Estructura general
Microcontrolador Atmel T89C51CC01:
Microcontrolador Atmel T89C51CC01:
32 líneas de E/S digital compatibles TTL (5V)
–Organizadas en 4 puertos de 8 bits (P0, P1, P2, P3) 2 líneas de entrada/salida digital (P4)
Para designar bits individuales se usa la notación:
– Px. y , donde x es el número de puerto e y el bit (0...7, para P8 solo 0...3) Ejemplo: P3.2 (Puerto 3 bit número 2)
3 - Características
• Cada patilla (pin) del puerto tiene un circuito formado por:
– Latch
– Driver de salida – Buffer de entrada
• Los terminales de los puertos tienen “funciones alternativas”
3 - Características
T89C51CC01
Estructura genérica de un puerto Px.y (Ej: P1.x)
LATCH
D clk
Q Q
bus interno orden escritura
LATCH
+Vcc
Lectura pin Lectura LATCH
pin P1.x pull-up interna
3 - Características
LATCH
D clk
Q Q
bus interno orden escritura
LATCH
+Vcc
Lectura pin Lectura LATCH
pin P1.x pull-up interna
3- Características: escritura de un “1”
=“1”
=“0”
LATCH
D clk
Q Q
bus interno orden escritura
LATCH
+Vcc
Lectura pin Lectura LATCH
pin P1.x pull-up interna
3- Características: escritura de un “0”
=“0”
=“1”
LATCH
D clk
Q Q
bus interno orden escritura
LATCH
+Vcc
Lectura pin Lectura LATCH
pin P1.x pull-up interna
3- Características: lectura de pin
LATCH
D clk
Q Q
bus interno orden escritura
LATCH
+Vcc
Lectura pin Lectura LATCH
pin P1.x pull-up interna
3- Características: lectura del latch
Ejemplos de conexiones a un pin de un puerto
pin P1.0
+5V 330 ?
7405 pin
P1.0
+5V
2k 7405
El FAN-OUT (número de puertas conectables en un pin del puerto) depende del modelo particular elegido.
El “51” normal dice
• Para cada pin de P0 (8 puertas TTL-LS)
• Para cada pin de P1, P2, ... (4 puertas TTL-LS)
3 - Características
Ejemplo de conexión más común a un pin de un puerto
pin P1.0
+5V
2k
pin P1.0
3 - Características
Ejemplo
4 - Programación
• Los programas usan los puertos manipulando los registros SFR correspondientes
• Hay instrucciones para:
– Leer los latchs – Leer los pines – Escribir los latch.
Cuidado, que no es lo mismo.
4 - Programación
Registros de Función Especial (SFR) asociados a los Puertos (direccionamiento directo)
Puerto Bits Dirección SFR
Direccionable bit a bit
Declaración en C
P0 8 80h Sí sfr P0= 0x080;
P1 8 90h Sí sfr P1= 0x090;
P2 8 A0h Sí sfr P2= 0x0A0;
P3 8 B0h Sí sfr P3= 0x0B0;
P4 2 C0h Sí sfr P4= 0x0C0;
5 - Programación
Leer los PINES de los puertos
/* ej1.c */
sfr P1 = 0x90; /* definición de P1 */
main() {
P1 = 0x55; /* asignar equivale a escribir en el puerto */
}
/* ej2.c */
sfr P1 = 0x90; /* definición de P1 */
main() {
unsigned char val;
Escribir los LATCH de los puertos
5 - Programación
Leer los PINES de los puertos
P1 .equ $90 ; definición de P1
MOV P1,#$55 ;asignar equivale a escribir en el puerto
P1 .equ 0x90 ;definición de P1 MOV A,P1 ;lectura de P1
Escribir los LATCH de los puertos
5 - Programación
Empleo de máscaras
&
|
^
<<
>>
?
AND a nivel de bit OR a nivel de bit XOR a nivel de bit
desplazamiento a la izq.
desplazamiento a la der.
complemento a 1
• Para el tratamiento de la información que se lee/escribe se suele recurrir a las operaciones booleanas a nivel de bit
5 - Programación
Empleo de máscaras
Por el puerto P1 entran 4 bits y se de- sean emitir esos 4 bits previamente complementados por las otras 4 líneas.
sfr P1 = 0x90; /* definición de P1 */
main() {
unsigned char val;
while(1) {
val = P1; /* leer P1 */
val = val & 0x0F; /* extraer 4 bits de menor peso */
val = ~val; /* complementar los bits */
val = val << 4; /* llevarlos a la parte alta */
val = val | 0x0F; /* bits de menor peso a 1 (ENTRADAS)*/
P1 = val; /* sacar el dato */
MCS-51
5 - Programación
ACTIVIDAD 1:
• Conseguir un efecto “carrusel” empleando el esquema electrónico mostrado conectado a un puerto del microcontrolador.
– Para generar el efecto se puede enviar la siguiente secuencia al puerto:
01111111b, 10111111b, 11011111b, 11101111b ...
– Cada vez que se escriba un dato se deberá realizar una pausa, para ello se puede hacer un bucle de retardo entre cada escritura
P1.7 P1.6 P1.5 P1.4 P1.3 P1.2 P1.1 P1.0
5 - Programación
Solución
ACTIVIDAD 2
• Un dispositivo introduce un número binario entre 0 y 7 (codificado en 3 bits) por las líneas P1.0 a P1.2 del ? C, y el resto de líneas se emplean en otros propósitos. Se desea sacar un FFh por P2 si el valor introducido es mayor que 2 y 00h en caso contrario.
5 - Programación
Solución
Operación Ensamblador 8x51 Operador C
AND ANL &=
OR ORL |=
XOR XRL ^=
incremento INC ++
decremento DEC --
Operaciones de lectura-modificación-escritura
• Las instrucciones L-M-E que emplean los puertos leen el latch de los puertos y no el pin. Son:
– Instrucciones lógicas: ANL, ORL, XRL, ...
– Instrucciones aritméticas: INC, DEC, ...
– Instrucciones booleanas: (se ven más adelante)
• El compilador de C está preparado para generarlas:
5 - Programación
Operaciones de lectura-modificación-escritura
Se desean leer los 4 bits de menor peso del puerto P1, sumarles el número 7 y emitirlo por los 5 bits de menor peso del puerto P2 sin afectar al resto de líneas de P2.
Solución. El número que se consigue al sumar 7 tendrá como máximo 5 bits, por lo que no plantea ningún problema. Para emitir la información por P2 sin afectar al resto de líneas se pueden emplear las operaciones lógicas sobre puertos en dos pasos.
sfr P1 = 0x90; /* definición de P1 */
sfr P2 = 0xA0; /* definición de P2 */
void main(void) {
unsigned char val;
while(1) {
val = (P1 & 0x0F) + 7; /* Lee los pines de P1*/
P2 |= val; /* Lee el latch de P2 y aplica la OR */
P2 &= (val | 0xE0); /* Lee el latch de P2 y aplica la AND*/
} }
5 - Programación
Procesador booleano (manejo bit a bit)
• Característica especifica de esta familia
• 32 posiciones del SFR son manejables bit a bit (32x8=256 posiciones de bit)
• Para expresar una dirección de bit se usa un número entre 0 y 255 o el identificador del byte seguido del bit dentro del byte. P.e:
– P1 es direccionable bit a bit, una referencia al bit 0 de P1 se escribiría P1.0 – el bit 4 de la dirección 20h (zona direccionable bit a bit) se referencia como
20.4
5 - Programación
Procesador booleano (manejo bit a bit)
Se desea comparar dos números binarios, A y B, de 4 bits cada uno que se introducen por la parte baja y la parte alta de P1 respectivamente. Cuando A>B se desea que P2.0 esté a nivel alto, en caso contrario que esté a nivel bajo.
sfr P1 = 0x90; /* definición de P1 */
sfr P2 = 0xA0; /* definición de P2 */
sbit P2_0 = P2^0; /* bit 2 de P2 */
void main(void) {
while(1) {
unsigned char val;
val = P1;
if ((val & 0x0F) > (val >> 4)) /* A > B*/
P2_0 = 1;
else
P2_0 = 0;
}
5 - Programación
Tablas de verdad (circuitos combinacionales)
Supóngase, por ejemplo, que se desea implementar un decodificador 3x8 según el siguiente esquema.
Su tabla de verdad será,
dec. C B A b7 b6 b5 b4 b3 b2 b1 b0 hexa.
0 0 0 0 0 0 0 0 0 0 0 1 01h
1 0 0 1 0 0 0 0 0 0 1 0 02h
2 0 1 0 0 0 0 0 0 1 0 0 04h
3 0 1 1 0 0 0 0 1 0 0 0 08h
4 1 0 0 0 0 0 1 0 0 0 0 10h
5 1 0 1 0 0 1 0 0 0 0 0 20h
5 - Programación
La forma más directa de implementar dicha función lógica es crear una tabla cuyos índices sean el dato de entrada y cuyo contenido sea la salida que corresponde a cada índice. Por ejemplo, en la po- sición 3 de la tabla que correspondería a leer un 3 de las líneas de entrada deberá estar el dato 08h.
En C sería,
sfr P1 = 0x90; /* definición de P1 */
sfr P2 = 0xA0; /* definición de P2 */
unsigned char deco3x8[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
void main(void) {
while(1)
P2 = deco3x8[P1 & 0x07];
}
5 - Programación
5 - Programación
Diodo Led intermitente
?C
P3.5
150 Ohm
+ Vcc
330 Ohm BC 327
Realizar un programa en Lenguaje C que gestione el funcionamiento intermitente del led de la figura.
ACTIVIDAD 3:
5 - Programación
Llenado carretilla:
Al llegar la carretilla se desconecta el motor,
y si no está llena se llenará y se activará nuevamente el motor Apertura
Salida Depósito
P2.1 (1: Abierto; 0:Cerrado)
Sensor Proximidad
P3.1 (1:presencia; 0:no presencia)
Material
Depósito
Carretilla
Motor
P2.2 (1: activado; 0:desactivado) Sensor Lleno
P3.0 (1:lleno; 0:no lleno)
ACTIVIDAD 4:
Solución
5 - Programación
Ralizar una función con el prototipo siguiente:
unsigned visuali_dos_digitos (unsigned char dato);
de forma que descomponga el parámetro de entrada “dato” en dos dígitos (decenas y unidades) y lo saque al exterior teniendo en cuenta el conexionado de la figura.
ACTIVIDAD 5:
?C
P3.0 P3.1 P3.2 P3.3 P3.4 P3.5 P3.6 P3.7
A
F
E
D C B
G P1.0
P1. 1
P1. 2
P1.3
P1.4 P1. 5 P1.6
A
F
E
D C B
G P1.0
P1. 1
P1. 2
P1.3
P1.4 P1. 5 P1.6
Convertidor binario a 7 seg 74LS48
Convertidor binario a 7 seg 74LS48
UNIDADES
DECENAS
Solución
5 - Programación ACTIVIDAD 6:
MOTOR PASO A PASO
?
C
P1.0 P1.1 P1.2 P1.3
PASO P1.3 P1.2 P1.1 P1.0
1 1 0 1 0
2 1 0 0 0
3 1 0 0 1
4 0 0 0 1
5 0 1 0 1
6 0 1 0 0
7 0 1 1 0
8 0 0 1 0
Deseamos utilizar el motor paso a paso para un limpiaparabrisas de automóvil.
Realizar un programa que de forma continuada haga girar el motor 30 pasos en un sentido y 30 pasos en el otro.
Tabla de accionamiento del motor en modo de
5 - Programación ACTIVIDAD 7:
Deseamos utilizar el motor DC para controlar su velocidad por ancho de pulso (PWM).
Utilizando las entradas P1.7, P1.6 y P1.5 seleccionaremos una de las tres posibles velocidades según la tabla y la figura adjunta.
Vel.
Alta
?
C
P1.0
Vmotor
VccVcc
P1.7 P1.6 P1.5
Vel.
Media
Vel.
Baja
P1.7 P1.6 P1.5 Velocidad 1 0 0 Alta (90% ON y 10% OFF) 0 1 0 Media (50% ON y 50% OFF) 0 0 1 Baja (10% ON y 90% OFF) Otra combinación Motor apagado
Vel. Alta Vel. Media
Solución
5 - Programación
ACTIVIDAD 8:
Realizar una función con el siguiente prototipo:
unsigned char teclado(void);
que verifique si se ha pulsado alguna tecla y en caso afirmativo devuelva el valor
10K 10K 10K 10K
1 2 3 4
8 7
6 5
9 10 11 12
16 15
14 13
P1.0 P1.1 P1.2 P1.3
P1.4
P1.5
P1.6
P1.7
Vcc
? C
Solución
ACTIVIDAD 9
Se tiene el siguiente esquema de un automatismo, donde se desea controlar el nivel de líquido de un depósito.
5 - Programación
B1 B2
A B
C Entradas
Salidas
Alarma Rebose
Lleno Vacío Bomba 2 Bomba 1
Los sensores A, B, C detectan si el líquido los toca (1=mojado, 0= seco).
Se propone la siguiente descripción de señales.
Sensores:
? sonda digital A, 1= mojada, 0=seca
? sonda digital B, 1= mojada, 0=seca
? sonda digital C, 1= mojada, 0=seca Actuadores:
? bomba 1, digital, 1=ON, 0=OFF
? bomba 2, digital, 1=ON, 0=OFF (indicadores):
? “Alarma”, digital, 1=ON, 0=OFF
? “Rebose”, digital, 1=ON, 0=OFF
? “Lleno”, digital, 1=ON, 0=OFF
? “Vacío”, digital, 1=ON, 0=OFF
? C
5 - Programación
? C
5 - Programación
Funcionamiento
• Sonda A señala nivel mínimo de líquido, por debajo de este nivel indica “VACIO”.
• Sonda B señala nivel óptimo y cuando se alcance indicará “LLENO” .
• Sonda C señala nivel peligroso e inidca “REBOSE”
• Cuando ninguna sonda está mojada se activarán las dos bombas (B1 y B2).
• Cuando el líquido toca la sonda B, se desactivará la bomba B2.
• Si el líquido moja la sonda C, se desactivará la bomba B1.
Solución
ACTIVIDAD 10
Se desea que un microcontrolador haga las funciones de un integrado digital con la siguiente tabla de verdad. Realizar un programa que permita al micro emular dicha tabla de verdad y emplee como entradas y salidas los pines del puerto P1 indicados.
C B A X4 X3 X2 X1 X0
0 0 0 0 0 1 0 0 X4 ? P1.7
0 0 1 0 1 0 1 0 X3 ? P1.6
0 1 0 1 0 0 0 1 X2 ? P1.5 8051
0 1 1 1 0 1 0 1 X1 ? P1.4
1 0 0 1 1 0 1 1 X0 ? P1.3
1 0 1 1 0 0 0 1 C ? P1.2
1 1 0 1 0 1 0 1 B ? P1.1
1 1 1 0 0 1 0 0 A ? P1.0
?
C
5 - Programación
Solución
5 - Programación
Solución
ACTIVIDAD 11:
A partir del hardware de la figura, realizar un programa que realice la lectura del teclado matricial y muestre el valor de la tecla pulsada en los displays de 7-segmentos.
10K 10K 10K 10K
1 2 3 4
8 7
6 5
9 10 11 12
16 15
14 13
P1.0 P1.1 P1.2 P1.3
P1.4
P1.5
P1.6
P1.7
Vcc
? C
P3.0 P3.1 P3.2 P3.3 P3.4 P3.5 P3.6 P3.7
A
F
E
D C B
G P1.0
P1.1
P1.2
P1.3 P1.4
P1.5 P1.6
A
F
E
D C B
G P1.0
P1.1
P1.2
P1.3 P1.4
P1.5 P1.6
Convertidor binario a 7 seg 74LS48
Convertidor binario a 7 seg 74LS48
UNDADES
DECENAS
6 - Bibliografía
• http://www.atmel.com
• http://www.disca.upv.es/aperles/web51
• José Adolfo González Vázquez: Introducción a los
Microcontroladores; Hardware, Software y Aplicaciones; 8x52, 8x51.
Ed. McGraw-Hill
• 8XC51/80C31: 8-bit CMOS microcontroller families Intel
• Richard H. Barnett; The 8051 family of microcontrollers Prentice Hall
6 - Bibliografía
7 - Apéndice
7 - Apéndice: Esquemas
80C51
P1.7 P1.6 P1.5 P1.4 P1.3 P1.2 P1.1 P1.0
R
R
R
R
7 - Apéndice: Esquemas
A
F
E
D
C B
G
P1.0
P1.1
P1.2
P1.3
P1.4
P1.5
P1.6
7 - Apéndice: Estructura puertos: P1, P3, P4
Estructura puertos: P1, P3, P4
7 - Apéndice: Estructura puerto P0
Estructura puerto P0
7 - Apéndice: Estructura puerto P2
Estructura puerto P2
Solución actividad 1:
7 - Apéndice: Soluciones
sfr P1 = 0x90; /* definición de P1 */
#define retardo 7000 unsigned char i, dato;
int r;
main() {
P1 = 0x7f; /* dato 0111 1111(b */
do
{ /* desplaza a la derecha el cero*/
dato=0x7F;
for(i=1;i<8;i++) {
P1= dato;
dato=dato>>1|0x80;/*Desplazar y rellenar bit 7 con 1 */
for(r=0;r<retardo;r++);
}
}while(1);
}
7 - Apéndice: Soluciones
Solución actividad 2:
/* Declaramos una variable (val) para leer el valor en el puerto, y comparamos el valor*/
sfr P1 =0x90; /* definición de P1 */
sfr P2 =0xA0; /* definición de P2 */
unsigned char val;
main() {
while(1);
{
val=P1&0x7; /* Extraemos los tres bits LSB de P1*/
if (val>2) P2=0xFF;
else
P2=0x00;
}
}
7 - Apéndice: Soluciones
Diodo Led intermitente
#define TEMPORIZ 65536 /* valor para pérdida de tiempo */
sfr P3=0xB0;
sbit LED=P3^5; /* definir pin del puerto de salida */
unsigned int tiempo; /* variable para pérdida de tiempo */
void main (void) {
while (1) {
LED=~LED;
for (tiempo=0;tiempo<TEMPORIZ;tiempo++);
} }
?C
P3.5
150 Ohm
+ Vcc
330 Ohm BC 327
Solución actividad 3:
7 - Apéndice: Soluciones
Apertura Salida Depósito
P2.1 (1: Abierto; 0:Cerrado)
Material
Depósito
Carretilla
Motor
P2.2 (1: activado; 0:desactivado) Sensor Lleno
P3.0 (1:lleno; 0:no lleno)
Solución actividad 4:
sbit MOTOR=0xa0^2;sbit DEPOSITO=0xa0^1;
sbit CARRETILLA=0xb0^1;
sbit LLENA=0xb0^0;
void main (void) {
while (1) {
while (!CARRETILLA);
MOTOR = 0;
while (!LLENA) {DEPOSITO = 1};
DEPOSITO = 0;
MOTOR = 1;
} }
7 - Apéndice: Soluciones
sfr P3=0xB0; /* define puerto */
#define displays P3
unsigned visuali_dos_digitos (unsigned char dato) {
unsigned char unidad,decenea;
decena=dato/10; /* obtención digito de decenas */
unidad=dato%10; /* obtención digito unidades */
decena <<=4; /* desplazar izqda. 4 posiciones */
displays=unidad|decena; /* unir ambos valores y sacar puerto */
?C
P3.0 P3.1 P3.2 P3.3 P3.4 P3.5 P3.6 P3.7
A
F
E
D C B
G P1.0
P1. 1
P1. 2
P1.3
P1.4 P1. 5 P1.6
A
F
E
D C B
G P1.0
P1. 1
P1. 2
P1.3
P1.4 P1. 5 P1.6
Convertidor binario a 7 seg 74LS48
Convertidor binario a 7 seg 74LS48
UNIDADES
DECENAS
Solución actividad 5:
7 - Apéndice: Soluciones
#define PASOS 30
sfr P1=0x90; /* define puerto */
unsigned char tabla[]={0x0a,0x08,0x09,0x01,0x05,0x04,0x06,0x02};
void main (void) {
unsigned char contador=0; /* contador de pasos */
unsigned char tot_pasos; /* contador total de pasos */
bit direccion; /* flag de sentido de giro */
direccion = 0;
while (1) {
for (tot_pasos=0;tot_pasos<PASOS;tot_pasos++) { P1 = tabla[contador&0x07];
PERDIDA_DE_TIEMPO
if (direccion==0) contador++; /* Paso siguiente */
else contador--; /* Paso anterior */
}
direccion=~direccion; /* cambio de sentido de giro */
Solución actividad 6:
7 - Apéndice: Soluciones
sfr P1=0x90; /* define puerto */
sbit MOTOR=0x90^0;
void main (void) {
unsigned char ton=0,cont;
while (1) {
if ((P1&0xe0)==0x80) ton=90;
if ((P1&0xe0)==0x40) ton=50;
if ((P1&0xe0)==0x20) ton=10;
if (ton>0) {
MOTOR=1; /* activar motor */
for (cont=0;cont<ton;cont++) PERDIDA_TIEMPO;
MOTOR=0; /* deconectar motor */
for (cont=ton;cont<100;cont++)PERDIDA_TIEMPO;
} ton=0;
Solución actividad 7:
7 - Apéndice: Soluciones
#define no_tecla 255
#define tecla_no_val 254 sfr P1=0x90;
unsigned char columna;
unsigned char fila;
unsigned char salida;
unsigned char teclado(void)
{ for(col=0,salida=0xef;col<=3;col++,(salida= (salida<<1)|0x0f) {
P1=salida;
fila=P1;
if((fila & 0x0f) != 0x0f) switch(fila&0x0f)
{case 0x0e: return(columna*4+0);
case 0x0d: return(columna*4+1);
case 0x0b: return(columna*4+2);
case 0x07: return(columna*4+3);
default: return(tecla_no_val);
} }
return(no_tecla);
Solución actividad 8:
7 - Apéndice: Soluciones
sfr P1 = 0x90; /* definición de P1 */
unsigned char tabla[] = {0x07,0x03,0x20,0x09,0x20,0x20,0x20,0x10};
main() {
while(1)
P2 = tabla[P1 & 0x07];
}
Solución actividad 9:
? C
7 - Apéndice: Soluciones
sfr P1 = 0x90; /* definición de P1 */
unsigned char tabla[] = {0x04,0x0A,0x11,0x15,0x1B,0x11,0x15,0x04};
main() {
while(1)
P1 = (tabla[P1 & 0x07] << 3) | 0x07;
}
Solución actividad 10:
7 - Apéndice: Soluciones
Solución actividad 11:
#define no_tecla 255
#define tecla_no_val 254 sfr P1=0x90;
sfr P3=0xB0;
unsigned char col;
unsigned char fil;
unsigned char excit;
unsigned char teclado(void);
void visualizar(unsigned char dato);
void main(void) {
unsigned char tecla;
while(1) {
tecla=teclado();
if((tecla>=0)&&(tecla<=15)) visualizar(tecla);
} }
7 - Apéndice: Soluciones
void visualizar(unsigned char dato) { unsigned char unidad,decena;
decena=dato/10;
unidad=dato%10;
decena<<=4;
P3=unidad|decena;
}
unsigned char teclado(void)
{for(col=0,excit=0xef;col<=3;col++,(excit= (excit<<1)|0x0f) { P1=excit;
fil=P1;
if((fil&0x0f)!=0x0f) switch(fil&0x0f) {
case 0x0e: return(col*4+0);
case 0x0d: return(col*4+1);
case 0x0b: return(col*4+2);
case 0x07: return(col*4+3);
default: return(tecla_no_val);
} }