This project shows the multiplication and division process using PIC16C55. To simulate circuit in this project, initially activate Mixed Mode simulator from the Schematic Editor window. Simulation can be performed by selecting Run Transient analysis (Oscillograph) from Simulation menu.
The circuit contains a PIC16C55, a voltage source, 74LS245 Octal 3-state bus transceiver,7404 NOT gate, HPDL-1414 Four Character Alphanumeric Display.
PIC 16C55 has only two 8 bit port and one 4 bit port. This circuit require two 8 bit input and one 16 bit out put .For implementing this a network of 74245 is designed according to the control pins DIR1, DIR2 from PORTA. PORTB and PORTC act as input port or output port.
According to the MODE control the circuit is perform multiplication and division. MODE control pin ids read through RA0.if MODE is high then multiplication is performing other wise division perform.
MODE = 1 (Multiplication)
Multiplicand is read through PORT B and multiplier through PORTC by setting 74245 networks in input mode. HPDL1414 display shows result of multiplication.
MODE = 0 (Division)
Dividend is read through PORT B and divisor through PORTC by setting 74245 networks in input mode. HPDL1414 display shows result of division. First two digits are quotient and last two digits are remainder.
The source code written in Assembly language can be viewed from the code editor window
The program is as shown:
#include p16c5x.inc
; VARIABLE DEFINITIONS
temp_var udata
multiplicand res 1 ;multiplicand varible declaration
multiplier res 1 ;multiplier variable declaration
result res 1 ;result variable declaration
count res 1 ;count declaration
resultmsb res 1 ;resultmsb variable declaration
dig0 res 1 ;dig0 variable declaration
dig1 res 1 ;dig1 variable declaration
dig2 res 1 ;dig2 variable declaration
dig3 res 1 ;dig3 variable declaration
control res 1 ;control variable declaration
mode res 1 ;mode variable declaration
dividend res 1 ;dividend variable definition
divisor res 1 ;divisor variable definition
quotient res 1 ;quotient variable definition
remainder res 1 ;remainder variable definition
counter res 1 ;counter variable definition
dividend_d res 1 ;dividend_d variable definition
remainder_1 res 1 ;remainder_1 variable definition
;********************************************************************
reset_vector code 0x1ff ;processor reset vector
goto start
MAIN CODE 0x000
start
;read 0 the pin of port A
;set PORTA <1:0> as input
;set PORTA <3:2> as output
;bit pattern is 0011(0x03) 0 for output and 1 for input
movlw 0x03 ;move literal value to accumulator
tris PORTA ;set PORTA <1:0> as inpu, set PORTA <3:2> as output
;check multiplication or division
;read PORTA <0>
movf PORTA,0 ;move PORT A to accumulator
movwf mode ;move accumulator to mode
;if mode<0> is 0 then division
;if mode<0> is 1 then multiplication
;check mode <0> is 0 if yes call division
btfss mode,0 ;skip if mode<0> is one
goto division ;goto nochange
;multiplication
;port reading
movlw 0x00 ;move literal value to accumulator
movwf PORTA ;move accumulator to PORT A
movlw 0xff ;move literal value to accumulator
tris PORTB ;Set PORT B as input
movf PORTB,0 ;move PORT B to accumulator
movwf multiplicand ;move accumulator to multiplicand
movlw 0xff ;move literal value to accumulator
tris PORTC ;Set PORT C as input
movf PORTC,0 ;move PORT C to accumulator
movwf multiplier ;move accumulator to multiplier
call multiplication ;call sub routine muiltiplication
call display
goto repeat
;*******************************************************************************A
;port reading
division movlw 0x0 ;move literal value to accumulator
movwf PORTA ;move accumulator to port A
movlw 0xff ;move literal value to accumulator
tris PORTB ;Set port B as input
movf PORTB,0 ;move port B to accumulator
movwf dividend ;move accumulator to dividend
movlw 0xff ;move literal value to accumulator
TRIS PORTC ;Set PORT C as input
movf PORTC,0 ;move PORT C to accumulator
movwf divisor ;move accumulator to divisor
movlw 0x5 ;move literal value to accumulator
movwf counter ;move accumulator to counter for initialize
clrw ;clear accumulator
movwf quotient ;move accumulator to quotient
movwf remainder ;move accumulator to remainder
loop1 bcf STATUS,0 ;clear carry
movf dividend,0 ;move dividend to accumulator
movwf dividend_d ;move accumulator to dividend_d
;shift right it by 4
rrf dividend_d,1 ;right shift
rrf dividend_d,1 ;right shift
rrf dividend_d,1 ;right shift
rrf dividend_d,1 ;right shift
;mask msb by 0
movlw 0x0f ;move literal value to accumulator
andwf dividend_d,1 ;AND accumulator with the dummy dividend, inorder to mask msb of dummy dividend.
;Comparison
movf divisor,0 ;move divisor to accumulator
subwf dividend_d,1 ;subtract accumulator with the dividend_d
btfsc STATUS,0 ;skip next statement if result is negative
call subtraction
rlf quotient,1 ;shift left the quotient
movf dividend,0 ;move dividend to accumulator
movwf dividend_d ;move dividend to its dummy
bcf STATUS,0 ;clear carry
rlf dividend,1 ;shift left the dividend
decfsz counter,1 ;decrement and skip if zero
goto loop1 ;check counter
movf dividend_d,0 ;move dividend_d to accumulator before shifting
movwf remainder ;move dividend_d to remainder
bcf STATUS,0 ;clear carry
rrf remainder,1 ;right shift
rrf remainder,1 ;right shift
rrf remainder,1 ;right shift
rrf remainder,1 ;right shift
;move remainder to result
;move quotient to resultmsb
movf remainder,0 ;move remainder to accumulator
movwf result ;move accumulator to remainder
movf quotient,0 ;move quotient to accumulator
movwf resultmsb ;move accumulator to resultmsb
call display
goto repeat ;infinite loop
subtraction
movlw 0x0f ;move literal value to accumulator
andwf dividend,1 ;AND accumulator with the dividend, inorder to mask msb of dividend.
bcf STATUS,0 ;clear carry
rlf dividend_d,1 ;left shift
rlf dividend_d,1 ;left shift
rlf dividend_d,1 ;left shift
rlf dividend_d,1 ;left shift
movlw 0xf0 ;move literal value to accumulator
andwf dividend_d,1 ;AND accumulator with the dummy dividend, inorder to mask lsb of dummy dividend.
movf dividend_d,0 ;move dividend_d to accumulator
addwf dividend,1 ;add accumulator with the dividend and store the result in divident
bsf STATUS,0 ;set carry
clrw ;clear accumulator
tris PORTB ;set port B as output port
movf dividend,0 ;move dividend to accumulator
movwf PORTB ;write the result to port B
retlw 0
tepeat goto repeat ;infinite loop
multiplication clrw ;clear accumulator
movwf result ;move accumulator value to result
movwf resultmsb ;move accumulator value to result msb
incf multiplier,1 ;increment multiplier by 1 and store in multiplier
movf multiplier,0 ;move multiplier value to accumulator
movwf count ;move accumulator value to count
loop
decfsz count,1 ;decrement count and test is zero if yes then skip
goto addition
retlw 0 ;return subroutine
addition movf multiplicand,0 ;move multiplicand to accumulator
addwf result,1 ;add multiplicand to result and stored in result
btfsc STATUS,0 ;if carry is zero then skip
ncf resultmsb,1 ;if carry then increment msb by 1
clrw ;clear accumulator
goto loop
;******************************************************************************
;hpdl 1414 implementation
;74245 as output mode
display movlw 0xf ;move literal value to accumulator
movwf PORTA ;move accumulator TO port A
movlw 0x00 ;move literal value to accumulator
tris PORTB ;Set PORT B as output
movlw 0x00 ;move literal value to accumulator
tris PORTC ;Set PORT C as output
;display of DIG0
;Set 74245 in output mode
;separation of zeroth digit
movlw 0x0f ;move literal value to accumulator
andwf result,0 ;AND result with accumulator and store the output in accumulator
movwf dig0 ;move accumulator to dig0
;check digit is greater than 9
movlw 0x09 ;move literal value to accumulator
subwf dig0,0 ;subtract 9 from dig0 and result in accumulator
btfss STATUS, 0 ;skip if carry flag is 1
goto nochange ;goto nochange
btfsc STATUS,2 ;skip if zero flag is zero, ie result is non zero
goto nochange ;goto nochange
movlw 0x09 ;move literal value to accumulator
subwf dig0,1 ;subtract 9 from dig0 and result in dig0
movlw 0x13 ;move literal value to accumulator
movwf control ;move control to accumulator
goto porting0 ;goto porting 0
nochange movlw 0x0f ;move literal value to accumulator
movwf control ;move control to accumulator
porting0 movf dig0,0 ;move dig0 value to accumulator
movwf PORTB ;move accumulator to portB
movf control,0 ;move control value to accumulator
movwf PORTC ;move accumulator to port C
movlw 0xff ;move literal value to accumulator
movwf control ;move control to accumulator
movf control,0 ;move control value to accumulator
movwf PORTC ;move accumulator to port C
;zeroth digit complete
;first digit ---------- separation of first digit
movlw 0xf0 ;move literal value to accumulator
andwf result,0 ;AND result with accumulator and output in accumulator
movwf dig1 ;move accumulator to dig1
swapf dig1,1 ;swap and result in dig1
;check digit is greater than 9
movlw 0x09 ;move literal value to accumulator
subwf dig1,0 ;subtract 9 from dig1 and result in accumulator
btfss STATUS, 0 ;skip if carry flag is 1
goto nochange1 ;goto nochange1
btfsc STATUS,2 ;skip if zero flag is zero, ie result is non zero
goto nochange1 ;goto nochange1
movlw 0x09 ;move literal value to accumulator
subwf dig1,1 ;subtract 9 from dig1 and result in dig1
movlw 0x12 ;move literal value to accumulator
movwf control ;move control to accumulator
goto porting1 ;goto porting 1
nochange1 movlw 0x0e ;move literal value to accumulator
movwf control ;move control to accumulator
porting1 movf dig1,0 ;move dig1 value to accumulator
movwf PORTB ;move accumulator to portB
movf control,0 ;move control value to accumulator
movwf PORTC ;move accumulator to port C
movlw 0xff ;move literal value to accumulator
movwf control ;move control to accumulator
movf control,0 ;move control value to accumulator
movwf PORTC ;move accumulator to port C
;separation of second digit
movlw 0x0f ;move literal value to accumulator
andwf resultmsb,0 ;AND resultmsb with accumulator and output in accumulator
movwf dig2 ;move accumulator to dig2
;check digit is greater than 9
movlw 0x09 ;move literal value to accumulator
subwf dig2,0 ;subtract 9 from dig2 and result in accumulator
btfss STATUS, 0 ;skip if carry flag is 1
goto nochange2 ;goto nochange2
btfsc STATUS,2 skip if zero flag is zero, ie result is non zero
goto nochange2 ;goto nochange2
movlw 0x09 ;move literal value to accumulator
subwf dig2,1 ;subtract 9 from dig2 and result in dig2
movlw 0x11 ;move literal value to accumulator
movwf control ;move control to accumulator
goto porting2 ;goto porting 2
nochange2 movlw 0x0d ;move literal value to accumulator
movwf control ;move control to accumulator
porting2 movf dig2,0 ;move dig2 value to accumulator
movwf PORTB ;move accumulator to portB
movf control,0 ;move control value to accumulator
movwf PORTC ;move accumulator to port C
movlw 0xff ;move literal value to accumulator
movwf control ;move control to accumulator
movf control,0 ;move control value to accumulator
movwf PORTC ;move accumulator to port C
;second digit complete
;third digit -------------- separation of third digit
movlw 0xf0 ;move literal value to accumulator
andwf resultmsb,0 ;AND resultmsb with accumulator and output in accumulator
movwf dig3 ;move accumulator to dig3
swapf dig3,1 ;swap and result in dig3
;check digit is greater than 9
movlw 0x09 ;move literal value to accumulator
subwf dig3,0 ;subtract 9 from dig3 and result in accumulator
btfss STATUS, 0 ;skip if carry flag is 1
goto nochange3 ;goto nochange3
btfsc STATUS,2 ;skip if zero flag is zero, ie result is non zero
goto nochange3 ;goto nochange3
movlw 0x09 ;move literal value to accumulator
subwf dig3,1 ;subtract 9 from dig3 and result in dig3
movlw 0x10 ;move literal value to accumulator
movwf control ;move control to accumulator
goto porting3 ;goto porting 3
nochange3 movlw 0x0c ;move literal value to accumulator
movwf control ;move control to accumulator
porting3 movf dig3,0 ;move dig3 value to accumulator
movwf PORTB ;move accumulator to portB
movf control,0 ;move control value to accumulator
movwf PORTC ;move accumulator to port C
movlw 0xff ;move literal value to accumulator
movwf control ;move control to accumulator
movf control,0 ;move control value to accumulator
movwf PORTC ;move accumulator to port C
;testing
;goto repeat
retlw 0
;testing
end ; directive 'end of program'
The source code in the code editor window has to be compiled after making any modifications
(editing). Also the code can be debugged during simulation.