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

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 '   && <= ' 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

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值