本帖最后由 卡米拉 于 2020-12-31 15:51 编辑
[size=13.3333px]文件读写演示视频 [size=13.3333px]
一、适用范围 本文档适合大彩M系列医用级的串口屏产品使用。
二、开发环境版本 1.VisualTFT软件版本:V3.0.0.1111及以上的版本。 版本查看: 1)打开VisualTFT软件启动页面如图2-1软件版本,右上角会显示的软件版本号; 图2-1软件版本
图2-2软件版本
2.串口屏硬件版本:V6.3.249.0 及以上的版本。 版本查看: 1) 查看屏幕背面版本号贴纸; 2) VisualTFT与屏幕联机成功后,右下角显示的版本号。
三、概述 本例程中,介绍Lua系统函数中的文件API读写,其中F系列和M系列仅支持对SD卡读写,物联型系列支持对屏内及SD卡、U盘的读写。
四、参考资料 1、《LUA 脚本API V1.4》可通过以下链接下载物联型开发包获取: http:/www.gz-dc.com/index.php?s=/List/index/cid/19.html 2、《LUA基础学习》可通过以下链接下载物联型开发包获取: http:/www.gz-dc.com/index.php?s=/List/index/cid/19.html
五、教程实现 本文主要将以下2点进行说明: 1. 准备工程素材; 2. 配置串口屏工程;
5.1 准备工程素材 5.1.1 准备工程素材 在实现例程前需要作以下3个准备: 1. 硬件平台; 2. 软件平台; 3. UI素材; 该例程使用大彩M系列7寸串口屏DC80480M070_1111_0T为验证开发平台。如图5-1所示; 图5-1 M系列7寸串口屏
5.1.2 软件平台 图5-2下载软件
5.2 配置串口屏工程 本文的文件主要介绍以下2点: (1) 读文件 (2) 写文件
5.2.1 读文件 本例程中的读文件,是读取SD根目录下的‘1.txt’文件,并用数据记录控件显示出来,用户可滑动数据记录控件,查看‘1.txt’里面的内容。
1. 画面配置 在画面ID1中,添加1个数据记录控件(控件ID1)和一个按钮控件(控件ID2),其中控件ID1用于显示‘1.txt’文件的内容。控件ID2 用于触发读取‘1.txt’文件的按钮。画面配置如图5-3所示: 注意:其他非关键控件不在一一介绍,下文不在累述 图5-3 画面配置
2. LUA脚本编辑 本例程中,用户点击按钮控件ID2后,将读取SD目录下载的‘1.txt’文件,并添加到数据记录控件中显示;若文件不存在,则弹框提示。代码如程序清单1所示:
程序清单 1 读文件 - <font size="2">--read file data
- --@file:file path
- function my_read_filedata(file)
- my_debug_print('---------- my_read_filedata ----------')
- my_debug_print('Lua_debug: file -> '..file)
- local count = 0
- local read_cnt = 0
- local offset = 0
- local all_byte = 0
- local read_byte_Tb = {}
- local read_char_Tb = {}
- local read_str = ''
- local open_state = file_open(file, FA_READ)
- if open_state == true
- then
- --获取当前文件大小
- all_byte = file_size()
- if all_byte > 0
- then
- read_cnt = math.modf(all_byte/WriteOnceSize)
- if all_byte % WriteOnceSize > 0
- then
- read_cnt = read_cnt + 1
- end
- my_debug_print('Lua_debug: need read allcnt -> '..read_cnt)
- for i = 1, read_cnt
- do
- --复位读字节数组
- read_byte_Tb = {}
- read_char_Tb = {}
- --计算读取的偏移位置
- offset = (i - 1) * WriteOnceSize
- local offst_result = file_seek(offset)
- --文件偏移失败
- if offst_result == false then
- set_text(sc_prompt, 1, ' When reading the file, an offset error occurred. please try again! ! !')
- set_text_roll(sc_prompt, 1, 50)
- change_child_screen(sc_prompt)
- braek;
- end
- my_debug_print('Lua_debug: cur offset -> '.. offset)
- --计算本次读的个数
- count = WriteOnceSize
- if i == read_cnt
- then
- if all_byte % WriteOnceSize > 0
- then
- count = all_byte % WriteOnceSize
- end
- end
- my_debug_print('Lua_debug: cur read -> '..i..'th / wrire count '..count)
- --读取字节转换为字符并拼接成字符串
- read_byte_Tb = file_read(count)
- if #(read_byte_Tb) > 0
- then
- for j = 0, #(read_byte_Tb)
- do
- read_char_Tb[j + 1] = string.char(read_byte_Tb[j])
- end
- read_str = read_str..table.concat(read_char_Tb)
- elseif read_byte_Tb ==nil
- then
- set_text(sc_prompt, 1, ' File read error. please try again! ! !')
- set_text_roll(sc_prompt, 1, 50)
- change_child_screen(sc_prompt)
- braek;
- end
- end
- my_ShowRecord_FromFile(read_str)
- end
- else
- set_text(sc_prompt, 1, 'The file don`t exist,
- please check the contents of the SD car! ! !')
- set_text_roll(sc_prompt, 1, 50)
- change_child_screen(sc_prompt)
- end
- --关闭文件
- file_close()
- end
- --用户通过触摸修改控件后,</font>执行此回调函数。
- --点击按钮控件,修改文本控件、修改滑动条都会触发此事件。
- function on_control_notify(screen,control,value)
- if screen == sc_ReadFlile and control == 2 and value == 0
- then
- sc_ShowRecord = sc_ReadFlile
- --SD卡是否存在
- if IsinsertSD == 1
- then
- record_clear(sc_ReadFlile, 1)
- my_read_filedata(sd_dir..'/'..'1.txt')
- else
- set_text(sc_prompt, 1, 'Please insert the SD card,
- or check if the SD is compatible! ! !')
- set_text_roll(sc_prompt, 1, 50)
- change_child_screen(sc_prompt)
- end
- ......
- end
- end
复制代码
核心API函数 1) file_open(path,mode) 打开文件,成功返回true,失败false
- path-文件路径
- mode-打开模式,如下组合方式:
打开模式 | 值 | FA_OPEN_EXISTING | 0x00 | FA_READ | 0x01 | FA_WRITE | 0x02 | FA_CREATE_NEW | 0x04 | FA_CREATE_ALWAYS | 0x08 | FA_OPEN_ALWAYS | 0x10 |
例如: 打开文件用于读取file_open(path, 0x01) 创建文件用于写入file_open(path, 0x02|0x08)
2) file_size() 获取当前文件大小,返回字节数 例如:all_byte = file_size()
3) file_seek(offset) 定位文件读取位置,成功返回true,失败false
例如:定位到第2048个字节,file_seek(2048)
4) file_read(count) 读取文件内容,成功返回table数组,失败返回nil
例如:读取2048个字节,read_byte_Tb = file_read(2048)
5) file_close() 关闭文件,成功返回true,失败false
基本思路:当按钮控件ID2按下的时候,触发触摸控件回调函数on_control_notify(),在调用自定义函数my_read_filedata()。 1) 打开文件:以只读的方式FA_READ(0x01)打开指定文件。2) 获取文件大小:文件打开成功后,调用file_size() Api函数获取该文件的大小。
3) 计算读取次数:根据文件大小,得出读取的次数。本例程采取一次读取2048个字节(注意:屏幕一次读取最大字节 <= 2048)
4) 计算读取偏移量:每次读取需要调用file_seek(offset)定位读取位置,offset相当于已读取的字节数
5) 读出数据:本文读取的数据,转换成字符拼接字符串显示出来,详细应用根据实际情况出来。6) 关闭文件:文件读取完毕,将该文件关闭。
5.2.2 写文件 常用的写文件操作主要有以下两种: 1) 追加写:写在文件末尾。本例程是写在SD根目录下的‘1.txt’文件末尾,并用数据记录控件显示出来。2) 覆盖写:清空在写入数据。本例程在SD卡目录下,每次写入创建一个新的NewFile.txt,并写入数据。
追加写和覆盖写的功能实现区别: 1) 打开方式:file_open(path,mode)。
- 追加写:mode = FA_WRITE|FA_READ;
- 覆盖写:mode = FA_CREATE_ALWAYS|FA_WRITE;
2) 写入位置:file_seek(offset)。
- 追加写:offset = file_size() + (i - 1) * WriteOnceSize;其中WriteOnceSize为一次写入数据的大小,i为循环写入的次数。
- 覆盖写:offset = 0;
1. 画面配置 在画面ID2中,添加1个数据记录控件、2个文本控件(控件ID2、控件ID4)和2个按钮控件(控件ID3、控件ID5),其中数据记录控件仅做显示文件内容效果。按钮控件3用于体现追加写功能,按钮控件5用于覆盖写功能。画面配置如图5-4所示: 图5-4 画面配置
2. LUA脚本编辑 按钮控件ID3按下时候,将文本控件ID2的内容写在SD根目录下的‘1.txt’文件末尾(追加写);按钮控件ID5按下时候,将文本控件ID4的内容写在SD根目录下的‘NewFile.txt’文件(覆盖写)代码如程序清单 2所示。
- <font size="2">--get the type and length of the variable
- --@data: 'string' or 'table'
- --@return: len and type of data
- function my_getdataLen_Type(data)
- my_debug_print('---------- my_getdataLen_Type ----------')
- local datalen = -1
- --获取数据类型
- local data_type = type(data)
- --计算数据长度
- if data_type == 'string'
- then
- datalen = string.len(data)
- elseif data_type == 'table'
- then
- datalen = #(data)
- end
- my_debug_print('Lua_debug data Type and Len: '..data_type..' /'..datalen)
- return datalen,data_type
- end
- --Write data to the end of the file
- --@file:file path
- --@data:The type of '@data' only be [string] or [byte array]
- --@open_mode:open file mode
- function my_write_filedata(file, data, open_mode)
- my_debug_print('---------- my_write_filedata ----------')
- my_debug_print('Lua_debug: file -> '..file..' / data -> '..type(data)..' / open_mode -> '..open_mode)
- local count = 0
- local write_cnt = 0
- local offset = 0
- local all_byte = 0
- --获取待写入数据的数据类型和长度
- local wrire_len, data_type = my_getdataLen_Type(data)
- local write_byte_Tb = {}
- local open_state = file_open(file, open_mode)
- if open_state == true
- then
- --获取当前文件大小,仅在追加文件末尾写入执行
- if open_mode == add_write
- then
- all_byte = file_size()
- end
- if wrire_len > 0
- then
- --计算'@data'要写多少次
- write_cnt = math.modf(wrire_len / WriteOnceSize)
- if wrire_len % WriteOnceSize > 0
- then
- write_cnt = write_cnt + 1
- end
- my_debug_print('Lua_debug: need write allcnt -> '..write_cnt)
- for i = 1, write_cnt
- do
- --复位写字节数组
- write_byte_Tb = {}
- --计算写的位置
- offset = (i - 1) * WriteOnceSize +all_byte
- local offst_result = file_seek(offset)
- --文件偏移失败
- if offst_result == false
- then
- set_text(sc_prompt, 1, 'When reading the file, an offset error occurred. please try again! ! !')
- set_text_roll(sc_prompt, 1, 50)
- change_child_screen(sc_prompt)
- break
- end
- my_debug_print('Lua_debug: cur offset -> '..offset)
- --计算本次写的个数
- count = WriteOnceSize
- if i == write_cnt
- then
- if wrire_len % WriteOnceSize > 0
- then
- count = wrire_len % WriteOnceSize
- end
- end
- my_debug_print('Lua_debug: cur write -> '..write_cnt..'th /wrire count '..count)
- --填充写入flash的字节数组
- for j = 1, count
- do
- if data_type == 'string'
- then
- --字符串类型,将每个字符转换为字节数组
- write_byte_Tb[j - 1] = tonumber(string.byte(data, ((i - 1) * WriteOnceSize + j), ((i - 1) * WriteOnceSize + j)))
- elseif data_type == 'table'
- then
- --数组类型,字节赋值
- write_byte_Tb[j - 1] =
- data[((i - 1) * WriteOnceSize + j)]
- end
- end
- local IswriteOK = file_write(write_byte_Tb)
- if IswriteOK == false
- then
- i = i - 1
- end
- end
- end
- else
- set_text(sc_prompt, 1, 'The file don`t exist, please check the contents of the SD car! ! !')
- set_text_roll(sc_prompt, 1, 50)
- change_child_screen(sc_prompt)
- end
- --关闭文件
- file_close()
- end
- --用户通过触摸修改控件后,执行此回调函数。
- --点击按钮控件,修改文本控件、修改滑动条都会触发此事件。
- function on_control_notify(screen,control,value)
- ......
- --追加写
- elseif screen == sc_WriteFile and control == 3 and value == 0
- then
- sc_ShowRecord = sc_WriteFile
- --已插入SD卡
- if IsinsertSD == 1
- then
- record_clear(sc_WriteFile, 1)
- local str = '\n'..get_text(sc_WriteFile, 2)
- my_write_filedata(sd_dir..'/'..'1.txt', str, add_write)
- my_read_filedata(sd_dir..'/'..'1.txt')
- local allrecordcnt = record_get_count(sc_WriteFile, 1)
- record_setoffset(sc_WriteFile, 1, allrecordcnt - 1)
- record_select(sc_WriteFile , 1, allrecordcnt - 1)
- --未插入SD卡
- else
- set_text(sc_prompt, 1, 'Please insert the SD card, or check if the SD is compatible! ! !')
- set_text_roll(sc_prompt, 1, 50)
- change_child_screen(sc_prompt)
- end
- --覆盖写
- elseif screen == sc_WriteFile and control == 5 and value == 0
- then
- sc_ShowRecord = sc_WriteFile
- --已插入SD卡
- if IsinsertSD == 1
- then
- record_clear(sc_WriteFile, 1)
- cnt = cnt + 1
- local str = (cnt + 1)..'th write -> '..get_text(sc_WriteFile, 4)
- my_write_filedata(sd_dir..'/'..'NewTxtFile.txt',str,over_write)
- my_read_filedata(sd_dir..'/'..'NewTxtFile.txt')
- --未插入SD卡
- else
- set_text(sc_prompt, 1, 'Please insert the SD card, or check if the SD is compatible! ! !')
- set_text_roll(sc_prompt, 1, 50)
- change_child_screen(sc_prompt)
- end
- ......
- end
- end</font>
复制代码
核心API函数 1) file_open(path,mode) 相关说明参考读文件章节,不在赘述
2) file_size() 相关说明参考读文件章节,不在赘述
3) file_seek(offset) 相关说明参考读文件章节,不在赘述
4) file_write(data) 写文件内容,成功返回true,失败返回false
- data-待写入的table数组,索引从0开始,最大一次性写2048个字节
5) file_close() 相关说明参考读文件章节,不在赘述
基本思路:当按钮控件ID3或按钮控件ID5按下的时候,触发触摸控件回调函数on_control_notify(),在调用自定义函数my_write_filedata()。 1) 打开文件:
- 追加写:以读写的方式(FA_READ|FA_WRITE:0x01|0x02)打开SD卡目录下的1.txt文件。
- 覆盖写:以新建写入的方式(FA_CREATE_ALWAYS|FA_WRITE:0x08|0x02)打开SD卡目录下的NewFile.txt文件
2) 获取文件大小:文件打开成功后,若追加写模式,则执行file_size() Api代码段。
3) 计算写入次数:根据写入数据的大小,得出读取的次数。本例程采取一次写入2048个字节(注意:屏幕一次读取最大字节 <= 2048)
4) 计算写入的偏移量:每次写入需要调用file_seek(offset)定位读取位置
5) 写入数据6) 关闭文件:文件写完后完毕,将该文件关闭。
5.3 下载工程 工程编译成功后在输出窗口会提示编译成功,如图5-4所示。编译成功后点击菜单栏中【工具】→【量产向导】,如图5-5所示; 图5-4编译成功
图5-5量产向导
在弹窗中选中【SD卡下载】,然后把将文件夹中的private文件夹拷贝到SD卡中,如图5-6和图5-7所示;把SD卡接上串口屏后重新上电,等到提示烧录工程成功后,拔掉SD卡重新上电即可。 图5-6量产向导
图5-7拷贝到SD卡 |