我的创作纪念日【第一个2048day】
机缘
- 初心:研究生期间,帮老师做一个项目,过程中学习的东西想记录下来,于是,就选择了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);}}
}
憧憬
希望在汽车电子领域深耕,创作更有价值的文章
相关文章:

我的创作纪念日【第一个2048day】
机缘 初心:研究生期间,帮老师做一个项目,过程中学习的东西想记录下来,于是,就选择了CADN让技术分享成为工作的一部分 收获 获得了1800多粉丝的关注获得了63万的访问量,其中《C#设计模式》专栏深受大家喜欢…...

内网穿透-————SSH远程连接树莓派
前言 文章目录 前言内网穿透实现公网SSH远程连接树莓派1. 在树莓派上安装[cpolar客户端](https://www.cpolar.com/)2. 在树莓派浏览器中输入本地9200端口3. 在公共互联网的电脑的命令行界面输入命令 内网穿透实现公网SSH远程连接树莓派 随着科技的进步和信息技术的发展&#x…...

一键开启ChatGPT“危险发言”
大数据文摘授权转载自学术头条 作者:Hazel Yan 编辑:佩奇 随着大模型技术的普及,AI 聊天机器人已成为社交娱乐、客户服务和教育辅助的常见工具之一。 然而,不安全的 AI 聊天机器人可能会被部分人用于传播虚假信息、操纵舆…...

RISC-V基础之函数调用(一)简单的函数调用(包含实例)
高级语言支持函数(也称为过程或子程序)来重用通用的代码,以及使程序更加模块化和可读。函数可以有输入,称为参数,和输出,称为返回值。函数应该计算返回值,并且不产生其他意外的副作用。 在一个…...

apt、aptitude、apt-get/apt-cache语法的区别
apt句法 aptitude句法 apt-get/apt-cache语法 描述 apt update aptitude update apt-get update 更新包存档元数据 apt install foo ap...

华为认证 | HCIA和HCIP有啥区别?
HCIA和HCIP都是华为认证体系里的,所以它们的考试流程大同小异,唯一区别的话,那可能就是课程内容方面的区别较大了。 那么HCIA和HCIP考试有啥区别呢?下面我们就来跟随小编来了解一下吧。 01 HCIA和HCIP考试有啥区别 ★ 等级不同 …...

JavaScript基础知识
JavaScript基础知识 一、变量与数据类型1. 变量2. 数据类型 二、表达式与运算符1.字面量2.表达式3.运算符3.1 算术运算符3.2 比较运算符3.3 逻辑运算符3.4 赋值运算符 三、条件语句1. 控制流程2. 语句块3. if 语句3. switch 语句4. 条件运算符 四、循环语句1. while2. do...whi…...

vue2 todoapp案例(静态)
1.创建三个子组件(TodoHeader、TodoMain、TodoFooter)和两个(index.css、base.css)样式; TodoHeader页面 <template><header class"header"><h1>todos</h1><input id"toggle-all" class"toggle-all" typ…...

qt5.14 和 qt5.15的区别
Qt 5.14 和 Qt 5.15 是两个不同的 Qt 版本,它们之间有一些区别和改进。 以下是一些 Qt 5.15 相对于 Qt 5.14 的变化和改进: 性能改进:Qt 5.15 引入了一些性能改进,包括提高渲染性能和减少内存占用。 Qt 3D:Qt 5.15 对…...

如何使用自己域名进行远程访问内网群晖NAS 6.X
使用自己的域名远程访问内网群晖NAS 6.X【内网穿透】 文章目录 使用自己的域名远程访问内网群晖NAS 6.X【内网穿透】 在之前的文章中,我们向大家演示了如何使用cpolar,创建一条固定的、能够在公共互联网登录内网群晖NAS的数据隧道。这条隧道已经能够应对…...

PHP判处重复延长队列执行时间
需求是这样: 14:00的时候,需要给1000个门店执行发券操作,有的门店需要发3个场景,开放平台的接口有请求频次限制,他是按照门店的场景发券需要间隔10秒。比如说,AB两个门店同时发a券,但不能 A门店…...

flask中的应用上下文
flask中的应用上下文 Flask应用上下文主要包含两个对象:current_app和g。这两个对象在处理请求期间都是全局可访问的,但在每个请求结束时都会被重置。 current_app:这是当前激活的Flask应用的实例。在大多数情况下,你可以将其视为…...

cocos creator 的input.on 不生效
序: 1、执行input.on的时候发现不生效 2、一直按控制台也打印不出来console.log 3、先收藏这篇,因为到时候cocos要开发serveApi的时候,你得选一款趁手的后端开发并且,对习惯用ts写脚本的你来说,node是入门最快…...

WFPlayer
WFPlayer WFPlayer 可以实现分析音视频生成音频波形图 在线demo地址: demo WFPlayer支持: 在不加载整个媒体文件的情况下创建波形自定义光标、进度、网格、标尺显示和颜色加载媒体url和加载媒体dom元素(视频标签和音频标签)颜色或宽度等实时…...

Netty面试题
1.BIO、NIO 和 AIO 的区别? BIO:一个连接一个线程,客户端有连接请求时服务器端就需要启动一个线程进行处理。线 程开销大。 伪异步 IO:将请求连接放入线程池,一对多,但线程还是很宝贵的资源。 NIO&#x…...

基于Home Assistant远程开门
基于Home Assistant远程开门 1.购买云服务器 1.1 阿里云服务器 本人使用的是阿里云服务器,其他的腾讯云,百度云都可以 如果你想要一个建议的话: 推荐在打折优惠的时候买,比如双十一 阿里云最近有一个飞天计划,在校…...

Docker相关的参数配置
Docker的配置文件/etc/docker/daemon.json中的大部分配置项如下所示 : {"allow-nondistributable-artifacts": [],"api-cors-header": "","authorization-plugins": [],"bip": "","bridge"…...

【CSS3】CSS3 2D 转换 - scale 缩放 ③ ( 使用 scale 设置制作可缩放的按钮案例 )
文章目录 一、需求分析二、代码分析三、代码示例四、执行结果 一、需求分析 设置一个 按钮 , 默认状态下显示的样式如下 : 按钮 外部 有 圆形的外边框 ;按钮 中的文本 , 水平居中对齐 , 垂直居中对齐 ; 当鼠标移动到 按钮 上之后 , 鼠标 变为 小手 样式 , 并且 按钮 以 中心位…...

Stable Diffusion教程(6) - 图片高清放大
放大后细节 修复图片损坏 显存占用 速度 批量放大 文生图放大 好 是 高 慢 否 附加功能放大 一般 否 中 快 是 图生图放大 好 是 低 慢 是 tile模型放大 非常好 是 高 快 是 通过文生图页面的高清修复 优点:放大时能添加更多细节&am…...

freeswitch 1.10.10-dev录音早期媒体卡通道的bug分析
最近编译了fs 1.10.10-dev也就是 master版本(2023年7月6日) 给几个客户升级了一下,发现非常不稳定(每天都有几个通道卡在early状态),最近才有空来分析原因。 之前跑的是1.10.8 release 版本,从来没出现过这个问题&…...

Zebec Protocol ,不止于 Web3 世界的 “Paypal”
Paypal 是传统支付领域的巨头企业,在北美支付市场占有率约为 77% 以上。从具体的业务数据看,在8月初,Paypal 公布的 2023 年第二季度财报显示,PayPal 第二季度净营收为 73 亿美元,净利润为 10.29 亿美元。虽然 Paypal …...

Gcd 2023牛客暑期多校训练营6 G
登录—专业IT笔试面试备考平台_牛客网 题目大意:给出一个集合,集合中初始有2个数x,y(x!y),每次操作可以将集合中任意两个不等的数的差放入集合或者将两个不等的数的gcd放入集合,给出一个数z,问z有没有可能出现在集合里…...

常用C++编译器推荐
本文将为大家带来的是几款简单实用的C编译器(非IDE),希望大家喜欢。 GCC(GNU Compiler Collection) 官方网站: GCC, the GNU Compiler Collection- GNU Project GCC有Windows移植版本,比较出名的就是Min…...

C++QT教程1——QT概述(下载与安装)
文章目录 1 Qt概述1.1 什么是Qt1.2 Qt的发展史1.3 Qt版本1.4 Qt的下载与安装下载地址:其实我是有点懵逼的,因为还有个qtcreator,我差点不知道下哪个。。。(qt框架比qtcreator功能更多更强大) 安装 1.5 Qt的优点1.6 QT成…...

在oracle SQL中创建返回表的函数
这是我的职责 create or replace FUNCTION split(i_str IN VARCHAR2,i_delim IN VARCHAR2 DEFAULT : ) RETURN TABLE AS BEGINRETURN SELECT trim(regexp_substr(i_str, [^||i_delim||], 1, LEVEL)) str FROM projetCONNECT BY instr(i_str, i_delim, 1, LEVEL - 1) …...

Kubernetes API Aggregation API聚合
Kubernetes API Aggregation - Kubernetes - Wiki.Shileizcc.com API 聚合机制是 Kubernetes 1.7 版本引入的特性,能够将用户扩展的 API 注册到 kube-apiserver 上,仍然通过 API Server 的 HTTP URL 对新的 API 进行访问和操作。为了实现这个机制&#…...

【雕爷学编程】Arduino动手做(184)---快餐盒盖,极低成本搭建机器人实验平台
吃完快餐粥,除了粥的味道不错之外,我对个快餐盒的圆盖子产生了兴趣,能否做个极低成本的简易机器人呢?也许只需要二十元左右 知识点:轮子(wheel) 中国词语。是用不同材料制成的圆形滚动物体。简…...

重生学c++系列第三课类和对象(上)
好的我们重生c系列的前两期已经介绍完了c祖师爷针对C语言补充的几个新功能,现在我们进入c的真正课题学习——类与对象: C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。 比如说我们洗菜做饭&am…...

驱动开发-按键中断
编写LED灯的驱动,使用GPIO子系统,里面添加按键的中断处理 1.应用程序发送指令控制LED亮灭 2.按键1 按下,led1电位反转 按键2按下,led2电位反转 按键3 按下,led3电位反转 功能函数 #include<stdlib.h> #inclu…...

数据结构 | 二叉树的应用
目录 一、解析树 二、树的遍历 一、解析树 我们可以用解析树来表示现实世界中像句子或数学表达式这样的构造。 我们可以将((73)*(5-2))这样的数学表达式表示成解析树。这是完全括号表达式,乘法的优先级高于加法和减法,但因为有括号,所以在…...