DP-51+开发工具上程序运行及BANK原理和实现方式
一个标准的8051器件能寻址64KB的代码地址空间。对于超过64KB的代码,单片机系统通常采用代码分页(CODE BANKING)的方式来扩展程序空间。本篇文章主要讲述8051器件中程序地址指针的运行原理和方式,并介绍了广州致远电子有限公司的DP-51+开发工具中程序的运行方式及如何利用代码分页来实现超过64KB代码空间的地址空间扩展。希望读者可以通过在DP-51+及其DP系列开发工具上的实验,理解8051系列单片机程序的运行原理,尤其是许多初级读者十分头疼的代码分页实现方式。
一、 8051程序执行方式及DP-51+程序的运行模式
程序执行方式是单片机的基本工作方式。所执行的程序可以放在单片机内部ROM,外部ROM或内部外部ROM同时运行。所有程序的开始指针都是从0X0000开始。8051有一个EA管脚可以选择程序是在单片机内部ROM开始运行还是在片外ROM开始运行。当EA为高电平时,芯片将从内部ROM开始执行程序,如果程序计数器超过了片内程序存储器的地址指针,芯片开始访问外部程序存储空间。当EA为低电平时,芯片将直接从外部程序存储空间的0X0000开始运行程序。对于超过64K的地址空间,单纯凭借单片机的P0,P2口已经不能完成这个任务,因此需要采用BANK(代码分页)技术扩充其地址空间。
在DP-51+开发工具,扩展了一块AT29C040A的512KB FLASH程序存储器。系统通过一个状态开关(RUN,MON,LOAD)来选择单片机执行方式,下面分别介绍这三种方式下程序的运行模式:
1. LOAD方式
LOAD方式是程序下载方式,它是通过配套的DPFLASH工具将HEX文件下载到片外FLASH中。其原理是利用单片机内部固化的LOAD程序实现其功能。LOAD程序一方面与DPFLASH进行串口通讯,接收DPFLASH 发过来的的指令和HEX文件数据,另一方面按照DPFLASH的指令和相应数据对片外FLASH程序存储器进行读写,擦除等操作,并将状态结果反馈给DPFLASH。因此,LOAD方式是单片机运行内部程序的过程。注意单片机内部的LOAD程序不可以擦写,否则将影响到开发板的正常运行。
2. MON方式
MON方式是开发板仿真调试方式。在这种方式下,首先需要利用DPFLASH将MON51监控程序下载到FLASH 片外程序存贮器的0X0000~0X3FFF地址空间中。MON方式采用的是单片机运行外部程序的方式。因此MON 方式开始时单片机首先运行MON51监控程序。MON51的功能一方面接收从Keil C51发过来的调试信息和相应数据,另一方面对用户程序进行断点设置、代码运行等调试动作,并将相应信息反馈给Keil C51,从而完成调试动作。
需要注意的是,MON51占用了FLASH中的0X0000~0X3FFF地址空间。因此,用户程序起始地址必须位于FLASH的0X4000地址空间以外的区域,否则将可能覆盖MON51程序。用户程序的中断向量也需要分配在0X4000空间以上,MON51监控程序将把中断信息映射到用户的中断程序中,从而实现用户中断程
序的运行。3. RUN方式
RUN方式就是单片机运行片外程序的过程。在这种方式下,单片机运行从0X0000开始的用户程序。因此,对于刚刚进行完MON方式的程序代码,请记住将中断向量分配到0X0000开始的空间中,否则将执行不了用户的中断程序。
正常使用情况下,用户运行的程序都在FLASH的0X0000~0XFFFF的地址空间中。如果没有相应的代码分页(CODE BANKING)设置,Keil C51将无法编辑超过64KB地址空间的程序。以下将详细的讲解分页的原理和在DP-51+中的实现过程。
二、 代码分页(CODE BANKING)的原理和实现
一个标准的8051器件能寻址64KB的代码空间。对于超过64KB的代码,单片机系统通常采用代码分页(CODE BANKING)的方式来扩展程序空间。代码分页的机理就是将地址空间分成小于或等于64KB的不同
的代码段,通过片选的方式实现程序在不同代码空间的跳转。Keil C51工具支持代码分页这个技术,它可以让你管理一个公共的区域和32个每个最大达64KB 的代码页,从而达到总共2MB 的代码切换空间。Keil C51支持的分页方式有三种。1)利用单片机I/O 口线。通常默认是P1,口线直接作为扩展的地址线
从而实现地址的扩展2)利用页面地址分配器(XDATA)空间实现分页。指定一个XDATA 端口字节,单片机通过对此存储器的命令输入实现对不同代码段的片选。如XDATA 地址为0XFFFF,字节偏移量为0,当向此地址写入0X0000时,数据存贮器将选中BANK0地址空间,写入0X0001将选中BANK1地址空间。扩展该字节中的剩余位,不能再用于其他目的。3) 用户自定义方式实现分页。相应结构图如下所示:
图1 利用I/O口线对代码分页
片外程序存储器
片外程序存储器
图2 利用片外数据存贮器实现代码分页
需要注意的是,每段代码空间中必须留出一段公用代码区域,此公共区域常常包括那些必须一直需要访问的进程和数据常量,如中断进程、中断和复位向量、字符串常量和块切换进程。因此,公用代码空间的起始位置通常为代码块的0X0000。Keil C51开发工具在编译的过程中,将把公用段程序(COMMON CODE )复制到每一个代码段的公用代码区域中。一般情况下,页切换需要大约50个机器周期和2字节的堆栈空间。
三、 DP-51+开发板的实现过程
DP-51+ 下载实验仪是由广州致远电子有限公司设计的DP系列下载实验仪之一,是一种功能强大的单片机应用技术学习调试开发工具。其内部扩展了512KB的FLASH程序存贮器和128KB的SRAM数据存贮器,采用分页方式进行程序代码寻址。
DP-51+采用XDATA方式实现代码空间的分页,相应页面地址分配器空间地址为0XF000。扩展512KB FLASH 被分成8个代码段,每段地址空间为0X0000~0XFFFF。页面地址分配器的地址扩展功能在实验仪中的XC9572芯片中实现。
1.Keil C51环境下的分页设置
在Keil C51环境下,新建一个工程文件,命名为bank_test。在菜单project中选择options for target “target1”选项,按图3进行项目配置c51中字符串函数
图3 Keil项目配置页面
在target选项中,选中code banking,并在bank中,选择8,即为8个代码空间,代码空间段地址选择0X0000~0XFFFF。
下面需要修改l51_bank.a51来确定代码页的数量,页面间跳转的方式。将keil\c51\lib\l51_bank.a51复制到项目目录下,并加入项目中,在l51_bank.a51中,修改如下选项:
?B_NBANKS EQU 8 ; 定义最大分页数
?B_MODE EQU 1 ; 0 为利用8051端口模式分页
; 1 为利用XDATA模式分页
; 4 为用户自定义分页模式
?B_XDATAPORT EQU 0F000H ; XDATA寄存器地址,DP-51+定义为0XF000 将修改后的l51_bank.a51编译文件后产生的目标代码与你的源代码目标代码连接。所使用的命令不再是L51,而是BL51。BL51是Keil提供的增强连接器,可进行多代码页面和BL51支持L51使用的命令,还有一些命令可以指定如何在代码页面中安排模块和段。
2.编译执行代码及在DP-51+上的测试
新建c_boot.c文件,作为公用代码段程序,文件中的main函数是分别调用不同分页区的程序,并将过程通过串口输出,程序代码如下:
/***********************************************************/
// 文件名:bank_test.c
// 版权: www.zlgmcu
// 日期: 04-8-2
// 功能: 8051单片机bank分页模式测试
/***********************************************************/
#include<reg52.h>
#include<stdio.h>
extern void func0();
extern void func1();
extern void func2();
extern void func3();
extern void func4();
extern void func5();
extern void func6();
extern void func7();
void (*p[8])() = { func0,func1,func2,func3,func4,func5,func6,func7 } ;
void main()
{
int i ;
// 设置波特率为2400,晶振11.0592
SCON = 0x50 ;
TMOD |= 0x20 ;
TH1 = 500 ;
TR1 = 1 ;
TI = 1 ;
for ( i = 0 ; i < 8 ; i++ )
{
printf("主模块调用bank%d\r\n" , i );
(*p[i])() ;
}
while(1) ;
}
新建c_bank0.c,c_bank1.c ,c_bank2.c, c_bank3.c, c_bank4.c, c_bank5.c, c_bank6.c, c_bank7.c 八个文件,文件中包含funx()函数,此函数的目的是将运行过程反馈到串口,从而方便的了解到此代码区间是否被调用。程序代码如下:
#include <stdio.h>
void funcx() // x为不同分页区号
{
printf("开始运行bankx\r\n");
}
下面,我们将这些文件指定到不同分区中。用右健点击树装列表中的c_boot.c,选中option for file “c_boot.c”, 在properties的code bank选项中,选择common项,如下图所示:
图4 Keil文件属性配置页面
此项表明c_boot.c将被编译到代码的公用代码段中,在所有分页代码的起始部分被复制。与此类似,我们将c_bank0.c, c_bank1.c, c_bank2.c, c_bank3.c, c_bank4.c, c_bank5.c, c_bank6.c, c_bank7.c,分别
指定到bank0, bank1, bank2, bank3, bank4, bank5, bank6, bank7中。编译bank_test项目,keil c编译器将生成从bank_test.h00到bank_test.h07等八个hex文件,将此八个文件按照指定的代码空间分别下载到不同的ROM空间段中,即可演示程序在不同代码段调用的情况。
DP-51+利用DPFLASH工具来将程序下载到片外FLASH程序存储器中。需要注意的是,Keil C51编译器生成的Hex文件地址范围为0X0000~0XFFFF,利用烧写器需要指定相应的偏移地址。但DPFLASH采用的是扩展Hex格式,它需要载入的hex文件指定绝对地址。因此需要修改Hex文件来手动设置偏移地址。我们打开除了bank_test.h00(偏移地址为0)的其他hex文件,在文件的起始位置,加入如下字样:
:020*********F9
其中,黑显示部分为需要调整的偏移量地址。如bank1设置为0001 ,bank6设置为0006。Hex文件可以用记事本等编辑软件打开和修改。关于hex文件格式,请参阅相关Intel Hex格式介绍。修改后的结果如图5所示:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论