|
|
由于客户产品项目上急用,所以花时间专门研究解决了下。
【截图功能简介】
早期包括现在做产品效果展示,需要截屏时,很多时候依然采用的SD卡/U盘这种的古老方案,不仅麻烦,而且繁琐。
emWin早期的时候有推出过emSPY截图功能,需要用户移植RTT或者网络协议栈,后续新版本更新,经常出现花屏,几乎没法使用。
1、用户仅需接上SWD接口(3线,4线或者5线均可),无需用户嵌入代码到目标,填入显存地址即可,通过这个功能,会大大方便大家产品效果展示。
2、支持RGB接口屏和总线接口屏方式,对于总线接口方式,比如使用STM32的FSMC总线外接ili9488,RA8875都是没问题的。并且也支持FSMC总线方式外接OLED屏读取。
3、裸机,TouchGFX,ThreadX GUIX,emWin,LVGL,AWTK全部测试通过,含多缓冲方式玩法。
4、颜色格式支持RGB565、RGB888、ARGB8888和1bit单色屏。
5、支持USB,WiFi和以太网通信方式,支持内网和外网访问,由于截图是原始数据,数据量较大,推荐用USB方式获取。
【问题现象】
读取的时候中间部分老是显示黑色方块,截图不连续
前期通过修改RA8875的程序代码配置无法解决,当前截图我们STM32-V5开发板RA8875显示屏效果又是没问题的。

【解决办法】
经过今天一上午的研究,最终锁定是下面这里读取的时候不能像我们V5开发板那样,直接开窗整个显示屏一次性读取。下面这个LUA代码是TOOL执行的操作过程,用户不用管,是上位机已经集成好的
[Lua] 纯文本查看 复制代码 RA8875_SetDispWin(0,0,height,width)
---------------------------------------------------
--- 设置0x40寄存器 地址不自增
---------------------------------------------------
pg_write8(CMD_REG, 0x40)
pg_write8(DATA_REG, 0x00)
RA8875_SetReadCursor(0,0)
pg_write8(CMD_REG, 0x02)
--第1次是哑读,丢弃
pg_read8(DATA_REG)
dispmem1 = ""
re, dispmem2 = pg_read_mem_16(DATA_REG, height * width)
if (re == 0) then print("pg_read_mem2() failed") end
re, dispmem3 = pg_read_mem_16(DATA_REG, height * width)
if (re == 0) then print("pg_read_mem3() failed") end
dispmem1 = dispmem2..dispmem3
t2 = get_runtime()
print("读显存耗时(ms):", t2 - t1)
现在改成32行读取一次,读取480行,问题解决
[Lua] 纯文本查看 复制代码
print("RA8875.lua")
--返回格式:每像素3个字节,2像素交错紧凑排列: G1 R1 R2 B1 B2 G2
function dev_read(driver, height, width, rgb, ltdc, pause,
data_reg_addr, cmd_reg_addr, buff_count, buff_addr1, buff_addr2, buff_addr3)
local dispmem1
local dispmem2
local dispmem3
local re = 0
local i, j
local px
local t1, t2
local str
pg_write32(0xE000EDF0, 0xA05F0000 + 0X00000001 + 0X00000002) -- 进入调试暂停CPU
--读第1个显存
t1 = get_runtime()
str = string.format("读RA8875显存 数据寄存器地址:0x%08X 指令寄存器地址:0x%08X 高度:%d 宽度:%d", data_reg_addr, cmd_reg_addr, height, width)
print(str)
DATA_REG = data_reg_addr
CMD_REG = cmd_reg_addr
pg_write8(CMD_REG, 0x00)
id1 = pg_read8(DATA_REG)
str = string.format("Chip ID = %02X", id1)
print(str)
---------------------------------------------------
--- 设置0x40寄存器 地址不自增
---------------------------------------------------
pg_write8(CMD_REG, 0x40)
pg_write8(DATA_REG, 0x00)
RA8875_SetReadCursor(0,0)
pg_write8(CMD_REG, 0x02)
--第1次是哑读,丢弃
--pg_read8(DATA_REG)
--pg_read8(DATA_REG)
dispmem1 = ""
for i=0,14,1 do
RA8875_SetDispWin(0,i*32,32*(i+1),width)
RA8875_SetReadCursor(0,i*32)
pg_write8(CMD_REG, 0x02)
re, dispmem2 = pg_read_mem_16(DATA_REG, 64 * 800)
if (re == 0) then print("pg_read_mem0() failed") end
dispmem1 = dispmem1 .. dispmem2;
end
t2 = get_runtime()
print("读显存耗时(ms):", t2 - t1)
-------------------------------------
-- 退出读取地址自增
-------------------------------------
pg_write8(CMD_REG, 0x40)
pg_write8(DATA_REG, 0x01)
pg_write32(0xE000EDF0, 0xA05F0000) --恢复
return re, dispmem1, dispmem2, dispmem3
end
function RA8875_SetReadCursor(_usX, _usY)
-- if (g_LcdDirection > 1) /* 竖屏 */
-- {
-- uint16_t temp;
-- temp = _usX;
-- _usX = _usY;
-- _usY = temp;
-- }
-- 设置内存读光标的坐标
RA8875_WriteReg(0x4A, _usX)
RA8875_WriteReg(0x4B, _usX >> 8)
RA8875_WriteReg(0x4C, _usY)
RA8875_WriteReg(0x4D, _usY >> 8)
end
function RA8875_WriteReg(_ucRegAddr, _ucRegValue)
pg_write8(CMD_REG, _ucRegAddr);
pg_write8(DATA_REG, _ucRegValue);
end
function RA8875_GetPixelGUI(_usX, _usY)
local usRGB
pg_write8(CMD_REG, 0x4A)
pg_write8(DATA_REG, _usX&0xff)
pg_write8(CMD_REG, 0x4B)
pg_write8(DATA_REG, (_usX>>8)&0xff)
pg_write8(CMD_REG, 0x4C)
pg_write8(DATA_REG, _usY&0xff)
pg_write8(CMD_REG, 0x4D)
pg_write8(DATA_REG, (_usY>>8)&0xff)
pg_write8(CMD_REG, 0x02)
return usRGB
end
function RA8875_SetDispWin(x, y, h, w)
local usTemp
RA8875_WriteReg(0x30, x)
RA8875_WriteReg(0x31, x >> 8)
RA8875_WriteReg(0x32, y)
RA8875_WriteReg(0x33, y >> 8)
usTemp = w + x - 1
RA8875_WriteReg(0x34, usTemp)
RA8875_WriteReg(0x35, usTemp >> 8)
usTemp = h + y - 1
RA8875_WriteReg(0x36, usTemp)
RA8875_WriteReg(0x37, usTemp >> 8)
end
下面是正常显示的伪效果:
|
|