全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1775
推到 Plurk!
推到 Facebook!

請教有關組合語言寫計時器按鈕的問題

答題得分者是:foreman
albeeboy
一般會員


發表:7
回覆:20
積分:5
註冊:2009-08-02

發送簡訊給我
#1 引用回覆 回覆 發表時間:2009-08-02 21:42:35 IP:114.40.xxx.xxx 訂閱
我寫了一個計時器的程式,這個計時器有時分秒,並且有三個彈跳按鈕去控制它,sw1(啟動計時),sw2(暫停計時),
sw3(重置),分別接在89c51的P2.0,P2.1與P2.2,這個計時器一開始並不啟動(七段顯示器顯示00:00:00:)
必須按下SW1才開始計時,我把電路接在麵包板上,實體會動,但遇到了下面2個問題:
一.當我按下任何一個按鈕,七段顯示器會閃一下,之後才會出現我需要的動作(也就是說我按下啟動並且放開會閃一下)
如果一直按著按鈕則七段顯示器不顯示,直到放開才顯示,請問這是正常的嗎?如果不是,我該如何修改。
二.這個計時器可以啟動暫停交互運作(也就是說啟動=>暫停=>啟動=>暫停=>啟動.....),但是如果啟動暫停交互五次完,在第六次,我按下啟
動,七段顯示器會自動變回一開始的狀態(00:00:00),我要的是啟動暫停可以一直交互運作,請大家幫我一下。
程式如下:
TIMEUP0 EQU 30H ;變數定義區
TIME_S EQU 31H
TIME_M EQU 32H
TIME_H EQU 33H
TMP0 EQU 37H
TMP1 EQU 38H
TMP2 EQU 39H
BUFR0 EQU 3AH
BUFR1 EQU 3BH
BUFR2 EQU 3CH
BUFR3 EQU 3DH
BUFR4 EQU 3EH
BUFR5 EQU 3FH
BUFR6 EQU 40H
BUFR7 EQU 41H
BUFA EQU 42H
BUFDPH EQU 43H
BUFDPL EQU 44H
BUFSO1 EQU 45H
BUFSO2 EQU 46H
;******************常數定義區(七段顯示碼)
SEG_NO EQU 00H ;1亮0暗
SEG_0 EQU 3FH
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,#80H ;
MOV P3,#40H ;
MOV SP,#50H ; 堆疊指標暫存器
MOV TIMEUP0,#20 ;
CLR RS0 ; 使用第0組通用暫存器
CLR RS1 ; 00H~07H
MOV TIME_S,#00H ;
MOV TIME_M,#00H ;
MOV TIME_H,#00H ;
MOV TMOD,#00010001B ; 計時器模式控制(模式1)
MOV IE,#10001010B ; 計時器中斷
CLR TR0 ; 未開始計時
;---------------------------------------
MAIN1 CALL ADJ_T1 ;
;---------------------------------------
NO1 CALL TESTSW ;偵測SW
LJMP MAIN1
;*******************************************
TSS_END AJMP TS_END
TOO_END AJMP T1_END
TMM_END AJMP TM_END
THH_END AJMP TH_END
TIMER0 PUSH PSW ; 計時器0中斷程式
PUSH A ;
SETB RS0 ; 使用暫存器組3
SETB RS1 ; 佔用18~1F
MOV TL0,#<(65536-49990) ;
MOV TH0,#>(65536-49990) ;
MOV A,TIMEUP0 ;\
DEC A ;TIMEUP0減一
MOV TIMEUP0,A ; /
CJNE A,#10,GODOWN ;A等於10就執行
CPL A ; 取補數
GODOWN CJNE A,#0,TOO_END ;A不等於0就到TOO_END
MOV TIMEUP0,#20 ;
CPL A ;
;----------------------------------------
MOV A,TIME_S ; 讀取目前秒數
ADD A,#1 ; 秒數加1
DA A ; 進行BCD調整
CJNE A,#60H,TSS_END ; A不等於60就跳
MOV TIME_S,#0 ; A等於60就歸零
MOV A,TIME_M ;
ADD A,#1 ;
DA A ;
CJNE A,#60H,TMM_END ;
MOV TIME_M,#0 ;
MOV A,TIME_H ;
ADD A,#1 ;
DA A ;
CJNE A,#24H,THH_END ;
MOV TIME_H,#0 ;
MOV A,TIME_H ;
;----------------------------------------
TS_END MOV TIME_S,A ; \秒數加一
AJMP T1_END ; /
TM_END MOV TIME_M,A ; \分鐘加一
AJMP T1_END ; /
TH_END MOV TIME_H,A ; \小時加一
AJMP T1_END ; /
T1_END CLR RS0 ;
CLR RS1 ;
POP A ;
POP PSW ;
RETI
;############################偵測SW副程式
TESTSW JB P2.0,SET_STAR ; if SW1 ON, 跳到SET_STAR
JB P2.1,SET_STOP ; if SW2 ON, 跳到SET_STOP
JB P2.2,SET_RESET ; if SW2 ON, 跳到SET_RESET
RET
;---------------------------------------
SET_STAR JB P2.0,$ ;
SETB TR0 ;
ACALL MAIN1 ;
ACALL DELAY ;
JNB P2.0,$ ;
ACALL DELAY ;
RET ;
;--------------------------------------------
SET_STOP JB P2.1,$ ;
CLR TR0 ;
ACALL MAIN1 ;
ACALL DELAY ;
JNB P2.1,$ ;
ACALL DELAY ;
RET ;
;------------------------------------------
SET_RESET JB P2.2,$ ;
AJMP START ;
RET ;
;---------------------------------------------SW延遲
DELAY MOV R6,#06H
DEY MOV R7,#FFH
$1 DJNZ R7,$1 ;R7減1,若不為0,跳到$1
DJNZ R6,DEY
MOV P1,#FFH
MOV P0,#00H
MOV R6,#20H
$2 NOP
DJNZ R6,$2
RET
;--------------------------------------------資料暫存
REGSAVE MOV BUFR0,R0
MOV BUFR1,R1
MOV BUFR2,R2
MOV BUFR3,R3
MOV BUFR4,R4
MOV BUFR5,R5
MOV BUFR6,R6
MOV BUFR7,R7
MOV BUFA,A
MOV BUFDPH,DPH
MOV BUFDPL,DPL
RET
;------------------------------------------------資料取回
REGBACK MOV R0,BUFR0
MOV R1,BUFR1
MOV R2,BUFR2
MOV R3,BUFR3
MOV R4,BUFR4
MOV R5,BUFR5
MOV R6,BUFR6
MOV R7,BUFR7
MOV A,BUFA
MOV DPH,BUFDPH
MOV DPL,BUFDPL
RET
;----------------------------------------取回七段顯示碼副程式
GET_7 CJNE A,#0,$1 ;
MOV A,#SEG_0 ;
RET ;
$1 CJNE A,#1,$2 ;
MOV A,#SEG_1 ;
RET ;
$2 CJNE A,#2,$3 ;
MOV A,#SEG_2 ;
RET ;
$3 CJNE A,#3,$4 ;
MOV A,#SEG_3 ;
RET ;
$4 CJNE A,#4,$5 ;
MOV A,#SEG_4 ;
RET ;
$5 CJNE A,#5,$6 ;
MOV A,#SEG_5 ;
RET ;
$6 CJNE A,#6,$7 ;
MOV A,#SEG_6 ;
RET ;
$7 CJNE A,#7,$8 ;
MOV A,#SEG_7 ;
RET ;
$8 CJNE A,#8,$9 ;
MOV A,#SEG_8 ;
RET ;
$9 CJNE A,#9,$10 ;
MOV A,#SEG_9 ;
RET ;
$10 MOV A,#SEG_NO ;
RET ;
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>時間顯示副程式
ADJ_T1 MOV TMP0,TIME_S ; 儲存秒
MOV TMP1,TIME_M ; 儲存分
MOV TMP2,TIME_H ; 儲存時
JB P2.0,ADJ ;
JB P2.1,ADJ ;
JB P2.2,ADJ ;
CALL REGSAVE ;
MOV R1,#03H ;
AJMP LOOP ;
ADJ CALL REGSAVE ;
MOV R1,#10H ;
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 ;
;--------------------------------------
MOV A,TMP2 ;
ANL A,#0FH ;
CALL GET_7 ;
MOV P1,A ;
MOV P0,#10H ;
CALL DELAY ;
;---------------------------------------
MOV A,TMP2 ;
SWAP A ;
ANL A,#0FH ;
CALL GET_7 ;
MOV P1,A ;
MOV P0,#20H ;
CALL DELAY ;
;---------------------------------------
DJNZ R1,LOOP
CALL REGBACK
RET
End

------
滴滴儒
foreman
高階會員


發表:3
回覆:124
積分:190
註冊:2004-09-10

發送簡訊給我
#2 引用回覆 回覆 發表時間:2009-08-03 10:32:48 IP:122.121.xxx.xxx 未訂閱
大大:
您這程式問題太多.
1.P2.0 p2.1 p2.2當按鍵怎可以將P2設成80H,至少設成07H這樣才能抓到按鍵為HIGH.
2.MAIN1不是副函式(沒有RET), ACALL MAIN1堆曡保證爆掉
naga88
一般會員


發表:0
回覆:13
積分:7
註冊:2008-06-23

發送簡訊給我
#3 引用回覆 回覆 發表時間:2009-08-03 11:23:14 IP:60.249.xxx.xxx 訂閱
>一.當我按下任何一個按鈕,七段顯示器會閃一下,之後才會出現我需要的動作(也就是說我按下啟動並且放開會閃一下) 如果一直按著按鈕則七段顯示器不顯示,直到放開才顯示,請問這是正常的嗎?

關於問題一 個人覺得 是你的按鍵處 的delay造成的

;---------------------------------------
SET_STAR JB P2.0,$ ;
SETB TR0 ;
ACALL MAIN1 ;
ACALL DELAY ; <<<<<<<<
JNB P2.0,$ ;
ACALL DELAY ;<<<<<<<<
RET ;
;--------------------------------------------
SET_STOP JB P2.1,$ ;
CLR TR0 ;
ACALL MAIN1 ;
ACALL DELAY ;<<<<<<<
JNB P2.1,$ ;
ACALL DELAY ;<<<<<<<
RET
>二.這個計時器可以啟動暫停交互運作(也就是說啟動=>暫停=>啟動=>暫停=>啟動.....)

問題二 就如二樓大大所回覆的 堆疊爆了

MAIN1 CALL ADJ_T1 ;
;---------------------------------------
NO1 CALL TESTSW ;偵測SW <<<<<<<<<<<<<
LJMP MAIN1

SET_STAR JB P2.0,$ ;
SETB TR0 ;
ACALL MAIN1 ; <<<<<<<<<<<<<
ACALL DELAY ;
JNB P2.0,$ ;
ACALL DELAY ;
RET ;
;--------------------------------------------
SET_STOP JB P2.1,$ ;
CLR TR0 ;
ACALL MAIN1 ;<<<<<<<<<<<<
ACALL DELAY ;
JNB P2.1,$ ;
ACALL DELAY ;
RET

以上如有誤 敬請見諒
------
http://tw.myblog.yahoo.com/naga_tooru
albeeboy
一般會員


發表:7
回覆:20
積分:5
註冊:2009-08-02

發送簡訊給我
#4 引用回覆 回覆 發表時間:2009-08-03 19:20:23 IP:114.40.xxx.xxx 訂閱
謝謝上面2位大大為我解惑!
堆疊爆掉的問題已經解決了!!
但是延遲的問題我還不太懂
希望樓上的大大能說清楚點~
是要把CALL DELAY這個拿掉
還是要去延遲副程式修改????
------
滴滴儒
阿信
版主


發表:111
回覆:983
積分:813
註冊:2005-03-10

發送簡訊給我
#5 引用回覆 回覆 發表時間:2009-08-04 09:38:19 IP:114.32.xxx.xxx 訂閱
有兩個方式
一是縮短delay的時間
或是另設按鍵變數,存按鍵狀態,
10mS處理一次,兩次都有按下即為按下。
===================引 用 albeeboy 文 章===================
謝謝上面2位大大為我解惑!
堆疊爆掉的問題已經解決了!!
但是延遲的問題我還不太懂
希望樓上的大大能說清楚點~
是要把CALL DELAY這個拿掉
還是要去延遲副程式修改????
系統時間:2024-05-02 19:43:47
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!