yincheng.zhong
3 天以前 30303d366d1a0d857357c90bed876686f2d1e603
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
校验和调试工具 - 详细分析STM32输出的原始数据帧
"""
 
import serial
import struct
import time
 
# 协议常量
FRAME_HEADER = bytes([0xAA, 0x55])
FRAME_FOOTER = bytes([0x0D, 0x0A])
TYPE_GPS = 0x01
TYPE_IMU = 0x02
 
def calculate_checksum(data):
    """计算16位累加和"""
    return sum(data) & 0xFFFF
 
def main():
    port = "COM28"
    baudrate = 921600
    
    print(f"打开串口 {port} @ {baudrate}")
    
    try:
        ser = serial.Serial(port, baudrate, timeout=1)
        print("串口已打开,接收数据中...\n")
        
        buffer = bytearray()
        frame_count = 0
        
        while frame_count < 5:  # 只分析前5帧
            if ser.in_waiting > 0:
                data = ser.read(ser.in_waiting)
                buffer.extend(data)
                
                # 查找帧头
                while len(buffer) >= 9:
                    idx = buffer.find(FRAME_HEADER)
                    if idx == -1:
                        buffer.clear()
                        break
                    
                    if idx > 0:
                        buffer = buffer[idx:]
                    
                    # 检查是否有足够的数据解析帧头
                    if len(buffer) < 5:
                        break
                    
                    frame_type = buffer[2]
                    payload_len = struct.unpack('<H', buffer[3:5])[0]
                    expected_len = 2 + 1 + 2 + payload_len + 2 + 2
                    
                    print(f"\n[调试] 发现帧头 @ buffer[{idx}], 类型=0x{frame_type:02X}, 载荷长度={payload_len}, 需要={expected_len}, 可用={len(buffer)}")
                    
                    if len(buffer) < expected_len:
                        print(f"[调试] 数据不足,等待更多数据...")
                        break
                    
                    # 提取完整帧
                    frame = buffer[:expected_len]
                    buffer = buffer[expected_len:]
                    
                    frame_count += 1
                    
                    # 详细分析这一帧
                    print(f"{'='*70}")
                    print(f"帧 #{frame_count} - 类型: 0x{frame_type:02X} ({'GPS' if frame_type == TYPE_GPS else 'IMU' if frame_type == TYPE_IMU else '未知'})")
                    print(f"{'='*70}")
                    
                    # 打印原始十六进制
                    print(f"原始数据 ({len(frame)} 字节):")
                    hex_str = ' '.join(f'{b:02X}' for b in frame)
                    for i in range(0, len(hex_str), 72):
                        print(f"  {hex_str[i:i+72]}")
                    
                    # 解析各个部分
                    print(f"\n帧结构分析:")
                    print(f"  帧头: {frame[:2].hex().upper()} (应为 AA55)")
                    print(f"  类型: 0x{frame[2]:02X}")
                    print(f"  长度: {payload_len} (0x{frame[3]:02X}{frame[4]:02X})")
                    
                    payload = frame[5:5+payload_len]
                    print(f"  载荷: {payload.hex().upper()} ({len(payload)} 字节)")
                    
                    checksum_received = struct.unpack('<H', frame[5+payload_len:5+payload_len+2])[0]
                    print(f"  校验和(接收): 0x{checksum_received:04X}")
                    
                    footer = frame[5+payload_len+2:5+payload_len+4]
                    print(f"  帧尾: {footer.hex().upper()} (应为 0D0A)")
                    
                    # 计算校验和 - 三种方式
                    print(f"\n校验和验证:")
                    
                    # 方式1: Type + Length + Payload (正确方式)
                    checksum_data1 = frame[2:5+payload_len]
                    checksum_calc1 = calculate_checksum(checksum_data1)
                    match1 = "✓" if checksum_calc1 == checksum_received else "✗"
                    print(f"  方式1 (Type+Len+Payload): 0x{checksum_calc1:04X} {match1}")
                    print(f"    计算范围: 字节[2:{5+payload_len}] = {checksum_data1.hex().upper()}")
                    
                    # 方式2: 包含帧头 (错误方式)
                    checksum_data2 = frame[0:5+payload_len]
                    checksum_calc2 = calculate_checksum(checksum_data2)
                    match2 = "✓" if checksum_calc2 == checksum_received else "✗"
                    print(f"  方式2 (含帧头AA55): 0x{checksum_calc2:04X} {match2}")
                    
                    # 方式3: 只有Payload (错误方式)
                    checksum_calc3 = calculate_checksum(payload)
                    match3 = "✓" if checksum_calc3 == checksum_received else "✗"
                    print(f"  方式3 (仅Payload): 0x{checksum_calc3:04X} {match3}")
                    
                    # 计算差值
                    diff = checksum_received - checksum_calc1
                    print(f"\n  差值 (接收 - 方式1): {diff} (0x{diff & 0xFFFF:04X})")
                    
                    print()
                    
                    if frame_count >= 5:
                        break
            
            time.sleep(0.01)
        
        ser.close()
        print("分析完成")
        
    except Exception as e:
        print(f"错误: {e}")
        import traceback
        traceback.print_exc()
 
if __name__ == "__main__":
    main()