Visualización de un número entero de 2 dígitos en dos pantallas de 7 segmentos

Tengo problemas para mostrar un número binario en una pantalla. No estoy seguro de cómo dividir un número en binario en sus números individuales.

Por ejemplo, si quiero mostrar 25, quiero dividirlo en "2" y "5" en binario. Tengo 8 bits entrantes y me gustaría dividirlos en dos partes de 4 bits con los primeros 4 bits que representan el primer dígito en binario y los segundos 4 bits que representan el segundo dígito en binario.

EDITAR: Para aclarar, estoy tratando de hacer esto usando puertas lógicas.

¿Que lenguaje de programación estas usando? ¿O no estás usando un micro y estás buscando alguna solución de puertas lógicas?
Estoy buscando una solución de puerta lógica.
¿Quiere hacer esto utilizando una lógica realmente discreta o diseñándolo en Verilog o VHDL?
Estoy usando logisim, pero creo que una representación general también estaría bien.

Respuestas (5)

La técnica Double-dabble convierte binario a BCD mediante cambios repetidos. Cada repetición reduce a la mitad el número binario restante y duplica el número BCD, después de cambiar el valor binario completo, se obtiene el resultado. Después de cada desplazamiento, se aplica una corrección a cada columna BCD de 4 bits (oa aquellas que tengan más de 3 bits desplazados en ese punto). Esta corrección busca dígitos que 'BCD overflow' decimal 9 -> 10 en el siguiente turno y parchea el resultado agregando tres .

¿Por qué tres? Los dígitos BCD en el rango de cero a cuatro (0,1,2,4) se duplicarán naturalmente a 0,2,4,8 después del cambio. Examinando 5 b 0101, cambiará a b 1010(0xA), que no es un dígito BCD. Por lo tanto, 5 se corrige a (3+5), es decir b 1000, (0x8), que durante el cambio se duplica a 16 decimales (0x10), lo que representa un acarreo de 1 al dígito siguiente y el cero esperado.

Las implementaciones repiten este proceso, ya sea sincrónicamente en el tiempo usando un registro de desplazamiento y 'n' ciclos para una entrada de n bits, o en el espacio colocando los circuitos lógicos para la corrección, alimentándose entre sí y haciendo el cambio con cableado. Hay una ruta de acarreo a través de cada dígito, y la lógica de acarreo no es adecuada para la lógica de cadena de acarreo FPGA (binaria), por lo que la implementación del espacio generalmente brinda resultados de tiempo inaceptables para entradas grandes. Una compensación típica de ingeniería.

Para una conversión paralela (asincrónica)

Para valores estrechos como el suyo , el sitio del Dr. John Loomis tiene una guía de la estructura lógica requerida para implementar en hardware. La lógica reprogramable moderna puede hacer de 8 bits de ancho a quizás 100 MHz después de una síntesis agresiva. El módulo add3toma una entrada de 4 bits y la emite palabra por palabra, o si hay más de cuatro, agrega tres:

module add3(in,out);
input [3:0] in;
output [3:0] out;
reg [3:0] out;

always @ (in)
    case (in)
    4'b0000: out <= 4'b0000;  // 0 -> 0
    4'b0001: out <= 4'b0001;
    4'b0010: out <= 4'b0010;
    4'b0011: out <= 4'b0011; 
    4'b0100: out <= 4'b0100;  // 4 -> 4
    4'b0101: out <= 4'b1000;  // 5 -> 8
    4'b0110: out <= 4'b1001;  
    4'b0111: out <= 4'b1010;
    4'b1000: out <= 4'b1011;
    4'b1001: out <= 4'b1100;  // 9 -> 12
    default: out <= 4'b0000;
    endcase
endmodule

La combinación de estos módulos juntos da la salida.módulos juntos

Para una variante secuencial (multiciclo, canalizada)

Para señales anchas, una técnica serial descrita en la Nota de la aplicación Xlinx "XAPP 029" ejecuta 1 bit por ciclo, probablemente a más de 300 mMhz.

Si alguien conoce una buena técnica híbrida, me interesaría conocerla. Modelé ambos en Verilog con bancos de prueba en mi colección verilog-utils .

Me gusta el enfoque de Xilinx; es simple y permite código compacto (aunque no necesariamente rápido) en microprocesadores que incluyen instrucciones para aritmética BCD. Si uno realmente no necesita velocidad, el enfoque de Xilinx se puede adaptar para generar salidas decimales largas con una sola unidad BCD de 4 bits junto con un montón de registros de desplazamiento. Por supuesto, para un número de dos dígitos eso no es realmente necesario.

Lo que quiere hacer es conocido como conversión a decimal codificado en binario . Algunas computadoras tienen instrucciones especiales para ayudar con la conversión a y desde BCD, y para ayudar con la suma y la resta. Sin embargo, eso no tiene relevancia para ti.

La forma más sencilla que conozco de convertir su número de 8 bits en dos números de 4 bits es manejarlo en potencias de 10.

unsigned char eight_bit_to_two_four_bit(unsigned char value)
{
    unsigned char result = 0;

    while (value >= 10)        // First, count how many 10s fit into value
    {
        value -= 10;
        result += 0x10;        // and count them in the top 4-bits of result
    }

    result += value;           // The remainder is the number of 1s in value
                               // These end up stored in the bottom 4-bits of result

    return result;
}

El bucle while básicamente está implementando una operación de división. Otra forma de implementar esta función es:

unsigned char eight_bit_to_two_four_bit(unsigned char value)
{
    unsigned char result = 0;

    result  = (value / 10) << 4;
    result += (value % 10);

    return result;
}

Esto en realidad usa dos operaciones de división. ¡Caro! En cambio, podemos reemplazar una de las divisiones con una multiplicación y resta.

unsigned char eight_bit_to_two_four_bit(unsigned char value)
{
    unsigned char result = 0;

    result  = (value / 10) << 4;
    result += (value - result*10);

    return result;
}

El hecho de que esta función se implemente con divisiones probablemente hace que sea difícil de implementar con lógica combinatoria. Para hacer esto en lógica pura, el mejor enfoque probablemente sea intentar implementar la primera función.

Eso es lo que yo haría también. Lástima que está buscando una solución de puerta lógica ...
Lo siento, entiendo cómo hacer esto lógicamente, pero no estoy muy seguro de cómo hacerlo usando puertas lógicas.
@YamatoC: es el mismo algoritmo si desea usar puertas lógicas. Deberá implementar operaciones de división y módulo en su lógica. Estos son cálculos algo complejos de hacer, pero si busca algoritmos de división, debería poder encontrar algo que sea implementable.

¿Está buscando un convertidor de binario a BCD como el 74185 ?

Si no, hay una lista de chips lógicos de la serie 7400 en Wikipedia que puede consultar y encontrar lo que necesita.

Una solución de puerta lógica es sencilla utilizando una tabla de verdad y mapas de Karnaugh. La tabla de verdad tendrá el valor binario como entrada y el valor BCD deseado como salida.

Su tabla de verdad debería verse así:

a0 a1 a2 a3 | b6 b5 b4 b3 b2 b1 b0 <br>
0  0  0  0  | 0  0  0  0  0  0  0
0  0  0  1  | 7-seg output for 1
0  0  1  0  | 7-seg output for 2
and so on

Luego convierta la tabla de verdad en mapas de Karnaugh (K-maps) y resuelva para b6, b5 ... b0. Tome las ecuaciones resultantes e impleméntelas usando puertas lógicas.

Información sobre K-maps: http://en.wikipedia.org/wiki/Karnaugh_map

Y aquí hay una solución que pasa por un ejercicio similar usando puertas Nand: http://circuitscan.homestead.com/files/digelec/bcdto7seg.htm

Editar: de los comentarios: si su número de 4 bits no representa estrictamente un BCD, es decir, va más allá de 9, derivaría la ecuación directamente de la tabla de verdad. Entonces, por ejemplo, para esta entrada en la tabla de verdad:

a0 a1 a2 a3   | output
0   1  0  1   | 0 1 1 0 1 1 0

su ecuación para el primer bit (0) es a0 + a1 (barra) + a2 + a3 (barra), el segundo bit (1) es a0 (barra) + a1 + a2 (barra) + a3 y así sucesivamente. La implementación de estas ecuaciones en puertas lógicas es sencilla.

Edit2: muchas de estas ecuaciones se superpondrán y podrá simplificar aún más después de la generación.

Para un número de 2 (¡decimales!) dígitos, será una tabla de verdad bastante grande.
La tabla de verdad solo necesita calcularse una vez para una entrada de 4 bits. Las mismas ecuaciones se aplicarán al segundo número de 4 bits.
La entrada es en realidad de 7 bits, no de 4 bits. El rango de entrada es [0..99], que requiere almacenamiento de 7 bits.
@xyzio No, la tabla de verdad depende de 4 bits + acarreo BCD del dígito anterior
Ah, hice una lectura literal de la pregunta donde 4 bits = 1 dígito BCD, lo que implica que los 4 bits solo tienen valores hasta 9. Si este es el caso, haría trampa y derivaría ecuaciones directas de la tabla de verdad. El k-map de 7 dígitos será difícil de manejar.

Si desea que el circuito sea lo más simple posible, le recomendaría que, en lugar de mostrarlo en decimal, use hexadecimal. En ese caso, cada pantalla de 7 segmentos muestra un valor de 0 a 15 donde los números 10, 11, 12, 13, 14 y 15 se muestran como A, B, C, D, E y F. Entonces solo necesita dos MC14495 IC para convertir cada valor de 4 bits en sus salidas de visualización de 7 segmentos.