精华内容
下载资源
问答
  • Keil C51 Code Banking

    千次阅读 2020-08-28 11:49:17
    针对这种情况,Keil C51提出了Code Banking机制来解决这个问题。 2. 基本原理 MCS-51内核的代码执行机制已经固定死了,代码运行的地址范围只能在0-64KB之间。一般情况下,我们编译生成的Bin文件,其代码执行地址和...

    1. 简介

    MCS-51是8根数据线,16根地址线,所以MCS-51最大只能访问64KB(216)的地址。很多较复杂的C51代码,其整个代码生成Bin文件可能大小64KB。针对这种情况,Keil C51提出了Code Banking机制来解决这个问题。

    2. 基本原理

    MCS-51内核的代码执行机制已经固定死了,代码运行的地址范围只能在0-64KB之间。一般情况下,我们编译生成的Bin文件,其代码执行地址和代码存储地址是一致。MCU执行到哪个地址,直接去ROM上取相应地址的内容然后执行即可。
    MCU要访问超过64KB的地址范围,肯定需要增加地址线。增加4根地址线,则能够访问到2MB的地址范围。由于MCS-51只能执行64K范围的代码,Keil C51编译器相应也只会生成64K地址范围内的代码。
    C51是采用分离编译,即单个文件独立编译,最后再链接成一个Bin文件。在链接的过程中,会有一个地址重定位的过程,会将每个obj文件中的代码映射成64K中的一个绝对地址。Keil链接器在链接时,可以将指定的多个Obj文件中的代码地址重定位到相同同地址空间去。如ObjA和ObB指定地址重定位到相同的地址范围内,并且各自的CodeSize为40KB。这样A.c和B.c的代码不能同时在MCU上执行,但是分两次加载,就可以在分别MCU上执行了。
    MCS-51默认ROM片外存储器为64KB,存放A.bin。MCS-51再外接1个64KB的外置存储器ROM存放B.bin。什么时候读取ROMA,什么时候读取ROMB呢?还需要1个Pin用来选择。执行A.C中的函数时,选择读取ROMA,执行B.C中的函数时,选择读取ROMB。那么如何知道A.C中的函数会读取ROMA,B.C中的函数会读取ROMB呢?这是因为编译器会将A.C中的函数全部标记0,将B.C中的函数全部标记1。这个标记正好对应上面选择ROM的Pin。

    3. Keil的实现

    像Reset Vector、Interrupt Vectors、Interrupt Service Routines以及负责几个相同地址模块切换的代码,都是必须固定位置,不能随意变动,可能导致系统出问题。所以Keil C51提出了一个Common Area的概念,存放上述代码。然后针对重定位到相同地址的代码,则被称为Bank Area。

    3.1. 具体设置

    1. Bank Area,选择指定有多少个相同地址范围的代码。
      在这里插入图片描述

    2. 指定文件所属Bank号。
      可以将多个文件指定为相同Bank号,未指定Bank号的文件默认为Common Area。BX51链接器最多支持32个Bank号,LX51链接器最多支持64个Bank号。
      在这里插入图片描述

    3. Bank分配基本原则。
      Common Bank因为是不需要重复加载的,所以效率最高。那些追求效率的代码,都可骗我在Common Bank中。如:Reset Vector、Interrupt Vector、Interruption Service Routines、String constants、Bank Switching Routines、Inter-Bank Jump Tables等等。
      Bank0放置一上电就需要调用,并且调用不是非常频率的代码。
      其他调用不频繁的代码放在其他Bank。

    4. 添加Bank调用代码,默认使用系统提供的(在Keil\C51\LIB\L51_BANK.A51)。
      B_NBANKS与前面配置的Bank数相同,B_MODE是Bank_Switching的方式。

    ;                         <i> For BL51 the maximum value for ?B_NBANKS is 32
    ;                         <i> For LX51 the maximum value for ?B_NBANKS is 64
    ?B_NBANKS       EQU  4    ; Define maximum Number of Banks
    ;                         ; following values are allowed: 2, 4, 8, 16, 32, 64
    ;                         ; for BL51 the maximum value for ?B_NBANKS is 32
    ;                         ; for LX51 the maximum value for ?B_NBANKS is 64
    ;
    ; <o> ?B_MODE: Bank Switching via
    ;                    <0=> 8051 Port
    ;                    <1=> XDATA Port
    ;                    <4=> User-provided bank switch code
    ?B_MODE         EQU  0    ; 0 for Bank-Switching via 8051 Port
    ;                         ; 1 for Bank-Switching via XDATA Port
    ;                         ; 4 for user-provided bank switch code
    

    3.2. 链接器

    Keil C51支持2种链接器,分别为BL51和LX51。
    在这里插入图片描述

    3.2.1. BL51链接器

    BL51默认生成的Hex文件为Hex80,并且当前工程设置多少个Bank,则生成多少个Hex文件,每个Bank和相同的Common组成一个文件,如下图。每个Hex文件可以用Hex2Bin.exe转换成Bin文件。
    在这里插入图片描述

    3.2.2. LX51链接器

    BL51是较早的链接器,LX51是在BL51基础上进行扩展的链接器,功能更强大,优化性能更好。一般情况下建议使用LX51。LX51会将多个Bank合并生成一个Hex文件。这个Hex文件中的代码地址空间是超过64KB的,Hex80格式不支持超过64KB的地址空间。针对这种情况,一种新的Hex描述格式产生了——Hex386。Hex386不仅支持多超过64KB地址范围,还支持指定偏移存储。
    在这里插入图片描述
    BL51链接器生成的Bin文件,如果Bank Area有多余空间,会以0填充。而LX51生成的Bin文件,如果Bank Rrea有多余空间,则会优先以Common代码填充。Offset默认为0,如果指定了,则将生成的代码放在Bin文件相应的偏移。下图为偏移为0。
    在这里插入图片描述

    在这里插入图片描述

    3.3. Bank Switching方式

    3.3.1. 8051Port

    MSC-51操作64KROM的结构如下:
    在这里插入图片描述
    我们完全可以依据上述接口,连接多个ROM。然后通过P口来选通。
    在这里插入图片描述
    L51_BANK.A51中有下述代码,即指定P1口用来控制选择哪个ROM,也即代码执行到Bank1时,P1=1;执行到Bank2时,P1=2,依次类推。更详细的切换流程,可以查看汇编代码。

    IF  ?B_MODE = 0;
    ;-----------------------------------------------------------------------------
    ; if ?BANK?MODE is 0 define the following values
    ; For Bank-Switching via 8051 Port define Port Address / Bits
    ;
    ;<h> Bank Switching via 8051 Port
    ;    <i> This is only used if ?B_MODE is 0
    ; <o> P1: 8051 Port address <0x0-0xFF>
    P1              DATA    90H      ; I/O Port Address
    ;
    ?B_PORT         EQU     P1       ; default is P1
    ; <o> ?B_FIRSTBIT: Starting with Bit <0-7>
    ;     <i> Default is Bit 2
    ?B_FIRSTBIT     EQU     2        ; default is Bit 2
    ;</h>
    ;-----------------------------------------------------------------------------
    ENDIF;
    

    3.3.2. XData Port

    查看L51_BANK.A51代码,变量B_XDATAPORT是参与切换的标识,默认设置为0xFFFF,可以根据需要修改。

    IF  ?B_MODE = 1;
    ;-----------------------------------------------------------------------------
    ; if ?BANK?MODE is 1 define the following values
    ; For Bank-Switching via XDATA Port define XDATA Port Address / Bits
    ;
    ;<h> Bank Switching via XDATA Port Address
    ;    <i> This is only used if ?B_MODE is 1
    ; <o> P1: XDATA port address <0x0-0xFFFF>
    ?B_XDATAPORT    EQU     0FFFFH   ; default is XDATA Port Address 0FFFFH
    ; <o> ?B_FIRSTBIT: Starting with Bit <0-7>
    ;     <i> Default is Bit 0
    ?B_FIRSTBIT     EQU     0        ; default is Bit 0
    ;</h>
    ;-----------------------------------------------------------------------------
    ENDIF;
    

    配合分布外部存储器,如下图。PSD813F2可以0FFFFH地址为控制位,来分别切换不同的Bank对应不同的存储空间,达到和8051Port类似的效果。标准的ROM成本较高,使用此种方式,可以更方便地支持更多的Bank,成本也低。PSD813F2更详细的配置可以参考PSD813F2的DataSheet。
    在这里插入图片描述

    3.3.3. user-provided

    以上两种方式,明显是8051Port更容易。所以用户定义也是基于这种方式。很多基于MSC-51内核的MCU,并未完整引出P1口,不能正确的使用方法1,此时可以自定义。见L51_BANK.A51代码。

    P1              DATA    90H      ; I/O Port Addresses
    P3              DATA    0B0H
    ;
    SWITCH0         MACRO            ; Switch to Memory Bank #0
                    CLR     P1.5     ; Clear Port 1 Bit 5
                    CLR     P3.3     ; Clear Port 3 Bit 3
                    ENDM
    ;
    SWITCH1         MACRO            ; Switch to Memory Bank #1
                    SETB    P1.5     ; Set   Port 1 Bit 5
                    CLR     P3.3     ; Clear Port 3 Bit 3
                    ENDM
    ;
    SWITCH2         MACRO            ; Switch to Memory Bank #2
                    CLR     P1.5     ; Clear Port 1 Bit 5
                    SETB    P3.3     ; Set   Port 3 Bit 3
                    ENDM
    ;
    SWITCH3         MACRO            ; Switch to Memory Bank #3
                    SETB    P1.5     ; Set   Port 1 Bit 5
                    SETB    P3.3     ; Set   Port 3 Bit 3
                    ENDM
    

    默认是以P1.5和P3.3两个Pin为例。需要匹配相应的外置电路,见下图。编译器编译Bank1的函数,会在前面插入SWITCH1指令,相当于Bank1对应的EPROM。编译器编译Bank2的函数,会在前面插入SWITCH2指令,相当于Bank2对应的EPROM。更多详细信息,可以在Keil中仿真调试查看。
    在这里插入图片描述

    3.3.4. 注意

    使用user-provided时,因为复位时,系统保持之前的状态,不会自动切换到Bank0,需要修改切换代码,见STARTUP.A51代码的最后,将if 0改为if 1。

    ; This code is required if you use L51_BANK.A51 with Banking Mode 4
    ;<h> Code Banking
    ; <q> Select Bank 0 for L51_BANK.A51 Mode 4
    #if 0   
    ;     <i> Initialize bank mechanism to code bank 0 when using L51_BANK.A51 with Banking Mode 4.
    EXTRN CODE (?B_SWITCH0)
                    CALL    ?B_SWITCH0      ; init bank mechanism to code bank 0
    #endif
    

    3.4. 自定义外部存储器

    除了MSC-51直接总线支持的的ROM外部存储器外,还有一些设备可以作为外部存储器存储bin文件。如EEPROM、NorFlash,这两种设置,MSC-51一般没有直接提供总线访问,也就是说直接连接到MSC-51上,然后直接利用Keil提供的Bank Switching方法。那么针对这种情况,我们有办法吗?可以的。我们可以完全不用Keil提供的Switch方法,完全自己构建Switch方法。如在执行Bank0中的FunA时,接下来需要执行Bank1中的函数B,那么在执行FunB之前,先让代码运行至Common Bank中的SwitchFun。SwitchFun负责将Bank1中的Bin文件加载SRAM中覆盖原有的Bank0的代码。详见下面的伪代码。

    // Common.c
    void SwitchFun(int nOldBankNo, int nNewBankNo, PFun pFun)
    {
    	LoadBinToSRAM(nNewBankNo);
    	pFun();
    	LoadBinToSRAM(nNewBankNo);
    }
    
    // Bank0.c
    void FunA()
    {
    	// Call FunB of bank1
    	SwitchFun(0, 1, FunB);
    	// Do some stuff
    }
    
    // Bank1.c
    void FunB()
    {
    	// Do some stuff
    }
    

    LoadBinToSRAM完成加载指定Bank的Bin覆盖到指定的SRAM。
    此种方法主要是利用Keil的Code Banking功能将指定文件生成相同的执行代码地址,加载切换的过程换成自己实现。这里依然要利用L51_BANK.A51文件,否则无法使用Bank功能。然后用user-provided模式,为了防止触发Keil提供的切换功能自动设置了相应的Pin,我们可以修改L51_BANK.A51中B_MODE = 4时时的代码,注释对相关Pin的设置。当我们调用Bank0的函数时,系统可能会调用SWITCHO函数,然后会设置对应的2个Pin,这会带来不可控影响。

    P1              DATA    90H      ; I/O Port Addresses
    P3              DATA    0B0H
    ;
    SWITCH0         MACRO            ; Switch to Memory Bank #0
    ;                CLR     P1.5     ; Clear Port 1 Bit 5
    ;                CLR     P3.3     ; Clear Port 3 Bit 3
                    ENDM
    ;
    SWITCH1         MACRO            ; Switch to Memory Bank #1
    ;                SETB    P1.5     ; Set   Port 1 Bit 5
    ;                CLR     P3.3     ; Clear Port 3 Bit 3
                    ENDM
    ;
    SWITCH2         MACRO            ; Switch to Memory Bank #2
    ;                CLR     P1.5     ; Clear Port 1 Bit 5
    ;                SETB    P3.3     ; Set   Port 3 Bit 3
                    ENDM
    ;
    SWITCH3         MACRO            ; Switch to Memory Bank #3
    ;                SETB    P1.5     ; Set   Port 1 Bit 5
    ;                SETB    P3.3     ; Set   Port 3 Bit 3
                    ENDM
    

    3.5 注意

    Hex386和Hex80的格式略有些差异,前者兼容后者,后者并不完全兼容前者。Demo中提供支持Hex386转成Bin的Hex2Bin.exe。
    更多细节见附件

    展开全文
  • 基于JSP的51Code博客网站前端功能实现,课程设计项目,功能齐全易懂,内涵项目源码、实验报告用于教学、数据库文件、结果图,不可用于商业用途,仅用于学习交流
  • 51_programming_code

    2011-08-26 18:27:54
    51_programming_code 51_programming_code
  • ucos51-code

    2010-05-12 17:10:21
    打包下载ucos51-code,可以自己研究学习操作系统的使用和移植,而且很详实,很适合刚刚学习的新手
  • 51+8019tcpip-code.rar

    2010-02-01 11:44:04
    51+8019tcpip-code.rar51+8019tcpip-code.rar51+8019tcpip-code.rar51+8019tcpip-code.rar51+8019tcpip-code.rar51+8019tcpip-code.rar51+8019tcpip-code.rar51+8019tcpip-code.rar51+8019tcpip-code.rar
  • C51的code用法

    千次阅读 2012-08-14 10:59:52
    一个变量放到代码空间也不是C51的特有的,只不过有MCS-51的指令结构决定了对它的读取需要使用专门的指令(MOVC),才 显得比较特别。 因为代码空间的特殊性,用code关键字之后,这个变量就一定是全局变量,且在...
    从code开始,是因为code比较简单,只不过是告诉程序这个变量(其实是不能变的)的存放空间是在代码空间里。当然,把
    一个变量放到代码空间也不是C51的特有的,只不过有MCS-51的指令结构决定了对它的读取需要使用专门的指令(MOVC),才
    显得比较特别。
    因为代码空间的特殊性,用code关键字之后,这个变量就一定是全局变量,且在整个程序的生存周期里都是一直存在且有
    效。
    因此,这种变量在函数调用时是没有必要作为参数传递的,那样的话,是一种浪费。如果需要的话传一个指针就好了。。
    。。。

    展开全文
  • keil中C51关键字code用法

    千次阅读 2020-08-14 16:06:01
    keil中关键字code说明  用unsigned int 或signed char等定义的变量都存储在单片机的RAM中,程序中可以随意更改这些变量的值。而运用code关键字修饰下定义的变量,比如unsigned char code i;,它们则存储在单片机...
    • keil中关键字code说明

     关键字code是51单片机特有关键字,用unsigned int 或signed char等定义的变量都存储在单片机的RAM中,程序中可以随意更改这些变量的值。而运用code关键字修饰下定义的变量,比如unsigned char code i;,它们则存储在单片机程序存储空间FLASH中,节省单片机RAM资源,但在程序中不能更改这些变量的值

    展开全文
  • 51单片机unsigned char code 定义

    千次阅读 2019-02-21 09:46:37
    对于51单片机 以下的代码定义: //定义一个数据表格 unsigned char code TAB[10]= { //定义表格一定要使用code,这样会做到程序存储区中 0x3F, //表格第1步数据0b00111111 0x06, //表格第2步数据0b0000...

    对于51单片机 以下的代码定义:

    //定义一个数据表格
    unsigned char code TAB[10]=
    {                          //定义表格一定要使用code,这样会做到程序存储区中
        0x3F,                  //表格第1步数据0b00111111
        0x06,                  //表格第2步数据0b00000110
        0x5B,                  //表格第3步数据0b01011011
        0x4F,                  //表格第4步数据0b01001111
        0x66,                  //表格第5步数据0b01100110
        0x6D,                  //表格第6步数据0b01101101
        0x7D,                  //表格第7步数据0b01111101
        0x07,                  //表格第8步数据0b00000111
        0x7F,                  //表格第9步数据0b01111111
        0x6F,                  //表格第10步数据0b01101111
    };
    

    定义中的 code 代表的是 把定义的数据表存储到 flash存储器中,如果定义 unsigned char TAB[10],表示的是定义的数据表格存储到RAM中,51单片机的RAM通常都比较小,1k 左右,对于小量的数据是可以存储到RAM中,如果是声音文件等大数据需要存储到FLASH存储器中

    展开全文
  • 51 单片机的代码分页(code bank)原理与实现
  • C51中的code关键字

    千次阅读 2014-03-23 15:13:21
    单片机C语言unsigned char code table[] code 是什么作用? code的作用是告诉单片机,我定义的数据要放在ROM(程序存储区)里面,写入后就不能再更改,其实是相当与汇编里面的寻址MOVC(好像是),因为C语言中没办法...
  • 51单片机按键驱动控制,pwm控制rgb彩灯
  • CodeWarrior51 for S12可视化调试例程
  • 关于keil-C51中code、idata以及xdata

    千次阅读 2020-01-28 17:32:32
    keil-c51编译后会输出程序所占用的code、idata以及xdata各自所占用的区段大小,根据自身所选用的51mcu片上资源,以该输出信息为根据,进行程序上的优化与调整
  • 用Keil写代码是会让人发疯的,以前一直用VS stdio 写,后来发现VS Code更强大,于是开始用,但是发现写C51有些关键字是不支持的,老是提出错误,也是几经折腾,终于摸索出一些解决办法,记录下来,碰到这些问题的...
  • 89c51_code 51单片机系列视频相关资料,包括源代码和仿真文件&其他相关资料 作者:hhhmxk 说明:该仓库于2020。10。30日创立,尚不完善,后期有时间会改进 大事记 2020/10/30创建该仓库,上传51单片机代码
  • Keil C51通过以下的关键字定义了不同的存储类型,从而确保用户能够访问到51架构的全部存储空间。 code:访问程序存储器ROM,即我们常说的代码段,用来存放可执行代码,空间可达64K(0x0000~0xffff),该存储空间的...
  • Visual Studio Code下载 https://code.visualstudio.com 配置vscode 1.中文界面 然后点install 2.路径 还有编辑器里的设定,都设下吧 改成自己的keil对应的目录 3.内码 3.5 C/C++支持 ...
  • KEIL C51中的data、idata、xdata、code详解

    万次阅读 2018-02-25 18:15:11
    51单片机采用哈佛结构。内存空间编址有重叠。可以在不同总线上定义不同的变量。在KEIL C51中定义了xdata、idata、xdata、code几种域修饰符。这些修饰符决定了变量访问方式。 data:固定指前面0x00-0x7F的128个RAM,...
  • Learn_source_code_lua51 部分lua 5.1的源代码阅读及注释解
  • curl error code 60 51 代码解决方式

    千次阅读 2016-08-29 10:44:12
    curl error code 60  命令行加选项-k就可以 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, ...curl error code 51  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, true); CURLOPT_SSL_VERIFYHOST的值
  • 51单片机(code,idata,关键字笔记)

    万次阅读 多人点赞 2018-03-01 20:40:25
    code”关键字 51特有有这样一种数据,我们在程序中要使用,但是却不会改变它的值,定义这种数据时可以加一个 code 关键字修饰一下,这个数据就会存储到我们的程序空间 Flash 中,这样可以大大节省单片机的 RAM 的...
  • 51系列单片机生成二维码 keil环境,12864打点程序附赠,有清楚的使用方法,以及注释,都是通俗易懂的代码~
  • 51系列单片机生成二维码 keil环境,12864打点程序附赠,有清楚的使用方法,以及注释,都是通俗易懂的代码~
  • keil c51中的data idata xdata code详解

    千次阅读 2014-01-11 11:26:19
    在keilc51中定义了data idata xdata code几种域修饰符。这些修饰符决定了变量访问方式。 data:用mov直接访问的内部RAM idata:用mov @间接访问的内部RAM xdata:用movx访问的外部RAM code:用movc访问的rom ...
  • code 指定存储位置位于程序存储器。程序存储器只读,因此code类型的变量,是无法再次赋值的。 unsigned char code ary[ ] = :"Read only"; /* 数组ary位于程序存储器 */ ary[0]='a'; /* 错误,不可修改*/
  • imx51 ROM boot code 启动分析

    千次阅读 2012-02-06 15:21:32
    3. iMX51的内部ram只有128KB,是无法装载整个uboot的,所以ROM boot code会把uboot最前面的部分读取出来放到内部ram(对于SD卡,boot ROM会读取SD设备的前2Kbytes数据到iram),并且把指针指向这个内部地址执行uboot...
  • 在这个语句中的code是告诉单片机我定义的这个数组是要放在ROM中的,是不能更改的,程序可以简单的分为code和data; 其中code在运行时是不能更改的,data存放的是不断改变的; 这么做是为了节省片上的RAM,一般...
  • 使用KEIL C BL51 中,code分配的指令

    千次阅读 2013-01-29 10:04:30
    CODE Linker Directive Home » Linking Programs » Directives » Reference » CODE Abbreviation CO Arguments CODE (〚range〛 〚segment 〚(address)〛 〚, ...〛〛) Default ...
  • 数组前不加“code”或“> code 指定数据是存储在代码区,数据是在编程的时候跟代码一起写入代码存储器,运行过程中不能改变;...idata 指定数据存储在内部低256字节数据存储器里,但51只有128字节内部RAM,52才...
  • 51单片机的data,xdata,code区别详解

    千次阅读 2016-01-13 16:35:54
    code 是在 0000H .. 0FFFFH 之间的一个代码地址。 我用 ORG 5000H TAB: DB 22H,3BH,43H,66H,5H,6DH,88H后, CODE从5000H开始以后变成DB各位 data 是 在 0 到 127 之间的一个数据存储器地址...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 357,852
精华内容 143,140
关键字:

51code