2005-02-16 17:31:00 czeus 阅读数 1661
  • 单片机控制第一个外设-LED灯-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    3998 人正在学习 去看看 朱有鹏
单片机定时中断的精确定时编程方法种种

作 者:■ 南京农业大学 蹇兴亮

引 言

  MCS-51单片机的中断响应延迟时间,取决于其它中断服务程序是否在进行,或取决于正在执行的是什么样的指令。单中断系统中的中断响应时间为3~8个机器周期[1]。无论是哪一种原因引起的误差,在精确定时的应用场合,必须考虑它们的影响,以确保精确的定时控制。根据定时中断的不同应用情况,应选择不同的精确定时编程方法。

  文中以定时器T1工作在定时方式1为例,晶振频率为12MHz 。

1 方法1

  在定时器溢出中断得到响应时,停止定时器计数,读出计数值(反映了中断响应的延迟时间),根据此计数值算出到下一次中断时,需多长时间,由此来重装载和启动定时器。例如定时周期为1ms,则通常定时器重装载值为-1000(0FC18H)。下面的程序在计算每个定时周期的精确重装载值时,考虑了由停止计数(CLR TR1)到重新启动计数(SETB TR1)之间的7个机器周期时间。程序中#LOW(-1000+7)和#HIGH(-1000+7)是汇编符号,分别表示-1000+7=0FC1FH这个立即数的低位字节(1FH)和高位字节(0FCH)。
……
CLR EA ;禁止所有中断
CLR TR1 ;停止定时器T1
MOV A,#LOW(-1000+7) ;期望数的低位字节
ADD A,TL1 ;进行修正
MOV TL1,A ;重装载低位字节
MOV A,#HIGH(-1000+7) ;对高位字节处理
ADDC A,TH1
MOV TH1,A
SETB TR1 ;重启动定时器
SETB EA ;重开中断
……

  此方法适用于各种原因造成的定时误差的情况,为通用方法。

2 方法2

  假如定时周期为10ms,通常定时器重装载值为0D8F0H,中断子程序如下[2]:
ORL TL1,#0F0H
MOV TH1,#0D8H
……

  这里用ORL TL1,#0F0H代替MOV TL1,#0F0H 可提高定时精度。此方法只适用于重装载值低位字节的低4位为零,且中断响应的延迟时间小于16个机器周期的情况。类似的定时器重装载值有0FFF0H,0FFE0H等。

3 方法3

  假如定时周期为1ms,通常定时器重装载值为0FC18H,中断子程序如下:
MOV A,#LOW(-1000+4) ;期望数的低位字节
ADD A,TL1
MOV TL1,A
MOV A,#HIGH(-1000+4) ;对高位字节处理
ADDC A,TH1
MOV TH1,A
DEC TL1 ;恢复提前了的2个机器周期
……

  这种方法中不停止定时器计数过程,若在执行指令ADDC A,TH1 或MOV TH1,A时,恰好产生TL1溢出向TH1进位的情况,则TH1的值就不对了,会产生更大的误差。为此,程序段开头为重装载值加4,若有溢出进位,则可提前发生,其中2个机器周期是考虑到为TL1重装载占用的时间。

  此方法适用于系统中无其它更高优先级中断源的情况。若类似方法1,在程序段开头和结尾分别加上禁止所有中断(CLR EA)和开中断(SETB EA)指令,则将适用于所有情况。

4 方法4

  假如定时周期不确定,只知道定时器重装载值存放在寄存器R3、R2中,中断子程序如下:
MOV A,#05H ;3个机器周期装载TL1,2个周期提前
ADD A,TL1
ADD A,R2
MOV TL1,A
MOV A,R3 ;处理高位字节
ADDC A,TH1
MOV TH1,A
DEC TL1 ;恢复提前了的2个机器周期
……

  此法适用于定时周期不确定的情况,其它同方法3。

5 方法5

  当定时中断发生的位置可预知时,通常出现在主程序的AJMP $ (或SJMP $)等待指令处,中断延迟时间为3个或4个机器周期。取固定值4可简化补偿程序。以定时周期1ms为例,中断子程序如下:
ORG 001BH
MOV TL1,#LOW(-1000+4)
MOV TH1,#HIGH(-1000+4)
……

  此方法适用于定时中断总发生在同一条指令位置,且无其它中断源的情况。
结 语

  上述5种方法误差均不超过1个机器周期,其中方法1、3、4较为通用,适用于任何情况,但程序较长;方法2、5简单,但必须注意满足对应条件,才能使用。当然,也还有其它方法[3],但比较烦琐,并不理想,这里不一一介绍。

                 参考文献
1 孙涵芳,徐爱卿. MCS-51/96系列单片机原理及应用[M]. 北京:北京航空航天大学出版社,1988
2 周航慈. 单片机应用程序设计技术. [M]. 修订版. 北京:北京:北京航空航天大学出版社,2002
3 聂毅. 单片机定时器中断时间误差的分析及补偿[J]. 微计算机信息,2002,18(4):37~38

蹇兴亮:讲师,主要从事测试计量技术及单片机的教学。
                               (收稿日期:2004-03-30)
2019-12-03 12:41:05 pangyinglong 阅读数 86
  • 单片机控制第一个外设-LED灯-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    3998 人正在学习 去看看 朱有鹏

1、单片机定时器中断后计数器是否还会计数

解决:单片机定时器中断后计数器还是会计数的,如果重新赋值,会按照设置的时间进行计时。如果没有,则从0开始。

2、单片机在执行定时器中断时,是否在没执行当前中断情况再次执行定时器中断(中断嵌套?)

解决:中断在执行时,如果又有一个中断产生,将不会进入中断函数,知道当前中断执行结束后,才允许下一个新的中断进入。

总结:定时器中断在执行中断过程中,计数器一直计数,但是产生的中断不能进入中断函数。只有上一个中断结束后,才会发生新的中断进入。

测试:

单片机:stc12c5a60s2

软件:keil

串口软件:stc-isp

思路:在定时中断执行函数中使用串口打印0-9,采用两次打印,它们之间间隔1s,定时中断时间是10ms。通过查看串口发送的数据,如果是相同的数字两两相邻,表示延迟1s过程中中断没有再次进入;如果数字是连续而且很快显示出来的,表示在延迟1s的过程中多次进入了中断。

代码:

void time0_inter() interrupt 1{
	//2msʱ¼ä
	TF0 = 0;
	TH0 = 0xF8;
  TL0 = 0x30;
	adc.transFlag++;
	if(adc.transFlag>=10){
		adc.transFlag=0;
	}
	uart0_send_byte('0'+adc.transFlag);
	//²âÊÔ¶¨Ê±ÖжÏʱÊÇ·ñ»á¼ÌÐø¼Æʱ
	delay1s();
	uart0_send_byte('0'+adc.transFlag);
	
	//´ò¿ªADC
	adc_switch(ADC_OPEN);
}

结果:

                                     

由结果可以看出:定时器在延迟1s的过程中没有多次进行定时中断函数执行。

可以得出的结论是:

如果在定时中断执行函数中处理的时间超过定时时间,那么会出现中断丢失的问题,即需要进行中断处理时,由于上一个中断还未结束,失去这个时间点需要处理执行指令的机会。

如果中断函数执行处理的时间小于定时中断时间,那么就能够在下一次中断到来之前结束本次中断,这样新来的中断就能够执行需要的处理指令。

2013-12-17 21:54:17 csuyishuan 阅读数 28
  • 单片机控制第一个外设-LED灯-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    3998 人正在学习 去看看 朱有鹏

                                         单片机定时器中断

    51单片机内部共有两个16位的可编程的定时器/计数器T0、T1,而52单片机内部多了一个T2定时器/计数器。通过设置相关的特殊功能寄存器,就可以选择启用定时或计数功能。

    需要注意的是,定时器系统是单片机内部一个独立的硬件部分,它与cpu和晶振通过内部某些控制线连接并相互作用,cpu一旦设置开启定时功能,定时器便在晶振的作用下自动开始计时,当定时器计数计满后,会溢出产生中断,并通知cpu作相应的处理。

    T0、T1实质是加一计数器,由高8位和低8位两个寄存器组成。TMOD是定时/计数器工作方式寄存器,确定工作方式和共

2018-12-02 09:49:32 sinat_38816924 阅读数 779
  • 单片机控制第一个外设-LED灯-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    3998 人正在学习 去看看 朱有鹏

前言:单片机的中断系统(一)

图片和内容来自普中科技的ppt。


相关知识:

周期:

振荡周期:为单片机提供定时信号的振荡源的周期(晶振周期或外加振荡周期)

状态周期:2个振荡周期为1个状态周期,用S表示。振荡周期又称S周期或时钟周期。

机器周期:1个机器周期含6个状态周期,12个振荡周期。

指令周期:完成1条指令所占用的全部时间,它以机器周期为单位。

(1M=1000000,所以在晶振频率为12MHZ时,一个机器周期=1/12M=1us)

  (指令周期的长短不一,如果不知道一些指令周期的长度,即使定时中断,也不能理论上绝对准确的中断。因为函数的调用等也需    要时间)(这目前我还不会,但是感觉应该可以更精确延时,因为可以在计时中剪掉相应的操作时间)

IT0/IT1:

51单片机有两组定时器/计数器IT0/IT1,因为既可以定时又可以计数,故称之为定时器/计数器。

定时器/计数器和单片机的CPU是相互独立的。定时器/计数器工作的过程是自动完成的,不需要CPU的参与。

51单片机中的定时器/计数器是根据机器内部的时钟或者是外部的脉冲信号对寄存器中的数据加1。

有了定时器/计数器之后,可以增加单片机的效率,一些简单的重复加1的工作可以交给定时器/计数器处理。CPU转而处理一些复杂的事情。同时可以实现精确定时作用。

 

定时/计数器的工作原理

定时/计数器实质上是一个加1计数器。它随着计数器的输入脉冲进行自加1,也就是每来一个脉冲,计数器就自动加1,,当加到计数器为全1时,再输入一个脉冲就使计数器回零,且计数器的溢出使相应的中断标志位置1,向CPU发出中断请求(定时/计数器中断允许时)。如果定时/计数器工作于定时模式,则表示定时时间已到;如果工作于计数模式,则表示计数值已满。

 

51单片机定时/计数器结构

定时/计数器的实质是加1计数器(16位),由高8位和低8位两个寄存器THx和TLx组成。TMOD是定时/计数器的工作方式寄存器,确定工作方式和功能;TCON是控制寄存器,控制T0、T1的启动和停止及设置溢出标志。

图一:定时计数器结构

 

定时/计数器的控制

51单片机定时/计数器的工作由两个特殊功能寄存器控制。TMOD用于设置其工作方式;TCON用于控制其启动和中断申请。

工作方式寄存器TMOD

图二:TMOD

1、高四位用来控制T1,低四位用来控制T0

2、GATE是门控位。GATE=0时,用于控制定时器的启动不受外部中断源信号的影响。只要用软件使TCON中的TR0或TR1为1,就可以启动定时/计数器工作;GATA=1时,要用软件使TR0或TR1为1,同时外部中断引脚INT0/1也为高电平时,才能启动定时/计数器工作。即此时定时器的启动条件,加上了INT0/1引脚为高电平这一条件。

3、C/T :定时/计数模式选择位。C/T =0为定时模式;C/T =1为计数模式。(T上有个非)

4、M1M0:工作方式设置位。定时/计数器有四种工作方式。(8位自动重装,指的是将初始化值装在高位,然后赋值给低位。低位进行计数或计溢出后,高位的数重新赋值给低位,重复)

图三

 

控制寄存器TCON

制定时/计数器的启动和中断申请。其格式如下:

图四

TF1(TCON.7):T1溢出中断请求标志位。T1计数溢出时由硬件自动置TF1为1。CPU响应中断后TF1由硬件自动清0。T1工作时,CPU可随时查询TF1的状态。所以,TF1可用作查询测试的标志。TF1也可以用软件置1或清0,同硬件置1或清0的效果一样。

TR1(TCON.6):T1运行控制位。TR1置1时,T1开始工作;TR1置0时,T1停止工作。TR1由软件置1或清0。所以,用软件可控制定时/计数器的启动与停止。

TF0(TCON.5):T0溢出中断请求标志位,其功能与TF1类同。

TR0(TCON.4):T0运行控制位,其功能与TR1类同。

 

定时/计数器的工作方式

这里仅仅提及方式一(我目前只用过这两种)

方式1的计数位数是16位,由TL0作为低8位,TH0作为高8位,组成了16位加1计数器 。

        计数个数与计数初值的关系为:X=216-N

图五

 

 

 

定时器的使用

对TMOD赋值,以确定T0和T1的工作方式。

计算初值,并将其写入TH0、TL0或TH1、TL1。

中断方式时,则对EA,ET0/1赋值,开放定时器中断。

使TR0或TR1置位,启动定时/计数器定时或计数。(这个最后设置,因为一旦设置,计时或计数就开始)

 

代码:

定时器0

#include<reg52.h>

sbit led=P2^0;//LED接在P2^0引脚上

int i=0;

void Timer0Init()
{
	TMOD|=0X01;//这样写是非常好的,仅仅设置定时器0,不影响定时器1的工作状态。在多文件编程中,这一点能更好的体现
	TH0=(65536-1000)/256;
   	TL0=(65536-1000)%256;
	//TH0=0xFC;//晶振频率为12M
	//TL0=0X18;
	TH0=0xFC;//我板子上晶振频率为11.05926M
	TL0=0X66;//这差别很小的
	ET0=1;//定时器0的中断允许
	EA=1;//打开总终端
	TR0=1;
}

void main(void)
{
	Timer0Init();
	while(1);			
}

void Timer0() interrupt 1//尽量减少中断中的操作,提高精度
{
   i++;
   TH0=0xFC;//重新赋初值
   TL0=0X66;
   if(i==1000)
   {
   		led=~led;
		i=0;
   }
}


1、TMOD|=0X01;//这样写是非常好的,仅仅设置定时器0,不影响定时器1的工作状态。在多文件编程中,这一点能更好的体现

2、尽量减少定时中断中的操作,提高精度。

3、这个定时中断是1ms,中断中的操作应该是不到1000的1/10,所以这个中断在ms级别中,可能还是相对准确的。可以用于以后的实验。但是在s级别误差逐渐变大,下面是我简单测量的方法和结果。

测量:

在灯灭下的瞬间,手机开始计时。如果要测10s,在第五次灯灭的时候结束计时。(因为点亮和熄灭各一秒)

下面用上述方法测量了10s,30s,50,70s,各三次。结果如下

1ms延时的测量
  10s 30s 50s 70s
第一次测量(s) 09.77 28.08 46.48 65.98
第二次测量(s) 09.38 28.15 46.44 65.88
第三次测量(s) 09.46 28.08 47.18 65.53
实际平均时间(s) 09.536 28.103 46.700 65.797

 上表可见,误差越来越大。当然也可能我的晶振不是11.0592MHz,上面没标注,问的淘宝客服。

好奇万年历是怎么做出来的,回头好好查查。

 

定时器1(普中科技的代码)

/**************************************************************************************
*		              定时器1实验												  *
实现现象:下载程序后数码管最后一位间隔一秒循环显示0-F。使用单片机内部定时器可以实现准确延时。
注意事项:如果不想让点阵模块显示,可以将74HC595模块上的JP595短接片拔掉。																				  
***************************************************************************************/

#include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器

typedef unsigned int u16;	  //对数据类型进行声明定义
typedef unsigned char u8;

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
					0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值
u8 n=0;
/*******************************************************************************
* 函 数 名         : Timer1Init
* 函数功能		   : 定时器1初始化
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void Timer1Init()
{
	TMOD|=0X10;//选择为定时器1模式,工作方式1,仅用TR1打开启动。

	TH1=0XFC;	//给定时器赋初值,定时1ms
	TL1=0X18;	
	ET1=1;//打开定时器1中断允许
	EA=1;//打开总中断
	TR1=1;//打开定时器			
}

/*******************************************************************************
* 函 数 名       : main
* 函数功能		 : 主函数
* 输    入       : 无
* 输    出    	 : 无
*******************************************************************************/
void main()
{	
	LSA=0;
	LSB=0;
	LSC=0;
	Timer1Init();  //定时器1初始化
	while(1);		
}

/*******************************************************************************
* 函 数 名         : void Timer1() interrupt 3
* 函数功能		   : 定时器0中断函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void Timer1() interrupt 3
{
	static u16 i;
	TH1=0XFC;	//给定时器赋初值,定时1ms
	TL1=0X18;
	i++;
	if(i==1000)
	{
		i=0;
		P0=smgduan[n++];
		if(n==16)n=0;	
	}	
}

在定时中断函数中,为了不断定时,进行了重装载(重新赋值)。当溢出的时候ET0置一,中断标志。

TR0=1,为打开计时器;ET0=1是打开定时器1中断允许。我咋感觉这两个有点重复呢?

 

补充:

来自百度百科:晶体振荡器

        石英晶体振荡器是高精度和高稳定度的振荡器,被广泛应用于彩电、计算机、遥控器等各类振荡电路中,以及通信系统中用于频率发生器、为数据处理设备产生时钟信号和为特定系统提供基准信号。

        石英晶体振荡器是利用石英晶体(二氧化硅的结晶体)的压电效应制成的一种谐振器件,它的基本构成大致是:从一块石英晶体上按一定方位角切下薄片(简称为晶片,它可以是正方形、矩形或圆形等),在它的两个对应面上涂敷银层作为电极,在每个电极上各焊一根引线接到管脚上,再加上封装外壳就构成了石英晶体谐振器,简称为石英晶体或晶体、晶振。其产品一般用金属外壳封装,也有用玻璃壳、陶瓷或塑料封装的

 

 

 

 

 

 

 

 

 

 

 

2019-04-20 12:57:48 qq_42842786 阅读数 253
  • 单片机控制第一个外设-LED灯-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    3998 人正在学习 去看看 朱有鹏

单片机的中断

由于本人水平有限,文章中难免出现错别字以及错误,欢迎大家私信批评指正
这个专栏,将直接从52系列单片机的中断开始连载;对于中断以前的基础内容都很简单,一般看原理图就能解决,主要由于我最近看中断一遍还是觉得有些逻辑混乱,所以直接从中断开始。

中断概念

刚在写博客的时候口渴,我起身起身去喝水,喝水过程中不小心打翻了杯子弄湿了地面,又不得不去拖地,其实这就是生活中常见的中断,我本来在写博客,这是我的主程序,口渴便是一个中断源,它提示我应该喝水,当我停下写博客在喝水的时候打翻了杯子 ,其实这又是一个中断源向我的大脑CPU申请中断去拖地,这实际上是一个中断的二级嵌套。对于中断的逻辑关系就是这么简单,实际上中断函数也不难,比较难的理解各个中断源的工作原理。
中断是为使单片机具有对外部或内部随即发生的事件实时处理而设置的,中断功能的存在很大程度上提高了单片机处理外部或内部事件的能力;对于单片机来讲中断指的是:CPU在处理事件A时,发生了另一件事件B,请求CPU去处理(中断发生);CPU暂停了当前工作(中断响应)转去处理事件B(中断服务);待CPU处理完事件B后,再回到中断发生的地方继续处理事件A(中断返回)。
图片源自GTX老师的书

其中引起CPU中断的根源是中断源
涉及中断还有一个重要的概念:中断优先级,即同一时刻发生了两个中断,单片机先执行哪个终端你取决于单片机内部的一个特殊功能寄存器——中断优先级寄存器的设置情况,其决定了执行中断的顺序。中断的开启与关闭、设置启用哪一个中断都是由单片机内部的特殊功能寄存器决定的
上面讲到的中断优先级寄存器,通过设置它我们可以选择当两个中断同时出现先执行哪一个中断程序,若没有人为操作优先级寄存器,单片机会按照默认优先级自动处理。其中T2为52系列单片机特有的
其中T2为52系列单片机特有的

中断允许寄存器IE

简单来说IE是个开关,用来设定中断源的打开和关闭,只有允许打开的时候才有可能引起中断。可进行位寻址,即对每一位进行单独操作
在这里插入图片描述

中断优先级寄存器IP

IP用来设定个中断源属于两级中断中的哪一级。同理可进行位寻址
(懒得码字,图片说话)
在这里插入图片描述

本篇主要讲了中断的逻辑概念以及IE和IP寄存器的信息,并没有涉及任何操作,下一篇我们将开始讲单片机定时器的中断

51单片机——中断

阅读数 807

没有更多推荐了,返回首页