STM32嵌入式:如何使用keil 来获取flash块数据并转换成可视化的数据 来判断源头数据是否错误

STM32嵌入式:如何使用keil 来获取flash块数据并转换成可视化的数据 来判断源头数据是否错误

比较实用的实战步骤,分三部分讲:

  • 在 Keil 里怎么看到/导出 Flash 数据
  • 怎么把原始 16 位补码数据"转成"我们能看懂的波形
  • 怎么对比"Flash 源头数据"和"你解析出来的数据",判断解析是否错误
    中间用一点伪命令,你按自己芯片型号和工程改一下就行。

一、整体流程示意(先有个整体感)

简单来说,你可以按下面这个思路来:

  1. Keil 进入调试模式 2. 在 Memory 窗口查看 Flash 数据 3. 用 SAVE 命令导出 Flash 块到 HEX 文件 4. HEX 转 数组/CSV 5. 用脚本做补码转换(16 位) 6. 用 Excel/Matlab/Python 画波形 7. 对比 Flash 源头数据 与 代码解析后数据
    判断源头/解析是否错误

二、在 Keil 中查看并导出 Flash 数据

1. 调试状态下打开 Memory 窗口

  • 在 Keil 中:
    • 点击 "Debug" → "Start/Stop Debug Session"(或 Ctrl+F5)进入调试
    • 菜单 "View" → "Memory Windows" → "Memory 1/2/3/4",打开一个内存窗口
  • 在 Memory 窗口的 "Address" 输入栏里填你要看的那块 Flash 地址,例如:
    • 0x08000000(STM32 的 Flash 起始地址,按你芯片的实际情况来)
  • 回车后,下面就会显示一段原始字节内容,形如:
    • 0x08000000 03 1F 03 3B 01 AD 01 15 ...
      如果你的 Flash 数据已经是一些"采样数据"写死在里面(比如 const 数组),你会在 Memory 窗口里看到它们以字节形式排布。

2. 确认数组/变量的地址

如果数据是以某个常量数组存在代码里,比如:

  • 代码中定义:
    • const int16_t flash_wave[128] = { ... };
      那么在调试时:
  • 打开 "View" → "Watch Windows" → "Watch 1"
  • 在 Watch 窗口里输入 flash_wave,Keil 会显示:
    • 这个数组的起始地址(比如 0x08001234
    • 数组里各个位置的值(如果显示格式对的话)
      你可以记下这个起始地址和长度,然后直接用 Memory 窗口看同一块区域。

3. 使用 SAVE 命令导出一段 Flash 到文件(重点)

Keil 的调试命令行(Debug → Command 窗口)支持 SAVE 命令,可以把一段内存内容导出为 Intel HEX 文件:

  • 在 Command 窗口输入(示例):

    text 复制代码
    SAVE flash_block.hex 0x08000000, 0x08000400

    参数含义:

    • flash_block.hex:你要保存的文件名(默认在工程目录)
    • 0x08000000:起始地址
    • 0x08000400:结束地址(导出 0x08000000~0x080003FF 这一段)
      注意:这里写的是"结束地址",不是"长度"。
  • SAVE 命令说明文档里讲的是:将内存区域以 HEX386 格式写入文件。
    这样你就有了一份"从 Flash 里原封不动导出来"的数据文件。


三、把 HEX 转成数组/CSV,并做 16 位补码转换

现在你拿到了 flash_block.hex,但它是 HEX 格式,不方便直接画图,一般做法是:

  • 要么用在线工具 / 小工具把 HEX 转成二进制 / C 数组 / CSV
  • 要么直接用 Python/C 脚本解析 HEX 文件并做补码转换
    这里给你一个最通用、可自动化的做法:用 Python 脚本一次性做完"解析 HEX + 补码转换 + 生成 CSV"。
    假设:
  • 你的原始采样数据是 16 位,按"小端模式(Little Endian)"存在 Flash 中(STM32 这类常见)
  • 地址 0x08000000 开始是:
    • 0x03 0x1F 0x03 0x3B 0x01 0xAD ...
  • 对应的 16 位有符号值是:
    • 0x1F030x3B030xAD01 ...

示例:Python 脚本解析 HEX + 转 16 位有符号 + 生成 CSV

你可以建一个 parse_hex.py

python 复制代码
import intelhex
import csv
# 输入 Keil 导出的 HEX 文件
hex_file = "flash_block.hex"
csv_file = "flash_wave.csv"
start_addr = 0x08000000
end_addr   = 0x08000400  # 和 SAVE 命令的结束地址一致
ih = intelhex.IntelHex(hex_file)
values = []
addr = start_addr
while addr < end_addr:
    # 小端模式:低字节在前,高字节在后
    low  = ih[addr]
    high = ih[addr + 1]
    u16 = (high << 8) | low   # 组合成 16 位无符号整数
    # 转为 16 位有符号(补码)
    if u16 & 0x8000:
        i16 = u16 - 0x10000
    else:
        i16 = u16
    values.append(i16)
    addr += 2  # 每次跳 2 字节
# 写入 CSV(只有一列,就是转换后的值)
with open(csv_file, "w", newline="") as f:
    writer = csv.writer(f)
    writer.writerow(["Index", "Value"])  # 表头
    for i, v in enumerate(values):
        writer.writerow([i, v])
print(f"Done. Written {len(values)} samples to {csv_file}.")

需要先安装 intelhex 库:

bash 复制代码
pip install intelhex

运行脚本后,你会得到 flash_wave.csv,里面形如:

text 复制代码
Index,Value
0,192
1,315
2,429
3,533
...

这个 Value 就是你"Flash 源头数据 + 16 位补码转换"之后的真实波形值。

四、可视化成波形,和你的解析结果对比

有了 CSV 之后,你可以用三种常用方式可视化。

1)用 Excel 快速看趋势

  • 直接用 Excel 打开 flash_wave.csv
  • 选中两列数据,插入"折线图"
  • 看一下:
    • 波形是否类似正弦/三角/你预期的信号
    • 有没有奇怪的跳变(比如从几百突然跳到几千)
      这一步主要用来判断"源头数据本身是不是就乱"。

2)用 Python + Matplotlib 画更漂亮的波形

python 复制代码
import csv
import matplotlib.pyplot as plt
xs = []
ys = []
with open("flash_wave.csv") as f:
    reader = csv.DictReader(f)
    for row in reader:
        xs.append(int(row["Index"]))
        ys.append(int(row["Value"]))
plt.figure(figsize=(10, 4))
plt.plot(xs, ys, marker='o', markersize=3, linestyle='-')
plt.title("Flash Waveform (signed 16-bit)")
plt.xlabel("Sample Index")
plt.ylabel("Amplitude")
plt.grid(True)
plt.tight_layout()
plt.show()

这样你可以很清楚地看到:

  • 是否是连续平滑的波形
  • 在 0 附近是否正确跨越正负(例如从几十到负几十,而不是从几十跳到 65471)

3)和"你的代码解析结果"对比(判断是否解析错误)

你前面有一段从 data 里解析通道数据并做 twos_comp 的代码。你可以:

  • 在 Keil 调试时:
    • 在 Watch 窗口添加 wavedata.channelValue[curchanneltmp][0]lenOfChannel 等,实时查看解析后的数组。
    • 或在调试过程中执行类似的 SAVE 命令,把解析后的数组所在内存也导出一份 HEX/CSV。
  • 然后画在同一张图上对比:
    • 曲线 A:直接从 Flash 导出 + 正确补码转换("标准答案")
    • 曲线 B:你的代码解析出来的数据
      对比时看几个点:
  • 形状是否一致(正弦/方波/三角等)
  • 幅值是否一致
  • 有没有"多出一些奇怪的点"或"整体平移/翻转"
  • 特别检查从正到负的过渡区域(例如你之前那组 60 → 65471)
    如果形状明显不一样,大部分是你代码里:
  • 通道号/索引用错
  • 数据长度算错
  • 高低位字节搞反
  • 没有做补码转换或转换方式不对

五、几个常见坑和检查点

1)大小端模式

  • 很多 ARM MCU(STM32 等)是小端:
    • 低字节在低地址,高字节在高地址
  • 如果你误用大端解析,波形会变得完全不对(幅值、噪声都异常)
  • 可以在 Memory 窗口先看几个典型点的字节分布:
    • 如果 Flash 中是 01 FC,预期值大概是 0xFC01
    • 如果你解析出 0x01FC,说明大小端反了

2)数据类型 & 步长

  • 如果你的数据实际是:
    • 16 位有符号:用 int16_t,步长 = 2 字节
    • 32 位有符号/浮点:步长 = 4 字节
  • 步长错了,会导致解析错位(比如把高/低字拼到相邻采样上)

3)数组边界 / 通道切换

  • 你之前的代码里 curchanneltmpmaxchannel 等逻辑,如果在 Flash 里有多个通道连续排布:
    • 需要确认每个通道的起始地址和长度
    • 不然容易把两个通道的数据拼在一起,看起来像奇怪的折线

4)如果只是简单确认 Flash 数据是不是"写死"得对

  • 直接在 Keil 里:
    • 打开 Watch 窗口,添加数组变量
    • 看它的值是不是你预期
    • 再对比一下 Memory 窗口同一位置的字节
  • 如果两者都对,那问题基本就出在"接收/解析"逻辑,而不是 Flash 源头。

六、小结:推荐的实战步骤

给出一个简单可照抄的流程:

  1. 在 Keil 里调试,Memory 窗口定位到你的 Flash 数组起始地址(比如 0x08001000

  2. 用 Command 窗口执行:

    text 复制代码
    SAVE flash_block.hex 0x08001000 0x08001200

    导出这块数据到 HEX 文件

  3. 用 Python 解析这个 HEX 文件,按 16 位小端 + 补码转换,生成 flash_wave.csv

  4. 用 Excel/Matlab/Python 画出波形,确认是否像你预期的正弦/三角等信号

  5. 同时,在 Keil 调试中导出你代码解析出来的数组(也可以用 SAVE 或 watch+复制),按相同方式画出来

  6. 把两张图叠在一起对比:

    • 完全一致:说明解析没问题,源头数据也 OK
    • 不一致:根据差异点反推:
      • 波形整体平移/翻转 → 大小端或符号位有问题
      • 多出跳变、毛刺 → 通道/长度/索引处理有误
      • 某一段完全乱掉 → 可能是多通道混在一起或数组指针错
相关推荐
深圳市九鼎创展科技21 小时前
瑞芯微 RK3399 开发板 X3399 评测:高性能 ARM 平台的多面手
linux·arm开发·人工智能·单片机·嵌入式硬件·边缘计算
辰哥单片机设计21 小时前
STM32项目分享:车辆防盗报警系统
stm32·单片机·嵌入式硬件
風清掦1 天前
【江科大STM32学习笔记-05】EXTI外部中断11
笔记·stm32·学习
小龙报1 天前
【51单片机】从 0 到 1 玩转 51 蜂鸣器:分清有源无源,轻松驱动它奏响新年旋律
c语言·数据结构·c++·stm32·单片机·嵌入式硬件·51单片机
范纹杉想快点毕业1 天前
嵌入式与单片机开发核心学习指南——从思维转变到第一性原理的深度实践
单片机·嵌入式硬件
Industio_触觉智能1 天前
瑞芯微RK3566开发板规格书,详细参数配置,型号EVB3566-V1,基于RK3566核心板SOM3566邮票孔封装
嵌入式硬件·开发板·rk3568·rk3566·核心板·瑞芯微
czwxkn1 天前
4STM32(stdl)TIM定时器
stm32·单片机·嵌入式硬件
Love Song残响1 天前
NVIDIA显卡终极优化指南
stm32·单片机·嵌入式硬件
qq_672592751 天前
电源芯片为什么发热
单片机·嵌入式硬件
天天爱吃肉82181 天前
【跨界封神|周杰伦×王传福(陶晶莹主持):音乐创作与新能源NVH测试,底层逻辑竟完全同源!(新人必看入行指南)】
python·嵌入式硬件·算法·汽车