DIY编程器网

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 7500|回复: 7
打印 上一主题 下一主题

[UUProg] uuprog开发教程:打开(加载)hex,bin文件

[复制链接]
跳转到指定楼层
楼主
发表于 2014-12-1 06:29:32 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
     对于编程器软件来说支持hex,bin文件的加载是必须的,也是必不可少的。具体怎么解码hex文件请参考hex文件格式说明之类的资料,这里不做详细解说,我们采用现成的hex文件读写模块。bin文件就简单多了,直接以二进制读取到内存即可。
通过调用系统默认的打开文件对话框实现:

手动配置好过滤条件hex和bin。实现代码如下:
  1. void CUUProgDlg::OnFileOpen()
  2. {
  3.         // TODO: Add your command handler code here
  4.         CFile ldfile;
  5.         CString m_sFileExt;
  6.         
  7.         SetAppLog("加载文件开始...");
  8.         CFileDialog mDlg(TRUE,".HEX",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"HEX文件(*.HEX)|*.HEX|BIN文件(*.bin)|*.bin||",this);
  9.         if(mDlg.DoModal() == IDOK)
  10.         {
  11.                 m_sFilename = mDlg.GetPathName();
  12.                 m_sFileExt = mDlg.GetFileExt();
  13.                 m_sFileExt.MakeUpper();
  14.                 //加载文件
  15.                 if(!m_sFilename.IsEmpty())
  16.                 {
  17.                         SetAppLog("加载文件:"+m_sFilename);
  18.                         if(ldfile.Open(m_sFilename,CFile::shareCompat|CFile::modeRead,NULL))
  19.                         {
  20.                                 int nFileSize;
  21.                                 nFileSize=ldfile.GetLength();
  22.                                 if(m_sFileExt=="HEX")
  23.                                 {
  24.                                         char* pFileBuf=(char*)GlobalAlloc(GMEM_FIXED,nFileSize+1);
  25.                                         memset(pFileBuf,0,nFileSize+1);
  26.                                         ldfile.Read(pFileBuf,nFileSize);
  27.                                         nFileSize = HexToBin(pFileBuf,pProgBuff);
  28.                                         GlobalFree(pFileBuf);
  29.                                 }
  30.                                 else
  31.                                 {
  32.                                         if(nFileSize>0x10000)  nFileSize=0x10000;
  33.                                         memset(pProgBuff,0xff,0x10000);
  34.                                         ldfile.Read(pProgBuff,nFileSize);
  35.                                 }
  36.                                 ldfile.Close();
  37.                                 SetLoadFileName(m_sFilename);
  38.                                 SetAppLog("加载完成:"+Int2Str(nFileSize)+"字节");
  39.                         }
  40.                         else
  41.                         {
  42.                                 SetAppLog("加载文件失败");
  43.                                 AfxMessageBox("加载指定的文件出错");
  44.                         }
  45.                 }
  46.         }        
  47.         
  48.         else
  49.         {
  50.                 SetAppLog("取消加载文件");
  51.         }
  52. }
复制代码
首先通过定一个字符型指针变量,然后在内存中开辟块文件大小+1的区块,再用hextobin函数转换成字节型数据流。为什么要先把文件加载到内存在转换呢?自己想一下就明白了。
下面就是hextobin(),有两个参数,前面是char*,后面是byte*
  1. int HexToBin(char* pHex,BYTE* pBin)//pBin指向的缓存必须不小于64k
  2. {                                                                   //pHex指向的缓存必须以0结尾
  3.         CString strHex;
  4.         CArray<BYTE,BYTE>* pByteArray=NULL;
  5.         CArray<CArray<BYTE,BYTE>*,CArray<BYTE,BYTE>*> arByteRec;
  6.         strHex=pHex;
  7.         int nEnd;
  8.         BYTE byteTmp;
  9.         int n=0,m=0;
  10.         nEnd=strHex.Find(":00000001");
  11.         if(nEnd<0)//先判断文件结尾处
  12.         {
  13.                 AfxMessageBox("*.Hex文件转换失败(未找到\":00000001\"记录)!");
  14.                 return -1;
  15.         }
  16.         
  17.         while(n<nEnd)//先把所有字符转换成字节
  18.         {
  19.                 if(pHex[n]==':')//发现':'就新增一条记录
  20.                 {
  21.                         pByteArray=new CArray<BYTE,BYTE>;
  22.                         arByteRec.Add(pByteArray);//增加一条记录
  23.                         n++;
  24.                 }
  25.                 else if(pHex[n]==0x0d)//检查是不是换行
  26.                 {
  27.                         n++;
  28.                 }
  29.                 else if(pHex[n]==0x0a)
  30.                 {
  31.                         n++;
  32.                 }
  33.                 else//字符转换成字节
  34.                 {
  35.                         if(CharToByte(&pHex[n],&byteTmp))
  36.                         {
  37.                                 if(pByteArray==NULL)
  38.                                         return -1;
  39.                                 pByteArray->Add(byteTmp);//增加一个字节
  40.                                 n++;
  41.                                 n++;
  42.                         }
  43.                         else
  44.                         {
  45.                                 AfxMessageBox("*.Hex文件转换失败(错误的字符)!");
  46.                                 return -1;
  47.                         }
  48.                 }
  49.         }
  50.         int nRec=arByteRec.GetSize();
  51.         int nAddr=0;//buf中的偏移地址
  52.         BYTE* pBuf;
  53.         int nLength=0;//数据块长度
  54.         int nByte=0;
  55.         memset(pBin,0xff,0xffff);//先把每个单元置成FFH
  56.         for(n=0;n<nRec;n++)//分析每条记录
  57.         {
  58.                 pByteArray=arByteRec.GetAt(n);
  59.                 if(pByteArray->GetSize()<5)
  60.                 {
  61.                         AfxMessageBox("*.Hex文件转换失败(错误的记录)!");
  62.                         return -1;
  63.                 }
  64.                 if(pByteArray->GetAt(3)==0)//判断是不是数据记录
  65.                 {
  66.                         nByte=(int)pByteArray->GetAt(0);
  67.                         if(nByte>(pByteArray->GetSize()-4))//记录中数据长度不符合
  68.                         {
  69.                                 AfxMessageBox("*.Hex文件转换失败(错误的记录)!");
  70.                                 return -1;
  71.                         }
  72.                         ((BYTE*)&nAddr)[0]=pByteArray->GetAt(2);//装入地址
  73.                         ((BYTE*)&nAddr)[1]=pByteArray->GetAt(1);
  74.                         
  75.                         pBuf=&pBin[nAddr];
  76.                         for(m=0;m<nByte;m++)//把数据都拷贝到pBin
  77.                         {
  78.                                 pBuf[m]=pByteArray->GetAt(4+m);
  79.                                 nLength++;
  80.                         }
  81.                 }
  82.                 else if(pByteArray->GetAt(3)==2)
  83.                 {
  84.                         AfxMessageBox("*.Hex文件转换失败(不支持大于64k)!");
  85.                         return -1;
  86.                 }
  87.                 else if(pByteArray->GetAt(3)==4)
  88.                 {
  89.                         AfxMessageBox("*.Hex文件转换失败(不支持大于64k)!");
  90.                         return -1;
  91.                 }
  92.                 else
  93.                 {
  94.                         AfxMessageBox("*.Hex文件转换失败(错误的记录)!");
  95.                         return -1;
  96.                 }
  97.                
  98.         }
  99.         return nLength;        
  100. }
复制代码
这里采用的是全局型函数,方便其他窗口调用
文件保存就是打开的逆过程,下面就是保存部分:
  1. void CUUProgDlg::OnFileSaveAs()
  2. {
  3.         // TODO: Add your command handler code here
  4.         CString filename;
  5.         CFile savefile;
  6.         CString m_sFileExt;
  7.         int filesize;

  8.         SetAppLog("保存开始...");
  9.         filesize = GetMinLength(pProgBuff,m_dDeviceSize);
  10.         if (filesize ==0)
  11.         {
  12.                 SetAppLog("缓冲区无数据,取消保存");
  13.                 AfxMessageBox("缓冲区无数据,不需保存");
  14.                 return;
  15.         }
  16.         CFileDialog mDlg(FALSE,".HEX",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"HEX文件(*.hex)|*.hex|BIN文件(*.bin)|*.bin||",this);
  17.         if(mDlg.DoModal() == IDOK)
  18.         {
  19.                 filename = mDlg.GetPathName();
  20.                 m_sFileExt = mDlg.GetFileExt();
  21.                 m_sFileExt.MakeUpper();
  22.                 SetAppLog("保存为:"+filename);
  23.                 //保存文件代码
  24.                 if (m_sFileExt=="HEX")
  25.                 {
  26.                 }
  27.                 else
  28.                 {
  29.                         if(savefile.Open(filename,CFile::shareCompat|CFile::modeCreate|CFile::modeWrite,NULL))
  30.                         {
  31.                                 //m_editBuf2.GetData(m_Pro.m_pReadBuf,0x10000);
  32.                                 savefile.Write(pProgBuff,filesize);
  33.                                 savefile.Close();
  34.                         }
  35.                 }
  36.                 SetAppLog("保存完成:"+Int2Str(filesize)+"字节");
  37.         }        
  38.         else
  39.         {
  40.                 SetAppLog("取消保存");
  41.         }

  42.         
  43. }
复制代码
我们这里只实现了bin文件的保存,hex处理部分没有代码,暂时无法实现。
实现hex,bin的识别主要通过文件后缀名实现的,通过if语句实现不同的处理。

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏1 分享分享 支持支持 反对反对
推荐
发表于 2014-12-1 08:29:21 | 只看该作者
这是用VC编的?
回复 支持 0 反对 1

使用道具 举报

板凳
 楼主| 发表于 2014-12-1 09:55:52 | 只看该作者
hdzl 发表于 2014-12-1 08:29
这是用VC编的?

整个工程都是用vc6++
5#
发表于 2014-12-10 13:35:40 | 只看该作者
功能这么强大。
6#
发表于 2015-1-12 09:31:20 | 只看该作者
现在学vc好吗,还是学c#,我会一点qt
7#
发表于 2015-1-12 09:33:59 | 只看该作者
能不能提供一些vc学习的资料,好快速的入门
8#
 楼主| 发表于 2015-1-12 10:10:13 | 只看该作者
bywqdq 发表于 2015-1-12 09:33
能不能提供一些vc学习的资料,好快速的入门

这个比较难推荐了,个人的基础不同,接受能力不同,学习的方法不同等等,你可以看看我店里提供的学vc的教程和资料,有些是我自己整理的,当然是以我的学习角度整理
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|文字版|手机版|DIY编程器网 ( 桂ICP备14005565号-1 )

GMT+8, 2024-12-26 15:35 , 耗时 0.091977 秒, 24 个查询请求 , Gzip 开启.

各位嘉宾言论仅代表个人观点,非属DIY编程器网立场。

桂公网安备 45031202000115号

DIY编程器群(超员):41210778 DIY编程器

DIY编程器群1(满员):3044634 DIY编程器1

diy编程器群2:551025008 diy编程器群2

QQ:28000622;Email:libyoufer@sina.com

本站由桂林市临桂区技兴电子商务经营部独家赞助。旨在技术交流,请自觉遵守国家法律法规,一旦发现将做封号删号处理。

快速回复 返回顶部 返回列表