华中科技大学单片机实验报告
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
滨江学院微机原理与接口技术综合实验报告题目:简易电子琴设计学号:学生姓名:XXX院系:滨江学院专业:指导教师:二OXX年月日【摘要…
51单片机课程设计报告学院:专业班级:姓名:指导教师:设计时间:51单片机课程设计一、设计任务与要求1.任务:制作并调试51单片机…
08424020xx单片微型计算机原理学院班级学号姓名指导教师成绩120xx年6月08424020xx硬件实验实验一定时器中断实验…
08424020xx硬件实验实验一定时器中断实验实验内容fosc110592MHzT0方式2产生定时中断实现秒表功能数码管后两位显…
班级姓名学号单片机实验报告实验一CPU片内外清零1CPU片内RAM清零一实验目的掌握MCS51汇编语言的设计了解单片机的寻址方式以…
福建农林大学计算机与信息学院信息工程类实验报告课程名称:单片机技术姓名:系:电子信息工程系专业:电子信息工程年级:学号:指导教师:…
HEFEIUNIVERSITY单片机实验报告系别电子信息与电气工程系专业班级学号姓名指导老师完成时间实验一构建单片机最小系统和实验…
1福建农林大学计算机与信息学院信息工程类实验报告课程名称姓名系专业年级学号指导教师职称单片机技术詹缓辉电子信息工程系电子信息工程2…
实验课程名称自动控制综合实验2》姓名学院自动化学院专业班级学号、班内序号指导教师20##年月单片机部分一、仿真软件的使用以及跑马灯…
单片机实验报告报告人xxx学号20xx211812班号20xx211407指导老师姚燕20xx0615实验一仿真软件的使用以及跑马…
单片机原理实验报告实验一熟悉μ’nSP?IDE集成开发环境下C语言程序的编写【实验目的】1.熟悉μ’nSP?IDE集成开发环境的使…