当前位置:文档之家› HEX文件格式+DELPHI源码

HEX文件格式+DELPHI源码


按照上面的数据行格式分析如下:
<0x3a> [数据长度 1Byte] [数据地址 2Byte] [数据类型 1Byte]
10 00 00
00
[数据 nByte] [校验 1Byte]
<0x0d> <0x0a>
18F09FE518F09FE518F09FE518F09FE5 C0
每行中的数据并不是一定有的,第二个字节数据长度为 0,那么这行就没 有数据。
++len; fgetc(myFile); } rewind(myFile); //因为是每两个字符表示一个字节,所以最大的数据个数要少于文件字符个数 的一半
outBuf = (BYTE*)malloc(len/2); memset(outBuf,0xff,len/2); while (!feof(myFile)) {
//将两个字符转化为一个字节量 void CharToByte(char* pChar,BYTE* pByte) {
char h,l; h=pChar[0];//高位 l=pChar[1];//低位 if(l>='0'&&l<='9')
l=l-'0'; else if(l>='a' && l<='f')
CharToByte(data,&adressHigh); //一行的第、个字符表示数据存储起始地址的低位 data[0] = fgetc(myFile); data[1] = fgetc(myFile); CharToByte(data,&adressLow); //一行的第、个字符表示数据类型 data[0] = fgetc(myFile); data[1] = fgetc(myFile); CharToByte(data,&dataType); //当数据类型为时,表示本行包含的是普通数据记录 if (dataType == 0x00) {
End of File Record 行是每一个 HEX 文件的最后一行。例如: :00000001FF 这样的一行数据内容是固定的,数据长度为 0,地址为 0。
校验值:每一行的最后一个值为此行数据的校验和。例如:
:1000000018F09FE518F09FE518F09FE518F09FE5C0 这行中的 0xC0
printf("不支持扩展段地址记录!"); return 0; } //当数据类型为时,表示本行包含的是扩展线性地址记录 if (dataType == 0x04) { printf("不支持扩展线性地址记录!"); return 0; } } } fclose(myFile); printf("请输入保存的 BIN 格式文件名:"); scanf_s("%s",fileName); if (fopen_s(&myFile,fileName,"w") != 0) { printf("打开文件%s 失败!",fileName); } for (i=0;i<totalLen;i++) { fputc(outBuf[i],myFile); } return 0; }
scanf_s("%s",fileName); printf("\n"); if (fopen_s(&myFile,fileName,"r") != 0) {
printf("打开文件%s 失败!",fileName); } //将文件长度计算出来用于申请存储数据的缓冲区 while (!feof(myFile)) {
:1000100018F09FE5805F20B9F0FF1FE518F09FE51D
第一行,是 Extended Linear Address Record,里面的数据,也就是基地址 是 0x0004,第二行是 Data Record,里面的地址值是 0x0000。那么数据 18F09FE518F09FE518F09FE518F09FE5 要写入 FLASH 中的地址为 (0x0004 << 16) | 0x0000,也就是写入 FLASH 的 0x40000 这个地址。同样,第三行的数据 的写入地址为 0x40010。当一个 HEX 文件的数据超过 64k 的时候,文件中就会 出现多个 Extended Linear Address Record。
Intel HEX 文件是记录文本行的 ASCII 文本文件,在 Intel HEX 文件中,每一行是 一个 HEX 记录,由十六进制数组成的机器码或者数据常量。Intel HEX 文件经常 被用于将程序或数据传输存储到 ROM、EPROM,大多数编程器和模拟器使用 Int el HEX 文件。
很多编译器的支持生成 HEX 格式的烧录文件,尤其是 Keil c。但是编程器能够 下载的往往是 BIN 格式,因此 HEX 转 BIN 是每个编程器都必须支持的功能。
HEX 格式文件以行为单位,每行由“:”(0x3a)开始,以回车键结束(0x0d, 0x0a)。行内的数据都是由两个字符表示一个 16 进制字节,比如”01”就表示数 0 x01;”0a”,就表示 0x0a。对于 16 位的地址,则高位在前低位在后,比如地址 0x010a,在 HEX 格式文件中就表示为字符串”010a”。下面为 HEX 文件中的一 行: :10000000FF0462FF051EFF0A93FF0572FF0A93FFBC
for (i=0;i<dataLen;i++) {
data[0] = fgetc(myFile); data[1] = fgetc(myFile); CharToByte(data,&byteData); outBuf[adressHigh*256+adressLow+i] = byteData; } totalLen += dataLen; } //当数据类型为时,表示到了最后一行 if (dataType == 0x01) { printf("文件结束记录!"); } //当数据类型为时,表示本行包含的是扩展段地址记录 if (dataType == 0x02) {
具体程序如下,该程序在 VC2005 下采用控制台项目编译,需要在 release 下 编译,在 debug 模式中会提示一个 dll 文件无法找到,这可能是 VC 自身的错 误。 // hextobin.cpp : 定义控制台应用程序的入口点。 //
#i nclude "stdafx.h" #i nclude <malloc.h> #i nclude <memory.h> typedef unsigned char BYTE;
以上的信息其实就足够进行 HEX 转 BIN 格式的程序的编写。首先我们只处理 数据类型为 0x00 及 0x01 的情况。0x02 表示对应的存储地址超过了 64K不处理,0x04 也是如此。
我的编程思路是从文件中一个一个读出字符,根据“:”判断一行的开始,然后 每两个字符转换成一个字节,并解释其对应的意义。然后将数据从该行中剥离出来 保存到缓冲区中,并最终输出到文件中。
*pByte=(BYTE)h*16+l; } int _tmain(int argc, _TCHAR* argv[]) {
char fileName[100]; char data[2]; BYTE *outBuf; FILE *myFile; int len; int i; BYTE adressHigh; BYTE adressLow; BYTE dataLen; BYTE dataType; BYTE byteData; int totalLen; totalLen = 0; len = 0; adressHigh = 0; adressLow = 0; dataLen = 0; dataType = 0; printf("请输入 HEX 格式文件名:");
然后,接着 0x04 后面的两个 0x00 0x00 就是数据。最后一个 0xFA 是校验码。
HEX 文件的每一行都是这样的格式:
<0x3a> [数据长度 1Byte] [数据地址 2Byte] [数据类型 1Byte]
[数据 nByte] [校验 1Byte]
<0x0d> <0x0a>
在例如:
:1000000018F09FE518F09FE518F09FE518F09FE5C0
:020000040000FA , 我把它看做 0x02 0x00 0x00 0x04 0x00 0x00 0xFA
第一个 0x02 为数据长度。
紧跟着后面的 0x00 0x00 为地址。
再后面的 0x04 为数据类型,类型共分以下几类:
'00' Data Record '01' End of File Record '02' Extended Segment Address Record '03' Start Segment Address Record '04' Extended Linear Address Record '05' Start Linear Address Record
//:号表示一行的开始 if (fgetc(myFile) == ':') {
//一行的头两个字符表示该行包含的数据长度 data[0] = fgetc(myFile); data[1] = fgetc(myFile); CharToByte(data,&dataLen); //一行的第、个字符表示数据存储起始地址的高位 data[0] = fgetc(myFile); data[1] = fgetc(myFile);
相关主题