serial模块
- 导入
import serial
- 串口的操作
打开串口
ser = serial.Serial(portx,bps,timeout=timeout) # portx为串口号,bps为波特率,timeout为超时的时间 ser.is_open # 返回实例的连接状态,如果连接失败,则为False # 可以使用该方法来添加异常处理
关闭串口
ser.close()
写入数据
result = ser.write(data) # 使用该方法来写入数据 # 如果要写入十六进制数据需要使用bytearray # writebuf = bytearray([0x55, 0xaa, 0x00, 0x01, 0x00, 0x00])
读取数据
ser.in_waiting # 如果没有返回数据,则为空 # 可以访问该属性查看是否有等待的数据 readbuff = ser.read(ser.in_waiting) # 使用该方法来读取等待的信息
- 完整的串口程序
创建串口信息类,定义了内部定义属性以及外部定义属性(在_init_方法中定义的属性,可以通过类实例化的时候传入)
class UartInfo(object): response = False image_addr = 0x00 image_crc = 0x00 version = 0 write_event = threading.Event() def __init__(self, fd, count, fail): self.fd = fd self.count = count # 测试次数 self.fail = fail # 失败次数
实例化类
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) # 遍历argv的每个元素 # %02x表示以16进制的形式输出,如果不足两位用0补足,如果超过两位以实际输出 # 遍历完成之后,用空格将其组成一个字符串 # 使用info级别打印出信息
进行CRC校验
def crc_sum(data, data_len): crc = 0 i = 0 while(i < data_len): crc += data[i] i += 1 return crc & 0x00FF # 将data中的所有元素进行循环相加 # 将其与0x00FF比对
进行CRC相加
def crc_sum_u32(data, data_len): crc = 0 i = 0 while(i < data_len): crc += data[i] i += 1 return crc # 返回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()

浙公网安备 33010602011771号