原创 如何把两个*.hex合并成一个*.hex?在写IAP/Bootloader很有用哦

2008-6-12 14:29 11793 11 13 分类: MCU/ 嵌入式

        前几天,一网友在某论坛上问我关于PIC Bootloader的问题,他问如何创建两个工程分别编写引导程序和用户程序,分别将两个工程编译成两个.hex文件,然后手工合为一个.hex文件,然后再把这个合并后的.hex文件(即包含引导程序和用户程序)烧写到芯片上去?


 


        恰好在这之前我写过PIC Bootloader,遇到并解决了这个问题.那么现在就来向大家介绍一下关于如何把两个.hex文件合并成一个.hex的方法,一般在你写IAP/Bootloader的时候能够用到,此方法自己认为很有创造性,希望大家喜欢,呵呵.


 


        阅读此文章之前你需要了解如下几个方面的知识:
        1.如何在PICC18编译器中实现程序定位?
答:方法是在MPLAB IDE中,从菜单中选择Project->Build Options...->Project,在PICC-18 Linker页标下的Specify offset for ROM(ROM代码偏移量)中输入偏移量XXX(注意这里输入的已经是16进制了,不用在转换)。 
        重新编译,然后在View->Program Memory就可以看到你的程序已经定位在XXX起始的地址上了.
        2.理解这个语句所代表的意思:  (*((void(*)(void))User_Start))();
        3.了解hex文件的格式.


 


        好,现在就开始谈谈实现方法吧:
        1.配置,编译,链接第一个程序,生成第一个.hex文件
        下边这个程序是0ffset_0x000.c,其代码位于0x000-0x4ff起始的地址块上,请参照Note上的提示进行设置,把生成的hex文件命名为:000.hex
/************************************************************************************************
**本程序只供学习使用,未经作者许可,不得用于其它任何用途
**版权所有,盗版必究。
**Copyright(C) CheungMan
**All rights reserved
**欢迎访问我的blog:http://www.ednchina.com/blog/cheungman
**E-mail          : zhw-198@163.com
************************************************************************************************
**FileName      : 0ffset_0x000.c
**Target        : PIC18F458
**XTAL          : 4MHZ
**Autor         : ZhangWen
**Start Date    : 2008.04.24
**Modify Date   :
**Edition       : V1.0
**HardWare      :
**SofeWare      : MPLAB IDE v8.02 + PICC 18 v8.35
**Function      : 请在MPLAB IDE中,从菜单中选择Project->Build Options...->Project,
**    在PICC-18 Linker页标下的Specify offset for ROM(ROM代码偏移量)中输入偏移量0
**Note          : 注意,此程序偏移0x000地址,其实默认就是0.
***********************************************************************************************/


#include


__CONFIG(1, HSPLL);   //配置HS,4倍频
__CONFIG(2, WDTDIS);   //禁止看门狗


#define User_Start    0x500     //用户程序开始位置


//延时
void Delay(void)
{
 unsigned long i;
 for(i=0; i<150000; i++);
}


void main(void)
{
 unsigned char FlashTime; //定义闪烁次数
     TRISB = 0x00;   //定义RB0-RB7为输出   
     PORTB = 0x00;   //初始化为低电平
     while(1)
    {
         for(FlashTime=0; FlashTime<10; FlashTime++)//闪烁10次
  {
   PORTB = 0xff;
          Delay();
          PORTB = 0x00;
          Delay();
  }
         (*((void(*)(void))User_Start))(); //进入用户程序,即0x500地址起始的程序代码,也就是0ffset_0x500.c
    } 
}


         2.配置,编译,链接第二个程序,生成第二个.hex文件
        下边这个程序是0ffset_0x500.c,其代码位于0x500-0xXXX起始的地址块上,请参照Note上的提示进行设置,把生成的hex文件命名为:500.hex
/************************************************************************************************
**本程序只供学习使用,未经作者许可,不得用于其它任何用途
**版权所有,盗版必究。
**Copyright(C) CheungMan
**All rights reserved
**欢迎访问我的blog:http://www.ednchina.com/blog/cheungman
**E-mail          : zhw-198@163.com
************************************************************************************************
**FileName      : 0ffset_0x500.c
**Target        : PIC18F458
**XTAL          : 4MHZ
**Autor         : ZhangWen
**Start Date    : 2008.04.24
**Modify Date   :
**Edition       : V1.0
**HardWare      :
**SofeWare      : MPLAB IDE v8.02 + PICC 18 v8.35
**Function      : 请在MPLAB IDE中,从菜单中选择Project->Build Options...->Project,
**    在PICC-18 Linker页标下的Specify offset for ROM(ROM代码偏移量)中输入偏移量0x500
**Note          : 注意,此程序偏移0x500地址
***********************************************************************************************/


#include


__CONFIG(1, HSPLL);     //配置HS,4倍频
__CONFIG(2, WDTDIS);    //禁止看门狗


//延时
void Delay(void)
{
 unsigned long i;
 for(i=0; i<150000; i++);
}


void main(void)
{
    TRISB = 0x00; //定义RB0-RB7为输出 
    PORTB = 0x00; //初始化为低电平
    while(1)
    {
 PORTB = 0xaa;
        Delay();
        PORTB = 0x55;
        Delay();
    } 
}


        3.使用UltraEdit分别打开000.hex和500.hex,然后对比一下两者,把500.hex中的部分代码复制并插入到000.hex的代码中,请看图1和图2所示,然后再另存为test.hex.至于为什么要这样操作或者怎样操作,请了解hex的格式先吧.


点击看大图


                                                     图1.选取500.hex上的数据


点击看大图


                                                   图2.拷贝到000.hex上去


        4.接着你可以把这个新生成的test.hex通过ICD2直接下载到芯片上去,你就可以看到0ffset_0x000.c程序中描述的,看到所有RB0-RB7闪烁10次后,接着就会进入0ffset_0x500.c程序中描述的,RB0-RB7间隔闪烁.如果在0ffset_0x500.c程序上再跳转到0x000地址上去的话,又运行0ffset_0x000.c程序了,是不是很有意思啊?不过我没增加这样的语句,你们自己加加看.


        5.在这里,我就用PROTEUS调试给大家看看吧,请看图3和图4.


51015fc0-59be-41bd-8b2b-bebb983de226.jpg


                                 图3.运行0ffset_0x000.c时的情况


0ee07d20-96a7-42bc-bb38-15e1bd38e4e2.jpg


                          图4.运行0ffset_0x500.c时的情况


        PS:在这里要注意的是0ffset_0x500.c,由于此程序已偏移到0x500地址上去,如果你编写含中断的程序的话,需要重定义中断向量.至于如何重定义,下次再写篇如何定义的博文吧.这里我就没有重定义中断向量了,为的是用最简单,最通俗的程序,让大家理解,明白.
    
        再PS:请严格按照程序中NOTE的指示进行设置.


源码:rar

文章评论2条评论)

登录后参与讨论

用户1832794 2015-4-29 20:00

xul是什么库?为什么会出错呢?

用户1409644 2010-12-31 15:00

嘻嘻,很神奇嘛。决定继续在您的文章中折腾。

用户152422 2008-6-22 22:52

您好,我是joylight,之前向您请教过bootloader的问题 强烈期待您重定义中断向量的博文,我现在中断向量的重定位搞不定啊。
相关推荐阅读
用户1177633 2008-07-09 23:35
PIC18F系列读写FLASH的函数
网上搜了一下,关于PIC18F系列读写FLASH的函数,有很多都是有错误的或者有BUG的,集中在表指针的操作上. 因此走了些弯路,现在发一个我自己写的读写FLASH的函数分享给大家,已测试过,支持绝大...
用户1177633 2008-06-04 23:39
Protel技巧之二:巧为元器件进行标注
        今天发现自己的博客中11篇博文,居然有5篇博客精华,质量很高啊,非常感谢EDNCHINA,非常开心,想起自己好久没有更新过BLOG了,想起以前设计原理图时候使用过的一个技巧,现发出来分...
用户1177633 2008-04-08 22:05
如何使用PIC C30中的外设库函数?
        刚开始学dsPIC33,发现MicroChip做的C30编译器还不错,里边有常用的外设库(Peripheral Libraries),写程序也不用查datasheet就可以很快配置好寄...
用户1177633 2008-04-02 21:47
Protel技巧之一:设计原理图模块化
         设计大系统的原理图的时候,通常元器件很多,而且连线错综复杂,很容易搞错,看起来也不舒服,如果大家设计的时候,把各个模块系统化,对不同功能的部分进行分类,然后用不同颜色的虚线框围起来,...
用户1177633 2007-09-14 17:50
真正的变形金刚
http://www.56.com/n_v165_/c17_/23_/18_/yuan8088_/zhajm_1184957140_349_/39000_/0_/15707484.swf简直是精品艺术...
我要评论
2
11
关闭 站长推荐上一条 /2 下一条