蓝桥杯单片机学习6——定时器/计数器&定时器实现秒表功能

这篇具有很好参考价值的文章主要介绍了蓝桥杯单片机学习6——定时器/计数器&定时器实现秒表功能。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

上一期我们学习了外部中断的相关内容,现在我接着来学习定时器。

定时器/计数器

1.工作原理

定时器/计数器是一种能够对内部时钟信号或者外部输入信号进行计数,当计数值达到设定要求时,向CPU提出中断请求,从而实现定时或计数功能的外设。定时器的基本工作原理是进行计数。

举个栗子:你可以把定时器比喻成一个装了水的瓶子,每一次计数理解成向瓶子里面丢一个石子,当丢的石子足够多时,瓶子里面的水就会溢出,产生中断请求。

当作为定时器使用时,计数信号的来源是周期性的内部时钟频率,在单片机的内部,有一个频率为12MHZ的晶振,可以稳定的产生的产生一个周期为12MHZ的时钟信号,那么定时器就可以实现在每隔一段时间加一,实现定时。我们可以来简单的计算一下一个定时器的溢出周期:
单片机的时钟周期:T=1/f(sys) = 1/12MHZ = 0.083us 这是一个时钟周期
单片机的指令周期:单片机的指令周期 = 12*时钟周期=12 * 0.083 = 1us;即定时器在工作的状态下每1us计数器就会加一(每1us向瓶子里面丢一个石子)。

那么最大可以加到多少呢?我们这里以定时器0为例:在单片机内部有两个寄存器TH0和TL0,用来给定时器0计数,那么计数的最大值就是2^16-1 = 65535(最多丢65535个石子,瓶子里的水就会溢出),也就是说定时器可以对时钟信号从0开始计数一直到65535,然后溢出产生中断请求。那么最大的定时周期就是1us*65535 =65.535ms;

当然:65.535ms的定时时间对于我们也许有一些鸡肋,但是我们可以认为的设置定时器初始的值(即可以设置这个瓶子里原来有多少石子),来控制定时的时间。

举个栗子:我们需要定时1ms,则我们可以设置:
TH0 = (65535-1000)/256 = 0xFC;
Tl0 = (65535-1000)%256 = 0x18;
这样,我们就可以控制定时器每1ms溢出一次

PS:STC15系列单片机有两种计数模式,一种是12T模式,每12个时钟周期加一,与传统的8051单片机相同;另一种时1T模式,每一个时钟信号加一,速度时12T模式的12倍,但一般默认是12T模式。

作为计数器使用时计数信号的来源是非周期性的外部输入信号。外部引号可以有对应的引脚的脉冲信号输入,其对应关系如下:
定时器0—>P3.4; 定时器1—>P3.5;定时器2—>P3.1;

2.相关寄存器

1.定时器/计数器0/1控制寄存器TCON(可位寻址)
单片机用工作方式0编写秒表,蓝桥杯单片机学习,单片机,蓝桥杯,学习,51单片机,c语言

TR0/TR1分别为定时器0/1的运行控制位,TR0/TR1为1时表示打开定时器0/1,为0时表示关闭

TF0/TF1为定时器0/1溢出中断标志,当定时器0/1溢出时由硬件置1,在CPU处理中断请求后自动清0,也可以由软件清0。(知道就行,不用管)

2.定时器/计数器工作模式寄存器TMOD(不可位寻址)
单片机用工作方式0编写秒表,蓝桥杯单片机学习,单片机,蓝桥杯,学习,51单片机,c语言
单片机用工作方式0编写秒表,蓝桥杯单片机学习,单片机,蓝桥杯,学习,51单片机,c语言

该寄存器的前四位控制定时器1,后四位控制定时器0。
GATE控制定时器打开方式。
C/T可以选择定时器的工作方式:为0时工作为定时器,为1时工作为计数器。
M1/M0控制定时器的工作模式:一共有四种。

3.辅助寄存器AUXR(不可位寻址)
主要负责对定时器0/1的速度控制,以及定时器2的相关配置
单片机用工作方式0编写秒表,蓝桥杯单片机学习,单片机,蓝桥杯,学习,51单片机,c语言

T0x12/T1x12/T2x12:控制定时器0/1/2的速度模式,为0时为12T模式,为1时为1T模式,默认是12T模式。
T2R::定时器2允许控制位,为1时表示打开定时器2,反之则关闭。
T2_C/T :为0表示工作为定时器,为1表示工作为计数器。

4.定时器T0heT1的中断控制寄存器IE和IP(可位寻址)

单片机用工作方式0编写秒表,蓝桥杯单片机学习,单片机,蓝桥杯,学习,51单片机,c语言

ET0/ET1:定时器T0/T1的中断允许位,为1时表示允许中断,反之则不允许
PT0/PT1:设置定时器T0/T1的中断优先级,为1设置为高优先级,为0设置低优先级。

5.定时器0/1/2高八位/低八位寄存器TLH0/TL0/TH1/TL1/T2H/T2L
单片机用工作方式0编写秒表,蓝桥杯单片机学习,单片机,蓝桥杯,学习,51单片机,c语言
前面讲过,定时器的本质是一个加法计数器,定时器的高八位/低八位寄存器的作用就是用来存放这个计数器的值,当计数器的值到达最大值溢出时,产生中断请求。

3.工作模式

1.16位自动重装载
单片机用工作方式0编写秒表,蓝桥杯单片机学习,单片机,蓝桥杯,学习,51单片机,c语言

在M1 = M0 = 0时,定时器工作在工作模式0(16位自动重装载)。
在定时器溢出之后,会自动装载为原来设置的TL0/TH0。

2.16位不可重装载
单片机用工作方式0编写秒表,蓝桥杯单片机学习,单片机,蓝桥杯,学习,51单片机,c语言

在M1 =0; M0 = 1时,定时器工作在工作模式1(16位不可重装载),
在定时器溢出之后,需要在中断服务函数中设置TL0和TH0。不可自动重装载。

3.八位自动重装载
单片机用工作方式0编写秒表,蓝桥杯单片机学习,单片机,蓝桥杯,学习,51单片机,c语言

当M1 = M0 = 1时,定时器工作在工作模式2(八位自动重装载)
此时定时器的计数范围位0~255,在定时器溢出时,TL0=TH0,将Th0的值装载的TL0中,实现八位自动重装载。可以通过改变TH0的值去控制定时器溢出的时间。

4.不可屏蔽中断16位自动重装载
由于这个模式几乎用不到,所以我们不讲。

PS:定时器2的工作模式固定位16位自动重装载,不可更改。

4.定时器中断配置

配置定时器中断,一般有一下几个步骤:

初始化函数

1.设置定时器工作模式
2.设置定时器高八位/低八位寄存器的值(设置定时器溢出时间)
3.开启中断允许
4.设置定时器中断优先级(定时器2不可以设置优先级)
5.开启定时器

具体代码如下:

//定时器0初始化函数,1ms进来一次
void Timer0_Init(void)
{
    TMOD |= 0x00;    //设置定时器0工作模式0,16位自动重装载
//    TMOD |= 0x01;    //设置定时器0工作模式1
//    TMOD |= 0x02;    //设置定时器0工作模式2,8位自动重装载
    TL0 = 0x18;     //设置定时器溢出时间
    TH0 = 0xFC;
    ET0 = 1;        //开启定时器0中断允许
    EA=1;           //开启总中断允许
    TR0 = 1;        //开启定时器0
    PT0 = 0;        //设置优先级为低优先级,为1时设置为高优先级
}
//定时器0初始化函数,1ms进来一次
void Timer1_Init(void)
{
    TMOD |= 0x00;    //设置定时器1工作模式0,16位自动重装载
//    TMOD |= 0x10;    //设置定时器1工作模式1
//    TMOD |= 0x20;    //设置定时器1工作模式2,8位自动重装载
    TL1 = 0x18;     //设置定时器溢出时间
    TH1 = 0xFC;
    ET1 = 1;        //开启定时器0中断允许
    EA=1;           //开启总中断允许
    TR1 = 1;        //开启定时器0
    PT1 = 0;        //设置优先级为低优先级,为1时设置为高优先级
}
//定时器2初始化函数,1ms进来一次
//定时器2工作模式固定为16位自动重装载模式
void Timer2_Init(void)
{
   AUXR |= 0x10;        //将T2R设置为1,打开定时器2
    IE2 |= 0x04;     //开启定时器2中断允许
    T2H = 0xFC;     //设置定时器2中断溢出时间
    T2L = 0x18;     
    EA = 1;         //开启中断总允许
}

中断服务函数

6.编写定时器中断服务函数
具体中断号与定时器对于关系如下:
定时器0 interrupt 1
定时器1 interrupt 3
定时器2 interrupt 12

具体代码如下:

//定时器0服务函数
void External_Hander0() interrupt 1
{
    //函数内容
}

//定时器1服务函数
void External_Hander2() interrupt 3
{
    //函数内容

}

//定时器2服务函数
void External_Hander2() interrupt 12
{
    //函数内容

}

实战环节

1.任务要求

单片机用工作方式0编写秒表,蓝桥杯单片机学习,单片机,蓝桥杯,学习,51单片机,c语言

2.实现思路

单片机用工作方式0编写秒表,蓝桥杯单片机学习,单片机,蓝桥杯,学习,51单片机,c语言

首先我们有一个Tick值,可以通过Tick得到数码管需要显示的数字,每50msTick++,数码管需要显示的数字也随之改变,就可以实现模拟秒表的走时功能,
然后通过外部中断0/S5按下,将Tick清0,数码管上的数字也随之清0.
通过外部中断1/S4按下,控制定时器的开启和关闭,实现暂停和启动的功能

3.代码实现

1.mian.c

#include <STC15F2K60S2.H>
#include "Interrupt.h"
#include "LS138.h"

unsigned char arr_NixieTube[8]; //用于存放数码管显示的内容
unsigned long int Tick = 0;     //用于计算数码管所需要显示的内容

//通过数码管显示的内容计数的到Tick的初始值
void arr_NixieTube_Init(void)
{
    arr_NixieTube[0]=0;
    arr_NixieTube[1]=8;
    arr_NixieTube[2]=21;
    arr_NixieTube[3]=2;
    arr_NixieTube[4]=6;
    arr_NixieTube[5]=21;
    arr_NixieTube[6]=1;
    arr_NixieTube[7]=8;
    Tick = arr_NixieTube[7] + 10*arr_NixieTube[6] + arr_NixieTube[4]*60 + 
    arr_NixieTube[3]*600 + arr_NixieTube[1]*3600 +arr_NixieTube[0]*360000;
}

//通过Tick的值,得到数码管需要显示的内容
void Tick_To_arr(void)
{
    arr_NixieTube[0] = Tick/12000;
    arr_NixieTube[1] = Tick/1200%10;
    arr_NixieTube[3] = Tick/200%10;
    arr_NixieTube[4] = Tick/20%10;
    arr_NixieTube[6] = Tick/10%2;
    arr_NixieTube[7] = Tick%10;
}
//初始化函数
void Init(void)
{
    Timer0_Init();
    LS138_Init();
    IT0_Init();
    IT1_Init();
    arr_NixieTube_Init();
}

void main()
{
    Init();
	while(1)
	{
        Tick_To_arr();  //在数码管显示之前,通过Tick的值,得到数码管需要显示的内容
		SEG_Write(arr_NixieTube);   //数码管显示内容
	}
}


//外部中断0服务函数
void External_Hander0() interrupt 0
{
    Tick = 0;       //将Tick清0
}

//外部中断1服务函数
void External_Hander2() interrupt 2
{
    
    TR0 = ~TR0;     //开启/关闭定时器
}  

void External_Hander1() interrupt 1
{
    static unsigned char Timer0_Count=0;
//    TL0 = 0x18;
//    TH0 = 0xFC;
    Timer0_Count++;
    if(Timer0_Count>=50)
    {
        Timer0_Count=0;     //每50msTick++
        Tick++;
    }
}    	

PS: void SEG_Write(unsigned char* p) 这个函数出现在“蓝桥杯单片机学习——数码管静态显示”,

2.Interrupt.c

#include "Interrupt.h"

//外部中断0初始化函数
void IT0_Init(void)
{
    EX0 = 1;    //开启外部中断0允许
    EA=1;       //开启中断总允许
    IT0=1;      //设置触发方式为下降沿触发,为0时触发方式为下降沿和上升沿都触发
    PX0 = 0;    //设置低优先级,为1时为高优先级
}
//外部中断1初始化函数
void IT1_Init(void)
{
    EX1 = 1;    //开启外部中断0允许
    EA=1;       //开启中断总允许
    IT1=1;      //设置触发方式为下降沿触发,为0时触发方式为下降沿和上升沿都触发
    PX1 = 0;    //设置低优先级,为1时为高优先级
}

//定时器0初始化函数,1ms进来一次
void Timer0_Init(void)
{
    TMOD |= 0x00;    //设置定时器0工作模式0,16位自动重装载
//    TMOD |= 0x01;    //设置定时器0工作模式1
//    TMOD |= 0x02;    //设置定时器0工作模式2,8位自动重装载
    TL0 = 0x18;     //设置定时器溢出时间
    TH0 = 0xFC;
    ET0 = 1;        //开启定时器0中断允许
    EA=1;           //开启总中断允许
    TR0 = 1;        //开启定时器0
    PT0 = 0;        //设置优先级为低优先级,为1时设置为高优先级
}

3.Interrupt.h

#ifndef __INTERRUPT_H_
#define __INTERRUPT_H_
#include <STC15F2K60S2.H>

//外部中断0初始化函数
void IT0_Init(void);

//外部中断1初始化函数
void IT1_Init(void);

//定时器0初始化函数,1ms进来一次
void Timer0_Init(void);


外部中断0服务函数
//void External_Hander0() interrupt 0
//{
//    
//}

外部中断1服务函数
//void External_Hander2() interrupt 2
//{
//    
//} 

定时器0服务函数
//void External_Hander0() interrupt 1
//{
//    
//}



#endif  /*__INTERRUPT_H_*/

总结

定时器在我们的程序编写工程中应用比较广泛,其中定时器0/1的使用频率最高,工作模式中16位自动重装载使用较多,需要重点掌握,使用方法并不难,但需要理解清楚定时器的工作原理,其他的就没有了,好好学习吧。单片机用工作方式0编写秒表,蓝桥杯单片机学习,单片机,蓝桥杯,学习,51单片机,c语言

单片机用工作方式0编写秒表,蓝桥杯单片机学习,单片机,蓝桥杯,学习,51单片机,c语言文章来源地址https://www.toymoban.com/news/detail-766418.html

到了这里,关于蓝桥杯单片机学习6——定时器/计数器&定时器实现秒表功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32单片机入门学习笔记——定时器TIM第二部分

    笔记整理自B站UP主 江科大自化协 教程 《STM32入门教程-2023持续更新中》 ,所用单片机也为教程推荐单片机。 第一部分:定时器基本定时的功能,定时器每隔这个时间产生一个中断,来实现每隔一个固定时间执行一段程序的目的,比如要做一个时钟、秒表或者使用一些程序算

    2024年02月08日
    浏览(54)
  • 学习笔记|定时器|STC中断|定时器时间计算|STC32G单片机视频开发教程(冲哥)|第十一集:定时器的作用和意义

    什么是定时器:定时器-与非网 上节课的一段代码: TimeCount++然后一个延时1毫秒,每运行1ms,变量就会加一。 系统已经运行了多少个毫秒。 实际使用时的代码如下, 判断按键有沿有按下的时候,我们等待按键松开,还有一个while循环。 如果没有松开,会一直死在这一行。所以,

    2024年02月09日
    浏览(64)
  • STM32单片机入门学习笔记——定时器TIM第一部分

    笔记整理自B站UP主 江科大自化协 教程 《STM32入门教程-2023持续更新中》 ,所用单片机也为教程推荐单片机。 第一部分:定时器基本定时的功能,定时器每隔这个时间产生一个中断,来实现每隔一个固定时间执行一段程序的目的,比如要做一个时钟、秒表或者使用一些程序算

    2024年02月03日
    浏览(56)
  • 51单片机定时器/计数器(定时器中断)

    实现功能 通过定时器终端控制LED灯 D1 间隔一秒闪烁 单片机型号:STC89C52 定时器介绍 1、51单片机定时器原理 定时器实质上就是一个加1计数器。它随着计数器的输入脉冲进行自加1,也就是每来一个脉冲,计数器就自动加1,,当加到定数器满时,再输入一个脉冲就使定时器回零

    2024年02月06日
    浏览(57)
  • 单片机-定时器时钟

    89C52RC 1.定时器0,lcd1602显示时间。    main.c

    2024年02月11日
    浏览(44)
  • 单片机中定时器

    1. 定时器的使用步骤 1)主函数; 2)对中断和定时器进行初始化=先设置计数器的工作方式,设定TH0、TL0或TH1、TL0的初值,即:TH0=(8192-C)/32,TL0=(8192-C)%32,开启中断和定时器,即:TR=1; 3)设置中断服务程序-》执行对应中断需要做的内容。 51单片机拥有两个定时器,分别为

    2024年02月08日
    浏览(47)
  • 51单片机定时器

    目录 前言 一、定时器的介绍及其作用 二、定时器的内部构造及其原理 计算机周期 定时器的工作模式与流程 定时器中断相关寄存器 寄存器的配置  三、程序 总结         下面来介绍学习51单片机第一个也是最常用的片上外设——定时器。该硬件是集成在单片机内部的,

    2024年02月05日
    浏览(57)
  • 【51单片机】:定时器的详解(包括对单片机定时解释、各类定时方式,以及中断方式)

              51定时/计数器的详解。                   码字不易,如有帮助请收藏,点赞哦。         前提:首先我们知道51单片机内部有21~26个特殊功能寄存器: P.x口寄存器:P0、P1、P2、P3 数据指针寄存器:DP0H、DP0L、DP1H、DP1L 定时器: TH1、TL1、TH0、TL0、TMOD、TCON 串口:

    2024年02月07日
    浏览(97)
  • 【单片机】STM32单片机的各个定时器的定时中断程序,标准库

    高级定时器和普通定时器的区别(https://zhuanlan.zhihu.com/p/557896041): TIM1是高级定时器,使用的时钟总线是RCC_APB2Periph_TIM1,和普通定时器不一样。 timer.c timer.h 调用 timer.c timer.h 调用 timer.c timer.h 调用 timer.c timer.h 调用 timer.c timer.h 调用

    2024年02月11日
    浏览(53)
  • 51单片机——定时器中断

    新版51单片机内部有 3 个16位可编程的定时器/计数器,即定时器 T0,T1,T2 。他们既有 定时 功能又有 计数 功能,我们可以通过配置与它们相关的特殊功能寄存器可以选择启用定时功能或计数功能;其中需要注意的是,这个定时器系统是单片机内部的一个独立的硬件部分,它与

    2023年04月10日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包