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

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

华中科技大学单片机实验报告
MCS-51系列单片机
(单片机原理及应用实验)
(根据2014年电气与电子工程学院单片机实验课程改编)
专业:电气工程及其自动化
班级:气卓1301
姓名:廖鹏毅
学号:
ALL RIGHT RESERVED
目录
实验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)
实验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_DA T0,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.1.4示例程序
含主程序
十六进制数转换为十进制数子程序双字节乘法运算子程序
三字节数除双字节数运算子程序D_DA T0 EQU 50H
D_DA T1 EQU D_DA T0+1
D_DA T2 EQU D_DA T1+1
D_DA T3 EQU D_DA T2+1
H_DA T0 EQU D_DA T3+1
H_DA T1 EQU H_DA T0+1
ODIV_L EQU H_DA T1+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_DA T1,#2
MOV H_DA T0,#0
LCALL HTD
;在此处给有关变量单元赋值
LCALL TMUL
;在此处给有关变量单元赋值
LCALL SDIV
LOOP: NOP
AJMP LOOP
HTD: MOV D_DA T3,#00H ;将结果千位清0
MOV D_DA T2,#00H
MOV D_DA T1,#00H
MOV D_DA T0,#00H
;以上将各位结果存储单元清0
H1000: CLR C;进位位C清0
MOV A,H_DA T0 ;源数据低位装载到累加器A中
MOV R6,A ;备份源数值低位到寄存器R6中
SUBB A,#0E8H ;源数值低位减去1000的低位0E8H
MOV H_DA T0,A ;余数存回到源数值低位存储单元
MOV A,H_DA T1 ;源数值高位装载到累加器A中
MOV R7,A ;备份源数值高位到寄存器R7中
SUBB A,#03H ;源数值高位带借位减1000的高位03H
MOV H_DA T1,A ;余数存回到源数值低位存储单元
INC D_DA T3 ;千位增1
JNC H1000 ;如果没有借位则利用余数循环再减
;有借位表明为最后一次无效减
;程序顺序执行,应还原最后一次修改值
MOV H_DA T0,R6
MOV H_DA T1,R7 ;用备份值作为新的源数值(余数)
DEC D_DA T3 ;千位数减1,去掉最后一次无效减的影响H100: MOV A,H_DA T0 ;源数值低位装载到累加器A中MOV R6,A ;备份源数值低位到寄存器R6中
CLR C;清0进位位C
SUBB A,#100 ;减去100
MOV H_DA T0,A ;存回余数低位
MOV A,H_DA T1 ;取源数值高位
SUBB A,#00H ;减100的高位0,实际上是减去借位位
MOV H_DA T1,A ;存回余数高位
JC H10 ;有借位则跳到下一步继续运算
INC D_DA T2 ;没有借位,百位增1
AJMP H100 ;没有借位继续减
;注意本轮循环中最后一次减时百位未增1
;所以不存在还原的问题
;进入下一轮时,源数值(余数)都在R6中
H10: CLR C
MOV A,R6 ;源数值(低位)装载到累加器A中
;到此源数值高位已经为0,不用再参加计算MOV D_DA T0,A ;存回源数值低位
;如果是最后一次减,则此值即为个位
SUBB A,#10 ;减去10
MOV R6,A ;保存余数
JC H1 ;有借位,运算结束
INC D_DA T1 ;没有借位,十位增1
LJMP H10 ;没有借位继续减
H1: RET ;子程序返回
TMUL: 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
LAST: 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
SDIV: MOV R0,#00H
MOV R1,#00H ;清0过渡单元
MOV R2,#24 ;因被除数有三个字节(24位),所以循环24次
SDIV0: CLR C;清0进位位C
MOV A,ODIV_L ;(ODIV_L)→A
RLC A;A中的值带进位位C左移1位
MOV ODIV_L,A ;(A)→ODIV_L,移位后存回
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 ;有借位,不够减,用备份值取代差值,即不减SDIV1: 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
实验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 S IO
CLR S CLK
CLR S RCLK
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 S CLK ;产生一个移位脉冲
SETB SRCLK
NOP
CLR S RCLK ;产生一个输出锁存脉冲
CJNE A,#0,FL YCON ;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,DEL Y2相同DJNZ R7,DEL Y1
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 ;死循环
;******************************************************
;通过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,FL YCON ;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,DEL Y2相同
DJNZ R7,DEL Y1
RET
END
实验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口的使用,掌握串行和并行的区别和使用,以及数码管的原理和使用
附:参考程序
LED-S-P数码管显示功能的实现(并行动态显示参考程序1)
D_DA T0 EQU 6AH
D_DA T1 EQU 6BH
D_DA T2 EQU 6CH
D_DA T3 EQU 6DH
D_DA T4 EQU 6EH
D_DA T5 EQU 6FH ;定义显示数据存储单元
DA TA_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_DA T0,#0
MOV D_DA T1,#1
MOV D_DA T2,#2
MOV D_DA T3,#3
MOV D_DA T4,#4
MOV D_DA T5,#5 ;初始化显示数据
CLR P LED1
CLR P LED2
CLR P LED3
CLR P LED4
NOP
MAIN: LCALL DISP ;调用数码管循环点亮子程序
LOOP: AJMP LOOP ;循环执行主程序
;******************************************************
;通过574显示6位数字子程序
;***************************************************** 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 P LED1 ;产生一个锁存脉冲,锁存笔画代码
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 P LED2 ;产生一个锁存脉冲,锁存笔画代码
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 P LED3 ;产生一个锁存脉冲,锁存笔画代码
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 P LED4 ;产生一个锁存脉冲,锁存笔画代码
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
并行动态显示参考程序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 S IO
CLR S CLK
CLR S RCLK
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 S CLK ;产生一个移位脉冲
SETB SRCLK
NOP
CLR S RCLK ;产生一个输出锁存脉冲
CJNE A,#0,FL YCON ;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,DEL Y2相同
DJNZ R7,DEL Y1
RET
END
并行动态显示参考程序3:
D_DA T0 EQU 6AH
D_DA T1 EQU 6BH
D_DA T2 EQU 6CH
D_DA T3 EQU 6DH
D_DA T4 EQU 6EH
D_DA T5 EQU 6FH ;定义显示数据单元
D_DA T6 EQU 70H
ORG 0000H
AJMP START
ORG 0030H
START: MOV SP,#30H ;初始化堆栈指针
MOV D_DA T0,#0
MOV D_DA T1,#1
MOV D_DA T2,#2
MOV D_DA T3,#3
MOV D_DA T4,#4
MOV D_DA T5,#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 ;循环执行主程序
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,DEL Y2相同
DJNZ R7,DELY1
RET
END
串行动态显示参考程序1:
D_DA T0 EQU 6AH
D_DA T1 EQU 6BH
D_DA T2 EQU 6CH
D_DA T3 EQU 6DH
D_DA T4 EQU 6EH
D_DA T5 EQU 6FH ;定义显示数据单元
D_DA T6 EQU 70H
ORG 0000H
AJMP START
ORG 0030H
START: MOV SP,#30H ;初始化堆栈指针
MOV D_DA T0,#0
MOV D_DA T1,#1
MOV D_DA T2,#2
MOV D_DA T3,#3
MOV D_DA T4,#4
MOV D_DA T5,#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
串行动态显示参考程序2:(本程序实验时来不及执行,不知是否正确)
D_DA T0 EQU 6AH
D_DA T1 EQU 6BH
D_DA T2 EQU 6CH
D_DA T3 EQU 6DH
D_DA T4 EQU 6EH
D_DA T5 EQU 6FH ;定义显示数据单元
D_DA T6 EQU 70H
ORG 0000H
AJMP START
ORG 0030H
START: MOV SP,#30H ;初始化堆栈指针
MOV D_DA T0,#0
MOV D_DA T1,#1
MOV D_DA T2,#2
MOV D_DA T3,#3 ;初始化显示数据
MOV D_DA T4,#4
MOV D_DA T5,#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 ;产生一个输入锁存脉冲
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,DEL Y2相同
DJNZ R7,DEL Y1
RET
END
实验任务:要让低次位LED数码管显示中总带有小数点,即显示的六位数值中总带有一位小数,请编程实现:
D_DA T0 EQU 6AH
D_DA T1 EQU 6BH
D_DA T2 EQU 6CH
D_DA T3 EQU 6DH
D_DA T4 EQU 6EH
D_DA T5 EQU 6FH ;定义显示数据单元
D_DA T6 EQU 70H
ORG 0000H
AJMP START
ORG 0030H
START: MOV SP,#30H ;初始化堆栈指针
MOV D_DA T0,#0
MOV D_DA T1,#1
MOV D_DA T2,#2
MOV D_DA T3,#3
MOV D_DA T4,#4
MOV D_DA T5,#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
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则继续
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,DEL Y2相同
DJNZ R7,DEL Y1
RET
END
实验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
NOP
CLR P1.1
LCALL DELAY
LJMP START
调试结果:4位按键分别操控四个数码管显示四个不同的数字
五实验小结
进一步了解I/O口和数码管使用和原理,掌握按键的使用和原理
附:示例程序
KEYUSE按键功能的实现
D_DA T0 EQU 60H
D_DA T1 EQU D_DA T0+1
D_DA T2 EQU D_DA T1+1
D_DA T3 EQU D_DA T2+1
D_DA T4 EQU D_DA T3+1
D_DA T5 EQU D_DA T4+1 ;定义显示数据单元LIGHT EQU D_DA T5+1
H_DA T0 EQU LIGHT+1
H_DA T1 EQU H_DA T0+1
KBM EQU H_DA T1+1 ;定义按键功能号存放单元
D_MAX EQU KBM+1 ;定义上限值存放单元
D_MIN EQU D_MAX+1 ;定义下限值存放单元
T_DA T0 EQU D_MIN+1
T_DA T1 EQU T_DA T0+1 ;定义测量值存放单元ORG 0000H
AJMP START
ORG 0030H
START: MOV SP,#30H ;初始化堆栈指针
MOV D_DA T0,#0
MOV D_DA T1,#0
MOV D_DA T2,#0
MOV D_DA T3,#0
MOV D_DA T4,#0
MOV D_DA T5,#0 ;初始化显示数据
MOV LIGHT,#80H
CLR P1.0
CLR P1.1
CLR P1.2
CLR P1.3 ;初始化有关I/O口
MOV R0,#D_DAT0 ;初始化数据指针
;R0指向第一位显示数字
MOV R1,#01H ;初始化需点亮数码管位置代码
MOV KBM,#0 ;初始化功能号
MOV D_MAX,#80
MOV D_MIN,#70 ;初始化上、下限值
MOV T_DA T0,#66
MOV T_DA T1,#0 ;目前人为赋给测量值一个值
;将来有实际测量值就存放在此
MOV H_DA T0,T_DA T0
MOV H_DA T1,T_DA T1
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
AJMP KEND
KEY21: CJNE A,#2,KEND
DEC D_MIN ;功能号2,下限值减1
KEND: NOP ;以下程序根据功能号显示不同内容MOV A,KBM
CJNE A,#0,KEND1
MOV H_DA T0,T_DA T0
MOV H_DA T1,T_DA T1 ;功能号0,准备显示测量数据
MOV LIGHT,#0BFH ;点亮相应指示灯
AJMP KEND3 ;跳转到刷新显示处
KEND1: NOP
CJNE A,#1,KEND2
MOV H_DA T0,D_MAX
MOV H_DA T1,#0 ;功能号1,准备显示上限值
MOV LIGHT,#7FH ;点亮相应指示灯
AJMP KEND3 ;跳转到刷新显示处
KEND2: NOP
CJNE A,#2,KEND3
MOV H_DA T0,D_MIN
MOV H_DA T1,#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位有用
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,DEL Y2相同
DJNZ R7,DEL Y1
RET;二进制转换十进制子程序
HTD: MOV D_DA T5,#00H ;将结果千位清0
MOV D_DA T4,#00H
MOV D_DA T3,#00H
MOV D_DA T2,#00H
;以上将各位结果存储单元清0
H1000: CLR C;进位位C清0
MOV A,H_DA T0 ;源数据低位装载到累加器A中
MOV R6,A ;备份源数值低位到寄存器R6中
SUBB A,#0E8H ;源数值低位减去1000的低位0E8H
MOV H_DA T0,A ;余数存回到源数值低位存储单元
MOV A,H_DA T1 ;源数值高位装载到累加器A中
MOV R7,A ;备份源数值高位到寄存器R7中
SUBB A,#03H ;源数值高位带借位减1000的高位03H
MOV H_DA T1,A ;余数存回到源数值低位存储单元
INC D_DA T2 ;千位增1
JNC H1000 ;如果没有借位则利用余数循环再减
;有借位表明为最后一次无效减
;程序顺序执行,应还原最后一次修改值
MOV H_DA T0,R6
MOV H_DA T1,R7 ;用备份值作为新的源数值(余数)
DEC D_DA T2 ;千位数减1,去掉最后一次无效减的影响H100: MOV A,H_DA T0 ;源数值低位装载到累加器A中MOV R6,A ;备份源数值低位到寄存器R6中
CLR C;清0进位位C
SUBB A,#100 ;减去100
MOV H_DA T0,A ;存回余数低位
MOV A,H_DA T1 ;取源数值高位
SUBB A,#00H ;减100的高位0,实际上是减去借位位
MOV H_DA T1,A ;存回余数高位
JC H10 ;有借位则跳到下一步继续运算
INC D_DA T3 ;没有借位,百位增1
AJMP H100 ;没有借位继续减
;注意本轮循环中最后一次减时百位未增1
;所以不存在还原的问题
;进入下一轮时,源数值(余数)都在R6中
H10: CLR C
MOV A,R6 ;源数值(低位)装载到累加器A中
;到此源数值高位已经为0,不用再参加计算MOV D_DA T5,A ;存回源数值低位
;如果是最后一次减,则此值即为个位
SUBB A,#10 ;减去10
MOV R6,A ;保存余数
JC H1 ;有借位,运算结束
INC D_DA T4 ;没有借位,十位增1
LJMP H10 ;没有借位继续减
H1: RET ;子程序返回
END
实验7 A/D转换器件TLC1543的应用AD_ADDR EQU 21H
AD_DAT0 EQU 64H
AD_DAT1 EQU 65H
D_DA T0 EQU 6AH
D_DA T1 EQU 6BH
D_DA T2 EQU 6CH
D_DA T3 EQU 6DH
D_DA T4 EQU 6EH
D_DA T5 EQU 6FH ;定义显示数据单元
D_DA T6 EQU 70H
ORG 0000H
AJMP START
ORG 0030H
START:MOV SP,#30H ;初始化堆栈指针
MOV D_DA T0,#0
MOV D_DA T1,#0
MOV D_DA T2,#0
MOV D_DA T3,#0
MOV D_DA T4,#0
MOV D_DA T5,#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
DL Y: LCALL DISP ;调用数码管循环点亮子程序
LCALL DELAY ;延时子程序同前,应修改延时长度
DJNZ R3,DL Y
AJMP MAIN ;循环执行主程序
LOOP: NOP
AJMP LOOP
;A/D转换子程序
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_DA T1,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
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_DA T0,A ;存低8位数据
SETB P3.6 ;传送数据完成,使片选信号/CS无效
RET
DISP:MOV A,AD_DAT0
MOV B,#100B
DIV AB
MOV D_DA T0,B
MOV D_DA T6,A
MOV A,AD_DAT1
MOV B,#1000000B
MUL AB
ADD A,D_DAT6
MOV B,#110011B
DIV AB
MOV D_DA T1,A
MOV A,#100B
MUL AB
ADD A,D_DAT0
MOV B,#14H
DIV AB
MOV D_DA T2,A
MOV A,B
MOV B,#02H
DIV AB
MOV D_DA T3,A
MOV D_DA T4,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,DEL Y2相同
DJNZ R7,DEL Y1 RET
END
实验8 D/A转换器件TLV5617的应用三角波参考程序:
DA TA_AL EQU 60H
DA TA_AH EQU 61H
DA TA_BL EQU 62H
DA TA_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 D A_CLK
CLR D A_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
AJMP LOOP1
;D/A转换子程序
DA_C: MOV R2,#2
CH1: CLR C
MOV A,DA TA_AL
RLC A
MOV DATA_AL,A
MOV A,DA TA_AH
RLC A
MOV DATA_AH,A
DJNZ R2,CH1 ;以上将数据A左移2位后存回
MOV R2,#2
CH2: CLR C
MOV A,DA TA_BL
RLC A
MOV DATA_BL,A
MOV A,DA TA_BH
RLC A
MOV DA TA_BH,A
DJNZ R2,CH2 ;以上将数据B左移2位后存回
CLR D A_CS ;片选信号有效,开始写数据B
MOV R2,#8
MOV A,DA TA_BH
ORL A,#10H ;R1R0=01,写数据B到缓冲寄存器SBYTE1: SETB DA_CLK
RLC A
MOV DA_IN,C ;移1位数据到DI引脚
NOP
CLR D A_CLK ;产生一个串行时钟CLK
DJNZ R2,SBYTE1 ;以上写高8位
MOV R2,#8
MOV A,DA TA_BL
SBYTE2: SETB DA_CLK
RLC A
MOV DA_IN,C
NOP
CLR D A_CLK
DJNZ R2,SBYTE2 ;以上写低8位
SETB DA_CLK
NOP
CLR D A_CLK ;最后再产生一个时钟
SETB DA_CS ;写完数据B,片选无效
MOV R2,#8
MOV A,DA TA_AH
ORL A,#80H ;R1R0=10,写数据到DAC A寄存器
;并且用缓冲寄存器内容更新DAC B寄存器CLR D A_CS ;片选信号有效,开始写数据A
NOP
SBYTE3: SETB DA_CLK
RLC A
MOV DA_IN,C
NOP
CLR D A_CLK
DJNZ R2,SBYTE3
MOV R2,#8
MOV A,DA TA_AL
SBYTE4: SETB DA_CLK
RLC A
MOV DA_IN,C
NOP
CLR D A_CLK
DJNZ R2,SBYTE4
SETB DA_CLK
NOP
CLR D A_CLK ;最后再产生一个时钟
SETB DA_CS ;数据A写完,片选无效
RET
DELAY: MOV R7,#80H
DELY1: MOV R6,#0FFH
DELY2: DJNZ R6,$ ;$代表当前行
;与DJNZ R6,DEL Y2相同
DJNZ R7,DEL Y1
RET
END
方波参考程序1:
DA TA_AL EQU 60H
DA TA_AH EQU 61H
DA TA_BL EQU 62H
DA TA_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 D A_CLK
CLR D A_IN
LCALL DA_C
LCALL DELAY
NOP
;MOV SP,#30H
CLR D A_CLK
CLR D A_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
MOV A,DA TA_AL
RLC A
MOV DATA_AL,A
MOV A,DA TA_AH
RLC A
MOV DATA_AH,A
DJNZ R2,CH1 ;以上将数据A左移2位后存回
MOV R2,#2
CH2: CLR C
MOV A,DA TA_BL
RLC A
MOV DATA_BL,A
MOV A,DA TA_BH
RLC A
MOV DATA_BH,A
DJNZ R2,CH2 ;以上将数据B左移2位后存回
CLR D A_CS ;片选信号有效,开始写数据B
MOV R2,#8
MOV A,DA TA_BH
ORL A,#10H ;R1R0=01,写数据B到缓冲寄存器SBYTE1: SETB DA_CLK
RLC A
MOV DA_IN,C ;移1位数据到DI引脚
NOP
CLR D A_CLK ;产生一个串行时钟CLK
DJNZ R2,SBYTE1 ;以上写高8位
MOV R2,#8
MOV A,DA TA_BL
SBYTE2: SETB DA_CLK
RLC A
MOV DA_IN,C
NOP
CLR D A_CLK
DJNZ R2,SBYTE2 ;以上写低8位
SETB DA_CLK
NOP
CLR D A_CLK ;最后再产生一个时钟
SETB DA_CS ;写完数据B,片选无效
MOV R2,#8
MOV A,DA TA_AH
ORL A,#80H ;R1R0=10,写数据到DAC A寄存器
;并且用缓冲寄存器内容更新DAC B寄存器
CLR D A_CS ;片选信号有效,开始写数据A
NOP
SBYTE3: SETB DA_CLK
RLC A
MOV DA_IN,C
NOP
CLR D A_CLK
DJNZ R2,SBYTE3
MOV R2,#8
MOV A,DA TA_AL
SBYTE4: SETB DA_CLK
RLC A
MOV DA_IN,C
NOP
CLR D A_CLK
DJNZ R2,SBYTE4
SETB DA_CLK
NOP
CLR D A_CLK ;最后再产生一个时钟
SETB DA_CS ;数据A写完,片选无效
RET
DELAY: MOV R7,#0FFH
DELY1: MOV R6,#0FFH
DELY2: DJNZ R6,$ ;$代表当前行
;与DJNZ R6,DEL Y2相同
DJNZ R7,DEL Y1
RET
END
方波参考程序2:
DA TA_AL EQU 60H
DA TA_AH EQU 61H
DA TA_BL EQU 62H
DA TA_BH EQU 63H
DA_IN EQU P3.4
DA_CLK EQU P3.5
DA_CS EQU P3.7。

相关文档
最新文档