Cálculo de tiempo de señal VGA usando MCU

Quiero generar señal VGA con microcontrolador. Pero tengo dificultades para encontrar una solución en línea sobre cómo generarlos en el software. Por ejemplo, por lo general, toda la generación de señales VGA en línea solo explica los requisitos de sincronización para HSYNC y VSYNC junto con la sincronización del porche delantero y trasero con algunos valores fijos como 640x480@60Hz o 1024x786@70Hz, etc. Pero lo que no se proporciona es cómo calcularlos y el píxel. reloj y otras cosas. Entonces, ¿cómo calcular el tiempo para VSYNC y HSYNC junto con el porche delantero y trasero para cualquier resolución aleatoria a una frecuencia de actualización aleatoria, por ejemplo, 480x240@60Hz?

Gracias por las respuestas. Ashutosh

Respuestas (3)

Es bastante fácil calcular todo lo que necesita a partir de la información básica proporcionada.

Por ejemplo, el sitio que más uso como referencia es este: http://tinyvga.com/vga-timing/640x480@60Hz y tiene todo lo que necesita para 640x480 @ 60Hz (especifica las resoluciones más comunes, pero esa es la más fácil de trabajar).

Especifica todo en píxeles y líneas, y proporciona una frecuencia de reloj de píxeles, así como frecuencias de actualización. Sin embargo, todo lo que necesita es el reloj de píxeles y la cantidad de píxeles para cada cosa.

Por ejemplo, proporciona un reloj de píxeles de 25,175 MHz. Eso no es fácil de generar para la mayoría de los microcontroladores, ya que es tanto de alta frecuencia como de alta resolución; en general, puede tener uno de esos dos: alta frecuencia o alta resolución. Sin embargo, 25 MHz suele ser lo suficientemente fácil de generar y está "lo suficientemente cerca" para que la mayoría de los monitores puedan manejarlo.

Así que tenemos un reloj de píxeles de 25 MHz. También tenemos un tamaño de "línea completa" de 800 píxeles. Ese tamaño incluye los porches, la sincronización y el área visible. Entonces, una línea de 800 píxeles, con un reloj de 25 MHz, estaría funcionando a (25 000 000/800) 31 250 Hz, o una línea cada 32 µS.

El pulso de sincronización horizontal - 96 píxeles - sería (96/25,000,000) = 3.84µS de largo.

Sabemos que una línea toma 32 µS y hay 525 líneas en un "cuadro completo", por lo que 0,000032 × 525 = 0,0168 s para un cuadro, o 59,524 Hz. Eso está bastante cerca de los 60 Hz para la especificación.

Entonces, dado un reloj de píxeles y un conjunto de períodos de píxeles, puede calcular cualquier cosa. Por supuesto, también puede retroceder. Dada una velocidad de fotogramas y una resolución, puede calcular:

60 H z × 525 = 31500 H z

31500 H z × 800 pag X = 25.2 METRO H z
Eso demuestra que incluso las especificaciones dadas no son 100% exactas, pero hay un poco de flexibilidad en los tiempos de VGA para que pueda ajustar su reloj para que se adapte a sus necesidades dentro de ciertos límites.

Y mientras estamos en eso, generar VGA únicamente con software requiere mucho procesamiento y, a menudo, lo deja sin ciclos de CPU para hacer cualquier cosa. Uno de los "trucos" más comunes para hacer una señal VGA en una CPU es usar SPI para generar el flujo de datos de píxeles. Aún mejor si tiene DMA en su microcontrolador para generar una línea completa de datos sin que la CPU tenga que hacer nada. Entonces, la CPU solo es responsable de generar los pulsos de sincronización y cargar el sistema DMA con las direcciones correctas; el resto se hace en segundo plano. Por supuesto, eso te deja con solo una pantalla monocromática de 1 bit. Si tiene una interfaz SQI y suficiente RAM, podría hacer una pantalla de 4 bits (16 colores) bastante fácil.

¡¡¡Eso es útil!!! Entonces, tomando el ejemplo de 640x480 en el enlace que compartiste, el porche delantero debe tener 1/40 de píxeles horizontales y así sucesivamente. Entonces, ¿puedo usar 12 píxeles para un ancho de 480 píxeles horizontales ya que no hay una fórmula específica?
480 no es un ancho adecuado para una resolución reconocida. El truco aquí es cambiar el tamaño de píxel. Mantenga (digamos) 640x480 como su resolución real, pero no emita los píxeles a la misma velocidad en su área visible. Entonces, aunque el área visible toma el mismo tiempo que 640 píxeles, en realidad estás generando 480 píxeles que son un poco más lentos en la misma cantidad de tiempo (si eso tiene sentido)
bien, eso es lógico. Gracias por la información Majenko! :)

Aunque no proporciona las fórmulas, esta página tiene una calculadora que le permite seleccionar de una lista de VGA o SVGA (hasta 1920 x 1080), y muestra una docena de parámetros diferentes. Luego puede modificar cualquiera de estos parámetros manualmente, y volverá a calcular elementos como frecuencias de sincronización, longitudes de pulso, etc.

Esta página es otra que solo tiene tablas de parámetros para varias resoluciones, en cuatro tablas con más de cien entradas diferentes en total.

Esta es una pregunta complicada porque está estrechamente relacionada con cualquier arquitectura de MCU y circuito de generación de imágenes que esté utilizando. Lo hice comenzando a definir macros que me permiten calcular varias cosas útiles, como ciclos de reloj por línea, etc., y luego adaptarlas al hardware que estoy usando.

Aquí hay un fragmento de código que he escrito para ese propósito. Con toda probabilidad, no le será útil como tal, pero podría mostrar un posible enfoque del problema.

/// Crystal frequency in MHZ (float, observe accuracy)
#define XTAL_MHZ 3.579545
/// Line length in microseconds (float, observe accuracy)
#define LINE_LENGTH_US 31.777557 
/// Frame length in lines (visible lines + nonvisible lines)
#define TOTAL_LINES 525
/// Number of visible lines in frame (excluding any border areas)
#define VISIBLE_LINES 480
/// Number of lines used for VSYNC
#define SYNC_LINES 2
/// Number of lines used after the VSYNC but before visible area
#define FRONT_PORCH_LINES 10

#define HSYNC_WIDTH_XTALCLKS 14
#define BACKPORCH_BORDER_XTALCLKS 14

#define FRONTPORCH_BORDER_XTALCLKS 12
/// Number of visible pixels (excluding any border areas)
#define VISIBLE_PIXELS 100
/// Width, in PLL clocks, of each pixel
#define PLLCLKS_PER_PIXEL 8
/// How many bits per pixel - this must match with the pattern generator microcode
#define BITS_PER_PIXEL 16

#define WORDS_PER_LINE ((VISIBLE_PIXELS * BITS_PER_PIXEL + 15) / 16)
#define FIRST_LINE (SYNC_LINES + FRONT_PORCH_LINES)
#define PLL_MHZ (XTAL_MHZ * 8.0)
#define PLLCLKS_PER_LINE ((u_int16)((LINE_LENGTH_US * PLL_MHZ)+0.5))
#define COLORCLKS_PER_LINE ((u_int16)((LINE_LENGTH_US * XTAL_MHZ)+0.5))
...and so on...