资源描述
电子信息工程学系实验报告
成 绩:
课程名称:单片机原理与接口
指导教师(签名):
实验项目名称:实验5 51定时器实验 实验时间:2011-12-15
班级:电信091 姓名:谢亮东 学号:910706140
实 验 目 的:
熟悉keil仿真软件、伟福仿真器的使用和C51定时程序的编写。了解51单片机中定时、计数的概念,熟悉51单片机内部定时/计数器的结构与工作原理。掌握中断方式处理定时/计数的工作过程。
实 验 环 境:
Windows 7 旗舰版PC机
Keil C51单片机仿真调试软件,Proteus 7.5 SP3。
实 验 原 理:
51型单片机有两个十六位定时/计数器T0、T1,有四种工作方式,由特殊功能寄存器中的定时计数方式控制寄存器TMOD控制:
表1 方式控制寄存器
D7
D6
D5
D4
D3
D2
D1
D0
GATE
C/T
M1
M0
GATE
C/T
M1
M0
1、M0的状态决定定时器的工作方式,定时和外部事件计数方式选择位C/T,GATE与TR0、TR1配合决定定时/计数器的启停。
加法计数寄存器TH0、TH1 (高八位)TL0、TL1(低八位);
定时/计数到标志TF0、TF1(中断控制寄存器TCON);
定时/计数器启停控制位TR0、TR1(TCON);
定时/计数器中断允许位ET0、ET1(中断允许寄存IE);
定时/计数器中断优先级控制位PT0、PT1(中断优IP)。
MCS-51单片机定时计数器的工作原理如下图1所示,
图1 定时器结构
单片机内部的定时计数模块,在定时时,对工作频率的12分频进行计数,先记入TL后记入TH,直到溢出为止,根据TL、TH内的初值不同可以定出不同的时间;在计数工作方式时,对T0(T1)引脚的输入脉冲进行计数,将计数值记入TL、TH。当定时/计数溢出时,会引起中断。
计数初值与定时时间的关系为:T = 12×(T_all – a)/fosc定时间隔为T,计数初值为a。所以有计数初值a =–T×fosc/12,THx = a / 256,TLx = a % 256。定时器均有一个最大定时时间,对于长时间的定时需要,可以将定时间隔为固定的较小时间,通过另设一全局变量ah1用于计数,累加固定的较小定时时间来进行。
使用MCS-51单片机的定时/计数器的步骤是:
设定TMOD,确定:工作状态(用作定时器/计数器)、工作方式、控制方式。
2.设置合适的计数初值,以产生期望的定时间隔。由于定时/计数器在方式0、方式1和方式2时的最大计数间隔取决于使用的晶振频率fosc,如下表所示,当需要的定时间隔较大时,要采用适当的方法,即将定时间隔分段处理。
3.确定定时/计数器工作于查询方式还是中断方式,若工作于中断方式,则在初始化时开放定时/计数器的中断及总中断:
实 验 内 容 及 过 程:
绘制电路图,根据实验的目的进行Proteus仿真制图,结果显示在图2。
图2 所需电路图
二、编写程序代码
1、八位数码管第几位0~9的计数实验,根据题意在keil中编写如下代码:
第 4 页 共 4 页
#include<reg51.h>
unsigned char tab[]={0x3f,0x06,0x5b,
0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
int i,b,a;
main()
{TMOD=0x01;
a=-50*0.001*12000000/12;
TH0=a/256;
TL0=a%256;
P2=0xfb;
P0=tab[i];
EA=1;
ET0=1;
TR0=1;
while(1);
}
void t00() interrupt 1
{TH0=a/256;
TL0=a%256;
b++;
if(b==20)
{i++;
b=0;
if(i==10)
{i=0;
}
P0=tab[i];
}
}
编译之后就可以下载到proteus的仿真图中就可以看到结果了。
2、第三、四位0~59的计数实验,在keil中新建工程并编写如下程序:
#include<reg51.h>
unsigned char tab[]={0x3f,0x06,0x5b,
0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
int i,b,a;
void delay(int);
main()
{TMOD=0x01;
a=-50*0.001*12000000/12;
TH0=a/256;
TL0=a%256;
EA=1;
ET0=1;
TR0=1;
while(1)
{P2=0xfb;
P0=tab[i%10];
delay(10);
P2=0xfd;
P0=tab[i/10];
delay(10);
}
}
void t00() interrupt 1
{TH0=a/256;
TL0=a%256;
b++;
if(b==20)
{i++;
b=0;
if(i==60)
{i=0;
}
}
}
void delay(int z)
{int i,j;
for(j=z;j>0;j--)
for(i=110;i>0;i--);
}
至此,代码输入完毕,同样的道理根据计数原理可以进行数码管的以秒为单位的计数。
3、在第一步基础上 加拨码开关实现暂停,编写程序。运行测试无误,生成hex格式文件。下面为主要部分程序内容:
#include<reg51.h>
unsigned char tab[]={0x3f,0x06,0x5b,
0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
sbit k=P3^7;
int i,b,a;
void delay(int);
main()
{TMOD=0x01;
a=-50*0.001*12000000/12;
TH0=a/256;
TL0=a%256;
EA=1;
ET0=1;
TR0=1;
EX0=1;
IT0=1;
while(1)
{P2=0xfb;
P0=tab[i%10];
delay(10);
P2=0xfd;
P0=tab[i/10];
delay(10);
}
}
void t00() interrupt 1
{TH0=a/256;
TL0=a%256;
b++;
if(b==20)
{i++;
b=0;
if(i==60)
{i=0;
}
}
}
void delay(int z)
{int i,j;
for(j=z;j>0;j--)
for(i=110;i>0;i--);
}
void kaiguan() interrupt 0
{TR0=!TR0;
}
实 验 结 果 及 分 析:
1、八位数码管的第三位显示0~9的实验,编译调试后可看到如下结果如图3。
数码管的第三位从0~9地计数,每秒钟增加
一个数也就是计时了,这样反复循环。
2在个位的计数基础上增加十位,就这样可以
计时99秒了,不过本次试验只针对60秒进制的,
因此,在整个过程中,只要分别对个位以及十位
分别赋值即可。由于是两位数在数码管的额动态
显示中一定要把握好延时的时间,多了或者是少
都不行。
3、这次加了个开关,所以我就加了个外部中断0
INT0.只要开关按钮一按下,定时器的开关TR0就会
一次,由此可以暂停计时。下面分别为按钮被按下的
前后两个状态: 图3 个位计数方式 图4 60秒计数方式
图5 按键两次按下前后改变的计数结果
没按下之前显示“13”按下第一次按钮后收到一个中断请求暂停,把按键放开来,之后再第二次按下按钮,CPU收到第二次中断请求,因此有改变TR0的值,又启动计数,因此编程了14,依次循环下去。
实 验 心 得:
本实验通过使用单片机定时器。了解并熟悉51单片机定时器的概念,定时器的工作原理。在学习中断以及计数的同时也复习了数码管的额动态显示原理,学习怎么编写51单片机中里的定时时间的设置为以后利用中断编写程序打下了良好的基础。
展开阅读全文