|
查看: 2002|回复: 24
|
我把自已写的 8051 Aasembly 放上来,请指点指点。
[复制链接]
|
|
|
本人正学写 8051 Aasembly ,但只是从书上学的。。
如果我把自已写的 8051 Aasembly 放上来,有没有人愿意指点指点。
不管好还是不好我都愿意接受。。
[ Last edited by pkl0001 on 24-8-2004 at 01:39 PM ] |
|
|
|
|
|
|
|
|
|
|
发表于 24-8-2004 09:56 AM
|
显示全部楼层
指点的话就不太好啦,讨论讨论的话还可以 
大家都是在学习中嘛。。。
这里应该有一些人会8051的组合语言 |
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 24-8-2004 12:17 PM
|
显示全部楼层
|
|
|
|
|
|
|
|
|
|
发表于 24-8-2004 12:25 PM
|
显示全部楼层
我的早已经忘光光了~~~~~
Final Year Project 才慢慢去回忆~~呵呵 |
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 24-8-2004 01:14 PM
|
显示全部楼层
faiko 于 24-8-2004 12:25 PM 说 :
我的早已经忘光光了~~~~~
Final Year Project 才慢慢去回忆~~呵呵
那我放上来噢!!! |
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 24-8-2004 01:32 PM
|
显示全部楼层
这是我从书上抄下来的。
本来是一个时钟,后来我把它改成计时器。
这还没有完成,因为遇上问题还不能解决。
基本上这程式是这样的:
Prees K1 start timer,
Than prees k2 Stop/Pause timer
Than press k1 Continued Timer , Press K3 Reset Timer
Befor Timer Start Press K4 Set Timer
Press K5 Set Min
Press K6 Set Second
Press K4 OK
我遇上问题是:
当Timer Set 了时间后,开始几次没问题它都会停下来。
可是大慨5-7次后,就不能在设定的时间停下。
; 8051 Timer With 7-Segment x 4 + Alarm + BZ
;---------------------------------------------------------------------
; MOV TL0,#(8192-5000).MOD.32
; MOV TH0,#(8192-5000)/32
LO EQU 24
HI EQU 99
;---------------------------------------------------------------------
CO EQU 200 ; Adj To Match Time 200 x 5 mS = 1 Second
ALB EQU 20H.0 ; Alarm Bit
BUF EQU 30H ; 7-Segment Buffer Ram 30H 31H 32H 33H 4 Bytes
MIN EQU 34H ; Min
SEC EQU 35H ; Second
DEDA EQU 36H ; DEDA Count 5 mS Count
SEC0 EQU 37H ; Old Second
MM EQU 38H ; Alarm Min
SS EQU 39H ; Alarm Second
;----------------------------------------------------------------------
; INPUT...
K1 EQU P3.7 ; K1 - Start / Continued Timer
K2 EQU P3.4 ; K2 - Stop / Pause Timer
K3 EQU P3.5 ; K3 - Reset Timer To 00:00
K4 EQU P3.3 ; K4 - Set Alarm / Set Alarm Finish
K5 EQU P2.6 ; K5 - Set Alarm Min
K6 EQU P3.2 ; K6 - Set Alarm Second
; OUTPUT...
OP_LAMP EQU P1.0 ; Opeartion Lamp
SEC_LED EQU P1.1 ; Second LED
ALM_LED EQU P1.2 ; Alarm On - LED On / Alarm Off - LED Off
TO_LED EQU P1.3 ; Time Out LED
SPK EQU P2.7 ; BZ
;----------------------------------------------------------------------
ORG 0H
JMP BEGIN
ORG 0BH
JMP T0_INT
;----------------------------------------------------------------------
BEGIN:
CLR ALB ; Off Alarm
MOV MM,#00 ; Default Alarm Time Min -- 00
MOV SS,#01 ; Default Alarm Time Second -- 01
RESET:
SETB OP_LAMP
SETB TO_LED
CALL LOAD_DATA ; Set 7-Segment Display 00:00
CALL INIT
;************************************************************
; SCAN_KEY
; K1 - Start / Continued Timer
; K2 - Stop / Pause Timer
; K3 - Reset Timer To 00:00
; K4 - Set Alarm
;************************************************************
; Scan K1 Start / Continued Timer ...
; Scan K4 Set Alarm ...
LOOP1:
CALL TIME_PRO ; Update Time Data
CALL SCAN1 ; Scan 7-Segment
JB K1,L1 ; Press K1 Start Timer
CALL INIT_TIMER_START ; Start Timer
JMP LOOP2
L1: JB K4,LOOP1 ; Press K4 Set Alarm
JNB K4,$
CALL SET_ALARM
CALL LOAD_DATA
JMP LOOP1
; Scan K2 Stop / Pause Timer ...
LOOP2:
CALL TIME_PRO ; Update Time Data
CALL SCAN1 ; Scan 7-Segment
JNB K2,LOOP3 ; Press K2 Stop Timer / Pause Timer
JMP LOOP2
; Scan K1 Continued Timer ...
; Scan K3 Reset Timer ...
LOOP3:
CALL INIT_TIMER_STOP ; Stot Timer
CALL TIME_PRO ; Update Time Data
CALL SCAN1 ; Scan 7-Segment
JB K1,L3 ; Prees K1 Continued Timer
JMP LOOP1
L3: JB K3,LOOP3 ; Press K3 Reset Timer
JMP RESET
;************************************************************
; K4 - Set Finish Alarm
; K5 - Set Alarm Min
; K6 - Set Alarm Second
;************************************************************
SET_ALARM:
CALL CONVA
; Scan K1 Adj Min ...
SK1:
CALL SCAN1 ; Scan 7-Segment
JB K5,SK2 ; Press K5 Count Up Min
INC MM
MOV A,MM
CJNE A,#30,N1 ; Maximize Display
MOV MM,#00
N1:
CALL CONVA
CALL SCANS
JMP SK1
; Scan K2 Adj Second ...
SK2:
JB K6,FINISH ; Press K6 Count Up Sec
INC SS
MOV A,SS
CJNE A,#60,N2 ; Maximize Display
MOV SS,#00
N2:
CALL CONVA
CALL SCANS
JMP SK1
FINISH:
JB K4,SK1
JNB K4,$
; CHECK MIN ...
MOV A,MM
CJNE A,#00,F1
; CHECK SEC ...
MOV A,SS
CJNE A,#00,F1
; OFF ALARM ...
CALL ALARM_OFF
JMP F2
F1:
CALL ALARM_ON
F2:
RET
;************************************************************; ALM_LED On - Alarm On
; ALM_LED Off - Alarm Off
;************************************************************ALARM_ON:
; Alarm On ...
SETB ALB
CLR ALM_LED
JMP AL1
ALARM_OFF:
; Alarm Off ...
CLR ALB
SETB ALM_LED
JMP AL1
AL1:
RET
;----------------------------------------------------------------------
TITLE: DB "8051 Clock With 7-Segment x 4 + Timer + Alarm + Bz"
;----------------------------------------------------------------------
; DELAY Xms R5*10 ms
DELAY:
MOV R6,#50
D1: MOV R7,#100
DJNZ R7,$
DJNZ R6,D1
DJNZ R5,DELAY
RET
;----------------------------------------------------------------------
; DELAY A WHILE
DELAY1:
MOV R6,#1
D2: MOV R7,#100
DJNZ R7,$
DJNZ R6,D2
DJNZ R5,DELAY1
RET
;----------------------------------------------------------------------
; 7-SEGMENT COMMON CATHODE
TABLE:
DB 3FH, 06H, 5BH, 4FH, 66H
DB 6DH, 7DH, 07H, 7FH, 6FH
DB 77H, 7CH, 58H, 5EH, 79H
DB 71H
;----------------------------------------------------------------------
LOAD_DATA:
MOV BUF, #3FH
MOV BUF+1,#3FH
MOV BUF+2,#3FH
MOV BUF+3,#3FH
RET
;----------------------------------------------------------------------
INIT:
MOV DEDA,#0
MOV SEC0,#0
MOV SEC,#0
MOV MIN,#0
RET
;----------------------------------------------------------------------
INIT_TIMER_START:
CLR OP_LAMP
MOV TMOD,#00000000B
MOV IE, #10000010B
MOV TL0,#LO
MOV TH0,#HI
SETB TR0
RET
;----------------------------------------------------------------------
INIT_TIMER_STOP:
MOV TMOD,#00000000B
MOV IE, #10000010B
MOV TL0,#LO
MOV TH0,#HI
CLR TR0
RET
;----------------------------------------------------------------------
; USE TIMER MODE 0
; COUNT=5ms/1us=5000
;----------------------------------------------------------------------
T0_INT:
PUSH ACC
MOV TL0,#LO
MOV TH0,#HI
INC DEDA
; 1 SEC TIME OUT CHECK
MOV A,DEDA
CJNE A,#CO,TT1
MOV DEDA, #0
CPL SEC_LED
INC SEC
MOV A,SEC
CJNE A,#60,TT1
; 1 MIN TIME OUT
INC MIN
MOV SEC,#0
MOV A, MIN
CJNE A,#99,TT1
MOV SEC,#0
MOV MIN,#0
TT1:
POP ACC
RETI
;----------------------------------------------------------------------
; 7 SEG HH:MM
; CONVERT ALARM DATA
; BUF0 | BUF1 | BUF2 | BUF3
CONVA:
; SHOW MIN...............
MOV A,MM
MOV B,#10
DIV AB
MOV DPTR, #TABLE
MOVC A,@A+DPTR
MOV BUF,A
MOV A,B
MOVC A,@A+DPTR
MOV BUF+1,A
; SHOW SEC...............
MOV A,SS
MOV B,#10
DIV AB
MOV DPTR, #TABLE
MOVC A,@A+DPTR
MOV BUF+2,A
MOV A,B
MOVC A,@A+DPTR
MOV BUF+3,A
RET
;----------------------------------------------------------------------
; 7 SEG MM:SS
; CONVERT DATA AND SHOW
; BUF0 | BUF1 | BUF2 | BUF3
CONV1:
; SHOW MIN...............
MOV A,MIN
MOV B,#10
DIV AB
MOV DPTR, #TABLE
MOVC A,@A+DPTR
MOV BUF,A
MOV A,B
MOVC A,@A+DPTR
MOV BUF+1,A
; SHOW SEC...............
MOV A,SEC
MOV B,#10
DIV AB
MOV DPTR, #TABLE
MOVC A,@A+DPTR
MOV BUF+2,A
MOV A,B
MOVC A,@A+DPTR
MOV BUF+3,A
RET
;----------------------------------------------------------------------
; SCAN 4 TIMES
SCAN1:
MOV R0, #BUF
MOV R2, #4
MOV ACC, #0FEH
S1:
PUSH ACC
; SEND OUT 1 7 SEGMENT DATA IN @R0
MOV A, @R0
MOV P0,ACC
; SEND SCAN CODE
POP ACC
MOV P2,ACC
MOV R5,#5
CALL DELAY1
; CHANGE SCAN CODE
RL A
INC R0
DJNZ R2, S1
RET
;----------------------------------------------------------------------
SCANS:
MOV R4,#55
SC: CALL SCAN1
DJNZ R4,SC
RET
;----------------------------------------------------------------------
; UPDATE MIN,SEC
TIME_PRO:
CALL CONV1 ; CONV. TO ASCII SHOW TO 7SEG
; CHECK ALARM ON/OFF............
JB ALB,TI1
RET
TI1:
; CHECK ALARM.................
MOV A,MIN
MOV B,MM
CJNE A,B,BK
MOV A,SEC
MOV B,SS
CJNE A,B,BK
; TIME MATCH....................
CLR TO_LED
CALL TIME_OUT
BK:
RET
;----------------------------------------------------------------------
TIME_OUT:
CALL INIT_TIMER_STOP
PK:
CALL SCAN1
JB K3,PK
JMP RESET
RET
;----------------------------------------------------------------------
BZ:
MOV R6,#0
B1: CALL DE
CPL SPK
DJNZ R6,B1
RET
;----------------------------------------------------------------------
DE: MOV R7,#50
DE1: NOP
DJNZ R7,DE1
RET
;----------------------------------------------------------------------
END
[ Last edited by pkl0001 on 24-8-2004 at 01:36 PM ] |
|
|
|
|
|
|
|
|
|
|
发表于 25-8-2004 11:57 AM
|
显示全部楼层
pkl0001 于 24-8-2004 01:32 PM 说 :
这是我从书上抄下来的。
本来是一个时钟,后来我把它改成计时器。
这还没有完成,因为遇上问题还不能解决。
基本上这程式是这样的:
Prees K1 start timer,
Than prees k2 Stop/Pause timer
Than press k ...
最近在考试中,迟些再帮你捉虫~~~
大压力~~~~~~ |
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 25-8-2004 12:48 PM
|
显示全部楼层
faiko 于 25-8-2004 11:57 AM 说 :
最近在考试中,迟些再帮你捉虫~~~
大压力~~~~~~
我先说声谢谢!!!! |
|
|
|
|
|
|
|
|
|
|
发表于 25-8-2004 03:26 PM
|
显示全部楼层
err。。 好像很难明白你的ASM,你有流程图(flow chart)吗? 那样的话,比较容易让人明白。
在写ASM时,最难的不是在编写,而是难在了解编写人是怎样编写。。。。 |
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 25-8-2004 03:54 PM
|
显示全部楼层
jefferylee 于 25-8-2004 03:26 PM 说 :
err。。 好像很难明白你的ASM,你有流程图(flow chart)吗? 那样的话,比较容易让人明白。
在写ASM时,最难的不是在编写,而是难在了解编写人是怎样编写。。。。
不懂耶!!!
我的 asm 全都是从书上学的。
并没有受过真正的 8051 教学课程。
所以你说的流程图(flow chart)是什么我都不知道,书上也没写。
谢谢你!!!你多多指教!!! |
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 25-8-2004 05:19 PM
|
显示全部楼层
faiko 于 25-8-2004 11:57 AM 说 :
最近在考试中,迟些再帮你捉虫~~~
大压力~~~~~~
考试噢!!
努力噢!!
放轻松,别让压力压死你。。。
你是什么学校的学生? |
|
|
|
|
|
|
|
|
|
|
发表于 26-8-2004 07:26 PM
|
显示全部楼层
pkl0001 于 25-8-2004 05:19 PM 说 :
考试噢!!
努力噢!!
放轻松,别让压力压死你。。。
你是什么学校的学生?
哦哦哦~~~~~压死人了~~~ 我在多媒体大学就读
星期五才考完,到时再帮你
p/s: 我想知道一下,那个Exact步骤来出现这个bug(例如,在当中是否有过timer setting,非正常使用步骤?,等等)。因为你说你是modify code,所以会比较难绘画流程图(因此,你的原码需要一段时间来看,呵呵)。可以给我那个.hex档案吗?email给我。因为我的compiler不知道去了那里,我可以用来simulate 8051 的output。这样就容易得多了。 |
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 26-8-2004 07:55 PM
|
显示全部楼层
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 27-8-2004 10:17 AM
|
显示全部楼层
|
|
|
|
|
|
|
|
|
|
发表于 31-8-2004 08:36 PM
|
显示全部楼层
你的原码,我大概看了几遍……基本上还看不出什么问题……
有些细节要注意一下,当你把JNB JB用在port pin上的时候,这些指令是在perform read pin operation。基本上,就是把microcontroller port变成input mode。这时候,就要写入‘1’给input port pin。详细的理由,可以参考书本,多数在appendix可以找到。
by default,每一个port的value是‘1’,但是,最好在之前郑重declare一下……
然后,你是用什么方法来接port pin?若是用button switch等有弹簧的,要call short delay for debouncing time……我想keypad的section会提到。
最后,我想知道你的timer是怎样function的?例如,如何set minute,second? 怎样操作?可以大概地叙述一下吗?
还有,你的虫是如何出现的?set timer后,5-7(有没有比较明确的号码?)次不能在设定的时间下,停下来?在此时,中间有操作别的东西吗? |
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 1-9-2004 01:17 PM
|
显示全部楼层
faiko,考完式了吧!几时放榜?
真的很感激你的回复。
有些细节要注意一下,当你把JNB JB用在port pin上的时候,这些指令是在perform read pin operation。基本上,就是把microcontroller port变成input mode。这时候,就要写入‘1’给input port pin。详细的理由,可以参考书本,多数在appendix可以找到。
by default,每一个port的value是‘1’,但是,最好在之前郑重declare一下……
然后,你是用什么方法来接port pin?若是用button switch等有弹簧的,要call short delay for debouncing time……我想keypad的section会提到
你说的没错,书上的确有提到这点。谢谢你的提醒!!!
最后,我想知道你的timer是怎样function的?例如,如何set minute,second? 怎样操作?可以大概地叙述一下吗?
基本上这程式是这样的:
当程式启动。。。只能够按K1和K4而已。。。
K1是“开始计时”。。。
K4是“设定计时的时间”。。。
当启动“开始计时”。。。只能够按K2而已。。。
K2是“停止 / 暂停”。。。
当K2 “停止 / 暂停”按下后只能够按K1和K3而已。。。
K1是“继续计时”。。。(如果计时器停在00:05,按下止键后继续6,7,8。。)
K3是“RESET TIMER”。。。(计时器回到00:00)
当启动“设定计时的时间”。。。只能够按K4,K5和K6而已。。。
当按下止键,七段显示器将显示00:01
如果要取消设定“00:00”
K4是“OK”。。。
K5是“设定分钟”。。。每按一次分钟加一
K6是“设定秒钟”。。。每按一次秒钟加一
还有,你的虫是如何出现的?set timer后,5-7(有没有比较明确的号码?)次不能在设定的时间下,停下来?在此时,中间有操作别的东西吗?
当程式启动,设定好计时的时间(计时的时间只需要设定一次),启动计时器(K1),时间到,再按“RESET TIMER”(K3)。再启动计时器(K1),时间到,再按“RESET TIMER”(K3)。重复几次后,计时器不会在事先设定好计时的时间停下,而是继续计时!!!在此中间没有操作别的东西。
[ Last edited by pkl0001 on 1-9-2004 at 01:47 PM ] |
|
|
|
|
|
|
|
|
|
|
发表于 3-9-2004 05:41 PM
|
显示全部楼层
呃呵呵~~昨天刚刚从马六甲回来……参加朋友的21岁生日。不知几时轮到我……
回话题,昨天看了你的解说后,大致上懂得如何操作了。其实,流程图(flowchart)就是从你的解说画出来的。只要你知道你的程序如何操作,在从文字变换成流程图,一切就一目了然。
从simulation来看,你的计时器只能在设定的时间内停五次,这还包括停止后更改设定时间。暂停时间是例外。换句话说,设定好时间-->start timer-->time up-->reset timer,这个步骤只能够操作五次。除非你按8051的reset button。
你的虫出现是因为SUBROUTINE的关系。我从模拟器看见那个Stack pointer(default value= 07H)在设定的时间停止后,就incremented。结果,你的ALB, Alarm bit在location 20H.0被overwrite了。这个时候,你的计时器就无法在设定的时间内停止。
通常,Stack pointer的数值一直增加的原因有两个,
- Push 跟 Pop,这两个指令出现次数不同。当这两个指令不对称时,就很容易会出现memory overwrite的现象。
- Call 跟 Ret,没有一个直接的联系。当你每次执行call指令时,memory address会被store进stack里面。当microprocessor看到ret时,它便可以回到当初它被call的location。所以,同样的,call跟ret必须要对称。
目前,我暂时还无法找出问题的根源。只知道,不是push & pop的问题,而是你的call module的问题。在给我少少时间,我再帮你看看。
p/s:你可以再寄你的.LST档案给我吗?上次忘了跟你拿……
[ Last edited by faiko on 3-9-2004 at 05:45 PM ] |
|
|
|
|
|
|
|
|
|
|
发表于 3-9-2004 11:38 PM
|
显示全部楼层
啊哈!找到了!
问题出现在你的TIME_OUT SUBROUTINE,在TIME_PRO SUBROUTINE里你CALL TIME_OUT SUBROUTINE,而在TIME_OUT SUBROUTINE里,你却直接JMP到RESET去。结果,漏了两个RET。这个造成了STACK OVERFLOW。基本上,个人认为TIME_OUT SUBROUTINE可以直接放在TIME_PRO里,不需要CALL。至于,如何解决STACK OVERFLOW的问题,就要看你了。因为我的ASSEMBLER不能ASSEMBLE你的原码(它不能ASSEMBLE ALB EQU 20H.0,这一类的SYNTAX,要重新写过……(>_<||)……),所以没办法帮你改。
靠你了,加油哦~~~ |
|
|
|
|
|
|
|
|
|
|

楼主 |
发表于 4-9-2004 01:50 AM
|
显示全部楼层
|
|
|
|
|
|
|
|
|
|
发表于 4-9-2004 10:08 AM
|
显示全部楼层
|
|
|
|
|
|
|
|
| |
本周最热论坛帖子
|