山寨:不是最好的,是最适合我们的!欢迎体验山寨 中文版MSDN

Blog @ Blog

当华美的叶片落尽,生命的脉络才历历可见。 -- 聂鲁达

常用链接

统计

积分与排名

BBS

Blog

Web

最新评论

hex格式介绍及转bin格式的源程序

Intel HEX文件是记录文本行的ASCII文本文件,在Intel HEX文件中,每一行是一个HEX记录,由十六进制数组成的机器码或者数据常量。Intel HEX文件经常被用于将程序或数据传输存储到ROMEPROM,大多数编程器和模拟器使用Intel HEX文件。

       很多编译器的支持生成HEX格式的烧录文件,尤其是Keil c。但是编程器能够下载的往往是BIN格式,因此HEXBIN是每个编程器都必须支持的功能。

       HEX格式文件以行为单位,每行由“:”(0x3a)开始,以回车键结束(0x0d,0x0a)。行内的数据都是由两个字符表示一个16进制字节,比如01”就表示数0x010a,就表示0x0a。对于16位的地址,则高位在前低位在后,比如地址0x010a,在HEX格式文件中就表示为字符串010a。下面为HEX文件中的一行:

:10000000FF0462FF051EFF0A93FF0572FF0A93FFBC

       “:”表示一行的开始。

       “:”后的第12个字符“10表示本行包含的数据的长度,这里就是0x1016个。

       3456个字符“0000表示数据存储的起始地址,这里表示从0x0000地址开始存储16个数据,其中高位地址在前,低位地址在后。

       78个字符“00表示数据的类型。该类型总共有以下几种:

00 ----数据记录      
01 ----
文件结束记录
02 ----
扩展段地址记录
04 ----
扩展线性地址记录

这里就是0x00即为普通数据记录。

自后的32个字符就是本行包含的数据,每两个字符表示一个字节数据,总共有16个字节数据跟行首的记录的长度相一致。

最后两个字符表示校验码。

每个HEX格式的最后一行都是固定为:

:00000001FF

       以上的信息其实就足够进行HEXBIN格式的程序的编写。首先我们只处理数据类型为0x000x01的情况。0x02表示对应的存储地址超过了64K,由于我的编程器只针对64K以下的单片机,因此在次不处理,0x04也是如此。

       我的编程思路是从文件中一个一个读出字符,根据“:”判断一行的开始,然后每两个字符转换成一个字节,并解释其对应的意义。然后将数据从该行中剥离出来保存到缓冲区中,并最终输出到文件中。

       具体程序如下,该程序在VC2005下采用控制台项目编译,需要在release下编译,在debug模式中会提示一个dll文件无法找到,这可能是VC自身的错误。

// hextobin.cpp : 定义控制台应用程序的入口点。

//

 

  1#include "stdafx.h"
  2
  3#include <malloc.h>
  4
  5#include <memory.h>
  6
  7typedef unsigned char BYTE;
  8
  9 
 10
 11//将两个字符转化为一个字节量
 12
 13void CharToByte(char* pChar,BYTE* pByte)
 14
 15{
 16
 17     char h,l;
 18
 19     h=pChar[0];//高位
 20
 21     l=pChar[1];//低位
 22
 23     if(l>='0'&&l<='9')
 24
 25         l=l-'0';
 26
 27     else if(l>='a' && l<='f')
 28
 29         l=l-'a'+0xa;
 30
 31     else if(l>='A' && l<='F')
 32
 33         l=l-'A'+0xa;
 34
 35     if(h>='0'&&h<='9')
 36
 37         h=h-'0';
 38
 39     else if(h>='a' && h<='f')
 40
 41         h=h-'a'+0xa;
 42
 43     else if(h>='A' &&<='F')
 44
 45         h=h-'A'+0xa;
 46
 47     *pByte=(BYTE)h*16+l;
 48
 49}

 50
 51 
 52
 53int _tmain(int argc, _TCHAR* argv[])
 54
 55{
 56
 57     char fileName[100];
 58
 59     char data[2];
 60
 61     BYTE *outBuf;
 62
 63     FILE *myFile;
 64
 65     int len;
 66
 67     int i;
 68
 69     BYTE adressHigh;
 70
 71     BYTE adressLow;
 72
 73     BYTE dataLen;
 74
 75     BYTE dataType; 
 76
 77     BYTE byteData;
 78
 79     int totalLen;
 80
 81     totalLen = 0;
 82
 83     len = 0;
 84
 85     adressHigh = 0;
 86
 87     adressLow = 0;
 88
 89     dataLen = 0;
 90
 91     dataType = 0;
 92
 93     printf("请输入HEX格式文件名:");
 94
 95     scanf_s("%s",fileName);
 96
 97     printf("\n");
 98
 99     if (fopen_s(&myFile,fileName,"r"!= 0)
100
101     {
102
103         printf("打开文件%s失败!",fileName);
104
105     }

106
107     //将文件长度计算出来用于申请存储数据的缓冲区
108
109     while (!feof(myFile))
110
111     {
112
113         ++len;
114
115         fgetc(myFile);
116
117     }

118
119     rewind(myFile);
120
121     //因为是每两个字符表示一个字节,所以最大的数据个数要少于文件字符个数的一半
122
123     outBuf = (BYTE*)malloc(len/2);
124
125     memset(outBuf,0xff,len/2);
126
127     while (!feof(myFile))
128
129     {
130
131         //:号表示一行的开始
132
133         if (fgetc(myFile) == ':')
134
135         {
136
137              //一行的头两个字符表示该行包含的数据长度
138
139              data[0= fgetc(myFile);
140
141              data[1= fgetc(myFile);
142
143              CharToByte(data,&dataLen);
144
145              //一行的第、个字符表示数据存储起始地址的高位
146
147              data[0= fgetc(myFile);
148
149              data[1= fgetc(myFile);
150
151              CharToByte(data,&adressHigh);
152
153              //一行的第、个字符表示数据存储起始地址的低位
154
155              data[0= fgetc(myFile);
156
157              data[1= fgetc(myFile);
158
159              CharToByte(data,&adressLow);
160
161              //一行的第、个字符表示数据类型
162
163              data[0= fgetc(myFile);
164
165              data[1= fgetc(myFile);
166
167              CharToByte(data,&dataType);
168
169              //当数据类型为时,表示本行包含的是普通数据记录
170
171              if (dataType == 0x00)
172
173              {
174
175                   for (i=0;i<dataLen;i++)
176
177                   {
178
179                       data[0= fgetc(myFile);
180
181                       data[1= fgetc(myFile);
182
183                       CharToByte(data,&byteData);
184
185                       outBuf[adressHigh*256+adressLow+i] = byteData;
186
187                   }

188
189                   totalLen += dataLen;
190
191              }

192
193              //当数据类型为时,表示到了最后一行
194
195              if (dataType == 0x01)
196
197              {
198
199                   printf("文件结束记录!");
200
201              }

202
203              //当数据类型为时,表示本行包含的是扩展段地址记录
204
205              if (dataType == 0x02)
206
207              {
208
209                   printf("不支持扩展段地址记录!");
210
211                   return 0;
212
213              }

214
215              //当数据类型为时,表示本行包含的是扩展线性地址记录
216
217              if (dataType == 0x04)
218
219              {
220
221                   printf("不支持扩展线性地址记录!");
222
223                   return 0;
224
225              }

226
227         }

228
229     }

230
231     fclose(myFile);
232
233     printf("请输入保存的BIN格式文件名:");
234
235     scanf_s("%s",fileName);
236
237     if (fopen_s(&myFile,fileName,"w"!= 0)
238
239     {
240
241         printf("打开文件%s失败!",fileName);
242
243     }

244
245     for (i=0;i<totalLen;i++)
246
247     {
248
249         fputc(outBuf[i],myFile);
250
251     }

252
253     return 0;
254
255}

256

posted on 2007-12-21 17:15 isabc 阅读(4751) 评论(1)  编辑 收藏 引用 所属分类: C++基础

评论

# re: hex格式介绍及转bin格式的源程序 2012-12-13 14:42

很好,不过程序上有一点问题
if (fopen_s(&myFile,fileName,"w") != 0)
改成
if (fopen_s(&myFile,fileName,"wb") != 0)
我用bcb转不行,用vs还是不行.  回复  更多评论   


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


广告信息(免费广告联系)

中文版MSDN:
欢迎体验