"); //-->
1 基本原理
类似于其他引导装载升级程序的方法,在系统中必须始终存在一段用于程序装载的代码(bootloader),该代码在启动时被运行。其基本功能是根据外部条件来判断是运行现有版本的程序还是从主机下载新程序。8051具有选择执行片内或者片外程序的功能,而对片内E2PROM编程过程相对比较复杂,因此这里将程序引导装载代码烧结在内部程序空间中,并不准备改变;而将系统应用程序存放在片外一编程相对简单和独立的E2PROM内,是随时可以更新的部分。通过外围电路的支持,单片机上电复位时首先执行片内的装载程序,如图1所示。该装载代码将应用程序从E2PROM拷贝到外部存储器(RAM)中以备执行,同时还通过通信接口监系统程序装载执行过程听主机命令。当收到主机更新程序的请求后,立即接收新的应用程序内容,并在最终确认后写入扩展E2PROM内。当片内程序执行完毕后,系统软件复位并执行片外RAM中的程序,而RAM的内容正是由装载所决定的。如果CPU再次复位,那么将重复上述装载执行过程。
图1
值得注意的是,在对外部程序存储器访问时,8051单片机只提供读指令(MOVC)而并不具备写指令。但是从单片机对外部程序和数据存储器的访问时序上看具有一致性,不同的是读代码使用PSEN信号而读数据使用RD信号。同时,单片机的PSEN﹑RD和WR信号不会同时有效,因此将PSEN和RD逻辑合并后,可以使程序和数据合二为一读写成为可能。这样同一个地址单元RD、WR(MOVX)和PSEN(MOVC)均可以进行访问。单片机可以使用MOVX写指令来更改相当于其外部程序空间中的内容。特别要注意的是,当程序和数据共存于一片RAM中时,必须使用编译器提供的相关连接命令使数据区偏离代码可能占用的区域,否则会导致系统混乱。
2 硬件电路
硬件参考电路如图2所示。系统加电后,由于C3两端电压不能瞬变,使D触发器置1端保持一短暂低电平,强制将单片机EA信号置高。在U4看门狗上电复位信号撤销后,单片机开始从内部程序空间0地址起执行。内部装载程序先通过P1.4、P1.5模拟I2C总线时序从E2PROMU3中将应用程序代码拷贝到片外RAM从0地址起的空间中。如果到代码拷贝结束串行口一直没有收到预定的程序下载命令,则通过软件置低P1.6口触发看门狗芯片对单片机复位,在复位脉冲的上升沿,D触发器锁存其输出的信号使EA电平翻转为低电平。待复位信号撤销后,单片机开始执行位于外部程序空间的系统应用程序代码。在执行外部程序时,如果看门狗再次复位,EA将会恢复高电平并重新执行内部装载程序。
图2 引导装载电路
当上位机欲更改终端设备程序时,可通过串口向其发送特定的握手字符串,无论片外程序还是片内程序最好都能识别该字符串并且复位单片机(如果是正在运行外部程序)执行内部装载程序。装载程序就绪后向上位机发送确认回应,并接收来自上位机的程序代码。单片机通过置低P1.3允许E2PROM写操作,将新的内容写入E2PROM中,完成程序的更新。
3 软件设计
装载程序主要有两个功能,其一是要将E2PROM的内容拷贝到片外RAM中;其二是要响应上位机的更新程序命令并接收代码内容更新E2PROM。
#define uchar unsigned char
#define uintunsigned int
sbit WDI=P1^7;
sbit RESET=P1^6;/*声明外部I2C读写函数*/
extern void I2c_wr(uchar addh,uchar addl,uchar buf[],uchar num,bit wr);
void main(void) {
uchar data addh,addl;
uchar data buf[16];
uchar j;
uint I=0;
XBYTE[0x1fff]=0;/*清除程序拷贝好标志*/
WDI=~WDI; /*喂狗*/
system_init(); /*初始化*/
for(addh=0;addh<0x10;addh++) {
for(addl=0;addl<0xf0;addl+=16) {/*读入E2PROM地址addh:addl16字节内容到buf*/
I2c_wr(addh,addl,buf,16,1);
for(j=0;j<16;j++)/*将代码写入外部绝对地址*/
XBYTE[I++]=buf[j];
}
I2c_wr(addh,0xf0,buf,16,1);
for(j=0;j<16;j++)
XBYTE[I++]=buf[j];
WDI=~WDI;
}
if(shake_hand==1) {/*shake_hand由串口中断收到握手命令后置1*/
rcv_data(); /*该函数负责从上位机获取程序*/
}
XBYTE[0x1fff]=0xaa;/*置程序拷贝好标志*/
RESET=0;/*复位单片机并执行外部RAM内的程序*/
while(1);
}
为了确保程序在装载完全正确后才开始执行,装载程序使用了外部RAM 0x1fff地址内容作为装载成功的标志。那么相应的应用程序应判断此标志后再执行。
调试结束的装载程序烧结在单片机中,而实际的系统应用程序则存储于外部E2PROM内。应用中,将单片机直接焊装在电路板上,而编程者只需通过串口或者其他形式的通信链路甚至无线的方式来更改升级目标应用程序。
4 几点讨论
在实际应用中,最好使用严格的校验及复查方法来确保程序拷贝无误。 另外, 在从上位机下载程序时应该制定一个可靠的通信协议, 从而保证获取的程序完全正确。 单片机在接收到上位机的代码数据时,不要急于写入外部E2PROM,而应先全部放在外部RAM区内,待代码获取完毕并且通过校验检查后再把RAM的内容一次性写入E2PROM。这样防止在获取程序的时候通信异常中断而E2PROM内将没有一个可以执行的程序。
从原理上看,如果片外RAM是非易失的,就可以不再使用E2PROM。但是这样系统成本变高且可靠性降低,因为当单片机程序跑飞时很容易产生MOVX指令而改变RAM区的内容,造成程序永久性不可恢复。而在程序跑飞的情况下,很难产生符合外部E2PROM接口的I2C写时序,同时E2PROM还有写保护功能。
虽然上述方法能使8051单片机系统具有远程升级代码的能力,但是程序装载过程将使系统的启动时间延长数秒,在对启动时间要求较短的场合不能应用本文中介绍的方法。
参考文献
1 何立民.MCS51系列单片机应用系统设计.北京:北京航空航天大学出版社,1990
2 Atmel公司器件手册,2003
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。