También tuve problemas para interpretar la estructura del archivo .LED, sin embargo, otro método sería crear sus propios mapas de bits. Creé una imagen LED con Microsoft Paint, en File | Properties
establecí el ancho y el alto en 10 píxeles seguidos de un File | Save As
y seleccionando 24-bit Bitmap
como el tipo. Si te acercas al máximo, es fácil seleccionar píxeles individualmente y Linux y Mac OSX tienen muchas aplicaciones que pueden escribir mapas de bits de Windows si estás usando un O / S diferente.
Luego creé la siguiente aplicación de línea de comandos de Visual C ++ para leer el mapa de bits y crear una definición de matriz constante. Escribe el código en la salida estándar para que, por ejemplo, pueda invocarlo utilizando bitmapconvert test.bmp > test.h
. Tenga en cuenta que hace varias suposiciones con respecto al tamaño del mapa de bits y la profundidad de bits, por lo que de ninguna manera lo es el "código de producción", por lo que en algún momento es posible que desee seguir analizando el formato del archivo de mapa de bits.
#include "stdafx.h"
#include <stdio.h>
#include <stdint.h>
#define BITMAP_WIDTH 10
#define BITMAP_HEIGHT 10
#pragma pack (1)
struct PIXEL_DEF {
uint8_t B, G, R;
} pixels[BITMAP_HEIGHT][BITMAP_WIDTH];
void read_bitmap_data(FILE *bmp)
{
uint32_t data_offset, curx = 0, cury = 0;
fseek(bmp, 10, SEEK_SET); // Skip to offset to bitmap bits
fread(&data_offset, sizeof(data_offset), 1, bmp);
fseek(bmp, data_offset, SEEK_SET); // Move to start of bits
while (fread(&pixels[cury][curx], sizeof(PIXEL_DEF), 1, bmp))
{
curx++;
if (curx >= BITMAP_WIDTH)
{
// Rows padded to 4 bytes, so we may need to skip some data
fseek(bmp, 32 - curx * sizeof(PIXEL_DEF) % 32, SEEK_CUR);
curx = 0;
cury++;
}
}
fclose(bmp);
}
// Following assumes top-left to bottom-right order, you may need to change
void dump_bitmap()
{
int x, y;
printf("const uint8_t bitmap_data[] = {\n");
for (y=0; y < BITMAP_HEIGHT; y++)
{
for (x=0; x < BITMAP_WIDTH; x++)
{
if (x == 0)
printf("\t");
else
printf(",");
printf("0x%02X,0x%02X,0x%02X", pixels[y][x].R, pixels[y][x].G, pixels[y][x].B);
}
if (y < BITMAP_HEIGHT)
printf(",");
printf("\n");
}
printf("};\n");
}
int _tmain(int argc, TCHAR* argv[])
{
FILE *bmp;
if (argc != 2)
printf("Usage: BitMapConvert infile.bmp");
else {
if (bmp = _wfopen(argv[1], _T("rb")))
{
read_bitmap_data(bmp);
dump_bitmap();
}
}
return 0;
}
El mapa de bits de 10 x 10 que usé para las pruebas tiene el siguiente patrón.
La salida generada desde el programa anterior se incluyó al comienzo del siguiente pseudocódigo que es mi interpretación de la hoja de datos de cómo deben enviarse los datos al dispositivo. Los siguientes retrasos son en el modo de baja velocidad, use la mitad de los valores para alta velocidad (aunque el reinicio puede permanecer igual). El pin 7 está conectado a VDD para baja velocidad y se deja desconectado para alta velocidad, por lo que deberá verificar cómo está configurado su hardware. Si es posible, la velocidad baja será más fácil.
const uint8_t bitmap_data[] = {
0x00,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0xFF,0xFF,
0xFF,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0xFF,
0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,
0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,
0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,
0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,
0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,
0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0xFF,
0xFF,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,
0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,
};
void send_zero()
{
set_DI_high();
delay_us(0.5);
set_DI_low();
delay_us(2);
}
void send_one()
{
set_DI_high();
delay_us(1.2);
set_DI_low();
delay_us(1.3);
}
void send_reset()
{
set_DI_low();
delay_us(50);
set_DI_high();
}
void send_image()
{
uint8_t i;
send_reset();
for (i=0; i < sizeof(bitmap_data); i++)
{
if (bitmap_data[i] & 0x80) send_one() else send_zero();
if (bitmap_data[i] & 0x40) send_one() else send_zero();
if (bitmap_data[i] & 0x20) send_one() else send_zero();
if (bitmap_data[i] & 0x10) send_one() else send_zero();
if (bitmap_data[i] & 0x08) send_one() else send_zero();
if (bitmap_data[i] & 0x04) send_one() else send_zero();
if (bitmap_data[i] & 0x02) send_one() else send_zero();
if (bitmap_data[i] & 0x01) send_one() else send_zero();
}
}
Como puede ver, el protocolo no es SPI y uno de los desafíos será obtener el tiempo correcto dentro de +/- 150nS especificado en la hoja de datos, que es aproximadamente 1 ciclo a 8MHz. En lugar de utilizar cualquier forma de delay_us
, es probable que tenga que usar las instrucciones de nop
y tener en cuenta los retrasos de tiempo causados por la configuración de los puertos y las llamadas de función, etc. A veces, examinar la salida del compilador del compilador puede ser útil a ese respecto Y un alcance siempre es útil para verificarlo. La hoja de datos parece mostrar el mismo valor de 150 nS para los modos de velocidad alta y baja. Puede que esté en modo de baja velocidad, pero es un poco menos crítico en la práctica.
Habiendo dicho que acabo de ver la biblioteca FastSPI que mencionaste y menciona el soporte para ese dispositivo. Parece que usa el canal SPI de una manera no estándar (no es que haya ningún problema con eso) para ayudar a aliviar las restricciones de tiempo. Por lo tanto, un buen punto de partida sería intentar usarlo en combinación con la tabla de mapa de bits anterior.