华中科技大学单片机实验实验报告MCS51单片机

时间:2024.3.27

华中科技大学单片机实验报告

MCS-51系列单片机

(单片机原理及应用实验)

(根据20xx年电气与电子工程学院单片机实验课程改编)

专 业: 电气工程及其自动化

班 级: 气卓1301

姓 名: 廖鹏毅

学 号:

ALL RIGHT RESERVED

1

目 录

实验3.1 软件仿真实验??????????????????3 实验2“跑马灯”实验???????????????????8 实验3 数码管显示功能的实现???????????????11 实验5 按键功能的实现??????????????????23 实验7 A/D转换器件TLC1543的用??????????????29 实验8 D/A转换器件TLV5617的应用?????????????34 实验14指示灯的外部中断控制???????????????47 实验18定时器控制继电器?????????????????49 自行设计实验 ??????????????????????53 实验总结 ????????????????????????55 2

实验3.1 软件仿真实验

一 实验目的

1 掌握软件仿真的方法

2 熟悉集成开发环境的使用

3 熟悉常用指令的功能

4 熟悉程序调试的方法

5 学习自己编写、调试计算机程序

二 实验内容

1 将Keil软件设置为软件仿真的方式

2 将3.1.4介绍的示例程序录入、编译、调试

3 观察有关寄存器、变量的值,理解程序及指令的功能

4 编译、调试、验证自己编写的子程序

三 实验步骤

1 先阅读课本,大致了解仿真软件的使用和注意事项

2 结合课本,边看书边上机操作,逐步了解和掌握仿真软件的使用

3 阅读和理解3.1.4介绍的示例程序,并将其录入、编译、调试

4 赋值给示例程序时,打开各观察窗口,观察有关寄存器、变量的值,验证其功能 5 自行编译、调试、验证自己编写的子程序

四 实验结果

1 给十六进制数转换为十进制数子程序赋初值,

MOV H_DAT0,#01H

MOV H_DAT1,#00H

则编译加载调试该子程序,打开各观察窗口观察有关变量,实验发现D_DAT0,D_DAT1,D_DAT2,D_DAT3中的值分别为00,00,00,01。则符合实际,即验证其功能。 2 给双字节乘法运算子程序赋初值,

MOV R4,#8

MOV R5,#9

MOV R6,#6

MOV R7,#7

然后编译加载调试该子程序,并用观察窗口观察有关变量,实验发现MUL_0,MUL_1,MUL_2,MUL_3分别为08,04,04,07.则符合实际,即验证其功能。 3 给三字节数除双字节数运算子程序赋初值,

MOV ODIV_H,#00H

MOV ODIV_M,#00H

MOV ODIV_L,#01H

MOV DIV_1,#00H

MOV DIV_0,#01H

接着编译加载调试该子程序,并用观察窗口观察有关变量,实验发现R0,R1,R3,R4,R5中的值分别为00,00,00,00,01,则实验验证其功能。

五 实验小结

本次实验,我初步了解仿真软件的使用,同时掌握了编译、加载、调试程序的方法以及验证实验结果的方法

3

附:3.1.4示例程序

含 主程序

十六进制数转换为十进制数子程序 双字节乘法运算子程序

三字节数除双字节数运算子程序 D_DAT0 EQU 50H

D_DAT1 EQU D_DAT0+1 D_DAT2 EQU D_DAT1+1 D_DAT3 EQU D_DAT2+1

H_DAT0 EQU D_DAT3+1 H_DAT1 EQU H_DAT0+1

ODIV_L EQU H_DAT1+1 ODIV_M EQU ODIV_L+1 ODIV_H EQU ODIV_M+1 DIV_0 EQU ODIV_H+1 DIV_1 EQU DIV_0+1

MUL_0 EQU DIV_1+1 MUL_1 EQU MUL_0+1 MUL_2 EQU MUL_1+1 MUL_3 EQU MUL_2+1

ORG 0000H AJMP START

ORG 0030H

START: MOV SP,#30H ;在此处给有关变量单元赋值 MOV H_DAT1,#2 MOV H_DAT0,#0 LCALL HTD

;在此处给有关变量单元赋值

LCALL TMUL ;在此处给有关变量单元赋值

LCALL SDIV

LOOP: NOP

AJMP LOOP 4

HTD: H1000: H100: H10: MOV D_DAT3,#00H ;将结果千位清0 MOV D_DAT2,#00H MOV D_DAT1,#00H MOV D_DAT0,#00H ;以上将各位结果存储单元清0 CLR C ;进位位C清0 MOV A,H_DAT0 ;源数据低位装载到累加器A中 MOV R6,A ;备份源数值低位到寄存器R6中 SUBB A,#0E8H ;源数值低位减去1000的低位0E8H MOV H_DAT0,A ;余数存回到源数值低位存储单元 MOV A,H_DAT1 ;源数值高位装载到累加器A中 MOV R7,A ;备份源数值高位到寄存器R7中 SUBB A,#03H ;源数值高位带借位减1000的高位03H MOV H_DAT1,A ;余数存回到源数值低位存储单元 INC D_DAT3 ;千位增1 JNC H1000 ;如果没有借位则利用余数循环再减 ;有借位表明为最后一次无效减 ;程序顺序执行,应还原最后一次修改值 MOV H_DAT0,R6 MOV H_DAT1,R7 ;用备份值作为新的源数值(余数) DEC D_DAT3 ;千位数减1,去掉最后一次无效减的影响 MOV A,H_DAT0 ;源数值低位装载到累加器A中 MOV R6,A ;备份源数值低位到寄存器R6中 CLR C ;清0进位位C SUBB A,#100 ;减去100 MOV H_DAT0,A ;存回余数低位 MOV A,H_DAT1 ;取源数值高位 SUBB A,#00H ;减100的高位0,实际上是减去借位位 MOV H_DAT1,A ;存回余数高位 JC H10 ;有借位则跳到下一步继续运算 INC D_DAT2 ;没有借位,百位增1 AJMP H100 ;没有借位继续减 ;注意本轮循环中最后一次减时百位未增1 ;所以不存在还原的问题 ;进入下一轮时,源数值(余数)都在R6中 CLR C MOV A,R6 ;源数值(低位)装载到累加器A中 ;到此源数值高位已经为0,不用再参加计算 MOV D_DAT0,A ;存回源数值低位 ;如果是最后一次减,则此值即为个位 SUBB A,#10 ;减去10 MOV R6,A ;保存余数 JC H1 ;有借位,运算结束 INC D_DAT1 ;没有借位,十位增1 5

H1: TMUL: LAST:

SDIV: SDIV0: LJMP H10 ;没有借位继续减 RET ;子程序返回 MOV A,R6 MOV B,R4 MUL AB ;第一次乘法 MOV MUL_0,A ;第一次乘法结果低位存到MUL_0(最终结果) MOV R3,B ;第一次乘法结果高位暂存在R3中 MOV A,R4 MOV B,R7 MUL AB ;第二次乘法 ADD A,R3 ;第二次乘法结果低位加第一次乘法结果的高位 MOV R3,A ;所得第一次加法结果低位暂存到R3中 MOV A,B ADDC A,#00H ; 第二次乘法结果高位加进位位C MOV R2,A ;所得第一次加法结果高位暂存到R2中 MOV A,R6 MOV B,R5 MUL AB ;第三次乘法 ADD A,R3 ;第三次乘法结果低位加R3 MOV MUL_1,A ;第二次加法结果低位存到MUL_1(最终结果) MOV R1,#00H ;第二次加法高位进位值清0 MOV A,R2 ADDC A,B ;第三次乘法结果高位加R2及进位位C MOV R2,A ;第二次加法结果高位暂存R2 JNC LAST ;没有进位则跳转(R1=0) MOV R1,#1 ;有进位,第二次加法高位进位值为1 MOV A,R7 MOV B,R5 MUL AB ;第四次乘法 ADD A,R2 ;第四次乘法结果低位加R2 MOV MUL_2,A ;第三次加法结果低位存到MUL_2(最终结果) MOV A,B ADDC A,R1 ;第四次乘法高位加第二次加法高位进位值R1 ;及第三次加法低位进位位C MOV MUL_3,A ;第三次加法结果高位存到MUL_3中(最终结果) RET MOV R0,#00H MOV R1,#00H ;清0过渡单元 MOV R2,#24 ;因被除数有三个字节(24位),所以循环24次 CLR C ;清0进位位C MOV A,ODIV_L ;(ODIV_L)→A RLC A ;A中的值带进位位C左移1位 MOV ODIV_L,A ;(A)→ODIV_L,移位后存回 6

SDIV1:

MOV A,ODIV_M RLC A MOV ODIV_M,A MOV A,ODIV_H RLC A MOV ODIV_H,A ;以上将被除数左移一位,最高位在进位位C中 MOV A,R0 RLC A MOV R0,A ;R0的值带进位左移后存回 MOV R6,A ;备份R0的值在R6中 MOV A,R1 RLC A MOV R1,A ;R1的值带进位左移后存回 MOV R7, A ;备份R1的值在R7中 ;以上实现Z和X一起左移1位 ;并把Z中的值备份了一份 CLR C MOV A,R0 SUBB A,DIV_0 MOV R0,A MOV A,R1 SUBB A,DIV_1 MOV R1,A ;以上将Z减Y后差值写回Z中 JNC SDIV1 ;没有借位(够减)则跳转,用差值继续计算 MOV A,R6 MOV R0,A MOV A,R7 MOV R1,A ;有借位,不够减,用备份值取代差值,即不减 CPL C ;借位C取反即为商。C为0,够减,商1 MOV A,R5 RLC A MOV R5,A MOV A,R4 RLC A MOV R4,A MOV A,R3 RLC A MOV R3,A ;以上将商移入R3、R4、R5中 DJNZ R2,SDIV0 ;按R2中的值,循环24次 RET END 7

实验2 “跑马灯”实验

一 实验目的

1 了解发光二极管的使用方法

2 熟悉串行、并行输出扩展接口的方法

3 学习常用指令用法和简单程序编写技巧

二 实验内容

1 理解图4.3.1的电路原理和参考程序

2 按图4.3.1连接电路,调试参考程序,单步执行每行指令,观察有关寄存器中值的变化,理解指令的功能和执行效果

三 实验步骤

1 先阅读课本,理解原理和程序

2 按图接线,然后编译加载调试程序,观察实验现象,是否出现“跑马灯”

四 实验结果

接好线,并运行程序后,8个灯依次循环闪亮,出现“跑马灯”,验证其功能。

五 实验小结

理解I/O口的使用,以及发光二极管的使用和原理

附:跑马灯子程序:

LIGHT-S跑马灯串行

LIGHT EQU 60H ;定义指示灯数据存放地址单元

SIO EQU P2.0 ;串行移位数据

SCLK EQU P2.1 ;串行移位时钟信号

SRCLK EQU P2.2 ;输出锁存信号

ORG 0000H

AJMP START

ORG 0030H

START: MOV SP,#30H ;初始化堆栈指针

CLR SIO

CLR SCLK

CLR SRCLK

MOV LIGHT,#01H ;初始化指示灯输出数据

NOP

MAIN: LCALL FLYLED ;调用指示灯循环点亮子程序

LCALL DELAY ;延时子程序同参考例程一

AJMP MAIN ;循环执行主程序

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

;通过595循环点亮指示灯子程序

*****************************************************

FLYLED: MOV A,LIGHT

CLR C

8

RLC A ;A中最高位移到C

CPL C ;因低电平点亮,故取反

MOV SIO,C ;LIGHT中数据最高位送到SER输入端 SETB SCLK

NOP

CLR SCLK ;产生一个移位脉冲

SETB SRCLK

NOP

CLR SRCLK ;产生一个输出锁存脉冲

CJNE A,#0,FLYCON ;A中不为0则继续

MOV A,#01H ;A中为0,表明循环完一轮

;重新赋初值

FLYCON: MOV LIGHT,A

RET

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

;延时子程序

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

DELAY: MOV R7,#80H

DELY1: MOV R6,#0FFH

DELY2: DJNZ R6,$ ;$代表当前行;;作用与DJNZ R6,DELY2相同 DJNZ R7,DELY1

LED-P跑马灯并行

LIGHT EQU 60H ;定义指示灯数据存放地址单元

ORG 0000H

AJMP START

ORG 0030H

START: MOV SP,#30H ;初始化堆栈指针

;

CLR P1.0 ;初始化有关I/O口

MOV LIGHT,#01H ;初始化指示灯数据

NOP

MAIN: LCALL FLYLED ;调用指示灯循环点亮子程序 LCALL DELAY ;延时子程序

AJMP MAIN ;死循环

;****************************************************** 9

;通过374循环点亮指示灯子程序

;***************************************************** FLYLED: MOV A,LIGHT

CPL A ;因为低电平点亮,故取反

MOV P0,A ;LIGHT中数据送到374的输入端 ;(因P1口与374输入端相连) SETB P1.0

NOP

CLR P1.0 ;产生一个锁存脉冲

;将数据锁存到374中输出

MOV A,LIGHT

CLR C

RLC A ;ACC中数据左移一位

;(高位丢到,低位补0)

CJNE A,#0,FLYCON ;A中不为0则继续 MOV A,#01H ;A中为0,循环完一轮 ;重新赋初值

FLYCON:MOV LIGHT,A

RET

;********************************************** ;延时子程序

;********************************************** DELAY: MOV R7,#80H

DELY1: MOV R6,#0FFH

DELY2: DJNZ R6,$ ;$代表当前行

;与DJNZ R6,DELY2相同

DJNZ R7,DELY1

RET

END

10

实验3 数码管显示功能的实现

一 实验目的

1 了解数码管显示器的特性和使用方法

2 进一步熟悉常用指令和编程技巧

3 熟悉单片机I/O口的使用方法

二 实验内容

1 对照图4.3.3和图4.3.4、图4.3.5,理解图4.3.3所示的电路原理

2 读懂参考例程一和参考例程二

3 分别验证参考例程一和参考例程二

4 利用试验箱通用板上的电路模块,自行设计一套4位数码管显示器的并行动态显示电路

三 实验步骤

1 首先阅读课本,理解相关原理和程序运行

2 调试示例程序,观察现象

3 根据所学知识,编写一套4位数码管显示器的并行动态显示电路

四 实验结果

1 调试示例程序,结果都出现6位静态显示

2 自行编写一套4位数码管显示器的并行动态显示电路

子程序:

MOV A,R0

MOV DPTR,#DISPD

MOV A,@A+DPTR

MOV P0,A

SETB P1.1

NOP

CLR P1.1

INC R0

LCALL DELAY

CJNE R0,#0AH,DISP

MOV R0,#00H

NOP

RET

调试后,可以4位数码管显示器的并行动态显示电路

五 实验总结

进一步了解I/O口的使用,掌握串行和并行的区别和使用,以及数码管的原理和使用 11

附:参考程序

LED-S-P数码管显示功能的实现 (并行动态显示参考程序1)

D_DAT0 EQU 6AH

D_DAT1 EQU 6BH

D_DAT2 EQU 6CH

D_DAT3 EQU 6DH

D_DAT4 EQU 6EH

D_DAT5 EQU 6FH ;定义显示数据存储单元

DATA_O EQU P0 ;定义显示数据输出口

PLED1 EQU P2.0

PLED2 EQU P2.1

PLED3 EQU P2.2

PLED4 EQU P2.3 ;以上定义四片574输出锁存信号

ORG 0000H

AJMP START

ORG 0030H

START: MOV SP,#30H ;初始化堆栈指针

MOV D_DAT0,#0

MOV D_DAT1,#1

MOV D_DAT2,#2

MOV D_DAT3,#3

MOV D_DAT4,#4

MOV D_DAT5,#5 ;初始化显示数据

CLR PLED1

CLR PLED2

CLR PLED3

CLR PLED4

NOP

MAIN: LCALL DISP ;调用数码管循环点亮子程序

LOOP: AJMP LOOP ;循环执行主程序

;****************************************************** ;通过574显示6位数字子程序

;***************************************************** DISP: MOV R0,#D_DAT0

MOV A,@R0 ;取需显示的数字

12

MOV DPTR,#DISPD ;装载笔画编码表首地址 MOVC A,@A+DPTR ;取需显示数字笔画代码

XRL A,#0FFH

MOV DATA_O,A ;笔画代码送到P0口

SETB PLED1

NOP

CLR PLED1 ;产生一个锁存脉冲,锁存笔画代码

INC R0 ;R0增1指向下一个需显示数字

MOV A,@R0 ;取需显示的数字

MOV DPTR,#DISPD ;装载笔画编码表首地址 MOVC A,@A+DPTR ;取需显示数字笔画代码

XRL A,#0FFH

MOV DATA_O,A ;笔画代码送到P0口

SETB PLED2

NOP

CLR PLED2 ;产生一个锁存脉冲,锁存笔画代码

INC R0 ;R0增1指向下一个需显示数字

MOV A,@R0 ;取需显示的数字

MOV DPTR,#DISPD ;装载笔画编码表首地址 MOVC A,@A+DPTR ;取需显示数字笔画代码

XRL A,#0FFH

MOV DATA_O,A ;笔画代码送到P0口

SETB PLED3

NOP

CLR PLED3 ;产生一个锁存脉冲,锁存笔画代码

INC R0 ;R0增1指向下一个需显示数字

MOV A,@R0 ;取需显示的数字

MOV DPTR,#DISPD ;装载笔画编码表首地址 MOVC A,@A+DPTR ;取需显示数字笔画代码

XRL A,#0FFH

MOV DATA_O,A ;笔画代码送到P0口

SETB PLED4

NOP

CLR PLED4 ;产生一个锁存脉冲,锁存笔画代码 RET

;数字笔画代码表

; 0 1 2 3 4 5 6 7 8 9 DISPD: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,0

END

13 熄

并行动态显示参考程序2

LIGHT EQU 60H ;定义指示灯数据存放地址单元 SIO EQU P2.0 ;串行移位数据

SCLK EQU P2.1 ;串行移位时钟信号

SRCLK EQU P2.2 ;输出锁存信号

ORG 0000H

AJMP START

ORG 0030H

START: MOV SP,#30H ;初始化堆栈指针

CLR SIO

CLR SCLK

CLR SRCLK

MOV LIGHT,#01H ;初始化指示灯输出数据

NOP

MAIN: LCALL FLYLED ;调用指示灯循环点亮子程序 LCALL DELAY ;延时子程序同参考例程一

AJMP MAIN ;循环执行主程序

;****************************************************** ;通过595循环点亮指示灯子程序

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

FLYLED: MOV A,LIGHT

CLR C

RLC A ;A中最高位移到C

CPL C ;因低电平点亮,故取反

MOV SIO,C ;LIGHT中数据最高位送到SER输入端 SETB SCLK

NOP

CLR SCLK ;产生一个移位脉冲

SETB SRCLK

NOP

CLR SRCLK ;产生一个输出锁存脉冲

CJNE A,#0,FLYCON ;A中不为0则继续

MOV A,#01H ;A中为0,表明循环完一轮

;重新赋初值

FLYCON: MOV LIGHT,A

14

RET

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

;延时子程序

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

DELAY: MOV R7,#80H

DELY1: MOV R6,#0FFH

DELY2: DJNZ R6,$ ;$代表当前行

;作用与DJNZ R6,DELY2相同

DJNZ R7,DELY1

RET

END

并行动态显示参考程序3:

D_DAT0 EQU 6AH

D_DAT1 EQU 6BH

D_DAT2 EQU 6CH

D_DAT3 EQU 6DH

D_DAT4 EQU 6EH

D_DAT5 EQU 6FH ;定义显示数据单元

D_DAT6 EQU 70H

ORG 0000H

AJMP START

ORG 0030H

START: MOV SP,#30H ;初始化堆栈指针

MOV D_DAT0,#0

MOV D_DAT1,#1

MOV D_DAT2,#2

MOV D_DAT3,#3

MOV D_DAT4,#4

MOV D_DAT5,#5 ;初始化显示数据

MOV P0,#0

CLR P1.1 ;初始化有关I/O口

CLR P1.2

MOV R0,#D_DAT0 ;初始化显示指针寄存器;R0指向第一位显示数字 MOV R1,#01H ;初始化需点亮数码管位置代码

NOP

MAIN: LCALL DISP ;调用数码管循环点亮子程序

LCALL DELAY ;延时子程序同前,应修改延时长度

AJMP MAIN ;循环执行主程序

15

DISP: MOV A,R1 ;取位代码

MOV P0,A ;位代码送P0口

SETB P1.2

NOP

CLR P1.2 ;产生一个锁存脉冲,锁存位代码

MOV A,@R0 ;取需显示的数字

MOV DPTR,#DISPD ;装载笔画编码表首地址 MOVC A,@A+DPTR ;取需显示数字笔画代码

MOV P0,A ;笔画代码送到P0口

SETB P1.1

NOP

CLR P1.1 ;产生一个锁存脉冲,锁存笔画代码

INC R0 ;R0增1指向下一个需显示数字

MOV A,R1

CLR C

RLC A

MOV R1,A ;R1中的值左移1位,指向下一位数码管 CJNE R0,#70H,DISP1 ;R0中不为70H则继续

MOV R0,#D_DAT0 ;R0中为70H,循环完一轮

;重新赋初值

MOV R1,#1 ;位置代码初值

DISP1: NOP

RET

;数字笔画代码表

; 0 1 2 3 4 5 6 7 8 9 DISPD: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,0 DELAY: MOV R7,#40H

DELY1: MOV R6,#0FH

DELY2: DJNZ R6,$ ;$代表当前行

;与DJNZ R6,DELY2相同

DJNZ R7,DELY1

RET

END

串行动态显示参考程序1:

D_DAT0 EQU 6AH

D_DAT1 EQU 6BH

D_DAT2 EQU 6CH

D_DAT3 EQU 6DH

16 熄

D_DAT4 EQU 6EH

D_DAT5 EQU 6FH ;定义显示数据单元

D_DAT6 EQU 70H

ORG 0000H

AJMP START

ORG 0030H

START: MOV SP,#30H ;初始化堆栈指针

MOV D_DAT0,#0

MOV D_DAT1,#1

MOV D_DAT2,#2

MOV D_DAT3,#3

MOV D_DAT4,#4

MOV D_DAT5,#5 ;初始化显示数据

MOV P0,#0

CLR P1.1 ;初始化有关I/O口

CLR P1.2

MOV R0,#D_DAT0 ;初始化显示指针寄存器 ;R0指向第一位显示数字

MOV R1,#01H ;初始化需点亮数码管位置代码 NOP

MAIN: LCALL DISP ;调用数码管循环点亮子程序 LCALL DELAY ;延时子程序同前,应修改延时长度 AJMP MAIN ;循环执行主程序

;****************************************************** ;通过574显示6位数字子程序

;***************************************************** DISP: MOV A,R1 ;取位代码

MOV P0,A ;位代码送P0口

SETB P1.2

NOP

CLR P1.2 ;产生一个锁存脉冲,锁存位代码

MOV A,@R0 ;取需显示的数字

MOV DPTR,#DISPD ;装载笔画编码表首地址 MOVC A,@A+DPTR ;取需显示数字笔画代码 MOV P0,A ;笔画代码送到P0口

SETB P1.1

17

串行动态显示参考程序2:(本程序实验时来不及执行,不知是否正确)

D_DAT0 EQU 6AH

D_DAT1 EQU 6BH

D_DAT2 EQU 6CH

D_DAT3 EQU 6DH

D_DAT4 EQU 6EH

D_DAT5 EQU 6FH ;定义显示数据单元

D_DAT6 EQU 70H

ORG 0000H

AJMP START

ORG 0030H

START: MOV SP,#30H ;初始化堆栈指针

MOV D_DAT0,#0

MOV D_DAT1,#1

MOV D_DAT2,#2

MOV D_DAT3,#3 ;初始化显示数据

MOV D_DAT4,#4

MOV D_DAT5,#5

CLR P1.3 ;SER引脚

CLR P1.1 ;SCLK引脚

CLR P1.2 ;SRCLK引脚;初始化有关I/O口

MOV R0,#D_DAT0 ;初始化数据指针;R0指向第一位显示数字 MOV R1,#01H ;初始化需点亮数码管位置代码 NOP

MAIN: LCALL DISP ;调用指示灯循环点亮子程序 ;LCALL DELAY ;延时子程序同前

NOP

AJMP MAIN ;死循环

;****************************************************** ;通过595显示4位数字子程序

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

DISP: MOV A,R1 ;取位代码数据

MOV R2,#8

DISP1: CLR C

RLC A

MOV P1.3,C ; 位代码送到SER的输入端

SETB P1.1

NOP

CLR P1.1 ;产生一个输入锁存脉冲

18

DJNZ R2,DISP1 ;依次将8位位代码移入;实际只有6位有用 MOV A,@R0 ;取需显示的数字

MOV DPTR,#DISPD ;笔画编码表同前

MOVC A,@A+DPTR ;取需显示数字笔画代码

MOV R2,#8

DISP2: CLR C

RLC A

MOV P1.3,C ;笔画代码送到SER的输入端

SETB P1.1

NOP

CLR P1.1 ;产生一个输入锁存脉冲

DJNZ R2,DISP2 ;依次将8位笔画代码(段代码)移入 INC R0 ;R0增1指向下一个需显示数字

MOV A,R1

CLR C

RLC A

MOV R1,A ;R1中的值左移1位,指向下一位数码管 CJNE R0,#070H,DISP3 ;R0中不为70H则继续

MOV R0,#D_DAT0

MOV R1,#01H ;R0中为70H,循环完一轮;重新赋初值 DISP3: SETB P1.2

CLR P1.2

RET

;数字笔画代码表

; 0 1 2 3 4 5 6 7 8 9 DISPD: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,0 DELAY: MOV R7,#80H

DELY1: MOV R6,#0FFH

DELY2: DJNZ R6,$ ;$代表当前行

;与DJNZ R6,DELY2相同

DJNZ R7,DELY1

RET

END

19 熄

实验任务:要让低次位LED数码管显示中总带有小数点,即显示的六位数值中总带有一位小数,请编程实现:

D_DAT0 EQU 6AH

D_DAT1 EQU 6BH

D_DAT2 EQU 6CH

D_DAT3 EQU 6DH

D_DAT4 EQU 6EH

D_DAT5 EQU 6FH ;定义显示数据单元

D_DAT6 EQU 70H

ORG 0000H

AJMP START

ORG 0030H

START: MOV SP,#30H ;初始化堆栈指针

MOV D_DAT0,#0

MOV D_DAT1,#1

MOV D_DAT2,#2

MOV D_DAT3,#3

MOV D_DAT4,#4

MOV D_DAT5,#5 ;初始化显示数据

MOV P0,#0

CLR P1.1 ;初始化有关I/O口

CLR P1.2

MOV R0,#D_DAT0 ;初始化显示指针寄存器

;R0指向第一位显示数字

MOV R1,#01H ;初始化需点亮数码管位置代码

mov R3,#0H

MOV R4,#0H

NOP

MAIN: LCALL DISP ;调用数码管循环点亮子程序

LCALL DELAY ;延时子程序同前,应修改延时长度

AJMP MAIN ;循环执行主程序

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

;通过574显示6位数字子程序

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

DISP:CJNE R4,#0FEH,NEXT

MOV A,R3

ADD A,#01H

20

MOV R3,A

CJNE R3,#07H,NEXT

MOV R3,#0H

NEXT:MOV A,R1 ;取位代码

MOV P0,A ;位代码送P0口

SETB P1.2

NOP

CLR P1.2 ;产生一个锁存脉冲,锁存位代码

MOV A,@R0 ;取需显示的数字

MOV DPTR,#DISPD ;装载笔画编码表首地址 MOVC A,@A+DPTR ;取需显示数字笔画代码

CJNE R3,#01H ,POT1

CJNE R1,#01H,DISP2

ADD A,#80H

POT1:CJNE R3,#02H ,POT2

CJNE R1,#02H,DISP2

ADD A,#80H

POT2:CJNE R3,#03H ,POT3

CJNE R1,#04H,DISP2

ADD A,#80H

POT3:CJNE R3,#04H ,POT4

CJNE R1,#08H,DISP2

ADD A,#80H

POT4:CJNE R3,#05H ,POT5

CJNE R1,#10H,DISP2

ADD A,#80H

POT5:CJNE R3,#06H ,DISP2

CJNE R1,#20H,DISP2

ADD A,#80H

DISP2: MOV P0,A ;笔画代码送到P0口

SETB P1.1

NOP

CLR P1.1 ;产生一个锁存脉冲,锁存笔画代码

INC R0 ;R0增1指向下一个需显示数字

MOV A,R1

CLR C

RLC A

MOV R1,A ;R1中的值左移1位,指向下一位数码管 MOV A,R4

ADD A,#01H

MOV R4,A

CJNE R4,#0FFH,NEXT2

MOV R4,#0H

NEXT2: CJNE R0,#70H,DISP1 ;R0中不为70H则继续 21

MOV R0,#D_DAT0 ;R0中为70H,循环完一轮

;重新赋初值

MOV R1,#1 ;位置代码初值

DISP1: NOP

RET

;数字笔画代码表

; 0 1 2 3 4 5 6 7 8 9 熄 DISPD: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,0 ;**********************************************

;延时子程序

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

DELAY: MOV R7,#40H

DELY1: MOV R6,#0FH

DELY2: DJNZ R6,$ ;$代表当前行

;与DJNZ R6,DELY2相同

DJNZ R7,DELY1

RET

END

22

实验5 按键功能的实现

一 实验目的

1 理解按键电路的作用

2 学习按键功能的编程方法

二 实验内容

1 进一步理解单片机I/O口的使用方法 2 看懂图4.3.6所示的电路,读懂参考程序

3 自行设计4位按键分别操控四个数码管显示四个不同的数字

三 实验步骤

1 先阅读课本,理解程序和按键原理

2 调试示例程序,观察现象

3 自行设计4位按键分别操控四个数码管显示四个不同的数字

四 实验结果

1 调试示例程序,发现其可以静态显示,且按键能改变数值 2 自行设计4位按键分别操控四个数码管显示四个不同的数字 子程序:

START: MOV P1,#0F0H

MOV P0,#0

INTR : JNB P1.4,K1

JNB P1.5,K2

JNB P1.6,K3

JNB P1.7,K4

JMP INTR

K1:MOV R0,#06H

MOV R1,#01H,

LJMP DISP

K2:MOV R0,#:5BH

MOV R1,#02H,

LJMP DISP

K3:MOV R0,#4FH

MOV R1,#04H,

LJMP DISP

K4:MOV R0,#66H

MOV R1,#08H,

LJMP DISP

DISP: MOV A,R1

MOV P0,A

SETB P1.2

NOP

CLR P1.2

MOV A,R0

MOV P0,A

SETB P1.1

23

NOP

CLR P1.1

LCALL DELAY

LJMP START

调试结果:4位按键分别操控四个数码管显示四个不同的数字

五 实验小结

进一步了解I/O口和数码管使用和原理,掌握按键的使用和原理

附:示例程序

KEYUSE按键功能的实现

D_DAT0 EQU 60H

D_DAT1 EQU D_DAT0+1

D_DAT2 EQU D_DAT1+1

D_DAT3 EQU D_DAT2+1

D_DAT4 EQU D_DAT3+1

D_DAT5 EQU D_DAT4+1 ;定义显示数据单元 LIGHT EQU D_DAT5+1

H_DAT0 EQU LIGHT+1

H_DAT1 EQU H_DAT0+1

KBM EQU H_DAT1+1 ;定义按键功能号存放单元 D_MAX EQU KBM+1 ;定义上限值存放单元 D_MIN EQU D_MAX+1 ;定义下限值存放单元 T_DAT0 EQU D_MIN+1

T_DAT1 EQU T_DAT0+1 ;定义测量值存放单元 ORG 0000H

AJMP START

ORG 0030H

START: MOV SP,#30H ;初始化堆栈指针

MOV D_DAT0,#0

MOV D_DAT1,#0

MOV D_DAT2,#0

MOV D_DAT3,#0

MOV D_DAT4,#0

MOV D_DAT5,#0 ;初始化显示数据

MOV LIGHT,#80H

CLR P1.0

CLR P1.1

CLR P1.2

CLR P1.3 ;初始化有关I/O口

MOV R0,#D_DAT0 ;初始化数据指针

;R0指向第一位显示数字

24

MOV R1,#01H ;初始化需点亮数码管位置代码 MOV KBM,#0 ;初始化功能号

MOV D_MAX,#80

MOV D_MIN,#70 ;初始化上、下限值

MOV T_DAT0,#66

MOV T_DAT1,#0 ;目前人为赋给测量值一个值 ;将来有实际测量值就存放在此

MOV H_DAT0,T_DAT0

MOV H_DAT1,T_DAT1

LCALL HTD ;将测量值二进制数转换为十进制数 MAIN: LCALL DISP ;刷新显示

LCALL DELAY ;显示、延时子程序同前

;****************************************************** ;按键处理程序

;***************************************************** JB P1.7,KEY1 ;查询K0,若K0未按下则跳转 LCALL DISP

LCALL DELAY ;延时去抖动,顺便刷新显示 JB P1.7,KEY1 ;若K0未真正按下则跳转

INC KBM ;K0真正按下,功能号增1

MOV A,KBM

CJNE A,#3,KEY01

MOV KBM,#0 ;若功能号为3,则清0

KEY01: NOP

AJMP KEND ;跳转至按键结束处理程序 KEY1: JB P1.6,KEY2 ;查询K1

LCALL DISP

LCALL DELAY

JB P1.6,KEY2

MOV A,KBM

CJNE A,#1,KEY11 ;功能号不为1则跳转

INC D_MAX ;功能号1,上限值加1

AJMP KEND

KEY11: CJNE A,#2,KEY12 ;功能号不为2则跳转 INC D_MIN ;功能号2,下限值加1

KEY12: AJMP KEND ;跳转至按键结束处理程序 KEY2: JB P1.5,KEND ;查询K2

LCALL DISP

LCALL DELAY

JB P1.5,KEND

MOV A,KBM

CJNE A,#1,KEY21

DEC D_MAX ;功能号1,上限值减1

25

AJMP KEND

KEY21: CJNE A,#2,KEND

DEC D_MIN ;功能号2,下限值减1

KEND: NOP ;以下程序根据功能号显示不同内容 MOV A,KBM

CJNE A,#0,KEND1

MOV H_DAT0,T_DAT0

MOV H_DAT1,T_DAT1 ;功能号0,准备显示测量数据 MOV LIGHT,#0BFH ;点亮相应指示灯

AJMP KEND3 ;跳转到刷新显示处

KEND1: NOP

CJNE A,#1,KEND2

MOV H_DAT0,D_MAX

MOV H_DAT1,#0 ;功能号1,准备显示上限值

MOV LIGHT,#7FH ;点亮相应指示灯

AJMP KEND3 ;跳转到刷新显示处

KEND2: NOP

CJNE A,#2,KEND3

MOV H_DAT0,D_MIN

MOV H_DAT1,#0 ;功能号2,准备显示下限值

MOV LIGHT,#0DFH ;点亮相应指示灯

KEND3: MOV P0,LIGHT

SETB P1.0

NOP

CLR P1.0 ;产生一个指示灯输出锁存脉冲 LCALL HTD ;将需显示数据转换成4个十进制数 MOV R4,#80H

KEND4: LCALL DISP

LCALL DELAY ;刷新显示,延时

DJNZ R4,KEND4 ;此处循环延时是为了避免按键多次重入 LJMP MAIN ;跳转到主程序开始处循环执行 ;****************************************************** ;通过595显示4位数字子程序

;***************************************************** DISP: MOV A,R1 ;取位代码数据

MOV R2,#8

DISP1: CLR C

RLC A

MOV P1.3,C ; 位代码送到SER的输入端

SETB P1.1

NOP

CLR P1.1 ;产生一个输入锁存脉冲

DJNZ R2,DISP1 ;依次将8位位代码移入

;实际只有6位有用

26

MOV A,@R0 ;取需显示的数字

MOV DPTR,#DISPD ;笔画编码表同前

MOVC A,@A+DPTR ;取需显示数字笔画代码

MOV R2,#8

DISP2: CLR C

RLC A

MOV P1.3,C ;笔画代码送到SER的输入端 SETB P1.1

NOP

CLR P1.1 ;产生一个输入锁存脉冲

DJNZ R2,DISP2 ;依次将8位笔画代码(段代码)移入 INC R0 ;R0增1指向下一个需显示数字

MOV A,R1

RL A

MOV R1,A ;R1中的值左移1位,指向下一位数码管 CJNE R1,#40H,DISP3 ;R0中不为70H则继续

MOV R0,#D_DAT0

MOV R1,#01H ;R0中为70H,循环完一轮;重新赋初值 DISP3: SETB P1.2

CLR P1.2

RET

;数字笔画代码表

; 0 1 2 3 4 5 6 7 8 9 熄 DISPD: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,0

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

;延时子程序

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

DELAY: MOV R7,#2

DELY1: MOV R6,#0FFH

DELY2: DJNZ R6,$ ;$代表当前行

;与DJNZ R6,DELY2相同

DJNZ R7,DELY1

RET;二进制转换十进制子程序

HTD: MOV D_DAT5,#00H ;将结果千位清0

MOV D_DAT4,#00H

MOV D_DAT3,#00H

MOV D_DAT2,#00H

;以上将各位结果存储单元清0

H1000: CLR C ;进位位C清0

MOV A,H_DAT0 ;源数据低位装载到累加器A中 MOV R6,A ;备份源数值低位到寄存器R6中 SUBB A,#0E8H ;源数值低位减去1000的低位0E8H MOV H_DAT0,A ;余数存回到源数值低位存储单元 27

H100: H10: H1: MOV A,H_DAT1 ;源数值高位装载到累加器A中 MOV R7,A ;备份源数值高位到寄存器R7中 SUBB A,#03H ;源数值高位带借位减1000的高位03H MOV H_DAT1,A ;余数存回到源数值低位存储单元 INC D_DAT2 ;千位增1 JNC H1000 ;如果没有借位则利用余数循环再减 ;有借位表明为最后一次无效减 ;程序顺序执行,应还原最后一次修改值 MOV H_DAT0,R6 MOV H_DAT1,R7 ;用备份值作为新的源数值(余数) DEC D_DAT2 ;千位数减1,去掉最后一次无效减的影响 MOV A,H_DAT0 ;源数值低位装载到累加器A中 MOV R6,A ;备份源数值低位到寄存器R6中 CLR C ;清0进位位C SUBB A,#100 ;减去100 MOV H_DAT0,A ;存回余数低位 MOV A,H_DAT1 ;取源数值高位 SUBB A,#00H ;减100的高位0,实际上是减去借位位 MOV H_DAT1,A ;存回余数高位 JC H10 ;有借位则跳到下一步继续运算 INC D_DAT3 ;没有借位,百位增1 AJMP H100 ;没有借位继续减 ;注意本轮循环中最后一次减时百位未增1 ;所以不存在还原的问题 ;进入下一轮时,源数值(余数)都在R6中 CLR C MOV A,R6 ;源数值(低位)装载到累加器A中 ;到此源数值高位已经为0,不用再参加计算 MOV D_DAT5,A ;存回源数值低位 ;如果是最后一次减,则此值即为个位 SUBB A,#10 ;减去10 MOV R6,A ;保存余数 JC H1 ;有借位,运算结束 INC D_DAT4 ;没有借位,十位增1 LJMP H10 ;没有借位继续减 RET ;子程序返回 END 28

实验7 A/D转换器件TLC1543的应用 AD_ADDR EQU 21H

AD_DAT0 EQU 64H

AD_DAT1 EQU 65H

D_DAT0 EQU 6AH

D_DAT1 EQU 6BH

D_DAT2 EQU 6CH

D_DAT3 EQU 6DH

D_DAT4 EQU 6EH

D_DAT5 EQU 6FH ;定义显示数据单元

D_DAT6 EQU 70H

ORG 0000H

AJMP START

ORG 0030H

START:MOV SP,#30H ;初始化堆栈指针

MOV D_DAT0,#0

MOV D_DAT1,#0

MOV D_DAT2,#0

MOV D_DAT3,#0

MOV D_DAT4,#0

MOV D_DAT5,#0 ;初始化显示数据

MOV P0,#0

CLR P1.1 ;初始化有关I/O口

CLR P1.2

MOV R0,#D_DAT0 ;初始化显示指针寄存器

;R0指向第一位显示数字

MOV R1,#01H ;初始化需点亮数码管位置代码

NOP

MAIN:MOV SP,#30H

CLR P3.4

CLR P3.5

CLR P3.6

MOV AD_ADDR,#1 ;选择通道0

LCALL AD_C

MOV R3,#255

DLY: LCALL DISP ;调用数码管循环点亮子程序 LCALL DELAY ;延时子程序同前,应修改延时长度 DJNZ R3,DLY

AJMP MAIN ;循环执行主程序

LOOP: NOP

AJMP LOOP

;A/D转换子程序

29

AD_C: CLR P3.6 ;片选信号/CS有效

MOV A,#00H

MOV C,0BH

MOV P3.4,C ;第一个地址信号(最高位)

;注意此处08H为位地址 SETB P3.5

;第一个时钟信号

MOV C,P3.3 ;取第一位数据(最高位MSB) RLC A

CLR P3.5

MOV C,0AH

MOV P3.4,C ;第二个地址信号

SETB P3.5

;第二个时钟信号

MOV C,P3.3

RLC A

CLR P3.5

MOV AD_DAT1,A ;存最高两位数据

MOV A,#00H

MOV C,09H

MOV P3.4,C ;第三个地址信号

SETB P3.5

;第三个时钟信号

MOV C,P3.3 ;取第三位数据

RLC A

CLR P3.5

MOV C,08H

MOV P3.4,C ;第四个地址信号

SETB P3.5

;第四个时钟信号

MOV C,P3.3

RLC A

CLR P3.5

CLR P3.4 ;以下地址信号一直为0,无效

SETB P3.5

;第五个时钟信号

MOV C,P3.3

RLC A

CLR P3.5

SETB P3.5

;第六个时钟信号

MOV C,P3.3

RLC A

CLR P3.5

30

SETB P3.5

;第七个时钟信号

MOV C,P3.3

RLC A

CLR P3.5

SETB P3.5

;第八个时钟信号

MOV C,P3.3

RLC A

CLR P3.5

SETB P3.5

;第九个时钟信号

MOV C,P3.3

RLC A

CLR P3.5

SETB P3.5

;第十个时钟信号

MOV C,P3.3

RLC A

CLR P3.5

MOV AD_DAT0,A ;存低8位数据

SETB P3.6 ;传送数据完成,使片选信号/CS无效 RET

DISP:MOV A,AD_DAT0

MOV B,#100B

DIV AB

MOV D_DAT0,B

MOV D_DAT6,A

MOV A,AD_DAT1

MOV B,#1000000B

MUL AB

ADD A,D_DAT6

MOV B,#110011B

DIV AB

MOV D_DAT1,A

MOV A,#100B

MUL AB

ADD A,D_DAT0

MOV B,#14H

DIV AB

MOV D_DAT2,A

MOV A,B

MOV B,#02H

DIV AB

31

MOV D_DAT3,A

MOV D_DAT4,B

MOV D_DAT0,#0

MOV A,R1 ;取位代码

MOV P0,A ;位代码送P0口

CJNE A,#02H,WXSD

XSD: SETB P1.2

NOP

CLR P1.2 ;产生一个锁存脉冲,锁存位代码

MOV A,@R0 ;取需显示的数字

MOV DPTR,#DISPD1

AJMP OK ;装载笔画编码表首地址

WXSD: SETB P1.2

NOP

CLR P1.2 ;产生一个锁存脉冲,锁存位代码

MOV A,@R0 ;取需显示的数字

MOV DPTR,#DISPD

OK: MOVC A,@A+DPTR ;取需显示数字笔画代码

MOV P0,A ;笔画代码送到P0口

SETB P1.1

NOP

CLR P1.1 ;产生一个锁存脉冲,锁存笔画代码

INC R0 ;R0增1指向下一个需显示数字

MOV A,R1

CLR C

RLC A

MOV R1,A ;R1中的值左移1位,指向下一位数码管

CJNE R0,#70H,DISP1 ;R0中不为70H则继续

MOV R0,#D_DAT0 ;R0中为70H,循环完一轮

;重新赋初值

MOV R1,#1 ;位置代码初值

DISP1: NOP

RET

;数字笔画代码表

; 0 1 2 3 4 5 6 7 8 9 熄 DISPD: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,0

DISPD1: DB 0BFH,86H,0DBH,0CFH,0E6H,0EDH,0FDH,87H,0FFH,0EFH,80H ;**********************************************

;延时子程序

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

DELAY: MOV R7,#40H

DELY1: MOV R6,#0FH

DELY2: DJNZ R6,$ ;$代表当前行

;与DJNZ R6,DELY2相同

32

DJNZ RET END R7,DELY1 33

实验8 D/A转换器件TLV5617的应用 三角波参考程序:

DATA_AL EQU 60H

DATA_AH EQU 61H

DATA_BL EQU 62H

DATA_BH EQU 63H

DA_IN EQU P3.4

DA_CLK EQU P3.5

DA_CS EQU P3.7

ORG 0000H

AJMP START

ORG 0030H

START: MOV SP,#30H

SETB DA_CS

CLR DA_CLK

CLR DA_IN

MOV DATA_AL,#0H

MOV DATA_AH,#0

MOV DATA_BL,#0H

MOV DATA_BH,#0

LCALL DA_C

MOV R5,#0

MOV 70H,#0

MOV 71H,#0

LOOP1: CLR C

INC 70H

MOV A,70H

JNZ HEAR

SETB C

HEAR: MOV A,#0

ADDC A,71H

CLR C

MOV 71H,A

MOV DATA_AL,70H

MOV DATA_Ah,71H

LCALL DA_C

MOV R5,DATA_AH

CJNE R5,#3,LOOP1

MOV 70H,#0

MOV 71H,#0

34

AJMP LOOP1

;D/A转换子程序

DA_C: MOV R2,#2

CH1: CLR C

MOV A,DATA_AL

RLC A

MOV DATA_AL,A

MOV A,DATA_AH

RLC A

MOV DATA_AH,A

DJNZ R2,CH1 ;以上将数据A左移2位后存回 MOV R2,#2

CH2: CLR C

MOV A,DATA_BL

RLC A

MOV DATA_BL,A

MOV A,DATA_BH

RLC A

MOV DATA_BH,A

DJNZ R2,CH2 ;以上将数据B左移2位后存回

CLR DA_CS ;片选信号有效,开始写数据B MOV R2,#8

MOV A,DATA_BH

ORL A,#10H ;R1R0=01,写数据B到缓冲寄存器 SBYTE1: SETB DA_CLK

RLC A

MOV DA_IN,C ;移1位数据到DI引脚 NOP

CLR DA_CLK ;产生一个串行时钟CLK

DJNZ R2,SBYTE1 ;以上写高8位

MOV R2,#8

MOV A,DATA_BL

SBYTE2: SETB DA_CLK

RLC A

MOV DA_IN,C

NOP

CLR DA_CLK

DJNZ R2,SBYTE2 ;以上写低8位

SETB DA_CLK

NOP

CLR DA_CLK ;最后再产生一个时钟

35

SETB DA_CS ;写完数据B,片选无效

MOV R2,#8

MOV A,DATA_AH

ORL A,#80H ;R1R0=10,写数据到DAC A寄存器 ;并且用缓冲寄存器内容更新DAC B寄存器 CLR DA_CS ;片选信号有效,开始写数据A NOP

SBYTE3: SETB DA_CLK

RLC A

MOV DA_IN,C

NOP

CLR DA_CLK

DJNZ R2,SBYTE3

MOV R2,#8

MOV A,DATA_AL

SBYTE4: SETB DA_CLK

RLC A

MOV DA_IN,C

NOP

CLR DA_CLK

DJNZ R2,SBYTE4

SETB DA_CLK

NOP

CLR DA_CLK ;最后再产生一个时钟

SETB DA_CS ;数据A写完,片选无效

RET

DELAY: MOV R7,#80H

DELY1: MOV R6,#0FFH

DELY2: DJNZ R6,$ ;$代表当前行

;与DJNZ R6,DELY2相同

DJNZ R7,DELY1

RET

END

36

方波参考程序1: DATA_AL EQU 60H DATA_AH EQU 61H DATA_BL EQU 62H DATA_BH EQU 63H

DA_IN EQU P3.4 DA_CLK EQU P3.5 DA_CS EQU P3.7

ORG 0000H AJMP START ORG 0030H

START: MOV DATA_AL,#00H MOV DATA_AH,#0 MOV DATA_BL,#80H MOV DATA_BH,#1 MOV SP,#30H

SETB DA_CS CLR DA_CLK CLR DA_IN

LCALL DA_C LCALL DELAY NOP

;MOV SP,#30H CLR DA_CLK CLR DA_IN

MOV DATA_AL,#0FFH MOV DATA_AH,#0 MOV DATA_BL,#80H MOV DATA_BH,#1 LCALL DA_C LCALL DELAY NOP

AJMP START

;D/A转换子程序

DA_C: MOV R2,#2 CH1: CLR C 37

MOV A,DATA_AL

RLC A

MOV DATA_AL,A

MOV A,DATA_AH

RLC A

MOV DATA_AH,A

DJNZ R2,CH1 ;以上将数据A左移2位后存回 MOV R2,#2

CH2: CLR C

MOV A,DATA_BL

RLC A

MOV DATA_BL,A

MOV A,DATA_BH

RLC A

MOV DATA_BH,A

DJNZ R2,CH2 ;以上将数据B左移2位后存回

CLR DA_CS ;片选信号有效,开始写数据B MOV R2,#8

MOV A,DATA_BH

ORL A,#10H ;R1R0=01,写数据B到缓冲寄存器 SBYTE1: SETB DA_CLK

RLC A

MOV DA_IN,C ;移1位数据到DI引脚

NOP

CLR DA_CLK ;产生一个串行时钟CLK

DJNZ R2,SBYTE1 ;以上写高8位

MOV R2,#8

MOV A,DATA_BL

SBYTE2: SETB DA_CLK

RLC A

MOV DA_IN,C

NOP

CLR DA_CLK

DJNZ R2,SBYTE2 ;以上写低8位

SETB DA_CLK

NOP

CLR DA_CLK ;最后再产生一个时钟

SETB DA_CS ;写完数据B,片选无效

MOV R2,#8

MOV A,DATA_AH

ORL A,#80H ;R1R0=10,写数据到DAC A寄存器 ;并且用缓冲寄存器内容更新DAC B寄存器 38

CLR DA_CS ;片选信号有效,开始写数据A NOP

SBYTE3: SETB DA_CLK

RLC A

MOV DA_IN,C

NOP

CLR DA_CLK

DJNZ R2,SBYTE3

MOV R2,#8

MOV A,DATA_AL

SBYTE4: SETB DA_CLK

RLC A

MOV DA_IN,C

NOP

CLR DA_CLK

DJNZ R2,SBYTE4

SETB DA_CLK

NOP

CLR DA_CLK ;最后再产生一个时钟

SETB DA_CS ;数据A写完,片选无效 RET

DELAY: MOV R7,#0FFH

DELY1: MOV R6,#0FFH

DELY2: DJNZ R6,$ ;$代表当前行

;与DJNZ R6,DELY2相同

DJNZ R7,DELY1

RET

END

方波参考程序2:

DATA_AL

DATA_AH

DATA_BL

DATA_BH

DA_IN

DA_CLK

DA_CS

EQU 60H EQU 61H EQU 62H EQU 63H EQU EQU EQU P3.4 P3.5 P3.7 39

ORG 0000H

AJMP START

ORG 0030H

START: MOV SP,#30H

SETB DA_CS

CLR DA_CLK

CLR DA_IN

MOV DATA_AL,#0FFH

MOV DATA_AH,#0

MOV DATA_BL,#0FFH

MOV DATA_BH,#1

LCALL DA_C

LCALL DELAY

SETB DA_CS

CLR DA_CLK

CLR DA_IN

MOV DATA_AL,#00H

MOV DATA_AH,#0

MOV DATA_BL,#00H

MOV DATA_BH,#1

LCALL DA_C

LCALL DELAY

LOOP: NOP

AJMP START

;D/A转换子程序

DA_C: MOV R2,#2

CH1: CLR C

MOV A,DATA_AL

RLC A

MOV DATA_AL,A

MOV A,DATA_AH

RLC A

MOV DATA_AH,A

DJNZ R2,CH1 ;以上将数据A左移2位后存回 MOV R2,#2

CH2: CLR C

MOV A,DATA_BL

RLC A

MOV DATA_BL,A

MOV A,DATA_BH

RLC A

MOV DATA_BH,A

DJNZ R2,CH2 ;以上将数据B左移2位后存回 40

CLR DA_CS ;片选信号有效,开始写数据B MOV R2,#8

MOV A,DATA_BH

ORL A,#10H ;R1R0=01,写数据B到缓冲寄存器 SBYTE1: SETB DA_CLK

RLC A

MOV DA_IN,C ;移1位数据到DI引脚

NOP

CLR DA_CLK ;产生一个串行时钟CLK

DJNZ R2,SBYTE1

;LCALL DELAY

;以上写高8位

MOV R2,#8

MOV A,DATA_BL

SBYTE2: SETB DA_CLK

RLC A

MOV DA_IN,C

NOP

CLR DA_CLK

DJNZ R2,SBYTE2 ;以上写低8位

SETB DA_CLK

NOP

CLR DA_CLK ;最后再产生一个时钟

SETB DA_CS ;写完数据B,片选无效

MOV R2,#8

MOV A,DATA_AH

ORL A,#80H ;R1R0=10,写数据到DAC A寄存器 ;并且用缓冲寄存器内容更新DAC B寄存器 CLR DA_CS ;片选信号有效,开始写数据A NOP

SBYTE3: SETB DA_CLK

RLC A

MOV DA_IN,C

NOP

CLR DA_CLK

DJNZ R2,SBYTE3

MOV R2,#8

MOV A,DATA_AL

SBYTE4: SETB DA_CLK

RLC A

MOV DA_IN,C

NOP

41

CLR DA_CLK DJNZ R2,SBYTE4 SETB DA_CLK NOP CLR DA_CLK ;最后再产生一个时钟 SETB DA_CS ;数据A写完,片选无效 RET

DELAY: MOV R7,#0FFH

DELAY1:MOV R6,#0FFH

DELAY2:DJNZ R6,$

DJNZ R7,DELAY1

RET

END

正弦波参考程序:

DATA_AL EQU 60H

DATA_AH EQU 61H

DATA_BL EQU 62H

DATA_BH EQU 63H

DA_IN EQU P3.4

DA_CLK EQU P3.5

DA_CS EQU P3.7

ORG 0000H

AJMP START

ORG 0030H

START: MOV SP,#30H

SETB DA_CS

CLR DA_CLK

CLR DA_IN

MOV DATA_AL,#00H

MOV DATA_AH,#0

MOV DATA_BL,#00H

MOV DATA_BH,#0

MOV DPTR,#DISPD

MOV R1,#0

DAC1: LCALL DA_C

AJMP CHANGE

LOOP: NOP

LCALL LOOP

CHANGE: MOV A,R1

42

MOVC A,@A+DPTR

MOV DATA_AL,A

MOV DATA_BL,A

MOV DATA_AH,#0

MOV DATA_BH,#0

INC R1

CJNE R1,#100,DAC1

MOV R1,#0

AJMP DAC1

;D/A转换子程序

DA_C: MOV R2,#2

CH1: CLR C

MOV A,DATA_AL

RLC A

MOV DATA_AL,A

MOV A,DATA_AH

RLC A

MOV DATA_AH,A

DJNZ R2,CH1 ;以上将数据A左移2位后存回 MOV R2,#2

CH2: CLR C

MOV A,DATA_BL

RLC A

MOV DATA_BL,A

MOV A,DATA_BH

RLC A

MOV DATA_BH,A

DJNZ R2,CH2 ;以上将数据B左移2位后存回 CLR DA_CS ;片选信号有效,开始写数据B MOV R2,#8

MOV A,DATA_BH SBYTE1: SETB DA_CLK

RLC A

MOV DA_IN,C ;移1位数据到DI引脚 NOP

CLR DA_CLK ;产生一个串行时钟CLK DJNZ R2,SBYTE1 ;以上写高8位

MOV R2,#8

MOV A,DATA_BL

SBYTE2: SETB DA_CLK

RLC A

MOV DA_IN,C

NOP

CLR DA_CLK

43

DJNZ R2,SBYTE2 ;以上写低8位

SETB DA_CLK

NOP

CLR DA_CLK ;最后再产生一个时钟

SETB DA_CS ;写完数据B,片选无效

MOV R2,#8

MOV A,DATA_AH

ORL A,#80H ;R1R0=10,写数据到DAC A寄存器 ;并且用缓冲寄存器内容更新DAC B寄存器 CLR DA_CS ;片选信号有效,开始写数据A NOP

SBYTE3: SETB DA_CLK

RLC A

MOV DA_IN,C

NOP

CLR DA_CLK

DJNZ R2,SBYTE3

MOV R2,#8

MOV A,DATA_AL

SBYTE4: SETB DA_CLK

RLC A

MOV DA_IN,C

NOP

CLR DA_CLK

DJNZ R2,SBYTE4

SETB DA_CLK

NOP

CLR DA_CLK ;最后再产生一个时钟

SETB DA_CS ;数据A写完,片选无效

RET

DISPD:DB

DB

DB

DB

DB

DB

DB

DB

DB

DB

DB

DB

DB

100 (后面用EXCEL编写输入) 94 87 81 75 69 63 57 52 46 41 36 32 44

DB 27 DB 23 DB 19 DB 16 DB 12 DB 10 DB 7 DB 5 DB 3 DB 2 DB 1 DB 0 DB 0 DB 0 DB 1 DB 2 DB 3 DB 5 DB 7 DB 10 DB 12 DB 16 DB 19 DB 23 DB 27 DB 32 DB 36 DB 41 DB 46 DB 52 DB 57 DB 63 DB 69 DB 75 DB 81 DB 87 DB 94 DB 100 DB 106 DB 113 DB 119 DB 125 DB 131 DB 137 45

DB 143 DB 148 DB 154 DB 159 DB 164 DB 168 DB 173 DB 177 DB 181 DB 184 DB 188 DB 190 DB 193 DB 195 DB 197 DB 198 DB 199 DB 200 DB 200 DB 200 DB 199 DB 198 DB 197 DB 195 DB 193 DB 190 DB 188 DB 184 DB 181 DB 177 DB 173 DB 168 DB 164 DB 159 DB 154 DB 148 DB 143 DB 137 DB 131 DB 125 DB 119 DB 113 DB 106 END 46

实验14 指示灯的外部中断控制

实验任务:要求来一个脉冲时指示灯全亮,下一个脉冲时指示灯全熄,如此交替循环,请编程实现:

LIGHT EQU 62H

ORG 0000H

AJMP START

ORG 0003H

LJMP EXINT0

ORG 0030H

START: MOV SP,#30H

MOV P0,#0FFH

MOV LIGHT,#0FFH

SETB IT0

SETB EX0

SETB EA

MAIN: AJMP $

EXINT0: PUSH ACC

MOV A,LIGHT

CPL A

MOV LIGHT,A

MOV P0,A

POP ACC

RETI

END

47

实验任务:8个LED控制8位二进制数,灯亮表示1,灯熄表示0,用8位数记录脉冲个数

LIGHT EQU 62H

ORG 0000H

AJMP START

ORG 0003H

LJMP EXINT0

ORG 0030H

START: MOV SP,#30H

MOV P0,#0FFH

MOV LIGHT,#01H

SETB IT0

SETB EX0

SETB EA

MAIN: AJMP $

EXINT0: PUSH ACC

MOV A,LIGHT

INC A

MOV LIGHT,A

CPL A

MOV P0,A

POP ACC

RETI

END

48

实验18 定时器控制继电器 TIMC0 EQU 70H

TIMC1 EQU 71H

TIMC2 EQU 72H

TIMC3 EQU 73H

ORG 0000H

AJMP START

ORG 001BH

LJMP TIM1

ORG 0030H

START: MOV SP,#30H

MOV TMOD,#20H

MOV TL1,#6

MOV TH1,#6

SETB ET1

SETB TR1

SETB EA

MAIN: MOV A,TIMC0

CJNE A,#40,MAIN1

MOV TIMC0,#0

INC TIMC1

MOV A,TIMC1

CJNE A,#100,MAIN1

MOV TIMC1,#0

INC TIMC2

CJNE A,#20,MAIN1

MOV TIMC2,#0

CPL P1.7

MAIN1: AJMP MAIN

TIM1: PUSH PSW

PUSH ACC

LCALL DISP

INC TIMC0

POP ACC

POP PSW

RETI

49

实验任务:让LED指示灯每2分钟改编一次点亮状态,LED数码管分别显示分、秒:

TIMC0 EQU 70H

TIMC1 EQU 71H

TIMC2 EQU 72H

TIMC3 EQU 73H

D_DAT0 EQU 6AH

D_DAT1 EQU 6BH

D_DAT2 EQU 6CH

D_DAT3 EQU 6DH

D_DAT4 EQU 6EH

D_DAT5 EQU 6FH

DATA_O EQU P0

PLED1 EQU P2.0

PLED2 EQU P2.1

PLED3 EQU P2.2

PLED4 EQU P2.3

ORG 0000H

AJMP START

ORG 001BH

LJMP TIM1

ORG 0030H

START: MOV SP,#30H

MOV P1,#00H

MOV D_DAT0,#0

MOV D_DAT1,#0

MOV D_DAT2,#0

MOV D_DAT3,#0

MOV D_DAT4,#0

CLR PLED1

CLR PLED2

CLR PLED3

CLR PLED4

NOP

MOV TIMC2,#0

MOV TIMC3,#0

LCALL HTD

LCALL DISP

MOV TMOD,#20H

MOV TL1,#6

MOV TH1,#6

50

SETB ET1

SETB TR1

SETB EA

MAIN: MOV A,TIMC0

CJNE A,#40,MAIN1

MOV TIMC0,#0

INC TIMC1

MOV A,TIMC1

CJNE A,#100,MAIN1

MOV TIMC1,#0

INC TIMC2

LCALL HTD

LCALL DISP

MOV A,TIMC2

CJNE A,#60,MAIN1

MOV TIMC2,#0

INC TIMC3

LCALL HTD

LCALL DISP

MOV A,TIMC3

CJNE A,#2,MAIN1

MOV TIMC3,#0

CPL P1.7

MAIN1:AJMP MAIN

TIM1: PUSH PSW

PUSH ACC

INC TIMC0

POP ACC

POP PSW

RETI

DISP: MOV R0,#D_DAT0

MOV A,@R0 ;取需显示的数字

MOV DPTR,#DISPD ;装载笔画编码表首地址 MOVC A,@A+DPTR ;取需显示数字笔画代码 XRL A,#0FFH

MOV DATA_O,A ;笔画代码送到P0口 SETB PLED1

NOP

CLR PLED1 ;产生一个锁存脉冲,锁存笔画代码 INC R0 ;R0增1指向下一个需显示数字 MOV A,@R0 ;取需显示的数字

MOV DPTR,#DISPD ;装载笔画编码表首地址 51

MOVC A,@A+DPTR ;取需显示数字笔画代码

XRL A,#0FFH

MOV DATA_O,A ;笔画代码送到P0口

SETB PLED2

NOP

CLR PLED2 ;产生一个锁存脉冲,锁存笔画代码

INC R0 ;R0增1指向下一个需显示数字

MOV A,@R0 ;取需显示的数字

MOV DPTR,#DISPD ;装载笔画编码表首地址 MOVC A,@A+DPTR ;取需显示数字笔画代码

XRL A,#0FFH

MOV DATA_O,A ;笔画代码送到P0口

SETB PLED3

NOP

CLR PLED3 ;产生一个锁存脉冲,锁存笔画代码 INC R0 ;R0增1指向下一个需显示数字

MOV A,@R0 ;取需显示的数字

MOV DPTR,#DISPD ;装载笔画编码表首地址 MOVC A,@A+DPTR ;取需显示数字笔画代码

XRL A,#0FFH

MOV DATA_O,A ;笔画代码送到P0口

SETB PLED4

NOP

CLR PLED4 ;产生一个锁存脉冲,锁存笔画代码 RET

HTD:MOV D_DAT4,TIMC2

MOV A,D_DAT4

MOV B,#0AH

DIV AB

MOV D_DAT2,A

MOV D_DAT3,B

MOV D_DAT5,TIMC3

MOV A,D_DAT5

MOV B,#0AH

DIV AB

MOV D_DAT0,A

MOV D_DAT1,B

RET

DISPD: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,0 END

52

自行设计实验

在A类题目中选择一个完成小系统的设计

交通灯控制设计

实验任务:要求模拟交通红绿灯,用不同的灯来代表红黄绿灯,每种状态下都要在数码管上倒计时显示出离下一状态的时间。

子程序:

ORG 0000H

AJMP START

ORG 0030H

START: MOV SP,#30H

MOV P0,#0

CLR P1.0

CLR P1.1

CLR P1.2

K0: MOV A,#0FEH

MOV P0,A

SETB P1.0

NOP

CLR P1.0

MOV A,#01H

MOV P0,A

SETB P1.2

NOP

CLR P1.2

MOV R0,#09H

K1: MOV A,R0

MOV DPTR,#DISPD

MOVC A,@A+DPTR

MOV P0,A

SETB P1.1

NOP

CLR P1.1

LCALL DELAY

DJNZ R0,K1

MOV A,#0FDH

MOV P0,A

SETB P1.0

NOP

CLR P1.0

MOV R1,#05H

K2: MOV A,R1

MOV DPTR,#DISPD

53

MOVC A,@A+DPTR

MOV P0,A

SETB P1.1

NOP

CLR P1.1

LCALL DELAY

DJNZ R1,K2

MOV A,#0FBH

MOV P0,A

SETB P1.0

NOP

CLR P1.0

MOV R2,#07H

K3: MOV A,R2

MOV DPTR,#DISPD

MOVC A,@A+DPTR

MOV P0,A

SETB P1.1

NOP

CLR P1.1

LCALL DELAY

DJNZ R2,K3

LJMP K0

;数字笔画代码表

; 0 1 2 3 4 5 6 7 8 9 熄 DISPD: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,0

DELAY: MOV R7,#05H

DELY1: MOV R6,#0FFH

DELY2: MOV R5,#0FFH

DELY3: DJNZ R5,DELY3

DJNZ R6,DELY2

DJNZ R7,DELY1

RET

END

调试结果:交通红绿灯,用不同的灯来代表红黄绿灯,每种状态下都要在数码管上倒计时显示出离下一状态的时间。

54

实验总结:

通过一系列的实验,我对单片机的了解越来越多。通过实验学习,我们从中我们掌握了仿真软件、I/O口、发光二极管、数码管和按键等重要知识,。以上内容大致覆盖了单片机几个主要知识内容,是课内课程的课外拓展。可以说,这一系列的实验帮助我们对单片机不仅温习了一遍,还是我们从中得到新的认识。印证了一句古语“温故而知新,可以为师矣”。同时加深了理论知识的认识和理解,达到了理论联系实际的效果。 同时,我们也学会了设计实验的方法和步骤。在本次试验中也遇到了很多问题,比如试验箱、软件的使用等,很多东西都要从头学起,查阅了很多资料,有时也会向同学请教,收获很多。一些问题都曾一度阻碍实验的进程,好在经过长时间的思考与实验,问题都得到了解决。很多时候,解决问题关键在于有一个好的心态,而不仅是看我们过去的能力到底有多强,只要态度端正目的明确,把自己置身于具体的问题之中,不轻易放弃,学会变通,问题一定能得到很好的解决。 为了较好的完成实验,我们必须在实验前有充分的预习,要对实验要求、内容、步骤等都要有清楚的认识和正确的设计。在实验进行中,我们要正确使用仪器,认真调试。同时,在实验后,还要认真分析和思考结果,与同学交流讨论,最后具体而准确地撰写实验报告。在这些过程中,锻炼了我们的思考和动手的能力,促进我们养成做实验的好方法和习惯,同时巩固我们已学的知识,并给我们学以致用的机会。另外通过本次实验设计,增强了学习兴趣,考验了收集、分析、组织材料的能力,锻炼了思维能力,提高了学术素养。

我们不仅要学好学校里所学到的知识,还要不断从生活中,实践中学其他知识,不断地从各方面武装自已,才能在竞争中突出自已,表现自已。在这次实践中,我感受很深的一点是,在学校理论的学习很多,而且是多方面的,几乎是面面俱到;而在实际工作中,可能会遇到书本上没学到的,又可能是书本上的知识一点都用不上的情况。

总而言之,在单片机实验过程中受益匪浅,不仅巩固了以前学习过的知识,还学习到了新知识,而且学以致用,将所学知识转化成了实际应用。

saodaxia版权所有。

55

56

更多相关推荐:
单片机实验报告(基于51单片机)

滨江学院微机原理与接口技术综合实验报告题目:简易电子琴设计学号:学生姓名:XXX院系:滨江学院专业:指导教师:二OXX年月日【摘要】由于音乐是许多不同的音阶组成的,而每个音阶对应着不同的频率,这样我们就可以利用…

51单片机课程设计实验报告

51单片机课程设计报告学院:专业班级:姓名:指导教师:设计时间:51单片机课程设计一、设计任务与要求1.任务:制作并调试51单片机学习板2.要求:(1)了解并能识别学习板上的各种元器件,会读元器件标示;(2)会…

51单片机实验报告

08424020xx单片微型计算机原理学院班级学号姓名指导教师成绩120xx年6月08424020xx硬件实验实验一定时器中断实验实验内容fosc110592MHzT0方式2产生定时中断实现秒表功能数码管后两位...

51单片机实验报告

08424020xx硬件实验实验一定时器中断实验实验内容fosc110592MHzT0方式2产生定时中断实现秒表功能数码管后两位显示10ms前两位显示秒数K1K2K3键分别启动停止清零按键操作不分先后实验程序流...

80C51单片机-实验报告

班级姓名学号单片机实验报告实验一CPU片内外清零1CPU片内RAM清零一实验目的掌握MCS51汇编语言的设计了解单片机的寻址方式以及调试方法二实验内容把单片机片内的30H7FH单元清零三实验框图四实验步骤用连续...

MCS51单片机原理及应用 实验报告

单片机原理与应用实验报告学校合肥工业大学姓名吕增威学号20xx2606班级计算机科学与技术0803班1目录前言3第一章MC51单片机原理及应用软件实验实验1系统认识实验6实验6数据排序实验验证性11第二章MC5...

李佛垚51单片机实验报告

实验报告实验名称矩阵键盘控制点阵的显示专业班级控制科学与工程学号s20xx0394学生姓名指导教师李晓林李丽宏牛昱光20xx年1月18日矩阵键盘控制点阵显示实验报告目录一实验目的1二实验内容1一扫描矩阵键盘读出...

华中科技大学单片机实验实验报告MCS51单片机

华中科技大学单片机实验报告MCS51系列单片机单片机原理及应用实验根据20xx年电气与电子工程学院单片机实验课程改编专业电气工程及其自动化班级气卓1301姓名廖鹏毅学号ALLRIGHTRESERVED1目录实验...

实验一 51单片机流水灯实验 实验报告

流水灯实验报告一实验目的1了解单片机IO口的工作原理2掌握51单片机的汇编指令3熟悉汇编程序开发调试以及仿真环境二实验内容通过汇编指令对单片机IO进行编程本实验使用P0口以控制八个发光二极管以一定顺序亮灭即流水...

51单片机综合实验交通灯设计报告

51单片机综合实验交通灯设计报告班级学生姓名学号指导教师一实验题目交通灯控制系统设计二实验目的1学会用8051单片机开发简单的计算机控制系统2学会用汇编语言和C语言开发系统软件3学会8051单片机开发环境wav...

基于51单片机的步进电机控制系统-单片机课程设计报告

微机原理与接口技术课程设计报告基于51单片机的步进电机控制系统学号姓名班级20xx级电子2班华侨大学电子工程系摘要步进电机是将电脉冲信号变换成角位移或直线位移的执行部件步进电机可以直接用数字信号驱动使用非常方便...

51单片机秒表实验报告

江西理工大学应用科学学院信息工程系单片机原理与应用课程设计报告设计题目基于51单片机的秒表设计专业电子信息工程班级电信121学号08060312109参与人员贺佳周代元周昶旭张浥中指导老师王苏敏完成日期20xx...

51单片机实验报告(27篇)