定时/计数器

定时/计数器

定时/计数器概述

概述

  • T0 and T1 编程选用作为定时器或计数器。
  • 不占用CPU时间(delay)image-20231018153418544引脚
  • TCON定时器控制寄存器&TMOD定时器方式寄存器。

原理

  • 加一计数器

  • 通过软件设置为4种工作方式,每种方式都可以 用作定时或计数

  • 当设置了工作方式,并启动定时器/计数器工作 后,对内部时钟或对外部事件计数,均按照设定的工作方式独立工作,不再占用CPU的时间, 只有在计数器溢出时,才会中断CPU当前的操作

  • CPU可以随时重新设置定时器的工作方式,改变定时器的操作

  • 作为定时器

  • 每一个机器周期加1,即对片内振荡器的12分频信号计数,直至计数器溢出为止;

计数周期 T = 1 f osc  × 1 12 计数周期\\ T=\frac{1}{f_{\text {osc }} \times \frac{1}{12}} 计数周期T=fosc ×1211

osc:晶振oscillator

  • 作为计数器

  • 对来自引脚T0(P3.4)和T1(P3.5)的外部信号进行计数;

  • 外部脉冲的下降沿触发计数;

  • 在每个机器周期的S5P2期间采样引脚的电平,若前一个机器周 期采样值为1,后一个机器周期采样值为0,则计数器加1。在下 一个机器周期的S3P1期间,计数器值更新

  • 因此,检测一个从1到0的跳变需要2个机器周期,所以,对外部 事件的最高计数频率为振荡器频率的1/24

控制方法

  • TMOD
  • 设置工作方式以及控制模式
image-20231018154642563

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • TCON

  • 控制定时器启停

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    MOV TMOD #53H
    SETB TR1;启动定时器1
    CLR TR0;关闭定时器0
    //初始化
    

    手册

    image-20231018155444673

    使定时器1为计数工作方式,软件启动,按方式1工 作;定时器0为定时方式,软件启动,按方式3工作

定时器/计数器初值的设定方法

  • M: 定时器的最大计数值;

  • X: 初值

  • X = M − 计数值 X=M-计数值 X=M计数值

    example:

    时钟频率6MHz,16位模式,要求产生1ms定时:

    计数周期 = 1 f osc  × 1 12 = 2 μ s 计数值 = 1 m s 2 μ s = 500 初值 = M − 计数值 = 65536 − 500 = 65036 计数周期=\frac{1}{f_{\text {osc }} \times \frac{1}{12}}=2\mu s\\计数值=\frac{1ms}{2\mu s}=500\\初值 = M -计数值 = 65536 - 500 = 65036 计数周期=fosc ×1211=2μs计数值=2μs1ms=500初值=M计数值=65536500=65036

工作方式

定时/计数器T0/T1的工作方式

  1. 方式0 13位定时/计数方式,由THx提供高8 位、TLx提供低5位的计数初值,最大计数值为
    M = 2 13 = 8192 M=2^{13}=8192 M=213=8192
    ,每次启动计数前均需预置计数初值。

  2. 方式1 16位定时/计数方式

    1. 最大计数值为
      M = 2 16 = 65536 M=2^{16}=65536 M=216=65536

    2. 由THx和TLx寄存器各提供8位计数初值,每次 启动计数前均需预置计数初值

  3. 方式2

  4. 方式3

看门狗定时器(重要)

  • WDT: watchdog timer
  • 功能——微控制器不正常工作时,产生一个复位信号
  • 系统软件工作不正常时,产生复位信号,防止程序进 入不可预料操作

定时/计数器的主要功能

  • 定时
  • 计数
  • 输入捕捉
  • 输出比较

应用举例

基本信息

初始化——将控制字写入定时器/计数器的过程

确定工作方式——工作方式控制字写入方式寄存器 TMOD;

预置定时或计数的初值——直接将初值写入TH0,TL0 或TH1,TL1;

中断控制: 根据需要开放定时/计数器的中断——直接对IE寄存器的定时器 中断位赋值;

启动定时/计数器,启动方式由TMOD寄存器的GATE 位确定;

若软件启动,置位TR0或TR1;

若由外中断引脚电平启动,则给相应引脚加启动电平

TIMER

  1. 用定时器T1定时,完成日历时钟秒、 分、时的定时,晶振为12MHz

    定时器的计时周期为一个机器周期,即:
    T 计时周期 = 1 f osc  × 1 12 = 1 μ s T_{计时周期}=\frac{1}{f_{\text {osc }} \times \frac{1}{12}}=1\mu s T计时周期=fosc ×1211=1μs
    最大计数值=65536 选择50ms作为定时周期,则: 50000= 65536−M 即定时器初值:M=15536

        ORG 0000H
        LJMP MAIN

        ORG 0100H
MAIN:	MOV 50H,#20
        MOV R1,#0
        MOV R2,#0
        MOV R3,#0
        MOV TMOD,#10H
        MOV TH1,#3CH
        MOV TL1,#0B0H
        SETB TR1
L1: 	JNB TF1,L1  ;jump to L1 if TF1=0(TF=1 when overflow)
        CLR TF1     ;clear by software in query mode
        
        MOV TH1,#3CH
        MOV TL1,#0B0H
        DJNZ 50H,L1 ;(50H)-=1,jump to L1 if (50H) <> 0
        MOV 50H,#20
        INC R1
        CJNE R1,#60,L1  ;jump to L1 if (R1)<>60
        MOV R1,#0
        INC R2
        CJNE R2,#60,L1
        MOV R2,#0
        INC R3
        CJNE R3,#24,L1
        MOV R3,#0
        SJMP L1
END
	

这段代码使用了8051微控制器的指令集来实现一个定时器循环计数器。在程序执行过程中,定时器1被设置为10H模式,初始计数值为3CH和0B0H,当定时器1溢出时(TF1标志位为1),程序会执行特定操作,并继续循环,直到R1、R2和R3寄存器的值分别达到60、60和24为止。from chatGPT

ORG 0000H       ; 设置程序起始地址为0000H
LJMP MAIN       ; 无条件跳转至MAIN标签

ORG 0100H       ; 设置程序的内存地址为0100H
MAIN:           ; 主程序入口标签

    MOV 50H, #20 ; 将数据20H加载到寄存器50H中
    MOV R1, #0   ; 将0加载到寄存器R1中
    MOV R2, #0   ; 将0加载到寄存器R2中
    MOV R3, #0   ; 将0加载到寄存器R3中
    MOV TMOD, #10H ; 初始化定时器模式为10H
    MOV TH1, #3CH  ; 初始化定时器1的高位计数器为3CH
    MOV TL1, #0B0H ; 初始化定时器1的低位计数器为0B0H
    SETB TR1      ; 启动定时器1
    
L1: 
    JNB TF1, L1   ; 如果TF1标志位为0,则跳转到L1标签(TF1在定时器溢出时为1)
    CLR TF1       ; 通过软件清除TF1标志位(在查询模式下)
    
    MOV TH1, #3CH  ; 重新加载定时器1的高位计数器为3CH
    MOV TL1, #0B0H ; 重新加载定时器1的低位计数器为0B0H
    DJNZ 50H, L1  ; (50H)-=1,如果(50H)不等于0,则跳转到L1标签
    
    MOV 50H, #20  ; 重新将数据20H加载到寄存器50H中
    INC R1       ; R1寄存器加1
    CJNE R1, #60, L1 ; 如果R1不等于60,则跳转到L1标签
    
    MOV R1, #0   ; 将0加载到寄存器R1中
    INC R2       ; R2寄存器加1
    CJNE R2, #60, L1 ; 如果R2不等于60,则跳转到L1标签
    
    MOV R2, #0   ; 将0加载到寄存器R2中
    INC R3       ; R3寄存器加1
    CJNE R3, #24, L1 ; 如果R3不等于24,则跳转到L1标签
    
    MOV R3, #0   ; 将0加载到寄存器R3中
    SJMP L1      ; 无条件跳转到L1标签
    
END             ; 程序结束标签
##code from chatGPT
#include "main.h"

UINT8 u8_s,u8_m,u8_h,u8_TNcnt;   //秒、分、时、定时器计数值
//UINT8 TH1_Val,TL1_Val;        //计算需要时间较长,可提前计算

void main(void)
{
    //变量初始化
    u8_s=0;
    u8_m=u8_h=0;    
    u8_TNcnt=T_NUM;
    
    //定时器初始化
    TMOD=0x10;          //00010000定时器1:模式1,16位定时器
    TH1=TH_N;           //定时器赋初值
    TL1=TL_N;

    TR1=1;              //启动定时器
    
    while (1)
    {
        if(TF1==1)
        {
            TF1=0;      //查询方式下需要软件清0
            TH1=TH_N;
            TL1=TL_N;
            u8_TNcnt--;
            if(u8_TNcnt==0)  //=0后就是溢出
            {
                u8_TNcnt=T_NUM;
                u8_s++;
                if(u8_s>=60)
                {
                    u8_s=0;
                    u8_m++;
                    if(u8_m>=60)
                    {
                        u8_m=0;
                        u8_h++;
                        if(u8_h>=24)
                        {
                            u8_h=0;
                        } 
                    } 
                }    
            }                
        }
    }  
}
//main.h

#ifndef __MAIN_H__
#define __MAIN_H__

#ifdef __cplusplus
    extern "C" {
#endif

//头文件

#include <reg51.h>
        
//变量类型

typedef unsigned char UINT8;
typedef unsigned int UINT16;
        
//宏定义
#define F_CLK   12000000   
#define T_PERD  1000000     
#define TIMER_PERD  50000   
#define TH_N    (65536-(TIMER_PERD/(1000000/(F_CLK/12)))) / 256 
#define TL_N    (65536-(TIMER_PERD/(1000000/(F_CLK/12)))) % 256
#define T_NUM   (T_PERD/TIMER_PERD)
        
#if ((1000000/(F_CLK/12))==0)  
    #error "parameters error"
#endif



#ifdef __cplusplus
}
#endif

#endif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值