mov DPTR, memory_location
mov a,a@DPTR
;write accumulator to external RAM
movx @DPTR,A
;write external RAM to accumulator
movx A,@DPTR
mov R0,#0x80
mov A,@R0 ;write value stored in address that is stored in R0 to accumulator
or
mov @R0,A ;write value in accumulator to address stored in R0
mov SP,#0x7F
mov A, <DATA>
push ACC
Code:mov SP,#0x7F mov A, <DATA> push ACC
The stack pointer is incremented before the value is written to the address in the stack pointer when a push instruction is executed. This means you would write the address - 1 to the stack pointer prior to pushing the stack. The above code will access location 0x80.
In most of my 8052 code, I use the upper 128 region as the stack. The first instruction in all of my code is mov SP,#0x7F. This gets the stack pointer out of the R register space. The upper 128 is then used as a 128 byte stack, while I use the lower 128 for all of my variable processing.
HELLO:
call prt_mess
DB 'HELLO, WORLD',00
...................
prt_mess:
pop Acc
mov dpl, Acc
pop Acc
mov dph, Acc
print the message after CALL
..................
mov Acc, dph
push reg ;restore return address
mov Acc, dpj
push reg
ret
; Internal RAM testing using indirect addressing
; start date = 5.05.2013
;
; phase 1: initial program.
; block move from $80-$bf to $c0-$ff
; first fill up $80-$bf with 00-3f
;
org 00h
jmp start
org 30h
source equ R0
dest equ R1
;
start:
; fill $80-$BF with numbers 00-#F
mov source, #0x80 ; source address
mov B,#0x40 ; 64 bytes to fill
mov A,#00 ; start number
next: mov @R0,A ; write Acc to source RAM
inc A ; A=A+1
inc source ; R0=R0+1
djnz B,next ; Do it 64 times
;Block move
mov source, #0x80 ; source address
mov dest, #0xC0 ; destination address
mov B,#0x40 ; number of bytes to move
repeat: mov A,@R0
mov @R1,A
inc source
inc dest
djnz b,repeat
here: jmp here ; stop here
end
FCTL: SETB KYF ;SET KEY FLG
CJNE A,#20H,$+3 ;A<20H ?
JC FCTL1 ;YES
CJNE A,#7FH,$+3 ;A<7FH ?
JNC FCTL1 ;NO
CLR KYF
FCTL1: RET
HUND DATA 0x30 ;hundreds place digit register
TEN DATA 0x31 ;tens place digit register
ONE DATA 0x32 ;ones place digit register
org 0x0000 ;reset vector
ajmp START ;jump to start of main code
;this space reserved for IRQ space
org 0x0100 ;main code starts past IRQ space
START: mov A,#0xFF ;place value to convert to BCD in A
acall BIN2BCD ;convert to BCD using this routine
acall LEDSegFetch ;convert to LED segment data using this routine
ajmp $ ;replace this line with rest of your code
;*************************************************************************************************
;*************************************************************************************************
;** **
;** LED Segment Pattern Fetch **
;** **
;*************************************************************************************************
;*************************************************************************************************
;The following function takes the BCD values in registers HUND, TEN and ONE, and replaces
;them with table values that will light up the LED segments in the correct digit pattern
;that matches the replaced BCD value. After this code execution completes, the segment patterns
;will be stored in registers HUND, TEN and ONE -
;HUND - Contains segment data for hundreds place digit
;TEN - Contains segment data for tens place digit
;ONE - Contains segment data for ones place digit
LEDSegFetch: mov DPTR,#CCDisplay ;DPTR to first line of table
mov A,HUND ;fetch BCD value from HUND, place in accumulator
movc A,@A+DPTR ;fetch LED pattern from table line number in A
mov HUND,A ;store in HUND, replacing original BCD value
mov A,TEN ;fetch BCD value from TEN, place in accumulator
movc A,@A+DPTR ;fetch LED pattern from table line number in A
mov TEN,A ;store in TEN, replacing original BCD value
mov A,ONE ;fetch BCD value from ONE, place in accumulator
movc A,@A+DPTR ;fetch LED pattern from table line number in A
mov ONE,A ;store in ONE, replacing original BCD value
ret ;done
;*************************************************************************************************
;*************************************************************************************************
;** **
;** 8-bit Binary to BCD Converter **
;** **
;*************************************************************************************************
;*************************************************************************************************
;The following subroutine converts a single byte into 3 binary coded decimal bytes, and
;stores them into buffer registers in RAM.
BIN2BCD: mov B,#0x64 ;divisor = 100
div AB ;divide value in accumulator by 100
mov HUND,A ;store integer in HUND register
mov A,B ;transfer remainder to accumulator
mov B,#0x0A ;divisor = 10
div AB ;divide value in accumulator by 10
mov TEN,A ;store integer in TEN register
mov ONE,B ;store remainder in ONE register
ret ;done
;*************************************************************************************************
;*************************************************************************************************
;** **
;** Common Cathode 7-Segment LED Display Patterns **
;** **
;*************************************************************************************************
;*************************************************************************************************
;The following look up table holds the binary patterns to light up the segments of a
;7 segment LED display in a pattern which resembles digits.
CCDisplay: db 00111111b ;0
db 00000110b ;1
db 01011011b ;2
db 01001111b ;3
db 01100110b ;4
db 01101101b ;5
db 01111101b ;6
db 00000111b ;7
db 01111111b ;8
db 01101111b ;9
end
; Multiplication Table x2 to x9
; Max output is Decimal 99
;
; start date = 5.05.2013
; phase 1: Make use of the 7 seg display routine
; phase 2: initial trial 6.05.2013
; phase 3: tested with John's "MULT codes" on 10.05.2013
;
org 00h
jmp start
org 1bh
jmp T1_isr
org 100h
sa equ 01h
sb equ 02h
sc equ 04h
sd equ 08h
se equ 10h
sf equ 20h
sg equ 40h
sdp equ 80h
;
d_flag bit 20h.0 ; disp flag
ovf bit 20h.2 ; overflow flag
button bit p2.7 ; button
sav_tl1 equ 30h ; temp for T1L
sav_th1 equ 31h ; temp for T1H
unit_dig equ 32h ; unit digit disp pattern
ten_dig equ 33h ; tenth digit disp pattern
m_cand equ 34h ; multiplicand
product equ 35h
unit equ R2 ; unit digit
tenth equ R3 ; tenth digit
hund equ R4
;
start:
mov SP,#0x80 ; move stack to upper RAM 0x80
call init
call display ; display them
nxt_num:
mov M_cand,#01 ; init multiplicand
but_loop:
call delay_200ms ; debounce button
jb button,but_loop ; button not pressed, loop
call mult ; do multiplication
call chk_product ; check if product out of range
jb ovf,nxt_num ; O.O.R. goto next number
call bin2BCD ; convert binary to BCD
call display ; convert to 7S pattern
call delay_200ms
call delay_200ms
jmp but_loop ; wait for next button press
mult: mov a,p2 ; get multiplier
anl a,#0x0f ; mask of upper nibble
mov b,m_cand ; get multiplicand
mul ab ; do the multiplication
mov product,a ; discard MSB byte
inc m_cand ; multiplicand +1
ret ; Acc is LSB of product
chk_product:
clr ovf ; clear overflow flag
mov a,product
cjne a,#99,$+3 ; Is product <100?
jc chk_exit ; yes
setb ovf ; set over flow flag
chk_exit: ret
BIN2BCD:
mov B,#0x64 ;divisor = 100
div AB ;divide value in accumulator by 100
mov HUND,A ;store integer in HUND register
mov A,B ;transfer remainder to accumulator
mov B,#0x0A ;divisor = 10
div AB ;divide value in accumulator by 10
mov TENTH,A ;store integer in TEN register
mov UNIT,B ;store remainder in ONE register
ret ;done
display:
mov a,r2
movc a,@a+dptr ; get number patter for display
mov unit_dig,a
mov a,r3
movc a,@a+dptr ; get number patter for display
mov ten_dig,a
ret
init:
mov DPTR,#TABLE ; dptr = 7 segment table address
mov unit, #0 ; unit digit
mov tenth, #0 ; tenth digit
mov TMOD,#0x10 ; set up timer1 for 10mS
mov TL1,#0xf0 ; Mode=1
mov TH1,#0xd8 ; 0xD8F0 is 10ms counting
mov sav_tl1,#0xf0
mov sav_th1,#0xd8
setb tr1 ; start timer1
setb et1 ; enable timer1 interrupt
setb ea ; enable global interrupt
ret
T1_isr:
PUSH ACC
PUSH PSW
PUSH DPH
PUSH DPL
clr TR1 ;stop timer1
mov TL1,sav_tl1 ;restore t1
mov TH1,sav_th1
setb TR1 ;start timer1
cpl d_flag ;toggle d_flag
jb d_flag,upper ;1=upper 0=lower
lower: clr p3.0 ;switch off both digits
clr p3.1
mov p1,unit_dig ;get new value
setb p3.0 ;turn on lower digit
sjmp isr_exit
upper: clr p3.0 ;switch off both digits
clr p3.1
mov p1,ten_dig ;get new value
setb p3.1 ;turn on upper digit
isr_exit:
clr TF1 ;clear timer1 flag
POP DPL
POP DPH
POP PSW
POP ACC
reti
;
; 7 segment pattern table
;
table: db sa+sb+sc+sd+se+sf ; 0
db sb+sc ; 1
db sa+sb+sg+se+sd ; 2
db sa+sb+sc+sd+sg ; 3
db sb+sc+sf+sg ; 4
db sa+sc+sd+sf+sg ; 5
db sa+sc+sd+se+sf+sg ; 6
db sa+sb+sc ; 7
db sa+sb+sc+sd+se+sf+sg ; 8
db sa+sb+sc+sd+sf+sg ; 9
delay_200ms:
mov r4,#0ffh
sjmp delay
delay_20ms:
mov r4,#1
loop0: djnz r4,loop0
ret
delay:
loop2: mov r5,#04Fh
loop1: djnz r5,loop1
djnz r4,loop1
ret
end
conv2BCD:
;divider in Acc
mov b,#100 ; put divisor in B
div ab ; A/B ans. in A, rem. in B
jz bcd2 ; If quotient = 0
nop ; discard 100's digit
bcd2: mov a,#10 ; put in new divisor
xch a,b ; divisor in B and remainder in Acc
div ab ; Acc/B
mov tenth,a ; get 10th digit
xch a,b ; Put B in ACc
mov unit,a ; get unit digit
ret
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?