TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Pchuqui_1 en 29 de Noviembre de 2021, 13:45:10

Título: LCD 128x64 / ST7565R
Publicado por: Pchuqui_1 en 29 de Noviembre de 2021, 13:45:10
Hola a todos.

Queria consultarles si tienen conocimiento donde puedo conseguir una libreria para CCS C  para un LCD SPI con controlador ST7565R. Lo busqué en el foro pero hay poca información al respecto.

Muchas gracias.

Saludos  a todos
Título: Re:LCD 128x64 / ST7565R
Publicado por: DominusDRR en 29 de Noviembre de 2021, 13:51:10
Hola a todos.

Queria consultarles si tienen conocimiento donde puedo conseguir una libreria para CCS C  para un LCD SPI con controlador ST7565R. Lo busqué en el foro pero hay poca información al respecto.

Muchas gracias.

Saludos  a todos

Podrías adaptar  este código con el  compilador que estas usando:

https://github.com/andygock/glcd/blob/master/controllers/ST7565R.c (https://github.com/andygock/glcd/blob/master/controllers/ST7565R.c)

Título: Re:LCD 128x64 / ST7565R
Publicado por: Pchuqui_1 en 29 de Noviembre de 2021, 14:21:32
Gracias Dominus por el aporte. Lo voy a intentar y voy subiendo los avances al foro. Asi lo tenemos todos (si logro hacerlo funcionar)  :oops:

Un abrazo
Título: Re:LCD 128x64 / ST7565R
Publicado por: DominusDRR en 29 de Noviembre de 2021, 14:38:47
Gracias Dominus por el aporte. Lo voy a intentar y voy subiendo los avances al foro. Asi lo tenemos todos (si logro hacerlo funcionar)  :oops:

Un abrazo

Respecto a las LCD gráficas monocromáticas es que si logras encontrar un ejemplo de sólo ponga un punto en las coordenadas X,Y. Lo demás eso solo adaptar las funciones de otras librerías.

Por ejemplo del PICC yo adapte sus librerías para una pantalla gráfica KS0107 que tiene un bus en paralelo para su control a una pantalla china (LM12832HCW) con comunicación SPI. Lo adapté (o podría decirse que copie las funciones) para el compilador XC32.
Título: Re:LCD 128x64 / ST7565R
Publicado por: Pchuqui_1 en 29 de Noviembre de 2021, 16:23:23
Lo máximo que legué hacer es usar dos LCD KS0107 en paralelo. Esas librerias las modifiqué para está función.
Pero con este controlador chino que hago referencia (ST7565R) nunca trabajé y lo tengo que sacar  :).

Salgo del trabajo, llego a casa y me pongo con el segundo trabajo... jajaj 
Título: Re:LCD 128x64 / ST7565R
Publicado por: Pchuqui_1 en 29 de Noviembre de 2021, 17:05:04
Encontré esta referencia también. Puede ser de utilidad a la hora  de anailizar. La comparto para no perderla.

https://asf.microchip.com/docs/latest/xmega.drivers.crc.example2.xmega_a3bu_xplained/html/group__st7565r__lcd__controller__group.html#ga26cd5aaf71339531a2dff6646b4572be
Título: Re:LCD 128x64 / ST7565R
Publicado por: AleSergi en 01 de Diciembre de 2021, 01:40:50
pregunta, éste lcd del que hablan, tiene modelo para simular en el Isis Proteus?, desde que versión?
Título: Re:LCD 128x64 / ST7565R
Publicado por: Pchuqui_1 en 02 de Diciembre de 2021, 01:26:47
Yo no puede encontrar ninguna libreria para simular en Proteus.  :5]

Ya voy a empezar a subir lo que tengo de la libreria para ccs c.

Saludos
Título: Re:LCD 128x64 / ST7565R
Publicado por: jonathanPIC888 en 03 de Diciembre de 2021, 23:53:23
Como estás Pchuqui_1,

Te comento, hace como 2 meses aproximadamente, me tocó tener que hacer una librería para el display ST7920. En su momento no encontré nada, tuve que ponerme a programar algo desde 0.

Mis pasos fueron los siguientes:

1 - Agarrar un arduino, conectar todo y probar la librería básica de control.
2 - Una vez funcionando, armé el mismo circuito con PIC.
3 - Me puse a copiar función por función, mirando cada tanto la hoja de datos por si algo se me pasaba por alto (más que nada por los tiempos entre comandos....)
4 - Probé las funciones básicas para el modo texto, que es escribir algo.
5 - Probé las funciones básicas para el modo gráfico, que es dibujar unos pixel.

Me habrá llevado un fin de semana intenso de trabajo, pero se puede.

Algo a tener en cuenta, para este tipo de cosas proteus no sirve, te va a tocar probar en físico.

Saludos !
Título: Re:LCD 128x64 / ST7565R
Publicado por: Pchuqui_1 en 07 de Diciembre de 2021, 19:53:02
Hola a todos. Pude avanzar un poco con la libreria y comparto los avances para saber sus opiniones. El programa se compiló y no arrojó ningún error, pero tengo dudas en los PASOS 11, 12 Y 13.

La idea es ir compilando de auna función a la vez, para trabajar en el funcionamiento.
En este caso comencé con la funcion de inicialización del Display "void glcd_init()".


El datasheet del controlador se puede descargar del siguiente link.
https://pdf1.alldatasheet.com/datasheet-pdf/view/326163/SITRONIX/ST7565R.html

La inicialzación del display sigue la secuencia descripta en la figura:

https://ibb.co/7kCfHwB (https://ibb.co/7kCfHwB)



#ifndef _ST7565_H_
#define _ST7565_H_

// Configuración pines SPI
#define GLCD_CS1 PIN_A5         // Selección de chip.
#define GLCD_RESET PIN_A2       // Si /RES =0 el registro seleccionado se limpia
#define GLCD_A0 PIN_A0          // A0 = 1: D0 a D7 se configuran como datos de visualización. A0 = 0: son pines de control
#define GLCD_SCL PIN_C3         // Pin de clock
#define GLCD_SDA PIN_C5         // Pin de data


#define SCREEN_WIDTH 128        // Ancho de pantalla
#define SCREEN_HEIGHT 64        // Largo pantalla


////////////////////////////////////COMANDOS//////////////////////////////////////////////////////////////////////////////////////////////

#define GLCD_CMD_DISPLAY_ON       0b10101111       // Encendemos el display
#define GLCD_CMD_DISPLAY_OFF      0b10101110       // Apagamos el display

#define GLCD_CMD_ALL_NORMAL       0b10100100       // Permite forzar todos los puntos del display en ON sin importar en contenido de la RAM. MODO NORMAL. El contenido de la RAM no se pierde.
#define GLCD_CMD_ALL_ON           0b10100101       // Permite forzar todos los puntos del display en ON sin importar en contenido de la RAM. MODO ON. El contenido de la RAM no se pierde.
// Cuando el dsiplay está OFF, ejecutando este el comando GLCD_CMD_ALL_ON el display se pondrá en modo SLEEP.

#define GLCD_CMD_DISPLAY_NORMAL    0b10100110      // Permite invertir la pantalla sin sobreescribir la memoria RAM. MODO NORMAL
#define GLCD_CMD_DISPLAY_REVERSE   0b10100111      // Permite invertir la pantalla sin sobreescribir la memoria RAM. MODO INVERTIDO


#define GLCD_CMD_BIAS_9            0b10100010      // Seleciona el voltaje requerido para el display. 1/9 th
#define GLCD_CMD_BIAS_7            0b10100011      // Seleciona el voltaje requerido para el display. 1/7 th

//Se revierte la correspondencia entre los datos de las columnas de la RAM y los segmentos de salida del driver.
//Se deberá usar la instrucció glcd_flip_screen para que el ancho se configure correctamente.
#define GLCD_CMD_HORIZONTAL_NORMAL   0b10100000     // MODO NORMAL
#define GLCD_CMD_HORIZONTAL_REVERSE   0b10100001    // MODO REVERSE

// Permite revertir la pantalla verticalmente.
#define GLCD_CMD_VERTICAL_NORMAL   0b11000000       // MODO NORMAL   
#define GLCD_CMD_VERTICAL_REVERSE  0b11001000       // MODO REVERSE

// Configura la fuente de alimentación. Tiene tres modos: 1) Booster circuits, 2) Voltage regulator, 3) Voltage follower cirtuits.
// Estos modos pueden ser usados independientente del uso del los comandos Power Control Set.
// Ver pag. 31 datasheet
#define GLCD_CMD_POWER_CONTROL      0b00101000      // Solo utiliza la fuente de alimentación externa


// Este comando configura el Vo= (1+Rb/Ra)*Vev. Puede ser utilizado para controlar por comandos (sin añadir resistencias externas) el brillo de la pantalla. Paguina 33/46 datasheet.
// Se utilizan 2 bytes para la configuración.
// El "Electronic Volume Set" se configura con "Electronic Volume Mode SET" y "Electronic Volume Register Set"
#define GLCD_CMD_RESISTOR         0b00100000       // 0b00000000 63   0b00111111 0. The "Electronic Volume Register SET"
#define GLCD_CMD_VOLUME_MODE      0b10000001       // The Electronic Volume Mode Set. Cuando se ingresa este comando se habilita el "Electronic Volume Set"

// Este comando se utiliza para especificar la posición de inicio en la memoria RAM. 0b01000000 posición 0. 0b01111111 posición 63
// Se puede utilizar para hacer screen srolling, page swapping. INTERESANTE  PAGUINA 26
#define GLCD_CMD_DISPLAY_START    0b01000000       // POSICIÓN 0

// Este comando especifica la dirección de la columna de los datos mostrados en RAM. La columna de direcciones se divide en dos secciones ( higher 4 bits y lower 4 bits). PAGUINA 42
#define GLCD_CMD_COLUMN_LOWER      0b00000000     // 0b00000000 Column address 0 0b10000011 Column address 131

#define GLCD_CMD_COLUMN_UPPER      0b00010000    // Se selecciona los 4 bits mas significantes de la columna.
#define GLCD_CMD_SET_PAGE          0b10110000     // Se selecciona la paguina actual (0..7))

// Este comando inicializa: la linea de inicio, la dirección de la columna, la dirección de la paguina, el Vo, el common output mode, the electronic volume y read/modify/write mode
// El test mode se libera
// No impacta en los datos de la RAM.
#define GLCD_CMD_RESET            0b11100010

// No realiza operación alguna. El datasheet suguiere enviar este comando periodicamente.
#define   GLCD_CMD_NOP            0b11100011
#endif // _ST7565_H_


/////////////////////////////////////////////////////////////////////////
// Funciones
/////////////////////////////////////////////////////////////////////////
void glcd_init();       // Inicializamos la pantalla. Tenemos que llamar a esta rutina primero
void glcd_command(char); // Enviamos un comando al Display. 
/////////////////////////////////////////////////////////////////////////


 // Inicialización del Display Pagina 51
   void glcd_init()
{

   output_low(GLCD_SCL);            // Initialize SCL
   output_low(GLCD_SDA);            // Initialize SD
   output_low(GLCD_CS1);            // Select the chip
   
   output_low(GLCD_RESET);                                                                  // PASO 1
   // Se estable 50 ms para estabilizar la tensión de alimentación.
   delay_ms(50);                                                                                   // PASO 2
   output_high(GLCD_RESET);                                                               // PASO 3

    // Según datasheet 1ms                                                                    // PASO 3
    delay_ms(1);                                                               

    // Se resetea el Display
     glcd_command(GLCD_CMD_RESET);                                              // PASO 4
     
     //0b10100010 // seleccionamos el voltaje requerido para el display         // PASO 5
     glcd_command(GLCD_CMD_BIAS_9);       
     
     // Modo Horizontal de la pantalla NORMAL
    glcd_command(GLCD_CMD_HORIZONTAL_NORMAL);    //0b10100000 //                // PASO 6
   
    // Modo Vertical de la pantall NORMAL
    glcd_command(GLCD_CMD_VERTICAL_REVERSE);    //0b11000000                    // PASO 7

    // Se selecciona el valor interno de resistencia. Por default usamos un valor medio 
    glcd_command(GLCD_CMD_RESISTOR | 0x3);      //  0b00100000                  // PASO 8

    // Volume set (brightness control).  A middle value is used here
    // also.
    glcd_command(GLCD_CMD_VOLUME_MODE | 0x31 );  //0b10000001                     // PASO 9
   
     // Solo utiliza la fuente de alimentación externa
     glcd_command(GLCD_CMD_POWER_CONTROL | 0x7); // 0b00101000                   //PASO 10
    //   DelayMs(10);

    // Posición de inicio en la memoria RAM.
    glcd_command(GLCD_CMD_DISPLAY_START);                                       // PASO 11

    // Encendemos el display
    glcd_command(GLCD_CMD_DISPLAY_ON);                                          // PASO 12

    // Deseleccionamos el chip
    output_high(GLCD_CS1);                                                      // PASO 13
}
   
 void glcd_command(char command) {
   int n;

   
    output_low(GLCD_A0);        // A0 low para que el dato enviado sea un comando

   
    output_low(GLCD_CS1);       // Necesario para seleccionar modo SPI

    for (n = 0; n < 8; n++) {

        if (command & 0x80) {       // Porque utiliza 0x80??
            output_high(GLCD_SDA);
        } else {
            output_low(GLCD_SDA);
        }
   
        // Pulse SCL
        output_high(GLCD_SCL);
        output_low(GLCD_SCL);

        command <<= 1;
    }

    // Unselect the chip
    output_high(GLCD_CS1);
}
Título: Re:LCD 128x64 / ST7565R
Publicado por: DominusDRR en 07 de Diciembre de 2021, 20:11:46
Código: C
  1. if (command & 0x80)  // Porque utiliza 0x80??
  2.    {      
  3.             output_high(GLCD_SDA);
  4.    }
  5.   else
  6.   {
  7.             output_low(GLCD_SDA);
  8.   }

Está utilizando un PIN como salida SPI:

EL primer bit que pone en el PIN es el 8 y mediante (command & 0x80) verificas si dicho bit es 1 ó 0, para escribir 1 o cero en SDA

Luego el bit 7 pasa al 8, el 6 al 7, etc mediante command <<= 1; es decir lo rotas a la izquierda una vez y repites de nuevo el if hasta enviar los 8 bits del byte de comando.

Claro que si tienes un módulo SPI en tu micro, es mucho mejor utilizar eso, pero para pruebas estaría bien por el momento.

Título: Re:LCD 128x64 / ST7565R
Publicado por: DominusDRR en 07 de Diciembre de 2021, 20:28:43
Código: C
  1. if (command & 0x80)  // Porque utiliza 0x80??
  2.    {      
  3.             output_high(GLCD_SDA);
  4.    }
  5.   else
  6.   {
  7.             output_low(GLCD_SDA);
  8.   }

Está utilizando un PIN como salida SPI:

EL primer bit que pone en el PIN es el 8 y mediante (command & 0x80) verificas si dicho bit es 1 ó 0, para escribir 1 o cero en SDA

Luego el bit 7 pasa al 8, el 6 al 7, etc mediante command <<= 1; es decir lo rotas a la izquierda una vez y repites de nuevo el if hasta enviar los 8 bits del byte de comando.

Claro que si tienes un módulo SPI en tu micro, es mucho mejor utilizar eso, pero para pruebas estaría bien por el momento.

Ha todo esto te falta una señal de reloj que de manera similar deberías ir poniendo en 1 y en 0 al ritmo de los bits que vas poniendo en SDA.
Título: Re:LCD 128x64 / ST7565R
Publicado por: Pchuqui_1 en 07 de Diciembre de 2021, 21:12:33
Hola DominusDRR. Gracias por la aclaración. Voy a tratar de desarrollar la librería para que se pueda utilizar tanto por software SPI y por hardware SPI.

Quedaría así  :?:

if (command & 0x80) 
   {     
            output_high(GLCD_SDA);
            output_high(GLCD_SCL);
   }
  else
  {
            output_low(GLCD_SDA);
            output_low(GLCD_SCL);
  }
Título: Re:LCD 128x64 / ST7565R
Publicado por: DominusDRR en 07 de Diciembre de 2021, 21:35:53
Hola DominusDRR. Gracias por la aclaración. Voy a tratar de desarrollar la librería para que se pueda utilizar tanto por software SPI y por hardware SPI.

Quedaría así  :?:

if (command & 0x80) 
   {     
            output_high(GLCD_SDA);
            output_high(GLCD_SCL);
   }
  else
  {
            output_low(GLCD_SDA);
            output_low(GLCD_SCL);
  }

Deberías conocer que modo de operación trabaja tu LCD, en SPi hay cuatro.

(https://aws1.discourse-cdn.com/arduino/original/4X/4/a/0/4a0f0eb9ff1f294710aec4f56b17016762163f9a.png)

Debería existir un retardo al crear la señal de reloj. Ahí le estás dando a toda la velocidad que puede ejecutar el microcontrolador. O sea la pregunta es: Sin retardos a que frecuencia es la señal de reloj.

Título: Re:LCD 128x64 / ST7565R
Publicado por: DominusDRR en 07 de Diciembre de 2021, 21:41:04
Hola DominusDRR. Gracias por la aclaración. Voy a tratar de desarrollar la librería para que se pueda utilizar tanto por software SPI y por hardware SPI.

Quedaría así  :?:

if (command & 0x80) 
   {     
            output_high(GLCD_SDA);
            output_high(GLCD_SCL);
   }
  else
  {
            output_low(GLCD_SDA);
            output_low(GLCD_SCL);
  }

Deberías conocer que modo de operación trabaja tu LCD, en SPi hay cuatro.

(https://aws1.discourse-cdn.com/arduino/original/4X/4/a/0/4a0f0eb9ff1f294710aec4f56b17016762163f9a.png)

Debería existir un retardo al crear la señal de reloj. Ahí le estás dando a toda la velocidad que puede ejecutar el microcontrolador. O sea la pregunta es: Sin retardos a que frecuencia es la señal de reloj.


Para uno de los modos de operación sería así:
Código: C
  1. output_low(GLCD_SCL); //reloj pasa a cero, debería estar inicialmente en 1
  2. if (command & 0x80)
  3. {    
  4.         output_high(GLCD_SDA);
  5.            
  6. }
  7. else
  8. {
  9.         output_low(GLCD_SDA);
  10. }
  11. delayUs(tiempoEnBajoReloj);
  12. output_high(GLCD_SCL); //reloj regresa a 1 lógico
  13. delayUs(tiempoEnAltoReloj);
  14. command <<= 1;
Título: Re:LCD 128x64 / ST7565R
Publicado por: Pchuqui_1 en 08 de Diciembre de 2021, 17:24:18
Gracias DominusDRR.

En la hoja de datos se muestra el diagrama:

https://ibb.co/Z8hCxpP (https://ibb.co/Z8hCxpP)

Por lo tanto utiliza el MODO 3. El código quedaría así:

void glcd_command(char command) {
   int n;

   
    output_low(GLCD_A0);       
    output_low(GLCD_CS1);       
    output_high(GLCD_SCK);
   
    for (n = 0; n < 8; n++) {
       
        output_low(GLCD_SCK);
        if (command & 0x80) {                             
            output_high(GLCD_SI);
        } else {
            output_low(GLCD_SI);
        }
   
       
        delayus(tiempobajoreloj);
        output_high(GLCD_SCK);     
        delayus(tiempaltoreloj);
        output_low(GLCD_SCK);

        command <<= 1;
    }

    // Unselect the chip
    output_high(GLCD_CS1);
}

Sin retardos en el código y suponiendo que tengo el micro corriendo a 20 Mhz la frecuencia del de la señal de reloj máxima quedaría: para 20 mhz--> 20/4=5 Mbps ----> 1/5 mhz=0,0000002 seg =0,2uS  por ciclo de instrucción. Si utilizo el SPI por hardware, podré alcanzar una mayor velocidad?

Otra duda que me surge, es la siguiente:
En la hoja de datos dice que este controlador, ST7565R, tiene dos terminales para la selección de chip. /CS1 y CS2. Cuando /CS1 =L y CS2 = H se habilita la recepción de datos. La cuestión con esto es que en el Display fisico solo se puede ver /CS, lo cual me hace suponer que CS2 está siempre con un estado lógico fijo.
Luego, como se muestra en el diagrama de arriba, habla que A0 se utiliza para determinar si los datos ingresados al display son, comandos o datos. Pero esté pin tampoco está fisicamente. Estoy tratando de ver a que se refieron los pin RES (supongo reset) y RS.  Los pines 10,11,12,13 ¿?

Esta es la imagen con los pines que tiene el display:

https://ibb.co/k1mwbYk (https://ibb.co/k1mwbYk)



Título: Re:LCD 128x64 / ST7565R
Publicado por: DominusDRR en 08 de Diciembre de 2021, 17:41:29

Sin retardos en el código y suponiendo que tengo el micro corriendo a 20 Mhz la frecuencia del de la señal de reloj máxima quedaría: para 20 mhz--> 20/4=5 Mbps ----> 1/5 mhz=0,0000002 seg =0,2uS  por ciclo de instrucción. Si utilizo el SPI por hardware, podré alcanzar una mayor velocidad?


Esos cálculos son si trabajaras en ensamblador, en C puede que cada línea de código se ejecute en más de 2 líneas en ensamblador dependiendo del nivel de optimización.

Respecto a la velocidad eso deberías consultarlo en las hoja de datos de tu microcontrolador, siempre hay una ecuación que te permite hallar ese valor en función del oscilador (o bus de reloj de los periféricos)

También no deberías trabajar a una velocidad mayor a la máxima que el fabricante de la pantalla debe proporcionar en la información técnica. Mientras la pantalla no esté muy lejos del MCU, podrías trabajar a la máxima velocidad.


Luego, como se muestra en el diagrama de arriba, habla que A0 se utiliza para determinar si los datos ingresados al display son, comandos o datos. Pero esté pin tampoco está fisicamente. Estoy tratando de ver a que se refieron los pin RES (supongo reset) y RS.  Los pines 10,11,12,13 ¿?


Debes googlear un poco más y sobre todo en Inglés:

Citar
A0 - sometiimes called RS

Fuente:

https://www.ladyada.net/learn/lcd/st7565.html (https://www.ladyada.net/learn/lcd/st7565.html)
Título: Re:LCD 128x64 / ST7565R
Publicado por: DominusDRR en 08 de Diciembre de 2021, 18:08:41
Otra duda que me surge, es la siguiente:
En la hoja de datos dice que este controlador, ST7565R, tiene dos terminales para la selección de chip. /CS1 y CS2. Cuando /CS1 =L y CS2 = H se habilita la recepción de datos. La cuestión con esto es que en el Display fisico solo se puede ver /CS, lo cual me hace suponer que CS2 está siempre con un estado lógico fijo.

No debes tanto fijarte en el controlador, sino en la pantalla.

El controlador posiblemente está diseñado para manejar pantallas de mayor resolución que 128x64 y por esa razón tiene dos CS. Y como tu dices por defecto debe estar deshabilitado.
Título: Re:LCD 128x64 / ST7565R
Publicado por: Pchuqui_1 en 08 de Diciembre de 2021, 19:41:29
Gracias DominusDRR! Voy a empezar con las pruebas de voy posteando los resultados. Créeme que busque mucho por google, no sé como diste con esa pagina... jajaja  ((:-))
Título: Re:LCD 128x64 / ST7565R
Publicado por: Pchuqui_1 en 09 de Diciembre de 2021, 21:07:12
Hola otra ves,  :-/

Parte del código que estoy terminando para esta librería, tiene la siguiente función. pgm_read_byte();. Se suponia que el codigo estaba escrito en C y esto parece ser una instrucción de ardruino..  :lol: Lo que pude ver es que esta instrucción funciona como macro que lee una palabra guardada en una posición de memoria.  El código es el siguiente:

void drawchar(int8 x, int8 line, char c){
  for (int8 i =0; i<5; i++ ) {
    buffer[x + (line*128) ] = pgm_read_byte(font+(c*5)+i);
    x++;
  }
}

Mi idea es utilizar la función strcpy para reemplazarla. Esta función se utiliza para copiar una cadena de caracteres (fuente) en el lugar que ocupaba otra (destino). Pero no estoy seguro:

void drawchar(int8 x, int8 line, char c){
  for (int8 i =0; i<5; i++ ) {
    buffer[x + (line*128) ] = strcpy (font, (c*5) + i);
    x++;
  }
}



Título: Re:LCD 128x64 / ST7565R
Publicado por: Pchuqui_1 en 09 de Diciembre de 2021, 23:30:01
Creo que no se está inicializando correctamente. Tengo que buscar si hay alguna flag que me indique que el display se inicializó correctamente.
Título: Re:LCD 128x64 / ST7565R
Publicado por: DominusDRR en 10 de Diciembre de 2021, 09:28:16
Hola otra ves,  :-/

Parte del código que estoy terminando para esta librería, tiene la siguiente función. pgm_read_byte();. Se suponia que el codigo estaba escrito en C y esto parece ser una instrucción de ardruino..  :lol: Lo que pude ver es que esta instrucción funciona como macro que lee una palabra guardada en una posición de memoria.  El código es el siguiente:

void drawchar(int8 x, int8 line, char c){
  for (int8 i =0; i<5; i++ ) {
    buffer[x + (line*128) ] = pgm_read_byte(font+(c*5)+i);
    x++;
  }
}

Mi idea es utilizar la función strcpy para reemplazarla. Esta función se utiliza para copiar una cadena de caracteres (fuente) en el lugar que ocupaba otra (destino). Pero no estoy seguro:

void drawchar(int8 x, int8 line, char c){
  for (int8 i =0; i<5; i++ ) {
    buffer[x + (line*128) ] = strcpy (font, (c*5) + i);
    x++;
  }
}

Esa pregunta deberías, creo hacer la pregunta en el foro de Arduino, o esperar que alguien que conozca un poco más del tema.

Según leí,  pgm_read_word lee el dato del parámetro (dirección) de la función.

En este caso font+(c*5) sería la dirección,  a la cual se incrementa con i

¿Pero la pregunta es dirección de donde? (RAM, Flash)?

Y lo que retorna es una palabra (16 ó 32 bits?)

Deberías buscar en el ejemplo de Arduino donde se utiliza esto font+(c*5), pueda que sea un array.

Como te dije al inicio, podrías hacer un simple ejemplo para poner un punto en las coordenadas x, y de la LCD y luego podrías adaptar las funciones para la pantalla KS0107 de CCS.
Título: Re:LCD 128x64 / ST7565R
Publicado por: Pchuqui_1 en 10 de Diciembre de 2021, 15:11:01
En el manejo del display crearon un buffer "static int8 buffer[1024]" que según entiendo se utiliza para alojar los datos de la RAM del display. "The display data RAM stores the dot data for the LCD. It has a 65 (8 page x 8 bit +1) x 132 bit structure". Y por otro lado crearon un array "int8 font[]" de mayor tamaño que el buffer.
En esa instrucción creo que están copiando datos de un array a otro.

 :lol: :lol:
Título: Re:LCD 128x64 / ST7565R
Publicado por: Pchuqui_1 en 10 de Diciembre de 2021, 15:13:56
Voy a seguir tu consejo de escribir una simple coordenada en el Display, haber si puedo lograrlo.

Ya voy subiendo mas avances. Tengo que encender esta cosa..  :lol:
Título: Re:LCD 128x64 / ST7565R
Publicado por: DominusDRR en 10 de Diciembre de 2021, 16:01:34
Voy a seguir tu consejo de escribir una simple coordenada en el Display, haber si puedo lograrlo.

Ya voy subiendo mas avances. Tengo que encender esta cosa..  :lol:


Si tomas de ejemplo el código de la KS0107, recuerda que ahí muchas veces se necesita leer un byte desde la pantalla, pero en este caso sólo puedes escribir (sólo tienes SDI y no SDO).

Es por eso que todo hacen en un buffer o arreglo en la RAM del MCU y cuando terminas de hacer cualquier proceso, envías ese buffer a la LCD.
Título: Re:LCD 128x64 / ST7565R
Publicado por: Pchuqui_1 en 11 de Diciembre de 2021, 22:06:48
Estoy empezando otra vez, repasando todo porque no logro inicializar el display.

Con respecto a la comunicación estoy capturando los datos del clock y data para ver como están sincronizados. El dato que estoy enviando al PIC es 0b10100011. Como puede verse en la imagen el byte está presente en el pin GLCD_SI y el clock también. Ustedes ven algo mal con respecto a esto? (quiero descartar que no sea un problema de comunicación).  El código para esto lo listo abajo.

El programa ingresa a glcd_init(); y luego ejecuta el primer comando que es el que se ve en la foto.

img (https://i.ibb.co/LYZ6pb8/Whats-App-Image-2021-12-11-at-21-42-59.jpg) (https://ibb.co/BcCjsdt) /img


#include <18F46K20.h>                                 //pic a utilizar                 

#fuses HS,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,NOPBADEN // el fuse
#use delay(clock=4000000)

#use STANDARD_IO(B)
#use STANDARD_IO(C)
#use STANDARD_IO(D)
#use STANDARD_IO(E)

#include "ST7565R_1.h"


void main(void)
{
   
output_high(GLCD_CS);       // Seleccionamos el chip   
output_high(GLCD_SCK);     // Reloj en alto
   
glcd_init();
glcd_command(GLCD_CMD_DISPLAY_ON);
glcd_command(GLCD_CMD_ALL_NORMAL);
glcd_contrast(0x5);
   


do{
    setpixel(20, 20, WHITE);
    display();
 

}while(true);

}


void glcd_init()
{   
   output_low(GLCD_CS);            // Select the chip
   
   output_low(GLCD_RESET);                                                      // PASO 1
   // Se estable 50 ms para estabilizar la tensión de alimentación.
   delay_ms(500);                                                                // PASO 2
   output_high(GLCD_RESET);                                                     // PASO 3
                                                               
     //0b10100010 // seleccionamos el voltaje requerido para el display         // PASO 5
     glcd_command(GLCD_CMD_BIAS_7);       
     
     // Modo Horizontal de la pantalla NORMAL
    glcd_command(GLCD_CMD_HORIZONTAL_NORMAL);    //0b10100000 //                // PASO 6
   
    // Modo Vertical de la pantall NORMAL
    glcd_command(GLCD_CMD_VERTICAL_NORMAL);    //0b11000000                    // PASO 7
   
     // Posición de inicio en la memoria RAM.
    glcd_command(GLCD_CMD_DISPLAY_START);      //0b10000000
   
    // Solo utiliza la fuente de alimentación externa. Turn on voltage converter (VC=1,VR=0,VF=0)
    glcd_command(GLCD_CMD_POWER_CONTROL | 0x4); // 0b00101000   
         delay_ms(50);
    // Solo utiliza la fuente de alimentación externa. Turn on voltage converter (VC=1,VR=1,VF=0)     
    glcd_command(GLCD_CMD_POWER_CONTROL | 0x6); // 0b00101000   
         delay_ms(50);
    // Solo utiliza la fuente de alimentación externa. Turn on voltage converter (VC=1,VR=1,VF=0)     
    glcd_command(GLCD_CMD_POWER_CONTROL | 0x7); // 0b00101000   
         delay_ms(10);
         
    // Se selecciona el valor interno de resistencia. Por default usamos un valor medio 
    glcd_command(CMD_SET_RESISTOR_RATIO | 0x6);      //  0b00100000                                                                     

    output_high(GLCD_CS);

   }


void glcd_command(char command) {
   int n;

   output_low(GLCD_RS);        // A0 low para que el dato enviado sea un comando
   delay_us(5);
   output_low(GLCD_CS);       // Seleccionamos el chip
   delay_us(5);
   
   // output_high(GLCD_SCK);
   
       
       
        if (command & 0x80) {                           //Si la comparación es 1 se pone GLCD_SDA a 1 lógico, Si es 0 GLCD_SDA se pone a 0.       
            output_high(GLCD_SI);  // Pin de datos   
        } else {
            output_low(GLCD_SI);
        }
   
        output_low(GLCD_SCK);
        delay_us(100);
        output_high(GLCD_SCK);      // Reloj regresa a 1
        delay_us(50);
       
        command <<= 1;
    }

    // Unselect the chip
    output_high(GLCD_CS);
   
 }
Título: Re:LCD 128x64 / ST7565R
Publicado por: DominusDRR en 11 de Diciembre de 2021, 22:15:48
Estoy empezando otra vez, repasando todo porque no logro inicializar el display.

Con respecto a la comunicación estoy capturando los datos del clock y data para ver como están sincronizados. El dato que estoy enviando al PIC es 0b10100011. Como puede verse en la imagen el byte está presente en el pin GLCD_SI y el clock también. Ustedes ven algo mal con respecto a esto? (quiero descartar que no sea un problema de comunicación).  El código para esto lo listo abajo.

El programa ingresa a glcd_init(); y luego ejecuta el primer comando que es el que se ve en la foto.

img (https://i.ibb.co/LYZ6pb8/Whats-App-Image-2021-12-11-at-21-42-59.jpg) (https://ibb.co/BcCjsdt) /img


#include <18F46K20.h>                                 //pic a utilizar                 

#fuses HS,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,NOPBADEN // el fuse
#use delay(clock=4000000)

#use STANDARD_IO(B)
#use STANDARD_IO(C)
#use STANDARD_IO(D)
#use STANDARD_IO(E)

#include "ST7565R_1.h"


void main(void)
{
   
output_high(GLCD_CS);       // Seleccionamos el chip   
output_high(GLCD_SCK);     // Reloj en alto
   
glcd_init();
glcd_command(GLCD_CMD_DISPLAY_ON);
glcd_command(GLCD_CMD_ALL_NORMAL);
glcd_contrast(0x5);
   


do{
    setpixel(20, 20, WHITE);
    display();
 

}while(true);

}


void glcd_init()
{   
   output_low(GLCD_CS);            // Select the chip
   
   output_low(GLCD_RESET);                                                      // PASO 1
   // Se estable 50 ms para estabilizar la tensión de alimentación.
   delay_ms(500);                                                                // PASO 2
   output_high(GLCD_RESET);                                                     // PASO 3
                                                               
     //0b10100010 // seleccionamos el voltaje requerido para el display         // PASO 5
     glcd_command(GLCD_CMD_BIAS_7);       
     
     // Modo Horizontal de la pantalla NORMAL
    glcd_command(GLCD_CMD_HORIZONTAL_NORMAL);    //0b10100000 //                // PASO 6
   
    // Modo Vertical de la pantall NORMAL
    glcd_command(GLCD_CMD_VERTICAL_NORMAL);    //0b11000000                    // PASO 7
   
     // Posición de inicio en la memoria RAM.
    glcd_command(GLCD_CMD_DISPLAY_START);      //0b10000000
   
    // Solo utiliza la fuente de alimentación externa. Turn on voltage converter (VC=1,VR=0,VF=0)
    glcd_command(GLCD_CMD_POWER_CONTROL | 0x4); // 0b00101000   
         delay_ms(50);
    // Solo utiliza la fuente de alimentación externa. Turn on voltage converter (VC=1,VR=1,VF=0)     
    glcd_command(GLCD_CMD_POWER_CONTROL | 0x6); // 0b00101000   
         delay_ms(50);
    // Solo utiliza la fuente de alimentación externa. Turn on voltage converter (VC=1,VR=1,VF=0)     
    glcd_command(GLCD_CMD_POWER_CONTROL | 0x7); // 0b00101000   
         delay_ms(10);
         
    // Se selecciona el valor interno de resistencia. Por default usamos un valor medio 
    glcd_command(CMD_SET_RESISTOR_RATIO | 0x6);      //  0b00100000                                                                     

    output_high(GLCD_CS);

   }


void glcd_command(char command) {
   int n;

   output_low(GLCD_RS);        // A0 low para que el dato enviado sea un comando
   delay_us(5);
   output_low(GLCD_CS);       // Seleccionamos el chip
   delay_us(5);
   
   // output_high(GLCD_SCK);
   
       
       
        if (command & 0x80) {                           //Si la comparación es 1 se pone GLCD_SDA a 1 lógico, Si es 0 GLCD_SDA se pone a 0.       
            output_high(GLCD_SI);  // Pin de datos   
        } else {
            output_low(GLCD_SI);
        }
   
        output_low(GLCD_SCK);
        delay_us(100);
        output_high(GLCD_SCK);      // Reloj regresa a 1
        delay_us(50);
       
        command <<= 1;
    }

    // Unselect the chip
    output_high(GLCD_CS);
   
 }

Me parece que te falta un pulso más en el reloj.

¿A qué comando corresponde  0b10100011?

¿Las líneas de CS y Reset también están bien? Es decir deberías revisarlas junto al reloj (o datos) con el scope
Título: Re:LCD 128x64 / ST7565R
Publicado por: DominusDRR en 11 de Diciembre de 2021, 22:18:49

Me parece que te falta un pulso más en el reloj.


Me retracto, parece que es correcto 7 pulsos en el reloj.
Título: Re:LCD 128x64 / ST7565R
Publicado por: DominusDRR en 11 de Diciembre de 2021, 22:32:16

img (https://i.ibb.co/LYZ6pb8/Whats-App-Image-2021-12-11-at-21-42-59.jpg) (https://ibb.co/BcCjsdt) /img


Ya noté algo mal en la imagen de los datos y el reloj.

Los datos está inicialmente en 0, cuando ya mandas el dato, al finalizar permanece en 1 lógico.

La línea o pin de datos, cuando no se está transmitiendo, esta en reposo o modo idle, esto implica que debe estar en cero o en 1 lógico, dependiendo del modo SPI que estás trabajando.

Y me parece que en el modo que lo necesitas, debe estar en 1 lógico.

Título: Re:LCD 128x64 / ST7565R
Publicado por: DominusDRR en 11 de Diciembre de 2021, 22:53:58
Estoy empezando otra vez, repasando todo porque no logro inicializar el display.

Con respecto a la comunicación estoy capturando los datos del clock y data para ver como están sincronizados. El dato que estoy enviando al PIC es 0b10100011. Como puede verse en la imagen el byte está presente en el pin GLCD_SI y el clock también. Ustedes ven algo mal con respecto a esto? (quiero descartar que no sea un problema de comunicación).  El código para esto lo listo abajo.

El programa ingresa a glcd_init(); y luego ejecuta el primer comando que es el que se ve en la foto.

img (https://i.ibb.co/LYZ6pb8/Whats-App-Image-2021-12-11-at-21-42-59.jpg) (https://ibb.co/BcCjsdt) /img


#include <18F46K20.h>                                 //pic a utilizar                 

#fuses HS,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,NOPBADEN // el fuse
#use delay(clock=4000000)

#use STANDARD_IO(B)
#use STANDARD_IO(C)
#use STANDARD_IO(D)
#use STANDARD_IO(E)

#include "ST7565R_1.h"


void main(void)
{
   
output_high(GLCD_CS);       // Seleccionamos el chip   
output_high(GLCD_SCK);     // Reloj en alto
   
glcd_init();
glcd_command(GLCD_CMD_DISPLAY_ON);
glcd_command(GLCD_CMD_ALL_NORMAL);
glcd_contrast(0x5);
   


do{
    setpixel(20, 20, WHITE);
    display();
 

}while(true);

}


void glcd_init()
{   
   output_low(GLCD_CS);            // Select the chip
   
   output_low(GLCD_RESET);                                                      // PASO 1
   // Se estable 50 ms para estabilizar la tensión de alimentación.
   delay_ms(500);                                                                // PASO 2
   output_high(GLCD_RESET);                                                     // PASO 3
                                                               
     //0b10100010 // seleccionamos el voltaje requerido para el display         // PASO 5
     glcd_command(GLCD_CMD_BIAS_7);       
     
     // Modo Horizontal de la pantalla NORMAL
    glcd_command(GLCD_CMD_HORIZONTAL_NORMAL);    //0b10100000 //                // PASO 6
   
    // Modo Vertical de la pantall NORMAL
    glcd_command(GLCD_CMD_VERTICAL_NORMAL);    //0b11000000                    // PASO 7
   
     // Posición de inicio en la memoria RAM.
    glcd_command(GLCD_CMD_DISPLAY_START);      //0b10000000
   
    // Solo utiliza la fuente de alimentación externa. Turn on voltage converter (VC=1,VR=0,VF=0)
    glcd_command(GLCD_CMD_POWER_CONTROL | 0x4); // 0b00101000   
         delay_ms(50);
    // Solo utiliza la fuente de alimentación externa. Turn on voltage converter (VC=1,VR=1,VF=0)     
    glcd_command(GLCD_CMD_POWER_CONTROL | 0x6); // 0b00101000   
         delay_ms(50);
    // Solo utiliza la fuente de alimentación externa. Turn on voltage converter (VC=1,VR=1,VF=0)     
    glcd_command(GLCD_CMD_POWER_CONTROL | 0x7); // 0b00101000   
         delay_ms(10);
         
    // Se selecciona el valor interno de resistencia. Por default usamos un valor medio 
    glcd_command(CMD_SET_RESISTOR_RATIO | 0x6);      //  0b00100000                                                                     

    output_high(GLCD_CS);

   }


void glcd_command(char command) {
   int n;

   output_low(GLCD_RS);        // A0 low para que el dato enviado sea un comando
   delay_us(5);
   output_low(GLCD_CS);       // Seleccionamos el chip
   delay_us(5);
   
   // output_high(GLCD_SCK);
   
       
       
        if (command & 0x80) {                           //Si la comparación es 1 se pone GLCD_SDA a 1 lógico, Si es 0 GLCD_SDA se pone a 0.       
            output_high(GLCD_SI);  // Pin de datos   
        } else {
            output_low(GLCD_SI);
        }
   
        output_low(GLCD_SCK);
        delay_us(100);
        output_high(GLCD_SCK);      // Reloj regresa a 1
        delay_us(50);
       
        command <<= 1;
    }

    // Unselect the chip
    output_high(GLCD_CS);
   
 }

También me parece mal como reinicias a la LCD.

O sea CS, RESET y A1 deben pasar a 1 lógico.

esperar un tiempo, por ejemplo 1 ms

RESET pasar a 0 lógico

esperar un tiempo (500ms me parece exagerado)


RESET pasar a 1 lógico

esperar 10 ms (según las hojas de datos del controlador de la LCD)

Y ahí empiezas a enviar los comandos de configuración de la LCD.



Título: Re:LCD 128x64 / ST7565R
Publicado por: Pchuqui_1 en 13 de Diciembre de 2021, 21:54:22
El dato que está representado en el diagrama es el 0b10100011. Es el primero en la rutina de inicialización. No coincide porque cuando tomé la foto lo cambié. Lo importante es que se represente envíe correctamente en este caso.

Estoy pensando en utilizar las instrucciones de SPI de CCS C por software para hacer la comunicación  y evitar estos tipos de errores. Que opinan?

Gracias.
Título: Re:LCD 128x64 / ST7565R
Publicado por: DominusDRR en 13 de Diciembre de 2021, 22:13:08
El dato que está representado en el diagrama es el 0b10100011. Es el primero en la rutina de inicialización. No coincide porque cuando tomé la foto lo cambié. Lo importante es que se represente envíe correctamente en este caso.

Estoy pensando en utilizar las instrucciones de SPI de CCS C por software para hacer la comunicación  y evitar estos tipos de errores. Que opinan?

Gracias.

Puede ser, pero para mi estás haciendo mal la configuración.

Intenta esto a ver que sucede:

Código: C
  1. void Confi_LCDG(void)
  2. {
  3.      CS  = 1;
  4.     RST = 1;
  5.     A0  = 1;
  6.     DelayMs(1);
  7.     RST = 0;
  8.     DelayMs(1);
  9.     RST = 1;
  10.     DelayMs(10);
  11.     SdCmd(0xaf);            // display on
  12.     SdCmd(0x40);            // display start line=0
  13.     SdCmd(0xa1);            // ADC=1
  14.     SdCmd(0xa6);            // normal display
  15.     SdCmd(0xa4);            // Display all point = off
  16.     SdCmd(0xa2);            // LCD bias = 1/9
  17.     SdCmd(0xc0);            // Common output mode select= reverse
  18.     SdCmd(0x2f);            // Power control = all on
  19.     SdCmd(0x25);            // RA/RB setting
  20.     SdCmd(0xf8);SdCmd(0x00);// Booster Ratio Set= 2x,3x,4x (2byte command)
  21.     SdCmd(0x81);            // E-Vol setting
  22.     SdCmd(0x21);   // (2byte command)
  23.  
  24. }


Código: C
  1. unsigned char LCDRAM[8][128];
  2.  
  3. void LimpiarLCD(unsigned char DesdeDonde)
  4. {
  5.     unsigned char i;
  6.     unsigned char j;
  7.     //Confi_LCDG();
  8.     for(i = DesdeDonde; i < 8;i++)
  9.     {
  10.         //LCD_Instrucciones(i); // LCD lista para instrucciones
  11.         SdCmd(0xb0 | i);    // select page 0~7
  12.         SdCmd(0x10);        // start form column 0
  13.         SdCmd(0x00);        // (2byte command)
  14.  
  15.         for(j = 0; j < 128; ++j)
  16.         {
  17.             SdData(0);//LCD_ESCRIBIR(0,SicoyLogo[s++]); // Los pixeles encendidos a OFF
  18.             LCDRAM[i][j] = 0;
  19.  
  20.         }
  21.     }
  22.  
  23. }

Código: C
  1. const unsigned char DOSENE [8] = { 1,2,4,8,16,32,64,128};
  2.  
  3. void PUNTO_LCD(unsigned char x, unsigned char y,unsigned char color)
  4. {
  5.     unsigned char data;
  6.     //unsigned char xl;
  7.     //unsigned char xh;
  8.     unsigned char auxi;          //  Yo creo este auxiliar ya que no existe la función bit_set de PICC
  9.  
  10.     /*xl = x & 0x0F;
  11.     xh = x & 0xF0;
  12.     xh = (xh >> 4);*/
  13.     //xh &= 0x0F;
  14.  
  15.     //auxi =DOSENE[ y%8];
  16.     //auxi =
  17.     //EncenderLED(y58)
  18.  
  19.     data = LCDRAM[y/8][x]; // primero lee el dato de la RAM
  20.     auxi = DOSENE[ y%8];  //equivale a 2 elevado a la y
  21.  
  22.     /*LCDRAM[i][j] = 0;
  23.  
  24.     SdCmd(0xb0 | y/8); // coordenada y
  25.  
  26.     SdCmd(0x10 | xh);// coordenada x
  27.     SdCmd(xl);*/
  28.  
  29.     if (color)
  30.         data = data  |  auxi;   // enciendo los pixeles
  31.     else
  32.         data = data & (~auxi);  // data = data NAND auxi
  33.  
  34.     LCDRAM[y/8][x] = data;

Código: C
  1. void Transferir_LCDRAM_LCD(void)
  2. {
  3.     unsigned char i;
  4.     unsigned char j;
  5.     //INTDisableInterrupts();
  6.     //Banderas.TransfiriendoInfoRamAGLCD = 1;
  7.     ConfiguracionPorDefectoGLCD();// Para que arregle cualquier cosa en la GLCD
  8.     for(i = 0; i < 8; ++i)
  9.     {
  10.         //LCD_Instrucciones(i); // LCD lista para instrucciones
  11.         SdCmd(0xb0 | i);    // select page 0~7
  12.         SdCmd(0x10);        // start form column 0
  13.         SdCmd(0x00);        // (2byte command)
  14.         for(j = 0; j < 128; ++j) SdData(LCDRAM[i][j]);//LCD_ESCRIBIR(0,solintecelogo[s++]); // Los pixeles encendidos a OFF
  15.     }
  16.     DelayUs(150);
  17.     //Banderas.TransfiriendoInfoRamAGLCD = 0;
  18.     //INTEnableInterrupts();
  19. }

Código: C
  1. void main
  2. {
  3.     Confi_LCDG();
  4.     LimpiarLCD(0x00);
  5.     PUNTO_LCD(10,10,0x01); // pongo un punto en x = 10 et y = 10.
  6.     Transferir_LCDRAM_LCD(); // pasa el areglo LCDRAM a la LCD.
  7.     while(true);
  8. }
Título: Re:LCD 128x64 / ST7565R
Publicado por: Pchuqui_1 en 16 de Diciembre de 2021, 23:41:26
Hola DominusDRR. Gracias por la ayuda.
Probé el código que me pasaste y el display no se inicializa.  En el código de la función de inicialización que subiste, lo escribiste teniendo en cuenta los pasos sugeridos por el datasheet?   
Título: Re:LCD 128x64 / ST7565R
Publicado por: DominusDRR en 17 de Diciembre de 2021, 09:41:49
Hola DominusDRR. Gracias por la ayuda.
Probé el código que me pasaste y el display no se inicializa.  En el código de la función de inicialización que subiste, lo escribiste teniendo en cuenta los pasos sugeridos por el datasheet?

Como mencioné antes, trabajé en una empresa donde fabricaban un producto con una LCD de bus paralelo, luego se migró a una LCD serial SPI (LM6063AFW). El fabricante nos proporcionó un pseudocódigo de ejemplo similar al tuyo donde emulaban un SPI en los pines de un microcontrolador cualquiera y graficaba el logo de su empresa.

Luego en base a los códigos ejemplos de CCS yo lo adapte para C32 (Ya que trabajaba con el PIC32MX)

Ya es casi diez años de eso y no encontraba el código, pensé que lo había perdido, pero al fin encontré una parte y lo compartí.

No se si es el mismos driver, pero lo que si te puedo decir es que al inicio tuve problemas, no funcionaba nada y era debido a un incorrecto uso del bus SPI. En mi caso no era el modo correcto (De los 4 que pueden ser con SPI) y también la frecuencia del reloj. La pantalla creo que trabaja a máximo 10MHZ y estaba utilizando 20MHz (me parce) luego use 8MHz.


Título: Re:LCD 128x64 / ST7565R
Publicado por: Pchuqui_1 en 19 de Diciembre de 2021, 18:54:09
Muchas gracias por tu aporte.  Yo te consultaba porque comparé las rutinas con el datasheet y hay algunas diferencias. De todas formas, el mismo datasheet dice que ellos recomiendan inicializarlo de esa forma, lo que entiendo que significa que puede haber otras..  :shock:

Con respecto a la comunicación, ahora estoy usando #use  spi para descartar posibles problemas en la comunicación. El micro que estoy utilizando es un 18F46K20 y lo estoy corriendo a 4 Mhz. Las rutinas de escritura de commando y data quedarón así:

Código: C
  1. #use spi(MASTER, CLK=PIN_D0, DO=PIN_D1,FORCE_SW, MODE=3, BITS=8,stream=BUSSPI)
  2.  
  3. void glcd_command(char command) {
  4.    //int n;
  5.  
  6.    output_low(GLCD_RS);        // A0 low para que el dato enviado sea un comando
  7.    delay_us(5);
  8.    output_low(GLCD_CS);       // Seleccionamos el chip
  9.    delay_us(5);
  10.    
  11.    spi_xfer(BUSSPI,command);
  12.    
  13.    utput_high(GLCD_CS);
  14. }
  15.  
  16. void glcd_data(unsigned char data) {
  17.  
  18. output_high(GLCD_RS);        // A0 HIGH para que el dato enviado sea un data
  19.    delay_us(5);
  20.    output_low(GLCD_CS);       // Seleccionamos el chip
  21.    delay_us(5);
  22.  
  23.    
  24.     spi_xfer(BUSSPI,data);
  25.    
  26.     // Unselect the chip
  27.     output_high(GLCD_CS);
  28.  
  29. }
Título: Re:LCD 128x64 / ST7565R
Publicado por: DominusDRR en 19 de Diciembre de 2021, 19:12:20
Muchas gracias por tu aporte.  Yo te consultaba porque comparé las rutinas con el datasheet y hay algunas diferencias. De todas formas, el mismo datasheet dice que ellos recomiendan inicializarlo de esa forma, lo que entiendo que significa que puede haber otras..  :shock:


O sea la configuración es esa porque vas a trabajar con 128x64 pixeles (Recuerda que tu mismo indicabas que el driver había otro CS y es para pantallas de mayor resolución), también configuras el sentido de orientación de la pantalla, el nivel de brillo, etc, alguna vez estuve jugando para ver que eran esas configuraciones.

Con respecto a lo que no logras hacer que funcione y suponiendo que las conexiones son correctas y la LCD no tiene algún defecto, lo más probable es la manera incorrecta como estas enviando los datos por el SPI.

Yo te recomendaría ver no solo las señales de reloj y datos , sino por ejemplo CS y el reloj, A1 y el reloj, etc., es posible que una de estas señales actives antes o luego de cuando debían ser activadas.
Si tienes una analizador lógico, sería mucho mejor para determinar si estas haciendo lo correcto.

Respecto al código en PICC o CCS no estaría seguro si estas configurando y escribiendo correctamente , no soy experto en eso. Deberías esperar a un comentario de alguien con ese conocimiento.

Título: Re:LCD 128x64 / ST7565R
Publicado por: Pchuqui_1 en 19 de Diciembre de 2021, 22:27:11
Con la configuración SPI por software y utilizando el scope, se  puede ver que la frecuencia del spi es de 13 Khz. Me parece baja, y aunque no se cual es la mínima y/o máxima que soporta este display, voy a cambiarle el cristal para mejorar un poco la frecuencia.
Ya empiezo a descartar problemas en la comunicación; es configuración como bien decís DominusDRR. Este display me está volviendo loco, debería ser fácil  :5] :5] :lol: :lol:

En la imagen se ve como se envía el código b10100011.  Según el datasheet tiene que enviarse el bit mas significativo primero.

(https://i.ibb.co/Yfx0C3b/Whats-App-Image-2021-12-19-at-22-19-16.jpg) (https://ibb.co/ssZWf2t)
Título: Re:LCD 128x64 / ST7565R
Publicado por: DominusDRR en 20 de Diciembre de 2021, 10:34:43
Con la configuración SPI por software y utilizando el scope, se  puede ver que la frecuencia del spi es de 13 Khz. Me parece baja, y aunque no se cual es la mínima y/o máxima que soporta este display, voy a cambiarle el cristal para mejorar un poco la frecuencia.
Ya empiezo a descartar problemas en la comunicación; es configuración como bien decís DominusDRR. Este display me está volviendo loco, debería ser fácil  :5] :5] :lol: :lol:

En la imagen se ve como se envía el código b10100011.  Según el datasheet tiene que enviarse el bit mas significativo primero.

(https://i.ibb.co/Yfx0C3b/Whats-App-Image-2021-12-19-at-22-19-16.jpg) (https://ibb.co/ssZWf2t)

Lo que no comprendo es porqué no analizas las otras líneas (Reset, CS, A0) junto con el reloj para determinar si lo estás haciendo bien. Obviamente si tienes un scope de más de dos o tres entradas, podrías ver todas al mismo tiempo.

Título: Re:LCD 128x64 / ST7565R
Publicado por: Pchuqui_1 en 26 de Diciembre de 2021, 19:59:52
Compañeros... El display está funcionando. Obviamente tenía problemas en la inicialización, como siempre lo dudé. Pero quedó funcionando.

Solo, hay un problema que aún no puedo resolver. El punto (0,0) está corrido, es decír que las columnas están fuera de posición. Por lo tanto cuando escribo algo en esas coordenas no se vé. Según el datasheet hay dos registros para desplazar las columnas, pero ya los modifiqué y no cambia.  :5]

Esta es la descripción de los registros para desplazar las columnas:

(https://i.ibb.co/dLQBTk1/Captura-de-pantalla-2021-12-26-195447.jpg) (https://ibb.co/3M013SG)

Y esta es la instrucción donde se utiliza, que ya está programada para que inicie en (0,0) pero no lo hace.

Código: C
  1. void Transferir_LCDRAM_LCD(void)
  2. {
  3.     unsigned char i;
  4.     unsigned char j;
  5.    
  6.     for(i = 0; i < 8; ++i)
  7.     {
  8.         //LCD_Instrucciones(i); // LCD lista para instrucciones
  9.         glcd_command(0xb0 | i);    // select page 0~7
  10.         glcd_command(0x10);       // start form column 0
  11.         glcd_command(0x00);        // (2byte command)
  12.         for(j = 0; j < 128; ++j)
  13.         glcd_data(LCDRAM[i][j]);  //LCD_ESCRIBIR(0,solintecelogo[s++]); // Los pixeles encendidos a OFF
  14.     }
  15.     delay_us(150);
  16. }

(https://i.ibb.co/xDjcB9V/20211225-172346.jpg) (https://ibb.co/805RfvF)
ver avatar online gratis en español completa (https://es.imgbb.com/)
Título: Re:LCD 128x64 / ST7565R
Publicado por: DominusDRR en 27 de Diciembre de 2021, 10:17:05
Compañeros... El display está funcionando. Obviamente tenía problemas en la inicialización, como siempre lo dudé. Pero quedó funcionando.

Solo, hay un problema que aún no puedo resolver. El punto (0,0) está corrido, es decír que las columnas están fuera de posición. Por lo tanto cuando escribo algo en esas coordenas no se vé. Según el datasheet hay dos registros para desplazar las columnas, pero ya los modifiqué y no cambia.  :5]

Esta es la descripción de los registros para desplazar las columnas:

(https://i.ibb.co/dLQBTk1/Captura-de-pantalla-2021-12-26-195447.jpg) (https://ibb.co/3M013SG)

Y esta es la instrucción donde se utiliza, que ya está programada para que inicie en (0,0) pero no lo hace.

Código: C
  1. void Transferir_LCDRAM_LCD(void)
  2. {
  3.     unsigned char i;
  4.     unsigned char j;
  5.    
  6.     for(i = 0; i < 8; ++i)
  7.     {
  8.         //LCD_Instrucciones(i); // LCD lista para instrucciones
  9.         glcd_command(0xb0 | i);    // select page 0~7
  10.         glcd_command(0x10);       // start form column 0
  11.         glcd_command(0x00);        // (2byte command)
  12.         for(j = 0; j < 128; ++j)
  13.         glcd_data(LCDRAM[i][j]);  //LCD_ESCRIBIR(0,solintecelogo[s++]); // Los pixeles encendidos a OFF
  14.     }
  15.     delay_us(150);
  16. }

(https://i.ibb.co/xDjcB9V/20211225-172346.jpg) (https://ibb.co/805RfvF)
ver avatar online gratis en español completa (https://es.imgbb.com/)

Suponiendo que no es un problema de configuración, cuando pones un punto en las coordenadas x = 0, y = 0, deberías primer revisar si LCDRAM[0][0] que debe ser igual a 0x80, si es correcto ese valor puede ser que al enviar el dato vía SPI lo alteres, por ejemplo pueda que esté trabajando con char en lugar de unsigned char.
Título: Re:LCD 128x64 / ST7565R
Publicado por: Pchuqui_1 en 30 de Diciembre de 2021, 21:58:11
Hola  DominusDRR. Gracias por la respuesta.

Porque dices que  LCDRAM[0][0] que debe ser igual a 0x80?

Feliz año nuevo!

Un abrazo
Título: Re:LCD 128x64 / ST7565R
Publicado por: DominusDRR en 30 de Diciembre de 2021, 22:17:45
Hola  DominusDRR. Gracias por la respuesta.

Porque dices que  LCDRAM[0][0] que debe ser igual a 0x80?

Feliz año nuevo!

Un abrazo

Lo voy a explicar en partes. Sabes que tu pantalla es de 128x64 pixeles. La coordenada 0,0 está en la esquina superior izquierda y la coordenada 128,64 está en la esquina inferior derecha.

La línea Vertical se denomina Y, et puede contener hasta 64 bytes (de 0 a 63)

La línea Horizontal puede contener hasta 16 bytes, cada byte es de 8 bits, por lo tanto 16 bytes * 8 = 128 bits o pixeles.



Título: Re:LCD 128x64 / ST7565R
Publicado por: DominusDRR en 30 de Diciembre de 2021, 22:23:04
Hola  DominusDRR. Gracias por la respuesta.

Porque dices que  LCDRAM[0][0] que debe ser igual a 0x80?

Feliz año nuevo!

Un abrazo

Si deseas poner un punto en las coordenadas 0, 0, debes activar el bit 7 del primer byte, que está en la esquina izquierda superior: (De igual manera feliz año nuevo)

Título: Re:LCD 128x64 / ST7565R
Publicado por: Pchuqui_1 en 09 de Enero de 2022, 18:55:58
Gracias DominusDRR! Ya puedo utilizar el display con normalidad!

 ((:-)) ((:-)) ((:-))
Título: Re:LCD 128x64 / ST7565R
Publicado por: DominusDRR en 09 de Enero de 2022, 19:08:07
Gracias DominusDRR! Ya puedo utilizar el display con normalidad!

 ((:-)) ((:-)) ((:-))

(https://c.tenor.com/AEnNLFoxzoIAAAAC/james-franco-wink.gif)