单片机学习整理----定时器/计数器

mengnan-konghai 2021-11-23 原文


单片机学习整理—-定时器/计数器

本来打算从LED开始写起的,仔细一想,没有必要。不妨博客当笔记把单片机重要的部分记下来。以后忘记了还可以看一看。


声明:1、我用是STC89C52系列单片机

   2、内有两个16位的定时器和计数器   T0 T1

     3、时钟频率是11.0592


 

关于定时器定时原理: 因为是16位计数寄存器。每经过一个机器周期,它内部就自动加1 直到溢出。

          (1111 1111 1111 1111)B = 65535 

           那么如果工作方式为 TL0 TH0 (两个装初值的寄存器)都用到了

              那定时模式时间最多为 65535 * 1.085us = 时间   71105.475us

            1.085怎么得来的:11.0592MHZ 1 / 11.0592 * 12 = 1.085us

          比如我要定时  50ms的定时器 工作模式为16位定时器 TH0 TL0 该赋什么初值?

              50ms = 50000us   用最大时间 减去 50ms   为  max-50ms = 21105.475us

              除以 1.058 ≈ 19452.05069   转化为二进制    0100 1011 1111 1101

            所以给TL0 = 0x4b   TH0 = 0XFD 


计数器工作原理:   当工作在计数器模式时,T0(P3.4引脚)T1(P3.5)引脚 每来一个脉冲,计数寄存器就加1。

          图为具体接口原理图    


  用定时器/计数器的流程可以分为3 步: ① 启动定时器/计数器 (TCON控制)

                ② 设置定时器/计数器工作模式(TMOD控制)

                ③ 判断定时器/计数器是否溢出 (TCON内的TF位)


 

  查阅单片机手册 看所需要配置寄存器(看手册是个很枯燥的事情)

 

 

 

 

看到这张图,找重点嘛     (可位寻址)

      1、我要用哪个定时器/或计数器,T0  T1 开启单位分别是 TR1 TR0  

           TR?是由软件置位和清零

      2、 溢出标志判断  TF? 由硬件清0   时间是否到就查询它受否溢出。

TMOD的手册

  

 

        1、不可位寻址

       2、C/T 管理是用于定时器还是计数器 

          如果用于计数器:需要从T0 (P3.4)  T1(P3.5) 口输入脉冲信号。

                    3、 M0 M1 用于管理哪种模式  怎么用TH0 和TL0 存初值。

                     上面已经讲过一次了。

  


下面开始写定时器0程序:

 1 #include <reg52.h>  //引入51头文件
 2 #include <intrins.h>    //引入循环库
 3 
 4 #define uchar unsigned char
 5 #define uint unsigned int
 6 
 7 sbit DU = P2^6;   //数码管段选
 8 sbit WE = P2^7;   //数码管位选
 9 /*共阴极数码管的段选表  code存放到rom区*/
10 uchar code table [] = {0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F}; //0123456789 的16进制
11 
12 void delay(uint z);
13 void display(uchar i);
14 void timer0Init();
15 
16 void main()
17 {
18     uchar msec,sec; //毫秒和秒存储变量
19     timer0Init();  
20     while(1)
21     {
22         if(TF0 == 1)  //判断标志位是否溢出,定时器是否到时间
23         {
24             TF0 = 0;   //软件清0
25             msec++;      //50毫秒到
26             if(msec == 20)
27             {
28                 msec = 0;
29                 sec++;      //一秒时间到 \'
30                 if(sec > 10)  sec = 0;  //如果大于10秒  秒清零
31             }
32         }
33         display(sec);
34     }
35 
36 }
37 /*ms级延迟函数*/
38 void delay(uint z)
39 {
40      uint x,y;
41     for(x = z; x>0; x--)
42         for(y = 144; y>0 ; y--);
43 }
44 /*数码管显示*/
45 void display(uchar i)
46 {
47         uchar bai,shi,ge;  //代表百十个
48         bai = i/100;
49         shi = i % 100 / 10;
50         ge = i % 10;
51         /*第一位数码管*/
52            P0 =0XFF;  //清除段码
53         WE = 1;      //打开位选锁存器
54         P0 = 0XFE;     // 1111 1110
55         WE = 0;   //锁存数据
56     
57         DU = 1;       //打开段选锁存器
58         P0 = table[bai];         
59         DU = 0;       // 锁存数据
60         delay(5);      //延迟 5 毫秒
61         /*第二位数码管*/
62         P0 = 0XFF;
63         WE = 1;      //打开位选锁存器
64         P0 = 0XFD;        // 1111 1101
65         WE = 0;   //锁存数据
66     
67         DU = 1;       //打开段选锁存器
68         P0 = table[shi];    
69         DU = 0;       // 锁存数据
70         delay(5);
71         /*第三位数码管*/
72         P0 = 0XFF;
73         WE = 1;      //打开位选锁存器
74         P0 = 0XFB;        //1111 1011
75         WE = 0;   //锁存数据
76     
77         DU = 1;       //打开段选锁存器
78         P0 = table[ge];       
79         DU = 0;       // 锁存数据
80         delay(5);
81 }
82 /*定时器0初始化函数*/
83 void timer0Init() 
84 {
85     TR0 = 1;    //定时器启动
86     TMOD = 0X01;  //设置模式为定时器 0000 0001  为16位定时器
87     TH0 = 0x4b;          //初始值的高8位   设置定时为50ms
88     TL0 = 0xfd;            //初始值的低8位
89 
90 }  

 

 

 


 

 计数器代码:用T1的定时器来计时 每50ms发送一次脉冲 (通过P1^0口实现

 /* 方法:用杜邦线从  P1^0接到 P3^4
     原理:用定时器来控制led灯的闪烁来产生脉冲波形
              使计数器计数,并且用数码管显示低8位 */





#include <reg52.h>  //引入51头文件
#include <intrins.h>    //引入循环库

#define uchar unsigned char
#define uint unsigned int

sbit DU = P2^6;   //数码管段选
sbit WE = P2^7;   //数码管位选
sbit led1 = P1^0;   // 第一个led1用它的闪烁来表示方波;
/*共阴极数码管的段选表  code存放到rom区*/
uchar code table [] = {0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F}; //0123456789 的16进制

void delay(uint z);
void display(uchar i);
void number0Init();
void timer1Init();

void main()
{
    uchar msec;  //毫秒和秒的存储变量
    timer1Init();     //定时器1初始化函数 调用
    number0Init();   //定时器0变计数器函数调用
    while(1)
    {    
        if(TF1 == 1)  //判断标志位是否溢出(定时器是否到时间)
        {
            TF1 = 0;   //软件清0
            TH1 = 0X4B;
            TL1 = 0XFD;  //再次定时50ms
            msec++;      //50毫秒到了自增
            if(msec == 10)          //定时500ms到了
            {
                msec = 0;
                led1 = !led1;   //产生一个方波
            }
        }

        display(TL0);      //显示低8位的值
    }

}

void delay(uint z)
{
     uint x,y;
    for(x = z; x>0; x--)
        for(y = 144; y>0 ; y--);
}

void display(uchar i)
{
        uchar bai,shi,ge;  //代表百十个
        bai = i/100;
        shi = i % 100 / 10;
        ge = i % 10;
        /*第一位数码管*/
           P0 =0XFF;  //清除段码
        WE = 1;      //打开位选锁存器
        P0 = 0XFE;     // 1111 1110
        WE = 0;   //锁存数据
    
        DU = 1;       //打开段选锁存器
        P0 = table[bai];         
        DU = 0;       // 锁存数据
        delay(5);      //延迟 5 毫秒
        /*第二位数码管*/
        P0 = 0XFF;
        WE = 1;      //打开位选锁存器
        P0 = 0XFD;        // 1111 1101
        WE = 0;   //锁存数据
    
        DU = 1;       //打开段选锁存器
        P0 = table[shi];    
        DU = 0;       // 锁存数据
        delay(5);
        /*第三位数码管*/
        P0 = 0XFF;
        WE = 1;      //打开位选锁存器
        P0 = 0XFB;        //1111 1011
        WE = 0;   //锁存数据
    
        DU = 1;       //打开段选锁存器
        P0 = table[ge];       
        DU = 0;       // 锁存数据
        delay(5);
}
/*定时器0初始化为计数器函数*/
void number0Init() 
{
    TR0 = 1;    //定时器启动
    TMOD |= 0X05;  //设置模式为计数器 0000 0101  为16位计数器
    TH0 = 0;          //初始值的高8位   
    TL0 = 0;            //初始值的低8位
} 
/*定时器1初始化函数*/
void timer1Init() 
{
    TR1 = 1;    //定时器启动
    TMOD |= 0X10;  //设置模式为计数器 0000 0101  为16位计数器
    TH1 = 0x4b;          //初始值的高8位   定时50ms
    TL1 = 0xfd;            //初始值的低8位
}               

 

 

 

 

 

 

 

 

 

 

 


 

发表于
2020-05-04 20:30 
沙弥空海 
阅读(277
评论(0
编辑 
收藏 
举报

 

版权声明:本文为mengnan-konghai原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/mengnan-konghai/p/juansheng030.html

单片机学习整理----定时器/计数器的更多相关文章

随机推荐

  1. 2013年6月 最新Godaddy(持续更新) – 游乐场123

    2013年6月 最新Godaddy(持续更新) 2013-06-22 01:58  游乐场123  阅读(24 […]...

  2. ubuntu16搭建文件服务器

    这篇记录,如何在ubuntu16 安装 FastDFS 文件服务器,详细步骤 环境依赖 apt-get ins […]...

  3. Use of Deep Learning in Modern Recommendation System: A Summary of Recent Works(笔记)

        注意:论文中,很多的地方出现baseline,可以理解为参照物的意思,但是在论文中,我们还是直接将它称 […]...

  4. 接口测试–测试工具:rap2 接口文档解析

    通过百度 OCR 工具识别 rap2 登录中的验证码,从而实现登录~那我们今天来实战解析 rap2 的接口数据 […]...

  5. access的一些简单操作

    Option Compare Database   Private sqladdress As String […]...

  6. python实现全北京的公交路线动图【一定收藏】

    今天教大家用pyecharts制作北京市公交线路动态图,这应该是全网唯一一篇能正常运行的教程 一、获取百度秘钥 […]...

  7. 阿里云服务器线上环境配置

    tomcat: tomcat服务器的默认访问路径是webapps目录下的ROOT。如果更改tomcat服务器下 […]...

  8. 并发系列(二)——FutureTask类源码简析

    背景   本文基于JDK 11,主要介绍FutureTask类中的run()、get()和cancel() 方 […]...

展开目录

目录导航