Fonctionnement en série de la bibliothèque 1-python

Le fonctionnement du port série peut être utilisé dans le processus de débogage des périphériques embarqués quotidiens, et il est très pratique. Le plus gênant devrait être le traitement de réception hexadécimal.

La bibliothèque série est utilisée pour faire fonctionner le port série en Python. Le processus d'utilisation de la série est similaire à celui habituel, qui est également ouvert, fermé, lu, écrit

1. Ouvrez le port série

Généralement, il s'agit de régler le port et la vitesse de transmission.

Lorsque vous utilisez serial.Serial pour créer une entité, vous ouvrez le port série, puis vous pouvez utiliser is_open pour déterminer si le port série est ouvert normalement.

def DOpenPort(portx, bps, timeout):
    try:
        # 打开串口,并得到串口对象
        ser = serial.Serial(portx, bps, timeout=timeout)
        # 判断是否打开成功
        if(False == ser.is_open):
           ser = -1
    except Exception as e:
        print("---异常---:", e)

    return ser

2. Fermez le port série

Utilisez ser.close pour fermer le port série

def DColsePort(ser):
    uart.fdstate = -1
    ser.close()

3. Écrire des données

Les données sont écrites à l'aide de l'interface ser.write. Si vous écrivez des données hexadécimales, utilisez bytearray pour définir, par exemplewritebuf = bytearray([0x55, 0xaa, 0x00, 0x01, 0x00, 0x00])

def DWritePort(ser, data):
    result = ser.write(data)  # 写数据
    logging.info(ser)
    logging.info("Write %s(%d)" % (data.hex(), result))
    return result

4. Lisez les données

Lisez les données à l'aide de l'interface ser.read, utilisez généralement in_waiting pour déterminer s'il y a des données, puis commencez à lire

# 十六进制显示
def hexShow(argv):
    try:
        result = ''
        hLen = len(argv)
        for i in range(hLen):
            hvol = argv[i]
            hhex = '%02x' % hvol
            result += hhex+' '

        logging.info('Led Read:%s', result)
        return result
    except Exception as e:
        print("---异常---:", e)



def DReadPort(ser):
    # 循环接收数据,此为死循环,可用线程实现
    readstr = ""
    if ser.in_waiting:
        readbuf = ser.read(ser.in_waiting)
        if readbuf[0] == 0x55 and readbuf[1] == 0xaa:
            readstr = readbuf
        else:
            readstr = readstr + readbuf

        hexShow(readstr)

5. Exemples

Voici un exemple pour illustrer notre utilisation réelle.

Généralement, un processus sera créé séparément pour recevoir les données, puis la logique sera traitée avec le bit d'étiquette ou le sémaphore.

import serial  # 导入模块
import threading
import time
import logging
import sys


class UartInfo(object):
    def __init__(self, fd, count, fail):
        self.fd = fd
        self.count = count  # 测试次数
        self.fail = fail  # 失败次数

    response = False
    image_addr = 0x00
    image_crc = 0x00
    version = 0
    write_event = threading.Event()


uart = UartInfo(-1, 0, 0)


def logging_init():
    logging.basicConfig(#  filename="test.log", # 指定输出的文件
        level=logging.DEBUG,
        format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')

    return True


# 十六进制显示
def hexShow(argv):
    try:
        result = ''
        hLen = len(argv)
        for i in range(hLen):
            hvol = argv[i]
            hhex = '%02x' % hvol
            result += hhex+' '

        logging.info('Led Read:%s', result)
        return result
    except Exception as e:
        print("---异常---:", e)


def crc_sum(data, data_len):
    crc = 0
    i = 0
    while(i < data_len):
        crc += data[i]
        i += 1
    return crc & 0x00FF


def crc_sum_u32(data, data_len):
    crc = 0
    i = 0
    while(i < data_len):
        crc += data[i]
        i += 1
    return crc

# 打开串口
def DOpenPort(portx, bps, timeout):
    try:
        # 打开串口,并得到串口对象
        ser = serial.Serial(portx, bps, timeout=timeout)
        # 判断是否打开成功
        if(False == ser.is_open):
           ser = -1
    except Exception as e:
        print("---异常---:", e)

    return ser


# 关闭串口
def DColsePort(ser):
    uart.fdstate = -1
    ser.close()


# 写数据
def DWritePort(ser, data):
    result = ser.write(data)  # 写数据
    logging.info(ser)
    logging.info("Led Write %s(%d)" % (data.hex(), result))
    return result


# 读数据
def ReadData_Thread(ser):
    # 循环接收数据,此为死循环,可用线程实现
    readstr = ""
    while(-1 != ser):
        if ser.in_waiting:
            try:  # 如果读取的不是十六进制数据--
                readbuf = ser.read(ser.in_waiting)
                if readbuf[0] == 0x55 and readbuf[1] == 0xaa:
                    readstr = readbuf
                else:
                    readstr = readstr + readbuf

                hexShow(readstr)

                if (readstr[3] == 0x01) and (len(readstr) > 10):
                    uart.version = readstr[16]
                    uart.response = True
                    uart.write_event.set()
                elif (readstr[3] == 0x21) and (readstr[4] == 0x00) and (readstr[5] == 0x00):
                    uart.response = True
                    uart.write_event.set()
                elif (readstr[3] == 0x22) and (len(readstr) > 10):
                    uart.image_addr = (readstr[6] << 24 & 0xFF000000)
                    uart.image_addr += (readstr[7] << 16 & 0x00FF0000)
                    uart.image_addr += (readstr[8] << 8 & 0x0000FF00)
                    uart.image_addr += (readstr[9] << 0 & 0x000000FF)
                    uart.response = True
                    uart.write_event.set()
                elif (readstr[3] == 0x23) and (len(readstr) > 25):
                    uart.response = True
                    uart.write_event.set()

            except:  # --则将其作为字符串读取
                readbuf = ser.read(ser.in_waiting)
                hexShow(readbuf)


def GetVersion(ser):
    print("GetVersion")
    writebuf = bytearray([0x55, 0xaa, 0x00, 0x01, 0x00, 0x00])
    # crc
    writebuf.append(crc_sum(writebuf, len(writebuf)))
    DWritePort(ser, writebuf)

    logging.info("take")
    uart.response = False
    uart.write_event.clear()
    uart.write_event.wait(timeout=3)
    uart.write_event.clear()
    logging.info("give")
    if uart.response == False:
        logging.info("fail")
        return False
    else:
        return True
        

# 测试任务
def Test_Thread(ser):
    while (-1 != ser):
        uart.response = False
        uart.image_addr = 0x00
        uart.image_crc = 0x00
        uart.version = 0
        logging.info("count:%d", uart.count)
        logging.info("fail:%d", uart.fail)
        print("count", uart.count)
        print("fail", uart.fail)

        if GetVersion(ser):
            logging.info(uart.version)
            if uart.version == 0x37:
                otafile = "./UartV108.bin"
            else:
                otafile = "./UartV107.bin"
        else:
            uart.fail += 1
            uart.count += 1
            continue

        print("ota:", otafile)
        logging.info("ota:%s", otafile)
        time.sleep(2)

        uart.count += 1
        time.sleep(5)


def TestStop(ser):
    DColsePort(uart.fd)  # 关闭串口


if __name__ == "__main__":
    if 2 != len(sys.argv):
        print("please enter COM")
        exit()
    else:
        uart.tty = sys.argv[1]

    logging_init()
    uart.fd = DOpenPort(uart.tty, 115200, None)

    if(uart.fd != -1):  # 判断串口是否成功打开
        threading.Thread(target=Test_Thread, args=(uart.fd,)).start()
        threading.Thread(target=ReadData_Thread, args=(uart.fd,)).start()


Publié 106 articles originaux · loué 76 · 130 000 visites +

Je suppose que tu aimes

Origine blog.csdn.net/Creator_Ly/article/details/104379479
conseillé
Classement