單片機(jī)軟件設(shè)計(jì)結(jié)構(gòu)
(2011/10/20 9:01:00)
mcu由于內(nèi)部資源的限制,軟件設(shè)計(jì)有其特殊性,程序一般沒有復(fù)雜的算法以及數(shù)據(jù)結(jié)構(gòu),代碼量也不大,通常不會(huì)使用OS(OperatingSystem),因?yàn)閷?duì)于一個(gè)只有若干KROM,一百多byteRAM的mcu來說,一個(gè)簡(jiǎn)單OS也會(huì)吃掉大部分的資源。
對(duì)于無os的系統(tǒng),流行的設(shè)計(jì)是主程序(主循環(huán))+(定時(shí))中斷,這種結(jié)構(gòu)雖然符合自然想法,不過卻有很多不利之處,首先是中斷可以在主程序的任何地方發(fā)生,隨意打斷主程序。其次主程序與中斷之間的耦合性(關(guān)聯(lián)度)較大,這種做法使得主程序與中斷纏繞在一起,必須仔細(xì)處理以防不測(cè)。
那么換一種思路,如果把主程序全部放入(定時(shí))中斷中會(huì)怎么樣?這么做至少可以立即看到幾個(gè)好處:系統(tǒng)可以處于低功耗的休眠狀態(tài),將由中斷喚醒進(jìn)入主程序;如果程序跑飛,則中斷可以拉回;沒有了主從之分(其他中斷另計(jì)),程序易于模塊化。
(題外話:這種方法就不會(huì)有何處喂狗的說法,也沒有中斷是否應(yīng)該盡可能的簡(jiǎn)短的爭(zhēng)論了)
為了把主程序全部放入(定時(shí))中斷中,必須把程序化分成一個(gè)個(gè)的模塊,即任務(wù),每個(gè)任務(wù)完成一個(gè)特定的功能,例如掃描鍵盤并檢測(cè)按鍵。設(shè)定一個(gè)合理的時(shí)基(tick),例如5,10或20ms,每次定時(shí)中斷,把所有任務(wù)執(zhí)行一遍,為減少復(fù)雜性,一般不做動(dòng)態(tài)調(diào)度(最多使用固定數(shù)組以簡(jiǎn)化設(shè)計(jì),做動(dòng)態(tài)調(diào)度就接近os了),這實(shí)際上是一種無優(yōu)先級(jí)時(shí)間片輪循的變種。來看看主程序的構(gòu)成:
voidmain()
{
….//Initialize
while(true){
IDLE;//sleep
}
}
這里的IDLE是一條sleep指令,讓mcu進(jìn)入低功耗模式。中斷程序的構(gòu)成
voidTimer_Interrupt()
{
SetTimer();
ResetStack();
Enable_Timer_Interrupt;
….
進(jìn)入中斷后,首先重置Timer,這主要針對(duì)8051,8051自動(dòng)重裝分頻器只有8-bit,難以做到長(zhǎng)時(shí)間定時(shí);復(fù)位stack,即把stack指針賦值為棧頂或棧底(對(duì)于pic,TIDSP等使用循環(huán)棧的mcu來說,則無此必要),用以表示與過去決裂,而且不準(zhǔn)備返回到中斷點(diǎn),保證不會(huì)保留程序在跑飛時(shí)stack中的遺體。Enable_Timer_Interrupt也主要是針對(duì)8051。8051由于中斷控制較弱,只有兩級(jí)中斷優(yōu)先級(jí),而且使用了如果中斷程序不用reti返回,則不能響應(yīng)同級(jí)中斷這種偷懶方法,所以對(duì)于8051,必須調(diào)用一次reti來開放中斷:
_Enable_Timer_Interrupt:
acall_reti
_reti:reti
下面就是任務(wù)的執(zhí)行了,這里有幾種方法。第一種是采用固定順序,由于mcu程序復(fù)雜度不高,多數(shù)情況下可以采用這種方法:
…
Enable_Timer_Interrupt;
ProcessKey();
RunTask2();
…
RunTaskN();
while(1)IDLE;
可以看到中斷把所有任務(wù)調(diào)用一遍,至于任務(wù)是否需要運(yùn)行,由程序員自己控制。另一種做法是通過函數(shù)指針數(shù)組:
#defineCountOfArray(x)(sizeof(x)/sizeof(x[0]))
typedefvoid(*FUNCTIONPTR)();
constFUNCTIONPTR[]tasks={
ProcessKey,
RunTask2,
…
RunTaskN
};
voidTimer_Interrupt()
{
SetTimer();
ResetStack();
Enable_Timer_Interrupt;
for(i=0;i<CountOfArray(tasks),i++)
(*tasks
)();
while(1)IDLE;
}
使用const是讓數(shù)組內(nèi)容位于codesegment(ROM)而非datasegment(RAM)中,8051中使用code作為const的替代品。
(題外話:關(guān)于函數(shù)指針賦值時(shí)是否需要取地址操作符&的問題,與數(shù)組名一樣,取決于compiler.對(duì)于熟悉匯編的人來說,函數(shù)名和數(shù)組名都是常數(shù)地址,無需也不能取地址。對(duì)于不熟悉匯編的人來說,用&取地址是理所當(dāng)然的事情。VisualC++2005對(duì)此兩者都支持)
這種方法在匯編下表現(xiàn)為散轉(zhuǎn),一個(gè)小技巧是利用stack獲取跳轉(zhuǎn)表入口:
movA,state
acallMultiJump
ajmpstate0
ajmpstate1
...
MultiJump:popDPH
popDPL
rlA
jmp@A+DPTR
還有一種方法是把函數(shù)指針數(shù)組(動(dòng)態(tài)數(shù)組,鏈表更好,不過在mcu中不適用)放在datasegment中,便于修改函數(shù)指針以運(yùn)行不同的任務(wù),這已經(jīng)接近于動(dòng)態(tài)調(diào)度了:
FUNCTIONPTR[COUNTOFTASKS]tasks;
tasks[0]=ProcessKey;
tasks[0]=RunTaskM;
tasks[0]=NULL;
...
FUNCTIONPTRpFunc;
for(i=0;i<COUNTOFTASKS;i++){
pFunc=tasks);
if(pFunc!=NULL)
(*pFunc)();
}
通過上面的手段,一個(gè)中斷驅(qū)動(dòng)的框架形成了,下面的事情就是保證每個(gè)tick內(nèi)所有任務(wù)的運(yùn)行時(shí)間總和不能超過一個(gè)tick的時(shí)間。為了做到這一點(diǎn),必須把每個(gè)任務(wù)切分成一個(gè)個(gè)的時(shí)間片,每個(gè)tick內(nèi)運(yùn)行一片。這里引入了狀態(tài)機(jī)(statemachine)來實(shí)現(xiàn)切分。關(guān)于statemachine,很多書中都有介紹,這里就不多說了。
(題外話:實(shí)踐升華出理論,理論再作用于實(shí)踐。我很長(zhǎng)時(shí)間不知道我一直沿用的方法就是statemachine,直到學(xué)習(xí)UML/C++,書中介紹tachniquesforidentifyingdynamicbehvior,方才豁然開朗。功夫在詩外,掌握C++,甚至C#JAVA,對(duì)理解嵌入式程序設(shè)計(jì),會(huì)有莫大的幫助)
狀態(tài)機(jī)的程序?qū)崿F(xiàn)相當(dāng)簡(jiǎn)單,第一種方法是用swich-case實(shí)現(xiàn):
voidRunTaskN()
{
switch(state){
case0:state0();break;
case1:state1();break;
…
caseM:stateM();break;
default:
state=0;
}
}
另一種方法還是用更通用簡(jiǎn)潔的函數(shù)指針數(shù)組:
constFUNCTIONPTR[]states={state0,state1,…,stateM};
voidRunTaskN()
{
(*states[state])();
}
下面是statemachine控制的例子:
voidstate0(){}
voidstate1(){state++;}//nextstate;
voidstate2(){state+=2;}//gotostate4;
voidstate3(){state--;}//gotopreviousstate;
voidstate4(){delay=100;state++;}
voidstate5(){delay--;if(delay<=0)state++;}//delay100*tick
voidstate6(){state=0;}//gotothefirststate
一個(gè)小技巧是把第一個(gè)狀態(tài)state0設(shè)置為空狀態(tài),即:
voidstate0(){}
這樣,state=0可以讓整個(gè)task停止運(yùn)行,如果需要投入運(yùn)行,簡(jiǎn)單的讓state=1即可。
以下是一個(gè)鍵盤掃描的例子,這里假設(shè)tick=20ms,ScanKeyboard()函數(shù)控制口線的輸出掃描,并檢測(cè)輸入轉(zhuǎn)換為鍵碼,利用每個(gè)state之間20ms的間隔去抖動(dòng)。
enumEnumKey{
EnumKey_NoKey=0,
…
};
structStructKey{
intkeyValue;
boolkeyPressed;
};
structStructKeyProcesskey;
voidProcessKey(){(*states[state])();}
voidstate0(){}
voidstate1(){key.keyPressed=false;state++;}
voidstate2(){if(ScanKey()!=EnumKey_NoKey)state++;}//nextstateifakeypressed
voidstate3()
{//debouncingstate
key.keyValue=ScanKey();
if(key.keyValue==EnumKey_NoKey)
state--;
else{
key.keyPressed=true;
state++;
}
}
voidstate4(){if(ScanKey()==EnumKey_NoKey)state++;}//nextstateifthekeyreleased
voidstate5(){ScanKey()==EnumKey_NoKey?state=1:state--;}
上面的鍵盤處理過程顯然比通常使用標(biāo)志去抖的程序簡(jiǎn)潔清晰,而且沒有軟件延時(shí)去抖的困擾。以此類推,各個(gè)任務(wù)都可以劃分成一個(gè)個(gè)的state,每個(gè)state實(shí)際上占用不多的處理時(shí)間。某些任務(wù)可以劃分成若干個(gè)子任務(wù),每個(gè)子任務(wù)再劃分成若干個(gè)狀態(tài)。
(題外話:對(duì)于常數(shù)類型,建議使用enum分類組織,避免使用大量#define定義常數(shù))
對(duì)于一些完全不能分割,必須獨(dú)占的任務(wù)來說,比如我以前一個(gè)低成本應(yīng)用中紅外遙控器的軟件解碼任務(wù),這時(shí)只能犧牲其他的任務(wù)了。兩種做法:一種是關(guān)閉中斷,完全的獨(dú)占;
voidRunTaskN()
{
Disable_Interrupt;
…
Enable_Interrupt;
}
第二種,允許定時(shí)中斷發(fā)生,保證某些時(shí)基register得以更新;
voidTimer_Interrupt()
{
SetTimer();
Enable_Timer_Interrupt;
UpdateTimingRegisters();
if(watchDogCounter=0){
ResetStack();
for(i=0;i<CountOfArray(tasks),i++)
(*tasks)();
while(1)IDLE;
}
else
watchDogCounter--;
}
只要watchDogCounter不為0,那么中斷正常返回到中斷點(diǎn),繼續(xù)執(zhí)行先前被中斷的任務(wù),否則,復(fù)位stack,重新進(jìn)行任務(wù)循環(huán)。這種狀況下,中斷處理過程極短,對(duì)獨(dú)占任務(wù)的影響也有限。
中斷驅(qū)動(dòng)多任務(wù)配合狀態(tài)機(jī)的使用,我相信這是mcu下無os系統(tǒng)較好的設(shè)計(jì)結(jié)構(gòu)。對(duì)于絕大多數(shù)mcu程序設(shè)計(jì)來說,可以極大的減輕程序結(jié)構(gòu)的安排,無需過多的考慮各個(gè)任務(wù)之間的時(shí)間安排,而且可以讓程序簡(jiǎn)潔易懂。缺點(diǎn)是,程序員必須花費(fèi)一定的時(shí)間考慮如何切分任務(wù)。
下面是一段用C改寫的CDPlayer中檢測(cè)disc是否存在的偽代碼,用以展示這種結(jié)構(gòu)的設(shè)計(jì)技巧,原源代碼為Z8mcu匯編,基于Sony的DSP,ServoandRF處理芯片,通過送出命令字來控制主軸/滑板/聚焦/尋跡電機(jī),并讀取狀態(tài)以及CD的subQ碼。這個(gè)處理任務(wù)只是一個(gè)大任務(wù)下用statemachine切開的一個(gè)二級(jí)子任務(wù),tick=20ms。
state1(){InitializeMotor();state++;}
state2(){
if(innerSwitch!=ON){
SendCommand(EnumCommand_SlidingMotorBackward);
timeout=MILLISECOND(10000);
state++;//滑板電機(jī)向內(nèi)運(yùn)動(dòng),直至觸及最內(nèi)開關(guān)。
}
else
state+=2;
}
state3(){
if((--timeout)==0){//note:someCcompliersdonotsupport(--timeout)==
SendCommand(EnumCommand_SlidingMotorStop)
systemErrorCode=EnumErrorCode_InnerSwitch;
state=0;//10s超時(shí)錯(cuò)誤,
}
else{
if(innerSwitch==ON){
SendCommand(EnumCommand_SlidingMotorStop)
timeout=MILLISECOND(200);//200ms電機(jī)停止時(shí)間
state++;
}
}
}
state4(){if((--timeout)==0)state++;}//等待電機(jī)完全停止
state5(){
SendCommand(EnumCommand_SlidingMotorForward);
timeout=MILLISECOND(2000);
state++;
}//滑板電機(jī)向外運(yùn)動(dòng),脫離innerswitch
state6(){
if((--timeout)==0){
SendCommand(EnumCommand_SlidingMotorStop)
systemErrorCode=EnumErrorCode_InnerSwitch;
state=0;//2s超時(shí)錯(cuò)誤,
}
else{
if(innerSwitch==OFF){
SendCommand(EnumCommand_SlidingMotorStop)
timeout=MILLISECOND(200);//200ms電機(jī)停止時(shí)間
state++;
}
}
}
state7(){state4();}
state8(){LaserOn();state++;retryCounter=3;}//打開激光器
state9(){
SendCommand(FocusUp);
state++;
timeout=MILLISECOND(2000);
}//光頭上舉,檢測(cè)聚焦過零3次,判斷cd是否存在
state10(){
if(FocusCrossZero){
systemStatus.Disc=EnumStatus_DiscExist;
SendCommand(EnumCommand_AutoFocusOn);//有cd,打開自動(dòng)聚焦。
state=0;//本任務(wù)結(jié)束。
playProcess.state=1;//啟動(dòng)play任務(wù)
}
elseif((--timeout)==0){
SendCommand(EnumCommand_FocusClose);//光頭聚焦復(fù)位
if((--retryCounter)==0){
systemStatus.Disc=EnumStatus_Nodisc;//無盤
displayProcess.state=EnumDisplayState_NoDisc;//顯示閃爍的無盤
LaserOff();
state=0;//任務(wù)停止
}
else
state--;//再試
}
}
stateStop(){
SendCommand(EnumCommand_SlidingMotorStop);
SendCommand(EnumCommand_FocusClose);
state=0;
}
網(wǎng)友評(píng)論:^_^
網(wǎng)友評(píng)論:如果象LZ這樣的高手被你一句話氣跑了,豈不是讓很多新手失去請(qǐng)教的機(jī)會(huì)?!!!
網(wǎng)友評(píng)論:為什么害死的是一只貓而不是一只老鼠或者別的???
網(wǎng)友評(píng)論:感謝樓主分享
網(wǎng)友評(píng)論:雖然很欣賞這種模式,可以降低功耗,但還是不愿意嘗試
貌似中斷服務(wù)程序還是簡(jiǎn)單點(diǎn)好
網(wǎng)友評(píng)論:不看好!
網(wǎng)友評(píng)論:處理一個(gè)跑馬燈程序可能這樣做可以。但是真的需要處理一些實(shí)時(shí)度要求高一點(diǎn)的程序就不可行了。
網(wǎng)友評(píng)論:這是典型的協(xié)作式,但是這樣做不安全,容易丟失時(shí)間片。建議中斷里面設(shè)置標(biāo)志,把那一大套移到外面,這樣更安全。
網(wǎng)友評(píng)論:不錯(cuò)!不錯(cuò)!!!!!!!!
網(wǎng)友評(píng)論:1.不是什么單片機(jī)都支持中斷嵌套,咱的意思,能放到外面的就不要放到中斷中,盡可能快的釋放中斷是中斷機(jī)制的本意
2.低功耗啥的和處理時(shí)間有關(guān),在終端中處理同樣不低功耗
網(wǎng)友評(píng)論:學(xué)習(xí)學(xué)習(xí)!!!!!!!!!!!!!
網(wǎng)友評(píng)論:非常歡迎來自五湖四海的朋友,電子技術(shù)交流群:29303696
網(wǎng)友評(píng)論:還沒有認(rèn)真地看,不過,粗略地看一下有點(diǎn)像RTX51的辦法。
RTX51就是用T0作時(shí)間中斷計(jì)時(shí)器,主程序就可以是一個(gè)maintask,然后給每個(gè)任務(wù)分配一定的運(yùn)行時(shí)間片,到時(shí)就中斷執(zhí)行別的任務(wù),
不知道我說的對(duì)不對(duì),我現(xiàn)在就新接手一個(gè)這樣的項(xiàng)目,遇到的問題是每個(gè)任務(wù)的運(yùn)行時(shí)間有比較嚴(yán)格的要求,不可以太長(zhǎng),想請(qǐng)問一下樓主你怎么預(yù)算一下每個(gè)task的執(zhí)行時(shí)間?
網(wǎng)友評(píng)論:收藏
網(wǎng)友評(píng)論:中斷復(fù)雜化與簡(jiǎn)約化并不矛盾,應(yīng)用不同,靈活選擇了
網(wǎng)友評(píng)論:沒法細(xì)細(xì)看完,樓主的意思是不是這樣的?(我不懂什么OS,操作系統(tǒng))
假設(shè)每5MS中斷一次,
中斷一次,做第1件事,要在5MS內(nèi)做完.做完空循環(huán).
中斷第2次,做第2件事,要在5MS內(nèi)做完.做完,做完空循環(huán).
中斷第3次,做第3件事,要在5MS內(nèi)做完.做完,做完空循環(huán).
...
中斷第N次,做第N件事,要在5MS內(nèi)做完.做完,清除中斷記數(shù)標(biāo)記.做完空循環(huán).
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
我在沒中斷的系統(tǒng)中這樣做:
計(jì)數(shù)器如果等于1,做第1件事,完成剛好200US,然后記數(shù)器加1.
計(jì)數(shù)器如果等于2,做第2件事,完成剛好200US,然后記數(shù)器加1.
計(jì)數(shù)器如果等于1,做第3件事,完成剛好200US,然后記數(shù)器加1.
...
計(jì)數(shù)器如果等于N,做第N件事,完成剛好200US,然后記數(shù)器清0.然后記數(shù)器加1.
網(wǎng)友評(píng)論:雖然我的觀點(diǎn)和樓主不同,我支持能在主程序做的絕不用中斷。例如按鍵去抖就用主程序周期,反正去抖有50%甚至更大的偏差都沒關(guān)系。
不過還是支持一下樓主原創(chuàng)。
網(wǎng)友評(píng)論:IC庫存管理軟件第一品牌,您的最佳選擇
要用就用“易管理”
“易管理”庫存管理系統(tǒng),輕松實(shí)現(xiàn)采購、銷售、詢價(jià)、客戶關(guān)系管理,銷售訂單合同等信息一體化管理,輕松實(shí)現(xiàn)庫存與貿(mào)易統(tǒng)一運(yùn)行。這是在國(guó)內(nèi)首次提出進(jìn)銷存貿(mào)易一體化的平臺(tái),這是領(lǐng)先全球的專享網(wǎng)絡(luò)平臺(tái)。
在激烈的市場(chǎng)競(jìng)爭(zhēng)中,如何提升企業(yè)市場(chǎng)競(jìng)爭(zhēng)力和自身形象,適應(yīng)社會(huì)各方面發(fā)展的需求,以及如何應(yīng)對(duì)新形勢(shì)、新挑戰(zhàn)?通過合理的企業(yè)信息化建設(shè)就可以讓你的企業(yè)插上騰飛的翅膀,它不但可以讓你的企業(yè)變得更高效,還可以讓您的企業(yè)具有更高的競(jìng)爭(zhēng)力!
隨著信息技術(shù)的發(fā)展,決戰(zhàn)IC市場(chǎng),信息在IC行業(yè)起著舉足輕重的作用,我們致力于專為IC行業(yè)的公司提供專業(yè)的全方位信息技術(shù)服務(wù)。
“易管理”,使您發(fā)現(xiàn)弊端,果斷解決
我們分析您的管理煩惱,為您尋求解決方案
想實(shí)時(shí)掌握公司的運(yùn)作情況嗎?
想節(jié)約時(shí)間將更多精力用于提升業(yè)務(wù)競(jìng)爭(zhēng)力嗎?
想隨時(shí)掌握客戶的銷售情況嗎?
想更有效的掌握庫存情況嗎?
想掌握復(fù)雜工作流程,從容知道處理方案嗎?
想排除加班處理繁雜財(cái)務(wù)工作的煩惱嗎??
企業(yè)在管理中遇到的問題
1、供應(yīng)商庫存管理混亂!
2、商業(yè)秘密的供應(yīng)商庫存信息給員工輕易帶走!
3、從前使用的庫存管理系統(tǒng),麻煩又不好用!
4、分公司數(shù)據(jù)無法共享!
5、詢報(bào)價(jià)記錄沒有存底,潛在客戶無法抓住!
。。。。。。。。。
我們擁有全國(guó)幾千客戶的優(yōu)異口碑見證,幫助你實(shí)時(shí)準(zhǔn)確的掌握公司庫存、客戶、財(cái)務(wù),業(yè)務(wù)的狀況。
聯(lián)系人:陳明亮
電子郵件:cml@eguanli.com
電 話:+86-755-83910101839102028306712183067044
移動(dòng)電話:13510964861
地 址:深圳市福田區(qū)深南中路6002號(hào)人民大廈5樓
網(wǎng) 址:http://www.iclook.cn
QQ:860736028
網(wǎng)友評(píng)論:想法不錯(cuò).
網(wǎng)友評(píng)論:還是比較贊成所長(zhǎng)的簡(jiǎn)約中斷
網(wǎng)友評(píng)論:板凳
網(wǎng)友評(píng)論:好像有處筆誤constFUNCTIONPTR[]tasks={
constFUNCTIONPTRtasks[]={
網(wǎng)友評(píng)論:不好理解,個(gè)人感覺:
時(shí)序的主次將完全顛倒;
而且系統(tǒng)可能變得很復(fù)雜;
是否放在中斷中CPU運(yùn)行的時(shí)間基本一樣,低功耗從何而來?
主程序往往耗時(shí)都很長(zhǎng),時(shí)序豈不是要大亂?
中斷中多安排一些例行性的動(dòng)作,如顯示,讀健,發(fā)聲等,這個(gè)是提倡的,但整個(gè)主程序搬過來,實(shí)在看不出什么好處。
網(wǎng)友評(píng)論:技術(shù)資料中心
匯集全球各大廠商的產(chǎn)品資料,從技術(shù)參數(shù)到應(yīng)用筆記、解決方案、應(yīng)用筆記等一應(yīng)俱全,搜索方式靈活,各種技術(shù)資料相互關(guān)聯(lián),資源集成度極高;同時(shí),為了幫助工程師獲得更多新技術(shù),ICBuy還將聯(lián)合各技術(shù)代理商開展在線技術(shù)培訓(xùn)。
億芯網(wǎng),簡(jiǎn)稱ICBuy,立足于通過互聯(lián)網(wǎng)為電子行業(yè)的用戶提供元器件相關(guān)信息服務(wù),內(nèi)容包括技術(shù)資料中心、工程樣片零售商城、市場(chǎng)供貨信息查詢?nèi)齻(gè)方面,為客戶提供從技術(shù)開發(fā)到小批量采購以及量產(chǎn)供應(yīng)商的選擇等一系列產(chǎn)品和信息服務(wù)。
相關(guān)鏈接:http://www.icbuy.com/
網(wǎng)友評(píng)論:樓主實(shí)在是把一件簡(jiǎn)單的事情復(fù)雜化了。如果能合理應(yīng)用“狀態(tài)機(jī)”的概念,所謂的多任務(wù)處理就能輕松實(shí)現(xiàn)。
網(wǎng)友評(píng)論:不錯(cuò),努力學(xué)習(xí)中
網(wǎng)友評(píng)論:這樣能保證時(shí)鐘的準(zhǔn)確?你能保證中斷里的任務(wù)能在這么短的時(shí)間內(nèi)完成?假如你用了液晶,有刷寫液晶任務(wù),他所耗用的時(shí)間早已經(jīng)夠定時(shí)器中段多次了。用這種方式,只能是任務(wù)少,且耗時(shí)短。
假如使用了ps2接口,而此時(shí)正在定時(shí)器中斷中處理任務(wù),當(dāng)ps2設(shè)備有請(qǐng)求時(shí),無法響應(yīng),應(yīng)此會(huì)錯(cuò)過這個(gè)響應(yīng)。此類對(duì)響應(yīng)要求苛刻的設(shè)備在這種系統(tǒng)中會(huì)很不可靠。
網(wǎng)友評(píng)論:雖然做過多年的單片機(jī)程序,還沒有想過原來可以這樣做,呵呵。。。
就像習(xí)慣了右手,卻忽視了左手也可以做一些事情,建議大家學(xué)習(xí)LZ變相思考的做法,沒準(zhǔn)能想出更好的辦法
與諸君共勉
網(wǎng)友評(píng)論:記號(hào)
網(wǎng)友評(píng)論:只是很多具體的情況是任務(wù)不多不復(fù)雜,這時(shí)所有任務(wù)都可以在中斷中完成。。。
網(wǎng)友評(píng)論:感覺不是個(gè)很好的一個(gè)構(gòu)架
當(dāng)然了,比沒有構(gòu)架好
網(wǎng)友評(píng)論:偶也是這么做的,就是有的觀點(diǎn)不敢茍同,個(gè)人認(rèn)為,一個(gè)時(shí)間片已經(jīng)足夠程序執(zhí)行了,想想12M晶振,平均每條語句算他2us,10ms一個(gè)時(shí)間片,可以執(zhí)行5000條語句,在狀態(tài)機(jī)的情況下并不是每條語句都執(zhí)行到的,一般的項(xiàng)目一個(gè)狀態(tài)執(zhí)行不可能5000條語句,好!執(zhí)行完跳出我可以讓它休眠,降低耗電,更重要的是增加的抗干擾性!偶覺得開門狗拉回來沒用,如果開門狗溢出,重啟,需要利用狀態(tài)機(jī)來返回,返回到原來執(zhí)行的狀態(tài)
網(wǎng)友評(píng)論:應(yīng)用的場(chǎng)合要求實(shí)時(shí)性高,用個(gè)狀態(tài)機(jī)機(jī)制好點(diǎn)。事件驅(qū)動(dòng),我不認(rèn)為中斷內(nèi)做太多的動(dòng)作,一般在中斷做個(gè)時(shí)間標(biāo)志或者處理一些響應(yīng)程度高的動(dòng)作。沒有必要復(fù)雜化
網(wǎng)友評(píng)論:中斷程序應(yīng)該做盡可能少的事情。
前后臺(tái)系統(tǒng)中,我喜歡這樣。
voidmain(void)
{
while(1)
{
Sleep();
SystemCounter++;
switch(status)
{
//各個(gè)任務(wù)......
}
}
}
網(wǎng)友評(píng)論:學(xué)習(xí)了。多謝LS
網(wǎng)友評(píng)論:不過用中斷要小心!
網(wǎng)友評(píng)論:超宏達(dá)科技是一家專業(yè)的電子元器件代理商(www.super-grand.net),主要是NXP、ATMEL、ST、FAIRCHILD、NS、MICROCHIP、Winbond、Rohm、JRC、SAMSUNG、IR、UTC的代理,公司強(qiáng)大的技術(shù)支持和電子商務(wù)平臺(tái),可以解決電子元器件BOM表一站式打樣和在線詢價(jià),詳細(xì)資料請(qǐng)登陸www.super-grand.net,電話:83219636傳真:83261186
網(wǎng)友評(píng)論:
voidmain(void)
{
ucharbuffer=SmartOption[0];//SmartOption
system_init();
receiver_init();
while(1)
{
keyscan_thread();
key_handle_therad();
minder_thread();
RF_encode_thread();
idle();
};
}
網(wǎng)友評(píng)論:有點(diǎn)操作系統(tǒng)的味道了