|
本帖最后由 zyqcome 于 2020-10-13 13:35 编辑
-1- 缘由
Excel 作为数据统计的神奇,能非常方便的筛选和生成各种数据
串口作为嵌入式的常见接口,是个板子都会用到
将二者结合起来使用,
- 方便直观的生成数据
- 在Excel中点击即可通过串口发送
- 在Excel中点击即可从串口读回数据
-2- 实现路径
在实现上,我绕过了用vba底层实现串口读写,采用更熟悉的编程语言生成串口读写 exe, 在通过 Excel vba 调用 cmd 运行 底层 exe。
这样的实现,相当于可以调用任一语言平台打包的 exe,在 exe 中封装底层,为实现更丰富的功能留下可能。
-3- 实现细节
-3.1- Excel文件的区别
- 选择 Excel 后缀为 xlsm 支持宏的文件格式
- alt + F11 打开 vba 编程面板
-3.2- 底层exe实现
这里实现一个最简单串口发送数据
- 我自己选择的实现平台是 C# net4.0 32bit
[**]net4.0 默认支持win7 (目前没有布置win7环境来测试)
[**]我对 c# 相对要熟悉一些 - 这里加了些编程内容
[**]对串口配置以xml文件的形式保存,在每次点击的时候读入配置,这样的实现只在excel点击时候占用串口
[**]封装了查找当前目录的实现
[**]封装了串口配置的序列化和反序列化
[**]对串口open失败的可能做了处理,但没有打印失败信息,为从串口读值留下打印信息
代码实现
- class Program
- {
- private static MySerialPort _serialPort;
- private static ServiceConfigModel _serviceConfigModel;
- static void Main(string[] sss)
- {
- byte[] result = CommonTool.HexStringToByteArray(sss[0]);
- if (result == null)
- {
- return;
- }
- string path = CommonTool.GetDirectory() + @"\ConsoleAppConfig.xml";
- _serviceConfigModel = new ServiceConfigModel();
- _serviceConfigModel = SerializeTool<ServiceConfigModel>.ReadXML(path);
- _serialPort = new MySerialPort();
- _serialPort.ConfigService(_serviceConfigModel.PortName, _serviceConfigModel.ConfigDates);
- try
- {
- _serialPort.Open();
- _serialPort.Write(result, 0, result.Length);
- _serialPort.Close();
- }
- catch
- {
- _serialPort = null; // 其实这个没必要,当总要放点啥在这才安心
- }
- }
- }
复制代码
代码就是一个很简单的控制台程序
-3.3- Excel的命令行调用
这个实现是对比了几种实现,搜了好一通才找到了,目前这种实现基本满意,唯一的不好的地方是 cmd 窗口会弹一下,目前把它当成有没有成功调用的提醒
在 excel vba 中添加一个模块,注意是添加一个模块 键入以下内容
- Public Sub SendStringNoRead(abc As String)
- Dim strProgramName As String
- strProgramName = Application.ActiveWorkbook.Path & "\ConsoleApp.exe " & abc
- ShellRun (strProgramName)
- End Sub
- '网上搜到的实现
- Public Function ShellRun(sCmd As String) As String
- 'Run a shell command, returning the output as a string
- Dim oShell As Object
- Set oShell = CreateObject("WScript.Shell")
- 'run command
- Dim oExec As Object
- Dim oOutput As Object
- Set oExec = oShell.Exec(sCmd)
- Set oOutput = oExec.StdOut
- 'handle the results as they are written to and read from the StdOut object
- Dim s As String
- Dim sLine As String
- While Not oOutput.AtEndOfStream
- sLine = oOutput.ReadLine
- If sLine <> "" Then s = s & sLine & vbCrLf
- Wend
- ShellRun = s
- End Function
复制代码
SendStringNoRead这个函数的功能是
- 接收单击单元格的值-就是输入参数
- 给出 exe 的路径 并把 命令行参数拼上去
- 调用函数 ShellRun 实现exe执行
-3.4- Excel单击发送的实现
- 在对应的 Sheet对象上双击
- 选择 Worksheet 中的 SelectionChange
键入下面的代码
- Private Sub Worksheet_SelectionChange(ByVal Target As Range)
- If Target.Column = 11 Then
- If Target.Count = 1 Then
- If Target.Value <> "" Then
- SendStringNoRead (Target.Value)
- End If
- End If
- End If
- End Sub
复制代码
要解释一下,这几个if
- Target.Column = 11 选择的 第11列
- Target.Count = 1 筛出单个格子点击的情况
- Target.Value <> "" 单个格子的内容不为空
tip:这里有个地方,命令行是以空格分割参数的,我不想再往字符串上加双引号,所以Excel生成的命令不能有空格(这个可以在 Excel 中观察到)
-4- 往后的方向
- 加入可配置的读串口
- 加入 modbus 协议
- 等等,待更新
-5- 测试指南
建议先通过虚拟串口,用命令行中测试 exe 能否使用
假设有两个直连的串口 COM2 <----> COM1
在命令行中
- //xml中配置 COM2
- >ConsoleApp.exe A55A0582036B0001
- >_
复制代码
在另一个串口调试器中连接 COM1
- [10:28:27.789]收←◆ A5 5A 05 82 03 6B 00 01
复制代码
测试文件下载 -- 文件是在实际的文件中简化的,所有不用奇怪 Excel 的空格 另外有异常报告可以留言
添加一个图片说明吧
排版还是有些不好用
你也可以看markdown 的博客 link
----修改记录---
0 添加博客链接
1 修改排版
2 添加图片说明
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|