广州大彩串口屏论坛_大彩开发者交流论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 7114|回复: 0

大彩医用级串口屏Lua应用-文件读写

[复制链接]

86

主题

109

帖子

9308

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
9308
发表于 2020-12-31 15:39:17 | 显示全部楼层 |阅读模式
本帖最后由 卡米拉 于 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) 打开VisualTFT,在软件右下角可以查看软件版本图2-2软件版本,最新版本可登录http://www.gz-dc.com/进行下载。
图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
3、LUA脚本初学者可以通过下面链接进行学习:http://www.runoob.com/lua/lua-arrays.html
4、AT指令,可以通过下面子连接了解:http://www.openluat.com/

五、教程实现
本文主要将以下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 软件平台
使用大彩自主研发的上位机软件VisualTFT配置工程,登录http://www.gz-dc.com/下载。如图5-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 读文件
  1. <font size="2">--read file data
  2. --@file:file path
  3. function my_read_filedata(file)
  4.     my_debug_print('---------- my_read_filedata ----------')
  5.     my_debug_print('Lua_debug: file -> '..file)

  6.     local count    = 0
  7.     local read_cnt = 0
  8.     local offset    = 0
  9.     local all_byte = 0

  10.     local read_byte_Tb = {}
  11.     local read_char_Tb = {}

  12.     local read_str     = ''
  13.     local open_state = file_open(file, FA_READ)
  14.     if open_state == true
  15.     then
  16.         --获取当前文件大小
  17.         all_byte = file_size()
  18.         if all_byte > 0
  19.         then
  20.             read_cnt =  math.modf(all_byte/WriteOnceSize)
  21.             if all_byte % WriteOnceSize > 0
  22.             then
  23.                 read_cnt = read_cnt + 1
  24.             end
  25.             my_debug_print('Lua_debug: need read allcnt -> '..read_cnt)

  26.             for i = 1, read_cnt
  27.             do
  28.                 --复位读字节数组
  29.                 read_byte_Tb = {}
  30.                 read_char_Tb = {}

  31.                 --计算读取的偏移位置
  32.                 offset = (i - 1) * WriteOnceSize
  33.                 local offst_result = file_seek(offset)
  34.                 --文件偏移失败
  35.                 if offst_result == false then
  36.                     set_text(sc_prompt, 1, ' When reading the file, an offset error occurred. please try again! ! !')
  37.                     set_text_roll(sc_prompt, 1, 50)
  38.                     change_child_screen(sc_prompt)
  39.                     braek;
  40.                 end
  41.                 my_debug_print('Lua_debug: cur offset  -> '.. offset)

  42.                 --计算本次读的个数
  43.                 count = WriteOnceSize
  44.                 if i == read_cnt
  45.                 then
  46.                     if all_byte % WriteOnceSize > 0
  47.                     then
  48.                         count = all_byte % WriteOnceSize
  49.                     end
  50.                 end
  51.                 my_debug_print('Lua_debug: cur read  -> '..i..'th / wrire count '..count)

  52.                 --读取字节转换为字符并拼接成字符串
  53.                 read_byte_Tb = file_read(count)
  54.                 if #(read_byte_Tb) > 0
  55.                 then
  56.                     for j = 0, #(read_byte_Tb)
  57.                     do
  58.                         read_char_Tb[j + 1] = string.char(read_byte_Tb[j])
  59.                     end
  60.                     read_str = read_str..table.concat(read_char_Tb)
  61.                 elseif read_byte_Tb ==nil
  62.                 then
  63.                     set_text(sc_prompt, 1, ' File read error. please try again! ! !')
  64.                     set_text_roll(sc_prompt, 1, 50)
  65.                     change_child_screen(sc_prompt)
  66.                     braek;
  67.                 end
  68.             end
  69.             my_ShowRecord_FromFile(read_str)
  70.         end
  71.    else
  72.         set_text(sc_prompt, 1, 'The file don`t exist,
  73.                 please check the contents of the SD car! ! !')
  74.         set_text_roll(sc_prompt, 1, 50)
  75.         change_child_screen(sc_prompt)
  76.     end

  77.     --关闭文件
  78.     file_close()
  79. end

  80. --用户通过触摸修改控件后,</font>执行此回调函数。
  81. --点击按钮控件,修改文本控件、修改滑动条都会触发此事件。
  82. function on_control_notify(screen,control,value)

  83.     if screen == sc_ReadFlile and control == 2 and value == 0
  84.     then
  85.         sc_ShowRecord = sc_ReadFlile

  86.         --SD卡是否存在
  87.         if IsinsertSD == 1
  88.         then
  89.             record_clear(sc_ReadFlile, 1)
  90.             my_read_filedata(sd_dir..'/'..'1.txt')
  91.         else
  92.             set_text(sc_prompt, 1, 'Please insert the SD card,
  93.                     or check if the SD is compatible! ! !')
  94.             set_text_roll(sc_prompt, 1, 50)
  95.             change_child_screen(sc_prompt)
  96.         end

  97.     ......
  98.     end
  99. 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

  • offset-文件偏移位置


例如:定位到第2048个字节,file_seek(2048)

4) file_read(count)
读取文件内容,成功返回table数组,失败返回nil

  • count-读取字节数,最大读取2048个字节


例如:读取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所示。

程序清单 2 写文件
  1. <font size="2">--get the type and length of the variable
  2. --@data: 'string' or 'table'
  3. --@return: len and type of data
  4. function my_getdataLen_Type(data)

  5.     my_debug_print('---------- my_getdataLen_Type ----------')
  6.     local datalen = -1
  7.     --获取数据类型
  8.     local data_type = type(data)

  9.     --计算数据长度
  10.     if data_type == 'string'
  11.     then
  12.         datalen = string.len(data)
  13.     elseif data_type == 'table'
  14.     then
  15.         datalen = #(data)
  16.     end
  17.     my_debug_print('Lua_debug data Type and Len: '..data_type..' /'..datalen)

  18.     return datalen,data_type
  19. end

  20. --Write data to the end of the file
  21. --@file:file path
  22. --@data:The type of '@data' only be [string] or [byte array]
  23. --@open_mode:open file mode
  24. function my_write_filedata(file, data, open_mode)

  25.     my_debug_print('---------- my_write_filedata ----------')
  26.     my_debug_print('Lua_debug: file -> '..file..' / data -> '..type(data)..' / open_mode -> '..open_mode)
  27.     local count     = 0
  28.     local write_cnt = 0
  29.     local offset    = 0
  30.     local all_byte  = 0
  31.     --获取待写入数据的数据类型和长度
  32.     local wrire_len, data_type = my_getdataLen_Type(data)

  33.     local write_byte_Tb = {}
  34.     local open_state = file_open(file, open_mode)

  35.     if open_state == true
  36.     then
  37.         --获取当前文件大小,仅在追加文件末尾写入执行
  38.         if open_mode == add_write
  39.         then
  40.             all_byte = file_size()
  41.         end

  42.         if wrire_len > 0
  43.         then
  44.             --计算'@data'要写多少次
  45.             write_cnt =  math.modf(wrire_len / WriteOnceSize)
  46.             if wrire_len % WriteOnceSize > 0
  47.             then
  48.                 write_cnt = write_cnt + 1
  49.             end
  50.             my_debug_print('Lua_debug: need write allcnt -> '..write_cnt)

  51.             for i = 1, write_cnt
  52.             do
  53.                 --复位写字节数组
  54.                 write_byte_Tb = {}

  55.                 --计算写的位置
  56.                 offset = (i - 1) * WriteOnceSize +all_byte
  57.                 local offst_result = file_seek(offset)
  58.                 --文件偏移失败
  59.                 if offst_result == false
  60.                 then
  61.                     set_text(sc_prompt, 1, 'When reading the file, an offset error occurred. please try again! ! !')
  62.                     set_text_roll(sc_prompt, 1, 50)
  63.                     change_child_screen(sc_prompt)
  64.                     break
  65.                 end
  66.                 my_debug_print('Lua_debug: cur offset  -> '..offset)

  67.                 --计算本次写的个数
  68.                 count = WriteOnceSize
  69.                 if i == write_cnt
  70.                 then
  71.                     if wrire_len % WriteOnceSize > 0
  72.                     then
  73.                         count = wrire_len % WriteOnceSize
  74.                     end
  75.                 end
  76.                 my_debug_print('Lua_debug: cur write  -> '..write_cnt..'th /wrire count '..count)
  77.                 --填充写入flash的字节数组
  78.                 for j = 1, count
  79.                 do
  80.                     if data_type == 'string'
  81.                     then
  82.                     --字符串类型,将每个字符转换为字节数组
  83.                     write_byte_Tb[j - 1] = tonumber(string.byte(data, ((i - 1) * WriteOnceSize + j), ((i - 1) * WriteOnceSize + j)))

  84.                     elseif data_type == 'table'
  85.                     then
  86.                         --数组类型,字节赋值
  87.                         write_byte_Tb[j - 1] =
  88.                         data[((i - 1) * WriteOnceSize + j)]
  89.                     end
  90.                 end
  91.                 local IswriteOK = file_write(write_byte_Tb)
  92.                 if IswriteOK == false
  93.                 then
  94.                     i = i - 1
  95.                 end   
  96.             end
  97.         end
  98.     else
  99.         set_text(sc_prompt, 1, 'The file don`t exist, please check the contents of the SD car! ! !')
  100.         set_text_roll(sc_prompt, 1, 50)
  101.         change_child_screen(sc_prompt)   
  102.     end

  103.     --关闭文件
  104.     file_close()
  105. end

  106. --用户通过触摸修改控件后,执行此回调函数。
  107. --点击按钮控件,修改文本控件、修改滑动条都会触发此事件。
  108. function on_control_notify(screen,control,value)
  109.     ......
  110.     --追加写
  111.     elseif screen == sc_WriteFile and control == 3 and value == 0
  112. then
  113.         sc_ShowRecord = sc_WriteFile
  114.         --已插入SD卡
  115.         if IsinsertSD == 1
  116.         then
  117.             record_clear(sc_WriteFile, 1)

  118.             local str = '\n'..get_text(sc_WriteFile, 2)   
  119.             my_write_filedata(sd_dir..'/'..'1.txt', str, add_write)

  120.             my_read_filedata(sd_dir..'/'..'1.txt')
  121.             local allrecordcnt = record_get_count(sc_WriteFile, 1)
  122.             record_setoffset(sc_WriteFile, 1, allrecordcnt - 1)
  123.             record_select(sc_WriteFile   , 1, allrecordcnt - 1)
  124.         --未插入SD卡
  125.         else
  126.             set_text(sc_prompt, 1, 'Please insert the SD card, or check if the SD is compatible! ! !')
  127.             set_text_roll(sc_prompt, 1, 50)
  128.             change_child_screen(sc_prompt)
  129.         end

  130.     --覆盖写
  131.     elseif screen == sc_WriteFile and control == 5 and value == 0
  132.     then
  133.         sc_ShowRecord = sc_WriteFile
  134.         --已插入SD卡
  135.         if IsinsertSD == 1
  136.         then
  137.             record_clear(sc_WriteFile, 1)

  138.             cnt = cnt + 1
  139.             local str = (cnt + 1)..'th write -> '..get_text(sc_WriteFile, 4)
  140.             my_write_filedata(sd_dir..'/'..'NewTxtFile.txt',str,over_write)

  141.             my_read_filedata(sd_dir..'/'..'NewTxtFile.txt')
  142.         --未插入SD卡
  143.         else
  144.             set_text(sc_prompt, 1, 'Please insert the SD card, or check if the SD is compatible! ! !')
  145.             set_text_roll(sc_prompt, 1, 50)
  146.             change_child_screen(sc_prompt)
  147.         end
  148.     ......
  149.     end
  150. 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卡

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
销售与技术支持:(020)82186683-601
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|广州大彩串口屏论坛_大彩开发者交流论坛

GMT+8, 2024-5-15 04:30 , Processed in 0.051132 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表