实验报告5 下载本文

大连理工大学软件学院 《单片机原理与应用》实验报告

姓 名: 韩广义 学号: 201193046 班级: 软1106 姓 名: 于世友 学号: 201192080 班级: 软 1103

组 号: 25

实验箱编号: 25

实验时间: 2013年5月28日实验室: 嵌入式实验室 实验台: _ 指导教师: 侯刚老师 成绩:

实验5:秒表定时器实验

一、实验目的和要求 实验目的:

1. 学习单片机的基本接口技术。

2. 学习74HC595、74HC138使用及与51单片机的控制方法。 实验要求:

用汇编语言设计程序,完成8个数码管的显示控制。

检查内容:当按下INT 按钮时,数码管开始快速计时,高五位为 秒数,低三位为ms 数,每1ms 刷新一次显示内容。当再次按下 INT 按钮时,停止计数。 二、实验原理和内容

:按键电路

我们在参考实验4的基础上,理解按键按钮的电路实现功能,使用了138和595两块电路,实现了实验要求功能。 原理内容见编程中的注释。 三、主要仪器设备及软件编程环境

Keil uVision2编译器、51单片机 四、实验步骤与编程

NumbList:

;; 0

1

2

3

4

5

6

7

8

9

ORG 00H LJMP START ORG 0BH

;定时器0的中断服务程序入口

LJMP T0_INT_SRV

ORG 013H ;外部中断1的中断服务程序入口 LJMP EX1_INT_SRV ORG 30H

DB 3fH, 6H, 5bH, 4fH, 66H, 6dH, 7dH, 7H, 7fH, 6fH

;; AFH 0EH DBH CFH E6H EDH FDH FH FFH EFH 带有小数

点的数码表示

MsecAddr EQU 70h ;毫秒的存放地址70H~72H 每个字节用于保存1位 SecAddr 表NumList

DispNomAddr EQU 78h ;78H~7FH中放置的是每个LED值对应的打印值 START:

;;初始化LED,默认为0 的话,此段可以省略,

MOV A,#0h

;A中数值为数码0

EQU 73h ;秒数的存放地址73h~77H 每个字节用于保存1位,保存的是实际值,显示的时候查

MOV R2,#8 ;一共8位 MOV R0,#MsecAddr MOV R1,#DispNomAddr

INILOOP:

MOV @R0,A MOV @R1,A INC R0 INC R1

DJNZ R2,INILOOP

;初始化8个LED

;;****************************************************** ;;开启中断

;;*******************************************************

SETB EA ;开启所有的中断 SETB EX1 ;允许外部中断1 SETB IT1 ;外部中断1跳变触发 SETB PX1 ;提高外部中断优先级

CLR PT0 ;降低定时器0的优先级 CLR TR0 ;关闭定时器0

MOV TMOD,#0001B ;T0设定为16位计数器(定时方式)

;;显示8LED的内容,无限循环显示 ;;无限循环 REFRESH:

;; 从DispNursAddr读值 在LED上显示 MOV P0,#0 MOV R6,#8h

MOV R1,#0;用于屏蔽高位不用的LED MOV R0,#DispNomAddr+7

NomShfting: ;移动到下一个要显示的数

CJNE R1,#0,BitShfting;不等则转移 DEC R0 INC P0

DJNZ R6,NomShfting

MOV R1,#1 CJNE A,#3fH,PING; MOV R7,#8h CLR A MOV A,@R0

;把要显示的数放到累加器A中

PING:

BitShfting:

DEC R0

;移动到下一个要显示的值

RLC A MOV P0.5,C

;把移出位放到SER引脚

;; 在SRCLK上制造一个正跳变,接收SER的值 CLR P0.4 SETB P0.4

DJNZ R7,BitShfting

;; 在RCLK上制造一个正跳变,接收整个8位值

CLR P0.3 SETB P0.3

LCALL DispDelay ;延迟

INC P0 ;(P0.0~P0.2) 对应LED移动

DJNZ R6,NomShfting LJMP REFRESH

;;******************************************************************* T0_INT_SRV:;;T0的中断服务程序

;; 用64h ~ 69h保存中断服务程序中用到得寄存器的值 MOV 69h,R0 MOV 68h,R1 MOV 67h,A MOV 66h,DPH MOV 65h,DPL MOV 64h,R7

;; 第1步,先累加1ms的值到保存计数值的位置

;push DPTR ;push R7

;push R0 ;push R1 ;push A

NOMINC: MOV R0,#MsecAddr

MOV R7,#8

;一共有8个数要判断

INCLOOP: ;有进位的话,高位也累加

INC @R0 ;对当前位进行加1

CJNE @R0,#10,INCFINISH ;如果当前位没有进位则循环结束

MOV @R0,#0 ;如果当前位有进位则当前位清零,并对下一位进行判断 INC R0 ;指针移动到下一位的位置 DJNZ R7,INCLOOP

INCFINISH:

;; 第2步,更新显示列表里面的数值

UpdateDispNom:

MOV R7,#8

MOV R0,#MsecAddr MOV R1,#DispNomAddr MOV DPTR,#NumbList

UpdateDispLoop:

MOV A,@R0

;把实际值放到A中

MOVC A,@A+DPTR ;用实际值取列表中的显示值 MOV @R1,A INC R0

;把A中显示值放到LED要显示的对应字节中去

;移动实际值指针

INC R1 ;移动显示值指针

DJNZ R7,UpdateDispLoop;一共有8个LED值要更新

PutPointer: ;子第三个数和第四个数之间加一个小数点

MOV R0,69h MOV R1,68h MOV A,67h MOV DPH,66h MOV DPL,65h MOV R7,64h RETI

;pop DPTR ;pop R7

;pop R0 ;pop R1 ;pop A

;; 第3步,重置定时器0 MOV TH0,#0FCH

MOV TL0,#017H ;重置定时器的值 SETB TR0 ;开启定时器 ;; 还原用到的寄存器的值 MOV R0,#DispNomAddr+3 MOV A,@R0

;

ORL A,#10000000b ;用或操作对对应位赋值1 MOV @R0,A

;更新

;;**************************************************************** EX1_INT_SRV:;外部中断1的服务程序 ;;设置T0,计时1ms

MOV 69h,R0 MOV R0,#03fH

;push R0

INT_DELAY:

JB P3.3, SRV_END MOV TH0,#0FCH

MOV TL0,#017H ;(65535-1000=0xFC17)定义为1ms CPL ET0 ;开启/关闭定时器中断0 SETB TR0

;启动定时器0

DJNZ R0,INT_DELAY ;按键去抖动

SRV_END:

MOV R0,69h

;pop R0

RETI ;中断服务程序返回 ;;相应中断后,硬件将IE1置零0

;;***************************************************************** ;;LED显示切换 DispDelay:

MOV R4,#05H

MOV R5,#0ffH DJNZ R5,LOOP2

LOOP1: LOOP2: END

DJNZ R4,LOOP1

RET

五、实验数据与结果分析

数据结果与实验要求完全符合。当第一次按下INT键时,开始秒表计时;再按下,停止计时;再按下,从停止的地方继续计时。根据定时器原理进行理论数据计算的寄存器值为FC17,实验结果与真实情况有较大误差,可能是由于程序执行和指令调用花费了一部分时间。经过测试和调整,我们选择了FC90作为定时数据,基本误差可控在5%以内。

六、讨论、建议

希望老师能让我们借用试验箱来进行代码的测试。