QT编程:S19转BIN

本文介绍如何使用QT编程将S19格式的烧录程序转换为BIN文件,适用于嵌入式单片机的bootloader。转换过程中,会在BIN文件头部添加包含数据块数、大小、CRC值等信息的数据区。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

QT编程:S19转BIN

在做嵌入式单片机的bootloader功能时,通常需要将HEX格式或S19格式的烧录程序转成纯数据的BIN文件。在学QT过程中,决定自己做一个S19转BIN文件的小工具。

关于S19文件的格式,网上有很多资料,这里不再赘述。在实际使用中生成的BIN文件中,除了S19的中有用数据,在BIN文件开头添加了一段信息数据。

在这里插入图片描述
如上表所示,在BIN文件的开头添加1K的的信息区。信息区中包含有效数据块数,有效数据大小,CRC值及程序版本日期等,后面是各个数据块对于的地址,数据格式,及CRC值等。

下面晒出代码:

s19tobin.h

#ifndef S19TOBIN_H
#define S19TOBIN_H

#include <QMainWindow>

#include <QTimer>                                                               /* 定时器 */
#include <QDebug>                                                               /* 调试诊断接口 */
#include <QTime>                                                                /* 系统时间 */
#include <QDebug>
#include "QFileDialog"



class s19tobin
{
   
   
public:
    s19tobin();
    ~s19tobin();

    /* analyze s19 file, get bin data, generate bin file */
    int s19tobin_pro(QString fpath,QString sv_str);


private:

    /* bin file information area */
    #define BIN_INFO_AREA_SEIZ       (1024)
    #define BIN_INFO_BASE_SEIZ       (256)
    #define BIN_INFO_BLOCK_NUM       (48)
    #define BIN_INFO_SV_SEIZ         (16)
    #define BIN_INFO_DATE_SEIZ       (32)
    typedef union
    {
   
   
        quint8  buf[BIN_INFO_BASE_SEIZ];
        struct
        {
   
   
            quint8  head;
            quint8  bnum[2];
            quint8  dlen[4];
            quint8  dcrc[4];
            quint8  resv1[5];
            char  soft_version[BIN_INFO_SV_SEIZ];
            char  date[BIN_INFO_DATE_SEIZ];
        }fd;
    }BIN_BASE_INFO_DEF;
    typedef struct
    {
   
   
        quint8 index;
        quint8 addr[4];
        quint8 dlen[4];
        quint8 dcrc[4];
        quint8 resv[2];
        quint8 crc;
    }BIN_BLOCK_INFO_DEF;
    typedef union
    {
   
   
        quint8  buf[BIN_INFO_AREA_SEIZ];
        struct
        {
   
   
            BIN_BASE_INFO_DEF  base;
            BIN_BLOCK_INFO_DEF block[BIN_INFO_BLOCK_NUM];
        }fd;
    }BIN_INFO_DEF;

    /* S19 TO BIN CONTROL CONTEXT */
    #define BIN_LINE_DATA_SIZE      (256)
    typedef struct
    {
   
   
        /* initialize flag */
        int initflag;                                    /* 1: initialzed */

        char    rl_draw[BIN_LINE_DATA_SIZE];             /* a s19 file line data */
        quint8  rl_draw_len;                             /* a s19 file line data size */
        quint8  rl_sindex;                               /* the first 's' position in a s19 file line data size */

        quint8  rl_data[BIN_LINE_DATA_SIZE];             /* the valid data in a s19 file line data */
        quint8  rl_dlen;                                 /* the valid data size */
        quint32 rl_addr;                                 /* the valid data addr */

        quint32 rl_block_flag;                           /* 1: first block have been got */
        quint32 rl_block_addr;                           /* the current block addr */
        quint32 rl_block_dcnt;                           /* the current block data counter */
        quint32 rl_block_dcrc;                           /* the current block data crc */


        /* bin file information area */
        BIN_INFO_DEF bin_info;

        quint32 block_addr[BIN_INFO_BLOCK_NUM];          /* record all block addr */
        quint32 block_dlen[BIN_INFO_BLOCK_NUM];          /* record all block data len */
        quint32 block_dcrc[BIN_INFO_BLOCK_NUM];          /* record all block crc */

        quint16 block_cnt;                               /* block cnt */
        quint32 total_dcrc;                              /* total data crc */
        quint32 total_dlen;                              /* total data len */
    }S19TOBIN_CONTEXT_DEF;


    QString fpath_s19;
    QFile fs19;
    QFile fbin;
    QFile flog;
    QTextStream login;
    QString logstr;
    S19TOBIN_CONTEXT_DEF ctx;

    uint8_t change_CharToHex(char ch);                                          /* 将字符转换成16进制数据 */
    char    change_HexToChar(uint8_t hex);                                      /* 将16进制数据转换成字符 */
    uint8_t change_CharToU8(char byteh,char bytel);                             /* 将两字节字符数据转换成一个字节HEX,第一个字符是高位 */
    quint8  calc_crc8(quint8 *buf,quint32 len);                                 /* calculate crc8 , add all data , left lowest 8 byte */
    quint32 calc_crc32(quint8 *buf,quint32 len);                                /* calculate crc32 , add all data , left lowest 32 byte */


    int open_fs19(QString p_fpath);
    int open_flog(QString p_fpath);
    int open_fbin(QString p_fpath);
    int analyze_line_check_len_and_crc(QString str,int *p_sindex);
    int analyze_line_check_addr_and_data(QString str);
    int analyze_line_write_valid_data_to_bin_file(void);
    int analyze_a_line(QString str);
    int analyze_write_bin_info_to_bin_file(QString sv);
    int analyze_fs19(QString sv_str);


};

#endif // S19TOBIN_H

s19tobin.cpp

#include "s19tobin.h"


s19tobin::s19tobin()
{
   
   
    memset(&ctx,0,sizeof(ctx));
}

s19tobin::~s19tobin()
{
   
   
    fs19.close();
    fbin.close();
    flog.close();
}

/*
*****************************************************************
*name: change_CharToHex
*descrip: 将字符转换成16进制数据
*input: 字符
*return: 对应数值
*****************************************************************
*/
uint8_t s19tobin::change_CharToHex(char ch)
{
   
   
    uint8_t hex = 0;
    switch (ch)
    {
   
   
        case '0': hex = 0; break;
        case '1': hex = 1; break;
        case '2': hex = 2; break;
        case '3': hex = 3; break;
        case '4': hex = 4; break;
        case '5': hex = 5; break;
        case '6': hex = 6; break;
        case '7': hex = 7; break;
        case '8': hex = 8; break;
        case '9': hex = 9; break;
        case 'a': hex = 10; break;
        case 'b': hex = 11; break;
        case 'c': hex = 12; break;
        case 'd': hex = 13; break;
        case 'e': hex = 14; break;
        case 'f': hex = 15; break;

        case 'A': hex = 10; break;
        case 'B': hex = 11; break;
        case 'C': hex = 12; break;
        case 'D': hex = 13; break;
        case 'E': hex = 14; break;
        case 'F': hex = 15; break;

        default:break;
    }

    return hex;
}

/*
*****************************************************************
*name: change_HexToChar
*descrip: 将16进制数据转换成字符
*input: 16进制数值
*return: 字符
*****************************************************************
*/
char s19tobin::change_HexToChar(uint8_t hex)
{
   
   
    char ch = 0;
    switch (hex & 0x0f)
    {
   
   
        case 0x00U: ch = '0'; break;
        case 0x01U: ch = '1'; break;
        case 0x02U: ch = '2'; break;
        case 0x03U: ch = '3'; break;
        case 0x04U: ch = '4'; break;
        case 0x05U: ch = '5'; break;
        case 0x06U: ch = '6'; break;
        case 0x07U: ch = '7'; break;
        case 0x08U: ch = '8'; break;
        case 0x09U: ch = '9'; break;
        case 0x0aU: ch = 'A'; break;
        case 0x0bU: ch = 'B'; break;
        case 0x0cU: ch = 'C'; break;
        case 0x0dU: ch = 'D'; break;
        case 0x0eU: ch = 'E'; break;
        case 0x0fU: ch = 'F'; break;
        default:break;
    }
    return ch;
}


/*
*****************************************************************
* name: change_CharToU8
* descrip: 将两字节字符数据转换成一个字节HEX,第一个字符是高位
* input: byteh - high part of a byte,
*        bytel -  low part of a byte
* output: result byte
*****************************************************************
*/
uint8_t s19tobin::change_CharToU8(char byteh,char bytel)
{
   
   
    return (uint8_t)(((uint8_t)change_CharToHex(byteh) << 4u) | ((uint8_t)change_CharToHex(bytel)));
}


/*
*****************************************************************
* name: calc_crc8
* descrip: calculate crc8 , add all data , left lowest 8 byte
* input: buf - data buf,
*        len -  size of data
* output: result byte
*****************************************************************
*/
quint8 s19tobin::calc_crc8(quint8 *buf,quint32 len)
{
   
   
    quint8 crc = 0
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值