找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 7037|回復(fù): 48
打印 上一主題 下一主題
收起左側(cè)

小容量的單片機(jī)芯片怎么提高存儲(chǔ)空間利用率?

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:887202 發(fā)表于 2021-9-22 11:12 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
如題,最近接觸到一款存儲(chǔ)空間非常小的單片機(jī),代碼量稍微大一點(diǎn)就用不了了,所以想問問大伙有沒有提高存儲(chǔ)空間利用率的辦法
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:88256 發(fā)表于 2021-9-22 12:02 | 只看該作者
用匯編吧
回復(fù)

使用道具 舉報(bào)

板凳
ID:277550 發(fā)表于 2021-9-22 12:12 | 只看該作者
精簡(jiǎn)代碼。。。
回復(fù)

使用道具 舉報(bào)

地板
ID:57657 發(fā)表于 2021-9-22 12:19 | 只看該作者
具體是多少位,什么型號(hào)?
回復(fù)

使用道具 舉報(bào)

5#
ID:161164 發(fā)表于 2021-9-22 12:39 | 只看該作者
把代碼貼上來看看
回復(fù)

使用道具 舉報(bào)

6#
ID:90613 發(fā)表于 2021-9-22 13:17 | 只看該作者
減少不必要的程序,特別是數(shù)組,能少定義就少定義,能不定義全局變量就不要全局。.h文件也不要隨便定義,如果只用到printf而調(diào)用了 <stdio.h>,就不要用了
回復(fù)

使用道具 舉報(bào)

7#
ID:366464 發(fā)表于 2021-9-22 13:26 | 只看該作者
加24系列芯片,想加多大就多大!
回復(fù)

使用道具 舉報(bào)

8#
ID:712493 發(fā)表于 2021-9-22 13:37 | 只看該作者
guizaishi 發(fā)表于 2021-9-22 13:17
減少不必要的程序,特別是數(shù)組,能少定義就少定義,能不定義全局變量就不要全局。.h文件也不要隨便定義,如 ...

實(shí)際局部變量也不見得小,要知道局部變量有生存周期,如果生存周期長(zhǎng)了,沒有及時(shí)銷掉,跟全局有啥區(qū)別,甚至還不如全局
回復(fù)

使用道具 舉報(bào)

9#
ID:514901 發(fā)表于 2021-9-22 13:48 | 只看該作者
經(jīng)典的時(shí)間換空間的方法
回復(fù)

使用道具 舉報(bào)

10#
ID:887202 發(fā)表于 2021-9-22 13:53 | 只看該作者
感謝各位的回復(fù),芯片是SQ013L,目前的代碼里面已經(jīng)非常精簡(jiǎn)了,所有的全局變量都是按位來定義的,使用了位域來定義全局變量,比較坑爹的就是,貌似官方的這個(gè)開發(fā)環(huán)境下臨時(shí)變量使用完之后空間不會(huì)釋放掉,還是會(huì)占用資源
回復(fù)

使用道具 舉報(bào)

11#
ID:887202 發(fā)表于 2021-9-22 13:53 | 只看該作者
npn 發(fā)表于 2021-9-22 12:19
具體是多少位,什么型號(hào)?

SQ013L
回復(fù)

使用道具 舉報(bào)

12#
ID:123289 發(fā)表于 2021-9-22 15:39 | 只看該作者
只有當(dāng)你懂得匯編和單片機(jī)原理時(shí),才能準(zhǔn)確地精減并節(jié)省出空間。
當(dāng)你懂匯編后,才會(huì)知道C語言在何情況下浪費(fèi)、節(jié)省空間,如此你當(dāng)然就知道如何做了。
回復(fù)

使用道具 舉報(bào)

13#
ID:624769 發(fā)表于 2021-9-22 15:42 | 只看該作者
sadv 發(fā)表于 2021-9-22 13:53
感謝各位的回復(fù),芯片是SQ013L,目前的代碼里面已經(jīng)非常精簡(jiǎn)了,所有的全局變量都是按位來定義的,使用了位 ...

只要是用C編寫的,永遠(yuǎn)沒資格說“非!本(jiǎn),全局變量,和和多所謂的局部變量,對(duì)程序大小是沒有直接關(guān)聯(lián)的,有關(guān)聯(lián)的是放入 R0~R7 的變量,還是放入內(nèi)存地址的變量,尤其是牽涉到計(jì)算,會(huì)對(duì)程序大小影響很大。然后避免只用一兩次的子函數(shù),直接囊括到主程序,也會(huì)有效的減小代碼,調(diào)用一次子函數(shù),就要有大量的 MOV R7,xxxx  以及返回后的 MOV xxxx, R7  這都是平白浪費(fèi)空間的操作,以及可重入函數(shù),不管有沒有涉及到重入的操作,都會(huì)有很多的 PUSH 和 POP 代碼。其實(shí)程序要縮小個(gè)20%左右,改匯編完全就能塞得下。
回復(fù)

使用道具 舉報(bào)

14#
ID:401564 發(fā)表于 2021-9-22 15:58 | 只看該作者
這玩意是仿(義隆(仿PIC匯編))指令的OTP單片機(jī),也不知道是誰仿誰,反正是跟著PIC走的
內(nèi)存只有1K,而且,是運(yùn)行精簡(jiǎn)指令的,沒有乘除法指令
所以,用C語言寫的話:盡量不要用浮點(diǎn)型數(shù)據(jù),盡量少用乘除法之類的高級(jí)運(yùn)算
當(dāng)然,最有效的辦法就是用匯編來寫,一般這種低端國(guó)產(chǎn)OTP單片機(jī),有些公司會(huì)要求指定用匯編來寫的
回復(fù)

使用道具 舉報(bào)

15#
ID:419909 發(fā)表于 2021-9-22 16:00 | 只看該作者
如果是用Keil的話。里面有一個(gè)代碼優(yōu)化級(jí)別的。你選最大。有時(shí)會(huì)省20%左右空間。但是會(huì)讓你程序慢一些。這個(gè)看你自己決定
回復(fù)

使用道具 舉報(bào)

16#
ID:887202 發(fā)表于 2021-9-22 16:00 | 只看該作者
188610329 發(fā)表于 2021-9-22 15:42
只要是用C編寫的,永遠(yuǎn)沒資格說“非!本(jiǎn),全局變量,和和多所謂的局部變量,對(duì)程序大小是沒有直接關(guān) ...

不懂匯編,不過感覺你說的很有道理,對(duì)于您說的調(diào)用次數(shù)很少的子函數(shù)浪費(fèi)空間的問題我也有做優(yōu)化,目前卡在一行進(jìn)行了多次移位和邏輯處理的語句上,加上這行語句程序大小增大很多就超出容量,單片機(jī)的RAM和ROM空間都很小,優(yōu)化了好一段時(shí)間也塞不進(jìn)去。
回復(fù)

使用道具 舉報(bào)

17#
ID:624769 發(fā)表于 2021-9-22 16:03 | 只看該作者
sadv 發(fā)表于 2021-9-22 16:00
不懂匯編,不過感覺你說的很有道理,對(duì)于您說的調(diào)用次數(shù)很少的子函數(shù)浪費(fèi)空間的問題我也有做優(yōu)化, ...

有些精度不高的中間量,比如本來 0-500, 縮小到 0-250,用1個(gè)字節(jié),也是精簡(jiǎn)的一個(gè)方案,你可以參考一下。
回復(fù)

使用道具 舉報(bào)

18#
ID:887202 發(fā)表于 2021-9-22 16:06 | 只看該作者
Y_G_G 發(fā)表于 2021-9-22 15:58
這玩意是仿(義隆(仿PIC匯編))指令的OTP單片機(jī),也不知道是誰仿誰,反正是跟著PIC走的
內(nèi)存只有1K,而且,是運(yùn) ...

確實(shí)是想替代義隆的單片機(jī)才找到的SQ013L,運(yùn)算方面沒有用到浮點(diǎn)類型的數(shù)據(jù),基本都是加減法和邏輯與或非的運(yùn)算。這個(gè)代碼只是一個(gè)demo,還有其他同事會(huì)在這個(gè)版本的基礎(chǔ)上修改滿足不同客戶的需求,匯編的話大家都不會(huì),改用匯編寫就會(huì)比較麻煩。
回復(fù)

使用道具 舉報(bào)

19#
ID:887202 發(fā)表于 2021-9-22 16:08 | 只看該作者
wfqxgw 發(fā)表于 2021-9-22 16:00
如果是用Keil的話。里面有一個(gè)代碼優(yōu)化級(jí)別的。你選最大。有時(shí)會(huì)省20%左右空間。但是會(huì)讓你程序慢一些。這 ...

是用的官方的開發(fā)環(huán)境,沒有KEIL那么強(qiáng)大,而且優(yōu)化效率不高,只能自己在代碼上想辦法
回復(fù)

使用道具 舉報(bào)

20#
ID:887202 發(fā)表于 2021-9-22 16:10 | 只看該作者
188610329 發(fā)表于 2021-9-22 16:03
有些精度不高的中間量,比如本來 0-500, 縮小到 0-250,用1個(gè)字節(jié),也是精簡(jiǎn)的一個(gè)方案,你可以參考一下 ...

感謝,已經(jīng)做過嘗試,所有變量都是按位來定義的,也沒有用到這么大的數(shù)據(jù),8位就夠用了
回復(fù)

使用道具 舉報(bào)

21#
ID:887202 發(fā)表于 2021-9-22 16:19 | 只看該作者
sadv 發(fā)表于 2021-9-22 13:53
感謝各位的回復(fù),芯片是SQ013L,目前的代碼里面已經(jīng)非常精簡(jiǎn)了,所有的全局變量都是按位來定義的,使用了位 ...

感謝各位的回復(fù),開發(fā)環(huán)境是芯片官方提供的,沒有KEIL那么強(qiáng)大的功能,優(yōu)化效率也比較低,我們?cè)谑褂弥猩踔涟l(fā)現(xiàn)在函數(shù)中定義的臨時(shí)變量會(huì)一直占用空間,退出函數(shù)后空間得不到釋放的情況,導(dǎo)致本來就不多的資源更是捉襟見肘,為此只有定義兩個(gè)全局在變量在各個(gè)子函數(shù)中做臨時(shí)變量使用。為了節(jié)約資源所有的變量都是按位定義的,也盡量減少子函數(shù)的調(diào)用,此代碼將會(huì)經(jīng)過多位同事的手做一些修改給到不同客戶,大家都不會(huì)匯編,暫不考慮用匯編寫。
回復(fù)

使用道具 舉報(bào)

22#
ID:624769 發(fā)表于 2021-9-22 16:22 | 只看該作者
sadv 發(fā)表于 2021-9-22 16:10
感謝,已經(jīng)做過嘗試,所有變量都是按位來定義的,也沒有用到這么大的數(shù)據(jù),8位就夠用了

那就在 子函數(shù) 不傳參方面嘗試。一旦子函數(shù)傳參,就會(huì)多出很多 MOV  如果,引用的變量固定,返回的變量也固定,可以試試。
還有 如果程序有很多 位操作 的話,可以嘗試用 unsigned char bdata   xxxx; 來定義字節(jié)變量,然后用 sbit 來定義每一個(gè)位, 那么在大量的,位定義的時(shí)候, 可以直接 用16進(jìn)制數(shù)對(duì)字節(jié)統(tǒng)一定義,畢竟改寫一個(gè) 字節(jié) 只需要 3個(gè)字節(jié)的程序, 改寫一個(gè)位就要 2個(gè)字節(jié)程序,改寫8個(gè)位就會(huì)需要16個(gè)字節(jié)程序,直接用字節(jié)方式改寫,就能省下 13個(gè)字節(jié)的程序。再不行就嘗試啃啃匯編了,我當(dāng)初也是為了壓縮壓縮再壓縮才學(xué)的匯編。用習(xí)慣后感覺在8位機(jī)編程來講,個(gè)人開發(fā),還是匯編用的更順手。就算合作開發(fā)的話,也可以自己負(fù)責(zé)寫底層,然后PUBLIC,對(duì)方extern 調(diào)用,這樣混合編寫也不錯(cuò)。
回復(fù)

使用道具 舉報(bào)

23#
ID:887202 發(fā)表于 2021-9-22 16:54 | 只看該作者
188610329 發(fā)表于 2021-9-22 16:22
那就在 子函數(shù) 不傳參方面嘗試。一旦子函數(shù)傳參,就會(huì)多出很多 MOV  如果,引用的變量固定,返回的變量也 ...

函數(shù)不傳參方面也已經(jīng)優(yōu)化過了,看了大家的說法感覺只有匯編才能解決了
回復(fù)

使用道具 舉報(bào)

24#
ID:668885 發(fā)表于 2021-9-22 17:25 | 只看該作者
小容量的單片機(jī),要用匯編,盡量精簡(jiǎn)代碼
回復(fù)

使用道具 舉報(bào)

25#
ID:592807 發(fā)表于 2021-9-22 17:35 | 只看該作者
盡量別用庫,printf函數(shù)所在的庫,直接占據(jù)8K
回復(fù)

使用道具 舉報(bào)

26#
ID:887202 發(fā)表于 2021-9-22 17:48 | 只看該作者
黃youhui 發(fā)表于 2021-9-22 17:35
盡量別用庫,printf函數(shù)所在的庫,直接占據(jù)8K

不敢不敢,一個(gè)字節(jié)都要精打細(xì)算的,不敢這么奢侈,根本就沒用UART
回復(fù)

使用道具 舉報(bào)

27#
ID:887202 發(fā)表于 2021-9-22 17:48 | 只看該作者
oblivionqqqqq 發(fā)表于 2021-9-22 17:25
小容量的單片機(jī),要用匯編,盡量精簡(jiǎn)代碼

考慮中
回復(fù)

使用道具 舉報(bào)

28#
ID:401564 發(fā)表于 2021-9-22 17:54 | 只看該作者
sadv 發(fā)表于 2021-9-22 16:06
確實(shí)是想替代義隆的單片機(jī)才找到的SQ013L,運(yùn)算方面沒有用到浮點(diǎn)類型的數(shù)據(jù),基本都是加減法和邏輯與或非 ...

24#也說,盡量別用的庫,有庫函數(shù)并不是一條語句那么簡(jiǎn)單的
在C語言編譯器效率那么高,單片機(jī)片上資源越來越豐富的今天,匯編還有人在學(xué),就說明匯編還是有一定作用的
函數(shù)調(diào)用不用程序空間的,主要是函數(shù)本身
1,全局變量和靜態(tài)變量能不用就不用
2,庫函數(shù)能少用就少用
3,函數(shù)內(nèi)部的變量盡量用 unsigned char型,但這個(gè)在不同的編譯環(huán)境下優(yōu)化效果不一樣,有的壓根就沒用,但也可以試一下
4,函數(shù)盡量少一點(diǎn)
回復(fù)

使用道具 舉報(bào)

29#
ID:824490 發(fā)表于 2021-9-22 19:49 | 只看該作者
1、少用靜態(tài)數(shù)組 uchar code xxx[]={},少用全局標(biāo)志。
2、for語句步進(jìn)用減,不用加:for(a=8;a>0;a--),ASM指令有減一(為0)跳轉(zhuǎn),少有加一跳轉(zhuǎn)(多了判斷)
3、盡量不要多重調(diào)用,如:
    void a()調(diào)用void b();void b()又調(diào)用void C();void c()中又調(diào)用了void c().....(常見于各種顯示函數(shù))
4、不要同時(shí)開多個(gè)中斷,每一個(gè)中斷產(chǎn)生都會(huì)用到棧、都要保護(hù)現(xiàn)場(chǎng)。
5、短延時(shí)小于5個(gè)指令周期的盡量直接用空轉(zhuǎn)NOP,調(diào)用延函數(shù)一進(jìn)一出都費(fèi)事。

  
  
回復(fù)

使用道具 舉報(bào)

30#
ID:155507 發(fā)表于 2021-9-22 19:51 | 只看該作者
芯圣SQ013L是一顆採用高速低功耗CMOS工藝設(shè)計(jì)開發(fā)的8位元高性能精簡(jiǎn)指令單片機(jī), 內(nèi)部有1K*14位一次性可程式設(shè)計(jì)ROM(OTP-ROM),49*8位的資料記憶體(RAM),兩個(gè)雙向I/O口,1個(gè)8位Timer計(jì)時(shí)器/計(jì)數(shù)器。

最有效的辦法就是用匯編來寫
回復(fù)

使用道具 舉報(bào)

31#
ID:491577 發(fā)表于 2021-9-23 01:32 | 只看該作者
這個(gè)單片機(jī)多少錢一片?資源這么少
回復(fù)

使用道具 舉報(bào)

32#
ID:155507 發(fā)表于 2021-9-23 07:27 | 只看該作者
hhh402 發(fā)表于 2021-9-23 01:32
這個(gè)單片機(jī)多少錢一片?資源這么少

這個(gè)單片機(jī)一片 ¥0.13
回復(fù)

使用道具 舉報(bào)

33#
ID:359272 發(fā)表于 2021-9-23 08:00 | 只看該作者
我也在用一款資源一樣的mcu,用C語言代碼寫不下,砍掉30%的功能,客戶勉強(qiáng)接受了
回復(fù)

使用道具 舉報(bào)

34#
ID:592807 發(fā)表于 2021-9-23 08:30 | 只看該作者
hhh402 發(fā)表于 2021-9-23 01:32
這個(gè)單片機(jī)多少錢一片?資源這么少

STC11F04E   2塊一片
回復(fù)

使用道具 舉報(bào)

35#
ID:146579 發(fā)表于 2021-9-23 09:15 | 只看該作者
1.使用匯編語言編寫程序,自己安排存儲(chǔ)空間。
回復(fù)

使用道具 舉報(bào)

36#
ID:146579 發(fā)表于 2021-9-23 09:16 | 只看該作者
1.使用匯編語言,合理安排存儲(chǔ)空間
2.優(yōu)化算法,減少代碼量
回復(fù)

使用道具 舉報(bào)

37#
ID:887202 發(fā)表于 2021-9-23 10:28 | 只看該作者
slf252 發(fā)表于 2021-9-23 08:00
我也在用一款資源一樣的mcu,用C語言代碼寫不下,砍掉30%的功能,客戶勉強(qiáng)接受了

我們這是之前的MCU買不到了,給客戶找替代品找到這個(gè),本來功能不復(fù)雜,就是邏輯上的判斷和比較特別多,再刪功能就沒意義了。
回復(fù)

使用道具 舉報(bào)

38#
ID:155507 發(fā)表于 2021-9-23 12:57 | 只看該作者

2塊, 可以買超過15片了
回復(fù)

使用道具 舉報(bào)

39#
ID:332444 發(fā)表于 2021-9-23 14:40 | 只看該作者
做個(gè)有趣的測(cè)試就知道C語言和匯編到底哪個(gè)能寫出占有更小的程序,也能測(cè)試出哪個(gè)優(yōu)化最好,之下復(fù)制一個(gè)提問.
通過按鍵SW2(連接在P2_0口)控制LED1~LED2的亮滅狀態(tài),要求如下: 1.系統(tǒng)上電后,LED1~LED2熄滅。 2.第一次按下SW2后,LED1點(diǎn)亮。 3.第二次按下SW2后,LED2點(diǎn)亮。 4.第三次按下SW2后,LED1熄滅。 5.第四次按下SW2后,LED2熄滅。 6.再次按下按鍵后,要求從步驟2開始進(jìn)入新的控制周期。
回復(fù)

使用道具 舉報(bào)

40#
ID:332444 發(fā)表于 2021-9-23 15:05 | 只看該作者
本帖最后由 xianfajushi 于 2021-9-23 15:28 編輯

寫了一個(gè)不用數(shù)組的用判斷的

  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. }
復(fù)制代碼

Program Size: data=9.0 xdata=0 code=71
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表