VS2022C#语言实现上位机通信,算是实况?
前期已经有了:Keil5代码,基于STM32,使用串口通信,同时遵循Modbus_RTU通信协议。
学习过程:分为多个小部分,如下逐点描述。
1.学习并总结C#基础语法
using: 包含命名空间,写在程序开头,类似KEIL的import。有官方的“库”,也有自己写的同项目其他cs文件的命名空间。
1 2
| using System.IO.Ports; using PC_code_test.Model;
|
命名空间:使用namespace开辟,其中可以定义变量、编写方法等。一个cs文件可以有多个命名空间。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| using System; namespace first_space { class namespace_cl { public void func() { Console.WriteLine("Inside first_space"); } } } namespace second_space { class namespace_cl { public void func() { Console.WriteLine("Inside second_space"); } } } class TestClass { static void Main(string[] args) { first_space.namespace_cl fc = new first_space.namespace_cl(); second_space.namespace_cl sc = new second_space.namespace_cl(); fc.func(); sc.func(); Console.ReadKey(); } }
|
注释:单行// 多行/ / 开辟新空间#region(可以直接加文字) #endregion
方法:类似C语言的函数,输入+执行一系列任务+输出。输入可为空(),输出可为空void。
1 2 3 4 5 6
| <Access Specifier> <Return Type> <Method Name>(Parameter List) { Method Body }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| using System; class NumberManipulator { public int FindMax(int num1, int num2) { int result; if (num1 > num2) result = num1; else result = num2; return result; } public void PrintMax(int a, int b) { int max = FindMax(a, b); Console.WriteLine("{0} 和 {1} 的最大值是 {2}", a, b, max); } static void Main(string[] args) { NumberManipulator nm = new NumberManipulator(); int result = nm.FindMax(100, 200); Console.WriteLine("100 和 200 的最大值是 {0}", result); Console.ReadKey(); } } class TEST { public static void text() { NumberManipulator nm = new NumberManipulator(); int result = nm.FindMax(10, 20); Console.WriteLine("最大值是:" + result); Console.ReadKey(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| using System; class NumberManipulator { public static int FindMax(int num1, int num2) { return num1 > num2 ? num1 : num2; } static void Main(string[] args) { int r2 = NumberManipulator.FindMax_Static(100, 200); Console.WriteLine("静态方法结果:" + r2); Console.ReadKey(); } }
|
class: 声明一个类,类不定义任何数据,只是一个蓝图,说明了xx的名称,数据类型,访问规则。由类造出来的具体东西就是实例。
实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| using System; namespace BoxApplication { class Box { public double length; public double breadth; public double height; } class Boxtester { static void Main(string[] args) { Box Box1 = new Box(); Box Box2 = new Box(); double volume = 0.0;
Box1.height = 5.0; Box1.length = 6.0; Box1.breadth = 7.0;
Box2.height = 10.0; Box2.length = 12.0; Box2.breadth = 13.0; volume = Box1.height * Box1.length * Box1.breadth; Console.WriteLine("Box1 的体积: {0}", volume); Console.ReadKey(); } } }
|
2.找到串口助手代码并学习
看起来蛮简单的哎,感觉逻辑上能“记住”很麻烦。所以一定要写注释!!!尤其是变量!!!
大体做的事情就是,判断串口打开关闭,读数据&写数据。注意数据格式的处理。
3.学习modbus协议
依旧整合知乎经验贴,CSDN资源,github代码,B站视频和商家说明书……
好像每次学习东西都是从四面八方东拼西凑,直到信息在脑海中整合了70%以上,才能够看出问题如何解决。(思维很发散,逻辑不清晰)
下载并使用到的工具:(当然也包括VS2022,很多功能自己写也可以的)
| Xcom |
很正常的串口助手,能够收发信息,满分 |
| modbusSlave |
模拟modbus协议从设备,满分 |
| modbuspoll |
模拟modbus协议主设备,满分 |
| Configure Virtual Serial Port Driver |
提供虚拟串口连接,满分 |
| 串口监听工具,我没找到能用的 |
理论上能在串口工作的时候监听这个串口读/写的数据 |
事实上我一开始拿到的是八千多行的工业化上位机代码,一开始的心理预期也是程序会非常复杂,加上之前没接触过C#,哪怕是在AI的帮助下,也没找到具体的收发数据流。而且还认为“硬件开始工作按钮”是需要很多类、状态机、处理多线程等等一层套一层的操作之后才能实现的。
之后看到了命令之下串口的收发数据流,只有
1
| 01 10 00 3B 00 01 02 00 04 A3 18
|
这一串数据。也就是说,我就算写一个
1 2
| byte[] data = new byte[] { 0x01, 0x10, 0x00, 0x3B, 0x00, 0x01, 0x02, 0x00, 0x04, 0xA3, 0x18 }; serialPort1.Write(data, 0, data.Length);
|
单片机也就开始工作了。(硬件是好用的,提前写好了通信协议)
之后为了不用记这么长串数字,使用了modbus类,每次使用都创建实例,不用明文摆在台面上了。
看起来我又把问题想得太复杂了,怎么能困在这里两个星期呢?!(DDL万岁(很抱歉说出这句话,但是好像到了紧急的时候我才能放下所有情绪,只是解决问题))