C8051 F12X中多bank的分区跳转处理

发布者:艺泉阁最新更新时间:2006-10-08 来源: 单片机及嵌入式系统应用关键字:衍生  单片机  嵌入式 手机看文章 扫描二维码
随时随地手机看文章
在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();
:
:
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分区间的强制跳转
通过上面的分析得知,如果要处理跨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

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支持。
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分区程序移植中应采取的措施,在开发实例中均得到了很好的应用。

关键字:衍生  单片机  嵌入式 引用地址:C8051 F12X中多bank的分区跳转处理

上一篇:单片机在微型打印机中的应用
下一篇:MSP430单片机中的WDT研究

推荐阅读最新更新时间:2024-05-13 18:14

C8051F005单片机的比例电磁铁控制技术
引 言 比例电磁铁作为执行元件,是机电一体化的关键产品之一,广泛应用于各种自动化控制系统中;比例电磁铁的推力大,结构简单,维护方便,成本低廉,是应用非常广泛的电一机械转换器;比例电磁铁的特性及工作的可靠性,对于整个控制系统具有十分重要的影响,是决定控制系统品质的关键部件之一。比例电磁铁作为电一机械转换元件,其功能是将比例控制放大器输给的电流信号,转换成位移或者力信号输出。比例电磁铁适用于直流电压为24 V比例控制放大器的控制线路中,作为连续地、按比例地控制系统执行元件的运动、速度和方向的动力元件。 比例电磁铁在其额定行程范围内的推力与通入其线圈的电流成正比,可在其他需要作用力自动控制的装置上作为线性动力元件,如自动油门控制等。
[应用]
PIC单片机定时中断
#INCLUDE P16F877.inc ORG 000H GOTO A1 ORG 004H;定时中断入口地址 GOTO ZD01; ORG 0CH A1 MOVLW 1;位1显示数 MOVWF 50H; MOVLW 2;位2显示数 MOVWF 51H; MOVLW 3;位3显示数 MOVWF 52H; MOVLW 4;位4显示数 MOVWF 53H; MOVLW 4;显示位数 MOVWF 40H; MOVLW B'00000001';位码 MOVWF 41H; MOVLW 50H; MOVWF FSR ;间接寻址 BSF ST
[单片机]
单片机控制步进电机PMW的驱动与放大
  单片机实现的步进电机控制系统具有成本低、使用灵活的特点,广泛应用于数控机床、机器人,定量进给、工业自动控制以及各种可控的有定位要求的机械工具等应用领域。步进电机是数字控制电机,将脉冲信号转换成角位移,电机的转速、停止的位置取决于脉冲信号的频率和脉冲数,而不受负载变化的影响,非超载状态下,根据上述线性关系,再加上步进电机只有周期性误差而无累积误差,因此步进电机适用于单片机控制。步进电机通过输入脉冲信号进行控制,即电机的总转动角度由输入脉冲总数决定,而电机的转速由脉冲信号频率决定。步进电机的 驱动电路 是根据单片机产生的控制信号进行工作。因此,单片机通过向步进电机驱动电路发送控制信号就能实现对步进电机的控制。   1 系统设计原理
[单片机]
<font color='red'>单片机</font>控制步进电机PMW的驱动与放大
基于PIC单片机的相干光通信系统设计
引言 在光通信领域,更大的带宽、更长的传输距离、更高的接收灵敏度,永远都是科研者的追求目标。尽管波分复用(WDM)技术和掺铒光纤放大器(EDFA)的应用已经极大的提高了光通信系统的带宽和传输距离,伴随着视频会议等通信技术的应用和互联网的普及产生的信息爆炸式增长,对作为整个通信系统基础的物理层提出了更高的传输性能要求。光通信系统采用强度调制/直接检测(IM/DD),即发送端调制光载波强度,接收机对光载波进行包络检测。尽管这种结构具有简单、容易集成等优点,但是由于只能采用ASK调制格式,其单路信道带宽很有限。因此这种传统光通信技术势必会被更先进的技术所代替。然而在通信泡沫破灭的今天,新的光通信技术的应用不可避免的会带来对新型通信设备的
[单片机]
基于PIC<font color='red'>单片机</font>的相干光通信系统设计
HOLTEK 新推出HT66FW2230 Wireless Charger A/D Flash MCU
HT66FW2230。专为WPC QI Transmitter规范所设计的专用MCU。除了可处理WPC QI规范所需的PID控制,达到规范需求。并对于无线电源功率控制关键所需的频率控制,具备高解析的频率输出,让功率控制更加平顺。内部则整合了功率控制所需的电流量测与通讯解调电路,可有效精简外部应用电路。对于安全性机制方面,提供了包括过流保护、过压保护、过温保护与异物侦测 (FOD,Foreign Object Detection) 等全方位的保护功能。对于LC Tank的驱动控制,除了一般外接Gate Driver驱动Power MOS的Solution外,更内建全桥互补式、具有Dead Time调整的Large D
[单片机]
HOLTEK 新推出HT66FW2230 Wireless Charger  A/D Flash <font color='red'>MCU</font>
如何优化嵌入式DSP应用的功耗
采用软硬件技术可以提高电源效率,而使用内置电源管理 API 的 DSP RTOS 更容易实现上述目的。 作者:Scott Gary, 德州仪器 (TI) 无线及有线系统设计师均必须重视电源效率问题,尽管双方的出发点不尽相同。 对于移动设备而言,更长的电池使用寿命、更长的通话时间或更长的工作时间都是明显的优势。降低电源要求意味着使用体积更小的电池或选择不同的电池技术,这在一定程度上也缓解了电池发热问题。 对于有线系统而言,设计师可通过减小电源体积、减少冷却需求以及降低风扇噪声来提高电池效率。人们很少会提到这样一个事实:提高电源效率还可节省空间,用以增加能够提高系统性能的组件,尤其是设计小组希望添加一个以上处理器时,这一点非
[工业控制]
如何优化<font color='red'>嵌入式</font>DSP应用的功耗
单片机扩展触摸屏人机接口的应用实例
触摸屏 如图1,典型触摸屏的工作部分一般由三部分组成:两层透明的阻性导体层、两层导体之间的隔离层、电极。阻性导体层选用阻性材料,如铟锡氧化物(ITO)涂在衬底上构成,上层衬底用塑料,下层衬底用玻璃。隔离层为粘性绝缘液体材料,如聚脂薄膜。电极选用导电性能极好的材料(如银粉墨)构成,其导电性能大约为ITO的1000倍。 图1 触摸屏 触摸屏工作时,上下导体层相当于电阻网络。当某一层电极加上电压时,会在该网络上形成电压梯度。如有外力使得上下两层在某一点接触,则在电极未加电压的另一层可以测得接触点处的电压,从而知道接触点处的坐标。比如,在顶层的电极(X+,X-)上加上电压,则在顶层导体层上形成电压梯度,当有外力使得上
[单片机]
stm32F103单片机无源晶振不起振排除问题
这是我在做单片机最小系统板时候碰到的问题,之前虽然也做过相似的板子,可是未曾出现过无源晶振不起振的问题。下面是我在遇到问题后的一些检查,排除问题的过程。本人小菜鸟一个,文章中如有错误和不足,还望各位大佬指正和补充。 事情是这样的,本人做了一款32单片机最小系统板(先叫它老大),在老大出来之前的前五个月,我用相同的PCB板焊了一款用在毕设上面,那个是能正常工作的。板上有个小负载,LED灯。想让这个灯闪烁。代码是没有问题的,因为下载到从网上买的单片机是正常工作的。用JLink下载到自己做的板子上也是能下载进去的,但是不工作。怀疑晶振没起振。用示波器测量晶振引脚对地为一个高电平,而控制那个灯亮的管脚一直是高电平。买回来的板子晶振引脚
[单片机]
小广播
最新应用文章
换一换 更多 相关热搜器件

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 安防电子 医疗电子 工业控制

词云: 1 2 3 4 5 6 7 8 9 10

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

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