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

发布者:EtherealGaze最新更新时间:2018-11-19 来源: eefocus关键字:51单片机  内存扩展  片内ROM  片外ROM 手机看文章 扫描二维码
随时随地手机看文章

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


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


2.png


此处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执行程序。


3.png


[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的内容是:

4.png


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


再查看0x1000H的内容:

5.png


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校验码不对,仿真失败。无奈,只能想其他办法了。加载地址一般是由连接器在连接阶段确定的(


1.png


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


:08100C007590337590CC80F85B


:03000000021000EB


:0C100000787FE4F6D8FD75810702100C23


:00000001FF


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


6.png


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单片机扩展片外RAM
下一篇:51单片机stack堆栈

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

51单片机串口通讯uart笔记
我需要设计一个夜晚蓝牙开关灯设计,采用的蓝牙芯片为JDY-30,刚开始不知道具体型号,后来连接蓝牙之后发现是JDY-30,查手册发现采用的是uart通讯,所以就进行了重新的温习。下面是uart串口通讯的笔记 使用串口通讯需要对相关寄存器进行配置 我这里需要将串口通讯工作在中断方式,那我肯定要用到中断有关的寄存器IE 还需要设置定时/计数器T1,可能有人会有疑问,为什么要用定时器呢,波特率是每秒传输二进制代码的位数,单位是 位/秒 即bps 而定时器是用来确定发送和发送执行每一位的时间的,所以需要对TCON与TMOD寄存器进行配置 使用串行通讯的话还需要确定串行通信的工作方式与控制功能,这就需要对SCON与PCON寄存器
[单片机]
<font color='red'>51单片机</font>串口通讯uart笔记
什么是51单片机最小系统
1.什么是51单片机 51 内核单片机是 指兼容Intel 的8051指令系统的单片机统称;从诞生到现在的几十年时间,已成为一款经过市场考验、成熟的芯片产品。目前国内也众多51单片机厂家,且还有众多带51内核,用于各种不同场景的专用类单片机。 51单片机内部框架: 以下以STC89C52单片机为例,其内部总体结构其基本特性如下: 8位CPU、4-8k 字节 ROM、128 字节 RAM、21 个特殊功能寄存器32根I/0线、可寻址的 64 字节外部数据、程序存贮空间、2个 16 位定时器计数器中断结构:具有二个优先级、五个中断源、一个全双工串行口、位寻址(即可对寄存器进行位操作)功能,能按位进行逻辑运算的位处理器。 除 1
[单片机]
什么是<font color='red'>51单片机</font>最小系统
51单片机-时钟芯片DS1302
在许多电子设备中,通常会进行一些与时间有关的控制,如果用系统的定时器来设计时钟的话,偶然的掉电或晶振的误差都会造成时间的错乱,更糟糕的是,若完全用程序设计时钟还会占用大量的系统资源,从而严重影响系统的其他功能。为此,很多芯片制造公司都设计出了各种各样的实时时钟芯片。 常见的时钟芯片有两种。 一种是体积非常小的表贴是元件,通常用在高端小型手持式仪器或设备中。这种芯片在使用时需要外接备份电池和外部晶振,电池用来保持主系统在意外时为时钟芯片供电,外部晶振用来给时钟芯片所必须的震荡来源。 另一种体积相对较大,一般为直插式,它的内部有可充电锂电池,同时内部还集成了32.768KHZ的标准晶振。 DS18B20是由
[单片机]
<font color='red'>51单片机</font>-时钟芯片DS1302
PROTUS仿真51单片机测频程序
频率计: LCD1602显示 在不增加外部计数硬件的情况下,本试验软件可测最高频率达到460KHz 工作原理: 1S 钟内对输入脉冲所计数的次数则为频率值。 16位二进制加法计数器的最大计数值为 65535。 设置定时器 0 工作在定时方式1,定时1S。 设置定时器 1 工作在计数方式1,对输入脉冲进行计数,溢出产生中断。 将定时器 1中断定义为优先。在中断处理程序里对中断次数进行计数。1S到后,将中断次数和计数器里的计数值取出进行综合数据处理,处理后的数据送LCD1602显示。 /******************** 程序名:频率计 功能:双通道频率测量,未加分频的情况下最高测频值65KHZ 网站:51单片机教程网 h
[单片机]
PROTUS仿真<font color='red'>51单片机</font>测频程序
8051单片机引脚图与引脚功能简介
首先我们来连接一下单片机的引脚图,如果,具体功能在下面都有介绍。 单片机的40个引脚大致可分为4类:电源、时钟、控制和I/O引脚。 ⒈ 电源: ⑴ VCC - 芯片电源,接+5V; ⑵ VSS - 接地端; ⒉ 时钟:XTAL1、XTAL2 - 晶体振荡电路反相输入端和输出端。 ⒊ 控制线:控制线共有4根, ⑴ ALE/PROG:地址锁存允许/片内EPROM 编程 脉冲 ① ALE功能:用来锁存P0口送出的低8位地址 ② PROG功能:片内有EPROM的芯片,在EPROM编程期间,此引脚输入编程脉冲。 ⑵ PSEN:外ROM读选通信号。 ⑶ RST/VPD:复位/备用电源。 ① RST(Reset)功能:
[单片机]
80<font color='red'>51单片机</font>引脚图与引脚功能简介
超声波测距51单片机12864液晶显示
超声波测距的模块,51单片机接上12864液晶,HC-SR04超声波模块,就可以了,具体程序没怎么看,超声波模块的硬件也不晓得,今天先贴个图,贴个程序吧(程序是淘宝买的模块附赠的)。 超声波测距51单片机12864液晶显示源程序: #include #include //引脚定义 sbit RX = P1 ^ 1; sbit TX = P1 ^ 2; sbit CS = P3 ^ 3; //片选 高电平有效 单片LCD使用时可固定高电平 sbit SID = P3 ^ 4; //数据 sbit SCLK = P3 ^ 5; //时钟 //Function
[单片机]
超声波测距<font color='red'>51单片机</font>12864液晶显示
51单片机红外解码过程时序图
红外解码过程: Ray_Read_bit_timer 103us自增变量 Ray_Read_bit_count 保存位置编号 Ray_bit_timer_Buffer 33字节数组 Ray_Flag 保存标志 Ray_Read_ok 允许分析长短 (1)、按下遥控器,单片机就会有下降沿中断。启动定时器TR0=1; (2)、定时器从0开始增加到255溢出,需要时间103us。 (3)、产生定时器中断。中断里面变量Ray_Read_bit_timer增加1。 (4)、在下降沿的中断服务,判断这个时候Ray_Read_bit_timer * 103us,是不是大于11.5ms 。 (5)、如果大于11.5,肯定大于9
[单片机]
<font color='red'>51单片机</font>红外解码过程时序图
基于51单片机数码管的代码例子
#include #include #define uchar unsigned char #define uint unsigned int sbit dula=P2^6; sbit wela=P2^7; uchar code table ={ //编码表 code为把程序放入ROM区 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71, 0x76,0x79,0x38,0x3f,0}; uchar temp,t0,t1,bai,shi,ge,flag,flag1; //flag flag1 为2个标志位 uint
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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