⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hex.c

📁 这是《Keil Cx51 V7.0单片机高级语言编程与uVision2应用实践》教材各章中列出的全部程序例子。
💻 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 + -