📄 calc.lst
字号:
C51 COMPILER V8.12 CALC 08/24/2008 11:27:21 PAGE 1
C51 COMPILER V8.12, COMPILATION OF MODULE CALC
OBJECT MODULE PLACED IN calc.OBJ
COMPILER INVOKED BY: D:\Program Files\Keil\C51\BIN\C51.EXE calc.c DEBUG OBJECTEXTEND
line level source
1
2 /*******************************************************************************
3 ************ LABCENTER ELECTRONICS ************
-
4 ************ Proteus VSM Sample Design Code ************
5 ************ Integer Calculator ( 2K Code Limit) ************
6 *******************************************************************************/
7
8 #include <intrins.h>
9 #include <reg51.h>
10 #include "calc.h"
11
12 //Variables
13 static data LONG lvalue;
14 static data LONG rvalue;
15 static data CHAR currtoken;
16 static data CHAR lasttoken;
17 static data CHAR lastpress;
18 static xdata CHAR outputbuffer[MAX_DISPLAY_CHAR];
19
20 VOID main (VOID)
21 //Initialise our variables and call the
22 //Assembly routine to initialise the LCD display.
23 { lvalue = 0;
24 1 rvalue = 0;
25 1 currtoken = '=';
26 1 lasttoken = '0';
27 1 initialise(); // Initialize the LCD
28 1 calc_output(OK);
29 1 calc_evaluate();
30 1 }
31
32 VOID calc_evaluate()
33 { CHAR data key;
34 1 INT data i;
35 1 CHAR xdata number[MAX_DISPLAY_CHAR];
36 1 CHAR xdata *bufferptr;
37 1
38 1 // Clear the buffer before we start.
39 1 for (i = 0; i <= MAX_DISPLAY_CHAR; i++)
40 1 { number[i] = ' ';
41 2 }
42 1 bufferptr = number;
43 1
44 1 for (;;)
45 1 { key = calc_getkey();
46 2 if (calc_testkey(key))
47 2 // Key test positive for digit so we read it into the
48 2 // buffer and then write the buffer to the screen/LCD.
49 2 // Size limit the number of digits - allow for termination
50 2 // and possible negative results.
51 2 { if (bufferptr != &number[MAX_DISPLAY_CHAR - 2])
52 3 { *bufferptr = key;
53 4 calc_display(number);
54 4 bufferptr++;
C51 COMPILER V8.12 CALC 08/24/2008 11:27:21 PAGE 2
55 4 }
56 3 }
57 2
58 2 else
59 2 // Key is an operator so pass it to the function handlers.
60 2 // If we are just after startup or cancel then assign to lvalue
61 2 // otherwise assign to rvalue.
62 2 {
63 3 //Assign the value.
64 3 if (lasttoken == '0')
65 3 { lvalue = calc_asciidec (number);}
66 3 else
67 3 { rvalue = calc_asciidec (number);}
68 3
69 3 //Clear the number buffer.
70 3 bufferptr = number;
71 3 for (i = 0;i <= MAX_DISPLAY_CHAR; i++)
72 3 { number[i] = ' '; }
73 3
74 3 //Process the Operator.
75 3 currtoken = key;
76 3 if (currtoken == 'C')
77 3 { calc_opfunctions(currtoken); }
78 3 else
79 3 { calc_opfunctions(lasttoken); }
80 3
81 3 // Clear the outputbuffer for reuse on next operation.
82 3 for (i = 0;i <= MAX_DISPLAY_CHAR;i++)
83 3 { outputbuffer[i] = ' ';}
84 3
85 3 bufferptr = number;
86 3 // Handle the equals operation here for brevity.
87 3 // All we need do is preserve the previous operator in
88 3 // lasttoken.
89 3 if (currtoken != 0x3D) lasttoken = currtoken;
90 3
91 3 }
92 2 lastpress = key;
93 2 }
94 1 }
95
96 VOID calc_opfunctions (CHAR token)
97 // Handle the operations. Lvalue holds the result and we test for
98 // consecutive operator presses.
99 { CHAR data result;
100 1 switch(token)
101 1 // Add.
102 1 { case '+' : if ((currtoken == '=' ) || ((lastpress >= 0x30) && (lastpress <=0x39)))
103 2 { lvalue += rvalue;
104 3 result = calc_chkerror(lvalue);
105 3 }
106 2 else
107 2 { result = SLEEP; } break;
108 2 // Subtract.
109 2 case '-' : if ((currtoken == '=' ) || ((lastpress >= 0x30) && (lastpress <=0x39)))
110 2 { lvalue -= rvalue;
111 3 result = calc_chkerror(lvalue);
112 3 }
113 2 else
114 2 { result = SLEEP;} break;
115 2 // Multiply.
116 2 case '*' : if ((currtoken == '=' ) || ((lastpress >= 0x30) && (lastpress <=0x39)))
C51 COMPILER V8.12 CALC 08/24/2008 11:27:21 PAGE 3
117 2 { lvalue *= rvalue;
118 3 result = calc_chkerror(lvalue);
119 3 }
120 2 else
121 2 { result = SLEEP;} break;
122 2 // Divide.
123 2 case '/' : if ((currtoken == '=' ) || ((lastpress >= 0x30) && (lastpress <=0x39)))
124 2 { if (rvalue)
125 3 { lvalue /= rvalue;
126 4 result = calc_chkerror(lvalue);
127 4 }
128 3 else
129 3 { result = ERROR;}
130 3 }
131 2 else
132 2 { result = SLEEP;} break;
133 2 // Cancel.
134 2 case 'C' : lvalue = 0;
135 2 rvalue = 0;
136 2 currtoken = '0';
137 2 lasttoken = '0';
138 2 result = OK; break;
139 2
140 2 default : result = SLEEP;
141 2
142 2 }
143 1 calc_output(result);
144 1 }
145
146
147 /************************************************************************
148 ***** Utility Routines *****
149 ***************************/
150
151 INT calc_chkerror (LONG num)
152 // Check upper and lower bounds for the display.
153 // i.e. 99999999 and -99999999.
154 { if ((num >= -9999999) && (num <= 9999999))
155 1 return OK;
156 1 else
157 1 return ERROR;
158 1 }
159
160
161 VOID calc_output (INT status)
162 // Output according to the status of the operation.
163 // *Sleep* is used for the first op press after a full cancel
164 // or on startup.
165 { switch (status)
166 1 { case OK : calc_display(calc_decascii(lvalue)); break;
167 2 case SLEEP : break;
168 2 case ERROR : calc_display("Exception "); break;
169 2 default : calc_display("Exception "); break;
170 2 }
171 1 }
172
173
174 LONG calc_asciidec (CHAR *buffer)
175 // Convert the ASCII string into the floating point number.
176 { LONG data value;
177 1 LONG data digit;
178 1 value = 0;
C51 COMPILER V8.12 CALC 08/24/2008 11:27:21 PAGE 4
179 1 while (*buffer != ' ')
180 1 { digit = *buffer - 48;
181 2 value = value*10 + digit;
182 2 buffer++;
183 2 }
184 1 return value;
185 1 }
186
187 CHAR *calc_decascii (LONG num)
188 // A rather messy function to convert a floating
189 // point number into an ASCII string.
190 { LONG data temp = num;
191 1 CHAR xdata *arrayptr = &outputbuffer[MAX_DISPLAY_CHAR];
192 1 LONG data divisor = 10;
193 1 LONG data result;
194 1 CHAR data remainder,asciival;
195 1 INT data i;
196 1
197 1 // If the result of the calculation is zero
198 1 // insert a zero in the buffer and finish.
199 1 if (!temp)
200 1 { *arrayptr = 48;
201 2 goto done;
202 2 }
203 1 // Handle Negative Numbers.
204 1 if (temp < 0)
205 1 { outputbuffer[0] = '-';
206 2 temp -= 2*temp;
207 2 }
208 1
209 1 for (i=0 ; i < sizeof(outputbuffer) ; i++)
210 1 { remainder = temp % divisor;
211 2 result = temp / divisor;
212 2
213 2 // If we run off the end of the number insert a space into
214 2 // the buffer.
215 2 if ((!remainder) && (!result))
216 2 { *arrayptr = ' ';}
217 2
218 2 // We're in business - store the digit offsetting
219 2 // by 48 decimal to account for the ascii value.
220 2 else
221 2 { asciival = remainder + 48;
222 3 *arrayptr = asciival;
223 3 }
224 2
225 2 temp /= 10;
226 2 // Save a place for a negative sign.
227 2 if (arrayptr != &outputbuffer[1]) arrayptr--;
228 2 }
229 1 done: return outputbuffer;
230 1 }
231
232
233 CHAR calc_testkey (CHAR key)
234 // Test whether the key is a digit or an operator. Return 1 for digit, 0 for op.
235 { if ((key >= 0x30) && (key <= 0x39))
236 1 { return 1;}
237 1 else
238 1 { return 0;}
239 1 }
240
C51 COMPILER V8.12 CALC 08/24/2008 11:27:21 PAGE 5
241 /************************************************************************
242 ***** I/O Routines *****
243 ***********************/
244
245 CHAR calc_getkey (VOID)
246 // Use the input routine from the *Keypad_Read* assembly file to
247 // Scan for a key and return ASCII value of the Key pressed.
248 { CHAR data mykey;
249 1 do mykey = input();
250 1 while (mykey == 0);
251 1 return mykey;
252 1 }
253
254 VOID calc_display (CHAR buf[MAX_DISPLAY_CHAR])
255 // Use the Output and Clearscreen routines from the
256 // *LCD_Write* assembly file to output ASCII values to the LCD.
257 { INT data i = 0;
258 1 clearscreen();
259 1 for (i ; i <= MAX_DISPLAY_CHAR ; i++)
260 1 { if (buf[i] != ' ')
261 2 { output(buf[i]); }
262 2 }
263 1 }
264
265
266
267
268
269
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 1132 ----
CONSTANT SIZE = 11 ----
XDATA SIZE = 9 9
PDATA SIZE = ---- ----
DATA SIZE = 11 39
IDATA SIZE = ---- ----
BIT SIZE = ---- ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -