bin檔案轉換為hex檔案C語言實現

來源:互聯網
上載者:User

標籤:hex檔案   bin檔案   批處理   

對於嵌入式而言,hex檔案可能大家再熟悉不過了,對,我們大學時學習的51單片機編寫的代碼在keil上編譯後就產生了hex檔案。那bin檔案又是什麼意思呢,它又和hex檔案的區別在哪?這也不是本文的重點,下面簡單的描述下:

最通俗的來講,hex是帶地址的,用下載器下載時,不需要設定位移地址,它是檔案流格式的,都是標準的ASCII碼。而bin檔案是不帶地址的,全部是位元據流,打住一下,其實就是我們所謂的機器代碼。有興趣的同學,可以嘗試著用反組譯碼,得到的就是彙編代碼了。我所用的開發板S3C2440在ADS1.2上編譯形成的代碼就是bin格式流,用j-flash開啟檔案的時候就需要填入位移地址,三星平台flash位移地址為0,而stm32平台flash位移地址就是0x08000000.

本來是應該要描述下hex檔案的資料格式,這個就留著下一篇文章來描述,其實百度上也有很多。下一張是hex檔案轉換為bin檔案,剛好和本文相反。說了這麼多,下面就直接貼出代碼了,有不詳細的可以給我留言,同時也歡迎大家噴我。

代碼是在VC6.0上面實現的:

首先建立bin2hex.h檔案

#ifndef BIN2HEX_H#define BIN2HEX_Htypedef unsigned char uint8_t;typedef unsigned short uint16_t;typedef unsigned long uint32_t;/********************************************************************************就是每次讀寫bin檔案N個位元組,然後再轉化為hex格式流,hex格式流長度計算方式: + 長度 + 地址 + 類型 + N個資料(N >= 0) + 校正1 + 2 + 4+ 2   + N * 2 + 2********************************************************************************/#define NUMBER_OF_ONE_LINE0x20#defineMAX_BUFFER_OF_ONE_LINE(NUMBER_OF_ONE_LINE * 2 + 11) typedef struct {uint8_t len;uint8_t addr[2];uint8_t type;uint8_t *data;} HexFormat;typedef enum {RES_OK = 0,//操作完成RES_BIN_FILE_NOT_EXIST,//相當於bin檔案不存在,包括輸入的路徑可能存在不正確RES_HEX_FILE_PATH_ERROR//目標檔案路徑可能輸入有誤} RESULT_STATUS;RESULT_STATUS BinFile2HexFile(char *src, char *dest);#endif

建立bin2hex.c 檔案

#include "bin2hex.h"#include <stdio.h>/********************************************************************************input:dest: 為轉換後的結果p->addr[0]: 高地址p->addr[1]: 低地址p->type: 記錄類型p->data: 為bin格式流有效資料指標p->len: 為bin格式流有效資料長度output:返回有效資料的長度********************************************************************************/uint16_t BinFormatEncode(uint8_t *dest, HexFormat *p){uint16_t offset = 0;uint8_t check = 0, num = 0;//:(1) + 長度(2) + 地址(4) + 類型(2)sprintf(&dest[offset], ":%02X%02X%02X%02X", p->len, p->addr[0], p->addr[1], p->type);offset += 9;//hex格式流資料指標位移2check = p->len + p->addr[0] + p->addr[1] + p->type;//計算校正和while (num < p->len)//當資料長度不為0,繼續在之前的hex格式流添加資料{sprintf(&dest[offset], "%02X", p->data[num]);check += p->data[num];//計算校正和offset += 2;//hex格式資料流資料指標位移2num++;//下一個字元}check = ~check + 1;//反碼+1sprintf(&dest[offset], "%02X", check);offset += 2;return offset;//返回hex格式資料流的長度}RESULT_STATUS BinFile2HexFile(char *src, char *dest){FILE *src_file, *dest_file;uint16_t tmp;HexFormat gHexFor;uint32_t low_addr = 0, hign_addr = 0;uint8_t buffer_bin[NUMBER_OF_ONE_LINE], buffer_hex[MAX_BUFFER_OF_ONE_LINE];uint32_t src_file_length;uint16_t src_file_quotient, cur_file_page = 0;uint8_t src_file_remainder;src_file = fopen(src, "rb");//源檔案為bin檔案,以二進位的形式開啟if (!src_file)//這裡也是相當於用來檢查使用者的輸入是否準備{return RES_BIN_FILE_NOT_EXIST;}dest_file = fopen(dest, "w");//目的檔案為hex檔案,以文本的形式開啟if (!dest_file){return RES_HEX_FILE_PATH_ERROR;}fseek(src_file, 0, SEEK_END);//定位到檔案末 src_file_length = ftell(src_file);fseek(src_file, 0, SEEK_SET);//重新置放到開頭,準備開始讀取資料src_file_quotient = (uint16_t)(src_file_length / NUMBER_OF_ONE_LINE);//商,需要讀取多少次src_file_remainder = (uint8_t)(src_file_length % NUMBER_OF_ONE_LINE);//餘數,最後一次需要多少個字元gHexFor.data = buffer_bin;//指向需要轉換的bin資料流while (cur_file_page < src_file_quotient){fread(buffer_bin, 1, NUMBER_OF_ONE_LINE, src_file);gHexFor.len = NUMBER_OF_ONE_LINE;if ((low_addr & 0xffff0000) != hign_addr && hign_addr != 0)//只有大於64K以後才寫入擴充線性地址,第一次一般是沒有{hign_addr = low_addr & 0xffff0000;gHexFor.addr[0] = (uint8_t)((hign_addr & 0xff000000) >> 24);gHexFor.addr[1] = (uint8_t)((hign_addr & 0xff0000) >> 16);gHexFor.type = 4;gHexFor.len = 0;//記錄擴充地址tmp = BinFormatEncode(buffer_hex, &gHexFor);fwrite(buffer_hex, 1, tmp, dest_file);fprintf(dest_file, "\n"); ;}gHexFor.addr[0] = (uint8_t)((low_addr & 0xff00) >> 8);gHexFor.addr[1] = (uint8_t)(low_addr & 0xff);gHexFor.type = 0;//資料記錄tmp = BinFormatEncode(buffer_hex, &gHexFor);fwrite(buffer_hex, 1, tmp, dest_file);fprintf(dest_file, "\n"); ;cur_file_page++;low_addr += NUMBER_OF_ONE_LINE; }if (src_file_remainder != 0)//最後一次讀取的個數不為0,這繼續讀取{fread(buffer_bin, 1, src_file_remainder, src_file);gHexFor.addr[0] = (uint8_t)((low_addr & 0xff00) >> 8);gHexFor.addr[1] = (uint8_t)(low_addr & 0x00ff);gHexFor.len = src_file_remainder;gHexFor.type = 0;//資料記錄tmp = BinFormatEncode(buffer_hex, &gHexFor);fwrite(buffer_hex, 1, tmp, dest_file);fprintf(dest_file, "\n"); ;}gHexFor.addr[0] = 0;gHexFor.addr[1] = 0;gHexFor.type = 1;//結束符gHexFor.len = 0;tmp = BinFormatEncode(buffer_hex, &gHexFor);fwrite(buffer_hex, 1, tmp, dest_file);fprintf(dest_file, "\n"); ;fclose(src_file);fclose(dest_file);return RES_OK;}

建立main.c檔案,這裡是帶參數的,主要是方便批處理,是另有用途。

#include <stdio.h>#include "bin2hex.h"int main(int argc, char *argv[]){RESULT_STATUS res;if (argc != 3){printf("input para doesn't match\r\n");return -1;}res = BinFile2HexFile(argv[1], argv[2]);switch (res){case RES_OK:printf("hex file to bin file success!\r\n");break;case RES_BIN_FILE_NOT_EXIST:printf("bin file doesn't exist!\r\n");break;case RES_HEX_FILE_PATH_ERROR:printf("hex file path is error, please check it!\r\n");break;}return 0;}

就三個源檔案,編譯產生bin2hex.c檔案。

下面描述下用法:

把bin2hex.c檔案拷貝到c盤根目錄下,再拷貝一個需要轉換的bin檔案,這裡我就拷貝了一個hwb.bin檔案。然後點擊菜單開始->運行->輸入cmd->進入dos視窗->調整目前的目錄為c:,這個如果不知道的可以百度一下,無法就是就是命令cd.

最後輸入命令:bin2hex hwb.bin hwb.hex,輸入後,可以看到提示說轉換成功,大家再檢查下是否有一個hex檔案,本文的代碼支援大於64K,大家把轉換後的hex下載到單片機上運行試試看。

bin檔案轉換為hex檔案C語言實現

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.