專注電子技術學習與研究
當前位置:單片機教程網(wǎng) >> MCU設計實例 >> 瀏覽文章

用單片機設計精確到百分之一秒的計時器

作者:佚名   來源:本站原創(chuàng)   點擊數(shù):  更新時間:2009年11月17日   【字體:

/*
程序效果:利用單片機的定時/計數(shù)器設計一個計時器,
 按key0后啟動,要求精確顯示到百分之一秒。
發(fā)揮部分:  
1:定時結(jié)束后有提示音報警,并可重新定時
2:定時時間可設置,最多30s
3:定時過程中可暫停
4:按下key1暫停計時,并記下此刻數(shù)值
5:按下key2顯示第一次按下key1的數(shù)值(按下第一次有效,其它均無效)
3:本程序版權(quán)所有:51hei.com.
*/
 ORG 0000H
 LJMP START   //主程序必須避開地址000BH
 ORG 000BH  //定時器0的中段服務程序,起始地址為000BH
 LJMP IT00
 ORG 0030H
START:    MOV TH0,#0EBH //裝入初始值,定時時間為10ms
 MOV TL0,#64H
 MOV TMOD,#01H //工作方式1
 MOV 40H,#00
 MOV 41H,#00
 MOV 42H,#00
 MOV 43H,#00
 MOV 33H,#00   //顯示初值為0
 MOV 32H,#00
 MOV 31H,#00
 MOV 30H,#00
 MOV R1,#00
 MOV R2,#00
 SETB ET0   //打開定時0
 SETB EA   //開總中斷
HERE:    JNB P3.4,KEY0  //掃描是否有按鍵按下
 JNB P3.5,KEY1
 JNB P3.6,KEY2
 LCALL DISPLAY  //此處是為了防止掉顯
 LJMP HERE

KEY0:    LCALL DELAY1  //延時10ms
 JB P3.4,HERE  //判斷key0是否真的按下去了
LKOP:      LCALL DISPLAY //真的按下去了
 JNB P3.4, LKOP //檢查是否松手,沒有則繼續(xù)循環(huán),別忘了要顯示
 MOV A,R2  
 CJNE A,#01,LSP //判斷key2 是否按下去過(只能按一次)

 MOV R2,#00  //清零

 MOV 30H,34H  //真的按下去了
 MOV 31H,35H  //顯示key2按下前的值
 MOV 32H,36H
 MOV 33H,37H
LSP:        SETB TR0 //啟動定時器
 LJMP HERE

KEY1:      LCALL DELAY1 //顯示消抖
 JB P3.5,HERE
 CLR  TR0  //關閉定時器
LKOP1:    LCALL DISPLAY
 JNB  P3.5,LKOP1
 INC R1
 MOV A,R1
LEP:        CJNE A,#01,HERE  //判斷key2是否按下(只能按一次)
 MOV 40H,30H  //暫存key2按下去前的值
 MOV 41H,31H
 MOV 42H,32H
 MOV 43H,33H
 LJMP HERE

KEY2:      LCALL DELAY1
 JB P3.6,HERE
 CLR TR0
LKOP2:    LCALL DISPLAY
 JNB  P3.6,LKOP2
 INC R2  //加1,為標志,用于判斷key2是否按下去了
 MOV A,R2  //此處寫的是一個通用形式,只暫存一個數(shù)值
LEP2:      CJNE A,#01,HERE  //此語句大可不寫
 MOV 34H,30H   
 MOV 35H,31H //保存碼表當時的數(shù)值,便于回復到原值
 MOV 36H,32H
 MOV 37H,33H

 MOV 30H,40H   //保存key1第一次按下的數(shù)值
 MOV 31H,41H
 MOV 32H,42H
 MOV 33H,43H
 LJMP HERE
 
//每10ms加1子程序
ADD1:      INC 30H     //百分位減1
 MOV A,30H
 CJNE A,#00AH,LOOP2 //判斷百分位減到0之后是否再減1
 MOV 30H,#00   //是,裝入初值9
 INC 31H    //十分位減1
 MOV A,31H
 CJNE A,#0AH,LOOP2 //判斷百分位減到0之后是否再減1
 MOV 31H,#00
 INC 32H
 MOV A,32H
 CJNE A,#0AH,LOOP2
 MOV 32H,#00
 INC 33H
 MOV A,33H
 CJNE A,#0AH,LOOP2
 MOV 33H,#00
 SETB P2.0  //關閉蜂鳴器 
 LCALL DELAY   //延時
 LCALL DELAY
  CLR P2.0    //從15s減到0s后,驅(qū)動蜂鳴器
 MOV 33H,#00   //裝入初值15s
 MOV 32H,#00
 MOV 31H,#00
 MOV 30H,#00
 CLR TR0   //關閉定時器,
LP1:         JB P3.4,LP //判斷KEY0是否按下
 SETB TR0 //按下,則啟動定時器 ,這里我沒有消抖
 SJMP LOOP2
LP:  LCALL  DISPLAY  //沒有按下,調(diào)用顯示,防止掉顯
 SJMP LP1
LOOP2:    NOP    //空指令
 RET    //返回
//顯示子程序
DISPLAY: MOV DPTR,#TAB  //賦表首地址
 MOV A,#0FBH  
 MOV P2,A  //亮最左邊的數(shù)碼管
 XCH A,R0   //暫存A的值
 MOV A,33H
 MOVC A,@A+DPTR //根據(jù)表值查找所需的值
 MOV P0,A  //顯示值
 LCALL DELAY   //延時
 XCH A,R0 //恢復原值
 RL A    //循環(huán)左移,為下次做準備

 MOV P2,A
 XCH A,R0
 MOV A,32H
 MOVC A,@A+DPTR
 MOV P0,A
 LCALL DELAY
 XCH A,R0
 RL A

 MOV P2,A
 XCH A,R0
 MOV A,31H
 MOVC A,@A+DPTR
 MOV P0,A
 LCALL DELAY
 XCH A,R0
 RL A

 MOV P2,A
 XCH A,R0
 MOV A,30H
 MOVC A,@A+DPTR
 MOV P0,A
 LCALL DELAY
 RET
TAB:     DB 3FH,06H,5BH,4FH,66H  ;數(shù)碼管顯示的數(shù)值  
 DB  6DH,7DH,07H,7FH,6FH   
IT00:     MOV TH0,#0EBH  //裝入初值,時間為10ms
 MOV TL0,#64H
 LCALL ADD1   //減10ms
 RETI     //返回
DELAY:    MOV R7,#04 //延時子程序,時間大約為:2us*4*250
DEL2:       MOV R6,#250
DEL1:       DJNZ R6,DEL1
 DJNZ R7,DEL2
 RET
DELAY1:  MOV R5,#20
DEL3:    MOV R4,#250
DEL4:      DJNZ R4,DEL4
    DJNZ R5,DEL3
 RET
 END  //結(jié)束 

關閉窗口

相關文章