单片机学习笔记第8章:定时器详解与实践

IAP15W4K58S4定时/计数器结构工作原理

 定时器工作方式控制寄存器TMOD

 不能进行位寻址,只能对整个寄存器进行赋值

寄存器 地址 D7 D6 D5 D4 D3 D2 D1 D0 复位值
TMOD 89H GATE C/(T低电平有效) M1 M0 GATE C/(T低电平有效) M1 M0 00000000B

D0-D3为T0控制,D4-D7为T1控制 

 GATE:门控位

GATE用于选通控制。

GATE=1时,INT1或INT0为高电平且TR1或TR0置1,T1或T0才能启动计数。

GATE=0时,只要TR1或TR0被置1,T1或T0就启动计数


C/(T低电平有效) :功能选择位

 C/(T低电平有效) =1,为计数器功能

 C/(T低电平有效) =0,为定时器功能


 M1和M0:方式选择位

M1 M0 工作方式 功能说明
0 0 0 16位自动装载的定时器/计数器
0 1 1 16位的定时器计数器
1 0 2 可自动重装的8位计数器
1 1 3

T1:停止计数

T0:不可屏蔽中断的16位自动装载的定时器/计数器


定时器控制寄存器TCON

寄存器 地址 D7 D6 D5 D4 D3 D2 D1 D0 复位值
TCON 88H TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 00000000B

 TF1和TF0:

T1和T1溢出标志位,为1时请求中断

TR1和TR0:

 T1和T0的运行控制位,GATE=0,TR1=1启动计数,TR1=0停止计数

 可以把初值写入THX,TLX用于控制计数长度


装入计数/定时器的初值的计算方法

16位的最大时间间隔:65.536ms

8位的最大时间间隔:256us

计算方法:

16位定时器:

T机=1/(fosc/12)

2^{16}-初值)*T机=定时时间


  定时量程的扩展:

在定时器中断服务程序中对定时器中断请求计数,当中断请求的次数达到要求的值时,才进行相应的处理

eg.50ms*20次=1s

即每20次进行一次事件的处理


 使用定时器 T0,在 P1.7 引脚输出周期位 1S 的方波,输出 10 个后停止。

;使用定时器 T0,在 P1.7 引脚输出周期位 1S 的方波,输出 10 个后停止。
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP T0_ISR
ORG 0100H
MAIN:
     MOV R0,#10
     MOV R1,#20
     MOV TMOD,#01H
     MOV TL0,#0B0H  ;50MS
     MOV TH0,#3CH
	 SETB ET0
	 SETB EA
	 SETB TR0
	 JZ STOP
T0_ISR:
     MOV TL0,#0B0H  ;50MS
     MOV TH0,#3CH
     DJNZ R0,DON
	 CPL P1.7
	 DEC R1
	 MOV A,R1
	 MOV R0,#10
	 DON:RETI
STOP:CLR ET0
	 CLR EA
     CLR TR0	 
	 RET
	END

上述代码存在的问题

  1. JZ STOP 语句位置有误JZ STOP 这个语句在定时器启动之后马上执行,而此时 R0R1 等计数器还未开始工作,R0 初始值为 10,并非 0,所以这个判断没有意义,而且会导致程序过早地跳到 STOP 处停止。
  2. 方波计数逻辑有问题:在中断服务程序里,DJNZ R0,DON 是用来判断是否达到半个周期(这里以 50ms 为一次中断,20 次中断即 1s 为一个周期),但对于方波个数的计数,在 DEC R1 之后没有对 R1 是否为 0 进行判断,所以无法准确停止输出方波。
  3. 程序结束逻辑有误RET 指令一般用于子程序返回,而这里程序结束时不应该使用 RET,可以使用 SJMP $ 让程序进入死循环,从而停止运行。
修改后:
;使用定时器 T0,在 P1.7 引脚输出周期位 1S 的方波,输出 10 个后停止。
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP T0_ISR
ORG 0100H
MAIN:
    MOV R0, #10      ; 半个周期的中断次数(20 次中断为 1 秒周期)
    MOV R1, #20      ; 方波个数计数器
    MOV TMOD, #01H   ; 设置定时器 T0 为模式 1
    MOV TL0, #0B0H   ; 定时 50ms 的初值
    MOV TH0, #3CH
    SETB ET0         ; 使能定时器 T0 中断
    SETB EA          ; 全局中断使能
    SETB TR0         ; 启动定时器 T0
    SJMP $           ; 等待中断

T0_ISR:
    MOV TL0, #0B0H   ; 重新加载定时 50ms 的初值
    MOV TH0, #3CH
    DJNZ R0, DON     ; 半个周期未到,继续等待
    CPL P1.7         ; 半个周期到,取反 P1.7 引脚电平
    MOV R0, #10      ; 重置半个周期计数器
    DJNZ R1, DON     ; 方波个数未达到 10 个,继续
    CLR ET0          ; 关闭定时器 T0 中断
    CLR EA           ; 关闭全局中断
    CLR TR0          ; 停止定时器 T0
;    SJMP $           ; 程序停止

DON:
    RETI             ; 中断返回

END


 T0 定时 100ms 实现 1s 定时控制 P1.7 小灯亮灭闪烁,增加一个 P1.6 小灯用 T1定时 100ms 实现 0.5S 定时控制 P1.6 小灯闪烁。

;T0 定时 100ms 实现 1s 定时控制 P1.7 小灯亮灭闪烁,增加一个 P1.6 小灯用 T1定时 100ms 实现 0.5S 定时控制 P1.6 小灯闪烁。
LED1 EQU P1.7
LED2 EQU P1.6
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP T0_ISR
ORG 001BH
LJMP T1_ISR
ORG 0100H	
MAIN:
     LCALL TIM_Init
     SETB ET0
     SETB ET1
	 SETB EA
	 SJMP $
TIM_Init:MOV R0,#20
         MOV R1,#10
         MOV TMOD,#011H
         MOV TL0, #0B0H   ; 定时 50ms 的初值
         MOV TH0, #3CH
		 MOV TL1, #0B0H   ; 定时 50ms 的初值
         MOV TH1, #3CH
		 SETB TR0
	     SETB TR1
		 RET
T0_ISR:MOV TL0, #0B0H   ; 定时 50ms 的初值,重赋初值
       MOV TH0, #3CH
	   DJNZ R0,DON_0
	   CPL LED1
	   MOV R0,#20
DON_0:RETI

T1_ISR:MOV TL1, #0B0H   ; 定时 50ms 的初值,重赋初值
       MOV TH1, #3CH
       DJNZ R1,DON_1
	   CPL LED2
	   MOV R1,#10
DON_1:RETI
      END

T0 定时 100ms 实现 1s 定时控制 P1.7 小灯


 使用定时/计数器延时,使 P1.0 和 P1.1 间两灯按 1S 间隔互相闪烁

; 使用定时/计数器延时,使 P1.0 和 P1.1 间两灯按 1S 间隔互相闪烁。
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP T0_ISR
ORG 0100H
MAIN:
     LCALL TIM_Init
	 LCALL LED_Init
     SETB ET0
	 SETB EA
     SJMP $
LED_Init:SETB P1.0
         SETB P1.1
         RET
TIM_Init:
        MOV R0,#20 ;1S
        MOV TMOD,#01H
        MOV TH0,#3CH ;50MS
		MOV TL0,#0B0H
		SETB TR0;开始计数
		RET
T0_ISR:
     MOV TH0, #3CH ; 重装 50ms 定时初值
     MOV TL0, #0B0H
     DJNZ R0, DON0 ; 判断是否达到 1s
     MOV R0, #20 ; 重置计数器
     JB P1.0, TURN_OFF_P10 ; 如果 P1.0 为高电平,关闭 P1.0 打开 P1.1
    SETB P1.0
    CLR P1.1
    SJMP DON0
TURN_OFF_P10:
    CLR P1.0
    SETB P1.1
DON0:RETI	
     END		 

使用定时/计数器延时,使 P1.0 和 P1.1 间两灯按


 用定时器 1,控制 P1.0 口输出 1ms 等宽方波,分别以查询方式和中断方式完成。

;定时器中断方式定时
ORG 0000H
LJMP MAIN
ORG 001BH
LJMP TINT1
ORG 0100H
MAIN:MOV TMOD,#11H;
     MOV TH1,#0FEH ;0.5MS
	 MOV TL1,#0CH
	 SETB TR1 ;启动定时
	 SETB ET1
	 SETB EA
	 SJMP $
TINT1:MOV TH1,#0FEH ;0.5MS
	  MOV TL1,#0CH
	  CPL P1.0
  DON:RETI
	  END
;定时器查询方式定时
ORG 0000H
MOV TMOD, #10H;
MOV TH1,#0FEH ;0.5MS
MOV TL1,#0CH
SETB P1.0
SETB TR1
WAIT: JNB TF1,WAIT
      CLR TF1
	  MOV TH1,#0FEH ;0.5MS
      MOV TL1,#0CH
	  CPL P1.0
	  LJMP WAIT
END


用 P2口控制 8 只 LED 闪烁,INT0 与按键 K1 连接,INT1 与按键 K2 连接。
(1)当奇数次按下按键 K1 时,8 个 LED 同时点亮 4 个,点亮 3 次,即 D0~D3 与D4~D7 交叉点亮 3 次。
(2)偶数次按下按键 K1 时, D0~ ~D7 进行左移和右移两次。
(3)当按下按键 K2 时,产生报警,K2 按键的中断优于 K1 按键中断。 

;用 P2口控制 8 只 LED 闪烁,INT0 与按键 K1 连接,INT1 与按键 K2 连接。
;1)当奇数次按下按键 K1 时,8 个 LED 同时点亮 4 个,点亮 3 次,即 D0~D3 与D4~D7 交叉点亮 3 次。
;2)偶数次按下按键 K1 时, D0~ ~D7 进行左移和右移两次。
;3)当按下按键 K2 时,产生报警,K2 按键的中断优于 K1 按键中断。

ORG 0000H
LJMP MAIN
ORG 0003H
LJMP IT0_ISR
ORG 000BH
LJMP T0_ISR
ORG 0013H
LJMP IT1_ISR
ORG 0100H
MAIN:
     LCALL TIM_Init
     SETB IT0;下降沿触发
     SETB IT1
	 SETB PX1;INT1优先于INT0
     SETB ET0
	 SETB EX0
	 SETB EX1
	 SETB EA
     SJMP $
TIM_Init:
        MOV R0,#20 ;1S
        MOV TMOD,#01H
        MOV TH0,#3CH ;50MS
		MOV TL0,#0B0H
		SETB TR0;开始计数
		RET
IT0_ISR:
   PUSH ACC
   PUSH PSW
   INC R1; 按键按下次数加 1
   MOV A, R1
   ANL A, #01H;将按键按下的次数和01H相与,奇数为01H,偶数为00H
   JZ EVEN_PRESS ; 偶数次按下
   MOV R2, #3 ; 奇数次按下,闪烁次数
 LOOP1:
    MOV P2, #0F0H ;1111 0000B
    LCALL DELAY_1S
	MOV P2, #0FH ;0000 1111B
    DJNZ R2, LOOP1
    SJMP INT0_END
EVEN_PRESS:; 偶数次按下 
          MOV R3, #2 ; 左右移次数
		  SETB C
SHIFT_LOOP:
    MOV A, #0FEH;1111 1110B
LEFT_SHIFT:
    MOV P2, A
	LCALL DELAY_1S
    RLC  A 
	JB P2.7,LEFT_SHIFT
	MOV A, #7FH;0111 1111B
RIGHT_SHIFT:
    MOV P2, A
	LCALL DELAY_1S
    RRC A
    JB  P2.0, RIGHT_SHIFT
    DJNZ R3, SHIFT_LOOP
	POP PSW
    POP ACC
	INT0_END:RETI
IT1_ISR:
    
    CPL P3.7
   RETI
T0_ISR:
      MOV TH0,#3CH ;50MS
	  MOV TL0,#0B0H
	  DJNZ R0,DON
	  SETB TF0 ; 延时时间到,设置定时器溢出标志
	  MOV R0,#20
  DON:RETI
DELAY_1S:
         MOV R0, #20 ; 重新初始化 1s 计数
WAIT_TF0:JNB TF0, WAIT_TF0 ; 等待定时器溢出
         CLR TF0 ; 清除定时器溢出标志
         RET
     END	 

用 P2口控制 8 只 LED 闪烁,INT0 与按键 K1

作者:RaLi和夕

物联沃分享整理
物联沃-IOTWORD物联网 » 单片机学习笔记第8章:定时器详解与实践

发表回复