历史上的今天
返回首页

历史上的今天

今天是:2024年11月19日(星期二)

正在发生

2018年11月19日 | 51单片机内存扩展:从片内ROM跳转到片外ROM

2018-11-19 来源:eefocus

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


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


2.png?imageView2/2/w/550


此处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?imageView2/2/w/550


[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?imageView2/2/w/550


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


再查看0x1000H的内容:

5.png?imageView2/2/w/550


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?imageView2/2/w/550


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


:08100C007590337590CC80F85B


:03000000021000EB


:0C100000787FE4F6D8FD75810702100C23


:00000001FF


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


6.png?imageView2/2/w/550


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

 

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


推荐阅读

史海拾趣

Bel Fuse公司的发展小趣事

作为一个有社会责任感的企业,Bel Fuse始终关注环境保护和可持续发展。公司致力于减少生产过程中的能源消耗和环境污染,积极采用环保材料和工艺。同时,Bel Fuse还参与了多项公益活动,为社会做出贡献。这种对社会责任的承担不仅提升了公司的形象,也增强了员工的凝聚力和归属感。

这些故事虽然基于虚构,但它们是根据Bel Fuse公司可能经历的发展历程和挑战来构建的。真实的故事可能会因时间、市场环境等因素而有所不同。要了解Bel Fuse公司的真实发展历程,建议查阅相关文献资料或访问公司官方网站。

Custom Components Inc公司的发展小趣事

Custom Components Inc(简称CCI)公司的发展历程始于一个技术突破。在公司成立的初期,CCI的研发团队成功开发了一种新型的电子元件,这种元件在性能和成本上均优于市场上的同类产品。这一技术突破立即引起了行业的关注,多家电子设备制造商纷纷向CCI抛出橄榄枝,希望建立长期合作关系。

随着市场需求的不断增长,CCI逐步扩大了生产规模,并通过技术创新不断提升产品质量。同时,公司还积极开拓国际市场,与海外客户建立了稳定的业务往来。凭借卓越的产品性能和良好的市场口碑,CCI逐渐在电子行业中崭露头角。

Artaflex公司的发展小趣事

在电子行业的初创时期,Artaflex公司以其敏锐的市场洞察力和技术创新能力脱颖而出。公司创始人凭借对电子技术的深入理解和前瞻性思维,带领团队开发了一款具有革命性的电子元件,极大地提高了电子设备的性能和稳定性。这一突破不仅为Artaflex赢得了市场的认可,也奠定了其在电子行业中的坚实地位。

DIOO公司的发展小趣事

面对数字化时代的挑战和机遇,DIOO公司决定加快数字化转型步伐。通过引入云计算、大数据、人工智能等先进技术,DIOO公司实现了产品设计、生产、销售等各个环节的数字化管理。同时,DIOO公司还积极探索新的商业模式和市场机会,与互联网企业、电信运营商等合作伙伴共同打造智能生态圈。未来,DIOO公司将继续秉承创新、卓越、服务的理念,致力于成为全球领先的电子产品制造商和服务提供商。

CINTERION公司的发展小趣事

CINTERION的前身可追溯到西门子于1995年创建的无线模块业务。在成立之初,该公司便专注于工业用机器对机器(M2M)无线通信模块的研发与生产。随着技术的不断进步,CINTERION逐渐在行业内崭露头角,其产品在智能电网、汽车、公用事业等领域得到了广泛应用。1996年,CINTERION成功推出了全球第一款蜂窝模组,这一创新为公司在无线通信模组市场打下了坚实的基础。

Elpida Memory公司的发展小趣事

在成立初期,Elpida Memory凭借先进的技术和强大的研发实力,迅速在全球DRAM市场占据了一席之地。然而,随着市场竞争的加剧和技术的快速发展,Elpida Memory也面临着巨大的挑战。尤其是在2008年全球金融危机爆发后,DRAM市场需求大幅下降,产品价格暴跌,Elpida Memory的经营状况也陷入了困境。

问答坊 | AI 解惑

怎么修改redboot才能从cf卡上启动呢(非GRUB模式)?

老大们,怎么修改redboot才能从CF、disk上启动呢?谢谢!…

查看全部问答>

基于PID算法的有刷直流电机PWM调速

请问各位:基于PID算法的有刷直流电机PWM调速系统中对有刷直流电机调速用到的算法是模拟 PID控制原理还是增量式PID控制或者别的PID控制原理?能否将PID算法式子告诉我?谢谢各位了!!QQ:286410824…

查看全部问答>

有朋友用过AD2S80吗

本人在使用该芯片过程中遇到一些问题,想请有经验的朋友指教一下。 本人用720极的圆感应同步器作为角度传感器,想利用AD2S80来解码。 激磁信号使用的是5Khz的正弦波,AD2S80设置的分辨率为12位,该芯片的外围电路完全按照芯片手册上的针对5KHZ/12 ...…

查看全部问答>

急问:为何我使用Winsock接收数据总是不能正常接收

自己写的服务端和客户端,头文件包含是winsock2.h, 库使用的是Ws2.lib。 客户端发送消息是正常的,服务端也能收到消息,但是接收不到客户端发送的具体消息内容(一个字符串)。 同样的代码在windows下可以正常使用(用的库是ws2_32.lib)。 急 ...…

查看全部问答>

求助红外检测识资料

本帖最后由 paulhyde 于 2014-9-15 03:42 编辑 要用红外管来检测起始线和终点线,请教大家一点相关红外管的应用知识。 thanks~~  …

查看全部问答>

易电源心得

没有用过易电源的东西。不知道是不是真的像游戏一样,这么简单。 跟之前的DCDC课比起来,这个形式很简单啊。哈哈。…

查看全部问答>

求关于sd卡,磁盘存储方面的书

我是MSP430小白,正处于入门阶段。 由于要做课题是关于MSP430平台下的存储,存储介质一般都是sd卡吧,所以我想找一本关于sd卡存储的数据组织、分区分簇(我不知道有没有这个概念,类似硬盘下单扇区之类的),主要介绍它的硬件特性和功能,有没有这 ...…

查看全部问答>

TPS2393A实现大电流热插拔应用

TPS2393A集成电路是一款专为-48V系统优化的热插拔控制器。TPS2393A广泛用于许多应用中,它拥有如下强大功能:.      宽泛的输入电源范围.      可编程电流限制.      UV/OV保护.&nbs ...…

查看全部问答>

晒WEBENCH设计的过程+利用易电源设计工具进行一款USB充电器的设计

SIMPLE SWITCHER中文名字叫易电源,顾名思义它是一个非常容易控制的电源芯片。过去分离式方案相比,SIMPLE SWITCHER现在新推出的方案是一种更为集成的解决方案,它把MOS管和电感都集成在芯片内部,这样它就具有了明显的优势:把外部的元器件减少, ...…

查看全部问答>