Display a colori con driver ILI9488
Ciao a tutti, sto lavorando su dei dispositivi per la gestione degli ambienti per la domotica, dovendo mettere un interfaccia utente, ho cercato dei display a colori da poter associare ad un micro e ho trovato dei display da 3.5" con driver ILI9488 che si possono configurare per comunicare tramite interfaccia SPI. Volendo usare un Atmega1284P per una questione di spazio, ho scelto di collegare i piedini del display a delle porte "non SPI" e di generare i segnali della comunicazione tramite semplicissimi HIGH e LOW in modo da evitare il prescaler (minimo di 2) presente nella porta SPI hardware presente nel micro. Effettuati i collegamenti e svolta una prova con i comandi "All Pixel ON" e "All Pixel OFF" sono riuscito a constatare che la comunicazione con il display avviene correttamente. Quando ho comprato i display ho chiesto al venditore di inviarmi i datasheet del dispositivo e all'interno dell'archivio ci ho trovato anche un esempio che però è per degli STM32. Provando la sequenza di inizializzazione il display non funziona e ho alcuni dubbii sulle configurazioni dei registri di Power Control e VCOM Control. Secondo me il problema potrebbe essere lì però non riesco a capire di cosa dovrei tenere conto per configurarli correttamente anche perché tra le note del Power Control 2 viene menzionato "Device damage" e quindi vorrei non dovermi ritrovare con un bel display nuovo da buttare... Guardando il codice di esempio ho stilato questo codice:
Commentando il blocco while(1) ottengo sul display non l'area di 50x150 di colore verde ma tutto il display di colore bianco e a mia impressione poco acceso rispetto al "All Pixel ON" il che mi porta a pensare che ci sia qualcosa di sbagliato nella sezione di inizializzazione.
Guardando nel datasheet come detto in precedenza ci sono dei campi nominati "Power control" 1,2,3,4,5 e VCOM Control. Nel Power Control 1 si impostano due tensioni: una positiva e una negativa, però non riesco a capire sulla base di cosa dovrei individuare il valore corretto di questo parametro. Nel Power Control 2 ci sono ad esempio "VCI x 5", "VCI x 4" che mi portano al dubbio che possa essere un valore da moltiplicare per un qualche altra cosa ma non riesco a capire ccome interpretare questa tabella e sotto questa tra le note c'è scritto "To prevent the device damage". Nel Power Control 3 invece si imposta una frequenza di uno step up che anche questo non capisco a cosa serve ma comunque in genere penso sia necessario conoscere su quale area di circuito e in che modo sinterviene questo parametro prima di impostare una determinata frequenza. Nel Power Control 4 C'è sempre una frequenza da impostare, stessa cosa nel Power Control 5. Per quanto riguarda il VCOM, dipende dal VREG2OUT ed è una tensione. A pagina 323 c'è una tabella con dei valori indicati ma non dice nulla di più di quello indicato nei comandi. Ci sono anche i Negative / Positive Gamma Control che da altre parti (cercando su internet) ho trovato anche con valori differenti,che però non li vedo forniti e non è presente uno "standard". Potete indicarmi come dovrei procedere per risolvere questo problema?
- Codice: Seleziona tutto
/*
* ili9488.c
*
* Created on: 30 mag 2025
* Author: daniele
*/
#include <avr/io.h>
#include <util/delay.h>
#include "ili9488.h"
void send_ilidata(uint8_t type,uint8_t data){
TOUCH_CS_high;
SD_CS_high;
DISPLAY_SCK_low;
if(type){//Send CMD 1
DISPLAY_DC_low;
}else{//Send Data 0
DISPLAY_DC_high;
}
//DISPLAY_SCK_low;
DISPLAY_CS_low;
for(type = 0; type < 8; type++){
if(data & 0b10000000){
DISPLAY_SDI_high;
}else{
DISPLAY_SDI_low;
}
DISPLAY_SCK_low;
DISPLAY_SCK_high;
data = data << 1;
}
DISPLAY_SCK_low;
DISPLAY_CS_high;
}
void display_direction(uint8_t dir){
send_ilidata(DISPLAY_send_cmd,0x36);
switch(dir){
case 0:
send_ilidata(DISPLAY_send_data,0x00 | (1<<3)|(0<<6)|(0<<7));//BGR==1,MY==0,MX==0,MV==0
break;
case 1:
send_ilidata(DISPLAY_send_data,0x00 | (1<<3)|(0<<7)|(1<<6)|(1<<5));//BGR==1,MY==1,MX==0,MV==1
break;
case 2:
send_ilidata(DISPLAY_send_data,0x00 | (1<<3)|(1<<6)|(1<<7));//BGR==1,MY==0,MX==0,MV==0
break;
case 3:
send_ilidata(DISPLAY_send_data,0x00 | (1<<3)|(1<<7)|(1<<5));//BGR==1,MY==1,MX==0,MV==1
break;
default:
send_ilidata(DISPLAY_send_data,0x00 | (1<<3)|(0<<6)|(0<<7));//Case 0
break;
}
}
void display_setFrame(uint16_t xStart,uint16_t xEnd, uint16_t yStart,uint16_t yEnd){
send_ilidata(DISPLAY_send_cmd,0x2A);//0x2A Column Address Set
send_ilidata(DISPLAY_send_data,(xStart >> 8));
send_ilidata(DISPLAY_send_data,(0x00FF & xStart));
send_ilidata(DISPLAY_send_data,(xEnd >> 8));
send_ilidata(DISPLAY_send_data,(0x00FF & xEnd));
send_ilidata(DISPLAY_send_cmd,0x2B);//0x2B Page Address Set
send_ilidata(DISPLAY_send_data,(yStart >> 8));
send_ilidata(DISPLAY_send_data,(0x00FF & yStart));
send_ilidata(DISPLAY_send_data,(yEnd >> 8));
send_ilidata(DISPLAY_send_data,(0x00FF & yEnd));
send_ilidata(DISPLAY_send_cmd,0x2C);//0x2C Memory Write
}
void display_sendColor16(uint16_t data){
//18Bit
send_ilidata(DISPLAY_send_data,(data >> 8) & 0xF8);//Red
send_ilidata(DISPLAY_send_data,(data >> 3) & 0xFC);//Green
send_ilidata(DISPLAY_send_data,(data << 3));//Blue
}
void display_clear(uint16_t color){
display_setFrame(0,50,0,150);
//DISPLAY_CS_low;
//DISPLAY_DC_high;
for(uint16_t tmp1=0;tmp1<50;tmp1++){
for(uint16_t tmp2;tmp2 < 150;tmp2++){
display_sendColor16(color);
}
}
//DISPLAY_CS_high;
}
void display_reset(){
DISPLAY_RST_high;
_delay_ms(100);
DISPLAY_RST_low;
_delay_ms(100);
DISPLAY_RST_high;
_delay_ms(100);
}
void init_display(){
DISPLAY_SDI_init;
DISPLAY_SDO_init;
DISPLAY_SCK_init;
DISPLAY_CS_init;
DISPLAY_DC_init;
DISPLAY_RST_init;
DISPLAY_BL_init;
TOUCH_CS_init;
SD_CS_init;
DISPLAY_CS_high;
TOUCH_CS_high;
SD_CS_high;
DISPLAY_BL_high; //PWM - timer0 OC0A
display_reset();
send_ilidata(DISPLAY_send_cmd,0x01);
_delay_ms(5);
send_ilidata(DISPLAY_send_cmd,0xB0);//Interface Mode Control
send_ilidata(DISPLAY_send_data,0x80);//00
send_ilidata(DISPLAY_send_cmd,0xF7); //ADJUST Control
send_ilidata(DISPLAY_send_data,0xA9);
send_ilidata(DISPLAY_send_data,0x51);
send_ilidata(DISPLAY_send_data,0x2C);
send_ilidata(DISPLAY_send_data,0x82);
send_ilidata(DISPLAY_send_cmd,0xC0); //Power Control
send_ilidata(DISPLAY_send_data,0x11);//11 VREG1OUT 4.625
send_ilidata(DISPLAY_send_data,0x09);//09 VREG2OUT -4.125
send_ilidata(DISPLAY_send_cmd,0xC1); //Power Control 2
send_ilidata(DISPLAY_send_data,0x41);// ??
send_ilidata(DISPLAY_send_cmd,0xC5); //VCOM Control
send_ilidata(DISPLAY_send_data,0x00);
send_ilidata(DISPLAY_send_data,0x0A);// -1.84
send_ilidata(DISPLAY_send_data,0x80);// use -1.84 VCOM
send_ilidata(DISPLAY_send_cmd,0xB1); //Frame Rate Control
send_ilidata(DISPLAY_send_data,0xB0);//B0 Framerate 65.65
send_ilidata(DISPLAY_send_data,0x11);// 17Clock
send_ilidata(DISPLAY_send_cmd,0xB4); //Display inversion control
send_ilidata(DISPLAY_send_data,0x02);
send_ilidata(DISPLAY_send_cmd,0xB6); //Display Function Control
send_ilidata(DISPLAY_send_data,0x02);
send_ilidata(DISPLAY_send_data,0x42);//
send_ilidata(DISPLAY_send_cmd,0xB7); //Entry Mode Set
send_ilidata(DISPLAY_send_data,0xC6);
send_ilidata(DISPLAY_send_cmd,0xBE); //HS Lanes Control
send_ilidata(DISPLAY_send_data,0x00);
send_ilidata(DISPLAY_send_data,0x04);
send_ilidata(DISPLAY_send_cmd,0xE9); //Set Image Function
send_ilidata(DISPLAY_send_data,0x00);
send_ilidata(DISPLAY_send_cmd,0x36); //Memory Access Control
send_ilidata(DISPLAY_send_data,0x00 | (1<<3)|(0<<7)|(1<<6)|(1<<5));
send_ilidata(DISPLAY_send_cmd,0x3A);//Interface Pixel Format
send_ilidata(DISPLAY_send_data,0x66);//DBI 18Bit-Pixel,DPI 18Bit-Pixel
//send_ilidata(DISPLAY_send_data,0x77); //24Bit
send_ilidata(DISPLAY_send_cmd,0xE0); //Positive Gamma Control
send_ilidata(DISPLAY_send_data,0x00);
send_ilidata(DISPLAY_send_data,0x07);
send_ilidata(DISPLAY_send_data,0x10);
send_ilidata(DISPLAY_send_data,0x09);
send_ilidata(DISPLAY_send_data,0x17);
send_ilidata(DISPLAY_send_data,0x0B);
send_ilidata(DISPLAY_send_data,0x41);
send_ilidata(DISPLAY_send_data,0x89);
send_ilidata(DISPLAY_send_data,0x4B);
send_ilidata(DISPLAY_send_data,0x0A);
send_ilidata(DISPLAY_send_data,0x0C);
send_ilidata(DISPLAY_send_data,0x0E);
send_ilidata(DISPLAY_send_data,0x18);
send_ilidata(DISPLAY_send_data,0x1B);
send_ilidata(DISPLAY_send_data,0x0F);
send_ilidata(DISPLAY_send_cmd,0xE1); //Negative Gamma Control
send_ilidata(DISPLAY_send_data,0x00);
send_ilidata(DISPLAY_send_data,0x17);
send_ilidata(DISPLAY_send_data,0x1A);
send_ilidata(DISPLAY_send_data,0x04);
send_ilidata(DISPLAY_send_data,0x0E);
send_ilidata(DISPLAY_send_data,0x06);
send_ilidata(DISPLAY_send_data,0x2F);
send_ilidata(DISPLAY_send_data,0x45);
send_ilidata(DISPLAY_send_data,0x43);
send_ilidata(DISPLAY_send_data,0x02);
send_ilidata(DISPLAY_send_data,0x0A);
send_ilidata(DISPLAY_send_data,0x09);
send_ilidata(DISPLAY_send_data,0x32);
send_ilidata(DISPLAY_send_data,0x36);
send_ilidata(DISPLAY_send_data,0x0F);
send_ilidata(DISPLAY_send_cmd,0x11); //Sleep OUT
_delay_ms(120);
//while(1);
send_ilidata(DISPLAY_send_cmd,0x21); //Display Inversion OFF
send_ilidata(DISPLAY_send_cmd,0x29); //Display ON
// //All Pixel OFF(0x22) ON(0x23)
while(1){
send_ilidata(DISPLAY_send_cmd,0x23);
_delay_ms(1000);
send_ilidata(DISPLAY_send_cmd,0x22);
_delay_ms(1000);
}
display_direction(0);
display_clear(COLOR_GREEN);
}
Commentando il blocco while(1) ottengo sul display non l'area di 50x150 di colore verde ma tutto il display di colore bianco e a mia impressione poco acceso rispetto al "All Pixel ON" il che mi porta a pensare che ci sia qualcosa di sbagliato nella sezione di inizializzazione.
Guardando nel datasheet come detto in precedenza ci sono dei campi nominati "Power control" 1,2,3,4,5 e VCOM Control. Nel Power Control 1 si impostano due tensioni: una positiva e una negativa, però non riesco a capire sulla base di cosa dovrei individuare il valore corretto di questo parametro. Nel Power Control 2 ci sono ad esempio "VCI x 5", "VCI x 4" che mi portano al dubbio che possa essere un valore da moltiplicare per un qualche altra cosa ma non riesco a capire ccome interpretare questa tabella e sotto questa tra le note c'è scritto "To prevent the device damage". Nel Power Control 3 invece si imposta una frequenza di uno step up che anche questo non capisco a cosa serve ma comunque in genere penso sia necessario conoscere su quale area di circuito e in che modo sinterviene questo parametro prima di impostare una determinata frequenza. Nel Power Control 4 C'è sempre una frequenza da impostare, stessa cosa nel Power Control 5. Per quanto riguarda il VCOM, dipende dal VREG2OUT ed è una tensione. A pagina 323 c'è una tabella con dei valori indicati ma non dice nulla di più di quello indicato nei comandi. Ci sono anche i Negative / Positive Gamma Control che da altre parti (cercando su internet) ho trovato anche con valori differenti,che però non li vedo forniti e non è presente uno "standard". Potete indicarmi come dovrei procedere per risolvere questo problema?