第四阶段C#通讯开发-1:通讯基础理论,串口,通讯模式,单位转换,代码示例
1_通讯基础理论
1.1_基础理论
(1)通讯:一般发生在两端或多端,两端之间的通讯,一端负责发送信息,一端负责接收信息。
(2)C#中的通讯两大块
-
串口通讯:串口通讯有距离限制,且速度慢
-
网络通讯:而网络通讯传输距离远,且速度快
1.2_通讯协议
(1)通讯的双方要【遵循约定好的数据格式,专业:数据报文,是通讯协议中的数据帧】,双方才能通讯,这些约定的规则,称为通讯协议。
(2)串口通讯协议:串口通讯协议:串口通讯执行标准。常见的协议:RS232,RS485,Modbus(通用),西门子S7协议等
https://blog.csdn.net/weixin_41442949/article/details/138337602
(3)网络通讯协议:即制定的网络通讯标准。常见的协议:TCP, UDP, HTTP, HTTPS, STMP等。
在网络通讯中,一端称为服务器(Server);另一端称为客户端(Client),可以有多个客户端。 服务器也可以称为主机(Host),客户端也可以称为从机(Slave奴隶)
(4)数据帧格式:即数据报文
RS232:https://baike.baidu.com/item/RS-232/2022036
2_串口
2.1_串口概念
(1)串口英文:serial port
串口通信是一个广泛使用的【数字通信协议】,它用于在两个设备之间通过【专门设计的线路】(称为串行端口)传输数据。串口通信可以使计算机与外部设备进行【可靠地点对点连接】,例如打印机、调制解调器、传感器等。串口通信允许将信息从计算机中发送到其他设备,或者从其他设备中接收信息并传递回计算机。通常情况下,串口通信需要指定一些参数,如【传输速率】、【校验方式】、【数据位数】和【停止位】等来保证传输数据的准确性。
(2)串行端口:也称串行通信接口或COM接口,简称串口。 串口端口按电气标准及协议来划分,包括【RS-232】,RS-232-C、RS-422、【RS485】,USB等
(3)点对点连接:即端对端连接 Point To Point。E2E:End To End。 P2P PTP E2E;COM===>Component组件
(4)串口需要两个设备,一个主机(也叫主站,类似于网络通讯中的服务器),一个从机(也叫从站,类似于网络通讯中客户端)
(5)波特率:传输的速度,单位:每秒比特数(bps),常用的波特率:传输波特率600bps,1200bps,2400bps,4800bps,9600bps,19200bps,38400bps
2.2_串口通讯原理
(1)串行数据传输是通过【单个线路】按【顺序地】发送一个【比特的信息】。与串行相反,还有并行数据传输方式,该方式使用多个少量且同时传输的信道
(2)比特:指发送的消息的单位,bit,位,按位传递数据。 8bit = 1字节
串行数据:单个线路(一根线,一个信道),按顺序传输(即同步传输)
并行数据:多个信道,可以同时传输(即异步传输)
2.3_串口数据传输方式:同步,异步
串口通讯有两种传递方式:同步(串行),异步(并行)
2.4_串口通讯数据格式
(1)串口通讯数据格式:一个完整的串口数据格式包括起始位、数据位、校验位、停止位几个参数。 起始位(1bit)+ 数据位(8bit)+ 奇偶校验位(1bit)+ 停止位(1bit)组成;
(2)串口通讯数据格式中几个重要的部分
【波特率】: 波特率表示信息传送的速率,是计算机与外设设备进行通信的重要参数。通俗地说,波特率描述的是单位时间内传输的比特数。波特率一般用“bps”来表示,它的单位为位/秒。串口常用的波特率有9600、115200、38400等,常用于MCU(单片机)与计算机之间的通信。通信设备使用串口通信时,波特率必须相同,否则会导致数据传输出错。
【数据位数】: 数据位数表示接收和发送的数据字节数。一般情况下,常用的数据位数为7位或8位,而在通常的情况下默认使用8位数据位数。数据位数的选择取决于所传输的数据格式以及传输需要的准确度和速度。
【校验位】: 校验位是为了保证接收到的数据的准确性而设置的一个位。校验位主要有三种方式,分别为奇校验、偶校验和无校验。奇校验是指在数据位数上奇数的传输信息完成后,将其全部加起来,如果结果为奇数则校验位为0,否则为1。偶校验则是将其全部加起来,如果结果为偶数,则校验位为0,否则为1。无校验是指在数据传输后不对数据进行任何的校验位检验。
0000 0001=1 奇数位全部加起来 1 校验0 0000 0010=2 奇数位全部加起来 0 校验1
Even 2 | 设置奇偶校验位,使位数等于偶数。 |
---|---|
Mark 3 | 将奇偶校验位保留为1。 |
None 0 | 不发生奇偶校验检查。 |
Odd 1 | 设置奇偶校验位,使位数等于奇数。 |
Space 4 | 将奇偶校验位保留为0。 |
【停止位】: 停止位指的是数据传输完成后发送器发送的一位信号。其目的是告诉接收器,本次数据传输已经结束。例如,对于8位数据加一位停止位,停止位为1,这样就能够表示出本次的数据传输已经结束。
3_通讯模式:
单工模式 半双工模式 全双工模式
https://blog.csdn.net/craftsman2020/article/details/127879721
串口通讯是全双工通讯。
4_单位转换
(1)1024位是多少字节?8bit==1byte
8位等于1字节,1024位等于128字节
(2)类型转换
-
Encoding.UTF8.GetString() 将字节数组转换成字符串
-
Encoding.UTF8.GetBytes() 将字符串转换成字节数组
(3)换行符:Environment.NewLine
(4)手动调用事件处理函数
-
btnSend_Click(null,null);
-
btnSend?.PerformClick()
5_代码示例
(1)串口通讯建立连接 要依赖 SerialPort对象,erialPort 需要实例化 可以直接new 也可以从工具箱中拖拽
(2)SerialPort常用属性和方法
属性/方法 | 说明 |
---|---|
PortName | 端口,默认COM1 |
BaudRate | 波特率,默认9600 |
DataBits | 数据位,默认8 |
StopBits | 停止位,默认One |
IsOpen | 串口是否已经打开 |
Open() | 打开串口 |
Close() | 关闭串口 |
Write(),WriteTimeout(),WirteLine() | 写数据(发送数据 |
ReadByte(),ReadChar(),ReadExisting() | 读数据(接收数据) |
ReadLine(),ReadTimeout(),ReadTo() | 读数据(接收数据) |
DataReceived事件 | 接受数据的时候引发的事件 |
//1.SerialPort 需要实例化 可以直接new 也可以从工具箱中拖拽SerialPort serialPort1=new SerialPort();
//2.SerialPort 实例化之后 需要配置属性(串口名称,波特率,奇偶校验,数据为,停止位)
serialPort1.PortName = RtbReceiveData.Text.Trim();
//设置波特率:常用波特率:300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200
serialPort1.BaudRate=Convert.ToInt32(cbbBaudRate.Text);
//停止位,注意: 停止位是一个枚举类型
//public enum StopBits{None, One, Two, OnePointFive }
serialPort1.StopBits=(StopBits)Enum.Parse(typeof(StopBits), cbbStopBits.SelectedValue.ToString());
//设置数据位
serialPort1.DataBits=Convert.ToInt32(cbbDataBits.Text);
//校验位:也是一个枚举类型
//public enum Parity{None, Odd, Even, Mark, Space}
serialPort1.Parity= (Parity)Enum.Parse(typeof(Parity), cbbParity.SelectedValue.ToString());
//3.打开串口
if (!serialPort1.IsOpen)
{serialPort1.Open();MessageBox.Show("串口打开成功");
}
//4.发送数据
serialPort1.Write(TxtData.Text);
//5.接收数据,使用serialPort1_DataReceived事件,需要注意,这是再在分线程中
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{//sender 就是触发这个事件的控件 也就是serialPort1//获取到串口对象SerialPort sp =sender as SerialPort;// serialPort1//获取到接收的数据string res= sp.ReadExisting();Invoke(new Action(() =>{RtbEceciveData.Text = res;}));
}