hex格式介绍 及转bin格式的源程序
http://www.cppblog.com/Lee7/archive/2007/12/21/39231.html
Intel HEX文件是记录文本行的 ASCII 文本文件,在 Intel HEX 文件中,每一行是一个 HEX 记录,由十六进制数组成的机器码或 者数据常量。 Intel HEX 文件经常被用于将程序或数据传输存储到 ROM 、 EPROM , 大多数编程器和模拟器使用 Intel HEX 文件。
很多编译器的支持生成 HEX 格 式的烧录文件,尤其是 Keil c 。但是编程器能够下载的往往是 BIN 格 式,因此 HEX 转 BIN 是每个编程器都必须 支持的功能。
HEX 格式文件以行为单位, 每行由“:”( 0x3a )开始,以回车键结束 (0x0d,0x0a) 。 行内的数据都是由两个字 符表示一个 16 进制字节,比如 ”01” 就表 示数 0x01 ; ”0a” ,就表示 0x0a 。 对于 16 位 的地址,则高位在前低位在后,比如地址 0x010a ,在 HEX 格 式文件中就表示为字符串 ”010a” 。 下面为 HEX 文件中的一行:
:10000000FF0462FF051EFF0A93FF0572FF0A93FFBC
“:”表示一行的开始。
“:” 后的第 1 , 2 个 字符“ 10 ” 表 示本行包含的数据的长度,这里就是 0x10 即 16 个。
第 3 , 4 , 5 , 6 个 字符“ 0000 ” 表 示数据存储的起始地址,这里表示从 0x0000 地址开始存储 16 个 数据,其中高位地址在前,低位地址在后。
第 7 , 8 个 字符“ 00 ” 表 示数据的类型。该类型总共有以下几种:
00 ---- 数据记录
01 ---- 文 件结束记录
02 ---- 扩展段地址记录
04 ---- 扩展线性地址记录
这里就是 0x00 即 为普通数据记录。
自后的 32 个字符就是本行包含的数据, 每两个字符表示一个字节数据,总共有 16 个 字节数据跟行首的记录的长度相一致。
最后两个字符表示校验码。
每个 HEX 格 式的最后一行都是固定为:
:00000001FF
以上的信息其实就足够进行 HEX 转 BIN 格 式的程序的编写。首先我们只处理数据类型为 0x00 及 0x01 的 情况。 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
7
typedef unsigned
char
BYTE;
8
9
10
11
//
将两个字符转化为一个字节量
12
13
void
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 ' && h <= ' F ' )
44
45
h = h - ' A ' + 0xa ;
46
47
* pByte = (BYTE)h * 16 + l;
48
49
}
50
51
52
53
int
_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