C# Hex转Bin函数

using System;
using System.IO;
using System.Windows.Forms;
using System.Globalization;



//hex文件格式详细说明 
//1
//推荐QUESTION
//What is the Intel HEX file format?
//ANSWER
//The Intel HEX file is an ASCII text file with lines of text that follow the
//Intel HEX file format. Each line in an Intel HEX file contains one HEX record.
//These records are made up of hexadecimal numbers that represent machine
//language code and/or constant data. Intel HEX files are often used to transfer
//the program and data that would be stored in a ROM or EPROM. Most EPROM
//programmers or emulators can use Intel HEX files.
//Record Format
//An Intel HEX file is composed of any number of HEX records. Each record is made
//up of five fields that are arranged in the following format:
//:llaaaatt[dd...]cc
//Each group of letters corresponds to a different field, and each letter
//represents a single hexadecimal digit. Each field is composed of at least two
//hexadecimal digits-which make up a byte-as described below:
//: is the colon that starts every Intel HEX record.
//ll is the record-length field that represents the number of data bytes (dd) in
//the record.
//aaaa is the address field that represents the starting address for subsequent
//data in the record.
//tt is the field that represents the HEX record type, which may be one of the
//following:
//00 - data record
//01 - end-of-file record
//02 - extended segment address record
//04 - extended linear address record
//dd is a data field that represents one byte of data. A record may have multiple
//data bytes. The number of data bytes in the record must match the number
//specified by the ll field.
//cc is the checksum field that represents the checksum of the record. The
//checksum is calculated by summing the values of all hexadecimal digit pairs in
//the record modulo 256 and taking the two's complement.
//Data Records
//The Intel HEX file is made up of any number of data records that are terminated
//with a carriage return and a linefeed. Data records appear as follows:
//:10246200464C5549442050524F46494C4500464C33
//where:
//10 is the number of data bytes in the record.
//2462 is the address where the data are to be located in memory.
//00 is the record type 00 (a data record).
//464C...464C is the data.
//33 is the checksum of the record.
//Extended Linear Address Records (HEX386)
//Extended linear address records are also known as 32-bit address records and
//HEX386 records. These records contain the upper 16 bits (bits 16-31) of the
//data address. The extended linear address record always has two data bytes and
//appears as follows:
//:02000004FFFFFC
//where:
//02 is the number of data bytes in the record.
//0000 is the address field. For the extended linear address record, this field
//is always 0000.
//04 is the record type 04 (an extended linear address record).
//FFFF is the upper 16 bits of the address.
//FC is the checksum of the record and is calculated as
//01h + NOT(02h + 00h + 00h + 04h + FFh + FFh).
//When an extended linear address record is read, the extended linear address
//stored in the data field is saved and is applied to subsequent records read
//from the Intel HEX file. The linear address remains effective until changed by
//another extended address record.
//The absolute-memory address of a data record is obtained by adding the address
//field in the record to the shifted address data from the extended linear
//address record. The following example illustrates this process..
//Address from the data record's address field      2462
//Extended linear address record data field     FFFF
//                                              --------
//Absolute-memory address                       FFFF2462
//Extended Segment Address Records (HEX86)
//Extended segment address records-also known as HEX86 records-contain bits 4-19
//of the data address segment. The extended segment address record always has two
//data bytes and appears as follows:
//:020000021200EA
//where:
//02 is the number of data bytes in the record.
//0000 is the address field. For the extended segment address record, this field
//is always 0000.
//02 is the record type 02 (an extended segment address record).
//1200 is the segment of the address.
//EA is the checksum of the record and is calculated as
//01h + NOT(02h + 00h + 00h + 02h + 12h + 00h).
//When an extended segment address record is read, the extended segment address
//stored in the data field is saved and is applied to subsequent records read
//from the Intel HEX file. The segment address remains effective until changed by
//another extended address record.
//The absolute-memory address of a data record is obtained by adding the address
//field in the record to the shifted-address data from the extended segment
//address record. The following example illustrates this process.
//Address from the data record's address field     2462
//Extended segment address record data field      1200
//                                             --------
//Absolute memory address                      00014462
//End-of-File (EOF) Records
//An Intel HEX file must end with an end-of-file (EOF) record. This record must
//have the value 01 in the record type field. An EOF record always appears as
//follows:
//:00000001FF
//where:
//00 is the number of data bytes in the record.
//0000 is the address where the data are to be located in memory. The address in
//end-of-file records is meaningless and is ignored. An address of 0000h is
//typical.
//01 is the record type 01 (an end-of-file record).
//FF is the checksum of the record and is calculated as
//01h + NOT(00h + 00h + 00h + 01h).
//Example Intel HEX File
//Following is an example of a complete Intel HEX 
//:10001300AC12AD13AE10AF1112002F8E0E8F0F2244
//:10000300E50B250DF509E50A350CF5081200132259
//:03000000020023D8
//:0C002300787FE4F6D8FD7581130200031D
//:10002F00EFF88DF0A4FFEDC5F0CEA42EFEEC88F016
//:04003F00A42EFE22CB
//:00000001FF
//Hex文件的INTEL格式:这是Intel公司提出的按地址排列的数据信息,数据宽度为字节,所有数
//据使用16进制数字表示.
//这是一个例子:
//:10008000AF5F67F0602703E0322CFA92007780C361
//:1000900089001C6B7EA7CA9200FE10D2AA00477D81
//:0B00A00080FA92006F3600C3A00076CB
//:00000001FF
//第一行,":"符号表明记录的开始. 后面的两个字符表明记录的长度,这里是10h. 后面的四个字
//符给出调入的地址,这里是0080h. 后面的两个字符表明记录的类型;
//0 数据记录 1 记录文件结束 2 扩展段地址记录 3 开始段地址记录 4 扩展线性地址记录 5
//开始线性地址记录
//后面则是真正的数据记录, 最后两位是校验和检查,它加上前面所有的数据和为0.
//最后一行特殊,总是写成这个样子.
//扩展Intel Hex的格式(最大1M): 由于普通的Intel的Hex记录文件只能记录64K的地址范围,
//所以大于64K的地址数据要靠扩展Intel Hex格式的文件来记录.对于扩展形式Hex文件,在每
//一个64K段的开始加上扩展的段地址规定,下面的数据地址均在这个段内,除非出现新的段地址
//定义.
//一个段地址 定义的格式如下:
//起始符 长度 起始地址 扩展段标示 扩展段序号 无用 累加和
//: 02 0000 02 3000 EC
//段地址的标识符是第四组数据02,表示扩展地址段的定义,再后面的以为HEX数表示段的数目,
//上面的定义为3,表示段地址是3,所以下面的数据地址是3 + XX(XX是64K段内的地址) 

namespace demo
{
    class BMU_Hex2Bin
    {
        public byte[] hex2BinByte(String szHexPath, String szBinPath)
        {
            Int32 i = 0;
            Int32 j = 0;
            Int32 maxAddr = 0;        //HEX文件的最大地址
            Int32 segAddr = 0;        //段地址
            
            byte[] szBin = null;
            try
            {
                String szLine = "";
                String szHex = "";
               
                StreamReader HexReader = new StreamReader(szHexPath);

                //先找出HEX文件的最大地址
                while (true)
                {
                    szLine = HexReader.ReadLine(); //读取一行数据
                    i++;
                    if (szLine == null) //读完所有行
                    {
                        break;
                    }
                    if (szLine.Substring(0, 1) == ":") //判断第1字符是否是:
                    {

                        if (szLine.Substring(1, 8) == "00000001")//数据结束,所有的Hex文件均是统一的格式
                        {

                            break;

                        }
    //                    if (szLine.Substring(7, 2) == "02")//查看是否有扩展线性地址出现,在BMU的HEX文件中是不会出现此扩展地址的。
     //                   {
       //                     segAddr = Int32.Parse(szLine.Substring(9, 4), NumberStyles.HexNumber);
       //                     segAddr *= 16;
         //               }
                        if (szLine.Substring(7, 2) == "04")//查看是否有扩展线性地址出现,在BMU的HEX文件中是不会出现此扩展地址的。
                        {
                            segAddr = Int32.Parse(szLine.Substring(9, 4), NumberStyles.HexNumber);
                            if (segAddr == 0x01)
                                segAddr = 0x10000;
                            else
                            {
                                segAddr = 0;
                            }
                        }
                        else if (szLine.Substring(7, 2) == "00")//大部分均是此
                        {
                            Int32 tmp;
                            Int32 tmpAddr = Int32.Parse(szLine.Substring(3, 4), NumberStyles.HexNumber);
                            tmpAddr += UInt16.Parse(szLine.Substring(1, 2), NumberStyles.HexNumber);
                            tmp = tmpAddr;
                            tmpAddr = tmp + segAddr;
                            if (tmpAddr > maxAddr)
                                maxAddr = tmpAddr;
                        }
                    }

                }

                //新建一个二进制文件,填充为0XFF
                szBin = new byte[maxAddr];
                for (i = 0; i < maxAddr; i++)
                    szBin[i] = 0XFF;
                //返回文件开头
                HexReader.BaseStream.Seek(0, SeekOrigin.Begin);
                HexReader.DiscardBufferedData();//不加这句不能正确返回开头 
                segAddr = 0;
                //根据hex文件地址,填充bin文件
                while (true)
                {

                    szLine = HexReader.ReadLine(); //读取一行数据

                    if (szLine == null) //读完所有行
                    {
                        break;
                    }
                    if (szLine.Substring(0, 1) == ":") //判断第1字符是否是:
                    {

                        if (szLine.Substring(1, 8) == "00000001")//数据结束
                        {
                            break;
                        }
                        if (szLine.Substring(7, 2) == "04")//查看是否有扩展线性地址出现,在BMU的HEX文件中是不会出现此扩展地址的。
                        {
                            segAddr = Int32.Parse(szLine.Substring(9, 4), NumberStyles.HexNumber);
                            if (segAddr == 0x01)
                                segAddr = 0x10000;
                            else
                            {
                                segAddr = 0;
                            }
                        }
                        if (szLine.Substring(7, 2) == "00")
                        {
                            int tmpAddr = Int32.Parse(szLine.Substring(3, 4), NumberStyles.HexNumber);
                            int num = Int16.Parse(szLine.Substring(1, 2), NumberStyles.HexNumber);
                            tmpAddr += segAddr;
                            j = 0;
                            for (i = 0; i < num; i++)
                            {
                                szBin[tmpAddr++] = (byte)Int16.Parse(szLine.Substring(j + 9, 2), NumberStyles.HexNumber);
                                j += 2;
                            }

                        }
                    }

                }

                HexReader.Close(); //关闭目标文件
 
/*
                if (szBinPath == "")
                {
                    szBinPath = Path.ChangeExtension(szHexPath, "bin");
                    //tbBinPath.Text = szBinPath;
                }
                FileStream fBin = new FileStream(szBinPath, FileMode.Create); //创建文件BIN文件
                BinaryWriter BinWrite = new BinaryWriter(fBin); //二进制方式打开文件
                BinWrite.Write(szBin, 0, maxAddr); //写入数据
                BinWrite.Flush();//释放缓存
                BinWrite.Close();//关闭文件
                string tmp = "文件转换完成! 文件大小: ";
                tmp += maxAddr.ToString();
                tmp += "字节";
                MessageBox.Show(tmp, "提示");
 */
            }
            catch (Exception ex)
            {
                //MessageBox.Show(ex.ToString());
                MessageBox.Show("Hex File Format damaged!","ERROR");
            }
            return szBin;
        }

    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值