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
137
138
139
140
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
分析STM32输出的原始十六进制数据
"""
 
import struct
 
# 原始数据
raw_hex = """
41 E7 00 2F 06 AF 0E 0D 0A AA 55 01 2C 00 68 70 21 B0 6E EA 43 40 E9 11 40 BD DB 11 5D 40 
7F C3 65 43 F4 FD 54 BC 58 39 34 BC A6 9B 44 BB 77 3E A5 42 EC 4C 9E 00 01 1B 00 00 6A 14 
0D 0A AA 55 02 20 00 58 39 34 BC BA 49 8C BE 4E 62 80 BF 7F 6A BC 3D D1 22 5B BE 00 00 00 
80 00 00 F0 41 F1 00 2F 06 A3 0D 0D 0A
"""
 
def parse_frames(hex_string):
    """解析帧数据"""
    # 移除空格和换行,转换为字节
    hex_clean = hex_string.replace(' ', '').replace('\n', '')
    data = bytes.fromhex(hex_clean)
    
    print(f"总数据长度: {len(data)} 字节\n")
    
    i = 0
    frame_count = 0
    
    while i < len(data) - 2:
        # 查找帧头 AA 55
        if data[i] == 0xAA and data[i+1] == 0x55:
            frame_count += 1
            print(f"{'='*60}")
            print(f"帧 #{frame_count} - 位置: {i} (0x{i:04X})")
            print(f"{'='*60}")
            
            if i + 5 > len(data):
                print("数据不足,无法解析帧头")
                break
            
            # 解析帧头
            frame_type = data[i+2]
            data_len = struct.unpack('<H', data[i+3:i+5])[0]
            
            print(f"帧头: AA 55")
            print(f"类型: 0x{frame_type:02X}", end='')
            if frame_type == 0x01:
                print(" (GPS数据)")
            elif frame_type == 0x02:
                print(" (IMU数据)")
            elif frame_type == 0x10:
                print(" (控制命令)")
            else:
                print(" (未知类型)")
            
            print(f"数据长度: {data_len} 字节")
            
            # 计算完整帧长度
            total_frame_len = 5 + data_len + 4  # 帧头(5) + 数据 + 校验和(2) + 帧尾(2)
            
            if i + total_frame_len > len(data):
                print(f"错误: 帧不完整,需要{total_frame_len}字节,剩余{len(data)-i}字节")
                print(f"原始数据: {data[i:min(i+20, len(data))].hex(' ').upper()}")
                i += 1
                continue
            
            # 提取完整帧
            frame = data[i:i+total_frame_len]
            payload = frame[5:5+data_len]
            checksum = struct.unpack('<H', frame[5+data_len:5+data_len+2])[0]
            footer = frame[5+data_len+2:5+data_len+4]
            
            # 计算校验和
            calc_checksum = sum(frame[0:5+data_len]) & 0xFFFF
            
            print(f"数据负载: {data_len} 字节")
            print(f"校验和: 0x{checksum:04X} (计算值: 0x{calc_checksum:04X})", end='')
            if checksum == calc_checksum:
                print(" ✓")
            else:
                print(" ✗ 校验失败!")
            
            print(f"帧尾: {footer.hex(' ').upper()}", end='')
            if footer == b'\x0D\x0A':
                print(" ✓")
            else:
                print(" ✗ 帧尾错误!")
            
            # 解析GPS数据
            if frame_type == 0x01 and data_len == 56:
                try:
                    gps = struct.unpack('<ddfffffff I BB 2x', payload)
                    print(f"\nGPS数据解析:")
                    print(f"  纬度:     {gps[0]:.8f}°")
                    print(f"  经度:     {gps[1]:.8f}°")
                    print(f"  航向角:   {gps[2]:.2f}°")
                    print(f"  东速度:   {gps[3]:.3f} m/s")
                    print(f"  北速度:   {gps[4]:.3f} m/s")
                    print(f"  天速度:   {gps[5]:.3f} m/s")
                    print(f"  高程:     {gps[6]:.2f} m")
                    print(f"  UTC时间:  {gps[7]}")
                    print(f"  定位质量: {gps[8]}")
                    print(f"  卫星数:   {gps[9]}")
                except Exception as e:
                    print(f"GPS解析错误: {e}")
            
            # 解析IMU数据
            elif frame_type == 0x02 and data_len == 32:
                try:
                    imu = struct.unpack('<7f I', payload)
                    print(f"\nIMU数据解析:")
                    print(f"  加速度X:  {imu[0]:.3f} g")
                    print(f"  加速度Y:  {imu[1]:.3f} g")
                    print(f"  加速度Z:  {imu[2]:.3f} g")
                    print(f"  角速度X:  {imu[3]:.2f} °/s")
                    print(f"  角速度Y:  {imu[4]:.2f} °/s")
                    print(f"  角速度Z:  {imu[5]:.2f} °/s")
                    print(f"  温度:     {imu[6]:.1f} ℃")
                    print(f"  UTC时间:  {imu[7]}")
                except Exception as e:
                    print(f"IMU解析错误: {e}")
            
            # 显示原始十六进制
            print(f"\n完整帧 ({total_frame_len}字节):")
            hex_str = frame.hex(' ').upper()
            for j in range(0, len(hex_str), 48):
                print(f"  {hex_str[j:j+48]}")
            
            print()
            
            # 跳到下一帧
            i += total_frame_len
        else:
            # 不是帧头,继续搜索
            i += 1
    
    print(f"共找到 {frame_count} 个完整帧")
 
 
if __name__ == "__main__":
    parse_frames(raw_hex)