最簡(jiǎn)單的51單片機(jī)多任務(wù)代碼
;由于使用了多個(gè)棧,調(diào)用時(shí)不能有太多的嵌套調(diào)用,以免超出棧的工作區(qū)(48個(gè)字節(jié)),使程序出錯(cuò)。
;這個(gè)程序只是為了做個(gè)多任務(wù)的試驗(yàn),實(shí)用性還有侍驗(yàn)證。
;當(dāng)然這種思路是來自PC操作系統(tǒng),我個(gè)人認(rèn)為把PC編程上的事件驅(qū)動(dòng)引入51是一種很好的方法。
;在另一程序內(nèi)已使用過,感覺還不錯(cuò)。(感興趣的朋友可向我索?。?br />;----------------------------------------------
;由于我用的MCS51程序有BUG,在調(diào)試時(shí)MCS51軟件的棧區(qū)數(shù)變化和數(shù)據(jù)區(qū)不一至。即:棧區(qū)數(shù)變化
;了對(duì)應(yīng)的數(shù)據(jù)區(qū)數(shù)據(jù)沒有按實(shí)際的應(yīng)同時(shí)變化(因用的是同一存儲(chǔ)空間)。
;(實(shí)際兩數(shù)據(jù)的地址和內(nèi)容都是相同的,只是模擬軟件內(nèi)部不同步)。要用手動(dòng)改寫才能正常工作。
;具體方法是:棧區(qū)數(shù)據(jù)變化時(shí)手動(dòng)改寫數(shù)據(jù)區(qū)對(duì)應(yīng)地址的數(shù)據(jù)與棧內(nèi)數(shù)據(jù)對(duì)應(yīng)。
;請(qǐng)使用該軟件的朋友用到棧區(qū)模擬調(diào)試時(shí)注意(否則程序就會(huì)飛掉)。
;----------------------------------------------
org 0000h;www.51hei.com2004.6028-89951522
;mail:xch1106@163.comQQ:15552363
jmp zcx;去主程序
org 001bh
call tim;定時(shí)中斷1入口
reti
zcx:
mov sp,#60h;置任務(wù)1棧頂位置,任務(wù)2 90h,任務(wù)3 0c0h
mov tmod,#10h;設(shè)定時(shí)器1工作方式2
mov th1,#0f3h;設(shè)高位初值
mov tl1,#00h;設(shè)低位初值
setb ea;開中斷
setb et1;開定時(shí)中斷
setb tr1;開啟計(jì)數(shù)器
mov 00h,#00h;任務(wù)計(jì)數(shù)器初始化
clr 00h;全部棧初始化完成標(biāo)志清0
clr 01h;任務(wù)1棧初始化標(biāo)志位清0
clr 02h;任務(wù)2棧初始化標(biāo)志位清0
clr 03h;任務(wù)3棧初始化標(biāo)志位清0
setb rs0;選擇寄存器組
clrrs1
;==============================
cshsp1: jnb 01h,$;等侍定時(shí)中斷,以便自動(dòng)初始化任務(wù)1棧數(shù)據(jù)
;mov 01h,sp
jb 00h,main1;全部棧區(qū)數(shù)據(jù)初始化完成則進(jìn)入任務(wù)1
jmp cshsp2;否則->初始化任務(wù)2
main1:;任務(wù)1
nop;你的代碼
nop
nop
nop
nop
jmp main1
;-------------------------------
cshsp2: mov sp,#90h;置任務(wù)2棧頂位置
jnb 02h,$;等侍定時(shí)中斷,以便自動(dòng)初始化任務(wù)2棧數(shù)據(jù)
;mov 02h,sp
jb 00h,main2;全部棧區(qū)數(shù)據(jù)初始化完成則進(jìn)入任務(wù)2
jmp cshsp3
main2:;任務(wù)2
nop
nop
nop
nop
nop
jmp main2
;---------------------------------------
cshsp3: mov sp,#0c0h;置任務(wù)3棧頂位置
jnb 03h,$;等侍定時(shí)中斷,以便自動(dòng)初始化任務(wù)3棧數(shù)據(jù)
;mov 03h,sp;全部棧區(qū)數(shù)據(jù)初始化完成則進(jìn)入任務(wù)3
main3:;任務(wù)3
nop
nop
nop
nop
nop
jmp main3
;;===========================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
tim:push a;定時(shí)1中斷子程序
push psw
clr tr1;關(guān)閉定時(shí)器
clr et1;關(guān)閉定時(shí)中斷
;使用資源:定時(shí)器1,定時(shí)器1中斷,0組寄存器,
clr rs0;選擇寄存器組
clr rs1
mov th1,#0f3h;設(shè)高位初值 (中斷時(shí)間的長(zhǎng)短)
mov tl1,#00h;設(shè)低位初值 (在操作系統(tǒng)中可能叫時(shí)間片參數(shù))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
jb 00h,rwqh;00H為1則初始化已完成(初始化只進(jìn)行3次中斷即全部初始化1次)
;就不再進(jìn)行初始化,而進(jìn)行任務(wù)切換操作
;------------------- sp 1 2 3初始化棧數(shù)據(jù)
jb 01h,stsp1
mov 01h,sp;保存當(dāng)前的棧位置(任務(wù)1)
;讀取當(dāng)前棧內(nèi)容并全部重壓入1次。
;相當(dāng)于在棧區(qū)做了一次備份,任務(wù)切換時(shí)使用
;本次中斷返回時(shí)將彈出原來的數(shù)據(jù),備份的則還在棧內(nèi)。
push 61h
push 62h
push 63h
push 64h
push 65h
push 66h
setb 01h
jmp end1
stsp1:
jb 02h,stsp2
mov 02h,sp;保存當(dāng)前的棧位置(任務(wù)2)
;讀取當(dāng)前棧內(nèi)容并全部重壓入1次。
push 91h
push 92h
push 93h
push 94h
push 95h
push 96h
setb 02h
jmp end1
stsp2:
jb 03h,rwqh
mov 03h,sp;保存當(dāng)前的棧位置(任務(wù)3)
;讀取當(dāng)前棧內(nèi)容并全部重壓入1次。(初始化棧區(qū)數(shù)據(jù)的方法)
push 0c1h
push 0c2h
push 0c3h
push 0c4h
push 0c5h
push 0c6h
setb 03h
setb 00h
jmp end1
;-------------------
rwqh:
;;;;;;;;;;;;;;;;;;;切換任務(wù),每中斷1次切換1次。
inc 00h;任務(wù)計(jì)數(shù)
cjne r0,#01h,rwqh2;當(dāng)前任務(wù)為3切換到任務(wù)1(改變SP位置,得到切換任務(wù)的目的)
mov 03h,sp
mov sp,01h
rwqh2:
cjne r0,#02h,rwqh3;當(dāng)前任務(wù)為1切換到任務(wù)2
mov 01h,sp
mov sp,02h
rwqh3:
cjne r0,#03h,end1;當(dāng)前任務(wù)為2切換到任務(wù)3
mov 02h,sp
mov sp,03h
mov 00h,#00h
end1:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
setb et1
setb tr1
pop psw
pop a
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
參考資料:http://www.51hei.com/mcu/1325.html
評(píng)論