Курсовая работа «Двухбайтовый десятичный калькулятор» по курсу «Микропроцессорные системы»

Московский государственный институт электроники и математики

Кафедра информационно-коммуникационных технологий

Курсовая работа

«Двухбайтовый десятичный калькулятор»

по курсу «Микропроцессорные системы»

Выполнил:

Группа С-85

Проверил:

Москва 2011
Аннотация

В данной работе разрабатывается двухбайтовый десятичный калькулятор на базе микроконтроллера 51 семейства. Работа выполняется на прототипе.

Оглавление

Техническое задание. 4

Анализ технического задания. 5

Алгоритмы.. 6

Служебная информация. 6

Алгоритм основной программы.. 6

Обработчик прерывания по таймеру. 7

Обработчик прерывания от COM-порта. 8

Опрос матричной клавиатуры.. 8

Подсчёт операнда. 9

Вычисление. 9

Вывод результата. 10

Печать результата на экране. 10

Исходный код. 11

Список использованной литературы.. 28

Техническое задание

Написать программу для тестового стенда на базе микроконтроллера Intel 8051, позволяющую выполнять сложение, вычитание, умножение и деление положительных целых чисел. Дополнительные условия:

1.  Числа вводятся с матричной клавиатуры в десятичной форме.

2.  Операции вводятся с клавиатуры компьютера кнопками «+», «-», «*», «/», «=».

3.  Результат выводится в десятичной форме в виде числа до четырёх знаков длиной.

Анализ технического задания

Результат вычислений – десятичное число до четырёх знаков длиной. Это означает, что для хранения данного числа требуется два байта памяти. То же самое касается вводимых данных: предполагается, что пользователь может ввести числа до четырёх знаков длиной.

Так как процессор используемого прототипа восьмибитный, то для вычисления в шестнадцати битах невозможно использовать стандартные операции сложения, вычитания, умножения и деления, и эти операции должны быть переопределены.

Программе потребуется банк регистров R0-R7 для хранения операндов, промежуточных вычислений и результата операции.

Также необходимы ячейки с побитовой адресацией для хранения служебных битов.

Приём символов от матричной клавиатуры производится с помощью прерываний по таймеру и анализа нажатой клавиши. Приём символов от компьютерной клавиатуры реализован с использованием прерываний от COM-порта.

Вывод результата на экран терминала производится посредством COM-порта.

Алгоритмы

Служебная информация

Для хранения служебной информации в течение всего цикла работы программы выделены два байта памяти с побитовой адресацией.

20h:

0-3 биты – длина вводимого числа.

4 бит – какое число вводится в данный момент (0 – первое, 1 – второе).

5, 6 биты – знак операции (00 – «+», 01 – «-», 10 – «*», 11 – «/»).

7 бит – индикатор, что клавиша нажата и держится. Используется для устранения проблемы дребезга контактов.

21h:

0 бит – этапы операции деления (см. соответствующий раздел).

1 бит – ошибка переполнения.

2 бит – получено отрицательное число.

3 бит – попытка деления на ноль.

Алгоритм основной программы

Обработчик прерывания по таймеру

Обработчик прерывания от COM-порта

Опрос матричной клавиатуры

Для ввода цифр используется стандартная шестнадцатикнопочная матричная клавиатура. Чтобы определить, какая клавиша нажата в данный момент, в регистре P1 устанавливаются различные значения для линий P1.4 – P1.7. На проверяемой линии выставляется «0», на остальных – «1». После чего производится проверка на «0» на линиях P1.0 – P1.3. При обнаружении «0» на пересечении линий вызывается обработчик для соответствующей цифры.

Подсчёт операнда

В зависимости от количества введённых знаков вызывается одна из четырёх функций, вычисляющих значение операнда. Расчёт производится путём умножения каждой введённой цифры на 10n, где n – номер разряда, который представляет данная цифра. После попарного умножения полученные значения складываются.

В зависимости от номера операнда полученное значение записывается в соответствующие ему регистры.

Вычисление

В зависимости от вида операции вызывается одна из четырёх функций подсчёта результата: сложение, вычитание, умножение, деление. Так как операнды представляют собой двухбайтовые числа, операции по вычислению были переопределены.

При сложении младшие и старшие байты операндов попарно складываются. Если при сложении младших байтов происходит переполнение, бит переполнения добавляется к сумме старших байтов. Если при сложении старших байтов происходит переполнение, на экран выводится ошибка переполнения.

При вычитании младшие и старшие байты операндов попарно вычитаются. Если при вычитании младших байтов получилось отрицательное число, то бит переноса вычитается из разности старших байтов. Если при вычитании старших байтов получилось отрицательное число, то оно записывается как результат, и устанавливается флаг отрицательного числа в служебном бите.

При умножении производится попарное умножение старших и младших байтов операндов. Если оба старших байта не равны нулю, то выводится ошибка переполнения. Результат перемножения младших байтов записывается в младший байт результата, переполнение – в старший байт. Сумма произведений старших байтов с младшими записывается в старший байт результата. При переполнении старшего байта выводится ошибка переполнения.

Деление производится в области памяти с возможностью побитовых операций. Сначала производится проверка второго операнда на ноль. Если делитель равен нулю, то выводится ошибка. Деление состоит из двух фаз. В первой фазе второй операнд сдвигается влево до тех пор, пока он не станет больше первого операнда, после чего производится обратный сдвиг вправо на один бит. После каждого сдвига в регистры R записывается множитель делителя (фактически, число 2n, где n – количество сдвигов делителя). Вторая фаза заключается в том, что из первого операнда вычитается второй, и к результату прибавляется значение регистров R. После чего второй операнд сдвигается вправо, и снова производится попытка вычитания. Вторая фаза повторяется до тех пор, пока второй операнд в своём первоначальном виде не станет больше первого операнда. В регистре с результатом будет записан конечный результат деления.

Вывод результата

Результат вычислений записан в двух байтах в двоичном виде. Для того чтобы вывести его на экран в десятичном виде необходимо последовательно вывести на экран результаты целочисленного деления результата на 10n, где n – номер разряда выводимого числа. Так как результат может занимать два байта, и представлять собой число из четырёх разрядов, что требует деления на 1000, при выводе на экран применяется алгоритм деления, описанный выше.

Печать результата на экране

При успешном завершении вычислений на экран выводится число – результат вычислений. При возникновении ошибки переполнения на экран выводится «OVERFLOW». При возникновении ошибки деления на ноль на экран выводится «DIVISION BY ZERO».

Исходный код

ASEM-51 V1.3

Copyright (c) 2002 by W. W. Heinz

MCS-51 Family Macro Assembler A S E M - 5 1 V 1.3

=====================================================

Source File: calculator_final_win. s03

Object File: calculator_final_win. hex

List File: calculator_final_win. lst

Line I Addr Code Source

1: N 8000 org 8000h

2: ; основная функция

3: 8AD jmp main

4:

5: N 8003 org 8003h

6: 8reti

7:

8: N 800B org 800Bh

9: ; обработка матричной клавиатуры

10: 800BA7 call delay

11: 800Ecall mx_keyboard

12: 8reti

13:

14: N 8023 org 8023h

15: ; обработка прерываний с клавиатуры

16: 8C5 call read

17: 8reti

18:

19: 8027 mx_keyboard:

20: ; верхние клавиши

21: 8DF mov P1, #b

22: 802Ajnb P1.1, a1

23: 802DB jnb P1.0, a2

24: 8jnb P1.3, a3

25: ; средние клавиши

26: 8EF mov P1, #b

27: 8jnb P1.1, a4

28: 8D jnb P1.0, a5

29: 803Cjnb P1.3, a6

30: ; нижние клавиши

31: 803FF mov P1, #b

32: 8jnb P1.1, a7

33: 8F jnb P1.0, a8

34: 8jnb P1.3, a9

35: ; самые нижние клавиши

36: 804BBF mov P1, #b

37: 804Ejnb P1.1, a0

38: 8jnb P1.0, aclear

39: ; клавиша отжата

40: 8054 C2 07 clr 20h.7

41:

42: 8056 mx_keyb_ret:

43: 8ret

44:

45: ; запись цифр

46: 8057 a0:

47: ; если клавиша нажата и держится

48: 8FC jb 20h.7, mx_keyb_ret

49: 805Amov A, #0

50: 805CF2 call digits_write

51: 805F 80 F5 jmp mx_keyb_ret

52:

53: 8061 a1:

54: 8F2 jb 20h.7, mx_keyb_ret

55: 8mov A, #1

56: 8F2 call digits_write

57: 8EB jmp mx_keyb_ret

58:

59: 806B a2:

60: 806BE8 jb 20h.7, mx_keyb_ret

61: 806Emov A, #2

62: 8F2 call digits_write

63: 8E1 jmp mx_keyb_ret

64:

65: 8075 a3:

66: 8DE jb 20h.7, mx_keyb_ret

67: 8mov A, #3

68: 807AF2 call digits_write

69: 807D 80 D7 jmp mx_keyb_ret

70:

71: 807F a4:

72: 807FD4 jb 20h.7, mx_keyb_ret

73: 8mov A, #4

74: 8F2 call digits_write

75: 8CD jmp mx_keyb_ret

76:

77: 8089 a5:

78: 8CA jb 20h.7, mx_keyb_ret

79: 808Cmov A, #5

80: 808EF2 call digits_write

81: 8C3 jmp mx_keyb_ret

82:

83: 8093 a6:

84: 8C0 jb 20h.7, mx_keyb_ret

85: 8mov A, #6

86: 8F2 call digits_write

87: 809B 80 B9 jmp mx_keyb_ret

88:

89: 809D a7:

90: 809DB6 jb 20h.7, mx_keyb_ret

91: 80A0mov A, #7

92: 80A2F2 call digits_write

93: 80A5 80 AF jmp mx_keyb_ret

94:

95: 80A7 a8:

96: 80A7AC jb 20h.7, mx_keyb_ret

97: 80AAmov A, #8

98: 80ACF2 call digits_write

99: 80AF 80 A5 jmp mx_keyb_ret

100:

101: 80B1 a9:

102: 80B1A2 jb 20h.7, mx_keyb_ret

103: 80B4mov A, #9

104: 80B6F2 call digits_write

105: 80B9 80 9B jmp mx_keyb_ret

106:

107: ; сброс

108: 80BB aclear:

109: 80BBmov 20h, #b

110: 80BE 74 0A mov A, #0Ah

111: 80C0call out

112: 80C3jmp mx_keyb_ret

113:

114: ; чтение из последовательного порта

115: 80C5 read:

116: 80C5D jnb RI, read_ret_abort

117: 80C8 C2 98 clr RI

118: 80CA E5 99 mov A, SBUF

119: ; если операция уже вводилась

120: ; проверить, не знак ли это равенства

121: 80CCjb 20h.4, aequ0

122: ; в противном случае операция ещё не вводилась

123: ; плюс ли это?

124: 80CF B4 2B 08 cjne A, #'+', aminus0

125: ; если плюс

126: 80D2jmp aplus1

127:

128: 80D5 read_ret_abort:

129: 80D5 22 ret

130:

131: 80D6 read_ret:

132: 80D6call out

133: 80D9 22 ret

134:

135: ; вычитание

136: 80DA aminus0:

137: ; минус ли это?

138: 80DA B4 2D 09 cjne A, #'-', amultiply0

139: 80DDjmp aminus1

140:

141: ; на вычисление

142: 80E0 aequ0:

143: ; равно ли это?

144: 80E0 B4 3D F2 cjne A, #'=', read_ret_abort

145: 80E3D jmp aequ1

146:

147: ; умножение

148: 80E6 amultiply0:

149: ; звездочка ли это?

150: 80E6 B4 2A 03 cjne A, #'*', adivide0

151: 80E9F jmp amultiply1

152:

153: ; деление

154: 80EC adivide0:

155: ; косая ли это черта?

156: ; все варианты перебрали

157: ; если ни один не подходит,

158: ; значит ввели что-то не то

159: 80EC B4 2F E6 cjne A, #'/', read_ret_abort

160: 80EFE jmp adivide1

161:

162: ; запись цифры в память

163: ; в зависимости от ее порядка

164: 80F2 digits_write:

165: ; клавиша нажата и держится

166: 80F2 D2 07 setb 20h.7

167: 80F4jb 20h.0, first_digit

168: 80F7jb 20h.1, second_digit

169: 80FAC jb 20h.2, third_digit

170: 80FDjb 20h.3, fourth_digit

171: 8ret

172:

173: 8101 aplus1:

174: ; если уже введено первое число

175: 8jnb 20h.0, aplus2

176: 8jmp mx_keyb_ret

177:

178: 8106 aplus2:

179: ; записать число из цифр

180: 8call merge_digits

181: ; операция - сложение

182: ; можно вводить второе число

183: 8mov 20h, #b

184: 810C 74 2B mov A, #'+'

185: 810E 80 C6 jmp read_ret

186:

187: 8110 aminus1:

188: ; если уже введено первое число

189: 8jnb 20h.0, aminus2

190: 8jmp mx_keyb_ret

191:

192: 8115 aminus2:

193: ; записать число из цифр

194: 8call merge_digits

195: ; операция - вычитание

196: ; можно вводить второе число

197: 8mov 20h, #b

198: 811B 74 2D mov A, #'-'

199: 811D 80 B7 jmp read_ret

200:

201: 811F amultiply1:

202: ; если уже введено первое число

203: 811Fjnb 20h.0, amultiply2

204: 8jmp mx_keyb_ret

205:

206: 8124 amultiply2:

207: ; записать число из цифр

208: 8call merge_digits

209: ; операция - умножение

210: ; можно вводить второе число

211: 8mov 20h, #b

212: 812A 74 2A mov A, #'*'

213: 812C 80 A8 jmp read_ret

214:

215: 812E adivide1:

216: ; если уже введено первое число

217: 812Ejnb 20h.0, adivide2

218: 8jmp mx_keyb_ret

219:

220: 8133 adivide2:

221: ; записать число из цифр

222: 8call merge_digits

223: ; операция - деление

224: ; можно вводить второе число

225: 8mov 20h, #b

226: 8F mov A, #'/'

227: 813Bjmp read_ret

228:

229: 813D aequ1:

230: 813Djnb 20h.0, aequ2

231: 8jmp mx_keyb_ret

232:

233: 8142 aequ2:

234: 8D mov A, #'='

235: 8call out

236: ; записать число из цифр

237: 8call merge_digits

238: ; подсчитать результат

239: 814AC call evaluate

240: ; очистить

241: 814Dmov 20h, #b

242: 8mov 21h, #0

243: 8jmp read_ret_abort

244:

245: 8155 digits_ret:

246: 8add A, #30h

247: 8call out

248: 815A 22 ret

249:

250: 815B first_digit:

251: 815B F8 mov R0, A

252: 815C C2 00 clr 20h.0

253: 815E D2 01 setb 20h.1

254: 8F3 jmp digits_ret

255:

256: 8162 second_digit:

257: 8162 F9 mov R1, A

258: 8163 C2 01 clr 20h.1

259: 8165 D2 02 setb 20h.2

260: 8EC jmp digits_ret

261:

262: 8169 third_digit:

263: 8169 FA mov R2, A

264: 816A C2 02 clr 20h.2

265: 816C D2 03 setb 20h.3

266: 816E 80 E5 jmp digits_ret

267:

268: 8170 fourth_digit:

269: 8170 FB mov R3, A

270: 8171 C2 03 clr 20h.3

271: 8E0 jmp digits_ret

272:

273: ; подсчет числа по записанным цифрам

274: 8175 merge_digits:

275: 8A jb 20h.1, merge_digits1

276: 8E jb 20h.2, merge_digits2

277: 817BC jb 20h.3, merge_digits3

278: 817EE jmp merge_digits4

279:

280: 8181 write_dptr1:

281: 8jnb 20h.4, write_dptr0

282: 8B jmp merge_digits_ret

283:

284: 8187 write_dptr0:

285: 8187 AE 83 mov R6, DPH

286: 8189 AF 82 mov R7, DPL

287:

288: 818B merge_digits_ret:

289: 818B 22 ret

290:

291: ; получение результата

292: 818C evaluate:

293: ; сложение и вычитание

294: 818Cjnb 20h.6, plusminus

295: ; умножение и деление

296: 818FAC jmp multdivide

297:

298: ; число из одного знака

299: ; просто записывается в DPL

300: 8192 merge_digits1:

301: 8mov DPH, #0

302: 8mov DPL, R0

303: 8E8 jmp write_dptr1

304:

305: ; число из двух знаков

306: 8199 merge_digits2:

307: ; второй разряд * 10

308: 8199 E8 mov A, R0

309: 819A 75 F0 0A mov B, #10

310: 819D A4 mul AB

311: ; сложить с первым разрядом

312: ; и записать в DPL

313: 819E 29 add A, R1

314: 819Fmov DPH, #0

315: 81A2 F5 82 mov DPL, A

316: 81A4 80 DB jmp write_dptr1

317:

318: ; выбор, сложение или вычитание

319: 81A6 plusminus:

320: 81A6jnb 20h.5, l_plus

321: 81A9B8 jmp l_minus

322:

323: ; выбор, умножение или деление

324: 81AC multdivide:

325: 81ACF jnb 20h.5, l_multiply

326: 81AFC4 jmp l_division

327:

328: 81B2 l_plus:

329: 81B2ED call plus

330: 81B5E9 jmp evaluate_ret

331:

332: 81B8 l_minus:

333: 81B8FD call minus

334: 81BBE9 jmp evaluate_ret

335:

336: 81BE l_multiply:

337: 81BEE call multiply

338: 81C1E9 jmp evaluate_ret

339:

340: 81C4 l_division:

341: 81C4E call division

342: 81C7E9 jmp evaluate_ret

343:

344: ; число из трех знаков

345: 81CA merge_digits3:

346: ; третий разряд * 100

347: ; результат записать в 2 ячейки

348: 81CA E8 mov A, R0

349: 81CB 75 F0 64 mov B, #100

350: 81CE A4 mul AB

351: 81CF FC mov R4, A

352: 81D0 AD F0 mov R5, B

353: ; второй разряд * 10

354: 81D2 E9 mov A, R1

355: 81D3 75 F0 0A mov B, #10

356: 81D6 A4 mul AB

357: ; сложить с третьим разрядом

358: 81D7 C3 clr C

359: 81D8 3C addc A, R4

360: ; сохранить

361: 81D9 FC mov R4, A

362: ; бит переноса записать в старшую ячейку

363: 81DA ED mov A, R5

364: 81DBaddc A, #0

365: ; сохранить

366: 81DD FD mov R5, A

367: ; прибавить к младшей ячейке

368: ; первый разряд

369: 81DE EC mov A, R4

370: 81DF 3A addc A, R2

371: ; записать в DPL

372: 81E0 F5 82 mov DPL, A

373: ; бит переноса записать в старшую ячейку

374: 81E2 ED mov A, R5

375: 81E3addc A, #0

376: ; записать в DPH

377: 81E5 F5 83 mov DPH, A

378: 81E7jmp write_dptr1

379:

380: 81E9 evaluate_ret:

381: 81E9call output

382: 81EC 22 ret

383:

384: ; сложение

385: 81ED plus:

386: ; сложение младших разрядов

387: 81ED EF mov A, R7

388: 81EE C3 clr C

389: 81EFaddc A, DPL

390: 81F1 F5 82 mov DPL, A

391: ; сложение старших разрядов

392: ; с учетом бита переноса

393: 81F3 EE mov A, R6

394: 81F4addc A, #0

395: 81F6addc A, DPH

396: 81F8 F5 83 mov DPH, A

397: ; переполнение

398: 81FAmov 21h.1, C

399: 81FC 22 ret

400:

401: ; вычитание

402: 81FD minus:

403: ; вычитание младших разрядов

404: 81FD EF mov A, R7

405: 81FE C3 clr C

406: 81FFsubb A, DPL

407: 8201 F8 mov R0, A

408: ; вычитание старших разрядов

409: ; с учетом бита переноса

410: 8202 EE mov A, R6

411: 8subb A, #0

412: 8subb A, DPH

413: 8jc minus_reverse

414: 8209 F5 83 mov DPH, A

415: 820Bmov DPL, R0

416: 820D 22 ret

417:

418: ; вычитание

419: ; первое число оказалось меньше второго

420: 820E minus_reverse:

421: ; отрицательность

422: 820E D2 0A setb 21h.2

423: ; вычитание младших байт

424: 8210 E5 82 mov A, DPL

425: 8212 C3 clr C

426: 8213 9F subb A, R7

427: 8214 F5 82 mov DPL, A

428: ; вычитание старших байт

429: ; с учетом бита переноса

430: 8216 E5 83 mov A, DPH

431: 8subb A, #0

432: 821A 9E subb A, R6

433: 821B F5 83 mov DPH, A

434: 821D 22 ret

435:

436: ; умножение

437: 821E multiply:

438: ; (a+b)*(c+d)=ac+ad+bc+bd

439: ; если в старших байтах обоих чисел

440: ; есть значения, то будет переполнение

441: 821E EE mov A, R6

442: 821Fjnz mult1

443: 8221 E5 83 mov A, DPH

444: 8E jnz mult2

445: ; данные только в младших байтах

446: 8225 EF mov A, R7

447: 8F0 mov B, DPL

448: 8229 A4 mul AB

449: 822A F5 82 mov DPL, A

450: 822C 85 F0 83 mov DPH, B

451: 822F 22 ret

452:

453: ; переполнение

454: 8230 overflow:

455: 8230 D2 09 setb 21h.1

456: 8ret

457:

458: 8233 mult1:

459: 8233 E5 83 mov A, DPH

460: 8F9 jnz overflow

461: ; первое число заняло два байта

462: ; второе - один

463: ; перемножаем младшие байты и записываем

464: 8237 E5 82 mov A, DPL

465: 8239 8F F0 mov B, R7

466: 823B A4 mul AB

467: 823C F9 mov R1, A

468: 823D 85 F0 83 mov DPH, B

469: ; умножаем старший байт первого числа

470: ; на второе число

471: 8240 E5 82 mov A, DPL

472: 8242 8E F0 mov B, R6

473: 8244 A4 mul AB

474: ; прибавляем к уже полученному результату

475: 8245 C3 clr C

476: 8addc A, DPH

477: 8248 F5 83 mov DPH, A

478: ; переполнение

479: 824A 40 E4 jc overflow

480: ; проверяем B: возможно переполнение

481: 824C E5 F0 mov A, B

482: 824E 70 E0 jnz overflow

483: ; дописываем результат

484: 8mov DPL, R1

485: 8ret

486:

487: 8253 mult2:

488: ; первое число заняло один байт

489: ; второе - два

490: ; перемножаем младшие байты и записываем

491: 8253 E5 82 mov A, DPL

492: 8255 8F F0 mov B, R7

493: 8257 A4 mul AB

494: 8258 F9 mov R1, A

495: 8259 A8 F0 mov R0, B

496: ; умножаем старший байт второго числа

497: ; на первое число

498: 825B E5 83 mov A, DPH

499: 825D 8F F0 mov B, R7

500: 825F A4 mul AB

501: ; прибавляем к уже полученному результату

502: 8260 C3 clr C

503: 8addc A, R0

504: 8262 F8 mov R0, A

505: ; переполнение

506: 8CB jc overflow

507: ; проверяем B: возможно переполнение

508: 8265 E5 F0 mov A, B

509: 8C7 jnz overflow

510: ; записываем результат

511: 8mov DPL, R1

512: 826Bmov DPH, R0

513: 826D 22 ret

514:

515: ; число из четырех знаков

516: 826E merge_digits4:

517: ; четвертый разряд * 10 * 100

518: 826E E8 mov A, R0

519: 826F 75 F0 0A mov B, #10

520: 8272 A4 mul AB

521: 8F0 64 mov B, #100

522: 8276 A4 mul AB

523: ; результат записать в 2 ячейки

524: 8277 FC mov R4, A

525: 8278 AD F0 mov R5, B

526: ; третий разряд * 100

527: 827A E9 mov A, R1

528: 827B 75 F0 64 mov B, #100

529: 827E A4 mul AB

530: ; прибавить к младшему разряду

531: ; младшую ячейку четвертого разряда

532: 827F C3 clr C

533: 8280 3C addc A, R4

534: 8281 FC mov R4, A

535: ; прибавить к старшему разряду

536: ; старшую ячейку четвертого разряда

537: ; учитывая бит переноса

538: 8282 E5 F0 mov A, B

539: 8284 3D addc A, R5

540: 8285 FD mov R5, A

541: ; второй разряд * 10

542: 8286 EA mov A, R2

543: 8F0 0A mov B, #10

544: 828A A4 mul AB

545: ; прибавить к нему

546: ; младшую ячейку

547: 828B C3 clr C

548: 828C 3C addc A, R4

549: 828D FC mov R4, A

550: ; бит переноса прибавить

551: ; к старшей ячейке

552: 828E ED mov A, R5

553: 828Faddc A, #0

554: 8291 FD mov R5, A

555: ; первый разряд прибавить

556: ; к младшей ячейке

557: 8292 EB mov A, R3

558: 8293 C3 clr C

559: 8294 3C addc A, R4

560: 8295 F5 82 mov DPL, A

561: ; бит переноса прибавить

562: ; к старшей ячейке

563: 8297 ED mov A, R5

564: 8addc A, #0

565: 829A F5 83 mov DPH, A

566: 829Cjmp write_dptr1

567:

568: ; деление

569: 829E division:

570: ; проверка деления на ноль

571: 829E E5 82 mov A, DPL

572: 82A0jz divbyzero

573: 82A2 nozero:

574: ; здесь будет результат

575: 82A2mov R0, #0

576: 82A4mov R1, #0

577: ; а это для удобства заполнения результата:

578: ; сдвигать влево и прибавлять к ответу

579: ; по мере необходимости

580: ; также - регистр-счетчик

581: 82A6 7A 00 mov R2, #0

582: 82A8 7B 01 mov R3, #1

583: ; режим работы:

584: ; 0 - первая фаза, сдвиг влево

585: ; 1 - вторая фаза, сдвиг вправо и вычитание

586: 82AA C2 08 clr 21h.0

587: ; пробуем вычесть из первого числа второе

588: 82ACF jmp subtract

589: 82AF sub_l_success:

590: ; сдвигаем второе число влево...

591: 82AFD2 jmp move_left

592: 82B2 mvl_success:

593: ; ... и повторяем процедуру...

594: 82B2F jmp subtract

595: 82B5 sub_l_fail:

596: ; ... пока второе число не окажется больше первого...

597: 82B5F3 jmp move_right

598: 82B8 mvl_fail:

599: ; ... или после сдвига второе число уехало влево

600: ; меняем режим работы на вторую фазу

601: 82B8 D2 08 setb 21h.0

602: 82BAF jmp subtract

603: 82BD sub_r_success:

604: ; можно записать в результат значение...

605: 82BDB jmp add_result

606: 82C0 sub_r_fail:

607: ; ... сдвинуть вправо...

608: 82C0F3 jmp move_right

609: 82C3 mvr_r_success:

610: ; ... вычесть ...

611: 82C3F jmp subtract

612: 82C6 mvr_fail:

613: ; ... пока второе число не упрется

614: ; в R0 и R1 будет результат

615: 82C6mov DPH, R0

616: 82C8mov DPL, R1

617: 82CA 22 ret

618:

619: ; проверка деления на ноль

620: 82CB divbyzero:

621: 82CB E5 83 mov A, DPH

622: 82CD 70 D3 jnz nozero

623: ; флаг ошибки деления на ноль

624: 82CF D2 0B setb 21h.3

625: 82D1 22 ret

626:

627: ; сдвиг второго операнда влево

628: 82D2 move_left:

629: ; сдвиг второго байта

630: 82D2 E5 82 mov A, DPL

631: 82D4 C3 clr C

632: 82D5 33 rlc A

633: 82D6 F5 82 mov DPL, A

634: ; сдвиг первого байта

635: 82D8 E5 83 mov A, DPH

636: 82DA 33 rlc A

637: ; число "уехало" влево

638: 82DB 40 0B jc rollback

639: 82DD F5 83 mov DPH, A

640: ; сдвиг регистра-счетчика

641: 82DF EB mov A, R3

642: 82E0 C3 clr C

643: 82E1 33 rlc A

644: 82E2 FB mov R3, A

645: 82E3 EA mov A, R2

646: 82E4 33 rlc A

647: 82E5 FA mov R2, A

648: 82E6 80 CA jmp mvl_success

649:

650: ; откат сдвига влево

651: 82E8 rollback:

652: 82E8 D3 setb C

653: 82E9 13 rrc A

654: 82EA F5 83 mov DPH, A

655: 82EC E5 82 mov A, DPL

656: 82EE 13 rrc A

657: 82EF F5 82 mov DPL, A

658: 82F1 80 C5 jmp mvl_fail

659:

660: ; сдвиг второго операнда вправо

661: 82F3 move_right:

662: ; сдвиг первого байта

663: 82F3 E5 83 mov A, DPH

664: 82F5 C3 clr C

665: 82F6 13 rrc A

666: 82F7 F5 83 mov DPH, A

667: ; сдвиг второго байта

668: 82F9 E5 82 mov A, DPL

669: 82FB 13 rrc A

670: 82FC F5 82 mov DPL, A

671: ; сдвиг регистра счетчика

672: 82FE EA mov A, R2

673: 82FF C3 clr C

674: 8rrc A

675: 8301 FA mov R2, A

676: 8302 EB mov A, R3

677: 8rrc A

678: ; число было в крайнем правом положении

679: 8C0 jc mvr_fail

680: 8306 FB mov R3, A

681: 8A jmp mvr_success

682:

683: ; к какой фазе относится

684: ; данный сдвиг вправо

685: 830A mvr_success:

686: ; к первой

687: 830AAB jnb 21h.0, mvl_fail

688: ; ко второй

689: 830D 80 B4 jmp mvr_r_success

690:

691: ; вычитание для деления

692: 830F subtract:

693: ; вычитание второго байта

694: 830F EF mov A, R7

695: 8310 C3 clr C

696: 8subb A, DPL

697: 8313 FD mov R5, A

698: ; вычитание первого байта

699: 8314 EE mov A, R6

700: 8subb A, #0

701: 8jc sub_fail

702: 8subb A, DPH

703: 831Bjc sub_fail

704: 831D FC mov R4, A

705: 831Ejmp sub_success

706:

707: ; вычитание не получилось,

708: ; куда теперь?

709: 8321 sub_fail:

710: ; на первую фазу

711: 8jnb 21h.0, sub_l_fail

712: ; на вторую фазу

713: 8A jmp sub_r_fail

714:

715: ; вычитание получилось,

716: ; но куда сейчас?

717: 8326 sub_success:

718: ; на первую фазу

719: 8jnb 21h.0, sub_l_success

720: ; на вторую фазу

721: 8jmp sub_r_success

722:

723: ; добавление значения

724: ; к результату деления

725: 832B add_result:

726: ; первый байт

727: 832B EA mov A, R2

728: 832C 48 orl A, R0

729: 832D F8 mov R0, A

730: ; второй байт

731: 832E EB mov A, R3

732: 832F 49 orl A, R1

733: 8330 F9 mov R1, A

734: ; записать новое делимое

735: 8331 EC mov A, R4

736: 8332 FE mov R6, A

737: 8333 ED mov A, R5

738: 8334 FF mov R7, A

739: 8jmp sub_r_fail

740:

741: ; вывод

742: 8337 output:

743: ; сообщения об ошибках

744: 8jb 21h.1, output_overflow

745: 833A 20 0B 8E jb 21h.3, divbyzero

746: 833DCF jmp output_correct

747:

748: 8340 output_ret:

749: 8ret

750:

751: ; ошибка переполнения

752: 8341 output_overflow:

753: 8F mov A, #'O'

754: 8call out

755: 8mov A, #'V'

756: 8call out

757: 834Bmov A, #'E'

758: 834Dcall out

759: 8mov A, #'R'

760: 8call out

761: 8mov A, #'F'

762: 8call out

763: 835A 74 4C mov A, #'L'

764: 835Ccall out

765: 835F 74 4F mov A, #'O'

766: 8call out

767: 8mov A, #'W'

768: 8call out

769: 8A mov A, #0Ah

770: 836Bcall out

771: 836E 80 D0 jmp output_ret

772:

773: ; ошибка деления на ноль

774: 8370 output_divbyzero:

775: 8mov A, #'D'

776: 8call out

777: 8mov A, #'I'

778: 8call out

779: 837Amov A, #'V'

780: 837Ccall out

781: 837Fmov A, #'I'

782: 8call out

783: 8mov A, #'S'

784: 8call out

785: 8mov A, #'I'

786: 838Bcall out

787: 838E 74 4F mov A, #'O'

788: 8call out

789: 8E mov A, #'N'

790: 8call out

791: 8mov A, #20h

792: 839Acall out

793: 839Dmov A, #'B'

794: 839Fcall out

795: 83A2mov A, #'Y'

796: 83A4call out

797: 83A7mov A, #20h

798: 83A9call out

799: 83AC 74 5A mov A, #'Z'

800: 83AEcall out

801: 83B1mov A, #'E'

802: 83B3call out

803: 83B6mov A, #'R'

804: 83B8call out

805: 83BB 74 4F mov A, #'O'

806: 83BDcall out

807: 83C0 74 0A mov A, #0Ah

808: 83C2call out

809: 83C5jmp output_ret

810:

811: ; вывод минуса

812: 83C7 out_minus:

813: 83C7 74 2D mov A, #2Dh

814: 83C9call out

815: 83CCD2 jmp minus_done

816:

817: ; вывод результата

818: 83CF output_correct:

819: ; если число отрицательное

820: 83CF 20 0A F5 jb 21h.2, out_minus

821: 83D2 minus_done:

822: ; резервные копии результата

823: 83D2mov 30h, DPH

824: 83D5mov 31h, DPL

825: ; первая итерация

826: ; деление на 10000

827: ; 000

828: 83D8 AE 83 mov R6, DPH

829: 83DA AF 82 mov R7, DPL

830: 83DCmov DPH, #b

831: 83DFmov DPL, #b

832: 83E2 51 9E call division

833: ; результат записать в первый разряд

834: 83E4mov A, #30h

835: 83E6add A, DPL

836: 83E8 F5 32 mov 32h, A

837: ; результат умножить на 10000

838: 83EA 7E 27 mov R6, #b

839: 83EC 7F 10 mov R7, #b

840: 83EE 51 1E call multiply

841: ; ... и вычесть из решения

842: 83F0 AE 30 mov R6, 30h

843: 83F2 AF 31 mov R7, 31h

844: 83F4 31 FD call minus

845: ; вторая итерация

846: ; повторить то же самое для 1000

847: ; 000

848: 83F6mov 30h, DPH

849: 83F9mov 31h, DPL

850: 83FC AE 83 mov R6, DPH

851: 83FE AF 82 mov R7, DPL

852: 8mov DPH, #b

853: 8E8 mov DPL, #b

854: 8E call division

855: ; результат записать во второй разряд

856: 8mov A, #30h

857: 840Aadd A, DPL

858: 840C F5 33 mov 33h, A

859: ; результат умножить на 1000

860: 840E 7E 03 mov R6, #b

861: 8410 7F E8 mov R7, #b

862: 8E call multiply

863: ; ... и вычесть из решения

864: 8414 AE 30 mov R6, 30h

865: 8416 AF 31 mov R7, 31h

866: 8FD call minus

867: ; третья итерация

868: ; повторить то же самое для 100

869: ; 000

870: 841Amov 30h, DPH

871: 841Dmov 31h, DPL

872: 8420 AE 83 mov R6, DPH

873: 8422 AF 82 mov R7, DPL

874: 8mov DPH, #0

875: 8mov DPL, #b

876: 842A 51 9E call division

877: ; результат записать в третий разряд

878: 842Cmov A, #30h

879: 842Eadd A, DPL

880: 8430 F5 34 mov 34h, A

881: ; результат умножить на 100

882: 8432 7E 00 mov R6, #0

883: 8434 7F 64 mov R7, #b

884: 8E call multiply

885: ; ... и вычесть из решения

886: 8438 AE 30 mov R6, 30h

887: 843A AF 31 mov R7, 31h

888: 843C 31 FD call minus

889: ; четвертая итерация

890: ; повторить для 10

891: ; и записать в четвертый разряд

892: 843E E5 82 mov A, DPL

893: 8F0 0A mov B, #10

894: 8div AB

895: 8444 FE mov R6, A

896: 8add A, #30h

897: 8447 F5 35 mov 35h, A

898: ; пятая итерация

899: ; остаток записать в пятый разряд

900: 8449 EE mov A, R6

901: 844A 75 F0 0A mov B, #10

902: 844D A4 mul AB

903: 844E F5 F0 mov B, A

904: 8450 E5 82 mov A, DPL

905: 8452 C3 clr C

906: 8F0 subb A, B

907: 8add A, #30h

908: 8457 F5 36 mov 36h, A

909: ; вывод на экран

910: 8459 E5 32 mov A, 32h

911: 845Bcall out

912: 845E E5 33 mov A, 33h

913: 8call out

914: 8463 E5 34 mov A, 34h

915: 8call out

916: 8468 E5 35 mov A, 35h

917: 846Acall out

918: 846D E5 36 mov A, 36h

919: 846Fcall out

920: 8A mov A, #0Ah

921: 8call out

922: 8jmp output_ret

923:

924: ; готовность к работе

925: 8479 output_ready:

926: 8mov A, #'R'

927: 847Bcall out

928: 847Emov A, #'E'

929: 8call out

930: 8mov A, #'A'

931: 8call out

932: 8mov A, #'D'

933: 848Acall out

934: 848Dmov A, #'Y'

935: 848Fcall out

936: 8A mov A, #0Ah

937: 8call out

938: 8ret

939:

940: ; вывод символа

941: 8498 out:

942: 8498 C2 AC clr ES

943: 849AFB jnb TI, out

944: 849D C2 99 clr TI

945: 849F F5 99 mov SBUF, A

946: 84A1 D2 AC setb ES

947: 84A3A7 call delay

948: 84A6 22 ret

949:

950: ; задержка как мера от дребезга контактов

951: 84A7 delay:

952: 84A7 74 1F mov A, #b

953: 84A9 loop_delay:

954: 84A9 14 dec A

955: 84AA 70 FD jnz loop_delay

956: 84AC 22 ret

957:

958: 84AD main:

959: ; биты 0..3 - длина вводимого числа

960: ; 4 бит - 0 - первое число, 1 - второе

961: ; 5, 6 биты - знак операции

962: ; (00 - +,, 10 - *, 11 - /)

963: ; 7 бит - клавиша нажата и держится

964: 84ADmov 20h, #1

965: ; бит 0 - этапы операции деления

966: ; бит 1 регистрирует переполнение

967: ; бит 2 указывает на отрицательность числа

968: ; бит 3 зарезервирован для ошибки деления на ноль

969: 84B0mov 21h, #0

970: 84B3 75 B8 00 mov IP, #0

971: ; прерывания принимаются

972: ; от таймера, матричной клавиатуры

973: ; и обычной клавиатуры

974: 84B6 75 A8 92 mov IE, #b

975: ; таймер

976: 84B9mov TMOD, #b

977: 84BCmov TCON, #b

978: 84BFcall output_ready

979:

980: 84C1 80 FE loop: jmp loop

981: end

Список использованной литературы

1.  , Лекции по микропроцессорным технологиям, 2010 г.

2.  «Микроконтроллеры семейства MCS-51», http://digital. *****/content. htm






Подпишитесь на рассылку:

Калькулятор




 Курсы:

Подготовительные курсыДистационное образование и курсыПодготовительные курсыДневные курсыВечерние курсыКонкурсы профессиональныеЗаочные конкурсыКурсовые работыПрограммы курсовКурсы МЭОКурсы лекций

Студенты: Для студентов I курсаДля студентов II курсаДля студентов III курсаДля студентов IV курсаДля студентов V курсаДля студентов VI курса

Основные темы

Проекты по теме:

Основные порталы, построенные редакторами

Домашний очаг

ДомДачаСадоводствоДетиАктивность ребенкаИгрыКрасотаЖенщины(Беременность)СемьяХобби
Здоровье: • АнатомияБолезниВредные привычкиДиагностикаНародная медицинаПервая помощьПитаниеФармацевтика
История: СССРИстория РоссииРоссийская Империя
Окружающий мир: Животный мирДомашние животныеНасекомыеРастенияПриродаКатаклизмыКосмосКлиматСтихийные бедствия

Справочная информация

ДокументыЗаконыИзвещенияУтверждения документовДоговораЗапросы предложенийТехнические заданияПланы развитияДокументоведениеАналитикаМероприятияКонкурсыИтогиАдминистрации городовПриказыКонтрактыВыполнение работПротоколы рассмотрения заявокАукционыПроектыПротоколыБюджетные организации
МуниципалитетыРайоныОбразованияПрограммы
Отчеты: • по упоминаниямДокументная базаЦенные бумаги
Положения: • Финансовые документы
Постановления: • Рубрикатор по темамФинансыгорода Российской Федерациирегионыпо точным датам
Регламенты
Термины: • Научная терминологияФинансоваяЭкономическая
Время: • Даты2015 год2016 год
Документы в финансовой сферев инвестиционнойФинансовые документы - программы

Техника

АвиацияАвтоВычислительная техникаОборудование(Электрооборудование)РадиоТехнологии(Аудио-видео)(Компьютеры)

Общество

БезопасностьГражданские права и свободыИскусство(Музыка)Культура(Этика)Мировые именаПолитика(Геополитика)(Идеологические конфликты)ВластьЗаговоры и переворотыГражданская позицияМиграцияРелигии и верования(Конфессии)ХристианствоМифологияРазвлеченияМасс МедиаСпорт (Боевые искусства)ТранспортТуризм
Войны и конфликты: АрмияВоенная техникаЗвания и награды

Образование и наука

Наука: Контрольные работыНаучно-технический прогрессПедагогикаРабочие программыФакультетыМетодические рекомендацииШколаПрофессиональное образованиеМотивация учащихся
Предметы: БиологияГеографияГеологияИсторияЛитератураЛитературные жанрыЛитературные героиМатематикаМедицинаМузыкаПравоЖилищное правоЗемельное правоУголовное правоКодексыПсихология (Логика) • Русский языкСоциологияФизикаФилологияФилософияХимияЮриспруденция

Мир

Регионы: АзияАмерикаАфрикаЕвропаПрибалтикаЕвропейская политикаОкеанияГорода мира
Россия: • МоскваКавказ
Регионы РоссииПрограммы регионовЭкономика

Бизнес и финансы

Бизнес: • БанкиБогатство и благосостояниеКоррупция(Преступность)МаркетингМенеджментИнвестицииЦенные бумаги: • УправлениеОткрытые акционерные обществаПроектыДокументыЦенные бумаги - контрольЦенные бумаги - оценкиОблигацииДолгиВалютаНедвижимость(Аренда)ПрофессииРаботаТорговляУслугиФинансыСтрахованиеБюджетФинансовые услугиКредитыКомпанииГосударственные предприятияЭкономикаМакроэкономикаМикроэкономикаНалогиАудит
Промышленность: • МеталлургияНефтьСельское хозяйствоЭнергетика
СтроительствоАрхитектураИнтерьерПолы и перекрытияПроцесс строительстваСтроительные материалыТеплоизоляцияЭкстерьерОрганизация и управление производством

Каталог авторов (частные аккаунты)

Авто

АвтосервисАвтозапчастиТовары для автоАвтотехцентрыАвтоаксессуарыавтозапчасти для иномарокКузовной ремонтАвторемонт и техобслуживаниеРемонт ходовой части автомобиляАвтохимиямаслатехцентрыРемонт бензиновых двигателейремонт автоэлектрикиремонт АКППШиномонтаж

Бизнес

Автоматизация бизнес-процессовИнтернет-магазиныСтроительствоТелефонная связьОптовые компании

Досуг

ДосугРазвлеченияТворчествоОбщественное питаниеРестораныБарыКафеКофейниНочные клубыЛитература

Технологии

Автоматизация производственных процессовИнтернетИнтернет-провайдерыСвязьИнформационные технологииIT-компанииWEB-студииПродвижение web-сайтовПродажа программного обеспеченияКоммутационное оборудованиеIP-телефония

Инфраструктура

ГородВластьАдминистрации районовСудыКоммунальные услугиПодростковые клубыОбщественные организацииГородские информационные сайты

Наука

ПедагогикаОбразованиеШколыОбучениеУчителя

Товары

Торговые компанииТоргово-сервисные компанииМобильные телефоныАксессуары к мобильным телефонамНавигационное оборудование

Услуги

Бытовые услугиТелекоммуникационные компанииДоставка готовых блюдОрганизация и проведение праздниковРемонт мобильных устройствАтелье швейныеХимчистки одеждыСервисные центрыФотоуслугиПраздничные агентства

Блокирование содержания является нарушением Правил пользования сайтом. Администрация сайта оставляет за собой право отклонять в доступе к содержанию в случае выявления блокировок.