关于串口上位机编程的背景知识
1、串行通信简介
串行通信是一种数据传输方式,它将数据位逐个按照顺序传输,相对于并行通信而言,串行通信只需要一根传输线路,因此更加简单和经济。在串行通信中,数据位按照一定的格式进行传输,通常包括以下几个要素:
1.1、起始位(Start Bit):表示数据传输开始的信号,通常为低电平。
1.2、数据位(Data Bits):表示要传输的数据,可以是一个字节(8位)或者其他长度。
1.3、校验位(Parity Bit):用于校验数据的正确性,通常为奇偶校验位。
1.4、停止位(Stop Bit):表示数据传输结束的信号,通常为高电平。
串行通信的传输速率由波特率(Baud Rate)决定,波特率表示每秒钟传输的位数。常见的波特率有9600、115200等。串行通信常用的接口有RS-232、RS-485、USB等,每种接口有自己的规范和特点。串行通信在许多领域得到广泛应用,例如计算机与外部设备的通信、嵌入式系统的通信、工业自动化控制系统等。它具有传输距离远、抗干扰性强、传输速率高等优点,因此被广泛采用。串行通信是一种简单、经济且可靠的数据传输方式,通过按顺序逐位传输数据,实现设备之间的数据交换和通信
2、串行参数配置
2.1、端口 port : [com1、com2、等]指使用哪个串行端口通信。
2.2、波特率 Baud Rate : [2400、4800、9600、19200 等]
这是一个衡量符号传输速率的参数。指的是信号被调制以后在单位时间内的变化,即单位时间内载波参数变化的次数,如每秒钟传送240个字符,而每个字符格式包含10位(1个起始位,1个停止位,8个数据位),这时的波特率为240Bd,比特率为10位*240个/秒=2400bps。高波特率常常用于放置的很近的仪器间的通信
2.3、数据位 Data Bits : [5、6、7、8]
这是衡量通信中实际数据位的参数。当计算机发送一个信息包,实际的数据往往不会是8位的,标准的值是6、7和8位。
2.4、停止位 Stop Bits : [1、1.5、2]
用于表示单个包的最后一位。典型的值为1,1.5和2位。由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。串口通信首先是设置波特率,由此决定每位数据在线上维持的时间。以传输1bit所需要的时间作为一个单位时间。1位停止位表示 停止信号在线上维持一个单位时间。2位停止位表示 停止信号在线上维持两个单位时间。
2.5、奇偶校验位 Parity : [Odd、Even、NONE、Mark、Space]奇偶校验是对数据传输正确性的一种校验方法。在数据传输前附加一位奇校验位,用来表示传输的数据中"1"的个数是奇数还是偶数,为奇数时,校验位置为"0",否则置为"1",用以保持数据的奇偶性不变。
Odd:奇校验
Even:偶校验
NONE:无校验
Mark:校验位始终为1(不常用)
Space:校验位始终为0(不常用)
3、串口通信相关的硬件知识
3.1、单工通信(Simplex):单工通信是指数据只能在一个方向上进行传输的通信方式。在单工通信中,数据只能从发送端传输到接收端,不能进行双向数据传输。
3.2、半双工通信(Half Duplex):半双工通信是指数据可以在两个方向上进行传输,但不能同时进行。在半双工通信中,发送端和接收端可以交替地发送和接收数据,但不能同时进行。
3.3、全双工通信(Full Duplex):全双工通信是指数据可以在两个方向上同时进行传输的通信方式。在全双工通信中,发送端和接收端可以同时进行数据的发送和接收,实现双向的数据传输。
3.4、RS-232:RS-232是一种常见的串口通信标准,用于计算机与外部设备之间的通信。RS-232是一种单工、点对点的串口接口,支持较短的传输距离(一般为15米左右),常用于个人电脑、终端设备等。
3.6、RS-232的特点:使用异步传输方式,即数据传输不依赖于时钟信号。通信速率较低,常见的波特率为9600、115200等。使用DB9或DB25接头连接,包括发送线、接收线、地线和控制线等。
3.7、RS-485:RS-485是一种多点、半双工的串口通信标准,常用于工业自动化控制系统等领域。RS-485支持较长的传输距离(最高可达1200米),可以连接多个设备。
3.8、RS-485的特点:支持多点连接,多个设备可以共享同一条总线。采用差分信号传输,具有较强的抗干扰能力。通信速率较高,常见的波特率为9600、115200等。使用RJ45或其他连接器连接,包括发送线、接收线和地线等
4、软件实现串口通信的相关知识
串口通信库/API:编程语言通常提供了相应的串口通信库或API,用于进行串口的打开、关闭、读取和写入等操作。这些库或API提供了一系列函数或方法,供开发者调用来实现串口通信。
4.1、打开串口:首先需要通过串口通信库或API打开串口,指定串口的端口号、波特率、数据位、停止位、校验位等参数。
4.2、读取数据:通过串口通信库或API读取串口接收缓冲区中的数据。可以使用阻塞模式或非阻塞模式进行读取操作。
4.3、写入数据:通过串口通信库或API向串口发送数据。可以将数据写入发送缓冲区,等待串口发送。
4.4、关闭串口:当串口通信结束后,需要通过串口通信库或API关闭串口,释放相关资源
5. 阻塞模式、非阻塞模式
在开发上位串口中,在初始化串口的时候,可以选择是“阻塞模式”或“非阻塞模式”,这个模式选择只影响串口接收函数:
5.1、阻塞模式:调用接收函数后,接收函数阻止程序继续运行,直到收到串口数据
python代码实现阻塞模式单线程伪代码
import serial
# 打开串口
ser = serial.Serial('COM1', 9600)
# 读取数据
data = ser.read(10) # 读取10个字节的数据
# 写入数据
ser.write(b'Hello World') # 向串口写入数据
# 关闭串口
ser.close()
python代码实现阻塞模式多线程伪代码
import serial
import threading
def read_from_serial(ser):
while True:
data = ser.read(10) # 读取数据
print('Received:', data)
def write_to_serial(ser):
while True:
data = input('Enter data to send: ')
ser.write(data.encode()) # 写入数据
# 打开串口
ser = serial.Serial('COM1', 9600)
# 创建读取线程
read_thread = threading.Thread(target=read_from_serial, args=(ser,))
read_thread.start()
# 创建写入线程
write_thread = threading.Thread(target=write_to_serial, args=(ser,))
write_thread.start()
# 等待线程结束
read_thread.join()
write_thread.join()
# 关闭串口
ser.close()
5.2、非阻塞模式:调用接收函数之后,函数判断串口接收缓存是否有数据,有则返回数据,没有则之间返回0,即,无论收到或没有收到数据,接收函数都不阻塞程序继续运行。
6、上位机实现查找串口设备的原理
6.1、遍历串口号:上位机程序会遍历一定范围内的串口号,通常从1到最大串口号(如COM1、COM2、COM3...)。
6.2、尝试打开串口:对于每个串口号,上位机程序会尝试打开该串口。如果成功打开,说明该串口号对应的设备存在。
6.3、发送查询命令:一旦成功打开串口,上位机程序会向该串口发送一个特定的查询命令。这个查询命令是预先定义好的,可以是一个特定的字节序列或者字符串。
6.4、等待设备响应:上位机程序会等待一定时间,通常是几百毫秒,以确保串口设备有足够的时间进行响应。
6.5检查响应数据:如果在等待时间内收到了设备的响应数据,上位机程序会判断该串口号对应的设备是有效的,并将其列为可用的串口设备。
6.6、关闭串口:无论是否有设备响应,上位机程序都会关闭当前打开的串口。
6.7、继续遍历其他串口号:上位机程序会继续遍历其他未尝试的串口号,重复上述步骤,直到遍历完所有的串口号。
6.8、返回可用串口列表:最终,上位机程序会返回一个可用的串口设备列表,供用户选择和使用。需要注意的是,不同的操作系统和编程语言可能有不同的实现方式,但基本原理是类似的。通过遍历串口号、尝试打开串口、发送查询命令并等待设备响应,上位机程序可以实现查找串口设备的功能。