51单片机玩转物联网基础篇08-定时器

前言

在实时控制系统中,经常需要定时时钟以实现精准延时、定时,也经常需要计数功能以实现对外界脉冲进行计数, 本节,我们开始学习51单片机的定时器,然后开启一个定时器,实现1S翻转一次电平,控制LED灯亮灭。

一、基础知识

1.定时器简介

51单片机的定时器有两个,分别是T0和T1,它们可以用于定时或者对外部脉冲(事件)计数,还可以作为串行口的波特率发生器使用,定时器裸机结构图如下所示
在这里插入图片描述

定时器工作在定时方式时候,计数器对内部时钟机器周期数进行计数,每个机器周期等于12个晶体震荡周期,定时器工作在计数方式时候,计数脉冲来自外部输入引脚P3.4、P3.5,当外部输入信号从1到0跳变时,计数器的值加一。

2.定时器相关寄存器

(1) 控制寄存器TCON(88H)
在这里插入图片描述
TCON用于控制定时器的启动、停止、溢出标志和外部中断信号触发方式。

(2) 方式控制寄存器TMOD(89H)
在这里插入图片描述
从上图中可知,GATE为0时候,定时器由TR0或TR1控制启动,为1的时候,只有在外部中断引脚为高电平时候,TR0或者TR1才可以控制启动,对于T1,有3种工作方式,而T0有四种工作方式;

3.定时器工作方式

定时器工作方式如下
方式位计数器
(1) 工作方式0
在这里插入图片描述
方式0为13位计数器,由TLi的低5位和THi的8位组成,当GATE为1的时候,取反为0,定时器启动需要外部中断i引脚为1,然后置位TRi启动定时器,当外部中断i引脚变为0时候,定时器停止计数,这种方式可用来测试外部中断引脚正脉冲的宽度,当处于计数模式时,计数脉冲是Ti引脚上的外部脉冲。
定时模式初值:

X = 2的13次方 - f/12 * T   (其中X为计数器初值, f为时钟频率,T为定时时间)

计数模式初值:

X = 2的13次方 - 计数值 

(2) 工作方式1
在这里插入图片描述
方式1和方式0结构几乎完全相同,唯一区别是计数器的长度不同,方式1定时器长度为16位
定时模式初值:

X = 2的16次方 - f/12 * T   (其中X为计数器初值, f为时钟频率,T为定时时间)

计数模式初值:

X = 2的16次方 - 计数值 

(3) 工作方式2
在这里插入图片描述
方式2是能自动重装载计数初值的8位计数器, TLi用作计数器,THi保存计数初值,当TLi计数溢出时,将TFi位置1,同时又将保存在高8位中的计数初值重新装入低8位计数器中。
定时模式初值:

X = 2的8次方 - f/12 * T   (其中X为计数器初值, f为时钟频率,T为定时时间)

计数模式初值:

X = 2的8次方 - 计数值 

(4) 工作方式3
在这里插入图片描述
方式3只有T0支持,T1不支持,若将T1设置为方式3,T1会立即停止计数,且方式3相比其他几种方式,方式3只用了TL0计数器,其他操作和方式0、方式1相同。
注意:通常定时器中定时使用方式1,串口通信使用方式2

二、实例

1.创建工程

将上一节工程复制出来,并修改名字为07-timer
在这里插入图片描述

2.程序

我们使用定时器T0的方式1实现一个20ms的中断,中断服务程序中软件计数,当达到50次,总计1S时候,翻转LED引脚电平

首先,计算初值X

X = 2的16次方 - f/12 * T (其中X为计数器初值, f为11.0592MHZ,T为0.02S)
X = 47104 = 0xB800

然后初始化定时器

void tiemr_init(void) 
{ 
    TMOD = 0x01;     //使用模式1,16位定时器
    TH0 = 0xB8;
    TL0 = 0x00;              
    EA=1;            //总中断打开 
    ET0=1;           //定时器中断打开 
    TR0=1;           //定时器开关打开 
}

中断服务子程序

void timer0_func() interrupt 1 
{ 
    TH0 = 0xB8; 
    TL0 = 0x00;               
    if (count >50) 
    { 
        LED = ~LED; 
        count = 0; 
    } 
    count ++; 
}

完整代码

/*------------------------------------------------------ 
*店铺网址:https://shop321633213.taobao.com/?spm=a1z10.3-c.0.0.33816af5iLgN2F 
*适用于A08开发板 
*实验现象:定时器中断实现LED 1S亮灭 
*QQ群:906015840 
-------------------------------------------------------*/ 
 
#include<reg51.h> //头文件 
#include <intrins.h> 
#define uchar unsigned char 
#define uint unsigned int 
         
sbit LED = P1^0; 
int count = 0; 
 
void tiemr_init(void) 
{ 
    TMOD = 0x01;     //使用模式1,16位定时器 
    TH0 = 0xB8;      // 20ms中断,初值0xB800 
    TL0 = 0x00;               
    EA=1;            //总中断打开  
    ET0=1;           //定时器中断打开  
    TR0=1;           //定时器开关打开  
} 
 
void main(void) //主函数 
{ 
    tiemr_init(); 
    while(1); 
} 
// 20ms进入一次中断,计数50次为一秒 
void timer0_func() interrupt 1 
{ 
    TH0 = 0xB8; 
    TL0 = 0x00;               
    if (count >50) 
    { 
        LED = ~LED; 
        count = 0; 
    } 
    count ++; 
}

注意:中断子程序中需要重新装载计数器初值

三、运行

将上述程序生成的hex文件烧录到板子中,可以看到P1^0对应LED灯每隔1秒亮灭一次,说明进入定时器中断程序执行成功。
在这里插入图片描述

四、结语

如您在使用过程中有任何问题,请加QQ群进一步交流。

QQ交流群:906015840 (备注:物联网项目交流)

源码获取:扫描下方二维码,关注公众号,回复"51单片机"即可

硬件获取:淘宝搜索店铺"小驿物联"。
在这里插入图片描述
一叶孤沙出品:一沙一世界,一叶一菩提

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

物联网客栈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值