Tutorial Microcontroller MCS-51 ATMEL ISP

Microcontroller Kits
Programmer and Target 89s51

Simple Mikrokontroller 89s51 Trainer


Standart
Mikrokontroller 89s51 Trainer


Super Mikrokontroller Trainer 89s51

+

All Item Include

Programmer
Via USB

 

 

32bit Floating point package for the 8051

; 32bit Floating point package for the 8051
; Created by Jerson Fernandes for the C16 meta assembler
; floating point format
           ; exponent, 24 bits mantissa
           ; xxxxxxxx, Sxxxxxxx xxxxxxxx xxxxxxxx
           ; stored internally from right to left
           CPU "8051.tbl"
           hof "INT8"
           incl "8051sfr.asm"
 ORG 8 ;internal memory
           float_arg: equ 3 ;3 bytes mantissa
           float_exp: equ 1 ;1 byte exponent
           expbias: equ 128 ;exponent bias
Quo: dfs float_arg ;holds quotient of divide
           Aarg: dfs float_arg
           Aexp: dfs float_exp
           Barg: dfs float_arg
           Bexp: dfs float_exp
           Aext: dfs 1 ;extension for Aarg
           Aext2: dfs 1 ;for holding the aligned bit
           TOS:
 ORG 0
 ;This segment is to test the functionality of the library
start: mov sp,#TOS ;point to the top of stack
           mov Aarg,#low 1
           mov Aarg+1,#high 1
           mov Aarg+2,#0 ;high -10
           acall int2float
           ;
           acall copy_ab
           ;
           mov Aarg,#low 1000
           mov Aarg+1,#high 1000
           mov Aarg+2,#0
           acall int2float
           ;
           acall fpmul32
           mov a,aarg
           push acc
           mov a,Aarg+1
           push acc
           mov a,Aarg+2
           push acc
           mov a,Aexp
           push acc
           mov Aarg,#low 2000
           mov Aarg+1,#high 2000
           mov Aarg+2,#0
           acall int2float
           acall copy_ab
 pop acc
           mov Aexp,a
           pop acc
           mov Aarg+2,a
           pop acc
           mov Aarg+1,a
           pop acc
           mov Aarg,a
 lcall fpdiv32
           acall float2int
           sjmp start
; This is where the library begins
;Copy ArgA to ArgB
Copy_AB:mov r7,#float_arg
        mov r0,#Aarg
        mov r1,#Barg
copy_AB_5:
        mov a,@r0
        mov @r1,a
        inc r0
        inc r1
        djnz r7,copy_AB_5
        mov Bexp,Aexp
        ret
; Convert a integer to a floating point number
; Input - 24 bit signed integer @ Aarg
; Output- 32 bit floating point number @ Aarg
int2float:
        acall Normalize
        ret
; Normalize the 24 bit signed integer in Aarg
Normalize:
        mov r6,#24 ;exponent counter
        mov a,Aarg+2 ;extract sign
        anl a,#80h
        mov r5,a ;keep in R5
        jz norm5
;negative number make +ve as we have the sign
        mov a,Aarg
        cpl a
        add a,#1 ;2s complement
        mov Aarg,a
        mov a,Aarg+1
        cpl a
        addc a,#0
        mov Aarg+1,a
        mov a,Aarg+2
        cpl a
           addc a,#0
           mov Aarg+2,a
           Norm5: mov r0,#Aarg+2
           mov a,@r0
           orl a,#0
           jnz Norm10
           ;the highest 8 are 0, shift 8
           mov a,#0
           xch a,Aarg
           xch a,Aarg+1
           xch a,Aarg+2
           clr c
           mov a,r6
           subb a,#8
           mov r6,a ;update the exponent
           ;
           jnc Norm5
           Norm10:mov a,@r0 ;read the msb
           jb ACC+7,Norm_end
           ;shift one bit left
           mov a,Aarg
           clr c
           rlc a
           mov Aarg,a
           mov a,Aarg+1
           rlc a
           mov Aarg+1,a
           mov a,Aarg+2
           rlc a
           mov Aarg+2,a
           djnz r6,Norm10 ;note the shift in the exponent too
           Norm_end:
           mov a,#expbias
           add a,r6
           mov Aexp,a
;now make the msbit implicit and put in the sign there
           mov a,r5
           orl a,#7fh
           anl a,Aarg+2
           mov Aarg+2,a ;sign is always for int2float
           ret
; Float to integer conversion routine
           ; Input - floating point number in Aarg,Aexp
           ; Output- 24 bit signed integer in Aarg
           float2int:
           mov a,Aexp
           clr c
           subb a,#expbias
           jc res032 ;result is 0
           cjne a,#24,$+3 ;overflow,return a 0 int
           jnc res032
           mov r6,a ;keep the exponent here
;find out how much to shift the float to get our int
           mov a,#24
           clr c
           subb a,r6
           mov r6,a
           ;take out the sign and make msb explicit
           mov a,Aarg+2 ;keep in R5
           mov r5,a
           orl a,#80h
           mov Aarg+2,a ;explicit msb
           ;now shift the float to form the int
           flint10:
           mov a,r6 ;if exp >= 8, shift bytes
           clr c
           subb a,#9
           jnc flint20
           ;now do bit shifts
           flint15:
           clr c
           mov a,Aarg+2
           rrc a
           mov Aarg+2,a
           mov a,Aarg+1
           rrc a
           mov Aarg+1,a
           mov a,Aarg+0
           rrc a
           mov Aarg+0,a
           djnz r6,flint15
           ;we're done getting the int,restore the sign
           mov a,r5
           anl a,#80h
           jz flint30
           ;restore the negative number
           mov a,Aarg
           cpl a
           add a,#1
           mov Aarg,a
           mov a,Aarg+1
           cpl a
           addc a,#0
           mov Aarg+1,a
           mov a,Aarg+2
           cpl a
           addc a,#0
           mov Aarg+2,a
           flint30:ret
           flint20:
           ;shift right 8 bits
           clr a
           xch a,Aarg+2
           xch a,Aarg+1
           xch a,Aarg+0
           ;and adjust the exp counter in r6
           mov a,r6
           subb a,#8
           mov r6,a
           sjmp flint10
           res032:
           clr a
           mov Aarg+0,a
           mov Aarg+1,a
           mov Aarg+2,a
           ret
;Floating point divide
           ; Input - Arg 1 in Aarg, Aexp
           ; - Arg 2 in Barg, Bexp
           ; Output- Divide arg1 by arg2
           ; - result in Aarg
           ; Temp - R5 resulting sign
           ; acc for dividend is
           ; Aarg[2,1,0],Quo[2,1,0] msb first
           fpdiv32:
           ;check if Bexp == 0
           mov a,Bexp
           jnz fpd10
           ajmp fpdivz
           fpd10: mov a,Aarg+2 ;extract resulting sign
           xrl a,Barg+2
           anl a,#80h ;keep the sign bit here
           mov r5,a
           ;make the msb explicit in args
           mov a,#80h
           orl a,Aarg+2
           mov Aarg+2,a
           mov a,#80h
           orl a,Barg+2
           mov Barg+2,a
           ;if A<B mantissa, divide, else align
           clr a
           mov Quo,a
           mov Quo+1,a
           mov Quo+2,a
           clr c
           mov a,Aarg
           subb a,Barg
           mov a,Aarg+1
           subb a,Barg+1
           mov a,Aarg+2
           subb a,Barg+2
           jc fpdok
           ;make A mantissa < B mantissa
           clr c
           mov a,Aarg+2 ;msb
           rrc a
           mov Aarg+2,a
           mov a,Aarg+1
           rrc a
           mov Aarg+1,a
           mov a,Aarg
           rrc a
           mov Aarg,a ;lsb
           mov a,Aext2 ;msb
           rrc a
           mov Aext2,a ;move into quotient
           ;adjust the Aexp accordingly
           mov a,Aexp
           inc a
           mov Aexp,a
           ;get the resulting exponent in Aexp
           fpdok: clr c
           mov a,Aexp
           subb a,Bexp
           add a,#expbias
           mov Aexp,a ;resulting exponent here
           fpdargok:
           clr a
           mov Aext,a
           mov r7,#24 ;initialize bit counter for divide
           fpdloop32:
           ;shift left 1 bit
           clr c
           mov a,Aext2
           rlc a
           mov Aext2,a
           mov a,Aarg+0
           rlc a
           mov Aarg+0,a
           mov a,Aarg+1
           rlc a
           mov Aarg+1,a
           mov a,Aarg+2
           rlc a
           mov Aarg+2,a
           ;move the bit into our accumulator
           mov a,Aext
           rlc a
           mov Aext,a
           ;subtract
           clr c
           mov a,Aarg+0
           subb a,Barg+0
           mov a,Aarg+1
           subb a,Barg+1
           mov a,Aarg+2
           subb a,Barg+2
           mov a,Aext
           subb a,#0
           jc nosub ;cannot subtract
           clr c
           mov a,Aarg+0 ;subtract
           subb a,Barg+0
           mov Aarg+0,a
           mov a,Aarg+1
           subb a,Barg+1
           mov Aarg+1,a
           mov a,Aarg+2
           subb a,Barg+2
           mov Aarg+2,a
           mov a,Aext
           subb a,#0
           mov Aext,a
           nosub: cpl c ;shift in the complement of C
           mov a,Quo ;into the result
           rlc a
           mov Quo,a
           mov a,Quo+1
           rlc a
           mov Quo+1,a
           mov a,Quo+2
           rlc a
           mov Quo+2,a
           djnz r7,fpdloop32
           ;move the quotient to Aarg and make msb implicit
           mov a,Quo+1
           mov Aarg+1,a
           mov a,Quo+0
           mov Aarg+0,a
           mov a,r5
           jnz minusdiv
           mov a,Quo+2
           anl a,#7fh ;make msb implicit if +ve number
           mov Aarg+2,a
           ret
           minusdiv:
           mov a,Quo+2
           mov Aarg+2,a
           ret
           fpdivz:
           ;return divide by zero error
           ret
           fpov: ;return divide overflow
           ret
;Floating point multiplication
           ; Input - Aarg,Aexp
           ; - Barg,Bexp
           ; Output- Aarg,Aexp
           ; partial product = Quo[2..0],Aarg[2..0]
           fpmul32:
           ;if A == 0 || B == 0 result = 0
           mov a,Aexp
           jz fpm10
           mov a,Bexp
           jnz fpm20
           fpm10: ljmp res032
           fpm20: ; get the resulting exponent
           clr c
           mov a,Aexp
           subb a,#expbias
           add a,Bexp
           mov Aexp,a ;store resulting exponent here
           jnc fpm30
           ljmp fpov
           fpm30: ;make the msbs explicit
           mov a,Aarg+2
           orl a,#80h
           mov Aarg+2,a
           mov a,Barg+2
           orl a,#80h
           mov Barg+2,a
           ;now multiply using Quo as the partial product
           clr a
           mov Quo,a
           mov Quo+1,a
           mov Quo+2,a
           mov r7,#24 ;bits
           fpmloop:
           ;
           mov a,Aarg
           rrc a
           jnc fpmnoadd
           ;add the multiplier to the product
           mov a,Quo
           add a,Barg
           mov Quo,a
           mov a,Quo+1
           addc a,Barg+1
           mov Quo+1,a
           mov a,Quo+2
           addc a,Barg+2
           mov Quo+2,a
           fpmnoadd:
           ;right shift the product
           mov a,Quo+2
           rrc a
           mov Quo+2,a
           mov a,Quo+1
           rrc a
           mov Quo+1,a
           mov a,Quo
           rrc a
           mov Quo,a
           ;shift right the multiplicand
           clr c
           mov a,Aarg+2
           rrc a
           mov Aarg+2,a
           mov a,Aarg+1
           rrc a
           mov Aarg+1,a
           mov a,Aarg
           rrc a
           mov Aarg,a
           fpm40: djnz r7,fpmloop
           ;multiplication is over
           ;check for normalisation now
           mov a,Quo+2
           jb acc+7,fpm50
           clr c
           mov a,Quo
           rlc a
           mov Quo,a
           mov a,Quo+1
           rlc a
           mov Quo+1,a
           mov a,Quo+2
           rlc a
           mov Quo+2,a
           dec Aexp
           fpm50: mov Aarg,Quo
           mov Aarg+1,Quo+1
           mov a,r5
           anl a,#80h ;check sign of result
           jz fpmplus
           mov Aarg+2,Quo+2
           ret
           fpmplus:
           mov a,Quo+2
           anl a,#7fh
           mov Aarg+2,a
           ret

Comments, questions and discussion about this topic

BACK