MCU-YT-4629点阵屏调试
点阵屏信息
型号:YT-4629
像素:128X64
通讯协议:SPI
背景
公司的产品需要降本,原本的彩屏因为成本比较高,更换为成本更低的点阵屏,原来使用的的像素是128*128的彩屏,一个像素点是由
对比原有彩屏的优劣势
彩屏:彩屏每个像素点是2个byte,采用的显示颜色显示方式是RGB565,对于开发者来说,只需要设置好颜色起始坐标以及结束坐标,将对应的颜色数据依次写入即可,使用上会比较方便,但同样缺点也比较明显,他每一帧图像数据占用的空间都比较大,使用时需仔细考虑,容易造成MCU资源不足,如果是复杂的满屏图像,一帧图像数据需要占用的空间是128x64x2个byte
点阵屏:点阵屏每个像素点的占用1bit,是彩屏的1/16,占用空间少,但是观看上是一个黑白的颜色,对于开发者说,虽然占用空间少了,但是以前在彩屏通用的直接设置X,Y坐标也需要在MCU自行实现,比如,在点阵屏上设置一个14x14的图像(我的点阵屏是列行式,每列的8个像素点为1byte,像素是128x64,简单来说,一个满屏图像是需要操作128x(64/8)个数据),显示在x=3,y=3的图像上,需要先去寻找x=3的坐标,在针对y坐标进行移位,如果超出了1个byte,则需要寻找下一行的数据进行移位,相对来说更需要去注重位运算的过程
显示思想
这篇文章更想表达的是一种思想,如果按照8bit的字节来进行处理数据,针对移位的操作会比较繁琐,针对64bit为一列的数据,那么可以想到的处理方式就是,使用一个uint64类型的数据表示一列的数据,或者使用2个uint32类型的数据来表示一列,针对某些MCU架构,他对于64bit类型的数据位运算是不支持的,所以需要根据自己的MCU架构来,本文介绍的是根据32bit的数据类型来作为显存处理图像贴上部分代码
1.定义一个数组作为显存,作为管理
//显存 128*64/8/4
uint32_t Graphics_Memory[256] ;
2.推入图片数据的接口
/***********************************************************************************************************************
* 函数名: pushGraphicsMemory
* 参数:Xstart :起始X坐标
* Xend :结束X坐标
* Ystart:起始Y坐标
* Yend :结束Y坐标
* color :图片数据
* 返回: 无
* 功能: 将图片数据推入显存,但是不发送给LCD,显示需要配合SendGraphicsMemory函数使用
*************************************************************************************************************************/
void pushGraphicsMemory(uint32_t Xstart, uint32_t Xend, uint32_t Ystart, uint32_t Yend,const uint8_t *color)
{
uint32_t *Graphics = Graphics_Memory ;
const uint8_t width = Xend-Xstart;
const uint8_t height = Yend-Ystart;
uint8_t i ,j ;
uint8_t offestBit,offestY , colorLine,offestX;
if(Ystart<=31 && Yend >= 32)
{
uint8_t topColorLine , currentLine;
offestBit = Ystart % 32 ;
colorLine = (height - 1) / 8 + 1 ;
offestBit = Ystart % 32 ;
topColorLine = Ystart / 8 ;
for(i = Xstart ; i < Xend ; i++)
{
for(j = 0 ; j < colorLine ; j ++)
{
if(topColorLine+j == 3)
{
*(Graphics + (((i << 1)|1))) ^= *(color + j*width + i - Xstart) << (offestBit + 8*j) ;
*(Graphics + ((i << 1))) ^= *(color + j*width + i - Xstart) >> (8-(offestBit + 8*j - 24)) ;
}
else if(topColorLine+j < 3)
{
*(Graphics + (((i << 1)|1))) ^= *(color + j*width + i - Xstart) << (offestBit + 8*j) ;
}
else
{
*(Graphics + ((i << 1))) ^= *(color + j*width + i - Xstart) << (offestBit + 8*j - 32) ;
}
}
}
}
else
{
offestY = (63-Yend) / 32 ;
colorLine = (height - 1) / 8 + 1 ;
offestBit = Ystart % 32 ;
for(i = Xstart ; i < Xend ; i++)
{
offestX = ((i << 1) | offestY) ;
for(j = 0 ; j < colorLine ; j ++)
{
*(Graphics + offestX) ^= *(color + j*width + i - Xstart) << (offestBit + 8*j) ;
}
}
}
}
3.发送显存的代码
void SendGraphicsMemory(uint32_t Xstart, uint32_t Xend, uint32_t Ystart, uint32_t Yend)
{
uint32_t *Graphics = Graphics_Memory ;
uint8_t i , k;
uint8_t startPage,cnt,currentPage;
const uint8_t width = Xend-Xstart;
Graphics += 2*Xstart ;
startPage = Ystart / 8 ;
cnt = (Yend-1) / 8 -startPage +1 ;
//LOG("Xstart:%d, Xend:%d, Ystart:%d Yend:%d\n",Xstart,Xend,Ystart,Yend) ;
for(i = 0 ; i < cnt ; i++)
{
currentPage = startPage + i ;
setPage(currentPage) ;
setX(Xstart) ;
for(k = 0 ; k < width ; k++)
{
*(spi_tx_buf + k) = (*(Graphics+2*k+(7-currentPage)/4) >> ((currentPage%4)*8)) & 0xff ;
//LOG("i:%d,k:%d,offest:%d,image_t:%08X,spi_tx_buf:%02x\n",i,k,2*k+(7-currentPage)/4,*(Graphics+2*k+(7-i)/4),*(spi_tx_buf + k)) ;
}
LCD_WR_data(spi_tx_buf, width) ;
}
}
结语
分享先到这里,希望能给大家带来启发与帮助。如果对内容存在疑问或想法,欢迎在评论区留言,我会积极回复大家的问题。欢迎一起探讨、一起学习。