兩個延遲副程式的問題 |
答題得分者是:阿信
|
albeeboy
一般會員 發表:7 回覆:20 積分:5 註冊:2009-08-02 發送簡訊給我 |
小弟的倒數計時器現在多加了一個蜂鳴器,是給電壓就會響的那種,
小弟想要蜂鳴器在倒數完時響個幾秒,現在也成功了,但是小弟一開始就有一個 延遲的副程式,然後又寫了一個倒數完響差不多4秒的延遲副程式,不知道是不是這兩個副程式 會互相影響,在倒數完時,蜂鳴器會叫,但七段顯示器只亮了一顆,直到響完時才會變成(00:00), 是不能寫2個延遲副程式嗎??請各位大大指導下,謝謝! 片段程式如下: TIMER0: PUSH PSW ; PUSH A ; SETB RS0 ;\使用BANK3 SETB RS1 ;/ MOV TL0,#<(65536-50000) ;計時器初始值50MS中斷一次 MOV TH0,#>(65536-50000) ; MOV A,TIMEUP0 ;TIMER0 每50MS中斷一次 DEC A ;20次中斷遞減 MOV TIMEUP0,A ; CJNE A,#0,OUT ;A不等於零就跳 MOV TIMEUP0,#20 ;20中斷重算 ;-------------------------------------- MOV A,TIME_S ;讀秒數 DEC A ;秒數減一 CJNE A,#0FFH,SS1 ;本來X:00-->X:59 TIME_S"00"-1 出現A=FF即是要借位這時分鐘減一. MOV R1,A ;A=FFH R1=FFH MOV A,TIME_M ;TIME_M=19H把TIME_M值給A DEC A ;A=18H MOV B,A ;SAVE A 修正分鐘的時間 ANL A,#0FH ;取個位數值 CJNE A,#0FH,G10 ;判斷個位數是否為0FH,不等於跳到G10 A=08 B=18H MOV A,B ; ANL A,#F0H ;\ ORL A,#09H ;|等於F則個位數設9 MOV B,A ;/ G10: MOV A,B ;B=18H,A=18H MOV TIME_M,A ;轉回修正好的時間回TIME_M MOV A,R1 ;R1=FFH A=FFH SS1: MOV B,A ;SAVE A 修正秒的時間 A=FFH B=FFH ANL A,#0FH ;取個位數值 CJNE A,#0FH,G20 ;判斷個位數是否為0FH A=0FH做下一句 MOV A,B ;B=FFH,A=FFH ANL A,#F0H ;\ ORL A,#09H ;|等於F則個位數設9 MOV B,A ;/A=F9H B=F9H ANL A,#F0H ;取十位數值 CJNE A,#F0H,G20 ;判斷十位數是否為F0H A=F0H做下一句 MOV A,B ;A=F9H B=F9H ANL A,#0FH ;\A=09H ORL A,#50H ;|等於F則十位數設5 MOV B,A ;/A=59H B=59H G20: MOV A,B ;A=59H B=59H MOV TIME_S,A ;轉回修正好的時間回TIME_S MOV R0,TIME_M ;讀取分鐘 CJNE R0,#00H,OUT ;判斷分鐘是否倒數完 否則跳出 CJNE A,#00H, OUT ;判斷秒鐘是否倒數完 否則跳出 MOV TIME_M,#0 ;分為0 MOV TIME_S,#0 ;秒為0 CLR TR0 ;暫停計時 CPL P2.7 ;蜂鳴器響 CALL DE1 ; CLR P2.7 ;停止蜂鳴器響 ;----------------------------------------- OUT: POP A ; POP PSW ; RETI ; ;------------------------------------------蜂鳴器延遲副程式(1) DE1: MOV R2,#50 $3: MOV R1,#200 $2: MOV R0,#200 $1: DJNZ R0,$1 DJNZ R1,$2 DJNZ R2,$3 RET : : : : : : : DELAY: MOV R6,#06H ; 延遲副程式(原來的) DEY: MOV R7,#FFH ; $1: DJNZ R7,$1 ; DJNZ R6,DEY ; MOV P1,#FFH ; MOV P0,#00H ; MOV R6,#20H ; $2: NOP ; DJNZ R6,$2 ; RET ; ; ; ; ; ; ; ; 需完整程式跟小弟說一聲,馬上補上!!
------
滴滴儒 |
mymj
版主 發表:132 回覆:486 積分:608 註冊:2002-10-25 發送簡訊給我 |
|
阿信
版主 發表:111 回覆:983 積分:813 註冊:2005-03-10 發送簡訊給我 |
|
albeeboy
一般會員 發表:7 回覆:20 積分:5 註冊:2009-08-02 發送簡訊給我 |
|
albeeboy
一般會員 發表:7 回覆:20 積分:5 註冊:2009-08-02 發送簡訊給我 |
|
alice12345
一般會員 發表:0 回覆:1 積分:0 註冊:2009-09-10 發送簡訊給我 |
|
albeeboy
一般會員 發表:7 回覆:20 積分:5 註冊:2009-08-02 發送簡訊給我 |
|
阿信
版主 發表:111 回覆:983 積分:813 註冊:2005-03-10 發送簡訊給我 |
我看懂你的程式了,
你在中斷副程式中執行了 CALL DE1的延遲副程式。 這是不好的! 基本上單晶片流程中最重要的 就是計時器的使用。 以你的程式而言, 你應該在主程式中設定一個變數做為計時, 如七段顯示器的掃描頻率是50Hz, 那要Delay 4秒,即計數200。 所以在程式初始時宣告一個變數, 假設為DCNT,且在初始時設為200, 及一個位元變數fg_Time0,初值為0。 中斷程式中,當計數到0秒時, 將位元變數fg_Time0設為1。 主程式中,每次執行七段顯示器掃描時 檢查fg_Time0是否為1, 若為1則{ 啟動蜂鳴器; DCNT=DCNT-1; if (DCNT==0) {fg_Time0=0l; 停止蜂鳴器;} } 阿信~ |
albeeboy
一般會員 發表:7 回覆:20 積分:5 註冊:2009-08-02 發送簡訊給我 |
阿信版主妳說的主程式是指延遲副程式嗎??
還是TIMER0運算副程式,我依你的做法去寫,可是 程式執行完蜂鳴器式一直叫,不會停,如果我要延遲四秒, 應該是要給CONT直給80吧,因為我的TIMER0裡面是每中斷一次50MS ,中斷20次就一秒,所以應該是給80吧,為什麼要設200,我寫的程式如下: 可以幫我看一下嗎??謝謝,需要完整程式跟小弟說一聲,馬上附上. TIMEUP0 EQU 30H ;變數定義區 TIME_S EQU 31H TIME_M EQU 32H TMP0 EQU 33H TMP1 EQU 34H DCNT EQU 35H FG_TIME0 REG P2.7 ;****************************常數定義區(七段顯示碼) SEG_0 EQU 3FH ;1亮0暗 SEG_1 EQU 06H SEG_2 EQU 5BH SEG_3 EQU 4FH SEG_4 EQU 66H SEG_5 EQU 6DH SEG_6 EQU 7DH SEG_7 EQU 07H SEG_8 EQU 7FH SEG_9 EQU 6FH ;***************************************** ORG 0000H ;程式起點 LJMP START ; ;------------------------------------------------------------- ORG 000BH ;若計時器0中斷 AJMP TIMER0 ;則跳到TIMER0,執行完後回START ;####################################### START: MOV P0,#00H ;P0,P1,P2,P3初始值設定 MOV P1,#FFH ; MOV P2,#00H ; MOV P3,#00H ; MOV SP,#50H ;堆疊指標暫存器 MOV TIMEUP0,#20 ; MOV DCNT,#200 ; CLR RS0 ;使用第0組通用暫存器 CLR RS1 ;00H~07H MOV TIME_S,#00H ;秒初始設定 MOV TIME_M,#00H ;分初始設定 MOV TMOD,#00010001B ;計時器模式控制(模式1) MOV IE,#10001010B ;計時器中斷 CLR FG_TIME0 ; CLR TR0 ;未開始計時 ;--------------------------------------- MAIN1: CALL ADJ_T1 ;呼叫顯示時間副程式 ;--------------------------------------- NO1: CALL TESTSW ;偵測SW LJMP MAIN1 ; ;******************************************* TIMER0: PUSH PSW ; PUSH A ; SETB RS0 ;\使用BANK3 SETB RS1 ;/ MOV TL0,#<(65536-50000) ;計時器初始值50MS中斷一次 MOV TH0,#>(65536-50000) ; MOV A,TIMEUP0 ;TIMER0 每50MS中斷一次 DEC A ;20次中斷遞減 MOV TIMEUP0,A ; CJNE A,#0,OUT ;A不等於零就跳 MOV TIMEUP0,#20 ;20中斷重算 ;--------------------------------------- MOV A,TIME_S ;讀秒數 DEC A ;秒數減一 CJNE A,#0FFH,SS1 ;本來X:00-->X:59 TIME_S"00"-1 出現A=FF即是要借位這時分鐘減一. MOV R1,A ;A=FFH R1=FFH MOV A,TIME_M ;TIME_M=19H把TIME_M值給A DEC A ;A=18H MOV B,A ;SAVE A 修正分鐘的時間 ANL A,#0FH ;取個位數值 CJNE A,#0FH,G10 ;判斷個位數是否為0FH,不等於跳到G10 A=08 B=18H MOV A,B ; ANL A,#F0H ;\ ORL A,#09H ;|等於F則個位數設9 MOV B,A ;/ G10: MOV A,B ;B=18H,A=18H MOV TIME_M,A ;轉回修正好的時間回TIME_M MOV A,R1 ;R1=FFH A=FFH SS1: MOV B,A ;SAVE A 修正秒的時間 A=FFH B=FFH ANL A,#0FH ;取個位數值 CJNE A,#0FH,G20 ;判斷個位數是否為0FH A=0FH做下一句 MOV A,B ;B=FFH,A=FFH ANL A,#F0H ;\ ORL A,#09H ;|等於F則個位數設9 MOV B,A ;/A=F9H B=F9H ANL A,#F0H ;取十位數值 CJNE A,#F0H,G20 ;判斷十位數是否為F0H A=F0H做下一句 MOV A,B ;A=F9H B=F9H ANL A,#0FH ;\A=09H ORL A,#50H ;|等於F則十位數設5 MOV B,A ;/A=59H B=59H G20: MOV A,B ;A=59H B=59H MOV TIME_S,A ;轉回修正好的時間回TIME_S MOV R0,TIME_M ;讀取分鐘 CJNE R0,#00H,OUT ;判斷分鐘是否倒數完 否則跳出 CJNE A,#00H, OUT ;判斷秒鐘是否倒數完 否則跳出 CLR TR0 ;暫停計時器 SETB FG_TIME0 ; AJMP TT ; ;----------------------------------------- OUT: POP A ; POP PSW ; RETI ; ;--------------------------------------- TT: MOV A,DCNT ;把DCNT直給A DEC A ;做減一的動作 MOV DCNT,A ;把A直給DCNT CJNE A,#0,OUT ;判斷A是否為0 CLR FG_TIME0 ; MOV DCNT,#200 ;DCNT200重算 RET; ; ; ; ; ; DELAY: MOV R6,#06H ;延遲副程式 DEY: MOV R7,#FFH ; $1: DJNZ R7,$1 ; DJNZ R6,DEY ; MOV P1,#FFH ; MOV P0,#00H ; MOV R6,#20H ; $2: NOP ; DJNZ R6,$2 ; RET ;
------
滴滴儒 |
albeeboy
一般會員 發表:7 回覆:20 積分:5 註冊:2009-08-02 發送簡訊給我 |
現在已經可以倒數完響一段時間了,可是有
個問題就是比如說我設想4秒,但是重複一兩次後 ,有時候也會嗶個一聲就沒了,也就是每次響的時間 長度不一樣,請各位大大幫幫我啊!! 程式如下: TIMER0: PUSH PSW ; PUSH A ; SETB RS0 ;\使用BANK3 SETB RS1 ;/ MOV TL0,#<(65536-50000) ;計時器初始值50MS中斷一次 MOV TH0,#>(65536-50000) ; MOV A,TIMEUP0 ;TIMER0 每50MS中斷一次 DEC A ;20次中斷遞減 MOV TIMEUP0,A ; CJNE A,#0,OUT ;A不等於零就跳 MOV TIMEUP0,#20 ;20中斷重算 ;--------------------------------------- MOV A,TIME_S ;讀秒數 DEC A ;秒數減一 CJNE A,#0FFH,SS1 ;本來X:00-->X:59 TIME_S"00"-1 出現A=FF即是要借位這時分鐘減一. MOV R1,A ;A=FFH R1=FFH MOV A,TIME_M ;TIME_M=19H把TIME_M值給A DEC A ;A=18H MOV B,A ;SAVE A 修正分鐘的時間 ANL A,#0FH ;取個位數值 CJNE A,#0FH,G10 ;判斷個位數是否為0FH,不等於跳到G10 A=08 B=18H MOV A,B ; ANL A,#F0H ;\ ORL A,#09H ;|等於F則個位數設9 MOV B,A ;/ G10: MOV A,B ;B=18H,A=18H MOV TIME_M,A ;轉回修正好的時間回TIME_M MOV A,R1 ;R1=FFH A=FFH SS1: MOV B,A ;SAVE A 修正秒的時間 A=FFH B=FFH ANL A,#0FH ;取個位數值 CJNE A,#0FH,G20 ;判斷個位數是否為0FH A=0FH做下一句 MOV A,B ;B=FFH,A=FFH ANL A,#F0H ;\ ORL A,#09H ;|等於F則個位數設9 MOV B,A ;/A=F9H B=F9H ANL A,#F0H ;取十位數值 CJNE A,#F0H,G20 ;判斷十位數是否為F0H A=F0H做下一句 MOV A,B ;A=F9H B=F9H ANL A,#0FH ;\A=09H ORL A,#50H ;|等於F則十位數設5 MOV B,A ;/A=59H B=59H G20: MOV A,B ;A=59H B=59H MOV TIME_S,A ;轉回修正好的時間回TIME_S MOV R0,TIME_M ;讀取分鐘 CJNE R0,#00H,OUT ;判斷分鐘是否倒數完 否則跳出 CJNE A,#00H, OUT ;判斷秒鐘是否倒數完 否則跳出 CLR TR0 ; CPL P2.7 ; ;----------------------------------------- OUT: POP A ; POP PSW ; RETI ; : : : : ADJ_T1: MOV TMP0,TIME_S ;儲存秒 MOV TMP1,TIME_M ;儲存分 MOV A,DCNT ;蜂鳴器響的時間 DEC A ; MOV DCNT,A ; CJNE A,#0,LOOP ; CLR P2.7 ; MOV DCNT,#200 ; AJMP LOOP ; LOOP: MOV A,TMP0 ;讀秒鐘 ANL A,#0FH ;秒鐘個位數生效 CALL GET_7 ;取得七段顯示碼 MOV P1,A ;節點輸出顯示 MOV P0,#01H ;秒鐘個位數日字生效 CALL DELAY ;呼叫時間顯示副程式 ;--------------------------------------- MOV A,TMP0 ;讀秒鐘 SWAP A ;取秒鐘十位數 ANL A,#0FH ;秒鐘十位數生效 CALL GET_7 ;取得七段顯示碼 MOV P1,A ;節點輸出顯示 MOV P0,#02H ;秒鐘十位數日字生效 CALL DELAY ;呼叫時間顯示副程式 ;----------------------------------------- MOV A,TMP1 ;讀分鐘 ANL A,#0FH ;分鐘個位數生效 CALL GET_7 ;取得七段顯示碼 MOV P1,A ;節點輸出顯示 MOV P0,#04H ;分鐘個位數日字生效 CALL DELAY ;呼叫時間顯示副程式 ;--------------------------------------- MOV A,TMP1 ;讀分鐘 SWAP A ;取分鐘十位數 ANL A,#0FH ;分鐘十位數生效 CALL GET_7 ;取得七段顯示碼 MOV P1,A ;節點輸出顯示 MOV P0,#08H ;分鐘十位數日字生效 CALL DELAY ;呼叫時間顯示副程式 ;--------------------------------------- RET End
------
滴滴儒 |
albeeboy
一般會員 發表:7 回覆:20 積分:5 註冊:2009-08-02 發送簡訊給我 |
TIMER0: PUSH PSW ;
PUSH A ; SETB RS0 ;\使用BANK3 SETB RS1 ;/ MOV TL0,#<(65536-50000) ;計時器初始值50MS中斷一次 MOV TH0,#>(65536-50000) ; MOV A,TIMEUP0 ;TIMER0 每50MS中斷一次 DEC A ;20次中斷遞減 MOV TIMEUP0,A ; CJNE A,#0,OUT ;A不等於零就跳 MOV TIMEUP0,#20 ;20中斷重算 ;--------------------------------------- MOV A,TIME_S ;讀秒數 DEC A ;秒數減一 CJNE A,#0FFH,SS1 ;本來X:00-->X:59 TIME_S"00"-1 出現A=FF即是要借位這時分鐘減一. MOV R1,A ;A=FFH R1=FFH MOV A,TIME_M ;TIME_M=19H把TIME_M值給A DEC A ;A=18H MOV B,A ;SAVE A 修正分鐘的時間 ANL A,#0FH ;取個位數值 CJNE A,#0FH,G10 ;判斷個位數是否為0FH,不等於跳到G10 A=08 B=18H MOV A,B ; ANL A,#F0H ;\ ORL A,#09H ;|等於F則個位數設9 MOV B,A ;/ G10: MOV A,B ;B=18H,A=18H MOV TIME_M,A ;轉回修正好的時間回TIME_M MOV A,R1 ;R1=FFH A=FFH SS1: MOV B,A ;SAVE A 修正秒的時間 A=FFH B=FFH ANL A,#0FH ;取個位數值 CJNE A,#0FH,G20 ;判斷個位數是否為0FH A=0FH做下一句 MOV A,B ;B=FFH,A=FFH ANL A,#F0H ;\ ORL A,#09H ;|等於F則個位數設9 MOV B,A ;/A=F9H B=F9H ANL A,#F0H ;取十位數值 CJNE A,#F0H,G20 ;判斷十位數是否為F0H A=F0H做下一句 MOV A,B ;A=F9H B=F9H ANL A,#0FH ;\A=09H ORL A,#50H ;|等於F則十位數設5 MOV B,A ;/A=59H B=59H G20: MOV A,B ;A=59H B=59H MOV TIME_S,A ;轉回修正好的時間回TIME_S MOV R0,TIME_M ;讀取分鐘 CJNE R0,#00H,OUT ;判斷分鐘是否倒數完 否則跳出 CJNE A,#00H, OUT ;判斷秒鐘是否倒數完 否則跳出 CLR TR0 ; CPL P2.7 ; ;----------------------------------------- OUT: POP A ; POP PSW ; RETI ; : : : : ADJ_T1: MOV TMP0,TIME_S ;儲存秒 MOV TMP1,TIME_M ;儲存分 MOV A,DCNT ;蜂鳴器響的時間 DEC A ; MOV DCNT,A ; CJNE A,#0,LOOP ; CLR P2.7 ; MOV DCNT,#200 ; AJMP LOOP ; LOOP: MOV A,TMP0 ;讀秒鐘 ANL A,#0FH ;秒鐘個位數生效 CALL GET_7 ;取得七段顯示碼 MOV P1,A ;節點輸出顯示 MOV P0,#01H ;秒鐘個位數日字生效 CALL DELAY ;呼叫時間顯示副程式 ;--------------------------------------- MOV A,TMP0 ;讀秒鐘 SWAP A ;取秒鐘十位數 ANL A,#0FH ;秒鐘十位數生效 CALL GET_7 ;取得七段顯示碼 MOV P1,A ;節點輸出顯示 MOV P0,#02H ;秒鐘十位數日字生效 CALL DELAY ;呼叫時間顯示副程式 ;----------------------------------------- MOV A,TMP1 ;讀分鐘 ANL A,#0FH ;分鐘個位數生效 CALL GET_7 ;取得七段顯示碼 MOV P1,A ;節點輸出顯示 MOV P0,#04H ;分鐘個位數日字生效 CALL DELAY ;呼叫時間顯示副程式 ;--------------------------------------- MOV A,TMP1 ;讀分鐘 SWAP A ;取分鐘十位數 ANL A,#0FH ;分鐘十位數生效 CALL GET_7 ;取得七段顯示碼 MOV P1,A ;節點輸出顯示 MOV P0,#08H ;分鐘十位數日字生效 CALL DELAY ;呼叫時間顯示副程式 ;--------------------------------------- RET End
------
滴滴儒 |
阿信
版主 發表:111 回覆:983 積分:813 註冊:2005-03-10 發送簡訊給我 |
>阿信版主妳說的主程式是指延遲副程式嗎??
主程式就是主程式! 「START:」之後的程式 你的程式架構: [code cpp] 主程式 { 初始化; while (1) { ADJ_T1(); 按鍵; } } 時間中斷50mS { if (--TIMEUP0==0) { TIMEUP0=20; 倒數1秒(TIME_M,TIME_S); if (TIME_M==0 && TIME_S==0) { 停止計時; CPL P2.7; //蜂鳴器反相 } } } ADJ_T1() { if (--DCNT==0) { CLR P2.7; //停止蜂鳴器 DCNT=200; } 顯示秒個位數; 延遲; 顯示秒十位數; 延遲; 顯示分個位數; 延遲; 顯示分十位數; 延遲; } [/code] ===================== 你可以重新說一遍,你要做怎麼樣的動作嗎? FG_TIME0 REG P2.7 <--- 蜂鳴器怎麼會又等於FG_TIMER0呢? |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |