HELP!高手帮帮我!
单片机AT89C55,液晶屏幕青云公司的LCM046四位串行带小数,单片机INT1口接按键,现要求从0000开始记数到9999,程序编好后调试发现堆栈一直开销到内部RAM耗尽,导致只能记数到0061,不知道哪里弄错了,望高手指教!
;MYSELF ASM
;ONLY FOR STUDY
BUZZER BIT P1.4 ;蜂鸣器
JPAN BIT P3.3 ;按键
LCD_CS EQU P1.7 ;LCD使能端口
LCD_WR EQU P3.4 ;LCD写端口
LCD_DT EQU P3.5 ;LCD数据端口
LCD_CODE DATA 30H ;LCD命令代码
LCD_ADDR DATA 31H ;LCD地址单元
LCD_DATA DATA 32H ;LCD数据单元
FIRSTBAK DATA 33H ;第一位显示备份单元
LCD_1 DATA 34H ;LCD显示缓冲区第一位
LCD_2 DATA 35H ;LCD显示缓冲区第二位
LCD_3 DATA 36H ;LCD显示缓冲区第三位
LCD_4 DATA 37H ;LCD显示缓冲区第四位
ORG 0000H
JMP START
ORG 0100H
START:MOV SP,#60H
AAAA: CALL DLY50MS
MOV 30H,#00101001B ;初始化
CALL WRCOM
MOV 30H,#00011000B ;定义模块内部RC振荡器工作
CALL WRCOM
MOV 30H,#00000001B ;开振荡器
CALL WRCOM
MOV 30H,#00000011B ;开显示
CALL WRCOM
MOV R4,#00H
MOV R5,#00H
MOV LCD_1,R5
LCALL LCD_N
INC R4
MOV LCD_2,R5
INC R4
MOV LCD_3,R5
INC R4
MOV LCD_4,R5
;*************************************
CLR BUZZER
CALL DLY1S
SETB BUZZER
;********************************主程序
ZCX:LCALL KEY
;****************************按键检测
KEY:JB JPAN,NO_KEY
LCALL DLY15MS
JNB JPAN,OK_KEY ;15MS以后再次检测确认是否误动
NO_KEY:LCALL DLY6MS ;无按键延时6MS
LJMP KEY
RET
;*****************************************等待按键释放
OK_KEY:
JB JPAN,START_1
LJMP OK_KEY
;*****************************************
START_1:
MOV R4,#00H
MOV A,LCD_1
CJNE A,#09H,FFFF
MOV A,#00H
MOV LCD_1,A
LCALL LCD_N ;个位
JMP SSSS
FFFF:ADD A,#01H
MOV LCD_1,A
LCALL LCD_N
LJMP MMMM
SSSS:CLR A
MOV A,LCD_2
CJNE A,#09H,TTTT
MOV A,#00H
MOV LCD_2,A
LCALL LCD_N ;十位
JMP YYYY
TTTT:ADD A,#01H
MOV LCD_2,A
LCALL LCD_N
LJMP MMMM
YYYY:CLR A
MOV A,LCD_3
CJNE A,#09H,ZZZZ
MOV A,#00H
MOV LCD_3,A
LCALL LCD_N ;百位
JMP YYYY
ZZZZ:ADD A,#01H
MOV LCD_3,A
LCALL LCD_N
LJMP MMMM
QQQQ:CLR A
MOV A,LCD_4
CJNE A,#09H,DDDD
MOV A,#00H
MOV LCD_4,A
LCALL LCD_N ;千位
JMP START_2
DDDD:ADD A,#01H
MOV LCD_4,A
LCALL LCD_N
MMMM: CLR BUZZER
LCALL DLY0_25S
SETB BUZZER
START_2:
AJMP ZCX
;***************************************
;液晶显示模块子程序
;R4=显示位置 R5=数字
;从左到右0--3
;用到:R2,R3,R7,30H--32H
;***************************************
;小数表
NUMB_Y: DB 0FH,0DH,08H,05H,0DH,0BH,09H,0FH
DB 0AH,07H,0BH,0EH,0FH,0EH,09H,05H
DB 0FH,0FH,0BH,0FH ;0--9
DB 08H,02H ;- 0A
DB 0FH,02H ;F 0B
DB 0EH,08H ;L 0C
DB 0EH,07H ;H 0D
DB 0FH,03H ;P 0E
DB 0FH,00H ;R 0F
DB 08H,00H ; 10
DB 0FH,05H ;N 11
DB 0FH,0AH ;E 12
DB 0FH,0FH ;8: 13
DB 0EH,0DH ;U 14
DB 0FH,08H ;C 15
DB 0FH,02H ;F: 16
DB 0FH,07H ;A 17
;无小数表
NUMB_N: DB 07H,0DH,00H,05H,05H,0BH,01H,0FH
DB 02H,07H,03H,0EH,07H,0EH,01H,05H
DB 07H,0FH,03H,0FH ;0--9
DB 00H,02H ;- 0A
DB 07H,02H ;F 0B
DB 06H,08H ;L 0C
DB 06H,07H ;H 0D
DB 07H,03H ;P 0E
DB 07H,00H ;R 0F
DB 00H,00H ; 10
DB 07H,05H ;N 11
DB 07H,0AH ;E 12
DB 0FH,0FH ;8: 13
DB 06H,0DH ;U 14
DB 07H,08H ;C 15
DB 0FH,02H ;F: 16
DB 07H,07H ;A 17
LCD_Y: MOV DPTR,#NUMB_Y ;小数
AJMP LCD_00
LCD_N: MOV DPTR,#NUMB_N ;无小数
LCD_00: CLR A
MOV A,R4
CJNE A,#04H,LCD_02
MOV 31H,#00H
LCALL WRDD
MOV A,FIRSTBAK
;ANL A,#0FH
RL A
MOVC A,@A+DPTR
ORL A,#08H
MOV 32H,A
LCALL WRDATA
;****************
MOV 31H,#04H
LCALL WRDD
MOV A,FIRSTBAK
RL A
INC DPTR
MOVC A,@A+DPTR
MOV 32H,A
LCALL WRDATA
JMP LCD_END
;****************************************************
LCD_01: CJNE R4,#00H,LCD_02
MOV FIRSTBAK,R5
LCD_02: CLR A
MOV A,R4
CLR C
ANL A,#0FH
RL A
RL A
RL A
MOV 31H,A
LCALL WRDD
MOV A,R5
RL A
MOVC A,@A+DPTR
MOV 32H,A
LCALL WRDATA
;*************
CLR A
MOV A,R4
CLR C
ANL A,#0FH
INC A
RL A
RL A
MOV 31H,A
LCALL WRDD
MOV A,R5
RL A
INC DPTR
MOVC A,@A+DPTR
MOV 32H,A
LCALL WRDATA
LCD_END: NOP
RET
;***************************************************
;写命令代码 * 用到R7,30H,LCD_CS,LCD_WR,LCD_DT,A,CY *
;***************************************************
WRCOM: SETB LCD_CS ;/CS=1
CALL DLY5
CLR LCD_CS ;/CS=0 ;开CS
CALL DLY5
CLR LCD_WR ;/WR=0 ;开WR
CALL DLY5
SETB LCD_DT ;D=1 (100)
CALL DLY5
SETB LCD_WR ;/WR=1
CALL DLY5
CLR LCD_WR ;/WR=0
CALL DLY5
CLR LCD_DT ;D=0
CALL DLY5
SETB LCD_WR ;/WR=1
CALL DLY5
CLR LCD_WR ;/WR=0
CALL DLY5
CLR LCD_DT ;D=0
CALL DLY5
SETB LCD_WR ;/WR=1
CALL DLY5
MOV R7,#9 ;LOOP=DATA 8 BIT +1X
CLR C
LOOPWR:
CALL DLY5
CLR LCD_WR ;开WR
CALL DLY5
MOV A,30H
RLC A ;左移位
MOV 30H,A
JC ONE
CLR LCD_DT ;DATA=0
CALL DLY5
JMP ZERO
ONE: SETB LCD_DT ;DATA=1
CALL DLY5
ZERO: SETB LCD_WR
CALL DLY5
DJNZ R7,LOOPWR
SETB LCD_CS ;关CS
RET
;************************************************************
;写6位地址+4位数据 格式:101 0_A4_A3_A2_A1_A0 D0_D1_D2_D3
;用到31H,32H,R7,LCD_CS,LCD_WR,LCD_DT,A,CY
;************************************************************
WRDD: SETB LCD_CS ;/CS=1
CALL DLY5
CLR LCD_CS ;/CS=0 ;开CS
CALL DLY5
CLR LCD_WR ;/WR=0 ;开WR
CALL DLY5
SETB LCD_DT ;D=1 (101)
CALL DLY5
SETB LCD_WR ;/WR=1
CALL DLY5
CLR LCD_WR ;/WR=0
CALL DLY5
CLR LCD_DT ;D=0
CALL DLY5
SETB LCD_WR ;/WR=1
CALL DLY5
CLR LCD_WR ;/WR=0
CALL DLY5
SETB LCD_DT ;D=1
CALL DLY5
SETB LCD_WR ;/WR=1
CALL DLY5
;写6位地址
MOV R7,#6
WRADDR:
CALL DLY5
CLR LCD_WR ;开WR
CALL DLY5
MOV A,31H
RLC A ;左移位
MOV 31H,A
JC ONE_1
CLR LCD_DT ;DATA=0
CALL DLY5
JMP ZERO_0
ONE_1:
CALL DLY5
SETB LCD_DT ;DATA=1
CALL DLY5
ZERO_0:
CALL DLY5
SETB LCD_WR
CALL DLY5
DJNZ R7,WRADDR
SETB LCD_CS ;关CS
RET
;**********************************************
;写4位数据
WRDATA: MOV R7,#4 ;LOOP=DATA 4 BIT
LOOPDATA:
CALL DLY5
CLR LCD_WR
CALL DLY5
MOV A,32H
RRC A ;右移位
MOV 32H,A
JC ONE_11
CLR LCD_DT ;DATA=0
CALL DLY5
JMP ZERO_00
ONE_11:
CALL DLY5
SETB LCD_DT ;DATA=1
CALL DLY5
ZERO_00:
CALL DLY5
SETB LCD_WR
CALL DLY5
DJNZ R7,LOOPDATA
SETB LCD_CS
RET
;***************************************
;延时程序
DLY5: NOP ;6uS
NOP
NOP
NOP
NOP
RET
DLY2_5MS: MOV R2,#210 ;12M/2.5MS
DLOP: CALL DLY5
DJNZ R2,DLOP
RET
DLY6MS:MOV R3,#255 ;延时5.5MS
DLOP1:CALL DLY5
CALL DLY5
DJNZ R3,DLOP1
RET
DLY1S: MOV R3,#200 ;1S
DLOP10: CALL DLY2_5MS
CALL DLY2_5MS
DJNZ R3,DLOP10
RET
DLY50MS: MOV R3,#10 ;50MS
DLOP11: CALL DLY2_5MS
CALL DLY2_5MS
DJNZ R3,DLOP11
RET
DLY0_25S: MOV R3,#50 ;0.25S
DLOP12: CALL DLY2_5MS
CALL DLY2_5MS
DJNZ R3,DLOP12
RET
DLY15MS: MOV R3,#3 ;15MS
DLOP13: CALL DLY2_5MS
CALL DLY2_5MS
DJNZ R3,DLOP13
RET
发表时间:2004年10月6日14:02:32