Multifunction shield con Alhambra II, Display 7 segmentos y 74595, ¿algún módulo disponible?

108 views
Skip to first unread message

Salva_F

unread,
Mar 31, 2025, 7:37:11 PMMar 31
to FPGAwars: explorando el lado libre
Hola, estoy usando la Multifunction Shield de Arduino y en principio lo hago funcionar todo menos los displays de 7 segmentos que van con un par de registros de desplazamiento 74HC595,  ¿existe algún módulo que genere las señales adecuadas para atacar a estos registros?

Este es la shield.

thnks
Salva

Democrito

unread,
Apr 1, 2025, 4:55:40 AMApr 1
to FPGAwars: explorando el lado libre
Hola Salva,

Los 74HC595 son registros de desplazamiento de 8 bits. Por tanto has de meter la información en serie, en tu caso es a través de la patilla SDI, pin 8 de la shield. Y para validad dicho bit has de dar un flanco de subida en la patilla SHIFTCLK que es la patilla 7 de tu shield. Así 16 veces. Y para terminar has de dar un flanco de subida en la patilla 4 que es LATCHCLK, lo que hará será hacer transparente a la salida los valores que has transmitido a los registros. Por otra parte has de averiguar si tu displays son de ánodo o cátodo común porque si esto lo pones al revés no verás nada, todo apagado.

Consejos:

Si nunca has manejado displays de 7 segmentos, hacerlos funcionar con registros de desplazamiento te va a parecer "un Cristo" (de difícil). Si ese es tu caso, primero aprende a manejar un sólo display y entender conceptos como ánodo común y cátodo común. De esta podrás saber si has de enviar la información de manera normal o invertida e identificar dónde está esos cátodos o ánodos.

Te dejo con información por si te sirve de algo:



Saludos.

Democrito

unread,
Apr 1, 2025, 5:06:02 AMApr 1
to FPGAwars: explorando el lado libre
Observa en el esquema que te pasé, que el registro de desplazamiento izquierdo se encarga de los ánodos o cátodos comunes de cada display (por eso son 4, tantos como displays de 7 segmentos existen) y el registro de desplazamiento derecho se encargaría de prender los leds que corresponda al display en cuestión (a, b, c, d, e, f, g y h). Si a, b, c se prenden con lógica positiva, entonces 1, 2, 3 o 4 se ha de poner a 0, o viceversa.

Salva_F

unread,
Apr 1, 2025, 8:57:19 AMApr 1
to FPGAwars: explorando el lado libre
Hola Gracias, si,  tengo experiencia en sistemas embebidos y displays de todos los colores, lo que no había tocado nunca eran FPGAs, bueno, PALs hace mil años pero es como la versión baby de las FPGA. voy a ver si hago algo que más o menos haga rodar a esta tarjeta con la entrada AD, el display y los botones, la cosa era si había algo hecho ya, pero percibo que no.

Salva F.

Alexander Lang

unread,
Apr 1, 2025, 9:30:10 AMApr 1
to fpga-wars-explora...@googlegroups.com
Hi Salva

I have definitely driven Shift registers with FPGAS before...

I don't think anyone has used Ice-Studio to do it though.

As mentioned by others...the code to do it isn't too hard to write and therefore should be easy enough to recreate graphically with Ice-Studio.

Here is some verilog code that does it:

//---------------------------------------------------------------------------------

module shift_register_driver (
    input clk,          // Clock input
    input rst_n,        // Asynchronous reset (active low)
    input serial_in,    // Serial data input
    input shift_enable, // Enable shifting (active high)
    input latch_enable, // Enable latching to output (active high)
    output reg ser,     // Serial output (for daisy-chaining)
    output reg [7:0] parallel_out // 8-bit parallel output
);

reg [7:0] shift_reg;

// Shift register logic
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        shift_reg <= 8'b0;
        ser <= 1'b0;
    end else if (shift_enable) begin
        shift_reg <= {shift_reg[6:0], serial_in};
        ser <= shift_reg[7]; // Output the most significant bit
    end
end

// Latch logic
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        parallel_out <= 8'b0;
    end else if (latch_enable) begin
        parallel_out <= shift_reg;
    end
end

endmodule

//---------------------------------------------------------------------------------

Here is how the code works:

Verilog
module shift_register_driver (
    input clk,          // Clock input
    input rst_n,        // Asynchronous reset (active low)
    input serial_in,    // Serial data input
    input shift_enable, // Enable shifting (active high)
    input latch_enable, // Enable latching to output (active high)
    output reg ser,     // Serial output (for daisy-chaining)
    output reg [7:0] parallel_out // 8-bit parallel output
);

reg [7:0] shift_reg;

// Shift register logic
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        shift_reg <= 8'b0;
        ser <= 1'b0;
    end else if (shift_enable) begin
        shift_reg <= {shift_reg[6:0], serial_in};
        ser <= shift_reg[7]; // Output the most significant bit
    end
end

// Latch logic
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        parallel_out <= 8'b0;
    end else if (latch_enable) begin
        parallel_out <= shift_reg;
    end
end

endmodule

Explanation:

  1. Module Declaration:

    • module shift_register_driver (...): Defines a Verilog module named shift_register_driver with the specified input and output ports.
  2. Inputs:

    • clk: The clock signal that synchronizes the operations.
    • rst_n: An asynchronous reset signal. When low (0), it resets the shift register and parallel output. The _n suffix indicates active low.
    • serial_in: The serial data bit that will be shifted into the register.
    • shift_enable: A control signal. When high (1), data is shifted into the register on the rising edge of the clock.
    • latch_enable: A control signal. When high (1), the contents of the shift register are transferred to the parallel output on the rising edge of the clock.
  3. Outputs:

    • ser: The serial output (often labeled Q' or QH on the 74LS595). This can be connected to the serial_in of another 74LS595 for daisy-chaining multiple chips.
    • parallel_out [7:0]: An 8-bit register representing the parallel output pins (QA to QH) of the 74LS595. reg is used because these outputs are driven by procedural assignments within the always blocks.
  4. Internal Register:

    • reg [7:0] shift_reg;: An 8-bit internal register that holds the data being shifted.
  5. Shift Register Logic (always @(posedge clk or negedge rst_n)):

    • This always block is triggered on the rising edge of the clock (posedge clk) or the falling edge of the reset signal (negedge rst_n).
    • Reset Condition: if (!rst_n) begin ... end: If the reset signal is low, the shift_reg and ser output are set to 0.
    • Shift Enable Condition: else if (shift_enable) begin ... end: If shift_enable is high, on the rising edge of the clock:
      • shift_reg <= {shift_reg[6:0], serial_in};: The contents of shift_reg are shifted one bit to the left. The serial_in value is shifted into the least significant bit (LSB), and the most significant bit (MSB) is shifted out.
      • ser <= shift_reg[7];: The most significant bit of the shift_reg is assigned to the ser output.
  6. Latch Logic (always @(posedge clk or negedge rst_n)):

    • This always block is also triggered on the rising edge of the clock or the falling edge of the reset signal.
    • Reset Condition: if (!rst_n) begin ... end: If the reset signal is low, the parallel_out is set to 0.
    • Latch Enable Condition: else if (latch_enable) begin ... end: If latch_enable is high, on the rising edge of the clock, the current contents of shift_reg are copied to the parallel_out register.
If you are still struggling I can implement this code in ice-studio for you later on...supposed to be working at the moment!

Cheers

Alex


--
Has recibido este mensaje porque estás suscrito al grupo "FPGAwars: explorando el lado libre" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a fpga-wars-explorando-el...@googlegroups.com.
Para ver este debate, visita https://groups.google.com/d/msgid/fpga-wars-explorando-el-lado-libre/109d027c-68fc-4a9f-9086-5cd3e0c10454n%40googlegroups.com.

Jesus Arias

unread,
Apr 1, 2025, 10:39:35 AMApr 1
to FPGAwars: explorando el lado libre
Hola,
Lo que necesitas es básicamente  un controlador SPI maestro, aunque te basta con la función de salida.
El reloj no debería ser muy rápido: Hay que refrescar las 4 pantallas en unos 10ms, los que nos da unos 2.5ms para cada dato a transmitir, y son 16 bits más un ciclo adicional para copiar el dato al registro de salida de los HC595. Esto nos daría una frecuencia de reloj de 6800Hz.

El controlador constaría principalmente de:
- Un divisor (prescaler) que nos baje la frecuencia de los 12MHz del reloj de la FPGA a unos 6800Hz , más o menos.
- Un contador módulo 17: Un estado de carga, y 16 estados de desplazamiento
- Un registro de desplazamiento de 16 bits. Los datos se desplazan en los flancos de bajada del reloj (el hc595 los muestrea en los flancos de subida). En el estado de carga el registro se precarga con el dato a trasmitir y el HC595 transfiere los datos anteriores a su registro de salida en paralelo. En el resto de los estados simplemente se desplaza.

Saludos

charli va

unread,
Apr 1, 2025, 10:51:21 AMApr 1
to fpga-wars-explora...@googlegroups.com
Por si necesitas ayuda con el SPI (o módulos ya funcionales), Obijuan tiene un vídeo bastante bueno sobre ello:


In other hand, thanks @Alexander Lang for share your code!

Nice day!

--
Has recibido este mensaje porque estás suscrito al grupo "FPGAwars: explorando el lado libre" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a fpga-wars-explorando-el...@googlegroups.com.

Jesus Arias

unread,
Apr 1, 2025, 5:37:52 PMApr 1
to FPGAwars: explorando el lado libre
Hola Salva,
Incluyo un posible controlador para el display en Verilog. No he podido resistirme a hacerlo ;) Tan sólo faltaría un prescaler para el reloj, que podría ser de 10 bits (1/1024).
Y aunque no tengo el shield en cuestión y no lo puedo probar en condiciones creo que la funcionalidad básica está bien:
waves1.png
Espero que te pueda servir, al menos como ejemplo de partida.
display7s595.v

Alexander Lang

unread,
Apr 2, 2025, 1:48:10 AMApr 2
to fpga-wars-explora...@googlegroups.com
Compré un protector porque tenía curiosidad por ver si podía hacerlo funcionar 😀.

Probaré tu solución. El protector llega hoy y espero probarlo esta tarde.

Gracias por la solución.

Saludos 

Alex

---------------

I have bought a shield as I was curious to see if I could make it work 😀.

I will test your solution. The shield arrives today and I will try it this evening hopefully.

Thanks for the solution.

regards

Alex

charli va

unread,
Apr 2, 2025, 5:46:56 AMApr 2
to fpga-wars-explora...@googlegroups.com
Aporto mi granito de arena al hilo.

Captura de pantalla 2025-04-02 a las 11.31.40.png

Tampoco tengo la shield, así que  al tener el código de Jesús , he  hecho un módulo verilog  "clon" del 595 he pegado todo y he montado un testbench en verilator que simula el display de la  shield.

Me he venido arriba y lo he hecho en ascii como si fuera una fuente e 8x16, teóricamente soporta cualquier configuración porque al simular directamente el 595 no interpreto valores sino que miro que pines se activan para dibujar.

Podeis ver el resultado en el vídeo (en modo cutre pinto los displays en ascii) en el testbench  a modo de prueba estoy sumando de 3 en 3, a framerate de 1fps para verlo bien y poder depurar. estoy pintando en hexadecimal para ver que se pintan bien el display y que soporta cualquier combinación.

He tenido que hacer pequeños ajustes al código de Jesús para que funcionara con el testbench, como el display puede ser de cátodo/ánodo común, se me iba de cuentas y lo he reajustado.

La configuración que he intuido que lleva la shield por la foto (no me he metido a ver el diseño la verdad) es de cátodo común, que en nuestro testbench quiere decir  que un 1 en un bit de q1 (después de q1 & 0x7F) indica que el segmento debe encenderse (se dibuja con #).

Os he subido un vídeo por si queréis verlo:


Para probarlo sólo tenéis que bajaros los adjuntos que son, el código de Jesús ajustado.  el clon del 895, el top que une las piezas (sería la shield) y el fichero .cpp que simula la multiplicación para que los 4 digitos evolucionen y muestre el resultado.

Todo ello se compila con verilator así:
verilator -Wall --cc --exe --build -j top.v hc595.v serialdisplay.v testbench.cpp

y luego lanzais el ejecutable que se compila y veréis lo mismo que en el vídeo, en linux y mac:

obj_dir/Vtop

El testbench es c++ porque verilator es lo que le gusta (se puede hacer en C pero se complica bastante porque no se han currado una interfaz nativa, yo soy mucho más de C que de C++ así que disculpad si alguien experto en c++ me ve alguna chapuza).

No he querido invertir demasiado tiempo en el testbench es una prueba de concepto y he dejado líneas de depuración por si a alguien que le interese pueda ver como he ido depurando o viendo diferentes estados etc de los módulos verilog. El tema se que Verilator es muy caprichoso y sus buffers de salida van "tuneados"lo que hace que jugar con caracteres d control ASCII para generar la animación o posicionar las cosas a veces no salgan bien o se cuelen  (de repente igual veis un [^H1 o cosas así). 

Como os digo es más una prueba de concepto de poder ver el resultado físico de un módulo verilog simulado que me parece muy interesante.

He hecho hoy un pedido de material y he metido unos 595 por probarlo físicamente la semana próxima.

Espero que os pueda resultar útil , pasad buen día!!

hc595.v
serialdisplay.v
testbench.cpp
top.v

Jesus Arias

unread,
Apr 2, 2025, 6:42:38 AMApr 2
to FPGAwars: explorando el lado libre
Hola Carlos,
Me parece que tienes los 595s intercambiados respecto de lo que aparece en el esquemático del shield: el que controla los segmentos es el segundo....

charli va

unread,
Apr 2, 2025, 7:57:00 AMApr 2
to fpga-wars-explora...@googlegroups.com
“Si tienes que elegir aleatoriamente entre dos opciones siempre cogerás la incorrecta” - ley de murphy de la electrónica 😂

Luego le pego un repaso y lo dejamos como la shield! Gracias por echarle un vistazo Jesús!


Alexander Lang

unread,
Apr 2, 2025, 8:01:54 AMApr 2
to fpga-wars-explora...@googlegroups.com
Cuando tener tiempo esta tarde yo voy a pruebar con mi nuevo protector!

Gracias por la assistencia caballeros.

Saludos 

Alex

---------Translated in my head so please excuse my poor spanish! I'm trying to get better and not rely on translation apps or AI.---------

If I have the time tonight I will try it with my new shield 😁

Thanks for the assistance gentlemen.

Kind regards

Alex

charli va

unread,
Apr 2, 2025, 12:29:03 PMApr 2
to fpga-wars-explora...@googlegroups.com
Me había quedado en el primer post el foro y sólo había visto la foto y no me di cuenta que debajo había un esquemático de la tarjeta....

bebe-lendo.gif

Adjunto el esquemático por referencia por si alguno no lo ha visto y porque quede todo reunido.

Ahora ajustando las conexiones para que U2 gestione los dígitos y U3 los segmentos como en el  esquemático de la shield y como indicaba Jesús, os devuelvo el paquete con la simulación lista para quemar dígitos XD, os comento ajustes que he hecho por si  pudiera haber caído en suposiciones o errores de concepto.

El módulo de Jesús ahora me funciona perfecto sin cambios salvo un pequeño eror en el dígito C que se había bailado algún bit (lo he indicado en los comentarios).

Y en el always como es continuo, verilator no acepta el <= y he tenido que cambiarlo por = pero eso posiblemente yosys si que lo infiera, verilator es demasiado estricto muchas veces.

 Le he tenido que cambiar el nombre al fichero a serialdisplay.v aunque el contenido es como os comento como el del original, porque verilator necesita que el fichero se llame como el módulo principal que contiene, si no hay que poner una excepción y no me gusta meter cosas de este tipo si es evitable.

También comentaros que el testbench tiene su  punto de interés porque intenta simular lo más fielmente posible el display, se podría simular mucho más fácilmente sin incluir ni siquiera los 595 y simplemente mirando valores y pintando los dígitos ya precalculados pero he querido hacerlo así porque me ha parecido interesante ver una replica de funcionamiento físico del display lo más fiel que se me ha ocurrido implementar (ando explorando temas de simulación para icestudio desde hace meses y este tipo de cosas me interesan mucho). En el código del testbench el bucle principal está redundado, lo he hecho así a posta porque son tres situaciones diferentes que aunque al final han quedado exactas y se podría encapsular en una función por reducir el código, al depurar me ha venido bien tener esos tres puntos donde poder tocar de forma independiente, así que así lo he dejado por apaños futuros.

Así que con esto, en principio la simulación queda literalmente como el esquemático y aparentemente el display real debería funcionar a la perfección, con el código de Jesús. Una foto finish del simulador en marcha:


Captura de pantalla 2025-04-02 a las 18.19.59.png

He comentado el código más o menos para que sea autoexplicativo, le he pegado un repaso en esta última tanda, espero que sea útil!

Buena tarde!


El El mié, 2 abr 2025 a las 12:42, Jesus Arias <ges...@gmail.com> escribió:
image.png
serialdisplay.v
hc595.v
testbench.cpp
top.v

Jesus Arias

unread,
Apr 2, 2025, 1:16:13 PMApr 2
to FPGAwars: explorando el lado libre
Hola
Has cambiado la 'c' por 'C' :) las dos versiones son posibles.
Y si alguien quiere probar un orden de refresco distinto para los displays también se puede. Sólo hay que cambiar una línea, por ejemplo:

// digit multiplexer (firing order 1-3-4-2 ;)
wire [3:0] dsel={(dgcnt==2),(dgcnt==1),(dgcnt==3),(dgcnt==0)};

Una simulación visual estaría muy bien, el ASCII-art es una primera aproximación. Yo uso a menudo Proteus, que simula un montón de TTLs, displays, analógica y demás, pero los módulos Verilog  no resultan nada fácil de incorporar. Y además es software propietario (de los que mandan los "bug_report" a /dev/null ;)

Saludos

charli va

unread,
Apr 2, 2025, 2:02:40 PMApr 2
to fpga-wars-explora...@googlegroups.com
Madre mía Jesús vaya parranda la mia XD tomé una hoja de datos de display porque hacía mil años que no manejaba uno y me venían los códigos en mayuscula XD no caí la verdad, muchas gracias por la aclaración! como me pasaban cosas raras por haber invertido el orden de los 595, busqué fantasmas donde no los había.

Estoy trabajando en herramientas de simulación para este año de cara al otoño-invierno tendré cosas potables, mucho más gráfica y bonita que esto ,jeje , creo que será un salto importante con lo que tenemos ahora en icestudio que es nada :) os iré pasando cosas poco a poco o porque surjan como esto , ahora quiero cerrar bastantes cosas que tengo ya a punto y voy con retraso. 

La verdad que estoy ha sido más una curiosidad de ver como hacerlo con pocos recursos y de una forma relativamente rápida y probar tu código ya que te habías tomado la molestia de prepararlo.

Si alguien se anima a jugar con el testbench y hacer tu prueba de orden es super sencillo porque con cambiar tu línea y compilar debería ser más que suficiente .

Por cierto, Tim Rudy, que suele intervernir en la lista, se trabajó un montón de TTLs en verilog y icestudio con sus respectivos testbenches, por si no lo conocíais :


Siempre he pensado que con eso y un poco más se podría montar en icestudio o verilog una cpu sencilla tipo las de Ben Eater o esta https://austinmorlan.com/posts/8bit_breadboard/ ¿alguien se anima? XD

Pasad buena tarde!


Salva_F

unread,
Apr 5, 2025, 12:06:05 PMApr 5
to FPGAwars: explorando el lado libre
Hola, al final me he echado al monte y he hecho una pequeña adaptación del código de Obijuan, poniendo la Shield en la Alhambra y usando el código de ejemplo como base, se lee la entrada analógica de la Multishield ajustable con el multivuelta y se representa en el display de 00 a FF, también se muestra en los leds de la Alhambra, dejo el código y un pequeño video. La verdad que la Multishield esta bien como base para hacer pruebas sin necesidad de breadboard. Adjunto el código y un vídeo por si a alguien le puede ser de utilidad.  

Salva
Potenciometro Multishield_.mp4
Potenciometro Multishield.ice

Democrito

unread,
Apr 5, 2025, 12:51:40 PMApr 5
to FPGAwars: explorando el lado libre
Gracias por el vídeo, Salva, siempre se agradece ver una demo. Es una demostración muy completa de ADC y displays.

charli va

unread,
Apr 5, 2025, 2:38:39 PMApr 5
to fpga-wars-explora...@googlegroups.com
Me alegra mucho ver tus avances Salva! Mantennos al día!



--
Has recibido este mensaje porque estás suscrito al grupo "FPGAwars: explorando el lado libre" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a fpga-wars-explorando-el...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages