一、简介
定时器和计数器是两个名字,但是原理上来说是一样的,都是对脉冲进行计数,区别在于时钟来源,如果来自内部时钟信号,由于内部时钟通常是比较准确的,所以是定时器,如果来自外部引脚,而外部引脚的信号并一定准确,则只对其进行计数,所以是计数器。接下来主要以定时器为主进行简单介绍,计数器类同。
二、时间计算
顾名思义,定时器肯定是和时间有关系的,那么时间是怎么计算的呢,我们以普通51内核为例。如下图(图片来自百度,我觉得他和51不符,所以改了下),通常一个指令周期=2X机器周期=12X时钟周期。而时钟周期又来自晶振。因此晶振频率确定后,那么各个时间也就确定了。
1. 计算内部指令周期
假设晶振频率是12MHz,那么机器周期=1/12MHz=1/12us,指令周期=12*机器周期=1us,也就是说单片机每执行一条指令,最小时间是1us。
2. 计算定时器初值
大多数定时器都可以工作在两种模式,一种是8位(最大计数256次)自动重装模式,一种是16位(最大计数65536次)自动重装模式,由于16位很显然计数或定时的范围是要远远大于8位的,因此,我们以16位模式应用为例,讲解计算方法。定时器在进行计数时是采用向上的方式,也就是说每一个系统信号过来以后,定时器设置的值进行+1,这里就有两个方式:
给定时器设置结束的值,从0开始不断+1,直到达到设置值溢出结束
给定时器设置初始值,从初始值不断+1,直到达到65536溢出结束
我们的51单片机采用了第二种方式,所以给定时器设置值时,我们说设置的是初值。计算公式如下:
初值=65536-定时时长指令周期=65536-定时时长(12*机器周期)
当晶振取值12MHz时,指令周期最小时间就是1us,因此上式也可以写成 初值=65536-定时时长 定时时长取值范围:1~65536us或1~65.536ms
3. STC-12T系列单片机初值
STC单片机很多系列现在都做到了12T,也就是说指令周期最小可以做到等于机器周期,不需要再除以12。因此除了单片机运行速度加快以外,定时精度也更高,计算公式如下:
初值=65536-定时时长指令周期=65536-定时时长机器周期
当晶振取值12MHz时,指令周期最小时间就是1/12us 初值=65536-定时时长/12 定时时长取值范围:1/12~65536/12us或1/12~65.536/12ms
由于12不能整除,所以计算时会有小数点,精度上比普通51会高一个数量级
三、寄存器设置
举个例子,以定时器0、16位自动重装实现1秒定时,STC的C51定时器,需要使用到的寄存器有如下几个:
AUXR:辅助寄存器
TCON:定时器/计数器中断控制寄存器,很多中断的控制寄存器都在这里,定时器中断允许等操作在这里
TMOD:定时器/计数器工作设置寄存器
TH0:定时器初值高8位 除以上寄存器以外,还有两个隐藏寄存器RLTH0和RLTL0,这两个寄存器和TL0、TH0两个寄存器使用同一个地址,设置初值时会自动给这两个寄存器设置值,也就是溢出后,会将这两个隐藏值重新装入TL0、TH0。
四、代码示例
/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC15F4K60S4 系列 定时器0的16位自动重装载模式举例---------------*/
/* --- Mobile: (86)13922805190 -------------- -------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966-------------------------*/
/* --- Web: www.STCMCU.com --------------------------------------------*/
/* --- Web: www.GXWMCU.com --------------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序 */
/* 如果要在文章中应用此代码,请在文章中注明使用了STC的资料及程序 */
/*---------------------------------------------------------------------*/
//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
//若无特别说明,工作频率一般为11.0592MHz
#include "reg51.h"
typedef unsigned char BYTE;
typedef unsigned int WORD;
//-----------------------------------------------
#define FOSC 11059200L
#define T1MS (65536-FOSC/1000) //1T模式
//#define T1MS (65536-FOSC/12/1000) //12T模式
sfr AUXR = 0x8e; //Auxiliary register
sbit P10 = P1^0;
//-----------------------------------------------
/* Timer0 interrupt routine */
void tm0_isr() interrupt 1
{
P10 = ! P10; //将测试口取反
}
void main()
{
AUXR |= 0x80; //定时器0为1T模式
// AUXR &= 0x7f; //定时器0为12T模式
TMOD = 0x00; //设置定时器为模式0(16位自动重装载)
TL0 = T1MS; //初始化计时值
TH0 = T1MS >> 8;
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
EA = 1; //使能全部中断
while (1);
}
五、Proteus仿真
由于Proteus只能仿真普通51内核的单片机,所以上述代码还需要进行简单修改,改成普通51代码。示例:led灯隔一秒亮灭一次,GIF录得有问题
//设晶振为12MHz
#include "reg52.h"
sbit P20 = P2^0;
unsigned char count = 0;
void tm0_isr() interrupt 1
{
//定时器设置为10ms,1s=100*10ms
//这里使用count进行计数,100次即1s
count++;
if(count > 100)
{
P20 = ! P20; //将测试口取反
count = 0; //count清零,进行下次计数
}
}
void main()
{
TMOD &= 0xF1; //设置定时器模式,普通51和stc的不一样,模式不同
TL0 = 0xF0; //设置定时初值
TH0 = 0xD8; //设置定时初值
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
EA = 1;
while (1);
}
上一篇:C51流水灯 running water lamp
下一篇:C51-定时器/计数器
推荐阅读最新更新时间:2024-11-17 02:26
设计资源 培训 开发板 精华推荐
- 【涂鸦智能】人体传感器V2.0
- 51单片机蜂鸣器
- 有线键盘转换为蓝牙键盘
- 1.3寸OLED 屏幕驱动板
- LTC3630HMSE 4.5V 至 65V 输入至 3.3V 输出、1.5A 稳压器的典型应用电路
- SLWRB4104A、EFR32 2.4 GHz/10 dBm 无线电板,基于 EFR32BG13 无线 SoC
- TRK-KEA128、Kinetis KEA128 StarterTRAK 用于 CAN 应用
- LTC4055 USB 电源控制和电池充电器应用
- DER-713 - 使用 InnoSwitch3-EP PowiGaN 和 MinE-CAP 的 65 W 高功率密度适配器
- OP184FSZ 高端负载电流监控器的典型应用
- 微灵医疗李骁健:脑机接口技术正在开启意识与AI融合的新纪元
- USB Type-C® 和 USB Power Delivery:专为扩展功率范围和电池供电型系统而设计
- 景昱医疗耿东:脑机接口DBS治疗技术已实现国产替代
- 首都医科大学王长明:针对癫痫的数字疗法已进入使用阶段
- 非常见问题解答第223期:如何在没有软启动方程的情况下测量和确定软启动时序?
- 兆易创新GD25/55全系列车规级SPI NOR Flash荣获ISO 26262 ASIL D功能安全认证证书
- 新型IsoVu™ 隔离电流探头:为电流测量带来全新维度
- 英飞凌推出简化电机控制开发的ModusToolbox™电机套件
- 意法半导体IO-Link执行器电路板为工业监控和设备厂商带来一站式参考设计
- Melexis采用无磁芯技术缩小电流感测装置尺寸