谁能给我解释一下以下的单片机程序

这是用单片机和DAC0832产生多种波形发生器的程序同时其幅值和频率都可以改变
ORG 0000H
LJMP MAIN
ORG 0100H
MAIN: JNB P1.0,P10
JNB P1.1,P11
JNB P1.2,P12
JNB P1.3,P13
LJMP MAIN

P10: MOV R7,#00H
LCALL SQU
LJMP MAIN
P11: MOV R7,#01H
LCALL SAW
LJMP MAIN
P12: MOV R7,#02H
LCALL TRI
LJMP MAIN
P13: MOV R7,#03H
LCALL SIN
LJMP MAIN

SQU: JNB P1.1,N1
JNB P1.2,N2
JNB P1.3,N3
LJMP SSQU
N1: MOV R7,#01H
LJMP TC0
N2: MOV R7,#02H
LJMP TC0
N3: MOV R7,#03H
LJMP TC0
SSQU: CJNE R7,#00H,TC0

MOV R0,#00H
MOV DPTR,#7FFFH
K00: MOV A,#0FFH
MOVX @DPTR,A
MOV P0,#0FFH
MOV P2,#0FFH
MOV A,P2
CPL A
MOV R3,A
L00: DEC R3
CJNE R3,#255,L00
INC R0
INC R0
CJNE R0,#254,K00
MOV R0,#00H
K01: MOV A,#00H
MOVX @DPTR,A
MOV P0,#00H
MOV P2,#0FFH
MOV A,P2
CPL A
MOV R3,A

L01: DEC R3
CJNE R3,#255,L01
INC R0
INC R0
CJNE R0,#254,K01
LJMP SQU
TC0: RET

SAW: JNB P1.0,N4
JNB P1.2,N5
JNB P1.3,N6
LJMP SSAW
N4: MOV R7,#00H
LJMP TC1
N5: MOV R7,#02H
LJMP TC1
N6: MOV R7,#03H
LJMP TC1
SSAW: CJNE R7,#01H,TC1
MOV R0,#0FFH
MOV DPTR,#7FFFH
K10: MOV A,R0
MOVX @DPTR,A
MOV P0,R0
MOV P2,#0FFH
MOV A,P2
CPL A
MOV R3,A
L10: DEC R3
CJNE R3,#255,L10
INC R0
CJNE R0,#255,K10
LJMP SAW
TC1: RET

TRI: JNB P1.0,N7
JNB P1.1,N8
JNB P1.3,N9
LJMP TTRI
N7: MOV R7,#00H
LJMP TC2
N8: MOV R7,#01H
LJMP TC2
N9: MOV R7,#03H
LJMP TC2
TTRI: CJNE R7,#02H,TC2

MOV R0,#00H
MOV DPTR,#7FFFH
K20: MOV A,R0
MOVX @DPTR,A
MOV P0,R0
MOV P2,#0FFH
MOV A,P2
CPL A
MOV R3,A
L20: DEC R3
CJNE R3,#255,L20
INC R0
INC R0
CJNE R0,#254,K20
K21: MOV A,R0
MOVX @DPTR,A
MOV P0,R0
MOV P2,#0FFH
MOV A,P2
CPL A
MOV R3,A
L21: DEC R3
CJNE R3,#255,L21
DEC R0
DEC R0
CJNE R0,#0,K21
LJMP TRI
TC2: RET

SIN: JNB P1.0,N10
JNB P1.1,N11
JNB P1.2,N12
LJMP SSIN
N10: MOV R7,#00H
LJMP TC3
N11: MOV R7,#01H
LJMP TC3
N12: MOV R7,#02H
LJMP TC3
SSIN: CJNE R7,#03H,TC3

MOV R0,#00H
MOV DPTR,#7FFFH
K30: MOV A,R0
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV DPTR,#7FFFH
MOVX @DPTR,A
MOV P0,A
INC R0
MOV P2,#0FFH
MOV A,P2
CPL A
MOV R3,A
L30: DEC R3
CJNE R3,#255,L30
CJNE R0,#255,K30
LJMP SIN
TC3: RET

TAB: DB

ORG 0000H
LJMP MAIN
ORG 0100H ;主程序地址
MAIN: JNB P1.0,P10 ;哪个键按下,显示哪个波形
JNB P1.1,P11
JNB P1.2,P12
JNB P1.3,P13
LJMP MAIN ;没有键按下返回主程序循环

P10: MOV R7,#00H ;方波波形,R7为特征码,放00,表示方波
LCALL SQU ;调用方波波形函数
LJMP MAIN ;调用完返回主程序循环
P11: MOV R7,#01H ;01表示SAW波
LCALL SAW
LJMP MAIN
P12: MOV R7,#02H
LCALL TRI
LJMP MAIN
P13: MOV R7,#03H
LCALL SIN
LJMP MAIN

SQU: JNB P1.1,N1 ;方波函数,如果有其他键按下
JNB P1.2,N2 ;退出程序
JNB P1.3,N3
LJMP SSQU ;没有键按下,到SSQU函数产生方波
N1: MOV R7,#01H ;哪个键按下就在R7中记下特征码
LJMP TC0
N2: MOV R7,#02H
LJMP TC0
N3: MOV R7,#03H
LJMP TC0
SSQU: CJNE R7,#00H,TC0 ;R7不为0退出

MOV R0,#00H ;R0中放00
MOV DPTR,#7FFFH ;这个应该是DAC0832的地址
K00: MOV A,#0FFH ;A中放FF,高电平
MOVX @DPTR,A ;A到0832转换
MOV P0,#0FFH ;这一句不怎么懂,感觉可以去掉
MOV P2,#0FFH ;值P2输入方式,P2是通过拨码按钮改
MOV A,P2 ;变数值,P2越大,波形周期越小
CPL A
MOV R3,A
L00: DEC R3
CJNE R3,#255,L00 ;这个循环改变周期
INC R0
INC R0
CJNE R0,#254,K00 ;高电平波循环127次
MOV R0,#00H
K01: MOV A,#00H ;低电平,跟高电平差不多
MOVX @DPTR,A
MOV P0,#00H
MOV P2,#0FFH
MOV A,P2
CPL A
MOV R3,A

L01: DEC R3
CJNE R3,#255,L01
INC R0
INC R0
CJNE R0,#254,K01
LJMP SQU ;显示完一个波形,回到方波函数开始,判断有无其他按键
TC0: RET ;返回主函数

SAW: JNB P1.0,N4 ;判断有无其他按键,同方波
JNB P1.2,N5
JNB P1.3,N6
LJMP SSAW
N4: MOV R7,#00H
LJMP TC1
N5: MOV R7,#02H
LJMP TC1
N6: MOV R7,#03H
LJMP TC1
SSAW: CJNE R7,#01H,TC1 ;特征码不是01 退出
MOV R0,#0FFH ;RO中放即将输出的值
MOV DPTR,#7FFFH
K10: MOV A,R0 ;锯齿波的每个值
MOVX @DPTR,A ;输出
MOV P0,R0
MOV P2,#0FFH ;通过P2改变周期
MOV A,P2
CPL A
MOV R3,A
L10: DEC R3
CJNE R3,#255,L10
INC R0 ;通过R0加1 来显示锯齿波的斜坡
CJNE R0,#255,K10 ;RO不等于255,循环锯齿波的每个值
LJMP SAW ;等于255,完成一个锯齿波周期,回锯齿波开始
TC1: RET ;退出

TRI: JNB P1.0,N7 ;三角波,类似于两个相反的锯齿波
JNB P1.1,N8
JNB P1.3,N9
LJMP TTRI
N7: MOV R7,#00H
LJMP TC2
N8: MOV R7,#01H
LJMP TC2
N9: MOV R7,#03H
LJMP TC2
TTRI: CJNE R7,#02H,TC2

MOV R0,#00H
MOV DPTR,#7FFFH
K20: MOV A,R0
MOVX @DPTR,A
MOV P0,R0
MOV P2,#0FFH
MOV A,P2
CPL A
MOV R3,A
L20: DEC R3
CJNE R3,#255,L20
INC R0
INC R0
CJNE R0,#254,K20
K21: MOV A,R0
MOVX @DPTR,A
MOV P0,R0
MOV P2,#0FFH
MOV A,P2
CPL A
MOV R3,A
L21: DEC R3
CJNE R3,#255,L21
DEC R0
DEC R0
CJNE R0,#0,K21
LJMP TRI
TC2: RET

SIN: JNB P1.0,N10 ;正弦波,是通过存储在代码区的一个数
JNB P1.1,N11 ;组来显示值的
JNB P1.2,N12
LJMP SSIN
N10: MOV R7,#00H
LJMP TC3
N11: MOV R7,#01H
LJMP TC3
N12: MOV R7,#02H
LJMP TC3
SSIN: CJNE R7,#03H,TC3

MOV R0,#00H
MOV DPTR,#7FFFH
K30: MOV A,R0
MOV DPTR,#TAB ;数组的地址
MOVC A,@A+DPTR ;把第R0个数放到A中
MOV DPTR,#7FFFH
MOVX @DPTR,A ;输出A
MOV P0,A
INC R0 ;RO加1
MOV P2,#0FFH ;周期
MOV A,P2
CPL A
MOV R3,A
L30: DEC R3
CJNE R3,#255,L30
CJNE R0,#255,K30 ;不等于255表示一个周期内,跳到K30
LJMP SIN ;等于表示显示完一个周期,到SIN开始
TC3: RET ;退出

TAB: DB ;定义正弦函数的各个值

看了你的图和你的程序,感觉你的图画得简单了一点,特别是0832地址,控制信号都没接,看起来还在调试,建议P2口做地址总线,这样,编程比较方便,你可以把P3口做周期.或者把P1口的其他口做控制总线,这样要对0832时序比较熟悉才行.
我平时是用C开发的,很少用汇编,如果有什么错误,可以共同探讨.
温馨提示:答案为网友推荐,仅供参考
第1个回答  2020-02-20
ORG
0000H
LJMP
MAIN
ORG
0100H
;主程序地址
MAIN:
JNB
P1.0,P10
;哪个键按下,显示哪个波形
JNB
P1.1,P11
JNB
P1.2,P12
JNB
P1.3,P13
LJMP
MAIN
;没有键按下返回主程序循环
P10:
MOV
R7,#00H
;方波波形,R7为特征码,放00,表示方波
LCALL
SQU
;调用方波波形函数
LJMP
MAIN
;调用完返回主程序循环
P11:
MOV
R7,#01H
;01表示SAW波
LCALL
SAW
LJMP
MAIN
P12:
MOV
R7,#02H
LCALL
TRI
LJMP
MAIN
P13:
MOV
R7,#03H
LCALL
SIN
LJMP
MAIN
SQU:
JNB
P1.1,N1
;方波函数,如果有其他键按下
JNB
P1.2,N2
;退出程序
JNB
P1.3,N3
LJMP
SSQU
;没有键按下,到SSQU函数产生方波
N1:
MOV
R7,#01H
;哪个键按下就在R7中记下特征码
LJMP
TC0
N2:
MOV
R7,#02H
LJMP
TC0
N3:
MOV
R7,#03H
LJMP
TC0
SSQU:
CJNE
R7,#00H,TC0
;R7不为0退出
MOV
R0,#00H
;R0中放00
MOV
DPTR,#7FFFH
;这个应该是DAC0832的地址
K00:
MOV
A,#0FFH
;A中放FF,高电平
MOVX
@DPTR,A
;A到0832转换
MOV
P0,#0FFH
;这一句不怎么懂,感觉可以去掉
MOV
P2,#0FFH
;值P2输入方式,P2是通过拨码按钮改
MOV
A,P2
;变数值,P2越大,波形周期越小
CPL
A
MOV
R3,A
L00:
DEC
R3
CJNE
R3,#255,L00
;这个循环改变周期
INC
R0
INC
R0
CJNE
R0,#254,K00
;高电平波循环127次
MOV
R0,#00H
K01:
MOV
A,#00H
;低电平,跟高电平差不多
MOVX
@DPTR,A
MOV
P0,#00H
MOV
P2,#0FFH
MOV
A,P2
CPL
A
MOV
R3,A
L01:
DEC
R3
CJNE
R3,#255,L01
INC
R0
INC
R0
CJNE
R0,#254,K01
LJMP
SQU
;显示完一个波形,回到方波函数开始,判断有无其他按键
TC0:
RET
;返回主函数
SAW:
JNB
P1.0,N4
;判断有无其他按键,同方波
JNB
P1.2,N5
JNB
P1.3,N6
LJMP
SSAW
N4:
MOV
R7,#00H
LJMP
TC1
N5:
MOV
R7,#02H
LJMP
TC1
N6:
MOV
R7,#03H
LJMP
TC1
SSAW:
CJNE
R7,#01H,TC1
;特征码不是01
退出
MOV
R0,#0FFH
;RO中放即将输出的值
MOV
DPTR,#7FFFH
K10:
MOV
A,R0
;锯齿波的每个值
MOVX
@DPTR,A
;输出
MOV
P0,R0
MOV
P2,#0FFH
;通过P2改变周期
MOV
A,P2
CPL
A
MOV
R3,A
L10:
DEC
R3
CJNE
R3,#255,L10
INC
R0
;通过R0加1
来显示锯齿波的斜坡
CJNE
R0,#255,K10
;RO不等于255,循环锯齿波的每个值
LJMP
SAW
;等于255,完成一个锯齿波周期,回锯齿波开始
TC1:
RET
;退出
TRI:
JNB
P1.0,N7
;三角波,类似于两个相反的锯齿波
JNB
P1.1,N8
JNB
P1.3,N9
LJMP
TTRI
N7:
MOV
R7,#00H
LJMP
TC2
N8:
MOV
R7,#01H
LJMP
TC2
N9:
MOV
R7,#03H
LJMP
TC2
TTRI:
CJNE
R7,#02H,TC2
MOV
R0,#00H
MOV
DPTR,#7FFFH
K20:
MOV
A,R0
MOVX
@DPTR,A
MOV
P0,R0
MOV
P2,#0FFH
MOV
A,P2
CPL
A
MOV
R3,A
L20:
DEC
R3
CJNE
R3,#255,L20
INC
R0
INC
R0
CJNE
R0,#254,K20
K21:
MOV
A,R0
MOVX
@DPTR,A
MOV
P0,R0
MOV
P2,#0FFH
MOV
A,P2
CPL
A
MOV
R3,A
L21:
DEC
R3
CJNE
R3,#255,L21
DEC
R0
DEC
R0
CJNE
R0,#0,K21
LJMP
TRI
TC2:
RET
SIN:
JNB
P1.0,N10
;正弦波,是通过存储在代码区的一个数
JNB
P1.1,N11
;组来显示值的
JNB
P1.2,N12
LJMP
SSIN
N10:
MOV
R7,#00H
LJMP
TC3
N11:
MOV
R7,#01H
LJMP
TC3
N12:
MOV
R7,#02H
LJMP
TC3
SSIN:
CJNE
R7,#03H,TC3
MOV
R0,#00H
MOV
DPTR,#7FFFH
K30:
MOV
A,R0
MOV
DPTR,#TAB
;数组的地址
MOVC
A,@A+DPTR
;把第R0个数放到A中
MOV
DPTR,#7FFFH
MOVX
@DPTR,A
;输出A
MOV
P0,A
INC
R0
;RO加1
MOV
P2,#0FFH
;周期
MOV
A,P2
CPL
A
MOV
R3,A
L30:
DEC
R3
CJNE
R3,#255,L30
CJNE
R0,#255,K30
;不等于255表示一个周期内,跳到K30
LJMP
SIN
;等于表示显示完一个周期,到SIN开始
TC3:
RET
;退出
TAB:
DB
;定义正弦函数的各个值
看了你的图和你的程序,感觉你的图画得简单了一点,特别是0832地址,控制信号都没接,看起来还在调试,建议P2口做地址总线,这样,编程比较方便,你可以把P3口做周期.或者把P1口的其他口做控制总线,这样要对0832时序比较熟悉才行.
我平时是用C开发的,很少用汇编,如果有什么错误,可以共同探讨.
相似回答