找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3384|回复: 48
收起左侧

小容量的单片机芯片怎么提高存储空间利用率?

  [复制链接]
ID:887202 发表于 2021-9-22 11:12 | 显示全部楼层 |阅读模式
如题,最近接触到一款存储空间非常小的单片机,代码量稍微大一点就用不了了,所以想问问大伙有没有提高存储空间利用率的办法
回复

使用道具 举报

ID:88256 发表于 2021-9-22 12:02 | 显示全部楼层
用汇编吧
回复

使用道具 举报

ID:277550 发表于 2021-9-22 12:12 | 显示全部楼层
精简代码。。。
回复

使用道具 举报

ID:57657 发表于 2021-9-22 12:19 | 显示全部楼层
具体是多少位,什么型号?
回复

使用道具 举报

ID:161164 发表于 2021-9-22 12:39 | 显示全部楼层
把代码贴上来看看
回复

使用道具 举报

ID:90613 发表于 2021-9-22 13:17 | 显示全部楼层
减少不必要的程序,特别是数组,能少定义就少定义,能不定义全局变量就不要全局。.h文件也不要随便定义,如果只用到printf而调用了 <stdio.h>,就不要用了
回复

使用道具 举报

ID:366464 发表于 2021-9-22 13:26 | 显示全部楼层
加24系列芯片,想加多大就多大!
回复

使用道具 举报

ID:712493 发表于 2021-9-22 13:37 | 显示全部楼层
guizaishi 发表于 2021-9-22 13:17
减少不必要的程序,特别是数组,能少定义就少定义,能不定义全局变量就不要全局。.h文件也不要随便定义,如 ...

实际局部变量也不见得小,要知道局部变量有生存周期,如果生存周期长了,没有及时销掉,跟全局有啥区别,甚至还不如全局
回复

使用道具 举报

ID:514901 发表于 2021-9-22 13:48 | 显示全部楼层
经典的时间换空间的方法
回复

使用道具 举报

ID:887202 发表于 2021-9-22 13:53 | 显示全部楼层
感谢各位的回复,芯片是SQ013L,目前的代码里面已经非常精简了,所有的全局变量都是按位来定义的,使用了位域来定义全局变量,比较坑爹的就是,貌似官方的这个开发环境下临时变量使用完之后空间不会释放掉,还是会占用资源
回复

使用道具 举报

ID:887202 发表于 2021-9-22 13:53 | 显示全部楼层
npn 发表于 2021-9-22 12:19
具体是多少位,什么型号?

SQ013L
回复

使用道具 举报

ID:123289 发表于 2021-9-22 15:39 | 显示全部楼层
只有当你懂得汇编和单片机原理时,才能准确地精减并节省出空间。
当你懂汇编后,才会知道C语言在何情况下浪费、节省空间,如此你当然就知道如何做了。
回复

使用道具 举报

ID:624769 发表于 2021-9-22 15:42 | 显示全部楼层
sadv 发表于 2021-9-22 13:53
感谢各位的回复,芯片是SQ013L,目前的代码里面已经非常精简了,所有的全局变量都是按位来定义的,使用了位 ...

只要是用C编写的,永远没资格说“非常”精简,全局变量,和和多所谓的局部变量,对程序大小是没有直接关联的,有关联的是放入 R0~R7 的变量,还是放入内存地址的变量,尤其是牵涉到计算,会对程序大小影响很大。然后避免只用一两次的子函数,直接囊括到主程序,也会有效的减小代码,调用一次子函数,就要有大量的 MOV R7,xxxx  以及返回后的 MOV xxxx, R7  这都是平白浪费空间的操作,以及可重入函数,不管有没有涉及到重入的操作,都会有很多的 PUSH 和 POP 代码。其实程序要缩小个20%左右,改汇编完全就能塞得下。
回复

使用道具 举报

ID:401564 发表于 2021-9-22 15:58 | 显示全部楼层
这玩意是仿(义隆(仿PIC汇编))指令的OTP单片机,也不知道是谁仿谁,反正是跟着PIC走的
内存只有1K,而且,是运行精简指令的,没有乘除法指令
所以,用C语言写的话:尽量不要用浮点型数据,尽量少用乘除法之类的高级运算
当然,最有效的办法就是用汇编来写,一般这种低端国产OTP单片机,有些公司会要求指定用汇编来写的
回复

使用道具 举报

ID:419909 发表于 2021-9-22 16:00 | 显示全部楼层
如果是用Keil的话。里面有一个代码优化级别的。你选最大。有时会省20%左右空间。但是会让你程序慢一些。这个看你自己决定
回复

使用道具 举报

ID:887202 发表于 2021-9-22 16:00 | 显示全部楼层
188610329 发表于 2021-9-22 15:42
只要是用C编写的,永远没资格说“非常”精简,全局变量,和和多所谓的局部变量,对程序大小是没有直接关 ...

不懂汇编,不过感觉你说的很有道理,对于您说的调用次数很少的子函数浪费空间的问题我也有做优化,目前卡在一行进行了多次移位和逻辑处理的语句上,加上这行语句程序大小增大很多就超出容量,单片机的RAM和ROM空间都很小,优化了好一段时间也塞不进去。
回复

使用道具 举报

ID:624769 发表于 2021-9-22 16:03 | 显示全部楼层
sadv 发表于 2021-9-22 16:00
不懂汇编,不过感觉你说的很有道理,对于您说的调用次数很少的子函数浪费空间的问题我也有做优化, ...

有些精度不高的中间量,比如本来 0-500, 缩小到 0-250,用1个字节,也是精简的一个方案,你可以参考一下。
回复

使用道具 举报

ID:887202 发表于 2021-9-22 16:06 | 显示全部楼层
Y_G_G 发表于 2021-9-22 15:58
这玩意是仿(义隆(仿PIC汇编))指令的OTP单片机,也不知道是谁仿谁,反正是跟着PIC走的
内存只有1K,而且,是运 ...

确实是想替代义隆的单片机才找到的SQ013L,运算方面没有用到浮点类型的数据,基本都是加减法和逻辑与或非的运算。这个代码只是一个demo,还有其他同事会在这个版本的基础上修改满足不同客户的需求,汇编的话大家都不会,改用汇编写就会比较麻烦。
回复

使用道具 举报

ID:887202 发表于 2021-9-22 16:08 | 显示全部楼层
wfqxgw 发表于 2021-9-22 16:00
如果是用Keil的话。里面有一个代码优化级别的。你选最大。有时会省20%左右空间。但是会让你程序慢一些。这 ...

是用的官方的开发环境,没有KEIL那么强大,而且优化效率不高,只能自己在代码上想办法
回复

使用道具 举报

ID:887202 发表于 2021-9-22 16:10 | 显示全部楼层
188610329 发表于 2021-9-22 16:03
有些精度不高的中间量,比如本来 0-500, 缩小到 0-250,用1个字节,也是精简的一个方案,你可以参考一下 ...

感谢,已经做过尝试,所有变量都是按位来定义的,也没有用到这么大的数据,8位就够用了
回复

使用道具 举报

ID:887202 发表于 2021-9-22 16:19 | 显示全部楼层
sadv 发表于 2021-9-22 13:53
感谢各位的回复,芯片是SQ013L,目前的代码里面已经非常精简了,所有的全局变量都是按位来定义的,使用了位 ...

感谢各位的回复,开发环境是芯片官方提供的,没有KEIL那么强大的功能,优化效率也比较低,我们在使用中甚至发现在函数中定义的临时变量会一直占用空间,退出函数后空间得不到释放的情况,导致本来就不多的资源更是捉襟见肘,为此只有定义两个全局在变量在各个子函数中做临时变量使用。为了节约资源所有的变量都是按位定义的,也尽量减少子函数的调用,此代码将会经过多位同事的手做一些修改给到不同客户,大家都不会汇编,暂不考虑用汇编写。
回复

使用道具 举报

ID:624769 发表于 2021-9-22 16:22 | 显示全部楼层
sadv 发表于 2021-9-22 16:10
感谢,已经做过尝试,所有变量都是按位来定义的,也没有用到这么大的数据,8位就够用了

那就在 子函数 不传参方面尝试。一旦子函数传参,就会多出很多 MOV  如果,引用的变量固定,返回的变量也固定,可以试试。
还有 如果程序有很多 位操作 的话,可以尝试用 unsigned char bdata   xxxx; 来定义字节变量,然后用 sbit 来定义每一个位, 那么在大量的,位定义的时候, 可以直接 用16进制数对字节统一定义,毕竟改写一个 字节 只需要 3个字节的程序, 改写一个位就要 2个字节程序,改写8个位就会需要16个字节程序,直接用字节方式改写,就能省下 13个字节的程序。再不行就尝试啃啃汇编了,我当初也是为了压缩压缩再压缩才学的汇编。用习惯后感觉在8位机编程来讲,个人开发,还是汇编用的更顺手。就算合作开发的话,也可以自己负责写底层,然后PUBLIC,对方extern 调用,这样混合编写也不错。
回复

使用道具 举报

ID:887202 发表于 2021-9-22 16:54 | 显示全部楼层
188610329 发表于 2021-9-22 16:22
那就在 子函数 不传参方面尝试。一旦子函数传参,就会多出很多 MOV  如果,引用的变量固定,返回的变量也 ...

函数不传参方面也已经优化过了,看了大家的说法感觉只有汇编才能解决了
回复

使用道具 举报

ID:668885 发表于 2021-9-22 17:25 | 显示全部楼层
小容量的单片机,要用汇编,尽量精简代码
回复

使用道具 举报

ID:592807 发表于 2021-9-22 17:35 | 显示全部楼层
尽量别用库,printf函数所在的库,直接占据8K
回复

使用道具 举报

ID:887202 发表于 2021-9-22 17:48 | 显示全部楼层
黄youhui 发表于 2021-9-22 17:35
尽量别用库,printf函数所在的库,直接占据8K

不敢不敢,一个字节都要精打细算的,不敢这么奢侈,根本就没用UART
回复

使用道具 举报

ID:887202 发表于 2021-9-22 17:48 | 显示全部楼层
oblivionqqqqq 发表于 2021-9-22 17:25
小容量的单片机,要用汇编,尽量精简代码

考虑中
回复

使用道具 举报

ID:401564 发表于 2021-9-22 17:54 | 显示全部楼层
sadv 发表于 2021-9-22 16:06
确实是想替代义隆的单片机才找到的SQ013L,运算方面没有用到浮点类型的数据,基本都是加减法和逻辑与或非 ...

24#也说,尽量别用的库,有库函数并不是一条语句那么简单的
在C语言编译器效率那么高,单片机片上资源越来越丰富的今天,汇编还有人在学,就说明汇编还是有一定作用的
函数调用不用程序空间的,主要是函数本身
1,全局变量和静态变量能不用就不用
2,库函数能少用就少用
3,函数内部的变量尽量用 unsigned char型,但这个在不同的编译环境下优化效果不一样,有的压根就没用,但也可以试一下
4,函数尽量少一点
回复

使用道具 举报

ID:824490 发表于 2021-9-22 19:49 | 显示全部楼层
1、少用静态数组 uchar code xxx[]={},少用全局标志。
2、for语句步进用减,不用加:for(a=8;a>0;a--),ASM指令有减一(为0)跳转,少有加一跳转(多了判断)
3、尽量不要多重调用,如:
    void a()调用void b();void b()又调用void C();void c()中又调用了void c().....(常见于各种显示函数)
4、不要同时开多个中断,每一个中断产生都会用到栈、都要保护现场。
5、短延时小于5个指令周期的尽量直接用空转NOP,调用延函数一进一出都费事。

  
  
回复

使用道具 举报

ID:155507 发表于 2021-9-22 19:51 | 显示全部楼层
芯圣SQ013L是一顆採用高速低功耗CMOS工藝設計開發的8位元高性能精簡指令單片機, 內部有1K*14位一次性可程式設計ROM(OTP-ROM),49*8位的資料記憶體(RAM),兩個雙向I/O口,1個8位Timer計時器/計數器。

最有效的办法就是用汇编来写
回复

使用道具 举报

ID:491577 发表于 2021-9-23 01:32 | 显示全部楼层
这个单片机多少钱一片?资源这么少
回复

使用道具 举报

ID:155507 发表于 2021-9-23 07:27 | 显示全部楼层
hhh402 发表于 2021-9-23 01:32
这个单片机多少钱一片?资源这么少

这个单片机一片 ¥0.13
回复

使用道具 举报

ID:359272 发表于 2021-9-23 08:00 | 显示全部楼层
我也在用一款资源一样的mcu,用C语言代码写不下,砍掉30%的功能,客户勉强接受了
回复

使用道具 举报

ID:592807 发表于 2021-9-23 08:30 | 显示全部楼层
hhh402 发表于 2021-9-23 01:32
这个单片机多少钱一片?资源这么少

STC11F04E   2块一片
回复

使用道具 举报

ID:146579 发表于 2021-9-23 09:15 | 显示全部楼层
1.使用汇编语言编写程序,自己安排存储空间。
回复

使用道具 举报

ID:146579 发表于 2021-9-23 09:16 | 显示全部楼层
1.使用汇编语言,合理安排存储空间
2.优化算法,减少代码量
回复

使用道具 举报

ID:887202 发表于 2021-9-23 10:28 | 显示全部楼层
slf252 发表于 2021-9-23 08:00
我也在用一款资源一样的mcu,用C语言代码写不下,砍掉30%的功能,客户勉强接受了

我们这是之前的MCU买不到了,给客户找替代品找到这个,本来功能不复杂,就是逻辑上的判断和比较特别多,再删功能就没意义了。
回复

使用道具 举报

ID:155507 发表于 2021-9-23 12:57 | 显示全部楼层
黄youhui 发表于 2021-9-23 08:30
STC11F04E   2块一片

2块, 可以买超过15片了
回复

使用道具 举报

ID:332444 发表于 2021-9-23 14:40 | 显示全部楼层
做个有趣的测试就知道C语言和汇编到底哪个能写出占有更小的程序,也能测试出哪个优化最好,之下复制一个提问.
通过按键SW2(连接在P2_0口)控制LED1~LED2的亮灭状态,要求如下: 1.系统上电后,LED1~LED2熄灭。 2.第一次按下SW2后,LED1点亮。 3.第二次按下SW2后,LED2点亮。 4.第三次按下SW2后,LED1熄灭。 5.第四次按下SW2后,LED2熄灭。 6.再次按下按键后,要求从步骤2开始进入新的控制周期。
回复

使用道具 举报

ID:332444 发表于 2021-9-23 15:05 | 显示全部楼层
本帖最后由 xianfajushi 于 2021-9-23 15:28 编辑

写了一个不用数组的用判断的

  1. unsigned char a=0;
  2. sbit k=P2^0;
  3. while(1)
  4. {
  5. if(!k)
  6. {
  7. ++a;
  8. while(!k);
  9. }
  10. if(a==1)P1=1;
  11. else if(a==2)P1=3;
  12. else if(a==3)P1=2;
  13. else {P1=a=0;}
  14. }
复制代码

Program Size: data=9.0 xdata=0 code=71
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表