Electrónica Digital · Tema 21

Display de 7 segmentos

Hasta ahora tus circuitos mostraban resultados con un LED. Un número necesita más: siete segmentos que se combinan para dibujar cada dígito, un decodificador que traduce el nibble BCD a la combinación correcta y, la parte que quema componentes cuando se hace mal, la corriente de cada segmento. Es el primer lugar donde la lógica digital se encuentra con la física de la luz.

≈ 60 minutos Sin materiales: solo el navegador Incluye simulador y Python

01 · Punto de partida

Siete LED que saben contar

Un dígito de display de 7 segmentos son siete barras luminosas (a, b, c, d, e, f, g) más un punto decimal. Cada dígito del 0 al 9 enciende una combinación distinta. El camino de la información es siempre el mismo: un número en BCD (cuatro bits) entra a un decodificador BCD a 7 segmentos, que genera siete señales; cada señal alimenta un segmento a través de una resistencia.

nibble BCD (4 bits)→ decodificador (7 funciones) →7 señales→ resistencia por segmento →luz

Una escena típica. Armás un contador de 0 a 9 y querés ver el número. Conectás un 74LS47 a un display, ponés una sola resistencia para todos los segmentos «para ahorrar», y el 8 se ve opaco mientras el 1 brilla de más. Cambiás de display y no enciende nada: era de cátodo común y el 7447 solo maneja ánodo común. Un tercer problema aparece cuando querés mostrar cuatro dígitos: el montaje se llena de cables y te quedás sin pines.

Los tres problemas (la resistencia por segmento, el tipo de común y el multiplexado) tienen explicación y solución en este tema. Además, los siete segmentos son siete funciones de cuatro variables con seis condiciones «no importa», así que hay un ejercicio de Karnaugh escondido.

  • ¿Qué segmentos enciende cada dígito, y qué byte corresponde a cada uno?
  • ¿Qué diferencia hay entre ánodo común y cátodo común, y cuál decodificador va con cuál?
  • ¿Cuánta corriente consume un dígito y qué resistencia lleva cada segmento?
  • ¿Qué pasa con los códigos 10 a 15?
  • ¿Cómo se muestran varios dígitos con pocos pines?

02 · Segmentos

El mapa a–g y los códigos

Los segmentos se nombran con letras en un orden fijo: a arriba, luego b y c a la derecha (de arriba abajo), d abajo, e y f a la izquierda (de abajo arriba) y g en el medio. El punto decimal es el octavo elemento (dp).

Segmentos que enciende cada símbolo y su byte (bits: dp g f e d c b a, de MSB a LSB).
SímboloSegmentosCantidadByte para cátodo común (1 enciende)Byte para ánodo común (0 enciende)
0a b c d e f60x3F0xC0
1b c20x060xF9
2a b d e g50x5B0xA4
3a b c d g50x4F0xB0
4b c f g40x660x99
5a c d f g50x6D0x92
6a c d e f g60x7D0x82
7a b c30x070xF8
8a b c d e f g70x7F0x80
9a b c d f g60x6F0x90
Aa b c e f g60x770x88
bc d e f g50x7C0x83
Ca d e f40x390xC6
db c d e g50x5E0xA1
Ea d e f g50x790x86
Fa e f g40x710x8E
Un byte por símbolo
Con un microcontrolador, la tabla anterior es un arreglo de 16 bytes: const uint8_t SEG[16]. El byte de ánodo común es el complemento (XOR con 0xFF) del de cátodo común. El bit 7 es el punto decimal.
Variantes de dibujo
Según el fabricante, el 6 puede omitir el segmento a, el 9 el d y el 7 sumar el f. Son diferencias de estilo; verificá el aspecto antes de armar una tabla propia.
Siete funciones de cuatro variables
Cada segmento es una función de las cuatro entradas BCD, con los códigos 10 a 15 como «no importa». Por ejemplo, el segmento a vale 1 en los dígitos 0, 2, 3, 5, 6, 7, 8 y 9, y minimizando con las X queda a = A + C + B·D + ~B·~D (con A como bit más significativo). Se pueden obtener los otros seis de la misma manera con el Tema 16 (el Paso 2 de Python los calcula todos).

03 · Común

Ánodo común, cátodo común y sus decodificadores

Los siete LED de un dígito comparten un terminal, para ahorrar patas. Si comparten el ánodo, ese terminal va a VCC y cada segmento se enciende llevando su cátodo a un nivel bajo (el driver «hunde» corriente). Si comparten el cátodo, ese terminal va a masa y cada segmento se enciende con un nivel alto (el driver «entrega» corriente).

Ánodo común (CA)

Común a VCC, segmento a 0

Cada salida del decodificador es activa en bajo y debe soportar la corriente del segmento hacia masa. Driver clásico: 7447 (colector abierto, aguanta decenas de mA).

Cátodo común (CC)

Común a masa, segmento a 1

Cada salida es activa en alto y entrega la corriente. Drivers: 7448 (poca corriente) y CD4511/74HC4511 (con memoria).

Decodificadores BCD a 7 segmentos más comunes.
ChipDisplaySalidasCódigos 10 a 15Entradas especiales
74LS47 (7447)Ánodo comúnActivas en bajo, colector abierto (hunden decenas de mA)Símbolos raros (no son letras)~LT (prueba de lámpara), ~RBI y ~RBO (supresión de ceros), ~BI
74LS48 (7448)Cátodo comúnActivas en alto, con resistencias internas (poca corriente)Símbolos rarosLas mismas que el 47
CD4511 / 74HC4511Cátodo comúnActivas en alto, con corriente moderadaApagado (blanking)LE (retiene el dígito), ~BI (apagar), ~LT (prueba)
Microcontrolador + tablaEl que quierasPines de E/SLo que decidas: hexadecimal, guiones, letrasSoftware
Códigos 10 a 15
Los decodificadores BCD no están pensados para ellos (son «no importa» del Tema 6) y cada chip hace algo distinto. El 4511 apaga todo; los 7447 y 7448 dibujan símbolos extraños que no son las letras hexadecimales. Para ver A a F hace falta una tabla propia, normalmente en un microcontrolador.
Prueba de lámpara (~LT)
Con ~LT en 0 se encienden todos los segmentos sin importar la entrada: sirve para detectar segmentos quemados o mal soldados. Es una prueba que un programador reconoce: un «self-test» al arrancar.
Apagado (~BI)
Con ~BI en 0 el display se apaga completamente. Se usa para regular el brillo (con PWM) o para el multiplexado.
Latch del 4511
Con LE = 0 las salidas siguen a las entradas BCD; con LE = 1 el chip retiene el último dígito aunque las entradas cambien. Permite compartir el bus de datos entre varios 4511 (uno por dígito) y actualizarlos por turnos.
El punto decimal
No lo maneja el decodificador: es un LED aparte con su propia resistencia. No hay que olvidarlo al contar pines.

04 · Corriente

Resistencia por segmento y presupuesto de corriente

Un LED no limita su propia corriente: cualquier voltaje por encima de su caída directa (Vf) la dispara y lo quema. Cada segmento necesita una resistencia en serie que fije la corriente:

Resistencia para 10 mA a 5 V con una caída del driver de 0,5 V (valores típicos; medí los tuyos).
ColorVf típicaR exactaValor E12 (por arriba)Corriente real
Rojo1,8 V270 Ω270 Ω10,0 mA
Amarillo2,0 V250 Ω270 Ω9,3 mA
Verde2,1 V240 Ω270 Ω8,9 mA
Azul / blanco3,1 V140 Ω150 Ω9,3 mA

Una resistencia por segmento, no una común

Cada dígito enciende una cantidad distinta de segmentos, así que la corriente total cambia:

Corriente por dígito con 10 mA por segmento.
DígitoSegmentosCorriente total
1220 mA
7330 mA
4440 mA
2, 3, 5550 mA
0, 6, 9660 mA
8770 mA

Con una sola resistencia común (en el terminal común) la corriente total estaría fijada por esa resistencia y se repartiría entre los segmentos encendidos: el 1 (dos segmentos) brillaría el triple que cada segmento del 8 (siete). Con una resistencia por segmento, cada uno recibe la misma corriente sin importar cuántos más estén encendidos.

Los límites del driver
Un 74LS47 hunde 40 mA por salida: sobra. Los CMOS tienen un tope por salida (típicamente 25 mA como máximo absoluto) y otro por patita de alimentación (50 mA en la familia HC). Con 70 mA para un 8 a 10 mA por segmento, un 74HC4511 se pasaría del tope total: hay que bajar la corriente por segmento (menos de unos 7 mA con los siete encendidos) o usar transistores.
¿Cuánta corriente hace falta?
Los LED rojos de alta eficiencia modernos se ven bien con 2 a 5 mA. Los 10 mA de los textos clásicos eran para LED antiguos. Bajar la corriente ahorra energía, calor y problemas con el driver. Probá con una resistencia mayor antes de aceptar 10 mA.
Segmentos con distinta eficiencia
Un LED azul o blanco necesita más de 3 V: a 5 V con un driver que cae 0,5 V quedan 1,5 V para la resistencia. Con alimentación de 3,3 V directamente no encienden.

05 · Varios dígitos

El multiplexado: encender de a uno, rápido

Un display de cuatro dígitos con un decodificador por dígito necesita cuatro decodificadores y 28 resistencias. El multiplexado lo resuelve con un solo decodificador y siete resistencias: los segmentos de los cuatro dígitos están unidos en paralelo y cada dígito tiene su propio común. En cada instante se enciende un solo dígito, con sus datos, y se pasa al siguiente tan rápido que el ojo ve los cuatro encendidos a la vez (persistencia de la visión).

seleccionar dígito k→ poner sus datos en los segmentos →esperar un instante →apagar y pasar al k + 1
Cuánto hay que correr para N dígitos (100 Hz de refresco completo, 5 mA promedio por segmento).
Dígitos (N)Ciclo de trabajoFrecuencia de barrido (N × 100 Hz)Corriente pico para 5 mA promedio
1100 %—5 mA
250 %200 Hz10 mA
425 %400 Hz20 mA
812,5 %800 Hz40 mA
Compensar el brillo
Con N dígitos, cada uno está encendido 1/N del tiempo. Para el mismo brillo promedio hay que multiplicar la corriente pico por N. Eso exige que el driver soporte el pico (por eso en displays de 8 dígitos se usan transistores o drivers dedicados).
Selección de dígito
Un decodificador (74HC138 o 139, Tema 20) maneja transistores que conectan el común de cada dígito: PNP a VCC para ánodo común, NPN a masa para cátodo común. El común de un dígito lleva la suma de la corriente de todos sus segmentos.
Los datos
Un multiplexor (Tema 18) por cada bit del nibble elige el dígito BCD del que toca mostrar, y un contador sincroniza el selector de dígito con el selector del multiplexor. Con un microcontrolador, simplemente se escribe el byte del dígito en cada turno.
Parpadeo
Por debajo de unos 60 Hz de refresco completo se percibe parpadeo; más de 100 Hz es cómodo. Si el microcontrolador hace otras cosas, el barrido se programa en una interrupción de temporizador.
Fantasmas (ghosting)
Si se cambian los datos de los segmentos antes de apagar el dígito anterior, por un instante los segmentos del dígito nuevo se ven en el viejo: una tenue imagen fantasma. La regla es la de los buses (Tema 7): primero apagar, después cambiar, por último encender.

06 · Vida real

Ceros a la izquierda, binario a BCD y drivers integrados

Supresión de ceros a la izquierda
Un contador de 4 dígitos que vale 7 mostraría «0007». Los 7447 y 7448 tienen las entradas ~RBI y ~RBO (ripple blanking) para apagar los ceros del principio: el dígito más significativo recibe ~RBI = 0, y si vale 0 se apaga y emite ~RBO = 0 hacia el siguiente. El último dígito nunca se apaga (su ~RBI se ata a VCC), así que el cero solitario sigue viéndose.
El problema binario a BCD
Los contadores y los microcontroladores trabajan en binario; el decodificador espera BCD. 42 en binario es 101010; el decodificador de unidades recibiría 1010 (el código inválido A). Hay que convertir. El algoritmo clásico es el doble dabble (shift-and-add-3): por cada bit del número, de izquierda a derecha, se suma 3 a cada dígito BCD que valga 5 o más y se desplaza todo un lugar. En 8 iteraciones, el número binario queda en BCD.
Los contadores BCD
Si el contador ya cuenta en BCD (74HC160, 74HC4518), se evita la conversión: cada dígito cuenta de 0 a 9 y avisa al siguiente con un acarreo. Es la solución natural para contadores y relojes.
Drivers integrados
Para displays de varios dígitos, hoy es más cómodo un integrado que haga todo: el MAX7219 maneja hasta 8 dígitos por SPI (multiplexado, decodificación BCD, brillo y prueba de lámpara incluidos) y el TM1637 hace lo mismo para 4 dígitos con dos cables. Es el mismo principio que viste, empaquetado en un chip y una interfaz serie.
Supresión de ceros con ~RBI/~RBO en un display de 4 dígitos.
NúmeroDígitosSin supresiónCon supresión
70 0 0 70007···7
420 0 4 20042··42
1000 1 0 00100·100
00 0 0 00000···0
10051 0 0 510051005 (los ceros del medio se ven)

07 · Simulador

Laboratorio: probador de dígitos

El simulador dibuja un display de 7 segmentos y lo maneja desde un código de 4 bits (0 a 15). Elegís el decodificador (74LS47 para ánodo común, 74HC4511 para cátodo común, o un microcontrolador con tabla propia), el color del LED y la corriente por segmento, y ves qué segmentos se encienden, el nivel de cada salida, la resistencia comercial, la corriente total y el efecto de multiplexar N dígitos.

  • Display: los segmentos encendidos en amarillo, los apagados en gris. Con 74LS47 y códigos 10 a 15 se dibuja un «?» (los símbolos raros dependen del chip); con 74HC4511 el display se apaga; con la tabla propia se ve el hexadecimal.
  • Tabla de salidas: el nivel de cada salida del chip. En ánodo común un segmento encendido tiene su salida en 0 (el chip «hunde»); en cátodo común, en 1.
  • Corrientes: la resistencia exacta y la comercial para esa corriente, la corriente real y el total del dígito, con un aviso si se superan los límites del driver.
SIMULADOR 21

Probador de dígitos

5 → a c d f g

Display de 7 segmentos y sus señales Un dígito de siete segmentos y punto decimal con los segmentos encendidos en amarillo, una tabla con el nivel de cada salida del decodificador y un panel con las corrientes. UN DÍGITO · SIETE SEGMENTOS · UNA RESISTENCIA CADA UNO
Muestra y segmentos5 · a c d f g
Byte (dp g f e d c b a)0x6D
Resistencia y corriente270 Ω · 10 mA/segmento
Dígito y multiplexado50 mA · 1 dígito

5: segmentos a c d f g.

Recorrido guiado (8 minutos)

  1. 1
    Mirá el 5 con el 74LS47.

    Cinco segmentos (a, c, d, f, g) encendidos. La tabla muestra que en ánodo común esas salidas valen 0 (el chip las lleva a nivel bajo para que fluya corriente), y las otras dos valen 1. El byte de ánodo común es 0x92 (el complemento de 0x6D).

  2. 2
    Apretá «Dígito 8» y después «Dígito 1».

    El 8 enciende siete segmentos (70 mA con 10 mA cada uno); el 1 solo dos (20 mA). El consumo del dígito depende de lo que se muestra. Por eso la resistencia va en cada segmento y no en el común.

  3. 3
    Cambiá a 74HC4511 con el dígito 8 a 10 mA.

    Aparece un aviso: 70 mA superan el límite total de 50 mA por alimentación del CMOS. Bajá la corriente por segmento hasta que el aviso desaparezca (con el control en 8 mA o menos: la resistencia comercial, un poco mayor que la exacta, deja la corriente real en unos 7 mA).

  4. 4
    Probá los códigos 10 a 15 con cada decodificador.

    Con el 74LS47 se dibuja un «?»: símbolos extraños, no estándar. Con el 74HC4511 el display se apaga (blanking). Con la tabla de un microcontrolador ves A, b, C, d, E, F: tenés que dibujarlas vos.

  5. 5
    Cambiá el color a azul.

    La caída directa sube de 1,8 V a 3,1 V y la resistencia necesaria baja de 270 Ω a 150 Ω para la misma corriente: quedan 1,4 V para la resistencia.

  6. 6
    Subí la corriente a 20 mA con el 4511 o el micro.

    Aparece el aviso de límite por salida (25 mA para CMOS, 20 mA para un pin de microcontrolador). Los LED modernos se ven bien con mucho menos.

  7. 7
    Elegí 4 dígitos y después 8.

    El ciclo de trabajo baja a 25 % y 12,5 %, y la corriente pico necesaria para el mismo brillo sube de 10 mA a 40 y 80 mA. La frecuencia de barrido mínima sube a 400 y 800 Hz para mantener 100 Hz de refresco por dígito. A 8 dígitos, el pico excede lo que un driver CMOS soporta: hacen falta transistores o un MAX7219.

  8. 8
    Recorré el código con «Siguiente».

    Del 0 al 9 pasan los diez dígitos; después, lo que corresponda a cada decodificador. Compará el byte con la tabla de la sección 02.

Preguntas para pensar

  1. ¿Cuántos segmentos y qué corriente total tienen el 8 y el 1 con 10 mA por segmento?
  2. ¿Qué hace cada decodificador con los códigos 10 a 15?
  3. ¿Por qué cambia la resistencia al pasar de un LED rojo a uno azul?
  4. Con 4 dígitos multiplexados y 5 mA de brillo promedio, ¿qué corriente pico hace falta?
Ver respuestas sugeridas
  1. El 8 tiene 7 segmentos (70 mA) y el 1 tiene 2 (20 mA): el consumo depende del dígito.
  2. El 4511 apaga todo; los 7447 y 7448 dibujan símbolos raros; un microcontrolador con tabla puede mostrar A a F. Ninguno muestra «solo» las letras sin ayuda.
  3. El azul cae unos 3,1 V (contra 1,8 V del rojo): queda menos voltaje para la resistencia, y R = V/I resulta menor para la misma corriente.
  4. Cada dígito está encendido un cuarto del tiempo: el pico debe ser 4 × 5 = 20 mA.

08 · Dígitos en código

Dibujar, minimizar, calcular y convertir

Los bloques dibujan los 16 símbolos en texto con sus bytes, minimizan los siete segmentos del decodificador (con las X de 10 a 15), calculan resistencias y presupuestos de corriente, simulan el multiplexado con y sin apagado previo (fantasmas), reproducen la supresión de ceros con RBI/RBO y convierten binario a BCD con doble dabble.

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: los 16 símbolos y sus bytes

SEG = {"0": "abcdef", "1": "bc", "2": "abdeg", "3": "abcdg", "4": "bcfg", "5": "acdfg",
       "6": "acdefg", "7": "abc", "8": "abcdefg", "9": "abcdfg",
       "A": "abcefg", "b": "cdefg", "C": "adef", "d": "bcdeg", "E": "adefg", "F": "aefg"}


def byte_cc(c):
    return sum(1 << "abcdefg".index(x) for x in SEG[c])


def tres_lineas(c):
    s = SEG[c]
    return [" " + ("_" if "a" in s else " ") + " ",
            ("|" if "f" in s else " ") + ("_" if "g" in s else " ") + ("|" if "b" in s else " "),
            ("|" if "e" in s else " ") + ("_" if "d" in s else " ") + ("|" if "c" in s else " ")]


def mostrar(texto):
    cols = [tres_lineas(c) for c in texto]
    for fila in range(3):
        print(" ".join(col[fila] for col in cols))


mostrar("0123456789")
mostrar("ABCDEF")
print()
print("símbolo  segmentos  cátodo común  ánodo común")
for c in "0123456789AbCdEF":
    cc = byte_cc(c)
    print(f"   {c}     {len(SEG[c])}          0x{cc:02X}          0x{cc ^ 0xFF:02X}")

Los bytes coinciden con la tabla de la sección 02: 0x3F para el 0, 0x06 para el 1, 0x7F para el 8, y el de ánodo común es el complemento de cada uno. Con un micro, esto es literalmente el arreglo SEG[16].

Paso 2: los siete segmentos minimizados (con las X)

from itertools import combinations

SEG = {"0": "abcdef", "1": "bc", "2": "abdeg", "3": "abcdg", "4": "bcfg", "5": "acdfg",
       "6": "acdefg", "7": "abc", "8": "abcdefg", "9": "abcdfg"}


def primos(unos, dcs, n):
    actual = {format(m, f"0{n}b") for m in set(unos) | set(dcs)}
    res = set()
    while actual:
        sig, usados = set(), set()
        for a, b in combinations(sorted(actual), 2):
            d = [i for i in range(n) if a[i] != b[i]]
            if len(d) == 1 and "-" not in (a[d[0]], b[d[0]]):
                i = d[0]
                sig.add(a[:i] + "-" + a[i + 1:])
                usados.update((a, b))
        res |= actual - usados
        actual = sig
    return sorted(res)


def cubre(p, m, n):
    b = format(m, f"0{n}b")
    return all(x in ("-", y) for x, y in zip(p, b))


def minima(unos, dcs, n):
    ps = primos(unos, dcs, n)
    esc = set()
    for m in unos:
        c = [p for p in ps if cubre(p, m, n)]
        if len(c) == 1:
            esc.add(c[0])
    resto = [m for m in unos if not any(cubre(p, m, n) for p in esc)]
    libres = [p for p in ps if p not in esc]
    for k in range(len(libres) + 1):
        sol = [c for c in combinations(libres, k) if all(any(cubre(p, m, n) for p in c) for m in resto)]
        if sol:
            return sorted(esc | set(min(sol, key=lambda c: sum(x != "-" for p in c for x in p))))
    return sorted(esc)


def termino(p):
    return "·".join(v if x == "1" else "~" + v for v, x in zip("ABCD", p) if x != "-") or "1"


dcs = list(range(10, 16))
todos = set()
for s in "abcdefg":
    unos = [d for d in range(10) if s in SEG[str(d)]]
    ps = minima(unos, dcs, 4)
    todos.update(ps)
    ok = all(any(cubre(p, d, 4) for p in ps) == (s in SEG[str(d)]) for d in range(10))
    print(f"{s} = {' + '.join(termino(p) for p in ps):<28} {'ok' if ok else 'FALLA'}")
print(f"términos de producto distintos entre los siete segmentos: {len(todos)}")
print("alternativa: una ROM de 16 x 7 bits =", 16 * 7, "bits")

Cada segmento queda con entre 2 y 5 términos. El segmento a sale A + C + B·D + ~B·~D, como en la sección 02. Hay términos que se repiten entre segmentos y se pueden compartir, como en un diseño multisalida (Tema 17).

Paso 3: resistencias, E12 y el presupuesto de corriente

E12 = (1.0, 1.2, 1.5, 1.8, 2.2, 2.7, 3.3, 3.9, 4.7, 5.6, 6.8, 8.2)


def e12_mayor(r):
    dec = 1
    while True:
        for v in E12:
            if v * dec >= r - 1e-9:
                return v * dec
        dec *= 10


def resistencia(vcc, vf, vdrop, i_ma):
    r = (vcc - vf - vdrop) / (i_ma / 1000)
    rc = e12_mayor(r)
    return r, rc, (vcc - vf - vdrop) / rc * 1000


print("color        Vf   R exacta   E12   corriente real")
for color, vf in (("rojo", 1.8), ("amarillo", 2.0), ("verde", 2.1), ("azul/blanco", 3.1)):
    r, rc, i = resistencia(5.0, vf, 0.5, 10)
    print(f"{color:<11} {vf:>4}   {r:>6.0f} Ω   {rc:>4.0f} Ω   {i:>5.1f} mA")

SEGS = {"0": 6, "1": 2, "2": 5, "3": 5, "4": 4, "5": 5, "6": 6, "7": 3, "8": 7, "9": 6}
print()
print("corriente por dígito con 10 mA por segmento:", {d: n * 10 for d, n in SEGS.items()})
LIMITE_TOTAL = 50      # mA por patita de alimentación en un CMOS de la familia HC
print(f"con un 74HC4511 el dígito 8 admite como máximo {LIMITE_TOTAL / 7:.1f} mA por segmento")
r, rc, i = resistencia(5.0, 1.8, 0.5, 7)
print(f"para 7 mA: R exacta {r:.0f} Ω -> {rc:.0f} Ω -> {i:.1f} mA, el 8 consume {7 * i:.0f} mA")

Rojo: 270 Ω y 10 mA; verde y amarillo: 270 Ω y unos 9 mA; azul: 150 Ω. Con un CMOS limitado a 50 mA totales, un dígito 8 admite unos 7 mA por segmento (resistencia de 390 Ω).

Paso 4: multiplexado y fantasmas

print(" N  ciclo   barrido   pico para 5 mA promedio")
for N in (1, 2, 4, 8):
    print(f"{N:>2}  {100 / N:>5.1f} %  {100 * N:>5} Hz  {5 * N:>5} mA")

DATOS = {0: "1", 1: "2"}          # qué debe mostrar cada dígito


def secuencia(apagar_primero):
    pasos, activo, segs = [], None, None
    for d in (0, 1):
        if apagar_primero:
            activo = None
            pasos.append((activo, segs))          # primero apago el dígito
            segs = DATOS[d]
            pasos.append((activo, segs))          # cambio los segmentos con todo apagado
            activo = d
            pasos.append((activo, segs))          # recién ahora enciendo el dígito
        else:
            segs = DATOS[d]
            pasos.append((activo, segs))          # cambio los segmentos con el dígito anterior encendido
            activo = d
            pasos.append((activo, segs))
    return pasos


for apagar in (False, True):
    print()
    print("con apagado previo:" if apagar else "sin apagado previo:")
    fantasmas = 0
    for activo, segs in secuencia(apagar):
        fantasma = activo is not None and DATOS[activo] != segs
        fantasmas += fantasma
        print(f"   dígito encendido={activo}  segmentos={segs}  {'FANTASMA' if fantasma else ''}")
    print(f"   instantes con fantasma: {fantasmas}")

El pico de corriente crece con N (5, 10, 20, 40 mA para el mismo brillo). Cambiar los segmentos antes de apagar el dígito anterior muestra un instante del símbolo equivocado en el dígito viejo (fantasma). Con la regla «apagar, cambiar, encender» no hay ningún instante así.

Paso 5: supresión de ceros con RBI y RBO

def con_rbi(n, k=4):
    digs = [int(c) for c in str(n).zfill(k)]
    rbi = True                         # el dígito más significativo recibe ~RBI activo
    salida = []
    for i, d in enumerate(digs):
        ultimo = i == k - 1            # el último dígito nunca se apaga (su ~RBI va a VCC)
        if d == 0 and rbi and not ultimo:
            salida.append("·")         # apagado; su ~RBO activo pasa al siguiente
        else:
            salida.append(str(d))
            rbi = False                # un dígito visible corta la cadena
    return "".join(salida)


for n in (7, 42, 100, 0, 1005, 5000, 9999):
    print(f"{n:>5}  sin supresión: {str(n).zfill(4)}   con supresión: {con_rbi(n)}")

Los ceros del principio se apagan, pero un cero entre dígitos visibles (1005) o al final (100) se ve, y el número 0 muestra un cero en la última posición. La cadena RBI → RBO funciona de izquierda a derecha, igual que este bucle.

Paso 6: de binario a BCD con doble dabble

def doble_dabble(n, bits=8):
    bcd = 0
    digitos = (bits + 2) // 3
    for i in range(bits - 1, -1, -1):
        for d in range(digitos):
            nib = (bcd >> (4 * d)) & 0xF
            if nib >= 5:
                bcd += 3 << (4 * d)               # si un dígito es 5 o más, sumarle 3...
        bcd = (bcd << 1) | ((n >> i) & 1)       # ...y desplazar todo una posición
    return bcd


for n in (7, 42, 99, 100, 255):
    b = doble_dabble(n)
    print(f"{n:>3} = {n:08b} -> BCD {b >> 8 & 0xF}{b >> 4 & 0xF}{b & 0xF}  (0x{b:03X})")

print("verificado para 0 a 255:", all(doble_dabble(n) == int(str(n), 16) for n in range(256)))
print("42 sin convertir: nibble bajo =", format(42 & 0xF, "04b"), "= 0x%X (código inválido)" % (42 & 0xF))

El doble dabble convierte 0 a 255 en tres nibbles BCD (42 pasa a 0x042, es decir, 0, 4, 2). Es la razón por la que no se puede alimentar un decodificador directamente con la salida de un contador binario: el 42 binario tiene el nibble bajo en 0xA, un código inválido.

09 · Analogía de programador

Una fuente de 7 píxeles

El mismo concepto, en dos mundos.
En softwareEn el display de 7 segmentos
Una fuente bitmap: un mapa de bits por carácterEl byte de segmentos de cada símbolo
Un arreglo de consulta const uint8_t SEG[16]El decodificador 7447/4511 hecho en silicio
Validar el rango de una entrada antes de usarlaEl blanking del 4511 con los códigos 10 a 15
Limitar el consumo de recursos por hilo (rate limit)Una resistencia por segmento: corriente pareja en cada canal
Refrescar una pantalla a N cuadros por segundoEl multiplexado: cada dígito se redibuja en cada ciclo
Doble búfer: no mostrar un cuadro a medio escribirApagar antes de cambiar los segmentos (sin fantasmas)
itoa: pasar un número a dígitos decimalesLa conversión binario a BCD (doble dabble)
Un self-test al arrancarLa prueba de lámpara ~LT
Delegar el trabajo a un periférico por SPIEl MAX7219 o el TM1637
  1. 1
    Segmentos = bitmap.

    Cada dígito son siete bits: una fuente de siete píxeles con decodificador incluido.

  2. 2
    Blanking = validación.

    Entrada fuera de rango, sin salida: mejor que dibujar basura.

  3. 3
    Resistencia por segmento = límite por canal.

    Un único limitador global castiga a los canales que menos usan; un limitador por canal da un comportamiento uniforme.

Una diferencia con el software: el «píxel» consume corriente real, y la suma de todos los píxeles encendidos pasa por una sola patita de alimentación. Dibujar un 8 en lugar de un 1 puede superar el límite de un chip, algo que en una pantalla de software nunca pasa.

10 · Comprensión

Confusiones frecuentes

«Una resistencia común para todos los segmentos»

El brillo cambiaría con el dígito: el 1 (dos segmentos) se vería mucho más brillante por segmento que el 8 (siete). Cada segmento lleva su propia resistencia.

«Ánodo o cátodo da igual»

Define el decodificador (74LS47 para ánodo, 74LS48 y 4511 para cátodo) y el cableado del común. Equivocarse da un display apagado o al revés.

«Los códigos 10 a 15 muestran A a F»

El 4511 los apaga y el 7447/7448 dibuja símbolos raros. Para mostrar hexadecimal hace falta una tabla propia (un microcontrolador).

«Sin resistencia hay más brillo»

Hay un LED o un driver quemado. El brillo se diseña con la corriente, y la corriente la fija una resistencia.

«Un 74HC puede manejar 70 mA de un dígito 8»

Cada salida tiene su límite y la patita de alimentación tiene otro (unos 50 mA en la familia HC). Hay que bajar la corriente por segmento, usar transistores o un driver dedicado.

«Con 30 Hz de refresco alcanza»

Por debajo de unos 60 Hz de refresco completo se ve parpadeo. Conviene 100 Hz o más para todo el display, es decir, N × 100 Hz de barrido para N dígitos.

«Puedo conectar la salida de un contador binario al decodificador BCD»

Solo si el contador cuenta en BCD. Un contador binario llega al 10 como 1010, un código inválido. Se convierte (doble dabble) o se usa un contador de décadas.

11 · Práctica guiada

Ejercicios de display

Ejercicio 1: la resistencia exacta

Un display rojo (Vf = 1,8 V) a 5 V con un driver que cae 0,5 V, para 12 mA por segmento. ¿Qué resistencia exacta y cuál comercial (E12)? ¿Qué corriente real da?

Ver solución razonada

R = (5 − 1,8 − 0,5) V / 12 mA = 225 Ω. El valor E12 inmediato por arriba es 270 Ω, que da 2,7 / 270 = 10 mA (por debajo del objetivo, más seguro). El 220 Ω da 12,3 mA, ligeramente por encima de 12 mA; solo conviene si ese es el valor máximo tolerado. Con el 8 encendido (siete segmentos) el consumo es 70 mA con 270 Ω.

Ejercicio 2: dos dígitos con latch

Un contador de 00 a 99 usa dos 74HC4511. ¿Qué ventaja da el latch y cómo se carga el «42»?

Ver solución razonada

Con LE = 0 el 4511 sigue las entradas; con LE = 1 retiene el último dígito aunque las entradas cambien. Permite compartir un único bus de datos de 4 bits entre los dos chips: se pone 4 en el bus y se pulsa LE del primero a 1 para fijarlo; se pone 2 y se fija el segundo. Los dos dígitos quedan mostrando «42» aunque el bus siga cambiando.

Ejercicio 3: montar un dígito

Un 74HC4511 con un display de cátodo común y siete resistencias de 270 Ω. ¿A qué se atan ~LT, ~BI y LE para que funcione? ¿Qué se ve con los códigos 10 a 15?

Ver solución razonada

~LT y ~BI (activas en bajo) a VCC (desactivadas); LE a GND (transparente). Con 0 a 9, el dígito correcto; con 10 a 15, el display apagado (blanking). Si un segmento no enciende nunca, revisar su resistencia, su pin y que el común del display esté a masa.

Ejercicio 4: el límite del CMOS

Un 74HC4511 limita la corriente total de VCC a 50 mA. ¿Cuál es la máxima corriente por segmento para que el dígito 8 sea seguro? ¿Qué resistencia usarías para un LED rojo?

Ver solución razonada

50 mA / 7 segmentos ≈ 7,1 mA por segmento como máximo. Con una caída del driver de 0,5 V y un LED rojo: R = (5 − 1,8 − 0,5) / 0,007 ≈ 386 Ω → 390 Ω (E12), que da unos 6,9 mA y 48 mA con el 8. Bajo, pero con LED modernos se ve bien.

Ejercicio 5: multiplexar cuatro dígitos

Querés 5 mA promedio por segmento con 4 dígitos y 100 Hz de refresco por dígito. ¿Qué frecuencia de barrido, qué ciclo de trabajo y qué corriente pico necesita el driver?

Ver solución razonada

Ciclo de trabajo 25 %, barrido de 4 × 100 = 400 Hz (cada dígito está encendido 2,5 ms cada 10 ms) y corriente pico de 5 × 4 = 20 mA. Dentro de lo que soporta un driver CMOS por salida, pero hay que tener en cuenta el total de los siete segmentos encendidos de un mismo dígito: 140 mA en el común (hace falta un transistor).

Ejercicio 6: binario a BCD

El número binario 101010 (42) debe mostrarse en dos displays. ¿Qué recibiría el decodificador de las unidades si se le conectara directamente el nibble bajo? ¿Qué debería recibir? ¿Cómo lo resuelve el doble dabble?

Ver solución razonada

El nibble bajo de 101010 es 1010 = 0xA: un código inválido (en el 4511 apagaría el display). Debería recibir 0010 (unidades) y 0100 (decenas), es decir, BCD 0100 0010 = 0x42. El doble dabble lo hace en 6 pasos sumando 3 a los nibbles que valgan 5 o más y desplazando un bit por vez. Verificalo con el Paso 6.

12 · Síntesis

Ideas para recordar

  • Un dígito son 7 segmentos (a a g) y un punto; cada símbolo es un byte (0x3F para el 0, 0x7F para el 8). El de ánodo común es el complemento del de cátodo común.
  • 74LS47: ánodo común (salidas activas en bajo, colector abierto). 74LS48 y 74HC4511: cátodo común (activas en alto). El 4511 tiene latch y apaga los códigos 10 a 15.
  • Cada segmento es una función de 4 variables con 6 X: a = A + C + B·D + ~B·~D.
  • Una resistencia por segmento: R = (VCC − Vf − Vdriver) / I. 270 Ω para un LED rojo a 10 mA y 5 V.
  • La corriente depende del dígito: el 8 enciende siete segmentos, el 1 solo dos. Los CMOS tienen un límite por salida y otro total (unos 50 mA).
  • Multiplexado: un dígito a la vez, ciclo de trabajo 1/N, barrido de N × 100 Hz, corriente pico N veces mayor. Apagar, cambiar y encender para evitar fantasmas.
  • Ceros a la izquierda: ~RBI/~RBO apagan los ceros del principio. Un contador binario necesita conversión a BCD (doble dabble) antes del decodificador.
  • Para varios dígitos, un MAX7219 o un TM1637 encapsula todo esto en un chip.

¿Listo para el Tema 22?

Podés avanzar si sos capaz de responder esto sin mirar:

  • Decir qué segmentos enciende el 5 y qué byte le corresponde en cátodo común.
  • Elegir el decodificador para un display de ánodo común y para uno de cátodo común.
  • Calcular la resistencia para un LED verde a 8 mA con un driver que cae 0,5 V.
  • Explicar por qué la resistencia va en cada segmento y no en el común.
  • Describir qué hace el multiplexado con la corriente y la frecuencia.
  • Convertir 42 a BCD y explicar por qué no se pasa directamente a un 4511.

Ya mostrás números a una persona. Falta el camino de entrada: convertir lo que hace una persona (pulsar una tecla entre muchas) en un número binario. En el próximo tema, codificadores.