1 前言
由于串口屏显示图片需要将jpeg文件进行拆包,每个包240字节,尝试结合esp32的sdmmc加载并拆包。
2 硬件
esp32c3+串口屏
红字标的是串口屏的tx和rx
3 串口屏配置
选择图标页面平移显示,尺寸设为64、64。(注意和传入的图片尺寸一致),地址设为7FFE
4 测试数据包
数据帧
5AA5F3828000FFD8FFE000104A46494600010101009000900000FFE100224578696600004D4D002A00000008000101120003000000010001000000000000FFDB0043000201010201010202020202020202030503030303030604040305070607070706070708090B0908080A0807070A0D0A0A0B0C0C0C0C07090E0F0D0C0E0B0C0C0CFFDB004301020202030303060303060C0807080C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0CFFC00011080040004003012200021101031101FFC4001F0000010501010101010100000000000000000102030405
5AA5F3828078060708090A0BFFC400B5100002010303020403050504040000017D01020300041105122131410613516107227114328191A1082342B1C11552D1F02433627282090A161718191A25262728292A3435363738393A434445464748494A535455565758595A636465666768696A737475767778797A838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE1E2E3E4E5E6E7E8E9EAF1F2F3F4F5F6F7F8F9FAFFC4001F0100030101010101010101010000000000000102030405060708090A0BFFC400B51100020102040403040705040400
5AA5F38280f0010277000102031104052131061241510761711322328108144291A1B1C109233352F0156272D10A162434E125F11718191A262728292A35363738393A434445464748494A535455565758595A636465666768696A737475767778797A82838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE2E3E4E5E6E7E8E9EAF2F3F4F5F6F7F8F9FAFFDA000C03010002110311003F00FDFCA28A2800A28A2800A28A2800A28A2800AFC72FF83AD7F66DF16DD7C0DB5F8A579F17BC69FF0008859EBFE1FD174DF87965B6D343599EE646B8BCBC
5AA5F3828168DA49BC918AC3E56F0BE4946C16DF81FB1B5F34FF00C156FF00E09DFF00F0F3BFD96A1F86BFF0987FC20FE4F882C35DFED1FECAFED2CFD95D9BCAF2BCE87EF671BB7F1E86A63755A8D45F66A425E894D733F3F76FE7DB5B1574E9D483FB5092F9B8BB7FE4D6FD74B9F48587FC78C3FF005CD7F954D4DB78BC88123CE76285CFAE29D572DCC69C5A824FB05145148D028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A00FFFD90000
显示命令
5AA507827FFE5AA58000
先用串口工具传输,注意串口波特率115200
5 代码
5.1 拆分jpeg
table_jpg = {}
table_jpg_num = 0 -- 记录多少个包
function open_jpg(path)
-- if io.exists(path) == false then
-- log.info("sdio","error path")
-- return -1
-- end
print(path)
f_jpg = io.open(path,"rb")
local jpg_size = io.fileSize(path)
local jpg_pkg_num = math.ceil(jpg_size/240) --向上取整
table_jpg_num = jpg_pkg_num
log.info("sdio", "fileSize", jpg_size,jpg_pkg_num)
jpg_add_num = 0x8000
for i = 1, jpg_pkg_num, 1 do
-- 从文件中获取数据,240个字节为一组包(迪文定义)
local temp_jpg_value_hex = f_jpg:read(240)
-- pack.pack( b, temp_jpg_value)
-- 报头
jpg_head_char = "5AA5F382"
-- 地址
jpg_add_char = string.format("%x",jpg_add_num)
jpg_add_hex = string.fromHex(jpg_add_char)
print(jpg_add_char)
jpg_add_num = jpg_add_num+0x78
-- 数据包
-- 最后一个报附加0000
if i == jpg_pkg_num then
print("end pakage")
temp_jpg_value_hex = string.fromHex(string.toHex(temp_jpg_value_hex).."0000")
end
temp_jpg_value_char = string.toHex(temp_jpg_value_hex)
-- print(temp_jpg_value_char)
-- 拼接报头,地址,数据包,并转为16进制用于发送
uart2dwin_char = jpg_head_char..jpg_add_char..temp_jpg_value_char
uart2dwin_hex = string.fromHex(uart2dwin_char)
print(uart2dwin_char)
-- 存储当前的几个包
table_jpg[i]=uart2dwin_hex
end
f_jpg:close()
end
这样可以将jpeg数据拆分为一包240数据,然后加上报头以及最后附加0000
5.2 串口
tag_uart = "t5_uart"
uart_id = 1
uart_speed = 115200
len = 1024
function init_uart()
-- uart.on(1, "recv", function(uart_id, len)
-- local data = uart.read(1, 1024)
-- log.info("uart2", data)
-- -- libgnss.parse(data)
-- end)
log.info(tag_uart,"test5_init_uart")
uart.setup(uart_id, uart_speed)
-- 接收数据
uart.on(uart_id, "receive",uart_receive)
-- uart.on(uart_id, "sent",uart_send)
-- 定时发送数??
-- timex = sys.timerLoopStart(uart_send,3000)
-- log.info(tag_uart,"time:",timex)
end
function uart_send()
log.info("uart_send")
-- if temp_send_hex ~= nil then
-- log.info("uart_send",temp_send_hex)
uart.write(uart_id, 'a')
-- end
end
function uart_receive()
log.info("uart_receive")
local s = ""
s = uart.read(uart_id, len)
if #s > 0 then -- #s 是取字符串的长度
-- 如果传输二进??/十六进制数据, 部分字符不可??, 不代表没收到
-- 关于收发hex??,请查?? https://doc.openluat.com/article/583
-- log.info("uart", "receive", uart_id, #s, s)
-- log.info("uart", "receive", uart_id, #s, string.toHex(s))
dwin_uart2 = string.toHex(s)
print(dwin_uart2,type(dwin_uart2))
if dwin_uart2 == "5AA503824F4B" then
flag_ok = true
end
-- 判断传来的地址
judge_dwin_tx(dwin_uart2)
end
end
function judge_dwin_tx(str)
-- 0x1502是发送书名
if string.find(str,'831502') ~= nil then
sys.publish("SEND_BOOKNAME", false)
end
-- 0x122F是书名
if string.find(str,'83122F') ~= nil then
sys.publish("SAVE_BOOKNAME", str)
end
-- 0x1300是发送按钮,暂时用于显示jpg
if string.find(str,'831300') ~= nil then
sys.publish("DISPLAY_JPG", str)
end
end
function send_bookname(state)
log.info("SEND_BOOKNAME", state)
flag_search = true
end
sys.subscribe("SEND_BOOKNAME", send_bookname)
function save_bookname(str)
log.info("SAVE_BOOKNAME", str)
-- local v_start = string.find(str,'83122F')
-- local value = string.sub(str,v_start+7)
local dwin_adr_input_ta='83122F'
dwin_uart2_adr = string.find(str,dwin_adr_input_ta)
dwin_uart2_start = dwin_uart2_adr + #dwin_adr_input_ta + 4 -- 03 5A(标识??)
dwin_uart2_len = string.sub(str, dwin_uart2_start, dwin_uart2_start+1)
dwin_uart2_end = string.find(str,'FFFF')
local dwin_uart2_gbk_char = nil
dwin_uart2_gbk_char = string.sub(str, dwin_uart2_start+2, dwin_uart2_end-1)
dwin_uart2_gbk_hex = string.fromHex(dwin_uart2_gbk_char)
print("dwin_uart2_gbk_hex",dwin_uart2_gbk_hex,#dwin_uart2_gbk_hex)
temp_bookname = dwin_uart2_gbk_hex
end
sys.subscribe("SAVE_BOOKNAME", save_bookname)
function recv_jpg_pkg(state)
log.info("RECV_JPG_PKG", state)
-- flag_search = true
end
sys.subscribe("RECV_JPG_PKG", recv_jpg_pkg)
dwin_tx_jpg_display = "5AA507827FFE5AA58000"
function display_jpg(state)
log.info("DISPLAY_JPG", state)
-- send_table_jpg()
flag_display_jpg = true
end
sys.subscribe("DISPLAY_JPG", display_jpg)
function send_table_jpg()
for i=1,table_jpg_num do
flag_ok = false
while true do
if flag_ok == false then
print("send pkg:",i)
uart.write(uart_id, table_jpg[i])
-- print(table_jpg[i])
print("send ok")
sys.wait(200)
else
break
end
end
end
print("start display")
flag_ok = false
while true do
if flag_ok == false then
-- 发送显示命令
uart.write(uart_id, string.fromHex(dwin_tx_jpg_display))
sys.wait(100)
else
break
end
end
print("end display")
end
我在串口这里加了死循环,只有接收到ok才能停止传输,这样是为了确保串口屏收到了数据。后期可以在uart接收的时候加一个时间判定,如果超过一定时间就直接停止发送。