Sei sulla pagina 1di 4

C:\Users\tafatefo\Documents\myCalculator.

asm

1 ;---------------------------------------------------------------------------------------------------#!
2 ;---------------------------------------------------------------------------------------------------#!
3 ;-----------------------------{{Author: Mustafa Okasha}}--------------------------------------------#!
4 ;---------------------------{{Project: BasicCalculator 1.1}}----------------------------------------#!
5 ;---------------------------{{System: 8051 microcontroller}}----------------------------------------#!
6 ;------------------------------{{Released at: 24/2/2013}}-------------------------------------------#!
7 ;---------------------------------------------------------------------------------------------------#!
8 ;---------------------------------------------------------------------------------------------------#!
9 N1 EQU 30H ;#!Ram byte location holds first oeprand
10 N2 EQU 31H ;#!Ram byte locations holds second operand
11 OP EQU 32H ;#!Ram byte location holds operation ascii code
12 R EQU 33H ;#!Ram byte location holds result
13 SIGN EQU 34H ;#!Ram byte location holds result's sign
14 TEMP EQU 35H ;#!Ram byte location holds temporary data
15 DIF BIT 0AH ;#!Digit input flag bit(0,1,2,3,4,5,6,7,8,9)
16 OIF BIT 0BH ;#!Operator input flag bit(+,-,*,/)
17 AIF BIT 0CH ;#!Assignment operator flag bit(=)
18 ORG 0H ;#!Orginate at rom address 0000H
19 AJMP MAIN ;#!Absoulte jump to main routine
20 ;--------------------------------------------------------------------------------------------------#!
21 ;--------------------------------------------------------------------------------------------------#!
22 ORG 30H ;#!Orginate at rom adress 0030H
23 MAIN: ACALL memoryInit ;#!CALL memory initialization subroutine
24 ACALL lcdInit ;#!CALL lcd initialization subroutine
25 ACALL readInput ;#!CALL read input subroutine
26 ACALL calculateResult ;#!CALL calculate result subroutine
27 ACAll printOutput ;#!CALL print output subroutine
28 AJMP MAIN ;#!return and start the program once more
29 ;--------------------------------------------------------------------------------------------------#!
30 ;--------------------------------------------------------------------------------------------------#!
31 memoryInit:
32 CLR A ;#!Clear ACC
33 MOV N1,A ;#!Clear first operand location in ram
34 MOV N2,A ;#!Clear second operand location in ram
35 MOV OP,A ;#!Clear operation location in ram
36 MOV R,A ;#!Clear result location in ram
37 MOV SIGN,A ;#!Clear sign location in ram
38 MOV TEMP,A ;#!Clear result location in ram
39 CLR C ;#!Clear carry bit
40 MOV DIF,C ;#!Clear digit flag bit
41 MOV OIF,C ;#!Clear operator flag bit
42 MOV AIF,C ;#!Clear assignment operator flag bit
43 RET ;#!return to MAIN routine
44 ;--------------------------------------------------------------------------------------------------#!
45 lcdInit:
46 MOV DPTR,#MYCOM ;#!Set DPTR to look-up table's address
47 C1: CLR A ;#!Clear ACC
48 MOVC A,@A+DPTR ;#!Get code from look-up table and placing it into ACC
49 ACALL COMMWRT ;#!CALL LCD command write subroutine
50 INC DPTR ;#!Increment DPTR <DPTR = DPTR + 1>
51 JZ C2 ;#!Jump if ACC = ZERO to end of loop
52 SJMP C1 ;#!If not start the loop again
53 C2: RET ;#!return to MAIN routine
54 ;--------------------------------------------------------------------------------------------------#!
55 readInput:
56 ACALL readKey ;#!CALL keypad subroutine to read one number
57 ACALL validateInput ;#!CALL subroutine to confirm of valid number
58 JB OIF,ERROR ;#!Jump to ERROR routine if OIF = 1
59 JB AIF,ERROR ;#!Jump to ERROR routine if AIF = 1
60 ACALL DATAWRT ;#!CALL subroutine so pass data to LCD
61 ANL A,#0FH ;#!Masking to convert number form ASCII to BCD
62 MOV N1,A ;#!Save number at RAM
63 ACALL readKey ;#!CALL keypad subroutine to read operation(+,-,*,/)
64 ACALL validateInput ;#!CALL subroutine to confirm of valid operation
65 JB DIF,ERROR ;#!Jump to ERROR routine if DIF = 1
66 JB AIF,ERROR ;#!Jump to ERROR routine if AIF = 1
67 ACALL DATAWRT ;#!CALL subroutine so pass data to LCD
68 MOV OP,A ;#!Save operation at RAM
69 ACALL readKey ;#!CALL keypad subroutine to read one number
70 ACALL validateInput ;#!CALL subroutine to confirm of valid number
71 JB OIF,ERROR ;#!Jump to ERROR routine if OIF = 1
72 JB AIF,ERROR ;#!Jump to ERROR routine if AIF = 1
73 ACALL DATAWRT ;#!CALL subroutine so pass data to LCD
74 ANL A,#0FH ;#!Masking to convert number form ASCII to BCD

Page 1
C:\Users\tafatefo\Documents\myCalculator.asm

75 MOV N2,A ;#!Save number at RAM


76 ACALL readKey ;#!CALL keypad subroutine to read assignemt operation (=)
77 ACALL validateInput ;#!CALL subroutine to confirm of valid input
78 JB DIF,ERROR ;#!Jump to ERROR routine if OIF = 1
79 JB OIF,ERROR ;#!Jump to ERROR routine if OIF = 1
80 ACALL DATAWRT ;#!CALL subroutine so pass data to LCD
81 AJMP NOERROR ;#!Jump to END of subroutine if NO ERROR
82 ERROR: ACALL ERRFUN ;#!CALL ERROR subroutine if input was not valid
83 LJMP MAIN ;#!return if ERROR to start of program again
84 NOERROR:RET ;#!return if NO ERROR normally to MAIN
85 ;--------------------------------------------------------------------------------------------------#!
86 calculateResult:
87 MOV A,N1 ;#!Copy first number to ACC
88 MOV B,N2 ;#!Copy second number to B
89 MOV R7,OP ;#!Copy operation to R7
90 CJNE R7,#"+",NEXT11 ;#!Check firstly if the operation was "+", if not jump
91 ADD A,B ;#!If so, Add the two operands
92 MOV R,A ;#!Save result at RAM
93 MOV SIGN,#"+" ;#!Set result sign to positive
94 RET ;#!return to MAIN
95 NEXT11: CJNE R7,#"-",NEXT22 ;#!Check secondly if the operation was "-", if not jump
96 SUBB A,B ;#!If so, Sub the two operands
97 JC NIGATIV ;#!Check on carry for nigative result
98 MOV R,A ;#!Save result at RAM
99 MOV SIGN,#"+" ;#!Set result sign to positive
100 RET ;#!return to MAIN
101 NIGATIV:CPL A ;#!Convert to 1's complement if negativ
102 INC A ;#!Incremet to get 2's complement
103 MOV R,A ;#!Save result at RAM
104 MOV SIGN,#"-" ;#!Set result sign to nigative
105 RET ;#!return to MAIN
106 NEXT22: CJNE R7,#"*",NEXT33 ;#!Check thirdly if the operation was "*", if not jump
107 MUL AB ;#!If so, Multibly the oeprands
108 MOV R,A ;#!Save result in RAM
109 MOV SIGN,#"+" ;#!Set result sign to positive
110 RET ;#!return to MAIN
111 NEXT33: CJNE R7,#"/",NEXT44 ;#!Check finally if the operation was "/", if not jump
112 MOV TEMP,B ;#!Copy to TEMP location
113 DIV AB ;#!Carry out division to the two operands
114 MOV R,A ;#!Save the quotient in RAM
115 MOV A,#0AH ;#!Fill ACC with 10
116 MUL AB ;#!Multibly reminder by 10
117 MOV B,TEMP ;#!Get the second number again
118 DIV AB ;#!Divide again
119 MOV TEMP,A ;#!Save the result into RAM
120 MOV SIGN,#"+" ;#!Set result sign to positive
121 NEXT44: RET ;#!return to MAIN
122 ;--------------------------------------------------------------------------------------------------#!
123 printOutput:
124 MOV R7,TEMP ;#!Copy TEMP contents to R7
125 CJNE R7,#0,POINTED ;#!Check if the result was decimal point number
126 MOV R6,SIGN ;#!Copy SIGN contents to R6
127 CJNE R6,#"+",SIGNED ;#!Check on sign if positive or negative
128 RETURN: MOV A,R ;#!If positive, Copy R contents to ACC
129 MOV B,#0AH ;#!Fill B register with 10
130 DIV AB ;#!Divide result by 100
131 JZ LESSTEN ;#!jump if reminder equals 0 (result<10)
132 ORL A,#30H ;#!If not convert first digit from BIN to ASCII
133 ACALL DATAWRT ;#!CALL subroutine, so pass data to LCD
134 MOV A,B ;#!Get the second digit
135 ORL A,#30H ;#!Convert it from BIN to ASCII
136 ACALL DATAWRT ;#!CALL subroutine, so pass data to LCD
137 AJMP DONE ;#!Done!!
138 LESSTEN:MOV A,B ;#!If the result was one digit
139 ORL A,#30H ;#!Convert from Bin to ASCII
140 ACALL DATAWRT ;#!CALL subroutine, so print data on LCD
141 AJMP DONE ;#!Done!!
142 POINTED:MOV A,R ;#!For decimal point numbers
143 ORL A,#30H ;#!Convert from Bin to ASCII
144 ACALL DATAWRT ;#!CALL subroutine, so print data on LCD
145 MOV A,#"." ;#!MOV dot ascii code to ACC
146 ACALL DATAWRT ;#!CALL subroutine, so print data on LCD
147 MOV A,TEMP ;#!Get the digit that after point
148 ORL A,#30H ;#!Convert it from BIN to ASCII

Page 2
C:\Users\tafatefo\Documents\myCalculator.asm

149 ACALL DATAWRT ;#!CALL subroutine, so print data on LCD


150 AJMP DONE ;#!Done!!
151 SIGNED: MOV A,#"-" ;#!IF signed mov "-" ASCII to ACC
152 ACALL DATAWRT ;#!CALL subroutine, so print data on LCD
153 AJMP RETURN ;#!Return to carryout the remain process
154 DONE: ACALL LDELAY ;#!Give data some time on LCD
155 ACALL LDELAY ;#!More time again
156 RET ;#!return to MIAN routine
157 ;--------------------------------------------------------------------------------------------------#!
158 validateInput: ;#!Detemine and set flags for each kind of input
159 CJNE A,#"+", next1 ;#!Check if input is add operator,
160 AJMP found ;#!Jump to found if input match with (+,-,*,/)
161 next1: CJNE A,#"-", next2 ;#!Check if input is sub operator,
162 AJMP found ;#!Jump to found if input match with (+,-,*,/)
163 next2: CJNE A,#"*", next3 ;#!Check if input is multiply operator
164 AJMP found ;#!Jump to found if input match with (+,-,*,/)
165 next3: CJNE A,#"/", next4 ;#!Check if input is add operator,
166 AJMP found ;#!Jump to found if input match with (+,-,*,/)
167 next4: CJNE A,#"=", next5 ;#!Check if input is assignment operator
168 CLR DIF ;#!CLR digit input flag for non numbers
169 CLR OIF ;#!CLR operation input flag for non operation
170 SETB AIF ;#!SET assignment input flag for (=)
171 RET ;#!return to MAIN
172 next5: SETB DIF ;#!SET digit input flag for numbers
173 CLR OIF ;#!CLR operation input flag for non operatio
174 CLR AIF ;#!CLR assignment input flag if not (=)
175 RET ;#!return to MAIN
176 found: CLR DIF ;#!CLR digit input flag for non numbers
177 SETB OIF ;#!SET operation input flag for any of operations
178 CLR AIF ;#!CLR assignment input flag if not (=)
179 RET ;#!return
180 ;--------------------------------------------------------------------------------------------------#!
181 readKey:
182 MOV P1,#0FFH ;#!Make P1 an input port
183 K1: MOV P3,#0 ;#!Ground all rows at once
184 MOV A,P1 ;#!Read all colums
185 ANL A,#00001111B ;#!Masked unused bits
186 CJNE A,#00001111B,K1 ;#!Till all keys release
187 K2: LCALL SDELAY ;#!Call 20 msec delay
188 MOV A,P1 ;#!See if any key is pressed
189 ANL A,#00001111B ;#!Mask unused bits
190 CJNE A,#00001111B,OVER ;#!Key pressed, find row
191 SJMP K2 ;#!Check till key pressed
192 OVER: LCALL SDELAY ;#!Wait 20 msec debounce time
193 MOV A,P1 ;#!Check key closure
194 ANL A,#00001111B ;#!Mask unused bits
195 CJNE A,#00001111B,OVER1 ;#!Key pressed, find row
196 SJMP K2 ;#!If none, keep polling
197 OVER1: MOV P3,#11111110B ;#!Ground row 0
198 MOV A,P1 ;#!Read all columns
199 ANL A,#00001111B ;#!Mask unused bits
200 CJNE A,#00001111B,ROW_0 ;#!Key row 0, find col.
201 MOV P3,#11111101B ;#!Ground row 1
202 MOV A,P1 ;#!Read all columns
203 ANL A,#00001111B ;#!Mask unused bits
204 CJNE A,#00001111B,ROW_1 ;#!Key row 1, find col.
205 MOV P3,#11111011B ;#!Ground row 2
206 MOV A,P1 ;#!Read all columns
207 ANL A,#00001111B ;#!Mask unused bits
208 CJNE A,#00001111B,ROW_2 ;#!Key row 2, find col.
209 MOV P3,#11110111B ;#!Ground row 3
210 MOV A,P1 ;#!Read all columns
211 ANL A,#00001111B ;#!Mask unused bits
212 CJNE A,#00001111B,ROW_3 ;#!Key row 3, find col.
213 LJMP K2 ;#!If none, false input, repeat
214 ROW_0: MOV DPTR,#KCODE0 ;#!Set DPTR=start of row 0
215 SJMP FIND ;#!Find col. Key belongs to
216 ROW_1: MOV DPTR,#KCODE1 ;#!Set DPTR=start of row
217 SJMP FIND ;#!Find col. Key belongs to
218 ROW_2: MOV DPTR,#KCODE2 ;#!Set DPTR=start of row 2
219 SJMP FIND ;#!Find col. Key belongs to
220 ROW_3: MOV DPTR,#KCODE3 ;#!Set DPTR=start of row 3
221 FIND: RRC A ;#!See if any CY bit low
222 JNC MATCH ;#!If zero, get ASCII code

Page 3
C:\Users\tafatefo\Documents\myCalculator.asm

223 INC DPTR ;#!Point to next col. addr


224 SJMP FIND ;#!Keep searching
225 MATCH: CLR A ;#!Set A=0 (match is found)
226 MOVC A,@A+DPTR ;#!Get ASCII from table
227 RET ;#!return
228 ;--------------------------------------------------------------------------------------------------#!
229 ERRFUN: ACALL CLS ;#!CALL subroutine to clear screen
230 MOV DPTR,#ERRMSG ;#!Set DPTR to look-up table's address
231 E1: CLR A ;#!Clear ACC
232 MOVC A,@A+DPTR ;#!Get code from look-up table and placing it into ACC
233 ACALL DATAWRT ;#!CALL LCD command write subroutine
234 ACALL SDELAY ;#!Give LCD some time
235 INC DPTR ;#!Increment DPTR <DPTR = DPTR + 1>
236 JZ E2 ;#!Jump if ACC = ZERO to end of loop
237 SJMP E1 ;#!If not start the loop again
238 E2: ACALL LDELAY ;#!Give some time to msg on screen
239 ACALL CLS ;#!CALL subroutine to clear screen again
240 RET ;#!return
241 ;--------------------------------------------------------------------------------------------------#!
242 COMMWRT: ;#!Send command to LCD
243 MOV P2,A ;#!Copy reg A to P1
244 CLR P0.0 ;#!RS=0 for command
245 CLR P0.1 ;#!R/W=0 for write
246 SETB P0.2 ;#!E=1 for high pulse
247 ACALL SDELAY ;#!Give LCD some time
248 CLR P0.2 ;#!E=0 for H-to-L pulse
249 RET ;#!return to caller
250 ;--------------------------------------------------------------------------------------------------#!
251 DATAWRT: ;#!Write data to LCD
252 MOV P2,A ;#!Copy reg A to port 1
253 SETB P0.0 ;#!RS=1 for data
254 CLR P0.1 ;#!R/W=0 for write
255 SETB P0.2 ;#!E=1 for high pulse
256 ACALL SDELAY ;#!Give LCD some time
257 CLR P0.2 ;#!E=0 for H-to-L pulse
258 RET ;#!return to caller
259 ;--------------------------------------------------------------------------------------------------#!
260 CLS: ;#!CLear Screen subroutine
261 MOV A,#01H ;#!Fill ACC with the command code
262 ACALL COMMWRT ;#!CALL subroutine to send code to lCD
263 RET ;#!return to caller
264 ;--------------------------------------------------------------------------------------------------#!
265 SDELAY: ;#!Short Delay subroutine
266 MOV R0,#50 ;#!R0 = 50
267 S11: MOV R1,#255 ;#!R1 = 255
268 S21: DJNZ R1,S21 ;#!stay here until R1 becomes ZERO
269 DJNZ R0,S11 ;#!
270 RET ;#!return to caller
271 ;--------------------------------------------------------------------------------------------------#!
272 LDELAY: ;#!Long Delay Subroutine
273 MOV R0,#7 ;#!R0 = 7
274 L33: MOV R1,#190 ;#!R1 = 190
275 L22: MOV R2,#255 ;#!R2 = 255
276 L11: DJNZ R2,L11 ;#!stay here until R2 becomes ZERO
277 DJNZ R1,L22 ;#!
278 DJNZ R0,L33 ;#!
279 RET ;#!return to caller
280 ;--------------------------------------------------------------------------------------------------#!
281 ;--------------------------------------------------------------------------------------------------#!
282 ;-------COMMANDS LOOK-UP TABLE FOR LCD INITIALIZATION
283 ORG 300H
284 MYCOM: DB 38H,0FH,01H,06H,80H,0
285 ;-------ASCII LOOK-UP TABLE FOR EACH ROW
286 KCODE0: DB "7","8","9","/" ;#!ROW 0
287 KCODE1: DB "4","5","6","*" ;#!ROW 1
288 KCODE2: DB "1","2","3","-" ;#!ROW 2
289 KCODE3: DB 0,"0","=","+" ;#!ROW 3
290 ;-------ERROR MASSAGE FOR ANY INVALID INPUT
291 ERRMSG: DB "ERROR!!",0
292 END

Page 4

Potrebbero piacerti anche