标题: 小容量的单片机芯片怎么提高存储空间利用率? [打印本页]

作者: sadv    时间: 2021-9-22 11:12
标题: 小容量的单片机芯片怎么提高存储空间利用率?
如题,最近接触到一款存储空间非常小的单片机,代码量稍微大一点就用不了了,所以想问问大伙有没有提高存储空间利用率的办法

作者: hhdsdy    时间: 2021-9-22 12:02
用汇编吧
作者: devcang    时间: 2021-9-22 12:12
精简代码。。。
作者: npn    时间: 2021-9-22 12:19
具体是多少位,什么型号?
作者: lkc8210    时间: 2021-9-22 12:39
把代码贴上来看看
作者: guizaishi    时间: 2021-9-22 13:17
减少不必要的程序,特别是数组,能少定义就少定义,能不定义全局变量就不要全局。.h文件也不要随便定义,如果只用到printf而调用了 <stdio.h>,就不要用了
作者: zuiqf1978    时间: 2021-9-22 13:26
加24系列芯片,想加多大就多大!
作者: fj51hei    时间: 2021-9-22 13:37
guizaishi 发表于 2021-9-22 13:17
减少不必要的程序,特别是数组,能少定义就少定义,能不定义全局变量就不要全局。.h文件也不要随便定义,如 ...

实际局部变量也不见得小,要知道局部变量有生存周期,如果生存周期长了,没有及时销掉,跟全局有啥区别,甚至还不如全局
作者: 郑汉松    时间: 2021-9-22 13:48
经典的时间换空间的方法
作者: sadv    时间: 2021-9-22 13:53
感谢各位的回复,芯片是SQ013L,目前的代码里面已经非常精简了,所有的全局变量都是按位来定义的,使用了位域来定义全局变量,比较坑爹的就是,貌似官方的这个开发环境下临时变量使用完之后空间不会释放掉,还是会占用资源
作者: sadv    时间: 2021-9-22 13:53
npn 发表于 2021-9-22 12:19
具体是多少位,什么型号?

SQ013L
作者: yzwzfyz    时间: 2021-9-22 15:39
只有当你懂得汇编和单片机原理时,才能准确地精减并节省出空间。
当你懂汇编后,才会知道C语言在何情况下浪费、节省空间,如此你当然就知道如何做了。
作者: 188610329    时间: 2021-9-22 15:42
sadv 发表于 2021-9-22 13:53
感谢各位的回复,芯片是SQ013L,目前的代码里面已经非常精简了,所有的全局变量都是按位来定义的,使用了位 ...

只要是用C编写的,永远没资格说“非常”精简,全局变量,和和多所谓的局部变量,对程序大小是没有直接关联的,有关联的是放入 R0~R7 的变量,还是放入内存地址的变量,尤其是牵涉到计算,会对程序大小影响很大。然后避免只用一两次的子函数,直接囊括到主程序,也会有效的减小代码,调用一次子函数,就要有大量的 MOV R7,xxxx  以及返回后的 MOV xxxx, R7  这都是平白浪费空间的操作,以及可重入函数,不管有没有涉及到重入的操作,都会有很多的 PUSH 和 POP 代码。其实程序要缩小个20%左右,改汇编完全就能塞得下。
作者: Y_G_G    时间: 2021-9-22 15:58
这玩意是仿(义隆(仿PIC汇编))指令的OTP单片机,也不知道是谁仿谁,反正是跟着PIC走的
内存只有1K,而且,是运行精简指令的,没有乘除法指令
所以,用C语言写的话:尽量不要用浮点型数据,尽量少用乘除法之类的高级运算
当然,最有效的办法就是用汇编来写,一般这种低端国产OTP单片机,有些公司会要求指定用汇编来写的
作者: wfqxgw    时间: 2021-9-22 16:00
如果是用Keil的话。里面有一个代码优化级别的。你选最大。有时会省20%左右空间。但是会让你程序慢一些。这个看你自己决定
作者: sadv    时间: 2021-9-22 16:00
188610329 发表于 2021-9-22 15:42
只要是用C编写的,永远没资格说“非常”精简,全局变量,和和多所谓的局部变量,对程序大小是没有直接关 ...

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

有些精度不高的中间量,比如本来 0-500, 缩小到 0-250,用1个字节,也是精简的一个方案,你可以参考一下。
作者: sadv    时间: 2021-9-22 16:06
Y_G_G 发表于 2021-9-22 15:58
这玩意是仿(义隆(仿PIC汇编))指令的OTP单片机,也不知道是谁仿谁,反正是跟着PIC走的
内存只有1K,而且,是运 ...

确实是想替代义隆的单片机才找到的SQ013L,运算方面没有用到浮点类型的数据,基本都是加减法和逻辑与或非的运算。这个代码只是一个demo,还有其他同事会在这个版本的基础上修改满足不同客户的需求,汇编的话大家都不会,改用汇编写就会比较麻烦。
作者: sadv    时间: 2021-9-22 16:08
wfqxgw 发表于 2021-9-22 16:00
如果是用Keil的话。里面有一个代码优化级别的。你选最大。有时会省20%左右空间。但是会让你程序慢一些。这 ...

是用的官方的开发环境,没有KEIL那么强大,而且优化效率不高,只能自己在代码上想办法
作者: sadv    时间: 2021-9-22 16:10
188610329 发表于 2021-9-22 16:03
有些精度不高的中间量,比如本来 0-500, 缩小到 0-250,用1个字节,也是精简的一个方案,你可以参考一下 ...

感谢,已经做过尝试,所有变量都是按位来定义的,也没有用到这么大的数据,8位就够用了
作者: sadv    时间: 2021-9-22 16:19
sadv 发表于 2021-9-22 13:53
感谢各位的回复,芯片是SQ013L,目前的代码里面已经非常精简了,所有的全局变量都是按位来定义的,使用了位 ...

感谢各位的回复,开发环境是芯片官方提供的,没有KEIL那么强大的功能,优化效率也比较低,我们在使用中甚至发现在函数中定义的临时变量会一直占用空间,退出函数后空间得不到释放的情况,导致本来就不多的资源更是捉襟见肘,为此只有定义两个全局在变量在各个子函数中做临时变量使用。为了节约资源所有的变量都是按位定义的,也尽量减少子函数的调用,此代码将会经过多位同事的手做一些修改给到不同客户,大家都不会汇编,暂不考虑用汇编写。
作者: 188610329    时间: 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 调用,这样混合编写也不错。
作者: sadv    时间: 2021-9-22 16:54
188610329 发表于 2021-9-22 16:22
那就在 子函数 不传参方面尝试。一旦子函数传参,就会多出很多 MOV  如果,引用的变量固定,返回的变量也 ...

函数不传参方面也已经优化过了,看了大家的说法感觉只有汇编才能解决了
作者: oblivionqqqqq    时间: 2021-9-22 17:25
小容量的单片机,要用汇编,尽量精简代码
作者: 黄youhui    时间: 2021-9-22 17:35
尽量别用库,printf函数所在的库,直接占据8K
作者: sadv    时间: 2021-9-22 17:48
黄youhui 发表于 2021-9-22 17:35
尽量别用库,printf函数所在的库,直接占据8K

不敢不敢,一个字节都要精打细算的,不敢这么奢侈,根本就没用UART
作者: sadv    时间: 2021-9-22 17:48
oblivionqqqqq 发表于 2021-9-22 17:25
小容量的单片机,要用汇编,尽量精简代码

考虑中
作者: Y_G_G    时间: 2021-9-22 17:54
sadv 发表于 2021-9-22 16:06
确实是想替代义隆的单片机才找到的SQ013L,运算方面没有用到浮点类型的数据,基本都是加减法和逻辑与或非 ...

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

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

最有效的办法就是用汇编来写
作者: hhh402    时间: 2021-9-23 01:32
这个单片机多少钱一片?资源这么少
作者: angmall    时间: 2021-9-23 07:27
hhh402 发表于 2021-9-23 01:32
这个单片机多少钱一片?资源这么少

这个单片机一片 ¥0.13
作者: slf252    时间: 2021-9-23 08:00
我也在用一款资源一样的mcu,用C语言代码写不下,砍掉30%的功能,客户勉强接受了
作者: 黄youhui    时间: 2021-9-23 08:30
hhh402 发表于 2021-9-23 01:32
这个单片机多少钱一片?资源这么少

STC11F04E   2块一片
作者: wlg7705    时间: 2021-9-23 09:15
1.使用汇编语言编写程序,自己安排存储空间。
作者: wlg7705    时间: 2021-9-23 09:16
1.使用汇编语言,合理安排存储空间
2.优化算法,减少代码量
作者: sadv    时间: 2021-9-23 10:28
slf252 发表于 2021-9-23 08:00
我也在用一款资源一样的mcu,用C语言代码写不下,砍掉30%的功能,客户勉强接受了

我们这是之前的MCU买不到了,给客户找替代品找到这个,本来功能不复杂,就是逻辑上的判断和比较特别多,再删功能就没意义了。
作者: angmall    时间: 2021-9-23 12:57
黄youhui 发表于 2021-9-23 08:30
STC11F04E   2块一片

2块, 可以买超过15片了
作者: xianfajushi    时间: 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开始进入新的控制周期。
作者: xianfajushi    时间: 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
作者: 00云梦泽00    时间: 2021-9-23 15:35
这个需要和个人能力挂钩的   计算机原理、汇编缺一不可   用C代码精简不到最优  如果能用机器语言更好  
作者: sadv    时间: 2021-9-23 16:21
00云梦泽00 发表于 2021-9-23 15:35
这个需要和个人能力挂钩的   计算机原理、汇编缺一不可   用C代码精简不到最优  如果能用机器语言更好

入行半年的我有点吃不消啊
作者: shumivan    时间: 2021-9-23 17:14
不断优化自己的代码,拒绝冗余段
作者: 188610329    时间: 2021-9-23 19:42
sadv 发表于 2021-9-23 16:21
入行半年的我有点吃不消啊

基于,40楼的抛砖引玉…………
  1.                 K        BIT        P2.0

  2.                 CSEG        AT        0000H
  3. Start:           JB        K,Not_Press
  4.                    INC        A
  5.                    JNB        K,$
  6. Not_Press:    CJNE        A,#1,IF_2
  7.                    MOV        P1,#1
  8.                     AJMP        Start
  9. IF_2:            CJNE        A,#2,IF_3
  10.                     MOV        P1,#3
  11.                     AJMP        Start
  12. IF_3:             CJNE        A,#3,IF_x
  13.                     MOV        P1,#2
  14.                     AJMP        Start
  15. IF_x:             CLR        A
  16.                     MOV        P1,A
  17.                     AJMP        Start

  18. END
复制代码
Program Size: data=8.0 xdata=0 code=36
我把他的程序用,汇编写了一遍,你可以比较两者大小的差距。

作者: hhh402    时间: 2021-9-23 20:57
怎么便宜的单片机资源实在是不够用的话可以考虑用2片呀,
作者: 00云梦泽00    时间: 2021-9-23 21:32
sadv 发表于 2021-9-23 16:21
入行半年的我有点吃不消啊

师傅领进门  修行在个人  那只能选择高级点的单片机了   就不用考虑资源了

作者: Y_G_G    时间: 2021-9-24 10:44
188610329 发表于 2021-9-23 19:42
基于,40楼的抛砖引玉…………
Program Size: data=8.0 xdata=0 code=36
我把他的程序用,汇编写了一遍 ...

人家是PIC的汇编,不一样的
PIC有的汇编是没有比较的
MOV        P1,#1也是不行的,早先的PIC是不能这样的,不能直接对进行传送的,只能通过W(PIC的累加器,相当于A)进行传送
你这个在PIC是要这样:
MOV        A,#1
MOV        P1,A
PIC也没有比较相等的指令,只能通过减法进行比较
PIC也没有JNB这种指令,它只有条件跳过下一条指令,它只能跳过下一条指令,不能指定标号跳转.....
作者: wulin    时间: 2021-9-24 10:46
sadv 发表于 2021-9-22 13:53
SQ013L

这种极低价格的单片机只适用于对成本非常敏感且无安全等级要求的低附加值产品。楼主也不要指望用其开发什么高大上的玩意。真想玩就老老实实学汇编。
作者: 188610329    时间: 2021-9-24 15:24
Y_G_G 发表于 2021-9-24 10:44
人家是PIC的汇编,不一样的
PIC有的汇编是没有比较的
MOV        P1,#1也是不行的,早先的PIC是不能这样 ...

诚如 47楼所说, 这段代码只是让你看看 汇编 和 C 之间的程序大小差距,你好有个概念,正式编写的时候,下载由该单片机提供的 汇编码表,就算他是抄的PIC的汇编,也可能会增减部分代码, 比如WCH 的51系列 他就在51汇编的基础上,加了一条,补足了256条汇编指令。用起来更加舒服。你的SQ013L要是也有类似的增补,分分钟汇编比C还好用。




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1