版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq446252221/article/details/77725913
RA8875
是一块LCD驱动芯片,支持RGB接口的LCD液晶屏,提供8080时序的MCU接口;
RA8875内置了2D硬件加速功能,可以实现硬件绘制矩形,直线等功能;
本次测试就是为了验证RA8875的硬件绘图与使用MCU软件绘图的速度差异。
硬件环境:
CPU:STM32F407VE@168MHz
LCD:480x272x16bpp
测试方法:
计算1秒内填充整个屏幕的次数(FPS)
测试结果:
填充方式 |
帧率(FPS) |
速度(Pixel/s) |
备注 |
软件逐点填充 |
6 |
783360 |
|
软件逐行填充 |
63 |
8225280 |
|
软件矩形填充 |
69 |
9008640 |
|
硬件逐行填充1 |
201 |
26242560 |
先绘图,等待空闲后退出函数 |
硬件逐行填充2 |
207 |
27025920 |
进入函数先等待空闲,再绘图 |
硬件矩形填充1 |
312 |
40734720 |
先绘图 |
硬件矩形填充2 |
315 |
41126400 |
先等待 |
emWin(5.30) |
126 |
16441000 |
自带驱动,支持硬件加速 |
FastGUI |
201 |
26242560 |
驱动为硬件逐行填充2 |
FlatGUI |
324 |
42301440 |
说明:RA8875的硬件绘制功能,需要读取状态寄存器的BIT7,
如果该位为1说明硬件绘制没有完成,不能进行其它绘制,否则屏幕会显示不正常。
“先绘图”是指先发送硬件绘图指令,然后读取状态寄存器,等待BIT7清0后退出函数;
“先等待”是指先读取状态寄存器,等待BIT7清0后,再发送绘图指令;
测试结论:
由此可见使用RA8875的硬件绘图有着非常明显的速度优势,比使用软件绘图快了3-4倍。
附上RA8875的2D加速代码:
static void lcd_set_rect(int x1, int y1, int x2, int y2)
{
//窗口起始位置
lcd_command(0x30, x1);
lcd_command(0x31, (x1 >> 8) & 0x3);
lcd_command(0x32, y1);
lcd_command(0x33, (y1 >> 8) & 0x01);
//窗口结束位置
lcd_command(0x34, x2);
lcd_command(0x35, (x2 >> 8) & 0x03);
lcd_command(0x36, y2);
lcd_command(0x37, (y2 >> 8) & 0x01);
}
static void lcd_wseek(int x, int y)
{
lcd_command(0x46, x);
lcd_command(0x47, x >> 8);
lcd_command(0x48, y);
lcd_command(0x49, y >> 8);
}
static void lcd_rseek(int x, int y)
{
lcd_command(0x4A, x);
lcd_command(0x4B, x >> 8);
lcd_command(0x4C, y);
lcd_command(0x4D, y >> 8);
}
void lcd_set_pixel(int x, int y, int pixel)
{
lcd_wait_ram();
lcd_wseek(x, y);
lcd_command(0x02, pixel);
}
int lcd_get_pixel(int x, int y)
{
int data;
lcd_rseek(x, y);
LCD_CMD = 0x02;
data = LCD_DATA; //dummy read
data = LCD_DATA;
return data;
}
//BTE
static void bte_set_rect(int x, int y, int w, int h)
{
lcd_command(0x58, x);
lcd_command(0x59, (x >> 8) & 0x03);
lcd_command(0x5A, y);
lcd_command(0x5B, (y >> 8) & 0x01);
lcd_command(0x5C, w);
lcd_command(0x5D, (w >> 8) & 0x03);
lcd_command(0x5E, h);
lcd_command(0x5F, (h >> 8) & 0x03);
}
static void bte_set_bkcolor(int color)
{
lcd_command(0x60, (color >> 11) & 0x1F);
lcd_command(0x61, (color >> 5) & 0x3F);
lcd_command(0x62, color & 0x1F);
}
static void bte_set_fgcolor(int color)
{
lcd_command(0x63, (color >> 11) & 0x1F);
lcd_command(0x64, (color >> 5) & 0x3F);
lcd_command(0x65, color & 0x1F);
}
static void bte_set_colorkey(int color)
{
lcd_command(0x67, (color >> 11) & 0x1F);
lcd_command(0x68, (color >> 5) & 0x3F);
lcd_command(0x69, color & 0x1F);
}
static void bte_open(int mode)
{
lcd_command(0x51, lcd_rop_mask | mode);
lcd_command(0x50, 0x80);
}
static void g2d_set_rect(int x, int y, int x2, int y2)
{
lcd_command(0x91, x&0xFF);
lcd_command(0x92, (x>>8)&0xFF);
lcd_command(0x93, y&0xFF);
lcd_command(0x94, (y>>8)&0xFF);
lcd_command(0x95, x2&0xFF);
lcd_command(0x96, (x2>>8)&0xFF);
lcd_command(0x97, y2&0xFF);
lcd_command(0x98, (y2>>8)&0xFF);
}
static void g2d_command(uint8_t cmd)
{
lcd_command(0x90, cmd);
}
void lcd_set_rop(int mode)
{
lcd_rop_mask = (mode & 0x0F) << 4;
}
void bte_fill_rect(int x, int y, int w, int h, int color)
{
lcd_wait_bte();
bte_set_rect(x, y, w, h);
bte_set_fgcolor(color);
bte_open(0x0C);
}
void g2d_fill_rect(int x, int y, int x2, int y2, int color)
{
lcd_wait_ram();
bte_set_fgcolor(color);
g2d_set_rect(x, y, x2, y2);
g2d_command(0xB0);
}