登录
|
注册会员
开启辅助访问
设为首页
收藏本站
扫一扫关注官方微信
论坛
BBS
M币充值
M currency prepaid phone
M币获取
附件中心
搜索
search
全新论坛MCU智学网上线,欢迎访问新论坛!稀缺资源、技术干货、参考设计、原厂资料尽在MCU智学网
MCU资讯论坛
»
论坛
›
单片机论坛
›
51单片机论坛
›
C8051 F12X中多bank的分区跳转处理
更新自动建库工具PCB Footprint Expert 2024.04 Pro / Library Expert 破解版
C8051 F12X中多bank的分区跳转处理
[复制链接]
4383
1
ad***
管理员
发表于 2012-9-3 02:26:29
|
查看全部
|
阅读模式
本文包含原理图、PCB、源代码、封装库、中英文PDF等资源
您需要
登录
才可以下载或查看,没有帐号?
注册会员
x
在8051核
单片机
庞大的家族中,C8051F系列作为其中的后起之秀,是目前功能最全、速度最快的8051衍
生单片机之一,正得到越来越广泛的应用。它集成了嵌入式系统的许多先进技术,有丰富的模拟和数字
资源。是一个完全意义上的SoC产品。
C805IFl2X作为该系列中的高端部分,具有最快100MIPS的峰值速度,集成了最多的片上资源。其128
KB的片上Flash和8 KB的片上RAM足以满足绝大多数应用的需求。使用C8051F12X,只需外加为数不多的驱
动和接口,就可构成较大型的完整系统。只是其中128 KB的Flash存储器不可避免地要处理bank分区问题
。
幸运的是Keil
C51
开发环境对C8051F系列有良好的支持,包括一般的跨bank分区的程序跳转和调用
。作为数据存储器使用时,Flash的分区读写完全是编程者要考虑的事情,与开发环境无关。本文只针对
特殊的强制转移和μC/OS—II在多bank分区中的移植问题展开讨论。
1 C8051F12X在Keil C51中的多bank分区转移机制
Keil C51的连接定位器支持分组连接,允许生成代码长度大于64 KB的8051目标程序_1_.一般的8051
系统只提供16根地址线,需要附加地址线来实现代码分组切换,而编译器产生bank切换代码时受到配置
文件L51_BANK.A51的支持,所以用户必须根据自己的硬件结构来修改这个配置文件。
C8051F12X系列不用考虑硬件部分,也不存在地址线的扩展问题,因为128 KB的4个bank区全部都在
CPU内部,所以作为常规跨bank的跳转和调用,不需要处理1.5l_BANK.A51配置文件。但在特殊情况下就
必须考虑该问题,否则程序将无法工作。下面以C8051F120为例先讨论代码的透明分组切换过程。
C805IFl20在Keil C51的项目配置中被划分为4个bank,每个32 KB.公共bank地址从0~0x7fff,其余
bank从0x8000h~0xffff.在对应的配置文件L51_BANK.A51中,涉及到特殊功能寄存器PSBANK(SFR地址:
0B1H)、SWITCHn宏、B_BANKn、B_SWITCHn分组信息保存和切换代码,以及B_CURENTBANK变量。
PSBANK为C8051F120内的特殊功能寄存器,128KB Flash的分bank访问就是通过它来实现的。要想转
移到新的bank中去,必须赋予PSBANK正确的值,然后再转向bank区内地址即可。
SWITCHn宏共有4个,分别是SwITCH0、SWlTCH1、SWITCH2和SWITCH3,对应切换到4个bank中。其中
SWITCH0对应的语句为:
MOV PSBANK.#00h ;把00h用1Ih、22h和33h替换,
;就是其他三个宏
它将插入到B_SWITCHn代码中,用来切换新的bank和恢复到原来的bank。
所有4组B_BANKn和B_SWlTCHn代码也都是用宏实现的,对应4个bank处理。它们汇集在BANK SWITCH代码
段中,整个bank切换及恢复机制非常巧妙,可以实现任意bank之间函数的相互调用及嵌套。下面以bank3
区中的main函数调用bankl区的Delay_noOS()延时函数为例说明该机制。
void main(void){
MCUInit(); //初始化CPU
Delay_n00s(10); //延时lO ms
Lcmlnition();
:
:
[NextPage]
bank3中被调用的函数Delay_noOS(10)对应的汇编语句为:
LCALL C:5049
公共段(即Common段,对应bank0)中C:5049处的
汇编语句如下:
MOV dptr,#Delay_noOS
AJMP B_BANKl
这里的B_BANKl就是宏?B_BANK&N中N为1的例程。现在进入问题的核心:全部的跨bank区程序切换及恢复
过程依靠公共段中?BANK?SWITCH代码段里的以下汇编代码实现,对应的N为0、1、2和3。BANK?SWlTCH
SEGMENT CODE PAGE
;
B_BANK&N:
PUSH B_CURRENTBANK (1)
MOV A,#HIGH BANK SWITCH (2)
PUSH ACC (3)
PUSH DPL (4)
PUSH DPH (5)
B_SWITCH&N:
MOV B_CURRENTBANK,#LOW B_SWITCH&N
(6)
SWlTCH&N (7)
RET (8)
:
Delay_noOS(10)函数的返回地址,即函数LcmIni-tion()的入口地址(也在bank3中),其高低位字节表示
为ADDH和ADDL。程序进入main()后的B_CURRENTBANK变量初值是B_SWITCH3的低8位,其意义稍后叙述。
AJMP B_BANKl后程序执行B_BANKl和B_SWITCHl的(1)~(8),执行到(5)时的堆栈结构如图1所示。
继续执行B_SWITCHl到(7)时,PSBANK变为指向bankl,B_CURRENTBANK变为B_SWITCHl的低8位。执行(8)后
,从堆栈结构可以看出,堆栈弹出①作为新的PC值,程序进入Delay_noOS(10)函数,延时功能完成后,
函数最后一条RET指令开始返回。这是Keil C51处理bank机制的关键,此时的返回地址为堆栈中的②,此
地址即B_SWITCH&H代码的入口,这里对应main()函数所在的bank3分组,也就是B_SWITCH3的人口。
因为所有B_SWITCH&N的高8位地址,即BANK SWITCH代码段的高8位都一样,由语句(2)中的操作符HIGH
BANK SWITCH确定;低8位保存在已经压栈的B_CURRENTBANK变量中,此时堆栈中的?B_CURRENTBANK压栈
值是B_SWITCH3的低8位,这样②的地址就是B_SWITCH3。
程序继续执行B_SWITCH3,在执行B_SWITCH3的(6)语句之前,B_CURRENTBANK还是前面执行B_SWITCHl时的
值,即B_SWITCHl的低8位。执行语句(6)后,B_CURRENTBANK恢复为B_SWITCH3的低8位,为返回main函数
做准备。然后PSBANK置为33h,即指向bank3,接着执行RET语句,堆栈③成为RET的返回地址,程序回到
了main()中Delay_noOS(10)的下一条语句继续执行,B_CURRENTBANK也已恢复。
这个调用过程中,用了6个堆栈字节,3条RET指令,关键内容就是B_CURRENTBANK变量,它保存了可以恢
复调用前bank环境代码的地址低位。从被调用函数返回 到这个地址后,就能恢复调用前的bank环境,即
赋予PSBANK正确的值。
不采用直接保存PSBANK值然后再恢复,而是用压栈的方式保存了相关地址(语句(1)~(3)),是为了实现
跨bank区的嵌套调用。例如,在Delay_noOS(10)函数中,如果再次跨bank去调用新函数,会再次重复上
述过程,堆栈从②往上再长6个字节。Delay_noOS(10)函数之前执行B_SWITCHI产生的B_CURRENTBANK值
(B_SWITCHI的低8位)也会进栈,为调用完新函数后返回到bankl继续执行Delay_noOS(10)提供保证。
2 无操作系统bank分区间的强制跳转
[NextPage]
通过上面的分析得知,如果要处理跨bank区的跳转、调用和返回,关键是能正确处理好PSBANK中的内容
。当程序没有操作系统用于任务切换,而又需要强制退出某一函数进入到另一函数的某一地址时,比如
说在中断发生后,结束原来的工作转入到另一工作去,就需要处理好PSBANK。
如果不考虑bank,可以在转入新地址之前执行一段代码,保存该地址处的环境变量[2],包括堆栈指针sP
和需要的入口地址。然后在中断返回之前,恢复此环境变量,执行中断返回指令进入该新地址。这个思
路和C51库函数setjump和longjump比较相近,但比它们灵活,因为环境变量可以自己处理。
考虑bank后的情况稍微复杂些,环境变量中需增加bank的处理信息,那么只处理PSBANK行不行呢?
如果仅保存和恢复PSBANK,则很简单,在保存环境变量的程序中加入:
JMPEnv[envl][3]=PSBANK;
在恢复环境变量的程序中加入:
PSBANK=JMPEnv[envl][3];
这里环境变量是二维数组JMPEnv,envl代表一个环境变量,即一个返回点。第二维是变量中的参数个数
。因此可以保存多个环境变量以供使用。
初看起来这样处理是没有问题的,可实际上不行。因为进入返回点后,虽然PSBANK正确了,但是B_CUR-
RENTBANK可能已经被修改,不能和返回点程序的bank区匹配,如果再次出现跨bank调用的话将不能正确
返回。
处理方法是有点技巧的,因为C语言不支持汇编变量B_CURRENTBANK的写法,所以在L51_bank.A51中要加
上声明:
PUBLIC BLCURRENTBANK
和伪指令:
B_CURRENTBANK EQU ?B_CURRENTBANK
这样就可以在C程序中使用B_CURRENTBANK
了,先声明B_CURRENTBANK:
extern Uchar data B_CURRENTBANK;
然后在保存环境变量程序中加入:
JMPEnv[envl][3]=PSBANK;
JMPEnv[envl][4]=B_CURRENTBANK;
恢复环境变量程序中加入:
PSBANK=JMPEnv[envl][3];
B_CURRENTBANK=JMPEnv[envl][4];
这样恢复环境变量进入到新程序后,也将恢复该程序对应的正确B_cuRRENTBANK值,问题得到解决。
3 no/0S-ll移植中的bank分区处理
μC/OS-II的51版本已经很成熟,但是所有移植版本均未处理bank问题,需要增加该内容,否则不能在
包括C8051F12X系列及其他多bank程序中使用。
如前所述,Keil C51提供对跨bank调用的透明切换支持,但在使用操作系统时,这种透明切换机制还需
要提供对任务切换的支持。因为任务的切换,程序可能需要到别的代码分组中去运行,而此时PSBANK和
B_CUR-RENTBANK还停留在原来代码分组中的状态,将导致程序崩溃。显然,无论由于什么情况导致的任
务切换完成之前,都需要保存和恢复PSBANK和B_CURRENT-BANK的值。解决的办法是在每次任务切换前将
PS-BANK和B_CURRENTBANK压入用户任务栈。
按照μC/OS-II的要求,在任务创建时,任务栈必须初始化成像运行中的任务刚刚发生过中断一样嘲。
B_CURRENTBANK的初始值取决于该任务所在分组对应的切换代码段的低8位地址。所以,任务堆栈的初始
化函数OSTaskStkInit需要加入一个参数INT8U bank,指明该任务位于哪个代码分组中。又由于任务堆栈
的初始化函数是被任务创建函数OSTaskCreate调用的,所以该函数一样需要加入参数INT8U bank。
在压栈,出栈宏中需要加入:
PUSH PSBANK
PUSH B_CURRENTBANK
:
POP B_CURRENTBANK
POP PSBANK
在任务堆栈的初始化函数OSTaskStkInit中需要加入:
*stk++=17; //堆栈长度增加2个到17
;
[NextPage]
if(bank==0x22:){ //bank2
*stk++=bank;
*stk++=CurrentBank2();
else if(bank==0x33){ //bank3
*stk++=bank;
*stk++=CurrentBank3();
}
else{ //bankl和common
*stk++=0xll; //PSBANK
*stk++=CurrentBankl();
)
其中,bank0用任何的PSBANK值均没有问题,所以简化了PSBANK取值0x00的情况。
函数INT8U CurrentBankl(void),INT8U Current-Bank2(void)和INT8U CurrentBank3(void)是用汇编语
言实现的,返回值通过R7传递,目的是获得该任务所在分组对应切换代码段(SWITCHn)的低8位地址。不
用C语言编写的原因同样是B_SWITCH&N不被C支持。
单片机
相关帖子
怎么可以使51单片机和STC11系列的程序兼容呢
云龙51单片机视频教程,目前国内公认的最好的入门视频教程
求助!TX-1C开发板51串行中断 if 语句无法执行问题(看起来很简单,但不知为何总调不过去
求助
关于51单片机处理串口所接收到的数据的判断
国产单片机推荐:无锡矽杰微电子XC8P8600
51单片机(STC8051U34K64)_RA8889_SPI4参考代码(v1.3)
51单片机(STC8H8K64U/STC8051U34K64)_RA8889_8080参考代码(v1.3)
51单片机(STC8H8K64U/STC8051U34K64)_RA8889_HW_SPI4参考代码(v1.3) 硬件SPI方式
单片机驱动彩屏最简方案:单片机_RA8889最小开发板驱动控制TFT彩屏介绍(一)
举报
回复
1 个评论
ad***
管理员
发表于 2012-9-3 02:26:33
|
显示全部楼层
CurrentBankl(void)代码如下,其他两个类同。
RSEG PR CurrentBankl Os_CPU_A
CurrentBankl:
MOV DPTR,#B_SWITCHl
MOV R7.DPL
RET
结 语
本文介绍了Keil C51实现大于64 KB程序的bank分组代码切换机制的原理,提出了没有操作系统情况下非
正常转移时bank的处理方法以及μc/os—II操作系统在多bank分区程序移植中应采取的措施,在开发实
例中均得到了很好的应用。
本文章来自中国IT实验室
http://embed.chinaitlab.com/
举报
回复
支持
反对
返回列表
*
滑块验证:
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
注册会员
本版积分规则
发表回复
回帖后跳转到最后一页
回复
转播
评分
分享
打开支付宝扫一扫,最高立得1212元红包
搜索
本版
帖子
用户
热搜:
传感器
51串口程序
电子管放大器
夾式電表
夾式電流
Mentor论坛
打印机
版块推荐
百宝箱
My 布拉格
无边框Z9
Z9Max
Z9mini
nubia动态
问题 & 建议
资源分享
爱拍
同城会
牛仔生活
查看论坛所有版块>>
每日签到
论坛任务
摄影技巧
跳蚤市场
互助问答
论坛导读
申请内测
红包中心
每日摇一摇
活动中心
网站地图
官方旗舰店
图文热点
抗干扰LED数码管显示屏驱动芯片/3线串行接
VK1Q68D是一种带键盘扫描接口的数码管或点阵LED驱动控制专用芯片。内部集成有3线
抗干扰能力强/点阵数显LED屏驱动/数码管驱
VK1S68C是一种带键盘扫描接口的数码管或点阵LED驱动控制专用芯片,内部集成有3 线串
可支持14×4的点阵LED显示面板数码管LED驱
VK1624是一种数码管或点阵LED驱动控制专用芯片,内部集成有3线串行接口、数据锁 存
数显驱动器原厂-数显LED显示驱动芯片VK1620
VK1620B是一种数码管或点阵LED驱动控制专用芯片,内部集成有3线串行接口、 数据锁
抗干扰数显驱动数码管LED驱动芯片VK1618 SO
产品品牌:永嘉微电/VINKA 产品型号:VK1618 封装形式:SOP18/DIP18 概述 VK161
更多
精华推荐
抗干扰LED数码管显示屏驱动芯片/3线串行接
抗干扰能力强/点阵数显LED屏驱动/数码管驱
可支持14×4的点阵LED显示面板数码管LED驱
数显驱动器原厂-数显LED显示驱动芯片VK1620
抗干扰数显驱动数码管LED驱动芯片VK1618 SO
VK1616 SOP16/DIP16点阵LED数显驱动芯片/数
点阵数显驱动芯片/LED数码管显示屏驱动VK16
数显驱动电路LED显示驱动芯片VK1650 SOP16/
更多
社区学堂
抗干扰LED数码管显示屏驱动芯片/3线串
抗干扰能力强/点阵数显LED屏驱动/数码
抗干扰LED数码管显示屏驱动芯片/3线串行接
VK1Q68D是一种带键盘扫描接口的数码管或点阵LED驱动控制专用芯片。内部集成有3线
抗干扰能力强/点阵数显LED屏驱动/数码管驱
VK1S68C是一种带键盘扫描接口的数码管或点阵LED驱动控制专用芯片,内部集成有3 线串
可支持14×4的点阵LED显示面板数码管LED驱
VK1624是一种数码管或点阵LED驱动控制专用芯片,内部集成有3线串行接口、数据锁 存
更多
客服中心
QQ:187196467
服务时间:周一至周日 8:30-20:30
在线客服
客服微博
产品咨询
售后中心
关注我们
关于我们
关于我们
友情链接
联系我们
帮助中心
网友中心
购买须知
支付方式
服务支持
资源下载
售后服务
定制流程
关注我们
官方微博
官方空间
官方微信
QQ:187196467
周一到周日 8:30-22:00 (全年无休)
7 x 24小时在线客服
手机版
Powered by
MCUZX!
X3.4 © 2008-2015
MCU资讯论坛
版权所有
京ICP备18035221号-2
客服QQ: 187196467
技术支持:
MCU资讯论坛
|
网站地图
快速回复
返回顶部
返回列表