日韩在线不卡免费视频一区,日韩欧美精品一区二区三区经典,日产精品码2码三码四码区,人妻无码一区二区三区免费,日本feerbbwdh少妇丰满

  • 回復(fù)
  • 收藏
  • 點贊
  • 分享
  • 發(fā)新帖

使單片機達到最高效率的方法探討

效率問題一直很受關(guān)注,其中相關(guān)單位因素大多是代碼寫的簡潔合理,嵌套少,main中盡量少的進行運行等,最近在看到一篇關(guān)于單片機效率問題的文章,并不是常見的提高效率方式,大家來討論一下,看看是否可行。

文章:

我是PC機底層編程轉(zhuǎn)過來的,以前從來沒接觸過單片機,五個月前學(xué)習AVR,在這里學(xué)到很多東西。但也意識到電子工程師們的硬件編程思想與PC機底層編程思想上的很多不同,引發(fā)了一些思考。我說一說,供大家參考,只為學(xué)習,無意爭論。

我第一次看到教程里Delay()函數(shù)的代碼時我嚇了一跳,竟然讓單片機空轉(zhuǎn)以實現(xiàn)和外界同步,這怎么可能?

試想,如果PC機CPU空轉(zhuǎn)一秒,那么音樂會斷一秒、畫面會停頓一秒、下載文件會斷一秒,這怎么可行?

我看到很多單片機程序,它們的單片機99.9%的工作時間都在打空轉(zhuǎn),99.9%大家可能感到有些危言聳聽,那就讓我們算一算:

已內(nèi)部8M頻的AVR單片機來說,單指令周期僅為1/8 = 0.125us,那一毫秒可以執(zhí)行多少個單周期指令? 1%0.125*1000 = 8000個

而我看到論壇里下到的絕大多數(shù)程序,兩個延時函數(shù)之間代碼的執(zhí)行時間要遠遠小于8000個指令周期。

說實話,很多16K以上的程序,把所有延時函數(shù)去掉,總體能執(zhí)行幾毫秒就不錯了。

換句話說,我說單片機的利用率小于0.01%還是口下留情了。

要說怎么解決問題,就要先找到問題,我問問大家,程序中,我們?yōu)槭裁囱訒r?

原因很多,可能是外設(shè)速度太慢,也可能是為了躲過人眼視覺停留時間,等等。

總之就是與外界不同步,而我們想要同步。

所以說這些延時應(yīng)該是很有道理的,我不否定這一點,但問題的關(guān)鍵這些延時空轉(zhuǎn),我們?yōu)槭裁床荒馨堰@些時間回收起來做一些別的事呢?

試想,如果把這99.9%的時間回收,那可以一筆相當巨大的資源。

有很多人有些特殊方法回收過這些空轉(zhuǎn)時間,比如說在延時函數(shù)中做點事。

但這些往往都不通用,下面我說一些我的兩種方法:

1、前后臺模式下延時時間回收的方法:

前后臺模式就是大家最常用的主程序大循環(huán) + 中斷的模式。

首先解決外設(shè)太慢問題,像串口、鍵盤、LCD、SD卡等IO,這些收發(fā)可以建立外部緩沖區(qū)。比如串口收發(fā)在中斷中完成保存到緩沖區(qū),而主程序操作緩沖區(qū)而不直接操縱串口,這已經(jīng)看到很多人這樣用了。但像矩陣鍵盤的緩沖區(qū),我很少看到有人這么用,在中斷中接收按鍵信息保存到緩沖區(qū)。

還有像LCD,我們一個個往顯存中寫數(shù)據(jù)是很浪費的,也應(yīng)該建立緩沖,統(tǒng)一處理。

建立緩沖區(qū)這類方式中間有一些技術(shù)難點,比如像串口接收,無法判斷對發(fā)是否全部發(fā)完,怎么辦?可以設(shè)立定時,如果一個字節(jié)接收之后1ms之內(nèi)沒收到下一個,則認為接收完畢。這只是一個思想,具體應(yīng)用大家掌握。

可能有人會說,除了外設(shè)太慢,還有像視覺停留的問題怎么解決,總不能讓流水燈快到人眼都看不清吧。

這就我下面要說的問題,這些延時的時間怎么回收?就是全部放到定時中斷中!

可能又有些人會說,書里、教程都說了,中斷處理東西的時間要盡量短,你這樣整個中斷有太多判斷、很長,時間很長,這不行。

這是一種教條的思想,把書讀死了??梢栽谥袛嘀羞@樣處理,比如:

void (*Task)(void);

ISR

{

(*Task)(void);

}

中斷里用的內(nèi)容通過函數(shù)指針來調(diào)用,這樣可以在主程序根據(jù)需要時任意改變要執(zhí)行的任務(wù),還可以改任務(wù)的周期。所用的判斷都是在主程序需中執(zhí)行,然后改變指針的指向,來確定中斷中下一步的任務(wù)。

這樣,在前后臺系統(tǒng)中主程序?qū)⑷蝿?wù)分配完,還有很多余力處理很多事。

比如有很多個鍵盤、LED點陣、數(shù)碼管等,它們都需要實時響應(yīng),很容造成編程困難、響應(yīng)遲鈍,其實只要把延時的時間回收,處理這些就非常從容了。

可能還有人會說,有些項目用不了這么苛刻的時間,你回收的時間用不了,要那么多干嘛?

其實這時,你就可以用死循環(huán)掃描事件,可以實時響應(yīng)。你的系統(tǒng)跟原來空循環(huán)延時比,實時性要高了不知多少倍。

2、變異的協(xié)作式內(nèi)核

先說說嵌入式操作系統(tǒng)的內(nèi)核,簡單的說,它就是個任務(wù)調(diào)度器,讓多個任務(wù)在同一個CPU上同時執(zhí)行,所謂同時也是相對的,無非就第一個任務(wù)執(zhí)行幾毫秒、第二個任務(wù)在執(zhí)行幾毫秒。。。外表看起來就是同時執(zhí)行。

至于可剝奪式內(nèi)核和協(xié)作式內(nèi)核的區(qū)別,大家可以百度一下。

說道能在單片機上用的嵌入式操作系統(tǒng),大家會說出一些如uCosII、FreeOS等操作系統(tǒng)。

還有很多人對這些操作系統(tǒng)十分抗拒、十分反對,他們的理由是什么?

1、這些操作系統(tǒng)占用大量RAM、ROM

2、這些實時操作系統(tǒng)所謂的實時是相對非實時操作系統(tǒng)的,跟裸機比實際上是慢了

這些理由不是沒道理,因為這些商用操作系統(tǒng)都是可剝奪式內(nèi)核,它們的原則是保證最高優(yōu)先級任務(wù)在可確定的時間內(nèi)響應(yīng)。

它們的有優(yōu)點是任務(wù)切換時間是確定的,不會隨任務(wù)的多少而改變。

有了這些確定性,讓它們在商用產(chǎn)品大放光彩。因為其時間穩(wěn)定性。

但它們的缺點也很明顯,中斷級節(jié)拍浪費很多時間。任務(wù)間同時調(diào)用時引發(fā)同步問題而引入許多如信號量、郵箱等機制浪費大量RAM、ROM。

綜上,可剝奪式內(nèi)核穩(wěn)定可定量,在越高級的單片機上越有優(yōu)勢,在8位機上可用,但需要大量裁剪,并不一定合適。

而協(xié)作式內(nèi)核的核心思想是什么?它不像剝奪式內(nèi)核保證最高級任務(wù)速度最快,而是保證所有任務(wù)的平均速度最快!

正如我前面的說法,我連續(xù)兩個延時函數(shù)之間的代碼很難超過1ms,甚至很難超過100us,我們可以將其忽略。這樣10個任務(wù),第一個執(zhí)行完主動放棄單片機控制權(quán),交給第二個任務(wù),第二個任務(wù)執(zhí)行完主動放棄控制權(quán),交給第三個任務(wù)。10個任務(wù)之間無間隙,每一個任務(wù)需要延時時,就主動放棄控制權(quán)。

基于這種思想,我們的就達到了回收空轉(zhuǎn)延時的目的,而且應(yīng)為每個任務(wù)是執(zhí)行完后主動放棄,所以不存在剝奪式內(nèi)核的同步問題,基本不需要郵箱、信號量等機制,對RAM、ROM的要求就非常低了。

這樣來看,協(xié)作式內(nèi)核非常適合8位機。但可能有太多嵌入式系統(tǒng)的書中對剝奪式內(nèi)核不分場合的認可,造成很多人誤解。而且uCos等系統(tǒng)的權(quán)威,也讓很多RTOS作者爭相效仿,沒用對8位機的場合做合理分析。

商用系統(tǒng)中沒有協(xié)作式內(nèi)核,而民用的,還少有優(yōu)秀的協(xié)作式內(nèi)核,都是基于傳統(tǒng)節(jié)拍。

傳統(tǒng)協(xié)作式內(nèi)核需要定時中斷為時鐘基準,也會間歇性打斷任務(wù),造成不必要的損失,這并不是我們想要的。

我們其實可以僅僅是讓定時器以大分頻系數(shù)開著, 而不給其產(chǎn)生中斷的機會。當任務(wù)將要放棄使用權(quán)時,讀取定時器,作為時鐘基準,然后清零。

做法一句兩句說不清,而效果是什么?可以做到任務(wù)是以不受干擾,與裸機相同的工作狀態(tài),這是傳統(tǒng)協(xié)作式內(nèi)核做不到的,而僅當它需要延時了,才放棄使用權(quán),將延時的時間給其它任務(wù)。這正符合我全文的目的 -- 回收空轉(zhuǎn)延時時間

這樣的內(nèi)核體積會非常小,運行方式與裸機無異,僅僅是把空轉(zhuǎn)延時時間干些其它事。對使用者還沒什么要求,不想以往系統(tǒng)那么復(fù)雜。

可惜市面上并沒有基于這種方式的內(nèi)核,我已經(jīng)寫了一個,非常精簡,運行穩(wěn)定。但作為一個想應(yīng)用實際的內(nèi)核,還需要檢驗。

全部回復(fù)(5)
正序查看
倒序查看
stony_s
LV.3
2
2014-02-10 14:53
比較贊同這說法,現(xiàn)在搞單片機的延時函數(shù)用的太多,很多教材很多老師也都這樣講,好像這都成了習慣了
0
回復(fù)
matou
LV.3
3
2014-02-10 15:25
研究的很深呀,先收藏了,以前寫過按鍵掃描,沒有延時的,效率確實很高,但時基要把握好
0
回復(fù)
2014-02-10 16:19
還可以參照PC機的模式,用一個定時器(如定時器0)作為時間基準,通過中斷使變量(如i,j等)加1,或加幾,然后再在主函數(shù)中以查詢的方式(如while(i) if(i == 7)等)作為延時的功能
0
回復(fù)
for_real
LV.3
5
2014-02-10 16:45
我個人寫程序的話一般情況下大于1ms的延時都不會用,而是用狀態(tài)機+定時器去實現(xiàn),這樣就可以實現(xiàn)高效的利用
0
回復(fù)
wooda
LV.1
6
2018-10-13 18:23

說的不錯,真正發(fā)揮單片機性能的,需要對任務(wù)以及任務(wù)切換有很深的理解才行。

最近也在看非搶占式os,感覺這種方式比較穩(wěn)定,搶占式還是有很多限制,并且臨界時間太多,會有不穩(wěn)定現(xiàn)象并且非常難以debug

0
回復(fù)
發(fā)