Binärt till BCD

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
baltazar
Inlägg: 106
Blev medlem: 19 oktober 2003, 21:50:18

Binärt till BCD

Inlägg av baltazar »

Är det ngn som har förslag på hur man gör för att omvandla ett 16-bitars binärt tal till bcd i en microcontroller?
Ex. 111111 binärt = 63 ska göras om till två tal 110 (=6) och 11 (=3)
Lite jobbigt och göra en tabell med 65535 rader... :?
Användarvisningsbild
Hedis
Inlägg: 2493
Blev medlem: 8 december 2003, 15:10:44
Ort: Vänersborg
Kontakt:

Inlägg av Hedis »

Du får skriva tre räknare som räknar till 9 och när den är nådd så lägger den till en 1:a på nästa räknare. alltså blir det 10->11->12...19->20->21 osv.

Sen får man lägga ihop dessa mellan varje test och se om det är samma tal som det man ville dela på.

Ursch, dåligt beskrivet men så får man göra.

EDIT: Hehe CYR, det är sekunderna som gör det :)
Senast redigerad av Hedis 8 juli 2004, 23:00:00, redigerad totalt 1 gång.
cyr
Inlägg: 2712
Blev medlem: 27 maj 2003, 16:02:39
Ort: linköping
Kontakt:

Inlägg av cyr »

http://www.cs.uiowa.edu/~jones/bcd/decimal.html

Har även sett PIC-kod baserat på precis samma ide tror jag, nånstans...

Om det inte behöver vara jättesnabbt går det väl bra med typ:

(bin = 8bits binärt tal, hun,ten,one = bcd-siffror)

Kod: Markera allt

hun=0;
ten=0;
one=0;

while(bin>100)
{
    hun++;
    bin=bin-100;
}

while(bin>10)
{
    ten++;
    bin=bin-10;
}

one=bin;
Bara att utöka till så många siffror man behöver...
mullemeck
Inlägg: 1306
Blev medlem: 27 maj 2003, 23:52:06
Ort: Lund
Kontakt:

Inlägg av mullemeck »

man kan annars ta hjälp av avsaknaden av decimaler..

först tar du ditt tal 63 och delar med 10 då blir det 6.3 vilket då blir 6..

sen tar du och gångar det du precis fick fram med tio 6*10=60 och drar bort detta från det första talet du hade och får då 63-60 = 3...

för att få fram hundratal och tusental så får man göra på ungefär samma sätt men dividera/multiplicera med 100 eller 1000 istället..


kanske inte bästa sättet men det funkar för det mesta...
cyr
Inlägg: 2712
Blev medlem: 27 maj 2003, 16:02:39
Ort: linköping
Kontakt:

Inlägg av cyr »

Dividera är väl egentligen standardmetoden, på datorer där man kan göra det snabbt och enkelt (dvs det finns en div-instruktion). Det är ofta rätt omständigt att göra det på en mikrokontroller.
mullemeck
Inlägg: 1306
Blev medlem: 27 maj 2003, 23:52:06
Ort: Lund
Kontakt:

Inlägg av mullemeck »

jo kan tänka mej det.. har använt det sättet jag sa några gånger i picbasic innan jag fattade att det redan fanns en inbyggd funktion för att få fram bcd siffror... :doh:
Användarvisningsbild
baltazar
Inlägg: 106
Blev medlem: 19 oktober 2003, 21:50:18

Inlägg av baltazar »

Tack så mycket för tipsen :)
Jag glömde väl o säga att jag kör med assembler...men nu har jag fått ihop en funktion som verkar funka.
Hojta till om nån vill ha koden så lägger jag ut den...
Användarvisningsbild
Chribbe76
EF Sponsor
Inlägg: 1167
Blev medlem: 17 januari 2004, 22:43:17
Ort: Stockholm

Inlägg av Chribbe76 »

Jag har använt en skum variant som alltid tar lika många klockcycler 579st (jag har inte skrivit den själv bara optimerat den lite)
Jag vet inte vilken metod som är snabbast men den här är iaf skum :?

Programkoden är för pic16(går att optimera till 489klockcycler för pic18)

16 bitar i L_byte,H_byte ex: FFFFH
Resultatet: R0=06H R1=55H R2=35H

Kod: Markera allt

	movlw   .15
	movwf   count
	clrf    R0
	clrf    R1
	clrf    R2
loop16  rlf     L_byte, F
	rlf     H_byte, F
	rlf     R2, F
	rlf     R1, F
	rlf     R0, F

	movlw   3
	addwf   R2,W
	movwf   temp
	btfsc   temp,3          ; test if result > 7
	movwf   R2
	movlw   30
	addwf   R2,W
	movwf   temp
	btfsc   temp,7          ; test if result > 7
	movwf   R2               ; save as MSD
	movlw   3
	addwf   R1,W
	movwf   temp
	btfsc   temp,3          ; test if result > 7
	movwf   R1
	movlw   30
	addwf   R1,W
	movwf   temp
	btfsc   temp,7          ; test if result > 7
	movwf   R1               ; save as MSD
	movlw   3
	addwf   R0,W
	movwf   temp
	btfsc   temp,3          ; test if result > 7
	movwf   R0
	movlw   30
	addwf   R0,W
	movwf   temp
	btfsc   temp,7          ; test if result > 7
	movwf   R0               ; save as MSD

	decfsz  count, F
	goto    loop16

	rlf     H_byte, F
	rlf     R2, F
	rlf     R1, F
	rlf     R0, F
Hur många klockcycler går åt som mest med din funktion baltazar?
Användarvisningsbild
baltazar
Inlägg: 106
Blev medlem: 19 oktober 2003, 21:50:18

Inlägg av baltazar »

Jag förstår nog inte ditt program riktigt...Om jag stoppar in FFFFh i mina HI resp. LO byte så får jag ut: Tiotusental = 6, tusental = 5, hundratal = 5, tiotal = 3 och ental = 6, alltså som gjort för o skriva ut på en display.
Har inte räknat klockcyklerna... är inte kritiskt i mitt fall.
Användarvisningsbild
Chribbe76
EF Sponsor
Inlägg: 1167
Blev medlem: 17 januari 2004, 22:43:17
Ort: Stockholm

Inlägg av Chribbe76 »

Jag antar att du menar 65535.
Varje byte innehåller 2siffror i Resultatet.
Resultatet: R0=06H R1=55H R2=35H
evert2
Inlägg: 2182
Blev medlem: 18 april 2004, 22:47:56
Ort: Jönköping

Inlägg av evert2 »

Om det inte finns kra på att talet skall exekveras på lika lång tid oavsett talets storlek.......så finns det nog en variant på Hedis förslag....men som är lite effektivare....

Låt säga att du har ett register med ett tal............t ex 23 546.....

OM talet är större än tiotusen minskas värdet i registret med tioitusen.......och i ett annat register/address inkremeras värdet med ett........... och så håller det på tills värdet i registret understiger just tiotusen. Sen fortsätter man på samma sätt på "tusen".......osv

Detta gör att om du då har talet 59999, vilket bord var det tal som tar längst tid behöver man bara köra igenom de olika "subtraktionslooparna" 5+9+9+9 ggr ......alltså 32 ggr.....ä väl inte så farligt va?

(Obs! Entalsiffran påverkar inte exekveringstiden av detta program)
evert2
Inlägg: 2182
Blev medlem: 18 april 2004, 22:47:56
Ort: Jönköping

Inlägg av evert2 »

Fast det är klart att det kan bli lite krångligt om talet ligger uppdelat på två addresser.....för det är ju 8 bitar i varje address.......hmmm..... :evil:
Användarvisningsbild
baltazar
Inlägg: 106
Blev medlem: 19 oktober 2003, 21:50:18

Inlägg av baltazar »

>>Chribbe76 Ok nu fattar jag hur din kod funkar... med FFFFh tog min över 700 000 klockcykler :?
En viss skillnad alltså...jag räknar ju helt enkelt ner 16-bitarstalet till noll och fyller på variablerna under tiden...
Men med 0001h tar det bara 24 cykler 8)
Euphaz
Inlägg: 49
Blev medlem: 18 juni 2004, 23:21:07

Inlägg av Euphaz »

evert2 skrev: OM talet är större än tiotusen minskas värdet i registret med tioitusen.......och i ett annat register/address inkremeras värdet med ett...........
Den är ju ganska snabb ja. Satt och funderade lite och kom på en som kanske är ännu snabbare:

Subtrahera 40.000
Shifta carrybit in i utregister
Ingen carry (<40.000)?, addera 40.000 igen
Subtrahera 20.000
Shifta carrybit in i utregister
Ingen carry (<20.000)?, addera 20.000 igen
Subtrahera 10.000
Shifta carrybit in i utregister
Ingen carry (<10.000)?, addera 10.000 igen

Nu ska utregistret innehålla tiotusental, kopiera och clear utregister

Subtrahera 8.000
Shifta carrybit in i utregister
Ingen carry (<8.000)?, addera 8.000 igen
Subtrahera 4.000
Shifta carrybit in i utregister
Ingen carry (<4.000)?, addera 4.000 igen

osv... Dom sista 6 (200,100,80,40,20,10) blir bara 8 bit-operationer.
Användarvisningsbild
Chribbe76
EF Sponsor
Inlägg: 1167
Blev medlem: 17 januari 2004, 22:43:17
Ort: Stockholm

Inlägg av Chribbe76 »

Den verkar funka.
Jävligt smart.
Ska testa att skriva en för Pic.
Skriv svar