首页 > 其他分享 >08-定时器的基本原理与应用

08-定时器的基本原理与应用

时间:2023-10-05 23:22:06浏览次数:34  
标签:定时器 基本原理 08 计数 计数器 12 65535 定时

定时器的基本原理与应用

1、什么是定时/计数器?
在没有钟表的时候,定时的方式通过有一注香的时间,或者一桶水的时间。前者烧香不断减少是减法,后者滴水不断增加是加法。
定时/计数器,是一种能够对内部时钟信号或外部输入信号进行计数,当计数值达到设定要求时,向CPU提出中断处理请求,从而实现定时或者计数功能的外设。定时/计数器的最基本工作原理是进行计数。作为定时器时,计数信号的来源选择周期性的内部时钟脉冲;用作计数器时,计数信号的来源选择非周期性的外部输入信号。
不管是定时器还是计数器,本质上都是计数器
定时器的工作原理与计数初值计算,可以参考以下例子:

112649npg4n9cd4f119u4r.png.thumb

2、51单片机的定时/计数器
51单片机有两个定时/计数器T0和T1,为16位加法计数器,由低8位TLx和高8位THx两个寄存器组成,最大计数值为65535个计数脉冲
该加1计数器的计数脉冲来源有2个:
<1> 系统时钟振荡器输出的12分频
<2> T0或T1引脚输入的外部脉冲信号
每接收到一个计数脉冲,计数器就会加1,当计数值累计至全为1时(8位255,13位8191,16位65535),再输入一个计数脉冲,计数器便会溢出回零,并且计数器的溢出是TCON寄存器的TF0或TF1位置1,同时向内核提出中断请求。如果定时/计数器工作于定时模式,则表示间隔定时时间到,如果工作与计数模式,则表示计数值已满。
假设单片机的外部晶振为12MHz,那么,经过12分频后输入计数器的计数脉冲为1MHz,即每个脉冲的周期为1us。因此定时器T0的16位工作模式最大的定时时间为65535us,65.5ms。如果要定时10ms的话,计数器就不能够从0开始计数了,必须给它一个计数初值。怎么计算这个初值呢?
要定时10ms,则相当于计数10000个脉冲后计数器的值就到达65535了,那么开始计数的这个地方就是计数初值。
65535 - 10000 = 55535 = 0xd8ef
把这个计算得到的初值写入TH0和TL0寄存器即可:
TH0 = 0xd8; 或者 TH0 = (65535 - 10000) / 256;
TL0 = 0xef; 或者   TL0 = (65535 - 10000) % 256;

3、定时/计数器相关寄存器
与定时/计数器相关的寄存器除了计数初值寄存器THxTLx之外,就是TMOD寄存器和TCON寄存器,务必掌握。
<1> TMOD模式控制寄存器,不能进行位寻址,只能字节操作。

115216kelaqaauajq4zyll.png.thumb

<2> TCON中断标志寄存器,参考手册: IAP15F2K61S2_PDF_数据手册_Datasheet_规格书(semiee.com)

4、定时/计数器的编程思想
在定时/计数器的程序设计中,通常有两个函数:初始化函数中断服务函数
在初始化函数中,一般需要进行以下几个配置:
<1> 配置工作模式,即对TMOD寄存器编程。
<2> 计算技术初值,即对THx和TLx寄存器进行赋值。
<3> 使能定时/计数器中断,即ET0或ET1置1。
<4> 打开总中断,即EA =1。
<5> 启动定时器,即TR0或TR1置1。
在中断服务函数中,一般需要进行以下的编程:
<1> 如果不是自动重装模式,需要对THx和TLx重新赋值。
<2> 进行间隔定时到达的逻辑处理(越少越好)。
其程序框架和代码编写基本上差不多:

120001ebmt1mbf10pmhrlz.png.thumb

20231005164730

本次单片机为12HMZ晶振的单片机

为了大家的需求,以下以11.0592MHZ的单片机为例,12HMZ同理

1Hz:1秒内电流往返一次

晶振 11.0592MHz =11059200Hz

时钟周期  1/11059200 s(晶振的倒数)

机器周期是 12/11059200 s (标准框架下51单片机一个机器是12个时钟周期)

因为定时器是每个机器周期加1所以定时时间为 N*时钟机器周期时间=所定时间T

所以要经过的机器周期是N*(12/11059200 s)=T

​ N=t/(12/11059200) t为定时时间单位为s

初值等于 65536-N(因为16位的定时器65535再加1才溢出)

例如:

需要定时50ms=0.05s

0.05/(12/11059200)=0.05(11059200/12)=0.05921600=46080

​ 快速计算只需更改这个 ↑

初值y=65536-46080=19456=0X4C00

1.晶振12M

​ 12MHz除12为1MHz,也就是说一秒=1000000次机器周期。10ms=10000次 机器周期。

2.晶振11.0592M

​ 11.0592MHz除12为921600Hz,就是一秒921600次机器周期,10ms=9216次机器周期。

以上单位训练代码如下:

#include <REGX52.H>
sbit L1 = P0^0;
sbit L8 = P0^7;
void _74HC138(unsigned char n) {
	
	switch(n) {
		case 4:
			P2 = (P2& 0x1f) | 0x80;
			break;
		case 5:
			P2 = (P2& 0x1f) | 0xa0;
			break;
		case 6:
			P2 = (P2& 0x1f) | 0xc0;
			break;
		case 7:
			P2 = (P2& 0x1f) | 0xe0;
			break;
	
	}

}

void System_Init(void) {
	
	_74HC138(5);
	P0 = 0x00;
	_74HC138(4);
	P0 = 0xFF;
	

}
void InitTimer0() {
	
	TMOD = 0x01;
	
	
	//1Hz:1秒内电流往返一次

   //晶振           11.0592MHz =11059200Hz

   // 时钟周期  1/11059200   s(晶振的倒数)

  //机器周期是 12/11059200 s (标准框架下51单片机一个机器是12个时钟周期)

  //因为定时器是每个机器周期加1所以定时时间为 N*时钟机器周期时间=所定时间T

  //所以要经过的机器周期是N*(12/11059200 s)=T

//  N=t/(12/11059200)

 //初值等于 65536-N(因为16位的定时器65535再加1才溢出)
	
	// THx = (65535 - N) / 256;
	// TLx = (65535 - N) % 256;    11.0592MHZ = 11059200HZ
	// 机器周期是N*(12/11059200) = T
	//         N=t/(12/11059200)    t 单位s 
	
	
	
	
	// 50000us = 50ms
	TH0 = (65535 - 50000) / 256;
	TL0 = (65535 - 50000) % 256;
	// 打开定时中断
	ET0 = 1;
	// 总中断使能
	EA = 1;
	// 打开定时器T0
	TR0 = 1;
}
void main(void) {
	
	InitTimer0();
	_74HC138(4);
	System_Init();
	
	while(1) {
		
	
	}
}


unsigned char count =0;


void Timer0_Rountine(void) interrupt 1 {
	TH0 = (65535 -  50000) / 256;
	TL0 = (65535 -  50000) % 256;
	count++;
	
	// 0.5s         0.5*500 = 250s
	if(count % 10 == 0) {
		
		L1 = ~L1;
	}
	
	
	if(count == 100) {
		L8 = ~L8;
		
		count=0;
	}
	
	
	
	
}

标签:定时器,基本原理,08,计数,计数器,12,65535,定时
From: https://www.cnblogs.com/bky111/p/17744097.html

相关文章

  • C++算法之旅、08 基础篇 | 质数、约数
    质数在>1的整数中,如果只包含1和本身这两个约数,就被称为质数(素数)866试除法判定866.试除法判定质数-AcWing题库\(O(n)\)boolisprime(intx){if(x<2)returnfalse;for(inti=2;i<x;i++)if(x%i==0)returnfalse;returntrue;......
  • MCU第一次使用笔记-STC8H1K08
    计时中断开不起来:需要开启定时器,开启总中断控制ET0=1;EA=1;PWM端口指定,按示例无法使用其他端口更改输出端口需要修改PWMA_CCER1,PWMA_ENO,文档描述看的不是太明白ADC使用时需要配置端口状态,还有上拉电阻,另外实际使用时跳动非常大尝试了很多方法:a......
  • 题解 accoders::NOI 5508【漂亮大厨(cook)】
    题解accoders::NOI5508【漂亮大厨(cook)】part1区间加\(x\),区间询问有多少个数字\(\leqy\)。\(n,m\leq10^5,x\leq200,y\leq10^7\)。考虑P5356[Ynoi2017]由乃打扑克的做法,分块,块内按照值排序。修改就整块打tag,散块暴力重构(可以归并排序重构);询问在整块上二分,散块暴力......
  • 408_C语言基础
    408_C语言基础学习内容掌握以下知识点足以应付408考试了:常量、变量、运算符、流程控制、函数、指针、结构体。变量变量其实只不过是程序可操作的存储区的名称。C中每个变量都有特定的类型,类型决定了变量存储的大小和布局,该范围内的值都可以存储在内存中,运算符可应用于变量上......
  • JavaSE(08) - 集合 - ArrayList
    JavaSE(08)-集合-ArrayListp111ArrayList基本使用创建集合对象,泛型:限定集合中的数据类型.在jdk7中,后面的<>中可以不写数据类型.集合在底层做了一些处理,打印对象不是地址值,而是集合中存储的内容.publicclassArrayListBasic{publicstaticvoidmain......
  • Flutter/Dart第08天:Dart类型(内置类型、记录、集合、泛型和类型别名)
    Dart内置类型(共10类)Dart官网文档:https://dart.dev/language/built-in-typesDart内置类型即DartSDK自带的类型,我们编程过程中可直接使用的类型,主要分为10类:数值类型:包括int类、double类等。字符串类型:即String类。布尔类型:即bool类。记录类型:即Record类,Dart3中开始支持(最......
  • FreeRTOS 原理 --- 软件定时器
     简介 有一个定时器任务,任务内读队列。启动定时器,会向队列发送消息,定时器任务读到消息后把定时器回调函数等信息作为一个链表项插入链表。当链表有链表项,算出还剩多长时间执行定时器回调函数,这个时间作为定时器任务阻塞时间。所以定时器任务重新运行要么是时间到准备运行定时器......
  • 08. 点亮LED
    一、LED简介  发光二极管,简称为LED,是一种常用的发光器件,它由含镓(Ga)、砷(As)、磷(P)、氮(N)等的化合物制成。通过电子与空穴复合释放能量发光,它在照明领域应用广泛。  发光二极管与普通二极管一样是由一个PN结组成,也具有单向导电性。当给发光二极管加上正向电压后,从P......
  • Linux 内存泄漏检测的基本原理
    一、mtrace分析内存泄露mtrace(memorytrace),是GNUGlibc自带的内存问题检测工具,它可以用来协助定位内存泄露问题。它的实现源码在glibc源码的malloc目录下,其基本设计原理为设计一个函数voidmtrace(),函数对libc库中的malloc/free等函数的调用进行追踪,由此来检测内存是否存在......
  • 错误解决Error: error:0308010C:digital envelope routines::unsupported
    问题原因:查了下原因,主要是nodeJsV17版本发布了OpenSSL3.0对算法和秘钥大小增加了更为严格的限制,nodeJsv17之前版本没影响,但V17和之后版本会出现这个错误。我的node版本是v18.12.1解决方式(仅windows):在package.json的scripts中新增SETNODE_OPTIONS=--openssl-lega......