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

QQ登錄

只需一步,快速開始

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

請(qǐng)教C語(yǔ)言四位數(shù)拆出每一位的問題

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:47286 發(fā)表于 2021-12-5 12:47 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
最近弄個(gè)東西 需要把3位或者4位數(shù)的每一位拆出來 比如1234拆成1,2,3,4 過去 我學(xué)會(huì)的 就是求余求模 一位一位的算 據(jù)說乘除法在51片子上消耗時(shí)間比較多 那么 假設(shè)偏執(zhí)的只想減少計(jì)算時(shí)間 請(qǐng)教有什么其它方法嗎
很久以前記得就此問題請(qǐng)教過一位前輩 那位前輩的說法 第一 C51里沒什么好方法 基本就只能這么算 第二 他提出個(gè)移位的方法 但我沒太明白 而且我嘗試了一下 移位也不是特別簡(jiǎn)單的算法 比如1變成100并不是只要移位就行

我目前用的是笨方法 建立個(gè)四維數(shù)組 uchar code wei[4][256]={} 后邊是4組256位對(duì)應(yīng)值 使用的時(shí)候

qian=wei[0][x];
bai=wei[1][x];
shi=wei[2][x];
ge=wei[3][x];

我自認(rèn)為這樣比每一位求余求模快 是么

這樣也有問題 占用空間太大了 過百就要用int 這還是個(gè)8位ADC轉(zhuǎn)位 如果10位 那每個(gè)數(shù)組就的4*1024 而且每種數(shù)據(jù)的對(duì)應(yīng)值是不一樣的 比如電壓 電流 轉(zhuǎn)速三個(gè)采集的值要轉(zhuǎn)成單獨(dú)的位再發(fā)出去 就需要3個(gè)表 呃。。。。。。這么算 code表比程序都大了
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:624769 發(fā)表于 2021-12-5 15:11 | 只看該作者
建表思路不對(duì), 你想一個(gè)表全都出來, 就會(huì)發(fā)現(xiàn)表的大小不是你能接受的. 做這東西要循序漸進(jìn), 一點(diǎn)點(diǎn)地遞增。 先做出2位數(shù)的表,一般這個(gè)表我們稱之為BCD表, 把 0~99 對(duì)應(yīng)到 0x00~0x99 , 這樣你就能輕松的把一個(gè) 0~99 的char 轉(zhuǎn)成BCD碼,然后 高四位是一個(gè)0~9 低4位是一個(gè) 0~9 , 這樣一個(gè)表只有 100字節(jié)。

然后,你只需要把 0~9999 的雙字節(jié) 拆成 2個(gè) 0~99 的單字節(jié)就能直接套用上表了。
這時(shí)候建表思路就很重要了。
一種是針對(duì)高8位,和低8位分別建表,表面上看,查表時(shí)輕松一點(diǎn),但是查表后合并工作量會(huì)變大。
由于0~9999 轉(zhuǎn)成2進(jìn)制是沒有16位長(zhǎng)度的,總共只有14位長(zhǎng)度,所以最高2位是不需要考慮的,
所以,我的做法是, 取低6位(0~5位)做為新的低8位,和。6~13位)做為新的高8位,新的低8位(0~63 小于99)不需要查表,新的高8位查表得出  最終用于查表的 千百位, 和個(gè)十位,個(gè)十位和前面分割的新低8位合并,然后查詢前面作出來的 BCD表 得到你所需要的每一位即可。
這種做法,查表前麻煩點(diǎn),查表中后期工作量會(huì)少很多。你自己看著搞吧。
這樣做出復(fù)合表 表的總體大小 600字節(jié)左右。就沒有什么所謂了。

這問題吧,不適合問,你要問,大多數(shù)人都是跟你講 51 沒前途,去玩STM吧之類的,要么就是跟你說換1T的單片機(jī),不在乎這些,包括我,都想跟你說你要是用 STC8系列的話,也是51核,但是帶16位乘除法器,完全不用考慮乘除法效率問題。
也就以前自己做過查表,那么跟你說說這表的思路, 但是有一點(diǎn),用這種復(fù)合查表方式,你用匯編的話,效率卻是提高很多,用C的話,最終比除法取模也就提高各3~4倍左右效率,不是很明顯。自己衡量

評(píng)分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

板凳
ID:988145 發(fā)表于 2021-12-5 15:34 | 只看該作者
  1. unsigned int number=0;
  2. //千位
  3. number|=0x1;
  4. number<<=4;
  5. //百位
  6. number|=0x2;
  7. number<<=4;
  8. //十位
  9. number|=0x3;
  10. number<<=4;
  11. //各位
  12. number|=0x4;
  13. number<<=4;
復(fù)制代碼

用二進(jìn)制來存儲(chǔ)數(shù)字的話每四位可以存儲(chǔ)0-15,那么用一個(gè)unsigned int(2byte拆成4個(gè)bit)就可以存儲(chǔ)四位,比如1234就可以是0001 0010 0011 0100,但我也不知道你具體是要干什么,我就假設(shè)你是按位輸入然后儲(chǔ)存下來,那么代碼就可以是類似以上

評(píng)分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

地板
ID:47286 發(fā)表于 2021-12-5 16:51 | 只看該作者
先謝過 沙發(fā) 和 板凳 兩位前輩

有些是我沒說清 這并不是有什么不能說的 我就是個(gè)基于應(yīng)用寫程序 對(duì)基礎(chǔ)了解很少 問問題可能就問不到點(diǎn)上

轉(zhuǎn)換這個(gè)是為了給串口屏發(fā)數(shù)據(jù) 我用的這款只接受文本 就是說 不管屏幕以什么格式展現(xiàn)數(shù)字 發(fā)送給屏幕的時(shí)候都需要以文本格式 123就是0x31 0x32 0x33 這種情況下 我想了半天 好象不能用BCD碼

因?yàn)槲覍懙陌l(fā)送函數(shù)是進(jìn)入循環(huán)發(fā)送后 分別調(diào)用 發(fā)送電壓 發(fā)送電流 發(fā)送轉(zhuǎn)速3個(gè)子函數(shù) 每個(gè)函數(shù)里又把當(dāng)前ADC和中斷采集的值轉(zhuǎn)換成文本 那么 假設(shè)每個(gè)數(shù)值都是4位 電壓是1200v(12.00v避免浮點(diǎn)運(yùn)算) 電流是1000mA 轉(zhuǎn)速是2000轉(zhuǎn) 就是術(shù)哦每個(gè)都要求模求余4位

STM32干這個(gè)非常輕松 但我覺得浪費(fèi) 實(shí)際上演示部分是屏幕去完成 控制板只采集個(gè)電流 交互一下 控制電機(jī)起停 就這么點(diǎn)事 不是用不起也不是不能用 可能是一種偏執(zhí)吧 那假設(shè)我用PC+C干這點(diǎn)事 不是也行么

我用的片子是15系的 也是1T模式 但因?yàn)椴皇?系 沒有乘除法器
回復(fù)

使用道具 舉報(bào)

5#
ID:47286 發(fā)表于 2021-12-5 16:55 | 只看該作者
188610329 發(fā)表于 2021-12-5 15:11
建表思路不對(duì), 你想一個(gè)表全都出來, 就會(huì)發(fā)現(xiàn)表的大小不是你能接受的. 做這東西要循序漸進(jìn), 一點(diǎn)點(diǎn)地遞增。 ...

感謝你的回復(fù) 講的很清楚

你的思路 我需要再研究一下 畢竟水平不夠 理解的慢 但大蓋意思我明白了 是我問題描述的不夠清楚 我這情況不能用BCD碼

你說的用STM 或者8系啥的 我也接受 實(shí)際搞也可以的 僅僅就事論事 在這個(gè)范疇內(nèi)討論一下 有閑時(shí) 有興趣就回下即可

再次感謝
回復(fù)

使用道具 舉報(bào)

6#
ID:47286 發(fā)表于 2021-12-5 17:02 | 只看該作者
會(huì)會(huì)會(huì)不會(huì) 發(fā)表于 2021-12-5 15:34
用二進(jìn)制來存儲(chǔ)數(shù)字的話每四位可以存儲(chǔ)0-15,那么用一個(gè)unsigned int(2byte拆成4個(gè)bit)就可以存儲(chǔ)四位 ...

感謝你的回復(fù) 你的范例我看懂了 理解你的意思

我水平有限 先研究一下你的方法 稍候回復(fù)
回復(fù)

使用道具 舉報(bào)

7#
ID:624769 發(fā)表于 2021-12-5 17:37 | 只看該作者
dzbj 發(fā)表于 2021-12-5 16:55
感謝你的回復(fù) 講的很清楚

你的思路 我需要再研究一下 畢竟水平不夠 理解的慢 但大蓋意思我明白了 是我 ...

不不不,
基準(zhǔn),要按照 BCD碼考慮,不然反而更麻煩,
按你的需求,現(xiàn)轉(zhuǎn)BCD是必要的。

你先按BCD碼方式搞, 假定,算出 十位和個(gè)位, BCD 碼 Temp_Low = 0x39  也就是十進(jìn)制39,
發(fā)的時(shí)候:  
( (Temp_low & 0x0f)  | 0x30)  就是個(gè)位的  文本
( (Temp_low >> 4)  | 0x30)  就是十位的  文本
這個(gè)操作消耗資源極低, 如果你在源頭就要弄成 文本 反而消耗資源極高, 相信我。
回復(fù)

使用道具 舉報(bào)

8#
ID:47286 發(fā)表于 2021-12-5 20:19 | 只看該作者
188610329 發(fā)表于 2021-12-5 17:37
不不不,
基準(zhǔn),要按照 BCD碼考慮,不然反而更麻煩,
按你的需求,現(xiàn)轉(zhuǎn)BCD是必要的。

你的意思是用查表法把HEX轉(zhuǎn)BCD 然后用你說的移位法把BCD轉(zhuǎn)文本 是嗎

如果是 可能是個(gè)好辦法 我現(xiàn)在做表試試
回復(fù)

使用道具 舉報(bào)

9#
ID:401564 發(fā)表于 2021-12-5 20:53 | 只看該作者
消耗時(shí)間比較多
我敢打賭,很少有人把單片機(jī)消耗到慢下來的地步
除非是故意的,或者是在uS級(jí)別中斷中加入計(jì)算
否則,在很多時(shí)候,是不需要考慮單片機(jī)運(yùn)算速度的,因?yàn)?單片機(jī)單單依靠軟件去計(jì)算本身就很慢,在很多時(shí)候是不需要單片機(jī)很快的,要它快的時(shí)候,自然有對(duì)應(yīng)的處理辦法,比如增加片上的硬件加法器,或者硬件乘法器
而對(duì)于發(fā)送到串口,很多時(shí)候是不能用BCD碼的,這一點(diǎn)很重要,大多時(shí)候是要發(fā)送ASCII碼的
因?yàn)?發(fā)送數(shù)據(jù)或者BCD碼,都有可能出現(xiàn)'\0',也就是0x00,這是C語(yǔ)言中的字符串結(jié)束,有一些函數(shù)碰到結(jié)束符就會(huì)結(jié)束處理,這樣就容易出錯(cuò)了,因?yàn)?發(fā)送的是0x00這個(gè)是數(shù)據(jù),但上位機(jī)覺得你發(fā)的是結(jié)束符,提前收工了
就算是上位機(jī)給單片機(jī)發(fā)送數(shù)據(jù),一般都不會(huì)直接發(fā)送,大多是發(fā)送ASCII或者字符串,很少有直接心頭數(shù)據(jù),除非很有必要
回復(fù)

使用道具 舉報(bào)

10#
ID:47286 發(fā)表于 2021-12-5 21:26 | 只看該作者
188610329 發(fā)表于 2021-12-5 17:37
不不不,
基準(zhǔn),要按照 BCD碼考慮,不然反而更麻煩,
按你的需求,現(xiàn)轉(zhuǎn)BCD是必要的。

按照之前說的嘗試了 成功 code的量縮小一半 原來是四組char 每組256個(gè) 現(xiàn)在是一組int 也是256個(gè)

用電流做的測(cè)試 電流采集的方法是10mΩ采樣電阻 INA181 這東西出來的電壓對(duì)應(yīng)當(dāng)時(shí)電流

用excel把ADC采集的值轉(zhuǎn)換成對(duì)應(yīng)的電流 然后把這個(gè)值轉(zhuǎn)成整數(shù)的十進(jìn)制 再轉(zhuǎn)成BCD 導(dǎo)出成Keil的code

發(fā)送時(shí) 用當(dāng)時(shí)的ADC值(HEX)對(duì)應(yīng)code表位值(BCD) 等于把當(dāng)時(shí)的ADC采集HEX值直接轉(zhuǎn)成實(shí)際電流值 再分別右移 拆出具體的千 百 十 個(gè)位
回復(fù)

使用道具 舉報(bào)

11#
ID:47286 發(fā)表于 2021-12-5 23:50 | 只看該作者
Y_G_G 發(fā)表于 2021-12-5 20:53
消耗時(shí)間比較多
我敢打賭,很少有人把單片機(jī)消耗到慢下來的地步
除非是故意的,或者是在uS級(jí)別中斷中加入計(jì) ...

是的 單獨(dú)干一件事 確實(shí)如你所說 只是我在一個(gè)系統(tǒng)上干的事多 反正每次搞個(gè)東西 不給所有腳都用上就覺得虧 事情多了綜合處理 還是會(huì)有影響的 我相信一句話 每一步都追求完美 結(jié)果才會(huì)完美 受水平限制 我只能每一步都追求完美 讓結(jié)果盡量接近完美吧
回復(fù)

使用道具 舉報(bào)

12#
ID:624769 發(fā)表于 2021-12-6 00:15 | 只看該作者
dzbj 發(fā)表于 2021-12-5 23:50
是的 單獨(dú)干一件事 確實(shí)如你所說 只是我在一個(gè)系統(tǒng)上干的事多 反正每次搞個(gè)東西 不給所有腳都用上就覺得 ...

多的不說了,有興趣的話,看看這個(gè)吧,不需要數(shù)組的提高效率解析法。代碼大小也比常規(guī)的小。個(gè)人認(rèn)為,這樣就差不多了,畢竟,我后來也放棄數(shù)組法了。(雖然數(shù)組法是最高效的,有空再和你說原因)

在89C51,12Mhz 晶振下測(cè)試:
常規(guī)取模算法轉(zhuǎn)ASCII, 用時(shí)640us, 在Test_C 中
用我的算法,用時(shí)102us,在Test_A 中

如用1T單片機(jī)效率可以更高。

Test_Code.rar (861.79 KB, 下載次數(shù): 7)



回復(fù)

使用道具 舉報(bào)

13#
ID:47286 發(fā)表于 2021-12-6 00:49 | 只看該作者
188610329 發(fā)表于 2021-12-6 00:15
多的不說了,有興趣的話,看看這個(gè)吧,不需要數(shù)組的提高效率解析法。代碼大小也比常規(guī)的小。個(gè)人認(rèn)為,這 ...

好的 我仔細(xì)研讀一下 好好學(xué)習(xí)天天向上 哈哈

另外 補(bǔ)充一下 移位的時(shí)候 貌似每次都要&0x0f

比如0x0122=1 0010 0010

取十位右移4=1 0010

如果用unsigned char串口輸出是0x12 不是0x02 轉(zhuǎn)文本就成0x42了 得不到0x32
回復(fù)

使用道具 舉報(bào)

14#
ID:47286 發(fā)表于 2021-12-6 00:58 | 只看該作者
188610329 發(fā)表于 2021-12-6 00:15
多的不說了,有興趣的話,看看這個(gè)吧,不需要數(shù)組的提高效率解析法。代碼大小也比常規(guī)的小。個(gè)人認(rèn)為,這 ...

老大 匯編啊 不懂啊 真心看不懂啊

我還沒學(xué)單片機(jī) 我還高中剛畢業(yè)那年代 那時(shí)候8086國(guó)土上還沒有的年代 5.25寸軟盤=現(xiàn)在IPHONE的年代(APPLE II可以外掛5.25磁盤機(jī)) 我就覺得能寫匯編的都是神 現(xiàn)在我對(duì)會(huì)寫匯編的人只有裸的膜拜心 其它沒想法的
回復(fù)

使用道具 舉報(bào)

15#
ID:213173 發(fā)表于 2021-12-6 07:48 | 只看該作者
對(duì)于不同數(shù)據(jù)處理方法有所不同,沒有一招通吃天下的方法。就樓主的舉例用如下方法在12MHz晶振條件下488us即可完成4位十進(jìn)制的位分解。
        unsigned char i;
        unsigned char buf[4];
        unsigned int b=1234;
        for(i=0;i<4;i++)
        {
                buf[i]=b%10;//由低位到高位保存
                b/=10;
        }
回復(fù)

使用道具 舉報(bào)

16#
ID:47286 發(fā)表于 2021-12-6 09:29 | 只看該作者
wulin 發(fā)表于 2021-12-6 07:48
對(duì)于不同數(shù)據(jù)處理方法有所不同,沒有一招通吃天下的方法。就樓主的舉例用如下方法在12MHz晶振條件下488us即 ...

感謝回復(fù)

這思路也很棒啊 每次取末位 減少很多運(yùn)算量 我咋就沒想到呢 學(xué)習(xí)了

在和各位前輩請(qǐng)教前 我就知道傻傻的一位一位求模求余的算法 后來我那種查表不算算法 是人代替片子計(jì)算而已
回復(fù)

使用道具 舉報(bào)

17#
ID:401564 發(fā)表于 2021-12-6 11:02 | 只看該作者
dzbj 發(fā)表于 2021-12-5 23:50
是的 單獨(dú)干一件事 確實(shí)如你所說 只是我在一個(gè)系統(tǒng)上干的事多 反正每次搞個(gè)東西 不給所有腳都用上就覺得 ...

把功夫用在鉆牛角尖上,還不如多了解一下單片機(jī)方面的知識(shí)
比如:為什么人家不直接發(fā)送數(shù)據(jù)本身,或者BCD碼,而大多數(shù)是發(fā)送ASCII碼?我直接發(fā)送數(shù)據(jù)不行嗎?為什么非得那么麻煩呢?
你想提高運(yùn)算速度,為什么不用STC8G2K系列呢,也不知道你有用過硬件乘法器沒有
32位除以16位,只要17個(gè)時(shí)鐘,你試一下所謂的優(yōu)化代碼,軟件能達(dá)到這個(gè)速度嗎?
回復(fù)

使用道具 舉報(bào)

18#
ID:47286 發(fā)表于 2021-12-6 12:09 | 只看該作者
Y_G_G 發(fā)表于 2021-12-6 11:02
把功夫用在鉆牛角尖上,還不如多了解一下單片機(jī)方面的知識(shí)
比如:為什么人家不直接發(fā)送數(shù)據(jù)本身,或者BCD碼 ...

嗯嗯 你說的對(duì) 更好的東西誰會(huì)排斥呢 這不就是交流一下么 當(dāng)然 對(duì)我來說主要是學(xué)習(xí) 咱搞工科的人都喜歡較勁 你這一遍一遍的說我 看不上我這思路 不也是一種較勁 正常 正常 求同存異 別管我鉆不鉆牛角尖 好歹我這算是個(gè)上勁的心吧 看這份上 原諒我唄 哈哈
回復(fù)

使用道具 舉報(bào)

19#
ID:57657 發(fā)表于 2021-12-6 12:42 | 只看該作者
可以看下C語(yǔ)言u(píng)nion結(jié)構(gòu)的用法,如果有用就不用移位了。
回復(fù)

使用道具 舉報(bào)

20#
ID:47286 發(fā)表于 2021-12-6 13:12 | 只看該作者
npn 發(fā)表于 2021-12-6 12:42
可以看下C語(yǔ)言u(píng)nion結(jié)構(gòu)的用法,如果有用就不用移位了。

感謝回復(fù)

union我用過 用來拆分TL和TH的高低8位 但不了解原理 我這半路出家 只會(huì)用 感覺上union只能拆分兩個(gè)8位 但一個(gè)int可以表示1234 貌似拆不出來 就沒想過用這個(gè)東西
回復(fù)

使用道具 舉報(bào)

21#
ID:624769 發(fā)表于 2021-12-6 13:55 | 只看該作者
dzbj 發(fā)表于 2021-12-6 00:58
老大 匯編啊 不懂啊 真心看不懂啊

我還沒學(xué)單片機(jī) 我還高中剛畢業(yè)那年代 那時(shí)候8086國(guó)土上還沒有的年 ...

兄弟, 沒讓你學(xué)會(huì)編啊, 沒看我都打包好,讓你直接調(diào)用了么? 怎么調(diào)用的這個(gè)實(shí)例你總能看懂吧?

而且, 直接用出發(fā)取模, 為啥編譯后會(huì)那么大? 因?yàn)橐彩钦{(diào)用了一個(gè)系統(tǒng)內(nèi)部的,用于16位的除法的匯編代碼,你Debug跳進(jìn)去看,也是看不懂的。你的目的不就是提高效率么?所以我給你這個(gè),應(yīng)該是,再?zèng)]有16位硬件除法器的前提下,能達(dá)到的最高效率了。

查表方式我已經(jīng)放棄很久了,記不清了,印象當(dāng)中,在完全C語(yǔ)言代碼編寫的前提下,完成你需要達(dá)到的最終結(jié)果,怎么也要將近100us的時(shí)間。但是表非常占空間。

至于,這個(gè)算法為啥是匯編寫的,實(shí)在是因?yàn),我的C語(yǔ)言太濫,寫不出來,原理來講,就是強(qiáng)制調(diào)用51單片機(jī)的8位除法器,來分段除法,以此提高效率,但是,我嘗試用C語(yǔ)言寫,可能我C實(shí)在太差,不管我如何調(diào)整我的寫法,到了編譯的時(shí)候,始終都會(huì)被編譯成使用加法器來計(jì)算,所以,后來干脆就直接用匯編代碼寫了。
回復(fù)

使用道具 舉報(bào)

22#
ID:231701 發(fā)表于 2021-12-6 14:06 | 只看該作者
其實(shí)改成字符型的應(yīng)該就可以了吧?
回復(fù)

使用道具 舉報(bào)

23#
ID:47286 發(fā)表于 2021-12-6 14:23 | 只看該作者
188610329 發(fā)表于 2021-12-6 13:55
兄弟, 沒讓你學(xué)會(huì)編啊, 沒看我都打包好,讓你直接調(diào)用了么? 怎么調(diào)用的這個(gè)實(shí)例你總能看懂吧?

而且, 直 ...

調(diào)用會(huì) 一看就明白 本來以為你是發(fā)個(gè)范例讓我自己去理解 我都準(zhǔn)備好紙筆和馬扎了 誰想到老兄扔個(gè)成品上來 完全屬于被餡餅砸了后蒙B狀態(tài)

查表是太占空間了 以前只拆一個(gè)數(shù)字還好 雖然也想知道 但沒那么迫切就一直沒問過 這次數(shù)字多 對(duì)應(yīng)值還都不一樣 查表法就簡(jiǎn)直了 雖然用了個(gè)32k的片子那也不能這么禍害啊 就想問問前輩們 我覺得wulin前輩那思路也給我很大啟發(fā) 以前總想著從高位拆下來 他那個(gè)低位開拆的思路也是讓我受教了

匯編無疑是神器 一直是滿心崇拜 只是太底層了 我是沒時(shí)間去學(xué)了 不是每天的時(shí)間 是這輩子快混沒了 總不好咽氣那天還在記地址吧 哈哈 現(xiàn)在學(xué)東西和年輕的時(shí)候不一樣 打開書 基本上看看就明白了 合上書 嗯。。。。。全忘了 再打開書 又明白了 然后 看著看著 睡著了
回復(fù)

使用道具 舉報(bào)

24#
ID:624769 發(fā)表于 2021-12-6 14:50 | 只看該作者
dzbj 發(fā)表于 2021-12-6 14:23
調(diào)用會(huì) 一看就明白 本來以為你是發(fā)個(gè)范例讓我自己去理解 我都準(zhǔn)備好紙筆和馬扎了 誰想到老兄扔個(gè)成品上來 ...

先說 wulin 那個(gè)帖子的算法, 正確的拆分法,就是應(yīng)該從低位拆起,其實(shí)我給你的那個(gè)優(yōu)化算法,也是從低位拆起的,站在計(jì)算機(jī)的運(yùn)算原理上,低位拆起,效率是最高的,缺點(diǎn)是:正常保存的時(shí)候,就會(huì)低位在前,要高位在前的話,要增加一些代碼。我給你的那個(gè)也是低位在前,你如果需要高位在前,我可以幫你改一下。
然后,從低位拆起需要注意的是: 會(huì)破壞原始值。 wulin 同志給你的樣本里面沒有寫傳參,你正常用的話,如果寫成子函數(shù)調(diào)用的話,一般都會(huì)傳參,不需要考慮這個(gè)問題,但是,如果貼到主程序里直接使用,你就必須要注意,是否需要保留原始值的問題。
最后,匯編沒有你想象的那么神,我學(xué)了3年的C, 總之,用現(xiàn)在的我來評(píng)價(jià),我的C學(xué)的是垃圾中的戰(zhàn)斗機(jī),代碼寫的大,效率又低,唯一能做的就是不停的升級(jí)我的單片機(jī),擴(kuò)大單片機(jī)容量,后來因?yàn)槟承┰虿坏貌粚W(xué)一下匯編,大約1個(gè)月吧,就入門了,然后就開始用匯編改寫以前的代碼,代碼就越寫越小,效率越來越高,以前從STC89C51 一步步升到 STC8A8K64SA12 后來是一步一步退到STC15W204S. 因?yàn)樾矢吡耍a小了。 這個(gè)時(shí)候我充分的意識(shí)到………………  我的C,學(xué)得太濫了,所以,后來又重頭開始學(xué)C.
可能你覺得會(huì)匯編很神, 但是在我的角度來看, 但凡用C能寫出,我只能依靠匯編才實(shí)現(xiàn)的功能的人,全是牛人。
回復(fù)

使用道具 舉報(bào)

25#
ID:47286 發(fā)表于 2021-12-6 15:12 | 只看該作者
188610329 發(fā)表于 2021-12-6 14:50
先說 wulin 那個(gè)帖子的算法, 正確的拆分法,就是應(yīng)該從低位拆起,其實(shí)我給你的那個(gè)優(yōu)化算法,也是從低位 ...

大小頭的事 我注意到了 這個(gè)在用的時(shí)候會(huì)注意 但你說的先拆小會(huì)改變初值沒懂 從大頭拆不會(huì)么 不過問題不大 初值變了后邊肯定會(huì)有問題 調(diào)的時(shí)候碰壁自然就知道改 沒關(guān)系的

c可能更接近日常思路吧 匯編不了解 看過幾段東西 好象都是對(duì)具體物理地址的操作 想想自己從1數(shù)到1024得睡著好幾次 直接就撤了
回復(fù)

使用道具 舉報(bào)

26#
ID:155811 發(fā)表于 2021-12-6 15:47 | 只看該作者
樓主有鉆研精神
回復(fù)

使用道具 舉報(bào)

27#
ID:47286 發(fā)表于 2021-12-6 17:51 | 只看該作者

謝謝鼓勵(lì)
回復(fù)

使用道具 舉報(bào)

28#
ID:624769 發(fā)表于 2021-12-6 20:07 | 只看該作者
順便和你說說16位硬件乘除法器,以及為啥我會(huì)自己折騰優(yōu)化算法,假如,對(duì)此你有興趣的話。
曾經(jīng),有一段時(shí)間(在我還沒學(xué)匯編之前),我是非常迷信16位乘除法器的,但是,由于先天的缺陷,導(dǎo)致16位乘除法器,在姚老板的設(shè)計(jì)下,在STC8系列下,無法達(dá)到令人滿意的效果,(這是學(xué)了匯編之后,才發(fā)現(xiàn)的)。不多說,上圖。

以下是用16位除法器:



以下是用8位除法器:



在,同時(shí)用STC8G單片機(jī),晶振設(shè)定為12Mhz的前提下:
除去程序啟動(dòng)用去的65us,
使用16位除法器,需要耗時(shí)19us 完成所有運(yùn)算(其中還未包含等待除法完成的被我注釋掉那段的時(shí)間,否則總體時(shí)間會(huì)增加約3us),
而使用8位除法器,分段計(jì)算,實(shí)際只需要13us。

由此看來,使用16位硬件除法器,效率只有更低,這是什么原因呢,主要就是因?yàn)?1構(gòu)架,以及姚老板的設(shè)計(jì)上的不周,16位硬件除法器使用的是XSFR,雖然計(jì)算快了,但是訪問太慢,讀寫都耗費(fèi)太多時(shí)間。所以,使整體效率降低了。

之所以說這些,是因?yàn)樵?jīng)我迷信過姚老板,希望你不要同樣入我入過的坑。

以下提供代碼,可供驗(yàn)證。

Test_Code.rar (861.79 KB, 下載次數(shù): 2)


回復(fù)

使用道具 舉報(bào)

29#
ID:624769 發(fā)表于 2021-12-6 21:37 | 只看該作者
上文中16位硬件除法器的實(shí)驗(yàn)代碼略有錯(cuò)誤,修正如下:

使用16位除法器,需要耗時(shí)17us 完成所有運(yùn)算。(未包含注釋掉的等待計(jì)算完成的時(shí)間)

貼圖如下:




新的代碼包如下:
Test_Code16.rar (760.59 KB, 下載次數(shù): 2)


回復(fù)

使用道具 舉報(bào)

30#
ID:57657 發(fā)表于 2021-12-6 21:59 | 只看該作者
dzbj 發(fā)表于 2021-12-6 13:12
感謝回復(fù)

union我用過 用來拆分TL和TH的高低8位 但不了解原理 我這半路出家 只會(huì)用 感覺上union只能拆 ...

C語(yǔ)言的union、struct屬于基本語(yǔ)句,很多算法都要用的到,比如這樣:
  1. #include "reg51.h"
  2. #define u8 unsigned char
  3. void main() {
  4.         union {
  5.                 unsigned char c[4];
  6.                 unsigned int i[2];
  7.                 unsigned long l;
  8.                 float f;
  9.                 struct {
  10.                         u8 a0;
  11.                         u8 a1;
  12.                         u8 a2;
  13.                         u8 a3;
  14.                 } s;
  15.         } u;


  16.         u.f = 3.1415926;
  17.         if (u.s.a0 == u.c[0]) {
  18.                 if (u.s.a1 == u.c[1]) {
  19.                         if (u.s.a2 == u.c[2]) {
  20.                                 if (u.s.a3 == u.c[3]) {
  21.                                         if (u.l == 0x40490FDA) {
  22.                                                 P1 = 0xAA;
  23.                                         }
  24.                                 }
  25.                         }
  26.                 }
  27.         }

  28.         while (1);
  29. }
復(fù)制代碼
回復(fù)

使用道具 舉報(bào)

31#
ID:47286 發(fā)表于 2021-12-6 23:38 | 只看該作者
188610329 發(fā)表于 2021-12-6 20:07
順便和你說說16位硬件乘除法器,以及為啥我會(huì)自己折騰優(yōu)化算法,假如,對(duì)此你有興趣的話。
曾經(jīng),有一段時(shí) ...

明白 理解你說的意思 STC國(guó)內(nèi)應(yīng)用面廣一點(diǎn) 在很多領(lǐng)域夠用罷了 對(duì)它我個(gè)人倒是沒有迷信 它的技術(shù)文化還是比不了那些強(qiáng)大的公司

企業(yè)的文化決定對(duì)自身產(chǎn)品的認(rèn)知 這種認(rèn)知會(huì)體現(xiàn)在設(shè)計(jì) 制造 以及服務(wù)中 這方面 無疑STC和更好的企業(yè)比差距還不小 姚老板是個(gè)很成功的商人 我敬佩他的能力 但并不怎么佩服他的產(chǎn)品 湊合用就得了 當(dāng)然 他也看不上我這種原子級(jí)別的客戶 而我也不需要他看得上 全世界那么多品牌和產(chǎn)品隨便我選 就是這樣了

最后提個(gè)幼稚的問題 51片子有8位的乘除法器是么 至少我是第一次知道 之前我看過的書里也沒提這樣 也許我看那些書都更偏向使用 什么快速入門啊 什么經(jīng)典范例啊 深的也沒讀過

如果有8位的乘除法器 是不是意味著char級(jí)別的乘除法并不用太考慮運(yùn)算帶來的消耗 不過也許這想法沒毛的用 你都說過用C打不開
回復(fù)

使用道具 舉報(bào)

32#
ID:47286 發(fā)表于 2021-12-6 23:46 | 只看該作者
npn 發(fā)表于 2021-12-6 21:59
C語(yǔ)言的union、struct屬于基本語(yǔ)句,很多算法都要用的到,比如這樣:

感謝回復(fù) union還能這么用 受教了 明天我用程序?qū)嶋H看一下結(jié)果
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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