Delay 延遲副程式
C 語言的範例:
利用 Timer0 做時間計時並使用輪詢機制
步驟一、在 void main(void) 做計時器初始化動作(一次就可以),程式如下
void Init_Timer0(void)
{
TMOD = 0x01; // 模式1,可以計數 65536 次
TL0 = 0x00; // TL0 以及 TH0 設為 0,這樣可以計數 65536 次
TH0 = 0x00; // 12 MHz Osc.,而週期為 1uS,可以延遲 65536 uS
TR0 = 0; // 先關閉計時器
}
步驟二、寫一個延遲副程式,程式如下
void Delay(void)
{
TR0 = 1; // 開始計時
while(TF0 == 0); // 等待計數溢位
TR0 = 0; // 關閉計數
TF0 = 0; // 清除溢位旗標
TL0 = 0;
TH0 = 0;
}
步驟三、如果需要延遲則呼叫以上副程式即可,範例如下
void main(void)
{
Init_Timer0(); // 初始計數器
Delay(); // 延遲 65536 uS,假如 Osc. 是 12 MHz 且 週期為 1uS
}
以上是一個延遲 65536 uS 的範例
延遲 10 分鐘
使用迴圈的作法就可以達到,
僅需修改 Delay,
將 Delay 加入迴圈機制。
void Delay(void)
{
unsigned long dwSecond=0;
unsigned int iMinute=0;
for(;iMinute<600;iMinute++){ // 10 分鐘
for(;dwSecond<1000000;dwSecond++){ // 1 秒
TR0 = 1; // 開始計時
while(TF0 == 0); // 等待計數溢位
TR0 = 0; // 關閉計數
TF0 = 0; // 清除溢位旗標
TL0 = 0; // 假設週期為 1uS
TH0 = 0;
}
}
}
組合語言:
在c中設定TH0,TL0,TR0=1
;;-----------------------------------------------------------------------------
;; File: 51_Int.a51
;; Contents: This file contains 8051 standard Interrupts.
;; date: 2005/12/20
;;-----------------------------------------------------------------------------
$NOMOD51
$nolist
$INCLUDE (fx2regs.inc) ; *** for the Dallas (Synopsys) part
$list
;;-----------------------------------------------------------------------------
;; Global Variables
;;-----------------------------------------------------------------------------
cseg at 0BH ;;org 0BH
jmp Timer0_ISR
cseg at 125H ;;ISR 125H~1BEH
;;Timer0 Interrupt
;;Motion control
Timer0_ISR: push ACC ;;Timer0
mov TH0,R5
mov TL0,R4
mov R2,A
mov A,IOD
cpl A
anl A,21H
cpl 20H.0
jb 21H.7,Dir_m
clr ACC.7
jmp Bypass_Dir
Dir_m: setb ACC.7
Bypass_Dir: mov IOD,A
jb 20H.0,Bp_TP
mov A,R3
jz check_R2
djnz R3,Bypass_Timer0
check_R2: mov A,R2
jz motion_finish
mov R3,#255
djnz R2,Bypass_Timer0
motion_finish: setb c
jmp Bp_TP
Bypass_Timer0:
Bp_TP:
pop ACC
reti
轉載與整理 自 http://www.usblab.idv.tw/phpbb2/viewtopic.php?t=865 |