📄 hex.c
字号:
#include "config.h"
#include "isp.h"
#include <ctype.h>
/***************************** 宏定义 ***********************************/
/* 定义HEX文件解码符号 */
#define REC_MARK 0x01
#define REC_LEN_1 0x02
#define REC_LEN_2 0x03
#define OFFSET_1 0x04
#define OFFSET_2 0x05
#define OFFSET_3 0x06
#define OFFSET_4 0x07
#define REC_TYP_1 0x08
#define REC_TYP_2 0x09
#define DATA_1 0x0A
#define DATA_2 0x0B
#define CHEKSUM_1 0x0C
#define CHEKSUM_2 0x0D
Uchar hex_decoder(Uchar hex_data);
/****************************** HEX文件分析函数 **************************
* 功 能: 监视HEX文件接收缓冲区,一旦收到数据就调用HEX文件解码函数。
* 返 回 值:HEX文件分析状态(OK或CRC错)。
*************************************************************************/
Uchar hex_parser(void) {
Uchar hex_data, status;
status = HEX_DEC_OK;
while (status == HEX_DEC_OK) { /* HEX文件解码正确则继续处理 */
if(nb_rx_data != 0) {
hex_data = rx_buffer_rd();
status = hex_decoder(hex_data);
}
}
return status;
}
/***************************** HEX文件解码函数 ***************************
* 功 能: 对接收到的ASCII码文件按字节进行HEX文件记录解码,分离出用于
* FLASH编程的数据以及校验和。
* 参 数: Uchar hex_data,待解码的HEX文件数据。
* 返 回 值: HEX文件分析状态(OK或CRC错)。
************************************************************************/
Uchar hex_decoder(Uchar hex_data) {
static state = REC_MARK;
static Uchar length, type, nb_byte, data_value, sum, sum_1, sum_2;
static Uint16 offset;
Uchar status;
status = HEX_DEC_OK;
switch(state) {
case REC_MARK: { /* 开始一个新纪录 */
if (hex_data == ':') { /* 检查首字符是否正确*/
state = REC_LEN_1; /* 正确,获取第一个长度字符 */
nb_byte=0;
}
else
state = REC_MARK; /* 错误, 跳过伪字符 */
break;
}
case REC_LEN_1: { /* 获取长度字节中的第一个数字 */
length = toint(hex_data) * 16;
state = REC_LEN_2;
break;
}
case REC_LEN_2: { /* 获取长度字节中的第二个数字 */
length = length + toint(hex_data);
state = OFFSET_1;
break;
}
case OFFSET_1: { /* 获取地址字节中的第一个数字 */
offset = toint(hex_data) * 4096;
state = OFFSET_2;
break;
}
case OFFSET_2: { /* 获取地址字节中的第二个数字 */
offset = offset + toint(hex_data) * 256;
sum_1= offset / 256;
state = OFFSET_3;
break;
}
case OFFSET_3: { /* 获取地址字节中的第三个数字 */
offset = offset + toint(hex_data) * 16;
state = OFFSET_4;
break;
}
case OFFSET_4: { /* 获取地址字节中的第四个数字 */
offset = offset + toint(hex_data);
sum_2 = offset - sum_1 * 256;
state = REC_TYP_1;
break;
}
case REC_TYP_1: { /* 获取纪录字节中的第一个数字 */
type = toint(hex_data) * 16;
state =REC_TYP_2;
break;
}
case REC_TYP_2: { /* 获取纪录字节中的第二个数字 */
type = type + toint(hex_data);
sum = length + sum_1 + sum_2 + type;
if (length==0x00)
state=CHEKSUM_1; /* 如果没有数据, 转到计算校验和 */
else
state = DATA_1; /* 否则下一步为获取数据纪录 */
break;
}
case DATA_1: { /* 获取一个数据中的第一位数字 */
data_value = toint(hex_data) * 16 ;
state = DATA_2;
break;
}
case DATA_2: { /* 获取一个数据中的第二位数字 */
data_value = data_value + toint(hex_data);
sum = sum + data_value;
flash_prog(offset + nb_byte, data_value);
nb_byte++;
if (nb_byte == length)
state = CHEKSUM_1; /* 若已到数据块尾,转到校验和 */
else
state = DATA_1; /* 否则获取块中的下一个数据 */
break;
}
case CHEKSUM_1: { /* 获取校验和中的第一个数字 */
sum_1 = toint(hex_data) * 16;
sum = (~sum) + 1;
state = CHEKSUM_2;
break;
}
case CHEKSUM_2: { /* 获取校验和中的第二个数字 */
sum_1 = sum_1 + toint(hex_data);
if (sum_1 != sum)
status = HEX_DEC_CSERR;
state = REC_MARK; /* 准备好进行下一个纪录 */
if(type==0x01)
status = HEX_DEC_END; /* 传送结束 */
break;
}
}
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -