机缘
- 初心:研究生期间,帮老师做一个项目,过程中学习的东西想记录下来,于是,就选择了CADN
- 让技术分享成为工作的一部分
收获
- 获得了1800多粉丝的关注
- 获得了63万的访问量,其中《C#设计模式》专栏深受大家喜欢
- 关注了很多的技术大佬(主要在C#和汽车电子领域),从他们的文章中学到了很多
日常
- 创作已经是我生活的一部分了
- 虽然工作很忙,还是会主动挤出时间来创作
成就
Hex转bin文件的代码实现:
using System;
using System.Globalization;
using System.IO;
using System.Windows.Forms;namespace WindowsFormsApp1
{/*说明:1.hex内容读取规则示例: OxO-Ox500【所有字节内容都有】0x0-0x100,0x300-Ox500 【中间有部分地址内容缺失,根据实际情况默认填充Ox00/OxFF】2.扩展地址分区也可刷写【重点!!!】:hex文件地址分区的话(segment),此代码也可以通过*/public partial class Form1 : Form{ public Form1(){InitializeComponent();}public static string hexFilePath = null;//选择的hex文件路径public static string binFilePath = null;//保存的bin文件路径private void btn_OpenFile_Click(object sender, EventArgs e){OpenFileDialog open = new OpenFileDialog();open.RestoreDirectory = true;//open.Filter = "File(*.hex,*.s19)|*.hex;*.s19|BIN File(*.bin)|*.bin";open.Filter = "File(*.hex)|*.hex";open.InitialDirectory = Directory.GetCurrentDirectory();if (DialogResult.OK == open.ShowDialog()){hexFilePath = txt_HexFile.Text = open.FileName;binFilePath = open.FileName.Replace(".hex", ".bin");//确定生成的bin文件路径}}private void btn_StartConvert_Click(object sender, EventArgs e){try{//【01】获取hex文件的起始和终止地址(Lowest_Address和Highest_Address) ,并获取其字节长度(dataLength)GetAddress(hexFilePath);byte[] buffer = new byte[dataLength]; //创建和hex文件对应长度的字节数组//【02】填充数组内容//(情形1:所有地址内容都在hex文件中;情形2:在hex文件中有些地址内容缺失,需要填充默认值“0x00”或“0xFF”)FillData(hexFilePath, ref buffer);//【03】将数组写到bin文件WritetoBinFile(binFilePath, buffer, 0, dataLength);MessageBox.Show("转换成功");}catch (Exception ex){MessageBox.Show(ex.Message);}}public static int startAddress = 0;//解析的起始地址public static int endAddress = 0;//解析的终止地址public static int dataLength = 0;//字节总长度=endAddress-startAddress+1public static string startExtendedAddress = "0000";//第一个扩展地址public static string endExtendedAddress = "0000";//最后一个扩展地址public static bool isFirstExtendedAddress = true;//是否是第一次检测到“0x04”public static string startDataAddress = "0000";//第一个数据地址【对应startExtendedAddress】public static string endDataAddress = "0000";//最后一个数据地址【对应endExtendedAddress】public static bool isFirstDataAddress = true;//是否是第一次检测到“0x00”public static string lastDataLength = "00";//最后一行的数据长度/// <summary>/// 【第1步】获取hex文件的起始和终止地址,并获取其字节长度/// </summary>/// <param name="hexPath"></param>private void GetAddress(string hexPath){FileStream fsRead = new FileStream(hexPath, FileMode.OpenOrCreate, FileAccess.Read);StreamReader HexReader = new StreamReader(fsRead); //读取数据流while (true){string currentLineData = HexReader.ReadLine(); //读取Hex中一行if (currentLineData == null) { break; } //读取完毕,退出if (currentLineData.Substring(0, 1) == ":") //判断首字符是”:”{if (currentLineData.Substring(1, 8) == "00000001"){if (endExtendedAddress == "0000"){endAddress = Convert2Hex(startExtendedAddress + endDataAddress) + Convert2Hex(lastDataLength) - 1;//获得终止地址dataLength = endAddress - startAddress + 1;}else{endAddress = Convert2Hex(endExtendedAddress + endDataAddress) + Convert2Hex(lastDataLength) - 1;//获得终止地址dataLength = endAddress - startAddress + 1;}break;} //文件结束标识string type = currentLineData.Substring(7, 2);switch (type){case "04":if (isFirstExtendedAddress){startExtendedAddress = currentLineData.Substring(9, 4);isFirstExtendedAddress = false;}else{endExtendedAddress = currentLineData.Substring(9, 4);}break;case "00":if (isFirstDataAddress){startDataAddress = currentLineData.Substring(3, 4);startAddress = Convert2Hex(startExtendedAddress + startDataAddress);//获得起始地址isFirstDataAddress = false;}else{endDataAddress = currentLineData.Substring(3, 4);lastDataLength = currentLineData.Substring(1, 2);//为了获取最后一行的字节长度}break;default:break;}}}HexReader.Close();fsRead.Close();}/// <summary>///【第2步】填充数组内容/// </summary>/// <param name="hexPath">hex文件路径</param>/// <param name="buffer">填充的字节数组</param>private void FillData(string hexPath, ref byte[] buffer){int lastLine_EndAddress_Real = startAddress;//上一行结束的真实地址【扩展地址+数据地址】,初始值为hex文件的起始地址int currentLine_StartAddress_Real = 0;//下一行开始的真实地址【扩展地址+数据地址】string currentExtendedAddress = "0000";//当前扩展地址string currentLineDataAddress = "0000";//当前数据地址int current_BufferIndex = 0;FileStream fsRead = new FileStream(hexPath, FileMode.OpenOrCreate, FileAccess.Read);StreamReader HexReader = new StreamReader(fsRead); //读取数据流while (true){string currentLineData = HexReader.ReadLine(); //读取Hex中一行if (currentLineData == null) { break; } //读取完毕,退出if (currentLineData.Substring(0, 1) == ":") //判断首字符是”:”{//文件结束标识if (currentLineData.Substring(1, 8) == "00000001"){break;} string type = currentLineData.Substring(7, 2);//读取当前行的类型switch (type){case "04":currentExtendedAddress = currentLineData.Substring(9, 4);break;case "00":currentLineDataAddress = currentLineData.Substring(3, 4);//当前数据地址currentLine_StartAddress_Real = Convert2Hex(currentExtendedAddress + currentLineDataAddress);//实际开始地址值//如果这一次的起始地址不等于上一次结束的下一个地址,则填充"0x00"if (currentLine_StartAddress_Real != lastLine_EndAddress_Real){for (int i = 0; i < currentLine_StartAddress_Real - lastLine_EndAddress_Real; i++) // 补空位置{byte value = byte.Parse("00", NumberStyles.HexNumber);buffer[current_BufferIndex] = value;current_BufferIndex++;}}int currentLine_DataLength = Convert2Hex(currentLineData.Substring(1, 2));//获取当前行的数据长度for (int i = 0; i < currentLine_DataLength; i++){byte value = byte.Parse(currentLineData.Substring(i * 2 + 9, 2), NumberStyles.HexNumber);buffer[current_BufferIndex] = value;current_BufferIndex++;}lastLine_EndAddress_Real = currentLine_StartAddress_Real + currentLine_DataLength;break;default:break;}}}//关闭Stream和文件HexReader.Close();fsRead.Close();//hex文件最后没有的byte填充“00”if (buffer.Length > current_BufferIndex){for (int i = 0; i < buffer.Length - current_BufferIndex; i++){byte value = byte.Parse("FF", NumberStyles.HexNumber);buffer[current_BufferIndex + i] = value;}}}/// <summary>/// 【第3步】将数组写到bin文件/// </summary>/// <param name="binPath">新建bin文件的路径</param>/// <param name="buffer">写入的字节数组</param>/// <param name="startIndex">开始索引</param>/// <param name="length">写入的字节长度</param>private void WritetoBinFile(string binPath, byte[] buffer, int startIndex, int length){FileStream fsWrite = new FileStream(binPath, FileMode.Create, FileAccess.Write);//如果已存在相同文件名的文件,则删掉之前的,创建新的文件!!!fsWrite.Write(buffer, startIndex, length);fsWrite.Close();}/// <summary>/// 16进制字符串 转化为数值/// </summary>/// <param name="content">16进制字符串</param>/// <returns></returns>private int Convert2Hex(string content){return Convert.ToInt32(content, 16);}}
}
憧憬
希望在汽车电子领域深耕,创作更有价值的文章