ILI9488是个奇葩芯片,不单写的时序另类,读的时序也很另类。
写时序
SPI接口
SPI接口最常用,写的时候只能是18bit,因此只能将16bit的RGB565转换成RGB888,然后每次写8bit。
void tft_writedata_18bit(int color)
{
/* // Split out the colours
uint8_t r = (color & 0xF800)>>8;
uint8_t g = (color & 0x07E0)>>3;
uint8_t b = (color & 0x001F)<<3; */
// Convert swapped byte 16 bit colour to 18 bit and write in 3 bytes
// Split out the colours
uint8_t r = (color & 0xF8); // Red
uint8_t g = (color & 0xE000)>>11 | (color & 0x07)<<5; // Green
uint8_t b = (color & 0x1F00)>>5; // Blue
SPI_WRITE_8BIT(r); SPI_WRITE_8BIT(g); SPI_WRITE_8BIT(b);
}
而且3A寄存器需要设置为0x66,18bit的格式
FSMC接口
FSMC接口写入就想对简单很多,数据无需转换,直接16bit写入,它和SPI接口不一样,可以使用16bit的数据写入,所以FSMC接口的写入就没什么技术含量了,直接就下面一个函数解决
void fsmc_TxBuffer(const uint8_t *buffer, uint16_t len) {
while(len--) {
LCD_WRITE_DATA(*buffer++);//写入数据
}
}
读时序
FSMC接口
ILI9488不光写奇葩,读也很奇葩,按照写入的格式读出来的数据存入sd卡后发现像素截了一半,颜色还不对,如图
折腾了很久,最终确认读时序为:dumy R1G1 B1R2 G2B2 …
解释一下:
第一个数据为无效数据,你只管读,但是必须丢弃;
第二个数据为有效数据,高8位为R1,低8位为G1;
第三个数据为有效数据,高8位为B1,低8位为R2;
第四个数据为有效数据,高8位为G2,低8位为B2;
以此类推,规律就是从第二个数据开始读,3个16bit的数据为两个RGB888,然后将两个RGB888存入sd卡,或者转换成RGB565后再存入sd卡,我用的是后者,转换成RGB565后存入sd卡
void lcd_read_memory(int x, int y, int w, int h, uint16_t *out)
{
uint16_t len = w * h / 2;
lcd_setWindow(x, y, w, h, LCD_RAMRD);
LCD_READ_DATA();
uint16_t *rgbbuf = (uint16_t *)out;
do {
fsmc_RxBuffer((uint16_t *)rgbbuf, 3);
uint16_t r = rgbbuf[0];
uint16_t b = rgbbuf[1];
uint16_t g = ((r & 0xFF) << 8);
*out++ = (((r>>11)<<11)|((g>>10)<<5)|(b>>11));
r = (rgbbuf[1] << 8);
//rgbbuf+= 2;
g = rgbbuf[2];
b = ((g & 0xFF) << 8);
*out++ = (((r>>11)<<11)|((g>>10)<<5)|(b>>11));
//rgbbuf+= 2;
} while(--len);
}
最后图片读取成功