单片机汇编程序中断定时

已知某51单片机系统的晶振频率为12MHz,请编写汇编程序,使用定时器T0,采用中断的方式实现20毫秒定时。其中,定时器T0的中断入口地址为000BH。

求出初值是45536,TL0=0E0H,TH0=0B1H,之后汇编程序不太确定

  • 这篇博客: 【51单片机 】定时器的初始值计算 详解中的 定时器T0工作在方式一,晶振频率为11.0592MHZ,需要定时时间0.5s 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 那么计算思路是这样的:
    1. 首先要知道1s=1000ms,1ms=1000us。
    2. 由公式可得:(216-0)× 12 ÷ 11.0592=71ms,定时时间最大只能算到71ms,而0.5s=500ms,距离需要的时间还差429ms,剩下的怎么办?
    3. 所以,这个时候我们需要退一步计算,算个5ms再循环个100次,这样就可以得到5ms*100=500ms(0.5s)。

    5ms的定时时间先换算成us单位就是5000us
    公式:(216-X)× 12 ÷ 11.0592=5000(us)
    得 X=60928
    把十进制60928转换为16进制=0xee00,分配高8位TH=0xee,低8位TL=0x00,
    初始值这样就算好了。

    转换进制不熟练的同学可以用win10自带的计算器进行转换。

    #include<reg51.h>
       char i=100;    //用来循环100次,5ms*100=500ms,500ms=0.5s
       
      void Timer0Init(void)	 //5毫秒@11.0592MHz 定时器T0 子程序
    {
    	TMOD &= 0xF0;  //设置定时器模式
    	TMOD |= 0x01;  //设置定时器模式
    	
    	TL0 = 0x00;	   //低8位
    	TH0 = 0xEE;	   //高8位
    	    //高8位与低8位共同组成初始值
    	
    	TF0 = 0;	   //清除TF0标志
    	TR0 = 1;       //定时器0开始计时
    	ET0 = 1;      //允许定时器T0开启中断
    	EA = 1;		  //开启总中断
    }
    
      void main()			//主程序
    {
            P2=0Xff;         //led初始化  
            Timer0Init();	//调用定时器的初始化子程序
    		while(1);      //等待定时器进入中断
    }
    
      void T0_timer0() interrupt 1       //定时器0 进入中断程序
    {
    		TH0=0xEE;   //这里需要重新赋初始值,保证每次进入中断函数都是5ms
    		TL0=0x00;
         	i--;           //i=100开始循环自减
    	      if(i<=0)    //判断(i从100减到0的时候就执行下面程序)
    		{
    			i=100;   //进来就重置循环次数,保证出去可以重新开始计算
    		   P2=~P2;    //取反,i从100减到0刚好是0.5s,取反亮一次
    		}	     //亮完后i已经等于100,不满足if判断条件,重新开始定时
    }
    //end 
    

    当然,有更方便的计算方式,在烧录软件找到定时计算器,选好定时器、工作方式、时钟以及定时长度(初始值),就能自动得到初始值了
    在这里插入图片描述

    上图四个疑问
    1、

    定时长度:
    看上面公式,我们用到定时器方式一是16位,既216,最大只能算出71ms,我们定时单位是ms的话超出71是没有办法计算的,所以这就是为什么不直接输入500ms的原因。
    我们可以输入5ms算出初始值然后循环100次再运行
    也可以输入50ms得到初始值循环10次再运行,结果都是一样的。

    2、

    选择定时器:
    定时器0和定时器1都可以选择,只是有优先级设置——通过IP寄存器设定,但只有高和低两种,同等优先级时,先响应定时器0。
    只使用一个定时器时,随便选一个就行。

    3、

    定时器模式:
    1.模式分8、13、16位(具体看下表 定时器模式表),因为我们选择了方式一(216),所以在模式中选择16位。
    2.自动重载与无自动重载区别:无自动重载(下表方式0和方式1)特点是计数溢出后计数器全为0,在使用循环定时/计数时会影响精度。自动重载就是为了解决该问题而设计的。

    注意:89c52是没有 16位重载 的,选择的时候具体要看单片机手册,这里选 16位 即可。

    4、

    定时器时钟:
    标准8051单片机为12T。
    STC12系列有1T和12T,具体看芯片手册,这里不多赘述。

    另外,软件里面的程序也是可以直接使用的,只是要稍微修改一下。
    删除不用的(AURX)
    加入开启条件:
    ET0 = 1; //允许定时器T0中断。选择定时器1时改为ET1=1;
    EA = 1; //开启总中断
    (具体可看上面的代码)
    在这里插入图片描述

    用软件里的定时功能计算减去了我们自己写和计算的步骤,方便快捷准确,没用过的可以试一下哦。
    定时器模式表:
    定时器方式
    选择相应的方式:
    方式0 :213,(不常用)
    方式1 :216 ,(最常用)
    方式2 :28,(常用)
    方式3 :现在基本上没人用了,稍微了解下即可