打印
[技术问答]

单片机的HEX文件与BIN文件之间的格式是如何转换的?

[复制链接]
1745|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gejigeji521|  楼主 | 2025-2-28 15:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
HEX文件(Intel HEX格式):

是一种文本格式的文件,包含地址、数据和校验信息。
每一行记录由起始符(:)、字节数、地址、记录类型、数据、校验和组成。
支持分段地址(如扩展线性地址记录),适合存储复杂的内存布局。
通常用于烧录到单片机中。

BIN文件(二进制文件):

是纯二进制数据文件,没有地址信息或其他元数据。
文件内容直接是单片机的机器码,按顺序存储。
文件大小通常比HEX文件小,但需要明确知道烧录的起始地址。

将HEX文件转换为BIN文件的过程主要是提取HEX文件中的数据,并按照地址顺序写入BIN文件。

转换工具
使用现成工具:
HEX2BIN工具:许多单片机开发工具链(如Keil、IAR、MPLAB X IDE)自带HEX转BIN的工具。
第三方工具:如hex2bin、srecord等开源工具。
在线转换工具:一些网站提供在线HEX转BIN服务。
from intelhex import IntelHex

# 加载HEX文件
ih = IntelHex("input.hex")

# 转换为BIN文件
ih.tobinfile("output.bin")


使用特权

评论回复
沙发
gejigeji521|  楼主 | 2025-2-28 15:18 | 只看该作者
1. HEX文件格式(Intel HEX格式)
HEX文件是一种文本文件,每一行称为一个记录(Record),每个记录包含以下字段:

HEX记录的结构
一个典型的HEX记录格式如下:
:LLAAAARRDDDDDDDD...DDCC
::起始符,表示一条记录的开始。

LL:数据长度(1字节),表示该记录中数据的字节数(通常是16字节)。
AAAA:地址(2字节),表示数据的起始地址。
RR:记录类型(1字节),常见的类型有:
00:数据记录(存储实际数据)。
01:文件结束记录(标识HEX文件结束)。
04:扩展线性地址记录(用于扩展地址范围)。
05:开始线性地址记录(用于指定程序的起始地址)。
DD...DD:数据(可变长度),具体数据内容。
CC:校验和(1字节),用于验证记录的完整性。

HEX文件的示例
:100000000C9434000C9446000C9446000C9446006A
:100010000C9446000C9446000C9446000C94460050
:00000001FF
第一行是一个数据记录,地址为0x0000,数据长度为0x10(16字节)。

最后一行是文件结束记录(RR=01)。

校验和的计算
校验和是记录中从LL到DD...DD所有字节的和的补码(取反加1)。例如:

对于记录:100000000C9434000C9446000C9446000C9446006A:

计算0x10 + 0x00 + 0x00 + 0x00 + 0x0C + 0x94 + ... + 0x00的和。

取和的补码,得到校验和0x6A。

使用特权

评论回复
板凳
gejigeji521|  楼主 | 2025-2-28 15:19 | 只看该作者
2. BIN文件格式
BIN文件是纯二进制文件,没有地址信息或其他元数据。它的内容直接是单片机的机器码,按顺序存储。

BIN文件的特点
文件内容是连续的二进制数据。

没有地址信息,因此需要明确知道烧录的起始地址。

文件大小通常比HEX文件小。

BIN文件的示例
假设BIN文件的内容如下(十六进制表示):
0C 94 34 00 0C 94 46 00 0C 94 46 00 0C 94 46 00
0C 94 46 00 0C 94 46 00 0C 94 46 00 0C 94 46 00
这些数据可以直接写入单片机的Flash存储器中。


使用特权

评论回复
地板
gejigeji521|  楼主 | 2025-2-28 15:19 | 只看该作者
3. HEX文件与BIN文件的转换关系
HEX文件和BIN文件的转换本质上是提取HEX文件中的数据并按地址顺序写入BIN文件,或者为BIN文件添加地址信息并生成HEX文件。

HEX转BIN
解析HEX文件的每一行记录。

根据记录类型(RR)处理数据:

如果是数据记录(RR=00),提取数据并写入BIN文件的对应地址。

如果是扩展线性地址记录(RR=04),更新当前地址的高位。

如果是文件结束记录(RR=01),结束转换。

将数据按地址顺序写入BIN文件。

BIN转HEX
读取BIN文件的内容。

将数据按固定长度(如16字节)分块。

为每一块数据生成HEX记录:

计算地址、数据长度、记录类型和校验和。

将记录写入HEX文件。

在文件末尾添加文件结束记录(:00000001FF)。

使用特权

评论回复
5
gejigeji521|  楼主 | 2025-2-28 15:20 | 只看该作者
转换示例
HEX文件内容
:100000000C9434000C9446000C9446000C9446006A
:100010000C9446000C9446000C9446000C94460050
:00000001FF
转换后的BIN文件内容
0C 94 34 00 0C 94 46 00 0C 94 46 00 0C 94 46 00
0C 94 46 00 0C 94 46 00 0C 94 46 00 0C 94 46 00
转换步骤
解析HEX文件的第一行:

地址:0x0000

数据:0C 94 34 00 0C 94 46 00 0C 94 46 00 0C 94 46 00

将数据写入BIN文件的0x0000地址处。

解析HEX文件的第二行:

地址:0x0010

数据:0C 94 46 00 0C 94 46 00 0C 94 46 00 0C 94 46 00

将数据写入BIN文件的0x0010地址处。

遇到文件结束记录(:00000001FF),结束转换。




使用特权

评论回复
6
gejigeji521|  楼主 | 2025-2-28 15:21 | 只看该作者
HEX转BIN
bin_data = bytearray()  # 存储BIN文件数据
current_address = 0     # 当前地址

for line in hex_file:
    if line[0] != ":":  # 忽略非HEX记录
        continue
    length = int(line[1:3], 16)
    address = int(line[3:7], 16)
    record_type = int(line[7:9], 16)
    data = line[9:9+2*length]
    checksum = int(line[9+2*length:9+2*length+2], 16)

    if record_type == 0x00:  # 数据记录
        bin_data[address:address+length] = bytes.fromhex(data)
    elif record_type == 0x04:  # 扩展线性地址记录
        current_address = int(data, 16) << 16
    elif record_type == 0x01:  # 文件结束记录
        break



BIN转HEX
def bin_to_hex(bin_data, start_address=0x0000):
    hex_lines = []
    length = 16  # 每行16字节
    for i in range(0, len(bin_data), length):
        data = bin_data[i:i+length]
        address = start_address + i
        record = f":{length:02X}{address:04X}00{data.hex().upper()}"
        checksum = calculate_checksum(record)
        hex_lines.append(f"{record}{checksum:02X}")
    hex_lines.append(":00000001FF")  # 文件结束记录
    return "\n".join(hex_lines)


HEX文件包含地址、数据和校验信息,适合存储复杂的内存布局。

BIN文件是纯二进制数据,适合直接烧录到单片机的Flash中。

转换的核心是提取HEX文件中的数据并按地址写入BIN文件,或者为BIN文件添加地址信息并生成HEX文件。

使用特权

评论回复
7
yangjiaxu| | 2025-2-28 15:22 | 只看该作者
其实我理解就是hex属于bin+地址了,就是这样的了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

189

主题

2402

帖子

8

粉丝