51单片机资源扩展:从片内ROM跳转到片外ROM

发布者:时光如梦最新更新时间:2016-05-27 来源: eefocus关键字:51单片机  资源扩展  片内ROM  片外ROM 手机看文章 扫描二维码
随时随地手机看文章
    源于一年前想自己动手给51写个OS,编译选Large模式,调试时整个流程都跑的好好的,可是烧写到片上后得不到预期的效果,后来查书才知道51单片机片上只有4KRom,如果没有扩展片外Rom,当访问4K以外的程序空间,程序指针又会回到最开始执行。参考手册扩展片外Rom后,能访问达64K的程序空间。网上能搜索到的扩展方式都是将EA引脚接地,让MCU上电后从外部ROM开始执行。但查看芯片手册,明明说EA为高时,程序从片内ROM执行,当执行到0x1000以上地址时(标准51单片机),会跳转到片外ROM执行。按网上的做法,为了扩展个片外ROM,片内的基本ROM都不用了,有点浪费了,于是开始找资料如何从片内跳转到片外执行。

   射人先射马,发帖先上图,仿真图如下:

51单片机资源扩展:从片内ROM跳转到片外ROM

此处EA脚没有接地。如果想简单粗暴的加电时从片外ROM执行,EA引脚接地,双击U2(27C64)Image File选Hex然后就可以了,这不是本文的重点,略过,后面可能会写到。

跳转,最简单的方式用LJMP,当然也可以用把跳转地址压入栈,然后ret过去,不过这种方式我没尝试成功。

考虑到汇编写代码太苦逼,写规模大一点的代码还得靠C,因此程序的效果是:main函数在片内执行,流水灯代码存放在片外Rom,main函数跳转到流水灯中执行。

因为是一种尝试,所以从写汇编代码开始(加载地址容易控制:ORG指定即可)

1)用汇编代码跳转:

AT89C51中的代码:

ORG 0000H
    LJMP 1000H
END

#####################

27C64中代码:

ORG  1000H
STAR:
        MOV  A,#0AAH
    MOV  P1,A
    MOV A,#55H
    MOV  P1,A
        SJMP STAR
END

程序运行起来后,PC寄存器指向0x0000处的LJMP 0x1000,然后跳到27C64处执行。起初,在27C64 0x0000处搜索编码,没找到,查阅手册后知,当PC超过0FFFH时,会转向片外程序存储空间1000H-FFFFH执行程序。

51单片机资源扩展:从片内ROM跳转到片外ROM

[27C64处的内容]

2)用C代码跳转:
#include
int main()
{
    int i=0;
    i++;

/*

执行一些初始化逻辑,或者接受交互内容,按不同的输入,跳转到片外ROM

*/

#pragma asm
 LJMP 0x1000
#pragma endasm    
while(1);
}

C代码中嵌入汇编,做跳转。

这个连接中有相关的设置 http://bbs.ednchina.com/BLOG_ARTICLE_1721.HTM 如果不做设置,连接时会有警告找不到C_STARTUP,也不会运行到代码中。

调试运行,由于KEIL C加了启动代码,在protues仿真时有一长段麻烦的初始化堆栈的过程,因为没有源码,连设置断点都不行,只能按着F11傻等着。最终当然也是能跳转到片外ROM执行的。

3)片外ROM存放由KEIL C编写的HEX文件

这个摸索了很久才摸索出来!代码如下:

#include

int main()
{
    while(1)
    {
        P1 = 0x33;
        P1 = 0xcc;
    }
}

首先,由于KEIL C创建的新工程会添加启动代码(startup.a51),这个前面说过用来初始化C语言运行的堆栈。因为我的程序是从片内ROM跳转过来运行的,至少已经被初始化了一次,再初始化一次,原本保留的变量全没了,因此在创建工程的时候,跳过添加startup.a51这个文件。带来的不便是:程序没有C环境,想要在调试是不可能了。

hex文件是生成了,加载,但是从片内ROM跳转过来后,P1口的内容不是0x33/0xCC而是上一次运行时的0x55/0xAA,why?代码写错了?

查看27C64的内存印象:

0x0000H的内容是:

51单片机资源扩展:从片内ROM跳转到片外ROM

75 90 33和75 90 CC是往P1端口写入0x33/0xCC---就是现在的代码

再查看0x1000H的内容:

51单片机资源扩展:从片内ROM跳转到片外ROM

74 AA对应MOV A,#0AAH,F5 90 对应MOV 90,A,明显是上次仿真时的结果!

好吧,现在得想办法把代码加载到0x1000的位置,ORG是用不上了,得用其他办法。

在我的另一篇文章 中提到,INTEL HEX文件格式中每个规则开始处都有地址,那好先看看这段代码的地址:

:08000F007590337590CC80F868
:03000000020003F8
:0C000300787FE4F6D8FD75810702000F3D
:00000001FF

080000F007 08是这行的长度8字节,后面的0000是这行加载位置,从0x0000开始。shit,难怪加载补上。先手动修改地址,修改玩以后,protues提示HEX校验码不对,仿真失败。无奈,只能想其他办法了。加载地址一般是由连接器在连接阶段确定的(<程序员的自我修养>一书中有提到),既然这样,看看keil c在链接时有没有什么参数可以设置:

51单片机资源扩展:从片内ROM跳转到片外ROM

BL51是KEIL C的连接器,Code这个位置好像是,那就试试填入0x1000,然后再编译连接:

:08100C007590337590CC80F85B
:03000000021000EB
:0C100000787FE4F6D8FD75810702100C23
:00000001FF

这次生成的HEX文件,链接地址部分已经被改为0x100C。再仿真一次,不过这次仿真前要把片内ROM的跳转地址改为LJMP 0x1003,要不然指不准执行了非法指令。

 

27C64 0x100C处的内容75 90 33对应汇编语句 MOV 90,#33H 75 90 CC对应汇编语句MOV 90,#0CCH这正是c代码的内容,而且P1口的内容也是CC。

至此,从片内ROM跳转到片外ROM结束。另外估计ISP烧写器可能也是类似的工作原理

关键字:51单片机  资源扩展  片内ROM  片外ROM 引用地址:51单片机资源扩展:从片内ROM跳转到片外ROM

上一篇:与51单片机扩展有关的知识点
下一篇:51单片机指令详解

推荐阅读最新更新时间:2024-03-16 14:55

使用51单片机点亮我们的点阵灯
通过前面我们都知道点亮我们的不管是点阵,数码管,还是LED灯,不仅要熟悉我们的代码还要会看我们的原理图和真值表,所以我们如果真的要写代码倒是其次的,首先我们得学会看我们的原理图和真值表,但是认识那个我们可以在网上找教程的,所以啊我这里就不去重诉别人的话了。那么我们今天要讨论什么问题勒!?我们今天讲一下点阵吧,点阵说实话对于单片机来说虽然并不是最重要的,但是点阵却是我们单片机中花样最多的之一。可能说到这么有人会说了,学了单片机我们有什么用呢,那么我们可以留意一下我们身边的一些物品,比如我们常在街上可以看见一些商店利用那些LED灯做出的花样,什么闪烁啊,各种图形变化啊,其实和我们的点阵原理都很像,不过他们那些控制的位更多,而我们51
[单片机]
基于51单片机的串口中断发送数据帧
很少看到有资料写如何以中断的方式发送一帧数据,如果以等待的发送数据帧,对高速运行的单片机来说是很浪费时间的,下面就介绍一种使用中断方式发送数据帧,操作平台采用51 mcu 首先定义一个数据帧的结构体,该结构体可以做为一个全局变量,所有的发送都要经过这个结构体: //结构体 struct { char busy_falg;//忙标志,若在发送数据时置位1,即在开始发送置位1,发送结束置位0 int index;//索引,指向需要发送数组的位置 int length;//整个数据帧的长度 char *buf;//指向需要发送的数据帧,建议为全局变量,否则一旦开始发送,必须等到发送结束,即判断busy_falg为0
[单片机]
基于<font color='red'>51单片机</font>的串口中断发送数据帧
基于51单片机的智能营养秤系统设计与实现
一、项目背景 随着人们生活水平和健康意识的提高,越来越多的人开始注重自己的饮食健康。在此背景下,智能营养秤系统应运而生,成为了一种非常实用的工具。本项目基于51单片机设计和实现一种智能营养秤系统,通过该系统可准确地测量食物的重量并计算其热量、蛋白质、脂肪、碳水化合物等营养成分含量。 当前系统采用了STC89C52单片机作为主控芯片,预置了多种食材的营养成分数据。用户只需要使用矩阵键盘输入食材编号,将需要称重的食材放置在重力传感器上进行依次称重,系统就可以自动计算出所有食材的各类营养含量总值,并通过液晶屏显示出来。同时,系统根据预设的营养指标,对不达标或超标的食材进行对应的声光提示,提醒用户注意饮食健康。 当前系统还配备了无
[单片机]
基于<font color='red'>51单片机</font>的智能营养秤系统设计与实现
单片机学习笔记-51单片机实现独立按键的短按及长按触发
一、使用proteus绘制简单的电路图,用于后续仿真 二、编写程序 /******************************************************************************************************************** ---- @Project: Independent-KEY ---- @File: main.c ---- @Edit: ZHQ ---- @Version: V1.0 ---- @CreationTime: 20200506 ---- @ModifiedTime: 20200506 ---- @Description:
[单片机]
单片机学习笔记-<font color='red'>51单片机</font>实现独立按键的短按及长按触发
MCS51单片机的检索查找程序
;单字节顺序查找程序 ;入口 :R0,R1,A,R7 ;占用资源:B ;堆栈需求:2字节 ;出口 :R0,R1,A FINDB1 :MOV B,A MOV DPL,R1 MOV DPH,R0 FINDB11 :MOVX A,@DPTR CJNE A,B,FINDB12 MOV R1,DPL MOV R0,DPH CLR A RET FINDB12 :INC DPTR DJNZ R7,FINDB11 MOV A,#0FFH RET ;单字节顺序查找程序 ;入口 :R0,R1,A,R6,R7 ;占用资源
[单片机]
51单片机——存储器(二)
3.RAM(数据存储器) RAM(数据存储器)存放数据(常量或变量)或运算的结果,相当于计算机的内存; 3.1 片内外RAM(数据存储器) 8051单片机内部有256字节的数据存储器,如果内部数据存储器不够用,可以外接数据存储器。8051单片机最大可以外接容量为64KB的数据存储器(RAM),它与片内256字节数据存储器分开编址,如下图所示。 当8051单片机连接片外RAM时,片内RAM的00H~FFH存储单元地址与片外RAM的0000H~00FFH存储单元地址相同,为了区分两者,在用汇编语言编程时,读写片外RAM时要用“MOVX”指令(读写片内RAM时要用“MOV”指令),在用C语言编程时,读写RAM时须先声明数据类型(
[单片机]
51单片机TMOD及定时器配置
一,TMOD的配置 1.定时模式GATE=0 TMOD=0X01(T0工作方式1) TMOD=0X02(T0工作方式2) TMOD=0X10 (T1工作方式 1) TMOD=0X20 (T1工作方式2) 2.计数模式GATE=0
[单片机]
<font color='red'>51单片机</font>TMOD及定时器配置
51单片机超声波四通道端口扫描方式测距
超声波四通道测距:超声波测距实现分为三大块: 其一是12864带字库的液晶驱动程序: 代码如下: /////////////////12864驱动程序/////////////////////////// //1写数据 void WriteDataLCD(unsigned char WDLCD) { ReadStatusLCD(); //检测忙 LCD_RS = 1; LCD_RW = 0; LCD_Data = WDLCD; LCD_E = 1; LCD_E = 1; LCD_E = 1; LCD_E = 0; } //2写指令 void WriteCommandLCD(unsigned ch
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
热门活动
换一批
更多
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

更多精选电路图
换一换 更多 相关热搜器件
更多每日新闻
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved