Hallo. Darf mit kurz mal vorstellen. Bin angehender Elektrotechniker und betreibe die Mikrocontrollerprogrammierung hobbymässig. Habe das Forum des öfteren aufgesucht und immer eine Antwort auf meine Frage gefunden. Jetzt habe ich aber eine Sache, die ich auch mit der Suchfunktion nicht lösen konnte. Es geht um folgendes. Verwende folgenden Mikrocontroller: Infineon SAB80C515 Mit diesem Mikrocontroller habe ich folgendes vor bzw. geplant. Wie mit dem Timer 0 die Impulslänge eines externen Impulses im bereich von 0µs bit 65535µs messen und diesen Wert als BCD ausgeben. Mein Problem liegt nun daran, dass diese Controller nur 8Bit Zahlen verarbeiten kann. Wie zerlege ich nun die zwei 8Bit Zahlen so, dass auch der richtige Wert des Impulses an der Anzeige auftaucht. Bei Zahlen bis 255 habe ich es folgendesmassen gemacht: MOV A,TL0 // Lade Timerwert low von T0 in Akku MOV B,#0AH // Schiebe 10 in B-Register DIV AB // Teile Akku durch B Register MOV _1er,B // Schiebe Divisionsrest von B-Register in 1er Speicher MOV B,#0AH // Schiebe 10 in B-Register DIV AB // Teile Akku durch B Register MOV _10er,B // Schiebe Divisionsrest von B-Register in 10er Speicher MOV _100er,A // Schiebe Quotient von Akku in 100er Speicher Leider funktioniert das bei Zahlen größer 255 nicht mehr, da der µC keine 16Bit Zahlen dividieren kann. Habe es schon mit der Subdraktione der beiden 8Bit hälfen in 10000er, 1000er, 100er, 10er und 1er versucht, aber irgendwie funktioniert das auch nicht. Ich hoffe es hat jemand von euch eine guten Ansatz wie ich das Problem am einfachsten lösen kann. PS ich schreibe die Programm in Assembler. Bin für jede Hilfestellung dankbar. Gruß Hubert83
Moin leider nur für Atmel ,aber das Prinzip dürfte dadurch ja klar werden :-) “bin2BCD16” implements the following algorithm: 1. Load Loop counter with 16. 2. Clear all three bytes of result. 3. Shift left input value Low byte. 4. Shift left carry into input value High byte. 5. Shift left carry into result byte 0 (two least significant digits). 6. Shift left carry into result byte 1. 7. Shift left carry into result byte 2 (most significant digit). 8. Decrement Loop counter 9. If Loop counter is zero, return from subroutine. 10. Add $03 to result byte 2. 11. If bit 3 is zero after addition, restore old value of byte 2. 12. Add $30 to result byte 2. 13. If bit 7 is zero after addition, restore old value of byte 2. 14. Add $03 to result byte 1. 15. If bit 3 is zero after addition, restore old value of byte 1. 16. Add $30 to result byte 1. 17. If bit 7 is zero after addition, restore old value of byte 1. 18. Add $03 to result byte 0. 19. If bit 3 is zero after addition, restore old value of byte 0. 20. Add $30 to result byte 0. 21. If bit 7 is zero after addition, restore old value of byte 0. 22. Goto Step 3. In the implementation. Steps 10 - 21 are carried out inside a loop, where the Z-pointer is used for successive access of all three bytes of the result. This is shown in the flow chart shown in Figure 1. weiter gehts bei www.atmel.com http://www.atmel.com/dyn/products/app_notes.asp?family_id=607 dort dann die Applikation Nr. AVR204 ( BCD Arithmetics )
Es gibt 2 übliche Methoden: 1. Digit = Anzahl der Subtraktion von Zehnerpotenzen
1 | mov r6, #low(60900) |
2 | mov r7, #high(60900) |
3 | call bcd |
4 | mov r6, #low(09090) |
5 | mov r7, #high(09090) |
6 | call bcd |
7 | mov r6, #low(12345) |
8 | mov r7, #high(12345) |
9 | call bcd |
10 | jmp $ |
11 | |
12 | ;input: R7, R6 = 16 bit value 0 ... 65535 |
13 | ;output: R7, R6, R5, R4, R3 = digits (ASCII) |
14 | ;cycle: 37 .. 220 |
15 | ;bytes: 44 |
16 | ; |
17 | bcd: mov a, r7 |
18 | mov r3, a |
19 | mov a, r6 |
20 | mov r7, #-1 + '0' |
21 | ?bcd1: inc r7 |
22 | add a, #low(-10000) |
23 | xch a, r3 |
24 | addc a, #high(-10000) |
25 | xch a, r3 |
26 | jc ?bcd1 |
27 | mov r6, #10 + '0' |
28 | ?bcd2: dec r6 |
29 | add a, #low(1000) |
30 | xch a, r3 |
31 | addc a, #high(1000) |
32 | xch a, r3 |
33 | jnc ?bcd2 |
34 | mov r5, #-1 + '0' |
35 | inc r3 |
36 | ?bcd3: inc r5 |
37 | add a, #low(-100) |
38 | jc ?bcd3 |
39 | djnz r3, ?bcd3 |
40 | mov r4, #10 + '0' |
41 | ?bcd4: dec r4 |
42 | add a, #10 |
43 | jnc ?bcd4 |
44 | add a, #'0' |
45 | mov r3, a |
46 | ret |
47 | |
48 | end |
2. Digit = Rest aus Division / 10
1 | mov r6, #low(12345) |
2 | mov r7, #high(12345) |
3 | call bcd |
4 | jmp $ |
5 | |
6 | ;input: R7, R6 = value |
7 | ;output: R7, R6, R5, R4, R3 = digits |
8 | ;cycle: 292 |
9 | ;bytes: 40 |
10 | ; |
11 | using 0 |
12 | bcd: |
13 | mov a, r6 |
14 | mov r2, a |
15 | mov r1, #ar3 ;point to r3 |
16 | ?bcd1: mov r0, #ar7 ;point to msb |
17 | setb f0 |
18 | clr a |
19 | ?bcd2: xch a, @r0 |
20 | xchd a, @r0 |
21 | swap a |
22 | mov b, #10 |
23 | div ab ;high nibble / 10 |
24 | swap a |
25 | xch a, @r0 |
26 | swap a |
27 | add a, b |
28 | swap a |
29 | mov b, #10 |
30 | div ab ;low nibble / 10 |
31 | xchd a, @r0 |
32 | mov a, b |
33 | mov r0, #ar2 ;point to lsb |
34 | jbc f0, ?bcd2 |
35 | mov @r1, a |
36 | inc r1 |
37 | cjne r1, #ar7+1, ?bcd1 |
38 | ret |
39 | |
40 | end |
Peter
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.