欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

基于Proteus与keil联合仿真的51单片机学习记录(五)(使用T/C的工作方式0定时)

程序员文章站 2024-01-10 21:51:16
...

(一)、设计要求

  用T0的工作方式0来设计一个控制灯闪烁。定时器0每5ms产生一个中断,每秒让灯闪烁一次;另外,用外部中断“开始”、“停止”按钮控制定时器T0的开始和关闭。

(二)、程序设计

  首先是定时器初值的问题,定时器T0的工作方式0是13位定时器,也就是最大计数值是8 191,再计数加1后,溢出,共8 192个数。我们用12MHz的晶振,每一个机器周期计数器计数加1一次,而一个机器周期是12个时钟周期,也就是每微秒定时器计数加1。要使其每间隔5ms产生一个中断,就是计数器计数5 000产生一个中断,因而初始值是8 192-5000=3 192。而TL0是低5位有效最大值0x1F即31),也就是每32个计数TH0进位一次。这样就可以计算TH0、TL0的初始值:TH0=3192/32=99=0x63;TL0=3 192%32=24=0x18(注:TL0的值是3 192对32取余)。

						/*****************************************************************************
******************************************************************************************
***
						* 文件名:main.c
						* 说  明:使用T/C的工作方式0定时
						******************************************************************************
******************************************************************************************
**/
						#include "reg51.h"
						#include "main.h"
						#include "delay.h"
						sbit LED1 = P2^0;
						uchar g_ucNum;

						/*****************************************************************************
******************************************************************************************
***
						* 函数名:Int0中断函数,0是Int0的中断号
						* 参  数:空
						* 返回值:无
						******************************************************************************
******************************************************************************************
***/
						void int0_inter() interrupt 0
						{
							g_ucNum = 0;
							TL0 = 0x18;      //定时器赋初值,保证每一次开启中断号后都从此初值开始计数         
							TH0 = 0x63;
							TR0 = 1;         //打开定时器中断(由于默认gate为0,此时的定时器中断由TR控制)
						}
						/*****************************************************************************
******************************************************************************************
***
						* 函数名:Int1中断函数,2是Int1的中断号
						* 参  数:空
						* 返回值:无
						******************************************************************************
******************************************************************************************
***/
						void int1_inter() interrupt 2
						{
              TR0 =0;           //关闭定时器中断
						}
            /*****************************************************************************
******************************************************************************************
***
						* 函数名:定时器T0的中断函数
						* 参  数:空
						* 返回值:无
						******************************************************************************
******************************************************************************************
***/
						void timer0_inter() interrupt 1
						{
              g_ucNum++;        //在每次执行中断时对g_ucNum数值进行累加
							TL0 = 0x18;       //重新对定时器赋初值
							TH0 = 0x63;
							
						}
												
						/*****************************************************************************
******************************************************************************************
***
						* 函数名:主函数,初始化外部中断、定时器中断
						* 参  数:无
						* 返回值:无
						******************************************************************************
******************************************************************************************
***/
						void main (void)
						{
							g_ucNum = 0;             
							P2 = 0xFF;
							P3 = 0xFF;
							IT0 = 1;            //下降沿触发模式  或可以写成 TCON |= 0x05; 
							IT1 = 1;
							EX0 = 1;            //打开Int0外部中断
							EX1 = 1;            //

							TMOD = 0;           //定时器模式,工作方式0
							TL0 = 0x18;         
							TH0 = 0x63;
							ET0 = 1;            //定时器溢出中断允许
							EA = 1;             //打开全局中断
							while(1)
							{
								if(g_ucNum >= 200)
								{
									g_ucNum = 0;
									LED1 = ~LED1;
								}
							}
						}

  在主程序中完成了定时器的初始设置工作:TMOD=0,设定定时器的工作模式为定时器模式而非计数器模式,工作方式为方式0即13位定时器;TH0、TL0设定定时器的初始值;ET0=1使能定时器0的中断功能;然后通过EA=1使能全局中断,这样就可以进入外部中断和定时器中断了。

(三)、硬件设计

基于Proteus与keil联合仿真的51单片机学习记录(五)(使用T/C的工作方式0定时)

(四)、知识补充

一、可位寻址与不可位寻址

  位寻址指的是这个寄存器中各位值可以直接调用

如:可位寻址的IE中有八位EA - ET2 ES ET1 EX1 ET0 EX0可以直接用ET2=1来操作;

不可位寻址的TMOD只能用TMOD=0x00来控制其中的各位。

不可以未开控制其中的某一位,不可以单独赋值给某一位。

参考此篇文章

二、几个专用寄存器

1.计数寄存器TH0、TL0、TH1、TL1

  TH0、TL0是两个8位寄存器,正是由这两个寄存器组成了T/C0的16位定时/计数功能。同样,TH1、TL1是T/C1的两个8位计数寄存器。也就是说在我们将定时器中断打开的前提下,当这两个寄存器计数溢出时,就会发生定时/计数器中断。

2.T/C工作方式寄存器TMOD

基于Proteus与keil联合仿真的51单片机学习记录(五)(使用T/C的工作方式0定时)
  从表中可以看出,TMOD的高4位是用来控制T/C1的,低4位是用来控制T/C0的,我们以低4位来说明每个位的用途。
T0_GATE:门控制位。该位设置为1,T/C0的启动与停止由TCON寄存器中TR0和外部中断引脚INT0上的电平状态共同控制;该位设为0,T/C0的启动与停止仅受TCON寄存器中TR0的控制。通常会使用后一种方式,即设定该位为0(系统复位时,该位默认为0)。

T0_CT:定时/计数器工作模式选择位。该位设置为1,T/C0为计数器工作模式;该位设为0,T/C0为定时器工作模式。

T0_M0、T0_M1:工作方式选择位。每个T/C都有4种工作方式,它们由M1M0来设定,具体见下表。
基于Proteus与keil联合仿真的51单片机学习记录(五)(使用T/C的工作方式0定时)

3.各工作方式的应用

  注意:定时器0的工作模式3是分为两个8位的定时器,需要占用标志位TF1、TR1,这时定时器1不能使用中断,而且定时/计数器的工作方式3只对定时器0有效,当定时器1设定为工作方式3时,其将停止计数。