久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

請教C語言四位數(shù)拆出每一位的問題

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

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

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

我自認為這樣比每一位求余求模快 是么

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

使用道具 舉報

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

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

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

評分

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

查看全部評分

回復(fù)

使用道具 舉報

板凳
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ù)制代碼

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

評分

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

查看全部評分

回復(fù)

使用道具 舉報

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

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

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

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

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

我用的片子是15系的 也是1T模式 但因為不是8系 沒有乘除法器
回復(fù)

使用道具 舉報

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

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

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

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

再次感謝
回復(fù)

使用道具 舉報

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

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

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

使用道具 舉報

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

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

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

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

使用道具 舉報

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

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

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

使用道具 舉報

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

使用道具 舉報

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

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

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

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

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

使用道具 舉報

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

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

使用道具 舉報

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

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

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

如用1T單片機效率可以更高。

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



回復(fù)

使用道具 舉報

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

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

另外 補充一下 移位的時候 貌似每次都要&0x0f

比如0x0122=1 0010 0010

取十位右移4=1 0010

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

使用道具 舉報

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

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

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

使用道具 舉報

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

使用道具 舉報

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

感謝回復(fù)

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

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

使用道具 舉報

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

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

使用道具 舉報

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

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

使用道具 舉報

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

使用道具 舉報

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

感謝回復(fù)

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

使用道具 舉報

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

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

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

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

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

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

使用道具 舉報

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

使用道具 舉報

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

而且, 直 ...

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

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

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

使用道具 舉報

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

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

使用道具 舉報

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

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

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

使用道具 舉報

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

使用道具 舉報

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

謝謝鼓勵
回復(fù)

使用道具 舉報

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

以下是用16位除法器:



以下是用8位除法器:



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

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

之所以說這些,是因為曾經(jīng)我迷信過姚老板,希望你不要同樣入我入過的坑。

以下提供代碼,可供驗證。

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


回復(fù)

使用道具 舉報

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

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

貼圖如下:




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


回復(fù)

使用道具 舉報

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

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

C語言的union、struct屬于基本語句,很多算法都要用的到,比如這樣:
  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ù)

使用道具 舉報

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

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

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

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

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

使用道具 舉報

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

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

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 国产精品一区二区三区久久久 | 国产美女一区二区三区 | 亚洲一区二区免费 | 国产在线观看一区二区三区 | www.黄色片视频 | 欧美二区在线 | 91精品91久久久 | 国产一区二区在线视频 | 色吊丝2288sds中文字幕 | 精品在线免费看 | 亚洲最大看片网站 | 中文av网站 | 午夜精品久久久久久不卡欧美一级 | 91色视频在线观看 | 精品久久久久久久久久 | 国产精品国产精品国产专区不片 | 久久高清| 久久亚洲欧美日韩精品专区 | 久久精品一级 | 一区二区精品 | 91在线一区二区 | 操久久 | 国产亚洲一区二区在线观看 | 激情亚洲| 国产精品一二三区 | 美女久久 | 国产成人精品久久二区二区91 | 中文字幕福利视频 | 日韩免费av一区二区 | 成人国产一区二区三区精品麻豆 | 日韩在线观看网站 | 网黄在线| 不卡欧美 | 超碰最新在线 | 国产二区视频 | 欧美日韩亚洲一区 | 国产美女一区 | 国产精品久久久久久久久久 | wwww.xxxx免费 | 欧美一区二区三区在线观看视频 | 久久com|