← Índice del curso

Circuitos Secuenciales y Memoria · Tema 16

Taller: entradas con el 74HC165

El tema anterior sacó ocho bits con tres cables; este los trae de vuelta. El 74HC165 es un registro paralelo-serie: captura ocho entradas de golpe, congeladas en el mismo instante, y las entrega de a una por un único pin. Con él leés ocho interruptores o pulsadores con tres pines del microcontrolador, y con varios chips en cadena, treinta y dos. En el taller armás la lectura, comprobás el orden de los bits, la encadenás y aprendés a leer pulsadores sin falsas lecturas.

01 · Punto de partida

El espejo del 595

El 74HC595 era serie-paralelo: bits en fila que se convertían en ocho salidas. El 74HC165 hace el camino inverso: ocho entradas simultáneas que se convierten en una fila de bits. Es el PISO del tema 14 en un chip de 16 patas. La clave es la misma de siempre en este curso: todo el trabajo de «mirar» ocurre en un instante, y la transmisión lenta, bit a bit, se hace sobre una copia ya congelada.

Los tres montajes del taller.
MontajeQué haceChipsQué aprendés
1. Leer ocho interruptoresUn pulso de carga captura los interruptores y el reloj manual saca los bits uno por uno a un LED74HC165 + 74HC00Carga paralela, desplazamiento, orden MSB primero
2. Dos chips en cadena16 interruptores leídos por el mismo pin2 × 74HC165Q7 → DS, 16 pulsos, cuál chip llega primero
3. Pulsadores y lectura establePulsadores con pull-up (lógica negativa), lectura repetida y detección de cambios74HC165 + resistenciasRebotes, inversión, XOR entre lecturas

Como en los talleres anteriores, el tema se aprovecha sin materiales: el código reproduce el chip y el laboratorio lo simula con la lectura paso a paso.

02 · Preparación

Materiales y herramientas

Lista de materiales.
Cant.ComponentePara qué sirve
274HC165 (registro de desplazamiento de 8 bits con carga paralela)La protagonista (el segundo, para la cadena)
174HC00 (cuatro NAND)Latch antirrebote del reloj manual (tema 7)
1Conmutador de palanca SPDTReloj CP limpio
1 + 1Pulsador normalmente abierto y 10 kΩPulso de carga PL̅ (pull-up a +5 V)
2DIP de 8 interruptores (o 16 interruptores sueltos)Entradas D0..D7 de cada chip
16 + 4Resistencias de 10 kΩPull-down de los interruptores; pull-up de los pulsadores del montaje 3
4Pulsadores normalmente abiertosEntradas con lógica negativa (montaje 3)
1 a 2LED con resistencia de 1 kΩMostrar Q7 (y Q̅7)
3Condensador de 100 nFDesacople, uno por chip
1Protoboard, cables y fuente regulada de 5 VMontaje y alimentación

El multímetro alcanza para el montaje a mano. Con un analizador lógico de 3 canales (PL̅, CP y Q7) vas a ver la lectura entera de un vistazo. Dibujá el esquema con los números de pin: en el 165 las entradas D0..D7 están repartidas en los dos lados del chip, no en orden.

Antes de dar tensión

  • Un 100 nF entre Vcc (pin 16) y GND (pin 8), pegado al chip.
  • CE̅ (pin 15) a masa y DS (pin 10) a masa en los primeros montajes.
  • Ninguna entrada D al aire: las ocho tienen su resistencia a masa (o a +5 V), esté o no el interruptor conectado.
  • PL̅ (pin 1) en +5 V por una resistencia: en reposo no debe estar cargando.

03 · El chip

Pines del 74HC165

El encapsulado DIP de 16 patas tiene una muesca en un extremo; el pin 1 queda a la izquierda de la muesca y los números siguen en sentido antihorario. Las entradas D4..D7 están en los pines 3 a 6 y D0..D3 en los pines 11 a 14:

Pinout estándar del 74HC165 (confirmalo en la hoja de datos de tu fabricante).
PinNombreFunciónPinNombreFunción
1PL̅Carga paralela (activa en bajo, asíncrona)16Vcc+5 V
2CPReloj de desplazamiento (flanco ↑)15CE̅Habilitación de reloj (activa en bajo)
3D4Entrada paralela 514D3Entrada paralela 4
4D5Entrada paralela 613D2Entrada paralela 3
5D6Entrada paralela 712D1Entrada paralela 2
6D7Entrada paralela 8 (la primera que sale)11D0Entrada paralela 1
7Q̅7Salida serie complementada10DSEntrada serie (para encadenar)
8GNDMasa9Q7Salida serie

Algunos fabricantes llaman SH/LD̅ al pin 1 y CLK INH al pin 15. La función es la misma.

Cómo se comporta

Tabla de función simplificada (X = sin importancia).
PL̅CE̅CPEfecto
0XXCarga: D0..D7 pasan al registro de inmediato, sin esperar el reloj; Q7 = D7
10↑Desplazamiento: DS entra en Q0; cada bit avanza hacia Q7
11↑Reloj inhibido: no pasa nada
1Xsin flancoRetiene

Dos diferencias con el 595 conviene tener presentes. Primero, la carga paralela es asíncrona: mientras PL̅ esté en bajo, el registro sigue a las entradas y el reloj se ignora; la «foto» queda tomada cuando PL̅ vuelve a subir. Segundo, no hay registro de salida: Q7 es el último flip-flop del propio desplazamiento, así que cambia con cada flanco de CP.

04 · Montaje 1

Leer ocho interruptores

Reutilizamos el reloj manual de NAND de los talleres anteriores para CP. El pulsador de PL̅ no necesita antirrebote: cada rebote vuelve a cargar los mismos interruptores y el resultado no cambia.

Conexiones del montaje 1. U1 = 74HC00 (reloj manual); U2 = 74HC165.
Chip y pinSe conecta a
U1 pin 14 / pin 7+5 V / masa, con 100 nF entre ambos
U1 pin 1 y pin 4Contactos A y B del conmutador, cada uno con 10 kΩ a +5 V; común del conmutador a masa
U1 pin 2 ↔ pin 6; pin 3 ↔ pin 5Cruce del latch (como en el tema 7)
U1 pines 9, 10, 12, 13Masa (compuertas sobrantes)
U1 pin 3 (Q)U2 pin 2 (CP): el reloj de desplazamiento
U2 pin 16 / pin 8+5 V / masa, con 100 nF entre ambos
U2 pin 1 (PL̅)10 kΩ a +5 V y pulsador a masa (al pulsar, carga)
U2 pin 15 (CE̅) y pin 10 (DS)Masa
U2 pines 11, 12, 13, 14, 3, 4, 5, 6 (D0..D7)Cada uno al contacto de un interruptor del DIP (que va a +5 V) y a una resistencia de 10 kΩ a masa
U2 pin 9 (Q7)LED con resistencia de 1 kΩ a masa

Pruebas

Secuencia de pruebas del montaje 1. Cada «pulso de CP» es llevar la palanca a A y volver a B. Interruptores en D7..D0 = 10110010.
PasoAcciónLED de Q7Qué se comprueba
1Dar tensiónCualquieraEl registro arranca sin valor definido
2Pulsar PL̅EncendidoQ7 = D7 = 1 de inmediato, sin reloj
3Un pulso de CPApagadoSale D6 = 0
4Segundo y tercer pulsoEncendido, encendidoD5 = 1 y D4 = 1
5Cuarto y quinto pulsoApagado, apagadoD3 = 0 y D2 = 0
6Sexto pulsoEncendidoD1 = 1
7Séptimo pulsoApagadoD0 = 0
8Octavo pulso y siguientesApagadoEntran los ceros de DS: el registro se vacía
9Cambiar un interruptor después de la cargaSin cambioLo que se lee es la foto del momento de PL̅
10Pulsar PL̅ otra vezSegún el nuevo D7Una nueva carga toma las entradas actuales

Tené presente el orden: el primer bit que sale es D7. El microcontrolador debe leer Q7 antes de dar el flanco de CP, porque el flanco desplaza y haría perder ese bit.

05 · Montaje 2

Dos chips en cadena

La salida Q7 de un chip se conecta a la entrada DS del siguiente: cuando el primero termina de entregar sus bits, los del vecino quedan detrás. Ambos chips comparten CP y PL̅, de modo que se cargan y desplazan a la vez. El microcontrolador lee el Q7 del último chip de la cadena.

Cambios respecto del montaje 1. U3 = segundo 74HC165, el que se lee.
ConexiónFunción
U2 pin 9 (Q7) → U3 pin 10 (DS)Los bits de U2 pasan a U3 después de los propios de U3
U2 pin 2 ↔ U3 pin 2 (CP)Mismo reloj de desplazamiento
U2 pin 1 ↔ U3 pin 1 (PL̅)Misma orden de carga
U3 pin 15 (CE̅) → masa; U2 pin 10 (DS) → masaCE̅ activo en ambos; el primer DS se ata a masa
U3 pin 9 (Q7) → LED con 1 kΩ (o al microcontrolador)La salida serie de toda la cadena
U3 pines D0..D7 → interruptoresOcho interruptores más, con su pull-down
U3 pin 16 / pin 8, con 100 nFAlimentación propia del segundo chip

La lectura completa son 16 pulsos de CP después de un PL̅. Los primeros 8 bits que salen son los de U3 (D7..D0), y los 8 siguientes, los de U2. Si se leen solo 8 bits, el microcontrolador ve únicamente el chip que está al final de la cadena y nunca el otro. Es la imagen especular de lo que ocurría con el 595, donde los primeros 8 bits enviados terminaban en el último chip.

06 · Montaje 3

Pulsadores y lectura estable

Los interruptores del montaje 1 son «estables»: nadie los mueve mientras se lee. Los pulsadores no lo son. Ocurren dos cosas distintas: la lógica cambia de signo y el contacto rebota.

Lógica negativa

Es más cómodo conectar un pulsador entre la entrada y masa, con una resistencia de 10 kΩ a +5 V (pull-up). En reposo la entrada lee 1; al pulsar, lee 0. Los bits «activos» valen 0. En el programa se invierte la lectura (XOR con 0xFF) para trabajar con 1 = pulsado.

Cambios respecto del montaje 1 para cuatro pulsadores en D0..D3.
ConexiónFunción
10 kΩ de +5 V a cada entrada D0..D3 (pines 11 a 14)Pull-up: en reposo, 1
Pulsador de cada entrada a masaAl pulsar, 0
Entradas D4..D7 (pines 3 a 6) a +5 V con 10 kΩAtadas en reposo (leen 1 = «no pulsado»)
Opcional: 100 nF de cada entrada a masaFiltro RC: τ = 10 kΩ · 100 nF = 1 ms, atenúa los rebotes más cortos

Rebotes: leer hasta que se repita

Un pulsador rebota unos milisegundos (tema 7). Si el programa lee justo en ese momento, puede obtener un valor intermedio. Hay dos defensas, que se pueden combinar: el filtro RC de arriba y una lectura por software que exige varias lecturas iguales seguidas antes de aceptar el valor (en el código, 3). Como un byte entero se lee en microsegundos, tres lecturas consecutivas cubren apenas unas decenas de µs: para que el filtro por software sirva, las lecturas deben espaciarse unos milisegundos.

Pruebas

  • Reposo: sin pulsar nada, la lectura cruda debe ser 11111111 (todo en alto).
  • Un pulsador: con D3 apretado, la lectura cruda es 11110111; invertida, 00001000.
  • Dos pulsadores a la vez: ambos bits aparecen en la misma lectura, porque todas las entradas se capturan en el mismo instante.
  • Pulsar sin soltar: la lectura no cambia entre dos lecturas consecutivas; el programa no debe contar una pulsación por cada lectura, sino un evento por cambio.

07 · Cuando no funciona

Fallas y método

De síntoma a causa en los montajes de este tema.
SíntomaCausa probableCómo comprobarlo
Se lee siempre el mismo bit repetido (00000000 o 11111111)PL̅ permanece en bajo: el registro carga todo el tiempo y el reloj se ignoraMedir el pin 1 en reposo: debe estar en 5 V
El byte llega corrido un lugar (0xB2 se lee 0x64)Se lee Q7 después de dar el reloj, no antesRevisar el orden «leer, luego pulsar CP»
Bits espejadosSe arma el byte con el primero en el LSB, o D0..D7 cableados al revésPoner un solo interruptor (D7) y ver en qué pulso aparece
Lecturas aleatorias que cambian al acercar la manoAlguna entrada D sin resistencia (al aire)Medir cada entrada en reposo: 0 V o 5 V, nunca intermedio
Todos los bits en 1 con los interruptores abiertosSe usó pull-up donde se esperaba pull-down (lógica negativa)Medir una entrada con el interruptor abierto
Con dos chips, siempre se ve solo unoQ7 del primero no llega a DS del segundo, o se leen 8 pulsos y no 16Comprobar el cable pin 9 → pin 10 y contar los pulsos
La lectura cambia aun sin tocar nada, solo al soltar o apretarRebotes del pulsadorRepetir la lectura; agregar el filtro RC
El reloj parece no hacer nadaCE̅ en alto o CP sin conectarMedir pin 15 (0 V) y pin 2 durante el pulso

Armar por etapas

  1. Alimentación primero: Vcc, GND y el 100 nF en cada chip.
  2. Atar todas las entradas, también las de interruptores que no se conecten.
  3. Probar la carga sola: con PL̅ pulsado, Q7 debe copiar D7 al instante.
  4. Probar el desplazamiento: un pulso de CP por vez y anotar cada bit.
  5. Un chip antes que dos: terminar el montaje 1 antes de encadenar.
  6. Cambiar una sola cosa a la vez cuando algo falla, y comparar el byte observado con el esperado.

08 · El taller en código

Cargar, desplazar y detectar cambios

Los bloques reproducen el 74HC165 con su carga y su desplazamiento, encadenan dos chips, muestran cómo se obtiene una lectura estable con pulsadores de lógica negativa y detectan pulsaciones y liberaciones comparando lecturas con XOR.

Python en tu navegador. Los bloques son editables: cambiá los valores y presioná «Ejecutar Python». La primera vez tarda unos segundos en cargar.

Paso 1: carga paralela y lectura serie

class HC165:
    """74HC165: registro paralelo-serie. sr[0] = Q0 ... sr[7] = Q7 (la salida serie)."""

    def __init__(self):
        self.sr = [0] * 8
        self.ds = 0                          # entrada serie (pin 10)

    def carga(self, entradas):               # PL̅ = 0: carga asíncrona de D0..D7
        self.sr = [(entradas >> i) & 1 for i in range(8)]

    def clk(self):                           # flanco ascendente de CP con CE̅ = 0
        salida = self.sr[7]
        self.sr = [self.ds] + self.sr[:-1]
        return salida

    @property
    def q7(self):
        return self.sr[7]


def leer(chip, entradas):
    chip.carga(entradas)                     # 1) pulso en PL̅: congela las 8 entradas
    valor = 0
    for _ in range(8):
        valor = (valor << 1) | chip.q7       # 2) se lee Q7 y después se da el reloj
        chip.clk()
    return valor


c = HC165()
interruptores = 0b10110010
print(f"entradas D7..D0 = {interruptores:08b}")
c.carga(interruptores)
print("bit leído en cada paso (Q7 antes del reloj):")
bits = []
for i in range(8):
    bits.append(c.q7)
    print(f"  pulso {i}: Q7 = {c.q7}  (corresponde a D{7 - i})")
    c.clk()
print("byte reconstruido:", "".join(map(str, bits)), "=", f"0x{int(''.join(map(str, bits)), 2):02X}")
print("lectura con leer():", f"{leer(HC165(), interruptores):08b}")

Con los interruptores en 10110010, el primer bit leído es D7 y el último D0: el byte se reconstruye como 0xB2 sin ninguna reordenación. El orden «leer Q7 y después dar el reloj» es el que no pierde el bit D7. Probá invertir esas dos líneas dentro de leer() y verificá que el resultado pasa a ser 0x64.

Paso 2: dos chips en cadena

class HC165:
    def __init__(self):
        self.sr = [0] * 8
        self.ds = 0

    def carga(self, entradas):
        self.sr = [(entradas >> i) & 1 for i in range(8)]

    def clk(self):
        self.sr = [self.ds] + self.sr[:-1]


def clk_cadena(chips):
    """Q7 de cada chip alimenta DS del siguiente; el micro lee el Q7 del último."""
    salientes = [c.sr[7] for c in chips]
    for i, c in enumerate(chips):
        c.ds = salientes[i - 1] if i > 0 else 0
        c.clk()


def leer(chips, entradas, bits):
    for i, c in enumerate(chips):
        c.carga((entradas[i]))
    valor = 0
    for _ in range(bits):
        valor = (valor << 1) | chips[-1].sr[7]
        clk_cadena(chips)
    return valor


A, B = HC165(), HC165()                    # A: su Q7 va al DS de B; el micro lee Q7 de B
cadena = [A, B]
entradas = [0xA5, 0x3C]                    # A tiene 0xA5 en sus interruptores, B tiene 0x3C
print(f"16 pulsos: leído = 0x{leer(cadena, entradas, 16):04X}   (B = 0x3C primero, luego A = 0xA5)")
A, B = HC165(), HC165()
cadena = [A, B]
print(f" 8 pulsos: leído = 0x{leer(cadena, entradas, 8):02X}   (solo llegó el chip B; A no se vio)")

Con 16 pulsos el microcontrolador recibe 0x3CA5: primero los bits del chip final (B, 0x3C) y después los del chip anterior (A, 0xA5). Con solo 8 pulsos aparece únicamente 0x3C y el chip A permanece invisible. La palabra de 16 bits se arma en el programa en el orden en que llegan los bytes.

Paso 3: rebotes, lectura estable y lógica negativa

import random

rnd = random.Random(7)


def lectura_estable(muestra, repeticiones=3):
    ultimo, cuenta, lecturas = None, 0, 0
    while cuenta < repeticiones:
        lecturas += 1
        v = muestra()
        cuenta = cuenta + 1 if v == ultimo else 1
        ultimo = v
    return ultimo, lecturas


# Un contacto que acaba de cerrarse y todavía rebota
ruido = lambda: 0b00000001 | (rnd.randint(0, 1) << 3)
print("lecturas sueltas de un contacto que rebota:", *(f"{ruido():08b}" for _ in range(5)))
print("lectura estable (3 iguales seguidas):      ", end=" ")
v, n = lectura_estable(ruido, 3)
print(f"{v:08b} tras {n} lecturas")

# Pulsadores con pull-up: leen 1 en reposo y 0 al pulsar (lógica negativa)
crudo = 0b11110111                    # el pulsador 3 está apretado
print(f"\ncrudo (pull-up):  {crudo:08b}  -> activos en bajo")
print(f"invertido en SW:  {crudo ^ 0xFF:08b}  -> 1 = pulsado")

El bit 0 es estable (siempre 1) y el bit 3 oscila, como un contacto que todavía rebota. Las lecturas sueltas alternan entre 00000001 y 00001001; la lectura estable espera tres iguales seguidas y entrega 00000001 tras 5 lecturas. Con pull-up, el pulsador 3 apretado se lee 11110111 y, tras el XOR con 0xFF, 00001000: un 1 donde hay pulsación. Cambiá la semilla y la cantidad de repeticiones para ver cuánto cuesta (en lecturas) una mayor confianza.

Paso 4: detectar eventos con XOR

anterior = 0b00000000
lecturas = [0b00000000, 0b00000100, 0b00000100, 0b00001100, 0b00001000, 0b00001000]
print("lectura    cambios    pulsaciones   liberaciones")
for v in lecturas:
    cambios = anterior ^ v
    pulsa = cambios & v                # pasó de 0 a 1
    suelta = cambios & anterior        # pasó de 1 a 0
    print(f"{v:08b}   {cambios:08b}   {pulsa:08b}      {suelta:08b}")
    anterior = v

f_clk = 1_000_000
for chips in (1, 2, 4):
    bits = 8 * chips
    t = bits / f_clk
    print(f"{chips} chip(s): {bits:2d} bits, {t*1e6:4.0f} us por lectura, hasta {1/t:,.0f} lecturas/s")

Con XOR entre la lectura nueva y la anterior se obtiene un 1 en cada bit que cambió. Al combinarlo con & se separan las pulsaciones (el bit 2 aparece en la segunda lectura y el 3 en la cuarta) de las liberaciones (el bit 2 se suelta en la quinta). Mientras el botón sigue apretado, la lectura repetida no produce eventos nuevos. En cuanto a velocidad, un chip se lee en 8 µs a 1 MHz (125 000 lecturas por segundo) y cuatro en 32 µs: sobra para cualquier teclado humano.

Es la misma técnica que se usa en el software de teclados y paneles: no importa cuántas lecturas se hagan, solo los cambios generan acciones.

09 · Exploración interactiva

El banco de pruebas

El simulador reproduce uno o dos 74HC165. Escribís el valor de las entradas (el campo de texto equivale a los interruptores), cargás el registro con «PL̅ = 0» y leés bit a bit con «Pulso CP», o hacés una lectura completa de una vez. El panel muestra la fila de entradas, el registro interno con Q7 resaltado y los bits que ya recibió el microcontrolador. Podés cambiar las entradas después de cargar para ver que el registro conserva la foto, leer sin cargar para ver qué sale en ese caso, e inhibir el reloj con CE̅.

74HC165 (uno o dos en cadena)

74HC165 simulado Dos filas: las entradas paralelas D y el registro interno, con el bit Q7 resaltado. Debajo se muestran el valor de Q7 y los bits que el microcontrolador ya leyó. Con dos chips en cadena hay 16 columnas.
Entradas actuales10110010
Registro interno (Q7 … Q0)00000000
Q7 (salida serie)0
Bits recibidos—
Palabra completa leída—
¿Lectura al día con las entradas?—
Pulsos de carga (PL̅)0
Pulsos de CP0

Un chip, registro en cero. Presioná «PL̅ = 0 (cargar)» y después «Leer Q7 y pulso CP» ocho veces.

Últimos 8 eventos desde el inicio de la simulación.
N.ºEventoRegistroQ7Detalle
Sin eventos registrados.

Recorrido guiado

  1. Con las entradas en 10110010, presioná «PL̅ = 0 (cargar)»: el registro vale lo mismo que las entradas y Q7 = 1 sin haber dado ningún reloj.
  2. Presioná «Leer Q7 y pulso CP» ocho veces: los bits recibidos van formando 10110010. Fijate en que el primero fue D7 y el último D0.
  3. Después del octavo pulso el registro está vacío (se llenó con los ceros de DS). Dos pulsos más empiezan una lectura nueva con datos que ya no son los de las entradas.
  4. Cargá de nuevo y cambiá el texto de las entradas a 00000001 sin volver a cargar: «¿Lectura al día?» pasa a «No». El registro conserva la foto.
  5. Presioná «Lectura completa»: hace el PL̅ y los ocho CP seguidos, y ahora la lectura coincide con las entradas actuales.
  6. Probá «Leer sin cargar (error)»: sale lo que quedaba en el registro, no las entradas. En el hardware real es el error de olvidarse del pulso de PL̅.
  7. Marcá CE̅ = 1 y pulsá CP: nada se mueve. Desmarcalo y el desplazamiento continúa. Marcá DS = 1 y mirá cómo entran unos por Q0 en lugar de ceros.
  8. Marcá «Dos chips en cadena»: las entradas son ahora 16 bits (el byte alto es el del chip del final). La lectura completa necesita 16 pulsos y entrega primero el byte alto.
Desafío: leer solo el byte que importa

Con dos chips en cadena y 16 bits, suponé que solo te interesa el chip de U2 (el más lejano al microcontrolador). Hay que dar los 16 pulsos igual: sus bits llegan al final, después de los 8 del chip vecino, y no hay forma de saltarse los primeros. El simulador lo muestra: los últimos 8 bits recibidos son siempre los del primer chip. Es una limitación de toda cadena serie: el costo de leer un dato es el de la cadena completa.

10 · Comprensión

Confusiones frecuentes

«El 165 lee las entradas cada vez que hay un flanco de reloj»

No: las toma una sola vez, cuando PL̅ pasa por cero. Los flancos siguientes solo mueven esa copia. Cambiar un interruptor durante el desplazamiento no afecta la lectura en curso.

«La carga paralela necesita un flanco de reloj»

En el 165 es asíncrona: actúa mientras PL̅ esté en bajo, sin reloj. Hay otros registros, como el 74HC194, con carga síncrona.

«El primer bit que sale es D0»

Sale D7, porque Q7 es el extremo hacia el que se desplaza todo. D0 es el último en salir.

«Se lee Q7 después de dar el reloj»

Entonces se pierde D7: el flanco ya lo desplazó afuera. Se lee Q7 primero y se da el reloj después.

«Si no uso un interruptor puedo dejar su entrada sin conectar»

Una entrada al aire flota y lee valores aleatorios. Toda entrada D se ata a 0 o a 1, esté usada o no.

«Un pulsador y un interruptor se leen igual»

El pulsador tiene lógica negativa si se conecta a masa con pull-up, rebota y se mantiene por poco tiempo. Hay que invertir la lectura, esperar una lectura estable y contar cambios, no estados.

«Leer más seguido evita los rebotes»

Al revés: leer más seguido ve más rebotes. Las lecturas que filtran deben espaciarse unos milisegundos, o apoyarse en un filtro RC en la entrada.

«Con dos chips puedo leer el primero sin pagar los 16 pulsos»

Los bits del primer chip salen al final de la cadena; para tenerlos hay que dar todos los pulsos.

11 · Práctica guiada

Predecí antes de armar

1. Qué sale en cada pulso

Los interruptores están en D7..D0 = 01101001 y DS = 0. Después de PL̅, ¿cuál es el valor de Q7 antes de cada uno de los ocho pulsos de CP, y qué queda en el registro tras el octavo?

Ver solución

Q7 vale, en orden: 0, 1, 1, 0, 1, 0, 0, 1 (D7 a D0). Tras el octavo pulso el registro vale 00000000, porque entraron ocho ceros por DS.

2. Cadena de dos

U2 (DS a masa) tiene 0x5A en sus interruptores y U3 (DS ← Q7 de U2, se lee Q7 de U3) tiene 0xC3. ¿Qué palabra de 16 bits recibe el microcontrolador con 16 pulsos? ¿Y con solo 8?

Ver solución

Con 16 pulsos: primero los 8 bits de U3 y luego los de U2, es decir 0xC35A. Con 8 pulsos: solo 0xC3, y el byte de U2 no se ve.

3. Tiempo de lectura

Una botonera de 32 pulsadores se lee con cuatro 165 en cadena y un reloj de 4 MHz. ¿Cuánto dura una lectura y cuántas se pueden hacer por segundo?

Ver solución

32 bits a 4 MHz: 32 / 4 000 000 = 8 µs por lectura, o hasta 125 000 lecturas por segundo. En la práctica unos cientos de veces por segundo, por los rebotes.

4. Lógica negativa

Con pull-ups, la lectura cruda es 11011110. ¿Qué pulsadores están apretados?

Ver solución

Se invierte: 11011110 XOR 11111111 = 00100001. Están apretados los pulsadores de D5 y D0 (los bits en 1 después de invertir).

5. Eventos con XOR

La lectura anterior fue 00110000 y la nueva es 01010000. ¿Qué cambió, qué se pulsó y qué se soltó?

Ver solución

Cambios = 00110000 XOR 01010000 = 01100000. Pulsación = cambios AND nueva = 01000000 (bit 6). Liberación = cambios AND anterior = 00100000 (bit 5).

6. Diagnóstico

La lectura da siempre 11111111 cuando el interruptor de D7 está cerrado y siempre 00000000 cuando está abierto, sin importar cómo estén los demás, y los bits no cambian al dar el reloj. ¿Qué pasa?

Ver solución razonada

La lectura copia el valor de D7 ocho veces: el registro nunca sale del modo de carga. La causa más probable es PL̅ atascado en bajo (pulsador pegado, pin 1 a masa o sin la resistencia a +5 V). Con PL̅ = 0 el registro sigue a las entradas y el reloj se ignora, de modo que Q7 es siempre D7. Se confirma midiendo 0 V en el pin 1 en reposo.

12 · Síntesis

Ideas para recordar

  • El 74HC165 captura ocho entradas a la vez (PL̅ = 0, asíncrono) y las entrega en serie por Q7 con cada flanco de CP.
  • El primer bit que sale es D7. Se lee Q7 antes de dar el reloj; si se invierte el orden, se pierde D7 y el byte queda corrido.
  • La lectura es una foto: los cambios en las entradas después de PL̅ no afectan a la lectura en curso.
  • Q7 de un chip alimenta DS del siguiente y se lee el Q7 del último; los primeros bits recibidos son los del chip final. Una cadena de k chips necesita 8k pulsos.
  • Toda entrada D se ata a un nivel; los pulsadores con pull-up dan lógica negativa y hay que invertir la lectura.
  • Los pulsadores rebotan: se usan un filtro RC y lecturas repetidas espaciadas en milisegundos.
  • Con XOR entre la lectura nueva y la anterior se obtienen los bits que cambiaron, y con AND se separan pulsaciones de liberaciones.
  • Con el 595 y el 165 se forma una E/S expandible de cinco pines, sin importar cuántos chips haya.

¿Listo para el tema 17?

Antes de avanzar, explicá de memoria qué hace PL̅ y qué hace CP, por qué se lee Q7 antes de dar el reloj y cómo se detecta una pulsación nueva a partir de dos lecturas. Si podés justificar las tres respuestas, ya podés pasar de mover bits a contar con ellos.

En el próximo tema veremos los contadores asíncronos: cómo encadenar flip-flops T para que cada uno divida la frecuencia por dos y el conjunto cuente pulsos en binario.