将 0 到 255 转换为单个字符

问题描述 投票:0回答:1

我正在尝试将 0 到 255 之间的值转换为单个字符。 我正在使用 chr。但这会以某种方式将 255 这样的数字转换为两个字符的字符串。 我将这些值添加到一个字符串中,然后使用

bytes(string , 'UTF-8')
将其转换为字节流,并通过串行方式写入 UART。



#!/usr/bin/python
import os
import sys
import serial

def asbyte(v):
    return chr(v & 0xFF)
def printStdErr(*objs):
#    print("", *objs, file=stderr)
    print("")
class LightYModem:
    soh = 1     # 128 byte blocks
    stx = 2     # 1K blocks
    eot = 4
    ack = 6
    nak = 0x15
    ca =  0x18          # 24
    crc16 = 0x43        # 67
    abort1 = 0x41       # 65
    abort2 = 0x61       # 97

    packet_len = 1024
    expected_packet_len = packet_len+5
    packet_mark = stx

    def __init__(self):
        self.seq = None
        self.ymodem = None

    def blocking_read(self):
        ch = ''
        while not ch:
            ch = self.ymodem.read(1)
        printStdErr("read %d " % ord(ch))
        return ch

    def write(self, packet):
            #print(packet)
            b = bytes(packet, 'UTF-8')
            print(b)

            self.ymodem.write(b)

            return len(packet);

    def flush(self):
        pass
        #self.ymodem.flush()

    def _read_response(self):
        ch1 = self.blocking_read()
        ch1 = ord(ch1)
        printStdErr("response %d" % (ch1))

        if ch1==LightYModem.ack and self.seq==0:    # may send also a crc16
            ch2 = self.blocking_read()
        elif ch1==LightYModem.ca:                   # cancel, always sent in pairs
            ch2 = self.blocking_read()
        return ch1

    def transfer(self, file, ymodem, output):
        self.ymodem = ymodem
        """
        file: the file to transfer via ymodem
        ymodem: the ymodem endpoint (a file-like object supporting write)
        output: a stream for output messages
        """

        file.seek(0, os.SEEK_END)
        size = file.tell()
        file.seek(0, os.SEEK_SET)
        response = self.send_filename_header("binary", size)
        while response==LightYModem.ack:
            response = self.send_packet(file, output)

        file.close()
        if response==LightYModem.eot:
            self._send_close()

        return response
    def _send_ymodem_packet(self, data):
        # pad string to 1024 chars
        data = data.ljust(LightYModem.packet_len)
        seqchr = asbyte(self.seq & 0xFF)
        print("seqchr : "+str(len(seqchr)))
        seqchr_neg = asbyte((255-self.seq) & 0xFF)
        print("seqchr_neg : "+str(len(seqchr_neg)))
        crc16 = '\x00\x00'
        print("bytes "+ str(bytes([255])))
        packet = asbyte(LightYModem.packet_mark) + seqchr + seqchr_neg + data + crc16
        if len(packet)!=LightYModem.expected_packet_len:
            raise Exception("packet length is wrong!")
        self.packet = packet
        written = self.write(packet)
        printStdErr("sent packet data, flush..."+str(written))
        self.flush()
        printStdErr("wait response..")
        response = self._read_response()
        if response==LightYModem.ack:
            ("sent packet nr %d " % (self.seq))
            self.seq += 1
        return response
    def send_packet(self, file, output):
        response = LightYModem.eot
        data = file.read(LightYModem.packet_len)
        if len(data):
            response = self._send_ymodem_packet(data)
        return response
    

    def send_filename_header(self, name, size):
        self.seq = 0
        packet = name 
        packet += asbyte(0) 
        packet += str(size) 
        packet += ' '
        return self._send_ymodem_packet(packet)

    def transfer(self, file, ymodem, output):
        self.ymodem = ymodem
        """
        file: the file to transfer via ymodem
        ymodem: the ymodem endpoint (a file-like object supporting write)
        output: a stream for output messages
        """

        file.seek(0, os.SEEK_END)
        size = file.tell()
        file.seek(0, os.SEEK_SET)
        response = self.send_filename_header("binary", size)
        while response==LightYModem.ack:
            response = self.send_packet(file, output)

        file.close()
        if response==LightYModem.eot:
            self._send_close()

        return response
def ymodem(args):
    ser = serial.Serial('COM24', 115200, serial.EIGHTBITS, serial.PARITY_NONE, serial.STOPBITS_ONE)
    os.chdir(r'D:\projects\testprojects\code\Test1\config')
    file = open(os.getcwd()+'\testfile.bin', 'rb')
    result = LightYModem().transfer(file, ser, sys.stderr)
    file.close()
    print("result: " + str(result))

    try:
        while (True):
            print(ser.read())
    except:
        pass
    print("Done")

if __name__ == '__main__':
    ymodem(sys.argv)

尝试为不同元素构建字节数组,并将 0-255 添加为 uint8。然后我在通过 UART 作为接收器使用的 STM32 上看不到任何内容。

python byte uart bytestream chr
1个回答
0
投票

您不想使用

chr
来获取可能具有两字节 UTF-8 编码的字符串;您只需要单个 8 位整数的文字
bytes
值。

>>> bytes([230])
b'\xe6'

>>> import struct
>>> struct.pack('B', 230)
b'\xe6'
© www.soinside.com 2019 - 2024. All rights reserved.