日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HEX文件格式解析(转)

發布時間:2023/12/15 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HEX文件格式解析(转) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Hex格式文件有兩種,一種是Intel的Intel HEX,另一種是Motorola(摩托羅拉)的SREC(又稱MOT)。


Intel HEX 文件是由一行行符合Intel HEX 文件格式的文本所 構 成的ASCII 文本文件。在Intel HEX 文件中,每一行包含一 個 HEX 記錄 。 這 些 記錄 由 對應 機器 語 言 碼 和/ 或常量 數 據的十六 進 制 編碼數 字 組 成。Intel HEX 文件通常用于 傳輸將 被存于ROM 或者EPROM 中的程序和 數 據。大多 數 EPROM 編 程器或模 擬器使用Intel HEX 文件。

Hex文件是可以燒寫到單片機中,被單片機執行的一種文件格式,生成Hex文件的方式由很多種,可以通過不同的編譯器將C程序或者匯編程序編譯生成hex。

一般Hex文件通過記事本就可以打開。可以發現一般Hex文件的記錄格式如下:

Intel HEX 由任意數量的十六 進 制 記錄組 成。每 個記錄 包含5 個 域, 它們按以下格式排列:

每一組字母 對應 一 個 不同的域,每一 個 字母 對應 一 個 十六 進 制 編碼 的 數 字。每一 個 域由至少 兩個 十六 進制 編碼數 字 組 成, 它們構 成一 個 字 節 ,就像以下描述的那 樣:

(1):(冒號)每個Intel HEX 記錄 都由冒 號開頭 ;

(2)LL 是 數 據 長 度域, 它 代表 記錄當 中 數 據字 節 (dd) 的 數量 ;

(3)aaaa 是地址域, 它代表 記錄當 中 數據的起始地址;

(4)TT是代表HEX 記錄類 型的域 , 它 可能是以下 數 據 當 中的一 個:
00 – 數 據 記錄(Data Record)
01 – 文件結 束 記錄(End of FileRecord)
02 – 擴展段地址 記錄(ExtendedSegment Address Record)
03 – 開始段地址 記錄(Start Segment Address Record)
04 – 擴展 線 性地址 記錄(Extended Linear Address Record)
05 – 開始線性地址 記錄(Extended Segment Address Record)

(5)dd 是數 據域 , 它 代表一 個 字 節 的 數 據. 一 個記錄 可以有 許 多 數 據字 節 . 記錄當 中 數 據字 節 的 數 量必 須 和數 據 長 度域(ll) 中指定的 數字相符.

(6)cc 是校驗 和域 , 它 表示 這個記錄 的校 驗 和. 校 驗 和的 計 算是通 過將記錄當 中所有十六 進 制 編碼數 字 對 的 值相加, 以256 為 模 進 行以下 補 足.

表示為:“:[1字節長度][2字節地址][1字節記錄類型][n字節數據段][1字節校驗和] ”


(TT)具體根據記錄類型分析如下:

(1)數據記錄”00”

Intel HEX文件由任意數 量以回車換行符結束的數據記錄組成數據記錄外觀如下:
:10246200464C5549442050524F46494C4500464C33
其中:10 是這個記錄當中 數 據字 節 的 數量.即0x10 ;
2462 是數據 將 被下 載 到存 儲 器 當中的地址.即0x2462 ;

00 是記錄類型( 數 據 記錄).即0x00 ;
464C…464C是 數據.分別代表0x46,0x4C… ;
33 是這個記錄的校 驗和即0x33;計算方法如下:256D-(10H+24H+62H+00H+46H+4CH+55H+49H+44H+20H+50H+52H+4FH+46H+49H+4CH+45H+00H+46H+4CH)/100H=33H;

(2)文件結束(EOF)”01”

Intel HEX文件必須以文件結束(EOF) 記錄結束這個記錄的記錄類的值必須是01.EOF 記錄 外 觀總是如下:
:00000001FF
其中:00 是記錄當中 數 據字 節 的 數量.
0000 是數據被下載到存儲器當中的地址. 在文件結束記錄當中地址是沒有意義,被忽略的.0000h 是典型的地址;
01 是記錄類型 01( 文件 結 束 記錄)
FF 是 這個記錄 的校 驗 和, 計算方法如下: 256D-(00H+00H+00H+01H)=FFH;

(3)擴展線性地址記錄(HEX386) ”04”

由于每行標識數據地址的只有2Byte,所以最大只能到64K,為了可以保存高地址的數據,就有了Extended Linear AddressRecord。如果這行的數據類型是0x04,那么,這行的數據就是隨后數據的基地址。

擴展線性地址記錄也叫作32位地址記錄或HEX386記錄.這些記錄含數據的高16位擴展線性地址記錄總是有兩個數據字節,外觀如下:
:02000004FFFFFC

其中:02 是這個記錄當中 數 據字 節 的 數量.
0000 是地址域, 對于 擴 展 線 性地址 記錄 , 這個 域 總是0000.
04 是記錄類型 04( 擴 展 線 性地址 記錄)
FFFF 是地址的高16 位.
FC 是這個記錄的校 驗 和, 計算如下: 256D-(02H+00H+00H+04H+FFH+FFH)/100H=FCH;

當一 個擴展 線 性地址記錄被讀 取, 存 儲于數據域的擴展線性地址被保存,它被應于

從 Intel HEX 文件 讀取 來 的 隨 后的 記錄 . 線 性地址保持有效, 到 它 被另外一 個擴址記錄 所改 變。

通 過 把 記錄當 中的地址域 與 被移位的 來 自 擴 展 線 性地址 記錄 的地址 數 據相加

獲 得 數 據 記錄 的 絕對 存 儲器地址。

以下的例子演示了這個過 程:

:0200000480007A //數據記錄的絕對存儲器地址高16位為0x8000

:100000001D000A00000000000000000000000000C9

:100010000000000085F170706F0104005D00BD00FC

第一行,是Extended Linear Address Record,里面的數據,也就是基地址是0x8000,第二行是DataRecord,里面的地址值是0x0000。那么數據1D000A00000000000000000000000000(共16個字節)要寫入FLASH中的地址為 (0x8000<< 16)| 0x0000,也就是寫入FLASH的0x80000000這個地址;第三行的數據寫入地址為0x80000010.當一個HEX文件的數據超過64k的時候,文件中就會出現多個Extended Linear Address Record。

(4)擴展段地址記錄(HEX86)“02“

擴展段地址記錄也叫HEX86 記錄 , 它包括4-19 位數據地址段. 擴展段地址記總是有兩

個數 據字節 , 外觀如下:
:020000021200EA
其中:02 是記錄當中 數 據字 節 的 數量;
0000 是地址域. 對于 擴 展段地址 記錄 , 這個 域 總是0000;
02 是記錄類型 02( 擴 展段地址 記錄);
1200 是地址段;
EA 是這個記錄的校 驗 和;

當一 個擴 展段地址 記錄 被 讀 取, 存 儲 于 數 據域的 擴 展段地址被保存, 它 被 應 用于 從 Intel HEX 文件 讀 取 來的 隨 后的 記錄 . 段地址保持有效, 直到 它 被另外一 個擴 展地址 記錄 所改 變。

通 過 把 記錄當 中的地址域 與 被移位的 來 自 擴 展段地址 記錄 的地址 數 據相加 獲 得 數 據 記錄 的 絕對 存 儲器地址。
以下的例子演示了這個過 程…
來自 數 據 記錄地址域的地址 2462
擴展段地址 記錄數據域 + 1200
---------
絕對存 儲 器地址 00014462

Intel HEX 文件例子:
下面是一個 完整的Intel HEX 文件的例子:
:10001300AC12AD13AE10AF1112002F8E0E8F0F2244
:10000300E50B250DF509E50A350CF5081200132259
:03000000020023D8
:0C002300787FE4F6D8FD7581130200031D
:10002F00EFF88DF0A4FFEDC5F0CEA42EFEEC88F016
:04003F00A42EFE22CB
:00000001FF


SREC
SREC全稱Motorola S-record,一種文件格式,由摩托羅拉創建的,該文件使用ASCII HEX文件格式表達二進制信息。這種格式也叫做SRECORD, SREC, S19, S28, S37。通常用于微控制器編程,EPROMs和其他可編程的邏輯器件。在通常的應用中,編譯器或匯編器將程序的源代碼(如C語言或匯編語言)轉換成機器代碼,并將其輸出到一個HEX文件。然后這個HEX文件被程序員燒寫到ROM中,或者轉移到目標系統用于裝載和執行。
//SREC格式

//第一行數據
S0 0F 0000 636B3631302D6C2E73686578 0C
//行數據
S2 08 010000 FFFFFFFF FA
S3 15 08640000 6C0264086C0264086C0264086C026408 16
S5 03 0002 FA
S7 05 08640214 78

SREC文件一行為單位,分為5個部分。分別是記錄類型域、字節數域、地址域、數據域、校驗域。

第一部分類型域是SREC文件的起始標志,代表該行的類型,必須已S開始,值可以是從S0到S9;


第二部分字節數域是每行記錄的長度,地址域、數據域、校驗域三個域的長度,單位為字節數。

第三部分地址域,該域的長度取決于第一部分類型域。

第四部分數據域,該自動長度=字節數域的值-地址域長度-1(校驗域長度)

第五部分校驗域,該域長度為1byte(16-bit),校驗方法是:除了類型域的值其他十六進制值每兩個一組相加結果末兩位為0xFF。


讀取代碼:
QT語言

#include<stdio.h> #include<stdlib.h> #include<QDebug> #include<QString> #include<QByteArray> #include<QDebug> #include<QFile> #include<QDataStream>static char pq=9; //規范代碼/****16進制的數據類型*****/ const QString HexTypeTable[6] = {"00","01","02","03","04","05", };/****配套數據類型使用的枚舉變量*****/ typedef enum __tagHexType {RECORD_DATA = 0,RECORD_END_OF_FILE,RECORD_EXTENDED_SEGMENT_ADDRESS,RECORD_START_SEGMENT_ADDRESS,RECORD_EXTENDED_LINEAR_ADDRESS,RECORD_START_LINEAR_ADDRESS,RECORD_HEX_MAX, }emHexType;typedef enum Boolsymbol {DATA_Flase = 0,DATA_Ture }BoolTureFlase;//定義字符串的類型格式 typedef struct StringTypes {char Firstsymbolis;char StringCrcis;char StringSizeis;char StringResultis;char StringType;//QString BaseAddress; }StringType;static StringType StringTypeLine={DATA_Ture,DATA_Ture,DATA_Ture,DATA_Ture,RECORD_DATA}; //定義字符串的類型格式/****函數聲明*********/ QString AnalyseHEX(QByteArray dest); int mystrlen(const char *StrDest); int HexToDec(char *src); QString QStringLeftBit(QString src,int num); QString QStringToAdd(QString dest,QString src); StringType FormatHexjudge(QByteArray src); QString BaseAddjudge(QByteArray src); void ReadWrite(QString filenameread,QString filenameWrite);/****計算字符串長度*****/ int mystrlen(const char *StrDest) {int i;i=0;while((*StrDest++)!='\0'){i++;}//這個循環體意思是從字符串第一個字符起計數,只遇到字符串結束標志'\0’才停止計數return i; }/****16進制轉換10進制*****/ int HexToDec(char *src) {//將src中的無符號十六進制字符串轉為十進制數//如src="001A",則返回26//字符串src需要以'\0'作為結束標志int value=0,srclen=mystrlen(src);int i;for(i=0;i<srclen;i++){if(src[i]<='9'&&src[i]>='0'){value=value*16+(int)(src[i]-'0'); //'0'}else if(src[i]<='f'&&src[i]>='a'){value=value*16+(int)(src[i]-'a'+10);}else{value=value*16+(int)(src[i]-'A'+10);}}return value;//返回轉換后的數值 }/****字符串效驗*返回效驗的十進制數用來與字符串后兩位做比較****/ QString AnalyseHEX(QByteArray dest) {unsigned char i=1;int tempsum=0; //必須初始化,否則亂碼QString stype;QString ZERO="0";QString Date0x100="100";QString result;do{stype = dest.mid(i,2); //轉換成10進制運算后,再轉換成十六進制printf(" %d",HexToDec(stype.toLatin1().data()));tempsum+=HexToDec(stype.toLatin1().data());i+=2;} while (i<(mystrlen(dest)-2));/***HEX計算公式(0x100-(16進制數據和后兩位))再取后兩位=字符串后兩位*****/result=QString::number((HexToDec(Date0x100.toLatin1().data())-HexToDec(QString::number(tempsum,16).right(2).toLatin1().data())),16);if(result.size()<2){int count=2-result.size();//printf("count=2-result.right(2).size()=%d\n",count);while(count-->0){result.insert(0,ZERO);}}//qDebug()<<"result.right(2).toUpper()"<<result.right(2).toUpper();return result.right(2).toUpper();}/***0613*****字符串左移num位*****************/QString QStringLeftBit(QString src,int num) //{QString zero="0";while(num-->0){src.insert(src.size()-2,zero); //末尾位加零src.remove(0,1); //刪除起始位}return src;}/***0613*****字符串以十六進制的形式轉換成十進制相加,然后轉換成十六進制的字符串形式輸出*****/QString QStringToAdd(QString dest,QString src){QString ResultDate;QString ZERO="0";int num1,num2,ans;int count;bool ok;num1=dest.toInt(&ok,16); //轉換成10進制num2=src.toInt(&ok,16);ans=num1+num2;ResultDate=QString::number(ans,16);/**判斷結果字符串與輸入的兩個字符串的最大差值,用于給結果字符串補零***/(dest.size()-ResultDate.size()>src.size()-ResultDate.size())?count=dest.size()-ResultDate.size():count=src.size()-ResultDate.size();while(count-->0){ResultDate.insert(0,ZERO);}return ResultDate.toUpper();//十進制轉換成Qstring的形式輸出 toUpper() //轉換成大寫字母}/****文件格式類型判斷,有錯誤打印,返回值為基地址******/ StringType FormatHexjudge(QByteArray src) //QString *resultBaseAddres {QByteArray resultString=":00000001FF";static uint32_t count_num=0;count_num++;/******驗證一下傳入的數據***********/char *pcdata = src.data();//printf("Length of src:%d\n",mystrlen(src)); //打印傳入數據大小while(*pcdata){//printf("%c",*pcdata); //打印原始數據++pcdata;}//printf("\n");if(src.left(1)!=":"){//不是以":"開始StringTypeLine.Firstsymbolis=DATA_Flase;printf("Format FirstSymbol wrong!\n");system("Pause");}else{StringTypeLine.Firstsymbolis=DATA_Ture;}if(strlen(src)<11){//字符串長度小于11printf("Format length wrong!\n");system("Pause");}else{StringTypeLine.StringSizeis=DATA_Flase;}if(strcmp(src,resultString)==0){//結束標志StringTypeLine.StringResultis=DATA_Ture;printf("End of file\n");}else{StringTypeLine.StringResultis=DATA_Flase;}if(src.right(2)!= AnalyseHEX(src)) //字符效驗{StringTypeLine.StringCrcis=DATA_Flase; //字符效驗失敗printf("\nSerialcount is wrong in Address=%d\n",count_num);printf("XiaoYan_cc:%c%c\n",*src.right(2).data(),*(src.right(2).data()+1));printf("\nXiaoYan_calcu_int:%d\n",AnalyseHEX(src).toInt());printf("XiaoYan_read_int:%d\n",HexToDec(src.right(2).data())); //讀出來的效驗值system("Pause"); //如果效驗值錯誤,暫停界面}else{StringTypeLine.StringCrcis=DATA_Ture; //字符效驗正確//printf("\nFormat Effect Vaild!!!!!\n");while(mystrlen(src)-2>pq) //打印完所有的數據{QString st = src.mid(pq,2);pq+=2;printf("%c%c ",*st.toLatin1().data(),*(st.toLatin1().data()+1));}}/****判斷數據類型****/QString stringtype = src.mid(7,2);//printf("\nstringtype: %c%c\n",*stringtype.toLatin1().data(),*(stringtype.toLatin1().data()+1));if(stringtype==HexTypeTable[RECORD_DATA]){ //00正常數據類型StringTypeLine.StringType=RECORD_DATA;QString styadd = src.mid(3,4);/****只是分割字符串****/// printf("styadd:%c%c%c%c\n",*styadd.toLatin1().data(),*(styadd.toLatin1().data()+1),*(styadd.toLatin1().data()+2),*(styadd.toLatin1().data()+3));}else if (stringtype==HexTypeTable[RECORD_END_OF_FILE]){ //01 用來標識文件結束StringTypeLine.StringType=RECORD_END_OF_FILE;printf("RECORD_END_OF_FILE\n ");}else if (stringtype==HexTypeTable[RECORD_EXTENDED_LINEAR_ADDRESS]) //TODO:只需要判斷一次{ //04 擴展線性地址記錄StringTypeLine.StringType=RECORD_EXTENDED_LINEAR_ADDRESS;printf("RECORD_EXTENDED_LINEAR_ADDRESS \n");QString styadd = src.mid(3,4);QString styaddsub = src.mid(9,4); //字符串拼接styadd.insert(0,styaddsub);//printf("StyaddSub04:%c%c%c%c%c%c%c%c\n",*styadd.toLatin1().data(),*(styadd.toLatin1().data()+1),// *(styadd.toLatin1().data()+2),*(styadd.toLatin1().data()+3),*(styadd.toLatin1().data()+4),*(styadd.toLatin1().data()+5),*(styadd.toLatin1().data()+6),*(styadd.toLatin1().data()+7));//system("Pause");}else if(stringtype==HexTypeTable[RECORD_EXTENDED_SEGMENT_ADDRESS]){ //02 擴展段地址記錄StringTypeLine.StringType=RECORD_EXTENDED_SEGMENT_ADDRESS;printf("RECORD_EXTENDED_SEGMENT_ADDRESS\n");}else if(stringtype==HexTypeTable[RECORD_START_LINEAR_ADDRESS]){ //05 開始線性地址記錄StringTypeLine.StringType=RECORD_START_LINEAR_ADDRESS;printf("RECORD_START_LINEAR_ADDRESS\n");}else if(stringtype==HexTypeTable[RECORD_START_SEGMENT_ADDRESS]){ //03 開始段地址記錄StringTypeLine.StringType=RECORD_START_SEGMENT_ADDRESS;printf("RECORD_START_SEGMENT_ADDRESS\n");system("Pause"); //如果遇到03則暫停,預留處理03的代碼 (0613/還未遇到)}return StringTypeLine; }/******判斷基地址**如果數據類型為04調用*******/ QString BaseAddjudge(QByteArray src) {QString resultBaseAddres;QString stringtype = src.mid(7,2); /****判斷數據類型****/if (stringtype==HexTypeTable[RECORD_EXTENDED_LINEAR_ADDRESS]) //TODO:只需要判斷一次RECORD_EXTENDED_LINEAR_ADDRESS{ //04 擴展線性地址記錄QString styadd = src.mid(3,4);QString styaddsub = src.mid(9,4); //字符串拼接styadd.insert(0,styaddsub);printf("StyaddSub04:%c%c%c%c%c%c%c%c\n",*styadd.toLatin1().data(),*(styadd.toLatin1().data()+1),*(styadd.toLatin1().data()+2),*(styadd.toLatin1().data()+3),*(styadd.toLatin1().data()+4),*(styadd.toLatin1().data()+5),*(styadd.toLatin1().data()+6),*(styadd.toLatin1().data()+7));return styadd;}if (stringtype==HexTypeTable[RECORD_EXTENDED_SEGMENT_ADDRESS]) //TODO:只需要判斷一次RECORD_EXTENDED_LINEAR_ADDRESS{ //02 擴展段地址記錄QString Basezer0 = "0000";QString styaddsub = src.mid(9,4); //字符串拼接Basezer0.insert(4,styaddsub);Basezer0=QStringLeftBit(Basezer0,1);printf("StyaddSub02:%c%c%c%c%c%c%c%c\n",*Basezer0.toLatin1().data(),*(Basezer0.toLatin1().data()+1),*(Basezer0.toLatin1().data()+2),*(Basezer0.toLatin1().data()+3),*(Basezer0.toLatin1().data()+4),*(Basezer0.toLatin1().data()+5),*(Basezer0.toLatin1().data()+6),*(Basezer0.toLatin1().data()+7));return Basezer0; //在02數據類型的方式下需要左移一位}return resultBaseAddres; }/****新字符串拼接*****/ QString FormatTranQARRYbyte(QByteArray src) {char count=9;char newcount=10;QString ResultDate;static QString resultBaseAddress="00000000"; //static 修飾只初始化一次 //0x08000000QString space=" ";StringTypeLine=FormatHexjudge(src);if(StringTypeLine.StringCrcis==DATA_Ture) //如果效驗碼正確{if(StringTypeLine.StringType==RECORD_EXTENDED_LINEAR_ADDRESS) //如果是擴展性數據類型 04{resultBaseAddress=BaseAddjudge(src); //接收擴展地址qDebug()<<"resultBaseAddress"<<resultBaseAddress;}if(StringTypeLine.StringType==RECORD_EXTENDED_SEGMENT_ADDRESS) //如果是段數據類型 02{resultBaseAddress=BaseAddjudge(src);qDebug()<<"resultBaseAddress"<<resultBaseAddress;}ResultDate=resultBaseAddress; //第一個是地址ResultDate=QStringToAdd(ResultDate,src.mid(3,4)); //基地址和絕對地址相加if(StringTypeLine.Firstsymbolis==DATA_Ture) //如果字符串的第一個符號是“:”{ResultDate.insert(8,src.left(1)); //插入符號ResultDate.insert(9,space);}while(mystrlen(src)-2>count) //打印完所有的數據{ResultDate.insert(newcount,src.mid(count,2));newcount=newcount+3;ResultDate.insert(newcount,space);count=count+2;}if(StringTypeLine.StringType==RECORD_DATA) //當數據類型為00的時候才打印{printf("\n");qDebug()<<"ResultDate "<<ResultDate<<endl<<endl<<endl;}}return ResultDate; }#if 0 /***按行讀取HEX文件并進行處理*****/ void read(QString filename){QFile file(filename);if(!file.open(QFile::ReadOnly | QFile::Text)){qDebug() << " Could not open the file for reading";return;}QTextStream in(&file);while(!in.atEnd()){QString myText = in.readLine();QString str(myText);QByteArray bytes = str.toLatin1(); //Qstring 轉 QByteArrayqDebug() << bytes;FormatTranQARRYbyte(bytes);printf("\n\n\n");}file.close();}/***按行讀取HEX文件并進行處理*****/ void Write(QString filename) {QFile file(filename);if(!file.open(QFile::WriteOnly | QFile::Text)){qDebug() << " Could not open the file for reading";return;}//QTextStream stream(&file);//stream.seek(file.size());QString resultString=":00000001FF\n";QString EnterResul="\n";QByteArray AER=":10246200464c5549442050524f46494c4500464c33";file.write(FormatTranQARRYbyte(AER).toUtf8());file.write(EnterResul.toUtf8());file.write(resultString.toUtf8());file.close();return; } #endif/***按行讀取HEX文件并進行處理*****/ void ReadWrite(QString filenameread,QString filenameWrite){QString EnterResul="\n";QFile fileread(filenameread);if(!fileread.open(QFile::ReadOnly | QFile::Text)){qDebug() << " Could not open the file for reading";return;}QFile filewrite(filenameWrite);if(!filewrite.open(QFile::WriteOnly | QFile::Text)){qDebug() << " Could not open the file for reading";return;}QTextStream in(&fileread);while(!in.atEnd()){QString myText = in.readLine();QString str(myText);QByteArray bytes = str.toLatin1(); //Qstring 轉 QByteArrayqDebug() << bytes;QString ResultText;ResultText=FormatTranQARRYbyte(bytes);if(StringTypeLine.StringType==RECORD_DATA) //只將數據類型為 00 的字符串寫入{filewrite.write(ResultText.toUtf8()); //寫入數據filewrite.write(EnterResul.toUtf8()); //寫入回車}printf("\n");}fileread.close();filewrite.close();}/**0613生成成功**/ int main() {QString filename = "C:/Users/Administrator/Desktop/HEX2/VCU_S32K14X.hex";//QString filename = "C:/Users/Administrator/Desktop/HEX2/Projec.hex";QString filewritename = "C:/Users/Administrator/Desktop/HEX2/Pro1.hex";//QByteArray AER=":020000040800F2";// QByteArray AER=":105CC00010831C46234618465DF8044B704708B500";//FormatTranQARRYbyte(AER);ReadWrite(filename,filewritename);}

C#語言
頭文件

#ifndef CHEX_H #define CHEX_H#include <QFile>const quint8 MIN_HEX_LINE_COUNT_LENGHT = 12;typedef enum __tagHexErrorCode {HEX_NO_ERROR = 0,HEX_FORMAT_ERROR,HEX_VERIFY_ERROR,HEX_LENGHT_ERROR,HEX_USERPAPR_EEROR, }EHexErrorCode;typedef enum __tagHexType {RECORD_DATA = 0,RECORD_END_OF_FILE,RECORD_EXTENDED_SEGMENT_ADDRESS,RECORD_START_SEGMENT_ADDRESS,RECORD_EXTENDED_LINEAR_ADDRESS,RECORD_START_LINEAR_ADDRESS,RECORD_HEX_MAX, }emHexType;typedef struct __tagHexLineData {emHexType type;quint8 count;quint32 address;quint8 data[80];quint8 checksum;quint8 datalen; }stHexLineData;class CHex { public:CHex();EHexErrorCode getHexLineData(QByteArray bydata,stHexLineData *p); private:char ConvertHexChar(char ch); };#endif // CHEX_H

源文件

#include "chex.h"const QString HexTypeTable[6] = {"00","01","02","03","04","05", };CHex::CHex() {}char CHex::ConvertHexChar(char ch) {if((ch >= '0') && (ch <= '9'))return (ch-0x30);else if((ch >= 'A') && (ch <= 'F'))return ((ch-'A')+10);else if((ch >= 'a') && (ch <= 'f'))return ((ch-'a')+10);else return (-1); }EHexErrorCode CHex::getHexLineData(QByteArray bydata,stHexLineData *p) {quint8 i = 0;quint8 cs_temp = 0;QString str(bydata);char *pcdata = bydata.data();quint32 linelen = str.size();if((linelen < MIN_HEX_LINE_COUNT_LENGHT)) {return HEX_LENGHT_ERROR;}if(*pcdata != 0x3A) {return HEX_FORMAT_ERROR;}//必須以":"號開始//獲取TypeQString stype = str.mid(7,2);for(i = 0; i < RECORD_HEX_MAX; i++){if(stype == HexTypeTable[i]){p->type = (emHexType)i;break;}}if(i == RECORD_HEX_MAX) {qDebug("HEX_FORMAT_ERROR");return HEX_FORMAT_ERROR;}cs_temp += (ConvertHexChar(*(pcdata + 7)) << 4) | ConvertHexChar(*(pcdata + 8));//獲取countp->count = (ConvertHexChar(*(pcdata + 1)) << 4) | ConvertHexChar(*(pcdata + 2));cs_temp += p->count;if(p->count != (((linelen - 2) / 2) - 5)) {qDebug("HEX_FORMAT_ERROR");return HEX_FORMAT_ERROR;}//獲取addressp->address = (ConvertHexChar(*(pcdata + 3)) << 12) | (ConvertHexChar(*(pcdata + 4)) << 8) | (ConvertHexChar(*(pcdata + 5)) << 4) | ConvertHexChar(*(pcdata + 6));cs_temp += (p->address >> 8) & 0xFF;cs_temp += p->address & 0xFF;//獲取datafor(i = 0; i < p->count; i++){p->data[i] = (ConvertHexChar(*(pcdata + 2*i + 9)) << 4) | ConvertHexChar(*(pcdata + 2*i + 10));cs_temp += p->data[i];}p->checksum = (ConvertHexChar(*(pcdata + 2*i + 9)) << 4) | ConvertHexChar(*(pcdata + 2*i + 10));if(p->checksum != ((0x100 - cs_temp) & 0xFF)){qDebug("HEX_VERIFY_ERROR");return HEX_VERIFY_ERROR;}p->datalen = p->count;return HEX_NO_ERROR; }

總結

以上是生活随笔為你收集整理的HEX文件格式解析(转)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。