最近在做LVGL的移植,用到的屏幕驱动时GC9A01的,记录一下学习历程,防止日后遗忘。
这款屏幕我使用的是SPI协议,参考了部分稚辉菌大佬这个项目的程序:
【自制】我做了个能动的迷你电脑配件!【软核】_哔哩哔哩_bilibili
目录
编辑使用C实现SPI通信(标准库写法):
HALL库
SPI的通信部分是:CS和CLK拉低后即可通信,拉高结束通信
使用C实现SPI通信(标准库写法):
void LCD_Writ_Bus(u8 dat)
{ u8 i;LCD_CS_Clr();//拉低for(i=0;i<8;i++){ LCD_SCLK_Clr();//拉低if(dat&0x80){LCD_MOSI_Set();}else{LCD_MOSI_Clr();}LCD_SCLK_Set();//拉高dat<<=1;} LCD_CS_Set();//拉高
}
作为一个LCD最重要的就是画点函数了,长这样:
void LCD_DrawPoint(u16 x,u16 y,u16 color)
{// void LCD_Address_Set(u16 x1,u16 y1,u16 x2,u16 y2)//{// LCD_WR_REG(0x2a);//列地址设置// LCD_WR_DATA(x1);// LCD_WR_DATA(x2);// LCD_WR_REG(0x2b);//行地址设置// LCD_WR_DATA(y1);// LCD_WR_DATA(y2);// LCD_WR_REG(0x2c);//储存器写//}LCD_Address_Set(x,y,x,y);//设置光标位置 LCD_WR_DATA(color);
}
翻下数据手册 这是命令的作用(这个发送的是16位命令,上边介绍的是8位的):
HALL库
现在我们可以画点了,通过调用这个函数*(HALL库):
下图是调用2A命令,设置列地址的起始位置和结束位置,发一个16位的data就是设置起始地址,发两个16位的data就是设置起始和结束地址
void SetDataOrCommand(bool _isData)
{if (_isData) {LCD_DC_GPIO_Port->BSRR = LCD_DC_Pin;} else {LCD_DC_GPIO_Port->BSRR = (uint32_t) LCD_DC_Pin << 16U;}
}void WriteCommand(uint8_t _cmd)
{SetDataOrCommand(false);HAL_SPI_Transmit(spi, &_cmd, 1, 100);
}void Setpoint(uint16_t _startX, uint16_t _startY,uint16_t color)
{ChipSelect(true);uint8_t data[4];WriteCommand(0x2A); // COL_ADDR_SETdata[0] = (_startX >> 8) & 0xFF;data[1] = _startX & 0xFF;WriteData(data, sizeof(data), false);WriteCommand(0x2B); // ROW_ADDR_SETdata[0] = (_startY >> 8) & 0xFF;data[1] = _startY & 0xFF;WriteData(data, sizeof(data), false);WriteCommand(0x2C); // ROW_ADDR_SETdata[0] = (color >> 8) & 0xFF;data[1] = color & 0xFF;WriteData(data, sizeof(data), false); ChipSelect(false);
}
//这里传入的是一组数据,使用指针来接收数据
void Setwindow(uint16_t _startX, uint16_t _endX, uint16_t _startY, uint16_t _endY,uint16_t *color)
{ChipSelect(true);uint16_t height, width;uint16_t i, j;width = _endX - _startX + 1; /* 得到填充的宽度 */height = _endY - _startY + 1; /* 高度 */for (i = 0; i < height; i++){for (j = 0; j < width; j++){//将像素的值通过坐标写入Setpoint(_startX+j,_startY+i,color[i * width + j]);}}ChipSelect(false);
}
如果画一个区域就是这样的,依次进行设置,最后写内存的部分,本质上就是给像素点写颜色,因为这个芯片本质上就是一个巨大的RAM,一共320x18x240 bits,RGB的模式也分几种,上述代码主要是LVGL进行缓存更新时候调用的画区域的函数,本质上是对GRAM的内存进行更新
如有描述不对的地方,欢迎评论区指证!