中国IEEE
关于我们 | 会员登陆 | 收藏本站 | 留 言 薄
 

 | 网站首页 | 电子知识 | 单片机知识 | 电路设计 | 微电子技术 | SCADA系统 | 资源下载 | 给我留言 | 视频教程 | ieee | 
热门搜索关键字: 单片机教程 | 三极管微电子 |  C语言汇编语言SCADA元器件IEEE |
cnieee.com baidu
栏目导航  
栏目更新推荐  
·红外遥控及C语言51红外遥控解码程序
·8051单片机C语言数据采集程序
·LCD驱动芯片1335控制器C51源程序
·Keil C51和 标准C语言的异同…
·C51内存优化
·C51延时程序
·数字滤波常用的软件方法
·渐变LED流水灯程序(C源程序)
点击TOP(10)  
  • 此栏目下没有热点文章
  • 图片文章  

    C语言嵌入式系统编程…

    C语言嵌入式系统编程…

    C语言嵌入式系统编程…
     
    您现在的位置: 中国IEEE中国电气电子工程师网 >> 单片机知识 >> 编程语言 >> 单片机C语言 >> 正文

    C51内存优化
    文章来源:本站整理 点击数: 更新时间:2008-6-6 【字体:
    (欢迎光临中国IEEE,希望本文能对您有所帮助http://www.cnieee.com)


    相关文章:

    红外遥控及C语言51红外遥控解码程序
    LCD驱动芯片1335控制器C51源程序
    Keil C51和 标准C语言的异同…
    KEIL C51支持的完整芯片…

  • 上一个文章:

  • 下一个文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
     
    关于〖C51内存优化〗的最新评论:
    浅谈 C51 内存优化以及如何对内存优化,以达到最大的利用效果
        对 51 单片机内存的认识,很多人有误解,最常见的是以下两种

    ① 超过变量128后必须使用compact模式编译
       实际的情况是只要内存占用量不超过 256.0 就可以用 small 模式编译
    ② 128以上的某些地址为特殊寄存器使用,不能给程序用
       与 PC 机不同,51 单片机不使用线性编址,特殊寄存器与 RAM 使用重复的重复的地址。但访问时采用不同的指令,所以并不会占用 RAM 空间。

        由于内存比较小,一般要进行内存优化,尽量提高内存的使用效率。

        以 Keil C 编译器为例,small 模式下未指存储类型的变量默认为data型,即直接寻址,只能访问低 128 个字节,但这 128 个字节也不是全为我们的程序所用,寄存器 R0-R7必须映射到低RAM,要占去 8 个字节,如果使用寄存组切换,占用的更多。

        所以可以使用 data 区最大为 120 字节,超出 120 个字节则必须用 idata 显式的指定为间接寻址,另外堆栈至少要占用一个字节,所以极限情况下可以定义的变量可占 247 个字节。当然,实际应用中堆栈为一个字节肯定是不够用的,但如果嵌套调用层数不深,有十几个字节也够有了。


    为了验上面的观点,写了个例子

    #define LEN 120
    data UCHAR tt1[LEN];
    idata UCHAR tt2[127];

    void main()
    {
        UCHAR i,j;

        for(i = 0;  i < LEN; ++i )
        {
            j = i;
            tt1[j] = 0x55;
        }
    }

    可以计算 R0-7(8) + tt1(120) + tt2(127) + SP(1) 总共 256 个字节

    keil 编译的结果如下:
    Program Size: data=256.0 xdata=0 code=30
    creating hex file from ".\Debug\Test"...
    ".\Debug\Test" - 0 Error(s), 0 Warning(s).
    (测试环境为 XP + Keil C 7.5)

        这段代码已经达到了内存分配的极限,再定义任何全局变量或将数组加大,编译都会报错 107

        这里要引出一个问题:为什么变量 i、j 不计算在内?
        这是因为 i、j 是局部变量,编译器会试着将其优化到寄存器 Rx 或栈。问题也就在这了,如果局部变量过多或定义了局部数组,编译器无法将其优化,就必须使用 RAM 空间,虽然全局变量的分配经过精心计算没有超出使用范围,仍会产生内存溢出的错误!

        而编译器是否能成功的优化变量是根据代码来的
        上面的代码中,循环是臃肿的,变量 j 完全不必要,那么将代码改成

    UCHAR i;
    UCHAR j;

    for(i = 0;  i < LEN; ++i )
    {
        tt1[i] = 0x55;
    }

    再编译看看,出错了吧!
    因为编译器不知道该如何使用 j,所以没能优化,j 须占 RAM 空间,RAM 就溢出了。
    (智能一点的编译器会自动将这个无用的变量去掉,但这个不在讨论之列了)

    另外,对 idata 的定义的变量最好放在 data 变量之后

    对于这一种定义


    uchar c1;
    idata uchar c2;
    uchar c3;
    变量 c2 肯定会以间接寻址,但它有可能落在 data 区域,就浪费了一个可直接寻址的空间


    变量优化一般要注意几点:

        ①让尽可能多的变量使用直接寻址,提高速度
          假如有两个单字节的变量,一个长119的字符型数组
          因为总长超过 120 字节,不可能都定义在 data 区
          按这条原则,定义的方式如下:


          data UCHAR tab[119];
          data UCAHR c1;
          idata UCHaR c2;
          但也不是绝的,如果 c1, c2 需要以极高的频率访问,而 tab 访问不那么频繁
          则应该让访问量大的变量使用直接寻址:

          data UCAHR c1;
          data UCHaR c2;
          idata UCHAR tab[119];
          这个是要根据具体项目需求来确定的

        ②提高内存的重复利用率
          就是尽可能的利用局部变量,局部变量还有个好处是访问速度比较快
          由前面的例子可以看出,局部变量 i, j 是没有单独占用内存的
          子程序中使用内存数目不大的变量尽量定义为局部变量

        ③对于指针数组的定义,尽可能指明存储类型
     &nbs

    [1] [2] 下一页

    | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明网站地图 | 名站导航 | 管理登录 | 
    本站资源部分来自互联网,如侵犯您的权利,我们将予以删除  鲁ICP备08006092号
    本站欢迎同类网站做友情链接,QQ留言
    中国IEEE 中国电气电子工程师网 版权所有