我正在尝试将 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 上看不到任何内容。
您不想使用
chr
来获取可能具有两字节 UTF-8 编码的字符串;您只需要单个 8 位整数的文字 bytes
值。
>>> bytes([230])
b'\xe6'
或
>>> import struct
>>> struct.pack('B', 230)
b'\xe6'