Quiero compartir la experiencia de crear una pantalla LED de 8x8 píxeles, 262k combinaciones de colores (18 bits), una velocidad de cuadro de 180 FPS y una conexión USB. También estoy listo para escuchar sugerencias de optimización y refinamiento. En el futuro planeo usar las mejores prácticas para crear una pantalla de la estación meteorológica del hogar.Prólogo
Todo comenzó con el esquema de control más simple para una línea de 8 LED a través de un puerto LPT. La siguiente versión era una placa 5x8 de LED de tres colores, que también se conectaba al LPT y, de hecho, era una matriz de quince memorias intermedias de 8 bits con un decodificador para su direccionamiento. Más tarde, después de reunirme con los microcontroladores, me propuse crear una pantalla similar, pero con una conexión USB. Inicialmente se esperaba usar solo 8 colores. Posteriormente, encontró una manera de controlar el brillo de cada diodo usando un temporizador por analogía con PWM, y después de finalizar la parte del software, el dispositivo actual resultó. Teóricamente, puede trabajar con 16 millones de colores, pero los LED convencionales no son adecuados para este modo en términos de reproducción y repetibilidad del color. Además, los problemas con el color de los diferentes diodos ya son visibles en la configuración actual.Descripción del puesto
El dispositivo se basa en el microcontrolador PIC18F4550 que funciona a una frecuencia de 48 MHz. Se utiliza un controlador USB incorporado y una biblioteca preparada para trabajar con él, Timer0 en modo de 8 bits, que implementa la indicación dinámica. Para almacenar tres colores en una columna, se utilizaron tres disparadores de 8 bits en 74F374. El uso de este búfer permite reducir el tiempo de visualización de un cuadro en 3 veces. Nota: Cuando seleccioné el búfer 74F374, no presté atención al cableado de sus patas, pero entendí esto solo en el soporte de montaje, por lo que tuve que complicar significativamente la placa. Es mejor usar análogos más convenientes. Por ejemplo, 74HC574. Los LED se conectan mediante las teclas ULN2803 y UDN2982. Las resistencias limitantes de corriente solo están en el canal rojo, porque su voltaje de suministro está por debajo de azul y verde. Para la resistencia azul y verde no están instalados, porque suficiente caída de voltaje en las teclas. Nota: Para una reproducción de color más precisa, es mejor seleccionar resistencias limitantes de corriente más precisas en cada canal. El microcontrolador en un ciclo sin fin sondea el estado del USB y, cuando llega un paquete de datos, según el comando, inicia / detiene la pantalla o prepara los datos para su visualización. Debido a la limitación del tamaño de un paquete a 64 bytes, los datos para cada color se transmiten en un paquete separado de 48 bytes - 6 bytes para cada una de las 8 columnas, codificando el brillo de cada LED en la columna. Después de recibir cada paquete, se copia de la memoria USB a una matriz de su color. Después de recibir el comando de inicio de indicación, el MK activa el temporizador en modo de 8 bits y un divisor por 128. El temporizador utiliza la frecuencia de funcionamiento del microcontrolador como pulsos de reloj. Se produce un aumento en el contador del temporizador cada 4 medidas. El período mínimo de temporizador es de 10,6 μs (1/48 * 4 * 128), que es aproximadamente 2,8 veces el tiempo de procesamiento de la interrupción (46 operaciones, frente a 128 muestras de temporizador). Cuando el temporizador se desborda, se realiza una interrupción vectorial alta. El controlador de interrupciones deshabilita la indicación, actualiza los datos en las memorias intermedias, transfiere 1 byte de cada matriz de colores de acuerdo con el cursor, luego enciende la indicación. Introduce un nuevo valor en el temporizador desde el búfer temporal, disminuye el cursor, desplaza el búfer temporal para el temporizador. Si el buffer del temporizador excedió el valor máximo, es decir desplazado más de 5 veces, el búfer del temporizador se restablece al valor mínimo y se desplaza el puntero de la columna seleccionada.Como resultado, se obtiene el siguiente algoritmo de indicación dinámica:- Tomamos el primer grupo de 3 bytes de tres matrices y los colocamos en los buffers de cada color en la columna.
- Activamos el temporizador con un tiempo de retraso mínimo de 128 ticks.
- Tomamos el siguiente grupo de 3 bytes de tres matrices y lo colocamos en los buffers de cada color en la columna.
- Activamos el temporizador con un doble retraso en relación con el paso anterior.
- Repita la muestra 4 veces más y duplique el tiempo de retraso cada vez.
- Restablecemos el temporizador y comenzamos a procesar la siguiente columna del paso 1.
Por lo tanto, podemos establecer 2 ^ 6 = 64 opciones de brillo para cada diodo en la columna. Combinando el brillo de cada uno de los tres colores básicos, obtenemos 64 * 64 * 64 = 262144 colores. El tiempo de procesamiento para una columna es (2 ^ 6-1) * 10.6 μs = 672 μs. El tiempo por cuadro de 8 columnas es 672 * 8 = 5.4 ms, lo que corresponde aproximadamente a 186 cuadros por segundo.Componentes utilizados
- PIC18F4550 - Microcontrolador
- 74F374 - Disparador para mantener los valores de columna actuales
- ULN2803 - Clave para control de cátodos
- UDN2982 - Clave para controlar ánodos
- LED RGB de 4 pines con un cátodo común (se puede usar cualquier LED)
Esquema
Esquema en formato dsn - descargarTarifa
Lay6 dibujos - descargarFirmware
Fuentes y HEX ensamblados en MPLABX X IDE v2.30 - descargarCódigo principal#ifndef MAIN_C
#define MAIN_C
#include "config.h"
#include "usb.h"
#include "HardwareProfile.h"
#include "usb_function_hid.h"
#include "genericHID.h"
#define UdnOn LATA&=0b11111110
#define UdnOff LATA|=0b00000001
#define UlnOn LATD
#define UlnOff LATD =0b00000000
#define LineBufer LATB
#define WriteR LATE|=0b00000001
#define WriteG LATE|=0b00000010
#define WriteB LATE|=0b00000100
#define WriteRst LATE =0b00000000
#define Columns 8
#define BrightLevels 6
#define BlockSize (Columns*BrightLevels)
#define MinBright 0b11111111
unsigned char cursor;
unsigned char bright;
unsigned char column;
unsigned char dataR[BlockSize];
unsigned char dataG[BlockSize];
unsigned char dataB[BlockSize];
void ProcessIO(void) {
unsigned char temp = BlockSize + 1;
if ((USBDeviceState < CONFIGURED_STATE) || (USBSuspendControl == 1)) return;
if (!HIDRxHandleBusy(USBOutHandle))
{
switch (ReceivedDataBuffer[0])
{
case 0x80:
while (--temp) dataR[temp-1] = ReceivedDataBuffer[temp];
break;
case 0x81:
while (--temp) dataG[temp-1] = ReceivedDataBuffer[temp];
break;
case 0x82:
while (--temp) dataB[temp-1] = ReceivedDataBuffer[temp];
break;
case 0x90:
column = 0b00000001;
cursor = BlockSize;
bright = MinBright;
TMR0ON = 1;
SWDTEN = 0;
break;
case 0x91:
UdnOff;
UlnOff;
TMR0ON = 0;
SWDTEN = 0;
break;
case 0x92:
UdnOff;
UlnOff;
TMR0ON = 0;
SWDTEN = 0;
SLEEP();
break;
}
USBOutHandle = HIDRxPacket(HID_EP, (BYTE*) & ReceivedDataBuffer, 64);
}
}
void main(void)
{
PCFG3 = 1;
PORTA = 0b00000000;
PORTB = 0b00000000;
PORTC = 0b00000000;
PORTD = 0b00000000;
PORTE = 0b00000000;
TRISA = 0b00000000;
TRISB = 0b00000000;
TRISC = 0b00000000;
TRISD = 0b00000000;
TRISE = 0b00000000;
INTCON = 0b10100000;
T0CON = 0b01000110;
USBDeviceInit();
while(1)
{
USBDeviceTasks();
ProcessIO();
};
}
void interrupt tc_int()
{
UdnOff;
UlnOff;
LineBufer = dataR[cursor-1]; WriteR;
LineBufer = dataG[cursor-1]; WriteG;
LineBufer = dataB[cursor-1]; WriteB;
UdnOn;
UlnOn = column;
WriteRst;
TMR0L = bright;
if (!--cursor) cursor = BlockSize;
bright <<= 1;
asm("BTFSS _bright, 5, 0"); asm("RLNCF _column, 1, 0");
asm("BTFSS _bright, 5, 0"); bright = MinBright;
TMR0IF = 0;
}
#endif
Dispositivo en funcionamiento
Para el control, uso un reproductor de radio por Internet escrito en C, que se basa en la biblioteca BASS.DLL. Una demostración de degradado en toda la paleta de colores disponible funciona durante una pausa, la frecuencia de actualización de fotogramas (paquetes transmitidos al dispositivo) es de 20 Hz. Cuando se reproduce música, un visualizador funciona con la matriz FFT obtenida por BASS.DLL, la frecuencia de actualización de fotogramas (paquetes transmitidos al dispositivo) en este modo es de 29 Hz.Visualizador
: Tape Five — Soulsalicious
: ( ) ( ). .. , .- ( UDN)
- USB
- smd
- 74F374 74HC574,
- 74F374
- 74HC138,
- 3 ULN, UDN