单 片 机 实 验 报 告
一、实验目的
实验五 定时/计数器实验
1.学习8051内部定时/计数器的工作原理及编程方法; 2.掌握定时/计数器外扩中断的方法。
二、实验原理
8051单片机有2个16位的定时/计数器:定时器0(T0)和定时器1(T1)。它们都有定时器或事件计数的功能,可用于定时控制、延时、对外部事件计数和检测等场合。
T0由2个特殊功能寄存器TH0和TL0构成,T1则由TH1和TL1构成。作计数器时,通过引脚T0(P3.4)和T1(P3.5)对外部脉冲信号计数,当输入脉冲信号从1到0的负跳变时,计数器就自动加1。计数的最高频率一般为振荡频率的1/24。
定时/计数器的结构:
定时/计数器的实质是加1计数器(16位),由高8位和低8位两个寄存器组成。TMOD 是定时/计数器的工作方式寄存器,确定工作方式和功能;TCON 是控制寄存器,控制T0、T1的启动和停止及设置溢出标志。
外部中断相关位
T1方式
计数器初值的计算:
设计数器的最大计数值为M(根据不同工作方式,M 可以是213、216或
28) ,则计算初值X 的公式如下:
X=M-要求的计数值(十六进制数)
定时器初值的计算:
在定时器模式下,计数器由单片机主脉冲fosc 经12分频后计数。因此,定时器定时初值计算公式:
X=M-(要求的定时值)/(12/fosc)
80C51单片机定时/计数器的工作由两个特殊功能寄存器控制。TMOD 用于设置其工作方式;TCON 用于控制其启动和中断申请。 工作方式寄存器TMOD :
工作方式寄存器TMOD 用于设置定时/计数器的工作方式,低四 位用于T0,高四位用于T1。其格式如下:
GATE :门控位。GATE =0时,只要用软件使TCON 中的TR0或TR1为1,就可以启动定时/计数器工作;GATA =1时,要用软件使TR0或TR1为1,同时外部中断引脚或也为高电平时,才能启动定时/计数器工作。即此时定时器的启动条件,加上了或引脚为高电平这一条件。
M1M0:工作方式设置位。定时/计数器有四种工作方式,由M1M0进行设置。
控制寄存器TCON
TCON 的低4位用于控制外部中断, 已在前面介绍。TCON 的高4位用于控制定时/计数器的启动和中断申请。其格式如下:
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类同。
三、实验电路图
第一、三部分电路图:
第二部分电路图(加入一个脉冲计数的开关):
四、实验设备
微型计算机、单片机仿真器、实验仪、示波器(各一台) ; 实验连线(若干) 。
五、实验内容
*由于汇编语言程序中已经做了相应的注释,C 语言的编程原理与之相同不再做重复注释,请见谅。
实验例程
使8个发光二极管点亮,点亮时间间隔一秒,要求用定时器中断方 式产生延时。
汇编语言代码: ORG 0000H AJMP START ORG 000BH AJMP T0INT ; 定时器T0中断入口 ORG 0030H
START:
MOV SP ,#60H
MOV TMOD,#01H
MOV TL0,#0B0H ; 晶振为12兆赫资时,50ms 溢出一次 MOV TH0,#3CH SETB ET0 SETB EA
SETB TR0 ; 启动定时器 MOV A,#0FEH
MOV R1,#20 ; 定时器溢出20次为1秒 MOV P1,A LOOP:
CJNE R1,#0,LOOP MOV R1,#20 DEC A
MOV P1,A ; 发光二极管低电平点亮,因此为记数加显示 AJMP LOOP T0INT:
MOV TH0,#3CH ; 定时器重新初始化 MOV TL0,#0B0H DEC R1
RETI ; 中断返回 END
C 语言程序代码: #include #define TIMEINT 0x01 #define TIMEH 0x3C #define TIMEL 0xB0
extern unsigned char t_count;
void timer0(void) interrupt 1 using 1 {
TH0=TIMEH; TL0=TIMEL; t_count--; }
main() {
unsigned char DisNum; DisNum=0xFE; t_count=20;
TMOD=TIMEINT; TH0=TIMEH; TL0=TIMEL; ET0=1; EA=1; TR0=1; while(1) {
while(t_count!=0) {
P1=DisNum; }
t_count=20; DisNum--; } }
将定时器T0设置成定时方式,由P1.0输出50%占空比的500Hz 方波。 汇编语言代码: ORG 0000H AJMP START ORG 000BH AJMP T0INT ORG 0030H START:
MOV SP ,#60H
MOV TMOD,#01H MOV TL0,#18H MOV TH0,#0FCH
SETB ET0 ; 开中断 SETB EA SETB TR0 AJMP $ ; 等待中断 T0INT:
CPL P1.0
MOV TL0,#18H ; 初始化T0定时器 MOV TH0,#0FCH RETI END
C 语言程序代码: #include #define TIMEINT 0x01 #define TIMEH 0x00 #define TIMEL 0x00
extern unsigned char t_count,flag; void timer0(void) interrupt 1 using 1 {
TH0=TIMEH; TL0=TIMEL; flag=flag^1; }
main() {
flag=1;
TMOD=TIMEINT; TH0=TIMEH; TL0=TIMEL; ET0=1; EA=1; TR0=1; while(1) {
if(flag==0) {
P1=0xff; }
if(flag==1) {
P1=0xfe; }
continue; } }
将定时器T0设置成对外部脉冲计数方式,T0引脚每来一次外部脉冲,记数加
1,计数结果以二进制格式显示在8个发光二极管上。 汇编语言代码: ORG 0000H AJMP S TART ORG 000BH AJMP T 0INT ORG 0030H START:
MOV SP ,#60H
MOV TMOD,#0DH ; 设置为计数状态
MOV TL0,#0FFH ; 设置计数值为1时就溢出 MOV TH0,#0FFH
SETB ET0 ; 开中断 SETB EA
SETB TR0 ; 启动定时器 MOV A,#0FFH MOV R1,#1 ; 中断处理标志 MOV P1,A LOOP:
CJNE R1,#0,LOOP ; 等待中断 MOV R1,#1 DEC A
MOV P1,A ; 计数显示 AJMP LOOP T0INT:
MOV TH0,#0FFH MOV TL0,#0FFH DEC R1 RETI END
C 语言程序代码: #include #define TIMEINT 0x0D #define TIMEH 0xFF #define TIMEL 0xFF extern unsigned char flag;
main() {
unsigned char DisNum; DisNum=0xFF; TMOD=TIMEINT; TH0=TIMEH; TL0=TIMEL; ET0=1; EA=1; TR0=1; flag=1;
P1=DisNum; while(1) {
if(flag==0) {
flag=1; DisNum--; P1=DisNum; }
continue; } }
void timer0(void) interrupt 1 using 1 {
TH0=TIMEH; TL0=TIMEL; flag=0;
}
使用T0、T1两个定时器分别控制从P1.0输出波形的高、低电平的宽度。 汇编语言代码: ORG 0000H AJMP START ORG 000BH AJMP T0INT ORG 001BH AJMP T1INT ORG 0030H
START: MOV MOV MOV MOV MOV MOV SETB SETB SETB MOV SETB LOOP1: CJNE MOV AJMP SECOND: MOV RETURN: AJMP T0INT: CLR MOV MOV MOV SETB RETI T1INT: CLR MOV MOV MOV SETB RETI END
SP ,#60H
TMOD,#11H TL0,#00H TH0,#00H TL1,#00H TH1,#00H ET0 ET1 EA R1,#0 TR0
; 定时/计数器设置
; 两个定时器的初值设置
; 开中断T0、T1 ;R1作为标志位使用 ; 若标志位等于1则跳转
R1,#1,SECOND P1,#0FFH RETURN P1,#0FEH LOOP1 TR0 TL0,#00H TH0,#00H R1,#01H TR1 TR1 TL1,#00H TH1,#00H R1,#00H TR0
; 循环执行
;T0定时时间到,关闭 ;T0定时器设置初值 ; 标志位置1 ;T1定时开启
;T1定时时间到,关闭 ;T1定时器设置初值 ; 标志位置0 ;T0定时开启 ; 中断返回
C 语言程序代码: #include #define TIMEINT 0x11 #define TIMEH 0x00 #define TIMEL 0x00 extern unsigned char flag; main() {
TMOD=TIMEINT; TH0=TIMEH; TL0=TIMEL; ET0=1;
TH1=TIMEH; TL1=TIMEL; ET1=1; EA=1; flag=1; TR0=1; while(1) {
if(flag==0) {
P1=0xff; }
if(flag==1) {
P1=0xfe; }
continue; } }
void timer0(void) interrupt 1 using 1 {
TR0=0;
TH0=TIMEH; TL0=TIMEL; flag=1; TR1=1; }
void timer1(void) interrupt 3 using 1 {
TR1=0;
TH0=TIMEH; TL0=TIMEL; flag=0; TR0=1; }
六、实验小结
通过本次实验,我对单片机的定时/计数功能有了一定的了解,熟悉了定时/计数器的设置、控制和最基本的应用,初步获悉了定时/计数器的内部结构,再结合上一次实验对终端的了解,二者配合,编写一些简单的程序,完成诸如产生固定频率的方波、脉冲计数和占空比调整的功能,巩固对中断和定时/计数的知识,为下一步的学习打下坚实的基础。
以上程序均已经过实验仪现象验证,如有什么不足,请老师指出并告知,谢谢。
4.1
单 片 机 实 验 报 告
一、实验目的
实验五 定时/计数器实验
1.学习8051内部定时/计数器的工作原理及编程方法; 2.掌握定时/计数器外扩中断的方法。
二、实验原理
8051单片机有2个16位的定时/计数器:定时器0(T0)和定时器1(T1)。它们都有定时器或事件计数的功能,可用于定时控制、延时、对外部事件计数和检测等场合。
T0由2个特殊功能寄存器TH0和TL0构成,T1则由TH1和TL1构成。作计数器时,通过引脚T0(P3.4)和T1(P3.5)对外部脉冲信号计数,当输入脉冲信号从1到0的负跳变时,计数器就自动加1。计数的最高频率一般为振荡频率的1/24。
定时/计数器的结构:
定时/计数器的实质是加1计数器(16位),由高8位和低8位两个寄存器组成。TMOD 是定时/计数器的工作方式寄存器,确定工作方式和功能;TCON 是控制寄存器,控制T0、T1的启动和停止及设置溢出标志。
外部中断相关位
T1方式
计数器初值的计算:
设计数器的最大计数值为M(根据不同工作方式,M 可以是213、216或
28) ,则计算初值X 的公式如下:
X=M-要求的计数值(十六进制数)
定时器初值的计算:
在定时器模式下,计数器由单片机主脉冲fosc 经12分频后计数。因此,定时器定时初值计算公式:
X=M-(要求的定时值)/(12/fosc)
80C51单片机定时/计数器的工作由两个特殊功能寄存器控制。TMOD 用于设置其工作方式;TCON 用于控制其启动和中断申请。 工作方式寄存器TMOD :
工作方式寄存器TMOD 用于设置定时/计数器的工作方式,低四 位用于T0,高四位用于T1。其格式如下:
GATE :门控位。GATE =0时,只要用软件使TCON 中的TR0或TR1为1,就可以启动定时/计数器工作;GATA =1时,要用软件使TR0或TR1为1,同时外部中断引脚或也为高电平时,才能启动定时/计数器工作。即此时定时器的启动条件,加上了或引脚为高电平这一条件。
M1M0:工作方式设置位。定时/计数器有四种工作方式,由M1M0进行设置。
控制寄存器TCON
TCON 的低4位用于控制外部中断, 已在前面介绍。TCON 的高4位用于控制定时/计数器的启动和中断申请。其格式如下:
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类同。
三、实验电路图
第一、三部分电路图:
第二部分电路图(加入一个脉冲计数的开关):
四、实验设备
微型计算机、单片机仿真器、实验仪、示波器(各一台) ; 实验连线(若干) 。
五、实验内容
*由于汇编语言程序中已经做了相应的注释,C 语言的编程原理与之相同不再做重复注释,请见谅。
实验例程
使8个发光二极管点亮,点亮时间间隔一秒,要求用定时器中断方 式产生延时。
汇编语言代码: ORG 0000H AJMP START ORG 000BH AJMP T0INT ; 定时器T0中断入口 ORG 0030H
START:
MOV SP ,#60H
MOV TMOD,#01H
MOV TL0,#0B0H ; 晶振为12兆赫资时,50ms 溢出一次 MOV TH0,#3CH SETB ET0 SETB EA
SETB TR0 ; 启动定时器 MOV A,#0FEH
MOV R1,#20 ; 定时器溢出20次为1秒 MOV P1,A LOOP:
CJNE R1,#0,LOOP MOV R1,#20 DEC A
MOV P1,A ; 发光二极管低电平点亮,因此为记数加显示 AJMP LOOP T0INT:
MOV TH0,#3CH ; 定时器重新初始化 MOV TL0,#0B0H DEC R1
RETI ; 中断返回 END
C 语言程序代码: #include #define TIMEINT 0x01 #define TIMEH 0x3C #define TIMEL 0xB0
extern unsigned char t_count;
void timer0(void) interrupt 1 using 1 {
TH0=TIMEH; TL0=TIMEL; t_count--; }
main() {
unsigned char DisNum; DisNum=0xFE; t_count=20;
TMOD=TIMEINT; TH0=TIMEH; TL0=TIMEL; ET0=1; EA=1; TR0=1; while(1) {
while(t_count!=0) {
P1=DisNum; }
t_count=20; DisNum--; } }
将定时器T0设置成定时方式,由P1.0输出50%占空比的500Hz 方波。 汇编语言代码: ORG 0000H AJMP START ORG 000BH AJMP T0INT ORG 0030H START:
MOV SP ,#60H
MOV TMOD,#01H MOV TL0,#18H MOV TH0,#0FCH
SETB ET0 ; 开中断 SETB EA SETB TR0 AJMP $ ; 等待中断 T0INT:
CPL P1.0
MOV TL0,#18H ; 初始化T0定时器 MOV TH0,#0FCH RETI END
C 语言程序代码: #include #define TIMEINT 0x01 #define TIMEH 0x00 #define TIMEL 0x00
extern unsigned char t_count,flag; void timer0(void) interrupt 1 using 1 {
TH0=TIMEH; TL0=TIMEL; flag=flag^1; }
main() {
flag=1;
TMOD=TIMEINT; TH0=TIMEH; TL0=TIMEL; ET0=1; EA=1; TR0=1; while(1) {
if(flag==0) {
P1=0xff; }
if(flag==1) {
P1=0xfe; }
continue; } }
将定时器T0设置成对外部脉冲计数方式,T0引脚每来一次外部脉冲,记数加
1,计数结果以二进制格式显示在8个发光二极管上。 汇编语言代码: ORG 0000H AJMP S TART ORG 000BH AJMP T 0INT ORG 0030H START:
MOV SP ,#60H
MOV TMOD,#0DH ; 设置为计数状态
MOV TL0,#0FFH ; 设置计数值为1时就溢出 MOV TH0,#0FFH
SETB ET0 ; 开中断 SETB EA
SETB TR0 ; 启动定时器 MOV A,#0FFH MOV R1,#1 ; 中断处理标志 MOV P1,A LOOP:
CJNE R1,#0,LOOP ; 等待中断 MOV R1,#1 DEC A
MOV P1,A ; 计数显示 AJMP LOOP T0INT:
MOV TH0,#0FFH MOV TL0,#0FFH DEC R1 RETI END
C 语言程序代码: #include #define TIMEINT 0x0D #define TIMEH 0xFF #define TIMEL 0xFF extern unsigned char flag;
main() {
unsigned char DisNum; DisNum=0xFF; TMOD=TIMEINT; TH0=TIMEH; TL0=TIMEL; ET0=1; EA=1; TR0=1; flag=1;
P1=DisNum; while(1) {
if(flag==0) {
flag=1; DisNum--; P1=DisNum; }
continue; } }
void timer0(void) interrupt 1 using 1 {
TH0=TIMEH; TL0=TIMEL; flag=0;
}
使用T0、T1两个定时器分别控制从P1.0输出波形的高、低电平的宽度。 汇编语言代码: ORG 0000H AJMP START ORG 000BH AJMP T0INT ORG 001BH AJMP T1INT ORG 0030H
START: MOV MOV MOV MOV MOV MOV SETB SETB SETB MOV SETB LOOP1: CJNE MOV AJMP SECOND: MOV RETURN: AJMP T0INT: CLR MOV MOV MOV SETB RETI T1INT: CLR MOV MOV MOV SETB RETI END
SP ,#60H
TMOD,#11H TL0,#00H TH0,#00H TL1,#00H TH1,#00H ET0 ET1 EA R1,#0 TR0
; 定时/计数器设置
; 两个定时器的初值设置
; 开中断T0、T1 ;R1作为标志位使用 ; 若标志位等于1则跳转
R1,#1,SECOND P1,#0FFH RETURN P1,#0FEH LOOP1 TR0 TL0,#00H TH0,#00H R1,#01H TR1 TR1 TL1,#00H TH1,#00H R1,#00H TR0
; 循环执行
;T0定时时间到,关闭 ;T0定时器设置初值 ; 标志位置1 ;T1定时开启
;T1定时时间到,关闭 ;T1定时器设置初值 ; 标志位置0 ;T0定时开启 ; 中断返回
C 语言程序代码: #include #define TIMEINT 0x11 #define TIMEH 0x00 #define TIMEL 0x00 extern unsigned char flag; main() {
TMOD=TIMEINT; TH0=TIMEH; TL0=TIMEL; ET0=1;
TH1=TIMEH; TL1=TIMEL; ET1=1; EA=1; flag=1; TR0=1; while(1) {
if(flag==0) {
P1=0xff; }
if(flag==1) {
P1=0xfe; }
continue; } }
void timer0(void) interrupt 1 using 1 {
TR0=0;
TH0=TIMEH; TL0=TIMEL; flag=1; TR1=1; }
void timer1(void) interrupt 3 using 1 {
TR1=0;
TH0=TIMEH; TL0=TIMEL; flag=0; TR0=1; }
六、实验小结
通过本次实验,我对单片机的定时/计数功能有了一定的了解,熟悉了定时/计数器的设置、控制和最基本的应用,初步获悉了定时/计数器的内部结构,再结合上一次实验对终端的了解,二者配合,编写一些简单的程序,完成诸如产生固定频率的方波、脉冲计数和占空比调整的功能,巩固对中断和定时/计数的知识,为下一步的学习打下坚实的基础。
以上程序均已经过实验仪现象验证,如有什么不足,请老师指出并告知,谢谢。
4.1