Estoy luchando con mi primer microcontrolador AVR, AtTiny85, para que funcione con la conocida pantalla Nokia 5110. Escribí mi propio código para manejar la pantalla LCD, no funcionó. Luego probé un código que encontré en algún lugar de Internet, se suponía que debía manejar la pantalla, pero tampoco lo hizo. Pensé que mi pantalla estaba rota, pero la conecté a Raspberry Pi y ejecuté un script de Adafruit; funcionó sin problemas.
#include <avr/io.h>
#include <util/delay.h>
#define PIN_SCE PB0
#define PIN_RESET PB1
#define PIN_DC PB2
#define PIN_SCLK PB3
#define PIN_MOSI PB4
enum
{
FUNCTION_SET = 0x20,
FS_CHIP_POWERDOWN = 0x4,
FS_VERTICAL_ADDR = 0x2,
FS_EXTENDED_INSTR = 0x1,
DISPLAY_NORMAL = 0xc,
DISPLAY_BLANK = 0x8,
DISPLAY_ALL_ON = 0x9,
DISPLAY_INVERSE = 0xd,
DRAM_SET_X = 0x80,
DRAM_SET_Y = 0x40,
};
void BitTransfer(uint8_t Bits)
{
PORTB &= ~(1 << PIN_SCE);
int8_t i;
for(i = 7; i>=0; i--)
{
if((Bits >> i) & 1)
PORTB |= (1 << PIN_MOSI);
else
PORTB &= ~(1 << PIN_MOSI);
PORTB |= (1 << PIN_SCLK);
_delay_us(10);
PORTB &= ~(1 << PIN_SCLK);
_delay_us(10);
}
PORTB &= ~(1 << PIN_MOSI);
PORTB |= (1 << PIN_SCE);
}
void SendCommand(uint8_t Command)
{
PORTB &= ~(1 << PIN_DC);
BitTransfer(Command);
}
void SendData(uint8_t Data)
{
PORTB |= (1 << PIN_DC);
BitTransfer(Data);
}
int main(void)
{
DDRB |= (1 << PIN_SCE);
DDRB |= (1 << PIN_RESET);
DDRB |= (1 << PIN_DC);
DDRB |= (1 << PIN_SCLK);
DDRB |= (1 << PIN_MOSI);
PORTB = 0;
_delay_us(10);
PORTB |= (1 << PIN_RESET);
PORTB |= (1 << PIN_SCE);
_delay_us(10);
SendCommand(FUNCTION_SET | FS_EXTENDED_INSTR);
SendCommand(0xa5); // VOP
SendCommand(0x06); // temp coefficient
SendCommand(0x13); // BIAS
SendCommand(FUNCTION_SET);
SendCommand(DISPLAY_ALL_ON);
while(1)
{
}
return 0;
}
Enciendo mi AVR usando pinout de 3.3v de Raspberry Pi, lo mismo con la pantalla LCD. El AVR está trabajando a una frecuencia de 1 MHz. Cuando desconecto el enchufe que lleva a tierra, aparece una línea negra en la pantalla por un momento. No sé, ¿tal vez sea un problema de hardware?
¿son esos los mismos comandos que usaron los otros ejemplos de trabajo? Mis ejemplos de trabajo (este, el raspberry pi está manejando la pantalla) tienen algunos comandos/configuraciones más.
spi_command(0x21); //extended commands
// spi_command(0xB0); //vop
spi_command(0xBF); //vop
spi_command(0x04); //temp coef
spi_command(0x14); //bias mode 1:48
spi_command(0x20); //extended off
spi_command(0x0C); //display on
//experiment 1
if(1)
{
spi_command(0x80); //column
spi_command(0x40); //row
for(ra=0;ra<504;ra++) spi_data(ra);
}
Probablemente esté corriendo lo suficientemente lento como para no necesitar demoras, pero podría agregar un poco más, entre todo, básicamente, el cambio de D/C a la selección de spi al primer cambio de datos y así sucesivamente.
¿Tiene un alcance para examinar el autobús? Puede alimentar las señales a la frambuesa pi y muestrear muy rápido y guardar los datos para usarlos como un analizador lógico (el metal desnudo es más fácil/mejor, pero posiblemente también pueda hacerlo en Linux). O use cualquier otro microcontrolador siempre que sea más rápido de lo que cree que está golpeando un poco.
También puede poner luces LED en las líneas y hacer que los retrasos sean masivos, lo suficientemente lentos para que pueda ver visualmente qué está sucediendo y en qué orden.
Si la pantalla funciona cuando se usa el código comercial, pero no con el suyo, entonces claramente no es la pantalla. Es algo que su código está o no está haciendo. Es un objetivo spi bastante fácil de manipular, no se requiere volver a leer, solo disparar cosas.
Probablemente no tenga el almacenamiento en el microcontrolador, pero sí en el pi, también puede adoptar otro enfoque, tomar su código bit bang, simular el gpio y crear un archivo de registro de cada cambio de estado. Luego haga que el programa real simplemente los elimine. Al menos puedes ver visualmente
#include <stdio.h>
unsigned char port;
static void spi_delay ( void )
{
}
static void spi_dc ( unsigned int x )
{
if(x) port|=(1<<0);
else port&=~(1<<0);
printf("0x%02X,\n",port);
}
static void spi_cs ( unsigned int x )
{
if(x) port|=(1<<1);
else port&=~(1<<1);
printf("0x%02X,\n",port);
}
static void spi_clk ( unsigned int x )
{
if(x) port|=(1<<2);
else port&=~(1<<2);
printf("0x%02X,\n",port);
}
static void spi_mosi ( unsigned int x )
{
if(x) port|=(1<<3);
else port&=~(1<<3);
printf("0x%02X,\n",port);
}
static void spi_command ( unsigned int cmd )
{
unsigned int ra;
unsigned int rb;
spi_dc(0);
spi_cs(0);
spi_delay();
for(rb=cmd,ra=0;ra<8;ra++,rb<<=1)
{
spi_mosi((rb>>7)&1);
spi_delay();
spi_clk(1);
spi_delay();
spi_clk(0);
spi_delay();
}
spi_cs(1);
}
static void spi_data ( unsigned int data )
{
unsigned int ra;
unsigned int rb;
spi_dc(1);
spi_cs(0);
spi_delay();
for(rb=data,ra=0;ra<8;ra++,rb<<=1)
{
spi_mosi((rb>>7)&1);
spi_delay();
spi_clk(1);
spi_delay();
spi_clk(0);
spi_delay();
}
spi_cs(1);
}
int main ( void )
{
port=0;
spi_clk(0);
spi_data(0);
spi_cs(0);
spi_cs(1);
spi_command(0x21); //extended commands
...
para ese inicio y comando dando esta salida:
0x00,
0x01,
0x01,
0x01,
0x05,
0x01,
0x01,
0x05,
0x01,
0x01,
0x05,
0x01,
0x01,
0x05,
0x01,
0x01,
0x05,
0x01,
0x01,
0x05,
0x01,
0x01,
0x05,
0x01,
0x01,
0x05,
0x01,
0x03,
0x01,
0x03,
0x02,
0x00,
0x00,
0x04,
0x00,
0x00,
0x04,
0x00,
0x08,
0x0C,
0x08,
0x00,
0x04,
0x00,
0x00,
0x04,
0x00,
0x00,
0x04,
0x00,
0x00,
0x04,
0x00,
0x08,
0x0C,
0x08,
0x0A,
Tenga en cuenta que en el código tengo el bit 0 como D/C, el bit 1 es cs, el 2 es clk y el 3 mosi. no se restableció en este código, creo que este solo se restableció a la alimentación, puede ajustarlos fácilmente.
Puede tomar esa salida y luego introducirla en algún código que ejecute en el pi o el microcontrolador (si tiene espacio).
for(x=0;x<datalen;x++)
{
PORT = data[x];
delay();
}
Puede crear algunas herramientas para ver visualmente las formas de onda (recomiendo mirar el formato vcd muy simple y usar gtkwave). o incluso mejor, simplemente imprímalos como binarios y gire la cabeza hacia un lado.
Al menos puede tener la sensación de que tiene las cosas conectadas correctamente y que está golpeando bien, una vez que eso funciona, reemplaza las funciones de configuración/borrado para cada bit con acceso directo al gpio y mueve el código al microcontrolador. incluso puede escribirlo de manera que se compile en ambos sentidos con una capa de abstracción.
Si tiene un osciloscopio multicanal, puede ahorrarse mucho trabajo. Bit banging spi o i2c o mdio, etc., realmente necesita un alcance o necesita construir un analizador lógico a partir de un microcontrolador o algo así. Se prefiere el alcance, especialmente para cosas como i2c y mdio, donde puede ver cuándo los autobuses cambian de dirección y qué tan rápido/lento son los pull ups.
oscuro
Sam Gibson
Sam Gibson
usuario3366592
Sam Gibson
usuario3366592