嵌入式——定时器中断

先上代码

#include <reg52.h>

void Init();

void main(){
    Init();
}

void Init(){
    TMOD = 0x01;
    TH0 = 0x4b;
    TL0 = 0xfc;    //定时器时间50ms,针对11.0592MHz频率CPU
    ET0 = 1;
    EA = 1;
    TR0 = 1;
}

void Timer0() interrupt 1 {
    TH0 = 0x4b;
    TL0 = 0xfd;
    //Timer循环体,运行过程放这里
}

示例代码就要有示例代码的样子,简简单单的才能把问题说清楚!

先解释下几个变量,TMOD,TH0,TL0,ET0,EA,TR0,这些变量不是我定义的,而是<reg52.h>头文件中的,先掌握用法,再深究原理。

TMOD:选择定时器的模式,不同的模式主要是能数到的最大数不同,一般就用模式1,最大可数到65535

TH0:TL0:设置起始值,TH0 故名思议就是数字转为16进制的高8位,TL0为低八位

TR0:启动、停止定时器,1启动,0停止,这个比较好理解吧

EA:允许系统进行中断,1允许,0禁止,算是个权限之类的东西

ET0:允许定时器0进行中断,1允许,0禁止

到这里你肯定还会有疑问,我接着给你解释!

1.定时器定时时间怎么算的啊,0x4bfc转为10进制并不是50啊?

——确实不是50,在讲定时器时间的算法之前,先得说下这个定时器的原理。

在我们高级语言习惯中,定时器就是给他设定一个数,他一秒数一下,数到那个值后进行一次定时操作。但是在嵌入式中并不是这样,也是因为这样错误的想法,我不理解了很久。

  在嵌入式中,定时器的实现原理是,他从某个数开始数,一直数到上限(如65535),到65536的时候定时器溢出,进行一次操作,而我们给的0x4bfc是定时器的起始值,也就是说定时器将从这个值开始数,一直数到65535,中间所耗费的时间就是50ms。

2.似乎明白了,那这个时间具体怎么算啊?

——恩,这个问题稍有些复杂,回答这个问题之前,还是要继续引入几个概念。

  时钟周期T1:晶振振荡周期,公式  T1 = 1/频率  ,如11.0592MHz的晶振频率  T1 = 1/11.0592 us

  机器周期T2:机器执行一条基本指令的时间,公式  T2 = 12 * T1  ,如11.0592MHz的机器周期约为  1.085 us

  

  所以,要定时50ms的计算过程

  50ms = 50000us = 50000/1.085 机器周期 = 46083 次

  也就是说,要让计时器数 46083 次就好了,要数到65535,那么很自然就知道是要从 65535 - 46083 = 19452 数起

  19452D = 0x4bfc

  所以 TH0 = 0x4b,  TL0 = 0xfc

3.我有注意到,TH0 TL0 TR0 ET0 后面都有0,感觉挺奇怪的?

——你看的很仔细,没错,这个0是有意义的。事实上,单片机里有两个定时器,TH0表示第一个定时器,TH1表示第二个,另外几个以T开头的都表示定时器变量,也都有T_0和 T_1两种,E开头的表示与中断相关。

4.interrupt 1 里面的1是什么意思,能换成其他数字吗?

——后面的1是中断号,Timer0 这个函数名称你可以随便取,但是后面这个数字却是固定的,因为它是用来说明这个函数是谁的中断函数,1表示是定时器1来中断,3表示定时器2中断。事实上,还有几个额外的中断类型,但是作为入门,就不在这里列举了。

5.为什么在中断函数 Timer0 里又重新设置了一次 TH0 和 TL0 呢,这是必须的吗?

——上面有提到过,这个函数里面的过程是在定时器数到65536溢出后执行的,但是有个问题是溢出完后TH0 和 TL0就会被重置为0,如果你不重新设定的话它会从0开始数起,所以是必须的,定时器1和定时器2都是这样的。

定时器简单的理解到这就差不多了,关于中断还需要继续学习,另外几种中断方式原理上都是有共通点的!

时间: 2024-08-25 18:49:45

嵌入式——定时器中断的相关文章

79.ZYNQ内部私有定时器中断

上篇文章实现了了PS接受来自PL的中断,本片文章将在ZYNQ的纯PS里实现私有定时器中断.每个一秒中断一次,在中断函数里计数加1,通过串口打印输出. *本文所使用的开发板是Miz702(兼容zedboard) PC 开发环境版本:Vivado 2015.2 Xilinx SDK 2015.2* 中断原理 中断对于保证任务的实时性非常必要,在ZYNQ里集成了中断控制器GIC(Generic Interrupt Controller).GIC可以接受I/O外设中断IOP和PL中断,将这些中断发给CP

Arduino101学习笔记(十二)&mdash;&mdash; 101定时器中断

一.API 1.开定时器中断 //********************************************************************************************* //函数名称:CurieTimerOne.start(int timerPeriodUsec, userCallBack) //输入参数:timerPeriodUsec:: 多少微妙产生中断 // userCallBack : 中断函数 //函数返回:无 //函数功能:开定时器

定时器中断各个寄存器含义

中断寄存器,定时器/计数器相关寄存器本身或者相关位用来做初始化,中断函数的内容主要是体现发生中断后所需要的操作(在中断函数内写代码). 1.中断允许寄存器IE 图1.中断寄存器IE 中断寄存器用来设定各个中断源的打开和关闭,IE在特殊功能寄存器中,字节地址为A8H,位地址(由低位到高位)分别是A8H~AFH,该寄存器运行位寻址,即可对该寄存器的每一位进行单独操作.单片机复位时IE全部被清零.下面列举各位的在不同状态下的具体含义: EA-------全局中断允许位 EA = 1,打开全局中断控制,

stm32通用定时器中断问题

在使用stm32的通用定时器定时中断的时候,发现定时器在完成初始化配置后,定时器UIF位会立刻置位,导致在使能中断后,程序会立刻进入定时器中断. 如果设计代码时不希望定时器配置完成后,立刻进入中断,可以在定时器配置完成后,立刻清除UIF标志位(TIMx->SR &= 0xFFFE) ,再使能定时器更新中断.比如用库函数这么写: TIM_ClearITPendingBit(TIM4, TIM_IT_Update  ); TIM_ITConfig(TIM4,TIM_IT_Update,ENABL

用定时器中断,单片机中断处理时间大于定时器定时时间会怎样?

如果是不同的中断类型是可以根据优先级嵌套,如果是同一中断类型(如题), 有三种结果:1.马上进入新的中断处理(中断嵌套) 2.等待中断处理完再进入新的中断处理 3.出错. 单片机中断处理时间大于定时器定时时间,在下次中断时间到时,因为中断是同一类型.同一优先级,所以不会马上进入新的中断处理. 而是在本次中断处理结束后,单片机又马上进入新的定时器中断函数,主函数中的语句可能会没有机会运行下去,会影响后面中断的实时性.所以答案为2. 如果为了避免中断嵌套(同一优先级不会发生),在中断处理中人为的在进

奶爸业余单片机学习之:定时器中断的使用方法——进入中断TF0(TF1)值硬件自动重置

/*============定时器中断的使用方法—---TF0(TF1)值硬件重置法======== 第一:打开总中断第二:打开定时器 中断第三:设置特殊功能寄存器TMOD,配置好工作模式. 第四:设置计数寄存器TH0和TL0的初值. 第五:设置TCON,通过TR0置1来让定时器开始计数.*/ //LED由三极管及73HC138控制//用定时器0实现亮与灭之间的1秒延时 # include <reg52.h> sbit led2 = P0^0; sbit addr0 = P1^0;sbit a

STC10F10XE定时器中断输出10KHz的方波程序

//咱做硬件的也动手做点测试程序,为了测试新做的电机驱动板,找了个51的板子当10K信号发生器测试IGBT开关延时时间. #include <STC_NEW_8051.H>#include<intrins.h>#define uchar unsigned char//这个T0定时器中断程序网上找的,改了下定义和计数器值,移植到STC10F10XE上.sbit OUT=P2^7; //定义OUT输出端口 /*--------------------------------------

STM32 Timer (2) 定时器中断代码框架

3. 代码框架 3.1 分频系数的计算 x1/x2 /N(预分频) APB1时钟------->F(CK_PSC)--------------->CK_CNT 如果APB1的分频系数为1, CK_INT的倍频系数就是x1 如果APB1的分频系数不为1, CK_INT的倍频系数就是x2   STM32F1(MHz) STM32F4(MHz) STM32F7(MHz) SYSCLK 72 168 216 AHB 72 168 216 APB1 (AHB/4) 18 42 54 CK_INT(x1/

AVR单片机教程——定时器中断

本文隶属于AVR单片机教程系列. ? 中断,是单片机的精华. 中断基础 当一个事件发生时,CPU会停止当前执行的代码,转而处理这个事件,这就是一个中断.触发中断的事件成为中断源,处理事件的函数称为中断服务程序(ISR). 中断在单片机开发中有着举足轻重的地位--没有中断,很多功能就无法实现.比如,在程序干别的事时接受UART总线上的输入,而uart_scan_char等函数只会接收调用该函数后的输入,先前的则会被忽略.利用中断,我们可以在每次接受到一个字节输入时把数据存放到缓冲区中,程序可以从缓