欢迎访问宙启技术站
智能推送

使用ctypes.windll在Python中实现对Windows系统串口通信的控制

发布时间:2024-01-02 12:12:07

Python中可以使用ctypes库来调用Windows系统中的动态链接库(DLL)函数,从而实现对串口的控制。

首先,需要确保在Windows系统中已经安装了串口驱动,并且将串口设备连接到计算机上。然后在Python中导入ctypes库:

import ctypes

接下来,可以使用ctypes.windll来加载Windows系统提供的DLL库,并获得一个可以调用DLL函数的对象。

ser = ctypes.windll.LoadLibrary("kernel32.dll")

然后,可以使用该对象来调用DLL函数进行串口的打开、关闭、设置通信参数等操作。以下是几个常用的函数的调用方式,并给出了一个完整的串口通信的例子。

### 打开串口

hSerial = ser.CreateFileA("COM1", ctypes.c_uint32(0x80000000), 0, None, 3, 0, None)

其中, 个参数是串口的名称,可以是COM1、COM2等;第二个参数是打开模式,0x80000000表示以读写方式打开串口;其他参数分别表示文件的属性、共享模式、安全属性等,可以按需修改。

### 设置串口参数

dcb = ctypes.create_string_buffer(12)
ser.GetCommState(hSerial, ctypes.byref(dcb))
ctypes.memmove(ctypes.addressof(dcb.c_cc), b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 12)
dcb.BaudRate = 9600
dcb.ByteSize = 8
dcb.fParity = 0
dcb.StopBits = 0
ser.SetCommState(hSerial, ctypes.byref(dcb))

首先,使用GetCommState函数获取串口当前的配置信息,然后使用memmove函数将接收和发送缓冲区大小设置为0,以清空缓冲区。接下来,设置波特率为9600,数据位为8位,无校验位,停止位为1位,最后使用SetCommState函数将设置应用到串口。

### 读取串口数据

buf = ctypes.create_string_buffer(100)
nBytes = ctypes.c_uint32()
ser.ReadFile(hSerial, ctypes.byref(buf), ctypes.sizeof(buf), ctypes.byref(nBytes), None)
data = buf.raw[:nBytes.value]

使用ReadFile函数从串口读取数据,将数据读取到缓冲区buf中,然后截取有效数据,并存储到变量data中。

### 写入串口数据

buf = ctypes.create_string_buffer(b'Test')
nBytes = ctypes.c_uint32()
ser.WriteFile(hSerial, ctypes.byref(buf), ctypes.sizeof(buf), ctypes.byref(nBytes), None)

使用WriteFile函数将数据写入串口,将数据存储在缓冲区buf中,然后将数据长度存储在变量nBytes中。

### 关闭串口

ser.CloseHandle(hSerial)

使用CloseHandle函数关闭串口。

下面是一个完整的串口通信的例子,可以通过调用相应的函数进行打开、关闭、设置参数、读取和写入操作。

import ctypes

ser = ctypes.windll.LoadLibrary("kernel32.dll")

def open_serial_port(port_name):
    hSerial = ser.CreateFileA(port_name, ctypes.c_uint32(0x80000000), 0, None, 3, 0, None)
    return hSerial

def close_serial_port(hSerial):
    ser.CloseHandle(hSerial)

def set_serial_port_parameters(hSerial, baud_rate, data_bits=8, parity=0, stop_bits=0):
    dcb = ctypes.create_string_buffer(12)
    ser.GetCommState(hSerial, ctypes.byref(dcb))
    ctypes.memmove(ctypes.addressof(dcb.c_cc), b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 12)
    dcb.BaudRate = baud_rate
    dcb.ByteSize = data_bits
    dcb.fParity = parity
    dcb.StopBits = stop_bits
    ser.SetCommState(hSerial, ctypes.byref(dcb))

def read_serial_data(hSerial, nBytes):
    buf = ctypes.create_string_buffer(nBytes)
    nBytesRead = ctypes.c_uint32()
    ser.ReadFile(hSerial, ctypes.byref(buf), nBytes, ctypes.byref(nBytesRead), None)
    data = buf.raw[:nBytesRead.value]
    return data

def write_serial_data(hSerial, data):
    buf = ctypes.create_string_buffer(data)
    nBytesWritten = ctypes.c_uint32()
    ser.WriteFile(hSerial, ctypes.byref(buf), len(data), ctypes.byref(nBytesWritten), None)

# 测试例子
hSerial = open_serial_port("COM1")
set_serial_port_parameters(hSerial, 9600)
write_serial_data(hSerial, b'Test')
data = read_serial_data(hSerial, 100)
close_serial_port(hSerial)

以上就是使用ctypes.windll在Python中实现对Windows系统串口通信的控制的方法和示例。可以根据具体需求,调用相应的函数进行操作。