马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
各位大侠,本人目前在做一个用FPGA与51单片机相结合的低频数字式相位仪,目前51单片机程序如下,可是编译的时候老是出现长调用不能执行下去(比如LCALL DUSHUJU 不能调用)。
;符合定义
DATAL EQU 40H ;19位周期T的数据存放内存单元
DATAH EQU 41H
DATA3 EQU 42H
DATA2L EQU 43H ;19位相位差对应的时间差的数据存放内存单元
DATA2H EQU 44H
DATA33 EQU 45H
;除法占用单元及乘法占用单元
AD0 EQU 30H ;存放被除数(或被除数)的字节数的存放单元
AD1 EQU 31H ;存放除数(或乘数)的字节数的存放单元
AD2 EQU 32H
AD3 EQU 33H
AD4 EQU 34H
AD5 EQU 35H
AD6 EQU 36H
ADA EQU 4FH ;存放被除数(或被乘数)的末地址,即最低位字节存放单元地址
ADB EQU 5FH ;存放除数(或乘数)的末地址,即最低位字节存放单元地址
ADC EQU 4DH
ADE EQU 5DH
DSEL BIT P1.3 ;控制FPGA的信号
FEN BIT P1.5 ;控制FPGA的信号
KEY1 BIT P1.7 ;切换显示的按键S1
KEY2 BIT P1.6 ;未使用按键S2
ALA BIT P3.5 ;未使用
DISPBIT BIT 2FH.0 ;控制显示频率或相位差的标志位
;*****************************************************
;主程序
ORG 00H
LJMP 100H
ORG 100H
MAIN: MOV 2FH,#01H
MAIN1: NOP
LCALL DUSHUJU ;从FPGA读数据
LCALL ZHUNBEIZHOUQI ;装入频率计数数据(100000000及周期T)分别到4AH-4FH及5DH-5FH中
CLR 2FH.3
JNB 2FH.3,DIVDD1
LJMP CHCHU
DIVDD1:
LCALL DIVD1 ;调用除法子程序(6字节除以3字节)计算频率
MOV 6FH,4FH ;二进制形式的频率值在4DH,4EH,4FH中,最高位在4DH中
MOV 6EH,4EH
MOV 6DH,4DH
MOV 6CH,4CH
MOV 35H,4FH
MOV 34H,4EH
MOV 33H,4DH
MOV 32H,4CH
LCALL BCDST ;二进制转换为BCD码
MOV R0,#30H
MOV R1,#3FH
MOV R7,#04H
MOV 30H,#0
MOV 31H,#0
MOV 32H,#0
MOV 33H,#0
MOV 34H,#0
MOV 35H,#0
MOV 36H,#0
LCALL BCD_2BCD ;将压缩BCD码格式转换成单字节BCD码格式
MOV 70H,#18 ;将频率值存放在30H-35H中,最低位在30H中,最高位在35H中
MOV 71H,30H ;内存单元70H-76H是频率值显示缓冲区,其中70H是符号位
MOV 72H,31H
MOV 73H,32H
MOV 74H,33H
MOV 75H,34H
MOV 76H,35H
MIANWC:
LCALL X360 ;装入相位计计算数据
LCALL MULNM ;调用乘法子程序求360乘以时间差(3字节乘以3字节)
MOV 4AH,5AH ;将上述的乘积送入除法的被乘数缓冲区
MOV 4BH,5BH
MOV 4CH,5CH
MOV 4DH,5DH
MOV 4EH,5EH
MOV 4FH,5FH
MOV 5FH,DATAL
MOV 5EH,DATAH
MOV 5DH,DATA3
LCALL DIVD1 ;调用乘法子程序计算得到的相位差值
MOV 35H,4FH ;压缩BCD格式的相位差值存放在4F-4DH中,4FH为其中的最低位
MOV 34H,4EH
MOV 33H,4DH
MOV 32H,#0
LCALL BCDST ;二进制转换为压缩格式的BCD码
MOV R0,#30H
MOV R1,#3FH
MOV R7,#04H
MOV 30H,#0
MOV 31H,#0
MOV 32H,#0
MOV 33H,#0
MOV 34H,#0
MOV 35H,#0
MOV 36H,#0
LCALL BCD_2BCD ;由压缩BCD码转换为单字节BCD码
MOV 78H,#16 ;相位差值存放在30H-35H中,最低位在30H中
MOV 79H,30H ;内存单元78H-7EH是相位差值显示缓冲区。其中78H是符号位
MOV 7AH,31H
MOV 7BH,32H
MOV 7CH,33H
MOV 7DH,34H
MOV 7EH,35H
CHCHU: LCALL DISP ;调用显示子程序
KEYCOD: JB P1.7,MAIN11 ;查询按键S1
LCALL DELAY1 ;软件延时消抖
JNB P1.7,$ ;等待S1释放
CPL 2FH.0 ;取反标志位2FH.0
LCALL DELAY2
MAIN11: LCALL DELAY1
LCALL DELAY1
LCALL DELAY1
LJMP MAIN1 ;继续主程序循环,主程序段到此为止
;**************************************************************
PROC DUSHUJU ;CPU 从FPGA读数据到MCU子程序
DUSHUJU:
CLR DSEL ;先读周期T对应的19位数据
SETB FEN
MOV A,P0
MOV DATAL,A
MOV A,P2
MOV DATAH,A
MOV A,P1
ANL A,#00000111B ;屏蔽掉不需要的高5位
MOV DATA3,A
SETB DSEL ;准备读时间差对应的19位数据
NOP
NOP
NOP
MOV A,P0
MOV DATA2L,A
MOV A,P2
MOV DATA2H,A
MOV DATA2H,A
MOV A,P1
ANL A,#00000111B ;屏蔽掉不需要的高5位
MOV DATA33,A
CLR FEN
RET
NOP C值出错处理
NOP ;空操作
NOP ;空操作
LJMP MAIN ;重新复位起动
END
;********************************************************
PROC ZHUNBEIZHOUQI ;为了计算频率将被除数100000000装入4AH-4FH单元中
ZHUNBEIZHOUQI: ;将除数(周期T)装入5DH-5FH单元中
;2N Byte/N Byte=N Byte,Here N=3 in 31H
MOV 5FH,DATAL ;(4A,4B,4C,4D,4E,4FH)/(5D,5E,5FH)=(4D,4E,4FH)
MOV 5EH,DATAH
MOV 5DH,DATA3
MOV 4FH,#80H ;低位
MOV 4EH,#96H
MOV 4DH,#98H
MOV 4CH,#00H
MOV 4BH,#0H
MOV 4AH,#0H
RET
NOP ;C值出错处理
NOP ;空操作
NOP ;空操作
LJMP MAIN ;重新复位起动
END
;*************************************************************
PROC MULNM ;多字节乘法子程序
;N Byte*M bYTE=N+M Byte,Here N=3,M=3
;(4D,4E,4FH)*( 5D,5E,5FH)=(5AH-5FH)
MULNM:
NOP
MOV 30H,#03H
MOV 31H,#03H
MULTT: MOV A,AD0
MOV R3,AD1
MOV R2,A
ADD A,R3
INC A
MOV AD2,A
MOV A,#ADB
CLR C
SUBB A,R3
MOV AD6,A
MOV R1,A
SUBB A,R2
MOV AD5,A
INC R2
MULNMZ:MOV @R1,#00H
DEC R1
DJNZ R2,MULNMZ
MULNMB:MOV R2,AD0
MOV R1,AD6
MOV R0,#ADA
CLR 00H
MULNML:MOV A,ADB
JZ MULNMD
MOV B,@R0
MUL AB
ADD A,@R1
MOV 00H,MULLNM1
INC B
MULNM1:MOV A,B
DEC R1
ADDC A,@R1
MOV @R1,A
MOV 00H,C
DEC R0
DJNZ R2,MULNML
MULNMD:MOV R0,AD5
CLR A
MOV R2,AD2
MULNMS:XCH A,@R0
INC R0
DJNZ R2,MULNMS
DJNZ R3,MULNMB
RET
NOP C值出错处理
NOP ;空操作
NOP ;空操作
LJMP MAIN ;重新复位起动
END
;*******************************************************************
PROC X360 ;为了计算时间差乘以360,分别把被乘数(时间差)和乘数(360)送到4DH--4FH和5DH--5FH中
X360:
MOV 4DH,DATA33
MOV 4EH,DATA2H
MOV 4FH,DATA2L
MOV 5DH,#00H
MOV 5EH,#0EH
MOV 5FH,#10H
RET
NOP ;PC值出错处理
NOP ;空操作
NOP ;空操作
LJMP MAIN ;重新复位起动
END
;*******************************************************************
PROC BCD_2BCD
;功能:将压缩BCD码格式转换成单字节的BCD码格式子程序
;入口参数:R1指向待转换的压缩BCD码的低位字节地址(末地址)
; R0指向存放结果的低位字节地址(首地址)
; R7存放压缩BCD码的字节数,作计数器的使用
;出口参数:无
;使用资源:A,B,PSW,R0,R1,R7,存放压缩BCD码及单字节BCD码的存储单元
BCD_2BCD:
NOP
LOOP0: CLR A
MOV A,@R1
MOV B,A
ANL A,#0FH
MOV @R0,A
INC R0
MOV A,B
SWAP A
ANL A,#0FH
MOV @R0,A
DEC R1
INC R0
DJNZ R7,LOOP0
RET
NOP ;PC值出错处理
NOP ;空操作
NOP ;空操作
LJMP MAIN ;重新复位起动
END
;********************************************************************
PROC DISP ;;显示子程序
DISP:
PUSH ACC
PUSH PSW
PUSH DPH
PUSH DPL
MOV A,76H ;76H 单元是频率值显缓区数据最高位
CJNE A,#0,NOPB ;消隐无效数字0
MOV 76H,#17
MOV A,75H
CJNE A,#0,NOPB
MOV 75H,#17
MOV A,74H
CJNE A,#0,NOPB
MOV 74H,#17
MOV A,73H
CJNE A,#0,NOPB
MOV 73H,#17
MOV A,72H
CJNE A,#0,NOPB
MOV 72H,#17
MOV A,71H
CJNE A,#0,NOPB
MOV 71H,#0
MOV A,70H
CJNE A,#0,NOPB
MOV 70,#17
NOPB: MOV A,7EH ;7EH是相位差值显缓区最高位
CJNE A,#0,NOPB1 ;消隐无效数字0
MOV 7EH,#17
MOV A,7DH
CJNE A,#0,NOPB1
MOV 7DH,#17
MOV A,7CH
CJNE A,#0,NOPB1
MOV 7CH,#17
MOV A,7BH
CJNE A,#0,NOPB1
MOV 7BH,#17
NOPB1: MOV R1,#70H ;R1指向频率值显示缓冲区首址(最低位地址)
JNB 2FH.0,DISXW
JMP DISPP
DISXW: MOV R1,#78H ;R1指向相位差值显示缓冲区首址(最低位地址)
DISPP: MOV R2,#7
DISP1: MOV A,@R1
MOV DPTR,#TAB
MOVC A,@A+DPTR
JB 2FH.0,OKOK
MOV B,A
MOV A,R1
CJNE A,#7AH,NONO
MOV A,B
ANL A,#11110111B ;显示相位差时的小数点
MP OKOK
NONO: MOV A,B
OKOK: MOV SBUF,A ;开始发送数据
DL1: JNB TI,DL1 ;等待发送完一帧(8位)数据
CLR TI
INC R1
DJNZ R2,DISP1
POP DPL
POP DPH
POP PSW
POP ACC
RET
NOP ;PC值出错处理
NOP ;空操作
NOP ;空操作
LJMP MAIN ;重新复位起动
TAB: DB 88H,0EBH,04CH,049H,2BH
DB 19H,18H,0CBH,08H,09H
DB 0AH,38H,9CH,68H,1CH,1EH,00FH,0FFH,2AH
END
;************************************************************
PROC DELAY1
DELAY1: ;软件延时子程序1
CLR ALA
MOV R6,#64H
DELAY11:MOV R7,#250
DJNZ R7,$
DJNZ R6,DELAY11
SETB ALA
RET
NOP ;PC值出错处理
NOP ;空操作
NOP ;空操作
LJMP MAIN ;重新复位起动
END
;************************************************************
PROC DELAY2
DELAY2: ;软件延时子程序2
MOV R6,#64H
DELAY21:MOV R7,#250
DJNZ R7,$
DJNZ R6,DELAY21
RET
NOP ;PC值出错处理
NOP ;空操作
NOP ;空操作
LJMP MAIN ;重新复位起动
END
;*************************************************************
PROC DIVD1 ;多字节除法子程序
;2N BYTE/N Byte,Here N=3 in 31H
;(4A,4B,4C,4D,4E,4FH)/(5D,5E,5FH)=(4D,4E,4FH)
DIVD1: NOP
MOV 30H,#06H ;被除数的字节数为6(AD0)=6
MOV 31H,#03H ;除数的字节数为3
DIVPP: MOV A,AD1
MOV R2,A ;R2=03H
RL A
RL A
RL A
MOV R3,A ;R3=18H=24D
CLR 0F0H ;B.0=0 清标志位,寄存器B的字节地址为F0H
CLR C ;C=0
MOV A,#ADA
SUBB A,R2
MOV AD3,A ;(AD3)=4CH
MOV R1,#ADB
DIVMB2B:
MOV A,@R1
JNZ DIVM2B
DEC R1
DJNZ R2,DIVMB2B
SETB 0F0H
RET
DIVM2B:
MOV R2,AD1
MOV R1,#ADB
MOV R0,AD3
DIVM2L:
MOV A,@R0
SUBB A,@R1
DEC R0
DEC R1
DJNZ R2,DIVM2L
JNC DIVM20
DIVM2D: LCALL SHIL1
JC DIVM2S
DIVM2C:
MOV R0,AD3
MOV R1,#ADB
MOV R2,AD1
DIVM2CL:
MOV A,@R0
SUBB A,@R1
DEC R0
DEC R1
DJNZ R2,DIVM2CL
JC DIVM2E
DIVM2S: INC ADA
MOV R2,ADA
MOV R0,AD3
MOV R1,#ADB
LCALL SUBMBB
DIVM2E: DJNZ R3,DIVM2D
RET
DIVM20: SETB OFOH
RET
DB 02H,12H
SHIL1: MOV R2,AD0
MOV R0,#ADA
SHIL1B: CLR C
SHILL: MOV A,@R0
RLC A
MOV @R0,A
DEC R0
DJNZ R2,SHILL
RET
SUBMB: MOV R2,AD0
MOV R0,#ADA
MOV R1,#ADB
SUBMBB: CLR C
SUBMB1: MOV A,@R0
SUBB A,@R1
MOV @R0,A
DEC R0
DEC R1
DJNZ R2,SUBMB1
RET
NOP ;PC值出错处理
NOP ;空操作
NOP ;空操作
LJMP MAIN ;重新复位起动
END
;***************************************************************
PROC BCDST
BCDST: ;4字节二进制数转换为压缩BCD码子程序
MOV R7,#32 ;4字节有32位,R7作为计数器使用
CLR C
MOV 3FH,#00H
MOV 3EH,#00H
MOV 3DH,#00H
MOV 3CH,#00H
MOV 3BH,#00H
MOV 3AH,#00H
KKK: MOV A,35H
RLC A
MOV 35H,A
MOV A,34H
RLC A
MOV 35H,A
MOV A,34H
RLC A
MOV 34H,A
MOV A,33H
RLC A
MOV 33H,A
MOV A,32H
RLC A
MOV 32H,A
MOV A,3FH
ADDC A,3FH
DA A
MOV 3FH,A
MOV A,3EH
ADDC A,3EH
DA A
MOV 3EH,A
MOV A,3DH
ADDC A,3DH
DA A
MOV 3DH,A
MOV A,3CH
ADDC A,3CH
DA A
MOV 3CH,A
MOV A,3BH
ADDC A,3BH
DA A
MOV 3BH,A
MOV A,3AH
ADDC A,3AH
DA A
MOV 3AH,A
DJNZ R7,KKK
RET
NOP ;PC值出错处理
NOP ;空操作
NOP ;空操作
LJMP MAIN ;重新复位起动
END
;****************************************************************************
END |