Fundamentos · 20 min de lectura

Puertas lógicas: AND, OR, NOT, XOR, tablas de verdad y Arduino

¿Qué son las puertas lógicas? AND, OR, NOT, NAND, NOR y XOR: símbolos, tablas de verdad, chips 74HC08 y 74HC00, semisumador y código para Arduino y ESP32.

Las puertas lógicas (también llamadas compuertas lógicas) son los bloques básicos de los circuitos digitales: cada una observa una o más entradas digitales y produce una única salida digital según una regla fija. Las entradas solo pueden valer 0 (LOW) o 1 (HIGH), y la salida también. Hay siete puertas básicas: AND (Y), OR (O), NOT (NO), NAND, NOR, XOR y XNOR. Desde el procesador de tu móvil hasta la placa de una lavadora, desde el ATmega328P de un Arduino hasta una calculadora de bolsillo, todos los dispositivos digitales funcionan combinando millones de diminutas puertas lógicas.

En esta guía aprenderás el símbolo y la tabla de verdad de cada puerta, chips reales como el 74HC08, el 74HC32 y el 74HC00, un experimento con dos pulsadores en la protoboard, cómo construir todas las demás puertas solo con NAND y el circuito semisumador que suma dos bits. En las últimas secciones llevaremos la misma lógica al código del Arduino con los operadores &&, || y ! y con operaciones a nivel de bits, y seguiremos con ejemplos para ESP32 y Raspberry Pi Pico (MicroPython).

Protoboard para experimentos con puertas lógicas
Puedes probar los chips de puertas lógicas sin soldar, colocándolos sobre el canal central de la protoboard.

¿Qué es una puerta lógica y cómo funciona?

En electrónica digital cada señal está en uno de dos estados: 1 (HIGH, verdadero) o 0 (LOW, falso). Las matemáticas que trabajan con estos dos valores se llaman álgebra de Boole; George Boole expresó así el razonamiento lógico como álgebra en un libro publicado en 1854. En 1937 Claude Shannon demostró que esta álgebra encaja exactamente con los circuitos de conmutación hechos con relés, y así nació el diseño de circuitos digitales. Hoy una puerta lógica contiene solo unos pocos transistores: en tecnología CMOS una puerta NOT tiene 2 MOSFET y una NAND, 4. Explicamos cómo funciona un transistor como interruptor en ¿Qué es un transistor?.

¿Qué tensión considera el circuito un 1 y cuál un 0? Depende de la tensión de alimentación de la placa y de la familia del chip. La tabla siguiente muestra los límites a partir de los cuales una entrada cuenta con seguridad como 1 o como 0. La zona entre ambos límites es la zona indefinida; si una entrada se queda ahí, la salida puede comportarse al azar. Una entrada que no está conectada a nada, una entrada flotante, vaga justo por esa zona. Por eso cada entrada debe ir a una señal, o a GND o VCC a través de una resistencia.

Placa / familiaAlimentaciónEntrada segura como 1Entrada segura como 0
Arduino Uno (ATmega328P)5 V≥ 3,0 V≤ 1,5 V
ESP323,3 V≥ 2,5 V≤ 0,8 V
Raspberry Pi Pico (RP2040)3,3 V≥ 2,0 V≤ 0,8 V
Chip 74HC5 V≥ 3,5 V≤ 1,5 V
Chip 74HCT5 V≥ 2,0 V≤ 0,8 V
Chip CD40005 V≥ 3,5 V≤ 1,5 V

Las 7 puertas lógicas básicas y sus símbolos

En los esquemas las puertas se dibujan con dos normas distintas. En la norma estadounidense (ANSI/IEEE) cada puerta tiene su propia forma: AND parece una letra D, OR un escudo terminado en punta y NOT un triángulo. El pequeño círculo de la salida significa "invertir"; una NAND es en realidad una AND con un círculo en la punta. Lo que distingue a XOR de OR es la segunda línea curva del lado de las entradas. En la norma europea (IEC) todas las puertas son rectángulos y se distinguen por el signo de su interior: & para AND, ≥1 para OR, =1 para XOR y 1 para NOT. En los libros de texto verás también Y, O, NO, NO-Y, NO-O, O exclusiva y NO-O exclusiva.

PuertaNombre en españolSímbolo ANSISigno IECExpresión booleana¿Cuándo vale 1 la salida?
ANDYForma de D&Y = A · BLas dos entradas valen 1
OROEscudo en punta≥1Y = A + BAl menos una entrada vale 1
NOTNO (inversor)Triángulo + círculo1 (círculo en la salida)Y = A'La entrada vale 0
NANDNO-YForma de D + círculo& (círculo en la salida)Y = (A · B)'Al menos una entrada vale 0
NORNO-OEscudo + círculo≥1 (círculo en la salida)Y = (A + B)'Las dos entradas valen 0
XORO exclusivaEscudo con doble curva=1Y = A ⊕ BLas entradas son distintas
XNORNO-O exclusivaDoble curva + círculo=1 (círculo en la salida)Y = (A ⊕ B)'Las entradas son iguales

Tablas de verdad de las puertas lógicas

Una tabla de verdad indica qué salida da una puerta para cada combinación de sus entradas. Una puerta con n entradas tiene 2ⁿ filas: 4 filas con dos entradas, 8 con tres y 16 con cuatro. Si escribes las filas en orden de conteo binario (00, 01, 10, 11), nunca te saltarás una combinación. Aquí tienes las seis puertas de dos entradas en una sola tabla:

ABANDORNANDNORXORXNOR
00001101
01011010
10011010
11110001

Como la puerta NOT tiene una sola entrada, su tabla tiene dos filas: con A = 0 la salida es 1 y con A = 1 la salida es 0. Si miras la tabla con atención verás un patrón: la columna NAND es exactamente la contraria de AND, NOR la contraria de OR y XNOR la contraria de XOR. Para memorizarlas usa estas reglas cortas: AND pregunta "¿son todas 1?", OR "¿hay al menos un 1?" y XOR "¿son distintas las entradas?"; la puerta cuyo nombre empieza por N da la respuesta contraria a la misma pregunta. Para probar las puertas tú mismo y ver los símbolos en vivo, basta con tocar las entradas A y B en la herramienta Puertas lógicas.

  • AND (Y): Dos interruptores en serie. La lámpara solo se enciende cuando los dos están cerrados; una caja fuerte que se abre con dos llaves distintas también sigue la regla AND.
  • OR (O): Dos pulsadores en paralelo. Suena el mismo timbre tanto si llaman a la puerta principal como a la trasera.
  • NOT (NO): La luz de la nevera. Con la puerta cerrada el interruptor está pulsado y la luz apagada; al abrir la puerta el interruptor se suelta y la luz se enciende.
  • NAND: La regla "avisa si no está todo bien". Si aunque sea una de las dos protecciones de una máquina está abierta, se enciende la luz de aviso.
  • NOR: La regla "no ha pasado nada". Un piloto verde de "todo en orden" que solo se enciende si no se detecta ni humo ni gas.
  • XOR: Los interruptores conmutados de una escalera. Accionar el de abajo o el de arriba cambia el estado de la lámpara; la lámpara se enciende cuando los dos están en posiciones distintas y se apaga cuando coinciden.
  • XNOR: Una comprobación de igualdad. Da 1 cuando dos bits son iguales; se usa en comparadores digitales y en circuitos de detección de errores.

Circuitos integrados de puertas lógicas: 74HC08, 74HC32, 74HC00

En lugar de construir las puertas lógicas transistor a transistor, se usan chips ya hechos. La familia más común en electrónica de aficionado es la serie 74HC: un encapsulado DIP de 14 patillas contiene cuatro puertas de dos entradas, la alimentación va siempre a la patilla 14 (VCC) y la masa a la patilla 7 (GND). Los 74HC funcionan de 2 a 6 V, sus entradas casi no consumen corriente y a 5 V una puerta tiene un retardo de unos 10 nanosegundos, cientos de veces más rápida que una sola llamada a digitalWrite en el Arduino. Cada salida mantiene sus niveles garantizados con una carga de 4 mA; el límite absoluto es de 25 mA por salida y 50 mA para todo el chip.

ChipPuertaContienePatillajeEquivalente CMOS 4000
74HC08AND4 × 2 entradasEstándar (tabla de abajo)CD4081
74HC32OR4 × 2 entradasEstándarCD4071
74HC00NAND4 × 2 entradasEstándarCD4011
74HC86XOR4 × 2 entradasEstándarCD4070
74HC02NOR4 × 2 entradasDistinto: salidas en 1, 4, 10, 13CD4001
74HC04NOT6 × 1 entradaEntradas en 1, 3, 5, 9, 11, 13CD4069
74HC14NOT (Schmitt trigger)6 × 1 entradaIgual que el 74HC04CD40106
CD4077 / 74HCS7266XNOR4 × 2 entradasDifícil de encontrar; normalmente 74HC86 + 74HC04CD4077

El 74HC08, el 74HC32, el 74HC00 y el 74HC86 tienen exactamente el mismo patillaje; solo cambia el tipo de puerta del interior. La muesca o el punto de la parte superior marca la patilla 1. Si miras el chip desde arriba con la muesca a la izquierda, las patillas se numeran en sentido antihorario: la fila inferior de izquierda a derecha del 1 al 7 y la superior de derecha a izquierda del 8 al 14. A y B son entradas, Y es la salida y el número delante indica la puerta.

PatillaFunciónPatillaFunción
11A (entrada puerta 1)14VCC (+2…6 V)
21B (entrada puerta 1)134B (entrada puerta 4)
31Y (salida puerta 1)124A (entrada puerta 4)
42A (entrada puerta 2)114Y (salida puerta 4)
52B (entrada puerta 2)103B (entrada puerta 3)
62Y (salida puerta 2)93A (entrada puerta 3)
7GND83Y (salida puerta 3)
Nunca dejes al aire las entradas CMOS. Conecta las entradas de las puertas que no uses a GND (o a VCC); una entrada flotante cambia de estado con el ruido, aumenta el consumo del chip y puede incluso afectar a las puertas vecinas. Las salidas sin usar, en cambio, pueden quedar libres. No olvides un condensador cerámico de desacoplo de 100 nF entre VCC y GND, lo más cerca posible del chip.

Los chips que hacen la misma función vienen en distintas familias. La serie 74LS es la antigua tecnología TTL: solo funciona entre 4,75 y 5,25 V, consume más corriente y normalmente lee como 1 una entrada al aire. La serie 74HCT es un 74HC con entradas compatibles TTL; se alimenta a 5 V, pero acepta como 1 seguro cualquier tensión desde 2 V, así que lee sin problemas las señales de 3,3 V de un ESP32 o una Pico. La serie CD4000 (CD4081, CD4011, etc.) trabaja en un rango amplio de 3–18 V, pero es más lenta y su patillaje es distinto del de los 74HC: un CD4011 no puede sustituir directamente a un 74HC00.

Experimento con pulsadores en la protoboard: puerta AND con el 74HC08

La mejor forma de entender una puerta lógica es probarla tú mismo con dos pulsadores. En este experimento no hay microcontrolador; solo necesitas un 74HC08, dos pulsadores, dos resistencias de 10 kΩ, una de 1 kΩ, un LED y un condensador de 100 nF. Para alimentarlo valen los pines 5V y GND de un Arduino, un módulo de alimentación para protoboard o tres pilas AA (4,5 V). Si no tienes claras las conexiones internas de la protoboard, lee primero ¿Qué es una protoboard?.

Pulsador para el experimento en la protoboard
Un pulsador une sus dos lados mientras está pulsado. En los modelos de cuatro patas, las patas están unidas por dentro de dos en dos, así que lo más seguro es colocarlo sobre el canal central.
  1. Coloca el 74HC08 sobre el canal central de la protoboard, con las patillas a ambos lados y la muesca mirando a la izquierda.
  2. Conecta la patilla 14 a la línea + (5 V) y la patilla 7 a la línea − (GND), y pon el condensador de 100 nF entre esas dos patillas.
  3. Conecta un lado del pulsador A a la línea + y el otro a la patilla 1. Añade una resistencia de 10 kΩ desde esa misma patilla a GND: esta resistencia pull-down mantiene la entrada firmemente en 0 mientras el pulsador no está pulsado.
  4. Conecta el pulsador B a la patilla 2 del mismo modo y ponle también su propia resistencia pull-down de 10 kΩ.
  5. Desde la patilla 3, la salida, pasa por una resistencia de 1 kΩ hasta la pata larga del LED (ánodo); conecta la pata corta (cátodo) a GND.
  6. Conecta a GND las entradas que no usas, las patillas 4, 5, 9, 10, 12 y 13; deja libres las salidas 6, 8 y 11.
  7. Da alimentación y prueba las cuatro combinaciones una tras otra: el LED solo debe encenderse cuando pulses los dos pulsadores a la vez. Compara los resultados con la tabla de verdad.
ConexiónPatilla del 74HC08Se conecta a
Alimentación14 (VCC)Línea +, 5 V
Masa7 (GND)Línea −
Condensador de desacoploEntre 14 y 7100 nF cerámico, cerca del chip
Entrada A1Pulsador A → 5 V, 10 kΩ → GND
Entrada B2Pulsador B → 5 V, 10 kΩ → GND
Salida31 kΩ → ánodo del LED, cátodo → GND
Entradas sin usar4, 5, 9, 10, 12, 13GND
Salidas sin usar6, 8, 11Libres
Cuando el circuito funciona empieza lo divertido: si sacas el 74HC08 y pones un 74HC32 con el mismo patillaje, el LED se enciende al pulsar cualquiera de los dos pulsadores (OR). Con un 74HC00 se queda encendido hasta que pulsas los dos a la vez (NAND), y con un 74HC86 solo se enciende al pulsar uno solo (XOR). Con 1 kΩ, un LED rojo consume unos 3 mA, un valor seguro para una salida 74HC. Para un LED de otro color puedes calcular la resistencia con la herramienta Resistencia para LED.

Construir cualquier puerta con NAND: la puerta universal

La NAND se llama puerta universal porque puedes construir cualquier otra puerta usando solo puertas NAND. Esto tiene también un lado práctico: en tecnología CMOS la NAND es una de las puertas más sencillas, con solo 4 transistores, mientras que una AND es en realidad una NAND seguida de una NOT y necesita 6. Por eso a los diseñadores de chips les encanta la NAND. La memoria NAND flash de los pendrives también debe su nombre a que sus celdas se conectan en serie, como los transistores de una puerta NAND. La NOR también es universal: el ordenador de guiado del Apolo que viajó a la Luna se construyó con unos 2.800 chips, cada uno con dos puertas NOR de tres entradas.

Puerta que quieres¿Cómo con NAND?NAND necesarias
NOTA NAND A (une las dos entradas)1
ANDPasa la salida de (A NAND B) por una NOT2
OR(A NAND A) NAND (B NAND B)3
NOROR + NOT4
XORN1 = A NAND B; (A NAND N1) NAND (B NAND N1)4
XNORXOR + NOT5

La fila OR de la tabla se basa en la ley de De Morgan: (A' · B')' = A + B. Es decir, si primero inviertes cada entrada y luego las metes en una NAND, obtienes una OR. La segunda ley de De Morgan es (A + B)' = A' · B'. Ambas leyes también te ayudan a simplificar condiciones en el código: en Arduino, !(a && b) da siempre el mismo resultado que (!a || !b), y !(a || b) el mismo que (!a && !b).

Construir una XOR con cuatro puertas NAND es un ejercicio clásico de examen y de laboratorio, y las cuatro puertas de un solo 74HC00 bastan justo para ello. Primero se calcula N1 = A NAND B. Después se obtienen N2 = A NAND N1 y N3 = B NAND N1, y la salida de la última puerta, Y = N2 NAND N3, da la XOR. Con este cableado puedes convertir tu experimento de la protoboard en una XOR de cuatro NAND:

Patilla del 74HC00ConexiónFunción
1 y 4Pulsador AEntrada A (puertas 1 y 2)
2 y 10Pulsador BEntrada B (puertas 1 y 3)
3 → 5 y 9CableN1 = A NAND B
6 → 12CableN2 = A NAND N1
8 → 13CableN3 = B NAND N1
111 kΩ + LEDY = A XOR B
14 / 75 V / GNDAlimentación

Vamos un paso más allá: si conectas en cruz las salidas de dos puertas NAND a la entrada de la otra, obtienes una memoria de 1 bit llamada biestable SR (latch SR). Este circuito recuerda su último estado aunque sueltes el pulsador. Los registros de los procesadores, los contadores y chips como el registro de desplazamiento 74HC595 se forman encadenando celdas de memoria como esta, hechas con puertas.

El semisumador (half adder): sumar dos bits con puertas

Lo más impresionante que pueden hacer las puertas lógicas es sumar. En binario, 0 + 0 = 0, 0 + 1 = 1, 1 + 0 = 1 y 1 + 1 = 10 (2 en decimal). La cifra de la derecha del resultado se llama suma y la que se desborda hacia la izquierda, acarreo (carry). Mirando la tabla de abajo verás que la suma es exactamente XOR y el acarreo exactamente AND. Así que una puerta XOR y una AND juntas forman un semisumador que suma dos números de un bit.

ABAcarreo (C = A AND B)Suma (S = A XOR B)Resultado decimal
00000
01011
10011
11102 (binario 10)

Para montarlo en la protoboard, conecta los pulsadores A y B a las patillas 1 y 2 tanto de un 74HC86 como de un 74HC08. La patilla 3 del 74HC86 controla el LED de suma y la patilla 3 del 74HC08 el LED de acarreo. Al pulsar los dos a la vez, el LED de suma se apaga y el de acarreo se enciende: los LED muestran el binario 10, es decir, 2. Si solo quieres usar un 74HC00, necesitas cuatro NAND para la XOR y una quinta NAND que invierta N1 para obtener el acarreo; o sea, un semisumador se construye con 5 puertas NAND.

Un semisumador no puede tener en cuenta el acarreo que viene de la cifra anterior; para eso necesitas un sumador completo (full adder). Sus fórmulas son S = A ⊕ B ⊕ Cin y Cout = (A · B) + (Cin · (A ⊕ B)), lo que equivale a dos semisumadores y una puerta OR. Si encadenas cuatro sumadores completos de modo que cada uno pase su acarreo al siguiente, tienes un sumador de 4 bits; el chip 74HC283 hace la misma suma de 4 bits, pero calcula los acarreos con un circuito interno rápido (acarreo anticipado, carry look-ahead) en lugar de esperar a que recorran la cadena. La unidad aritmética del procesador de tu ordenador es una versión de 64 bits, y muchísimo más rápida, de la misma idea.

Puertas lógicas en Arduino: &&, ||, ! y operaciones a nivel de bits

En el código de Arduino cada puerta lógica tiene dos equivalentes. Los operadores lógicos (&&, ||, !) combinan condiciones y dan como resultado true o false; los usas en las sentencias if y while. Los operadores a nivel de bits (&, |, ^, ~), en cambio, se aplican a todos los bits de un número a la vez, columna por columna; trabajar con un byte es como hacer funcionar ocho puertas al mismo tiempo. Los ejemplos de la tabla usan los números 0b1100 y 0b1010:

PuertaLógico (bool)A nivel de bitsEjemploResultado
ANDa && bx & y0b1100 & 0b10100b1000
ORa || bx | y0b1100 | 0b10100b1110
NOT!a~x~0b00001100 (byte)0b11110011
NAND!(a && b)~(x & y)~(0b1100 & 0b1010) & 0x0F0b0111
NOR!(a || b)~(x | y)~(0b1100 | 0b1010) & 0x0F0b0001
XORa != bx ^ y0b1100 ^ 0b10100b0110
XNORa == b~(x ^ y)~(0b1100 ^ 0b1010) & 0x0F0b1001

La diferencia entre ambos tipos parece pequeña, pero provoca errores difíciles de ver. && y || usan evaluación en cortocircuito: en a && b, si a es falso, b ni siquiera se evalúa. & evalúa siempre los dos lados y mira los bits de los números: 2 && 1 es true, pero 2 & 1 es 0, porque 0b10 y 0b01 no tienen ningún bit en común. C++ no tiene un operador XOR lógico propio; para dos bool, escribir a != b es la forma más legible. Para saber más sobre operaciones de bits, los desplazamientos << y >> y el sistema binario, consulta Sistemas de numeración y operaciones de bits.

Ahora pasemos el experimento de la protoboard a un Arduino Uno. Dos pulsadores van a los pines 2 y 3, y siete LED (cada uno con una resistencia de 330 Ω) a los pines 4–10. Cada pulsador tiene un lado en el pin y el otro en GND; como se activa la resistencia pull-up interna, no hace falta ninguna resistencia extra. Un solo sketch da vida a las siete puertas a la vez:

Arduino (C++)
1// Mantık kapısı simülatörü: 2 buton, 7 LED / Logic gate simulator: 2 buttons, 7 LEDs
2const byte PIN_A = 2;   // A butonu, diğer ucu GND / button A, other leg to GND
3const byte PIN_B = 3;   // B butonu, diğer ucu GND / button B, other leg to GND
4
5// Sıra: AND, OR, NOT A, NAND, NOR, XOR, XNOR / Order: AND, OR, NOT A, NAND, NOR, XOR, XNOR
6const byte LED_PINS[7] = {4, 5, 6, 7, 8, 9, 10};
7const char* const GATE_NAMES[7] = {"AND", "OR", "NOT A", "NAND", "NOR", "XOR", "XNOR"};
8
9byte lastInputs = 0xFF;   // ilk turda yazdırmayı zorlar / forces a print on the first pass
10
11void setup() {
12  pinMode(PIN_A, INPUT_PULLUP);
13  pinMode(PIN_B, INPUT_PULLUP);
14  for (byte i = 0; i < 7; i++) {
15    pinMode(LED_PINS[i], OUTPUT);
16  }
17  Serial.begin(9600);
18}
19
20void loop() {
21  // Basılı buton LOW okunur, ! ile 1 yapılır / A pressed button reads LOW, ! turns it into 1
22  bool a = !digitalRead(PIN_A);
23  bool b = !digitalRead(PIN_B);
24
25  bool out[7];
26  out[0] = a && b;      // AND
27  out[1] = a || b;      // OR
28  out[2] = !a;          // NOT A
29  out[3] = !(a && b);   // NAND
30  out[4] = !(a || b);   // NOR
31  out[5] = a != b;      // XOR: girişler farklı mı? / are the inputs different?
32  out[6] = a == b;      // XNOR: girişler aynı mı? / are the inputs equal?
33
34  for (byte i = 0; i < 7; i++) {
35    digitalWrite(LED_PINS[i], out[i] ? HIGH : LOW);
36  }
37
38  // Yalnız girişler değişince yaz / Print only when the inputs change
39  byte inputs = (a << 1) | b;
40  if (inputs != lastInputs) {
41    Serial.print("A=");
42    Serial.print(a);
43    Serial.print(" B=");
44    Serial.print(b);
45    for (byte i = 0; i < 7; i++) {
46      Serial.print("  ");
47      Serial.print(GATE_NAMES[i]);
48      Serial.print('=');
49      Serial.print(out[i]);
50    }
51    Serial.println();
52    lastInputs = inputs;
53  }
54  delay(20);   // basit sıçrama önleme / simple debounce
55}

Con INPUT_PULLUP, un pulsador pulsado se lee como LOW, así que el código invierte la lectura con ! y el pulsador pulsado pasa a ser 1. Después, cada LED muestra el resultado de su puerta: 4 AND, 5 OR, 6 NOT A, 7 NAND, 8 NOR, 9 XOR y 10 XNOR. Si abres el Monitor Serie a 9600 baudios, cada vez que cambia un pulsador se imprime la línea completa; cuando hayas probado las cuatro combinaciones, habrás obtenido la tabla de verdad con tus propias manos. Los detalles de la lógica pull-up están en Cómo conectar un pulsador a Arduino.

Para ver la potencia de las operaciones de bits, el segundo ejemplo calcula toda la tabla de verdad en unas pocas líneas. El truco: si escribes la columna A como el número 0b1100 y la columna B como 0b1010, cada bit corresponde a una fila de la tabla, y un solo & te da las cuatro filas de la columna AND de una vez. La segunda mitad del sketch suma bit a bit dos números de 4 bits con las fórmulas del sumador completo, imitando por software el circuito sumador de un procesador. Este sketch no necesita hardware; solo abre el Monitor Serie.

Arduino (C++)
1// Bit işlemleriyle doğruluk tablosu ve 4 bitlik toplayıcı / Truth tables with bitwise ops and a 4-bit adder
2// Her bit bir satırdır: bit 0 = (A=0, B=0) ... bit 3 = (A=1, B=1) / Each bit is one row: bit 0 = (A=0, B=0) ... bit 3 = (A=1, B=1)
3const byte COL_A = 0b1100;
4const byte COL_B = 0b1010;
5const byte MASK  = 0b1111;   // yalnız 4 satır / only 4 rows
6
7void printRow(const char* name, byte column) {
8  Serial.print(name);
9  Serial.print('\t');
10  for (byte row = 0; row < 4; row++) {
11    Serial.print(bitRead(column, row));   // satır satır yaz / print row by row
12    Serial.print("  ");
13  }
14  Serial.println();
15}
16
17// Tam toplayıcı: iki bit + gelen elde / Full adder: two bits + carry in
18void fullAdder(byte a, byte b, byte carryIn, byte &sum, byte &carryOut) {
19  sum = a ^ b ^ carryIn;                         // XOR'lar toplamı verir / XORs give the sum
20  carryOut = (a & b) | (carryIn & (a ^ b));      // AND + OR eldeyi verir / AND + OR give the carry
21}
22
23// 4 tam toplayıcı zincirlenir (ripple carry) / 4 full adders chained (ripple carry)
24byte add4(byte x, byte y, byte &carryOut) {
25  byte result = 0;
26  byte carry = 0;
27  for (byte i = 0; i < 4; i++) {
28    byte s, c;
29    fullAdder(bitRead(x, i), bitRead(y, i), carry, s, c);
30    bitWrite(result, i, s);
31    carry = c;
32  }
33  carryOut = carry;
34  return result;
35}
36
37void setup() {
38  Serial.begin(9600);
39  Serial.println(F("AB:\t00 01 10 11"));
40  printRow("AND",  COL_A & COL_B);
41  printRow("OR",   COL_A | COL_B);
42  printRow("NAND", ~(COL_A & COL_B) & MASK);   // ~ sonrası maske şart / mask is required after ~
43  printRow("NOR",  ~(COL_A | COL_B) & MASK);
44  printRow("XOR",  COL_A ^ COL_B);
45  printRow("XNOR", ~(COL_A ^ COL_B) & MASK);
46
47  byte carry;
48  byte s = add4(9, 12, carry);   // 1001 + 1100
49  Serial.print(F("9 + 12 = "));
50  Serial.print(s + carry * 16);  // elde 16'lar basamağıdır / the carry is the 16s place
51  Serial.print(F("  (toplam / sum = "));
52  Serial.print(s, BIN);
53  Serial.print(F(", elde / carry = "));
54  Serial.print(carry);
55  Serial.println(')');
56}
57
58void loop() {
59}
No uses ~ con valores bool: ~ invierte todos los bits y convierte true (1) en -2, y como -2 no es cero sigue contando como true. Para un NO lógico usa siempre !. Otra trampa es la precedencia de operadores: en if (x & 1 == 0) se evalúa primero 1 == 0, así que lo correcto es if ((x & 1) == 0). Además, aplicar ~ a una variable byte convierte el resultado en int; recórtalo con una máscara como & 0x0F o & 0xFF, como hace el código.

Un comprobador de chips 74HC con Arduino

Si las letras de un chip se han borrado o quieres saber si todavía funciona, puedes convertir el Arduino en un comprobador. Este sketch aplica por turnos las cuatro combinaciones de entrada a las cuatro puertas de un 74HC00, 74HC08, 74HC32 o 74HC86 (los chips con patillaje estándar), lee las salidas y compara el resultado con patrones conocidos. Conecta la patilla 14 del chip a 5V, la patilla 7 a GND y el resto a los pines del Arduino según la tabla del código.

Arduino (C++)
1// 74HC00 / 08 / 32 / 86 tanıyıcı ve test cihazı / 74HC00 / 08 / 32 / 86 identifier and tester
2// Entegre: bacak 14 -> 5V, bacak 7 -> GND / Chip: pin 14 -> 5V, pin 7 -> GND
3// Her kapı: {A, B, Y} Arduino pinleri / Each gate: {A, B, Y} Arduino pins
4const byte GATES[4][3] = {
5  {2, 3, 4},      // kapı 1: entegre 1, 2 -> 3 / gate 1: chip 1, 2 -> 3
6  {5, 6, 7},      // kapı 2: entegre 4, 5 -> 6 / gate 2: chip 4, 5 -> 6
7  {8, 9, 10},     // kapı 3: entegre 9, 10 -> 8 / gate 3: chip 9, 10 -> 8
8  {11, 12, A0}    // kapı 4: entegre 12, 13 -> 11 / gate 4: chip 12, 13 -> 11
9};
10
11// Desenin bit sırası: bit 0 = (0,0), bit 3 = (1,1) / Pattern bit order: bit 0 = (0,0), bit 3 = (1,1)
12const char* nameOf(byte pattern) {
13  switch (pattern) {
14    case 0b1000: return "AND (74HC08)";
15    case 0b1110: return "OR (74HC32)";
16    case 0b0111: return "NAND (74HC00)";
17    case 0b0110: return "XOR (74HC86)";
18    default:     return "?";
19  }
20}
21
22byte testGate(byte g) {
23  byte pattern = 0;
24  for (byte row = 0; row < 4; row++) {
25    digitalWrite(GATES[g][0], bitRead(row, 1));   // A = satırın üst biti / A = high bit of the row
26    digitalWrite(GATES[g][1], bitRead(row, 0));   // B = satırın alt biti / B = low bit of the row
27    delayMicroseconds(10);                        // kapı ~10 ns gecikir, bol pay / the gate needs ~10 ns, plenty of margin
28    bitWrite(pattern, row, digitalRead(GATES[g][2]));
29  }
30  return pattern;
31}
32
33void setup() {
34  Serial.begin(9600);
35  for (byte g = 0; g < 4; g++) {
36    pinMode(GATES[g][0], OUTPUT);
37    pinMode(GATES[g][1], OUTPUT);
38    pinMode(GATES[g][2], INPUT);
39  }
40
41  byte first = testGate(0);
42  bool allSame = true;
43  for (byte g = 0; g < 4; g++) {
44    byte p = testGate(g);
45    Serial.print(F("Kapi / Gate "));
46    Serial.print(g + 1);
47    Serial.print(F(": "));
48    Serial.print(nameOf(p));
49    Serial.print(F("  desen / pattern 0b"));
50    Serial.println(p, BIN);
51    if (p != first) allSame = false;
52  }
53
54  if (allSame && nameOf(first)[0] != '?') {
55    Serial.println(F("Sonuc / Result: entegre saglam / chip OK"));
56  } else {
57    Serial.println(F("Sonuc / Result: bozuk kapi ya da baglanti hatasi / faulty gate or wiring error"));
58  }
59}
60
61void loop() {
62}
Si te equivocas al cablear, una salida del Arduino puede acabar enfrentada a una salida del chip. Para evitarlo, puedes poner una resistencia de 1 kΩ entre las salidas del chip (3, 6, 8, 11) y los pines del Arduino; el resultado de la prueba no cambia, pero los dos lados quedan protegidos si algo está mal conectado. El 74HC02 y el 74HC04 tienen otro patillaje, así que este sketch no puede probarlos directamente; tendrías que cambiar la tabla GATES según su hoja de datos.

Una puerta lógica programable con el ESP32

En el ESP32 los mismos operadores funcionan sin cambios. En este ejemplo, un tercer pulsador va cambiando el tipo de puerta y un solo LED muestra la salida de la puerta elegida. Así puedes enseñar seis puertas con un único circuito en clase o en una presentación. Los pulsadores van a GPIO 25, 26 y 27 (su otro lado a GND) y el LED a GPIO 23 con una resistencia de 220 Ω; el nombre de la puerta elegida aparece en el Monitor Serie a 115200 baudios.

Arduino (C++)
1// ESP32 programlanabilir mantık kapısı / ESP32 programmable logic gate
2const int PIN_A = 25;      // A butonu, diğer ucu GND / button A, other leg to GND
3const int PIN_B = 26;      // B butonu / button B
4const int PIN_MODE = 27;   // kapı seçme butonu / gate select button
5const int PIN_LED = 23;    // çıkış LED'i (220 ohm) / output LED (220 ohm)
6
7const char* const NAMES[] = {"AND", "OR", "NAND", "NOR", "XOR", "XNOR"};
8const int GATE_COUNT = 6;
9const unsigned long DEBOUNCE_MS = 30;   // sıçrama süresi / bounce time
10
11int gate = 0;
12int modeStable = HIGH;            // kararlı buton durumu / stable button state
13int modeRaw = HIGH;               // son ham okuma / last raw reading
14unsigned long modeChangedAt = 0;  // ham değerin son değiştiği an / when the raw value last changed
15
16bool evaluate(int g, bool a, bool b) {
17  switch (g) {
18    case 0:  return a && b;
19    case 1:  return a || b;
20    case 2:  return !(a && b);
21    case 3:  return !(a || b);
22    case 4:  return a != b;     // XOR
23    default: return a == b;     // XNOR
24  }
25}
26
27void setup() {
28  Serial.begin(115200);
29  pinMode(PIN_A, INPUT_PULLUP);
30  pinMode(PIN_B, INPUT_PULLUP);
31  pinMode(PIN_MODE, INPUT_PULLUP);
32  pinMode(PIN_LED, OUTPUT);
33  Serial.printf("Kapi / Gate: %s\n", NAMES[gate]);
34}
35
36void loop() {
37  int reading = digitalRead(PIN_MODE);
38  if (reading != modeRaw) {          // ham değer değişti, süreyi yeniden başlat / raw value changed, restart the timer
39    modeRaw = reading;
40    modeChangedAt = millis();
41  }
42  // 30 ms boyunca sabit kaldıysa gerçek değişimdir / steady for 30 ms means a real change
43  if (millis() - modeChangedAt > DEBOUNCE_MS && reading != modeStable) {
44    modeStable = reading;
45    if (modeStable == LOW) {         // yeni basış (bırakma sayılmaz) / new press (release is ignored)
46      gate = (gate + 1) % GATE_COUNT;
47      Serial.printf("Kapi / Gate: %s\n", NAMES[gate]);
48    }
49  }
50
51  bool a = !digitalRead(PIN_A);   // basılı = 1 / pressed = 1
52  bool b = !digitalRead(PIN_B);
53  digitalWrite(PIN_LED, evaluate(gate, a, b) ? HIGH : LOW);
54}
El ESP32 y la Pico funcionan a 3,3 V y sus pines no toleran 5 V. Si usas un chip 74HC con estas placas, aliméntalo también a 3,3 V; un 74HC funciona incluso con 2 V, así que no hay problema. Si el chip se alimenta a 5 V, los 5 V de su salida pueden dañar la entrada de la placa; en sentido contrario, una señal de 3,3 V queda por debajo de 3,5 V, el umbral de 1 seguro de un 74HC a 5 V. Si necesitas comunicarte con un circuito de 5 V, usa un chip 74HCT o un conversor de nivel lógico.

Puertas lógicas con la Raspberry Pi Pico y MicroPython

En MicroPython los operadores lógicos se escriben con palabras en inglés: and, or, not. Los operadores a nivel de bits son los mismos que en C++: &, |, ^ y ~. El código siguiente lee dos pulsadores en GP14 y GP15 y muestra los resultados de AND, OR, NAND, NOR, XOR y XNOR en seis LED conectados a GP16–GP21. El otro lado de cada pulsador va a GND y cada LED se conecta con una resistencia de 220–330 Ω. Si guardas el código en Thonny como main.py, se ejecuta cada vez que se enciende la Pico; si es tu primera vez con la Pico, empieza por ¿Qué es la Raspberry Pi Pico?.

MicroPython
1# Pico ile 6 mantık kapısı / 6 logic gates on the Pico
2from machine import Pin
3import time
4
5btn_a = Pin(14, Pin.IN, Pin.PULL_UP)   # A butonu, diğer ucu GND / button A, other leg to GND
6btn_b = Pin(15, Pin.IN, Pin.PULL_UP)   # B butonu / button B
7
8# GP16..GP21: AND, OR, NAND, NOR, XOR, XNOR
9leds = [Pin(n, Pin.OUT) for n in range(16, 22)]
10gates = [
11    ("AND",  lambda a, b: a and b),
12    ("OR",   lambda a, b: a or b),
13    ("NAND", lambda a, b: not (a and b)),
14    ("NOR",  lambda a, b: not (a or b)),
15    ("XOR",  lambda a, b: a != b),
16    ("XNOR", lambda a, b: a == b),
17]
18
19last = None
20while True:
21    a = int(not btn_a.value())   # basılı = 1 / pressed = 1
22    b = int(not btn_b.value())
23    results = [int(f(a, b)) for _, f in gates]
24    for led, r in zip(leds, results):
25        led.value(r)
26    if (a, b) != last:           # yalnız değişince yaz / print only on change
27        line = " ".join("%s=%d" % (g[0], r) for g, r in zip(gates, results))
28        print("A=%d B=%d  %s" % (a, b, line))
29        last = (a, b)
30    time.sleep_ms(20)

Python tiene una trampa parecida: ~True da -2, porque un bool es en realidad un entero. Para invertir un bit usa not x, 1 - x o x ^ 1. Además, los operadores and y or de Python no siempre devuelven True o False, sino el último valor que evalúan: 0 or 5 da 5. Por eso el código usa conversiones int(), para que los LED reciban siempre solo 0 o 1.

Ideas de proyectos con puertas lógicas

  • Luz nocturna inteligente (AND): Enciende la luz cuando está oscuro Y se detecta movimiento; combina un LDR y un sensor PIR en una sola condición &&.
  • Luz de escalera (XOR): Controla una lámpara con dos pulsadores, abajo y arriba de la escalera; calcula el estado de la lámpara con XOR y conmuta la lámpara de 230 V con un módulo de relé.
  • Alarma para casa (AND + OR): Con el sistema armado, haz sonar la sirena si se abre la puerta O la ventana. Detecta puerta y ventana con un interruptor reed; tienes los detalles en la guía sistema de alarma con Arduino.
  • Caja fuerte de dos llaves (AND): Que la cerradura no se abra a menos que dos personas distintas pulsen su botón a la vez, o hasta que se verifique el código del teclado matricial.
  • Calculadora de 4 bits: Suma dos números introducidos con interruptores usando la lógica del sumador completo y muestra el resultado en un display de 7 segmentos.
  • Pulsador de concurso: Bloquea el LED del primer concursante que pulse e impide que los demás lo hagan; es la versión por software de un biestable hecho con NAND.
  • Control de paridad: Aplica XOR a todos los bits de un byte; si el resultado es 1, el número de unos es impar. El bit de paridad de las comunicaciones serie se calcula exactamente así.

Errores frecuentes y cómo solucionarlos

SíntomaCausa probableSolución
El LED parpadea solo y cambia al acercar la manoEntrada al aire, sin resistencia pull-downPon una resistencia pull-down o pull-up de 10 kΩ en cada entrada
El chip se calientaVCC y GND invertidos o dos salidas unidasLa patilla 14 va a VCC y la 7 a GND; nunca unas salidas
Ninguna puerta respondeSin alimentación o el chip no está sobre el canal centralMide entre las patillas 14 y 7 con el multímetro y coloca el chip sobre el canal
Resultados erróneos con un 74HC02 o un CD4011Su patillaje es distinto del 74HC08Cablea según la tabla de patillas de la hoja de datos
El chip consume más corriente de la cuentaEntradas sin usar al aireConecta a GND todas las entradas libres
Resultados inestables con ESP32 o PicoUna señal de 3,3 V no basta para un 74HC a 5 VAlimenta el 74HC a 3,3 V o usa un 74HCT
if (a & b) da false de forma inesperada& trabaja bit a bit; 2 & 1 = 0Usa && en las condiciones
if (x & 1 == 0) nunca se cumple== se evalúa antes que &Usa paréntesis: (x & 1) == 0
Una pulsación cambia la puerta varias vecesRebote del pulsadorEspera 20–50 ms por software o usa un filtro RC + 74HC14
Antes de montar un circuito, escribe su tabla de verdad en un papel y prueba cada fila una por una. La fila en la que el LED no coincide con lo esperado te indica que el problema está en la puerta que usa esa fila o en su cableado. Ten abierta la herramienta Puertas lógicas para comprobar la tabla rápidamente, y antes de montarlo también puedes probar el circuito de forma virtual en Tinkercad.

Las puertas lógicas son el alfabeto de todo el mundo digital, desde encender un LED hasta que un procesador sume. Cuando entiendes AND, OR y NOT, leer una condición if, una regla de alarma o un registro de desplazamiento resulta mucho más fácil. En la app BlueGrays encontrarás proyectos para encender un LED con un pulsador, proyectos con pulsadores para ESP32 y Raspberry Pi Pico, una iluminación inteligente de escalera y una iluminación inteligente que combina PIR y LDR, todos con esquemas y código paso a paso, para que pongas en práctica la lógica de puertas de este artículo en proyectos reales.

Preguntas frecuentes

¿Cuáles son las puertas lógicas y para qué sirven?

Hay siete puertas lógicas básicas: AND, OR, NOT, NAND, NOR, XOR y XNOR. Cada una observa entradas que valen 0 o 1 y produce una única salida según su propia regla. Todos los circuitos digitales, como procesadores, memorias, contadores y calculadoras, se forman combinando estas puertas.

¿Cómo se hace una tabla de verdad?

Primero calcula el número de filas a partir del número de entradas: n entradas necesitan 2ⁿ filas. Escribe las entradas en orden de conteo binario (00, 01, 10, 11) y aplica la regla de la puerta a cada fila para rellenar la columna de salida. En circuitos con varias puertas, añadir una columna para cada salida intermedia facilita el cálculo.

¿Por qué la puerta NAND es universal?

Porque solo con puertas NAND puedes construir NOT, AND, OR, NOR, XOR y XNOR. Por ejemplo, unir las dos entradas de una NAND da una NOT, dos NAND seguidas dan una AND y cuatro NAND dan una XOR. La puerta NOR tiene la misma propiedad, así que también se considera universal.

¿Qué diferencia hay entre XOR y XNOR?

XOR da 1 cuando las entradas son distintas, mientras que XNOR da 1 cuando son iguales. XNOR es la inversa de XOR y sirve para comprobar si dos bits son iguales. XOR se usa en circuitos sumadores, en el control de paridad y para invertir un bit.

¿Qué diferencia hay entre el 74HC08 y el 74LS08?

Los dos contienen cuatro puertas AND de dos entradas y tienen el mismo patillaje. El 74HC08 es de tecnología CMOS, funciona entre 2 y 6 V y consume muy poca corriente; el 74LS08 es TTL, solo funciona en torno a 5 V y consume más. Para proyectos nuevos elige el 74HC, y el 74HCT cuando conectes señales de 3,3 V a un circuito de 5 V.

¿Qué diferencia hay entre && y & en Arduino?

&& es el operador AND lógico: comprueba si las dos condiciones son verdaderas y devuelve true o false. & es el AND a nivel de bits y compara cada bit de dos números por separado. Por eso 2 && 1 es true, pero 2 & 1 es 0; en las condiciones if debes usar &&.

Ver todos los proyectos
Encender un LED con pulsador (Push)
#9Principiante

Encender un LED con pulsador (Push)

Como un timbre: la luz se enciende mientras pulsas y se apaga cuando sueltas. El Arduino escucha el botón todo el rato; mientras está pulsado enciende el LED, y en cuanto levantas el dedo lo apaga. Co

4.9(112)
197
Encender y apagar un LED con un botón
#10Principiante

Encender y apagar un LED con un botón

Pulsas el botón una vez y la luz se enciende, lo pulsas otra vez y se apaga, igual que el interruptor de tu habitación. El Arduino nota cada pulsación y cambia el LED al estado contrario, esperando un

4.8(100)
162
Control de LED con pulsador en ESP32 (Push)
#104Principiante

Control de LED con pulsador en ESP32 (Push)

El LED se enciende cuando se pulsa el botón y se apaga cuando se suelta. Muestra cómo se utiliza el pin de entrada digital del ESP32 y la resistencia pull-up interna. Gracias al modo INPUT_PULLUP, no se necesita ninguna resistencia externa.

4.6(36)
55
Control de LED con botón en ESP32 (Toggle)
#105Principiante

Control de LED con botón en ESP32 (Toggle)

Cada vez que se pulsa el botón, cambia el estado del LED: si está encendido se apaga, si está apagado se enciende. Patrón de conmutación clásico. Con debounce limpiamos el ruido mecánico del pulsador para garantizar una sola conmutación con una sola pulsación.

4.6(39)
57
Raspberry Pi Pico LED Controlado por Botón (Push, GP14 + GP2)
#155Principiante
Premium

Raspberry Pi Pico LED Controlado por Botón (Push, GP14 + GP2)

¡Primer proyecto de **entrada** con Pico — lectura de botón! 🔘 LED se enciende mientras el botón está presionado. Aprende `Pin.IN`, `Pin.PULL_UP` y `button.value()`. GP14 LED, GP2 botón con PULL_UP interno. Presionado = 0, liberado = 1 — estándar.

0.0(0)
11
Control independiente de 2 LED con 2 botones en la Raspberry Pi Pico (GP12-13 + GP4-5)
#157Principiante
Premium

Control independiente de 2 LED con 2 botones en la Raspberry Pi Pico (GP12-13 + GP4-5)

2 botones, 2 LED: ¡totalmente independientes entre sí! 🔴🟢 Cada botón controla su propio LED: al pulsar BTN1 se enciende el LED rojo; al pulsar BTN2, se enciende el LED verde. Si pulsas los dos a la vez, se encienden ambos LED (funcionamiento en paralelo). Conceptos: **gestión de objetos de pines múltiples** (varias entradas/salidas simultáneas), **operador ternario** (`1 if x else 0` — el if-else compacto de Python), **control independiente de E/S** (lógica de funcionamiento en paralelo), **mapa

0.0(0)
7
Iluminación inteligente de escaleras y pasillos
#82Intermedio
Premium

Iluminación inteligente de escaleras y pasillos

Pisas la escalera o entras en el pasillo y las luces se encienden escalón a escalón en la dirección en la que caminas. Hay un sensor de distancia en cada extremo; pases por el que pases, los ocho LED

5.0(35)
51
Iluminación Inteligente ESP32 (PIR + LDR + Relé + OLED)
#141Avanzado
Premium

Iluminación Inteligente ESP32 (PIR + LDR + Relé + OLED)

¡Convierte tu pasillo, baño o despensa en iluminación inteligente con ESP32! Utilizando un sensor de movimiento PIR, un sensor de luz LDR y un módulo de relé, construimos el escenario clásico "la luz se enciende cuando se detecta movimiento en la oscuridad" — si el ambiente ya está iluminado, el movimiento NO activa la luz, ahorrando energía durante el día. La luz permanece encendida durante 30 segundos; si el movimiento continúa, el temporizador se reinicia y la luz permanece encendida más tiem

4.3(6)
11