10-bitové dvojkové číslo (omezeno na 0 - 999) na BCD, MCU 8051 – Assembler – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

10-bitové dvojkové číslo (omezeno na 0 - 999) na BCD, MCU 8051 – Assembler – Fórum – Programujte.com10-bitové dvojkové číslo (omezeno na 0 - 999) na BCD, MCU 8051 – Assembler – Fórum – Programujte.com

 

10. 5. 2017   #1
-
0
-

ahoj,

potřebuji na 8051 převést 10-bitové číslo v rozsahu 0 - 999 na jednotlivé cifry abych je mohl vyspat na 7-segmentový displej. Zatím mne napadlo dělení 4 (udělat pomocí RRA  A bitový posun) a pak dělit 25 instrukcí DIV, tak získat stovky a pak zbytek dělit pomocí DIV a získat desítky a jednotky. Máte někdo efektivnější postup?

hu

Nahlásit jako SPAM
IP: 193.86.81.–
Jerry
~ Anonymní uživatel
512 příspěvků
11. 5. 2017   #2
-
0
-

#1 hlucheucho
To co hledáš tomu se řiká BCD

https://cs.wikipedia.org/wiki/BCD

a  kod je tady

http://www.8052.com/codelib/

stačí když těch tvejch 10 bitu rozšíříš na 16 a horních 6 necháš nula.

stačí dát do googlu heslo: 8051  BCD conversion

a vyleze ti hafo odkazu

tady se to řeší

http://www.electro-tech-online.com/threads/binary-to-bcd-8051.130739/

https://okashtein.wordpress.com/2013/04/15/binary16-bit-to-bcd/

http://what-when-how.com/8051-microcontroller/data-conversion-programs-in-8051-c/

je na to aj speciální čip

https://elektronicstore.com/74185-binary-tp-bcd-converter-dip16-74-ls-74ls185.html

http://www.utm.edu/staff/leeb/DM74185.pdf

jenom tak ze zvědavosti kde že se učí 51' ka ??? SŠ elektro ?

Nahlásit jako SPAM
IP: 194.228.128.–
peter
~ Anonymní uživatel
4014 příspěvků
11. 5. 2017   #3
-
0
-

#2 Jerry
Obavam se, ze hu uz davno pracuje :)
51 se ucila na SPS Zlin, pred x lety a snad stale uci.
 

#1 hlucheucho
Z toho google jsem na jednom forku nasel tohle, ale obvykle se pouziva BCD prevodni chip

BIN_DEC: MOV A,R0
MOV B,#100
DIV AB
MOV R3,A ; R3 CONTAIN HUNDRED NUMBER
MOV A,B
MOV B,#10
DIV AB
MOV R2,A ; R2 CONTAIN TENTH NUMBER
MOV R1,B ; R1 CONTAIN LEFT DECIMAL NUMBER
RET 

Binarni shiftovani ti je na houby, protoze binarni soustava pouziva nasobky 1, 2, 4, 8, 16.

Nahlásit jako SPAM
IP: 2001:718:2601:26c:51a1:40...–
11. 5. 2017   #4
-
0
-

Hledání: hledal jsem "8051 convert binary to bcd" a našel kopu hnoje, po proklikání 2,5 stránky odkazů jsem to vzdal. 

Dotaz nebyl položen, že bych neměl nějaké řešení, ale jestli existuje lepší řešení. Kdybych nevěděl, jak na to, ještě bych mohl programovat v C a použít dělení a modulo. Jednoduché na udělání, ale uvnitř bude ne moc efektivní kód. Poslední "finta" by byla tabulka hodnot v paměti programu, pak by to mohlo současně fungovat jako dekodér pro displej. "Nadatlit" 3000 Bytů bez chyby bych asi nedal. Malé nároky na strojový čas, ale rozežranost co do objemu kódu.

S tím by mohl souviset i dotaz, jak udělat dělení. Dodnes mi zůstala domněnka, že to jde udělat jako kombinační logika. Dodnes by mne zajímalo, jestli to tak opravdu je. Kdysi jsem to dělal jako dvojkové dělení stejným algoritmem jak dělíš ručně na papíře v desítkové soustavě.

Co se dnes učí na průmyslovce nevím, maturoval jsem před 24 lety.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
11. 5. 2017   #5
-
0
-

#3 peter
něco takového jsem našel taky, ale všechno je to na rozsah 1 Byte, tedy pro kočku. Právě to shiftování má smysl, ono 100 = 4 x 25. Pokud tedy 10-bitové číslo podělím nejdříve 4 (posun vpravo o 2 bity), dostanu 8-bitové číslo. A to pak snadno podělím číslem 25 instrukcí DIV AB. Podíl jsou stovky. Zbytek je pak obsah B x 4 + zbytek dělení 4 ( tzn hodnota dvou vysunutých bitů). Získání desítek a jednotek už je pak snadné, číslo nepřekračuje rozsah 1 Byte.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
KIIV
~ Moderátor
+43
God of flame
11. 5. 2017   #6
-
0
-

No zrovna na x51 se az tak desit deleni nemusis (krom toho ze vraci jak vysledek, tak zbytek po deleni). U takoveho AVR, kde instrukce deleni neexistuje, tak tam je to neco uplne jineho.

Ani bych x51 uplne nezatracoval, jsou varianty s vykonavanim vetsiny instrukci v jednom taktu oscilatoru (na rozdil od puvodnich 12, ci 6 ve vylepsenych jadrech), nastavitelne push-pull vystupy... 

Nahlásit jako SPAM
IP: 212.47.3.–
Program vždy dělá to co naprogramujete, ne to co chcete...
11. 5. 2017   #7
-
0
-

instrukční sadu AVR neznám, vždy jsem to dělal v C/C++.

S názorem KIIV souhlasím. Hromada světových výrobců 8051 dodnes vyrábí (Analog Devices, Microchip - dříve Atmel, Texas Instruments ... ) , asi to nebude z rozmaru. Stejně tak se dodnes vyrábějí a aktualizují vývojové prostředky. Asi to bylo dobře vymyšlený jádro, když žije 40 let.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
11. 5. 2017   #8
-
0
-

a ještě poznámka k tomu codelib .... zkusil jsi některý z těch odkazů prokliknout? Ono to menu je hezký, ale když odkazuje na stránky, které neexistují, tak moc nepomůže.

Edtit: ještě jsem si vzpomněl na jednu možnost v C: použít sprintf. Ale to by efektivita kódu šla kam? No přece do ....

hu

Nahlásit jako SPAM
IP: 195.178.67.–
Jerry
~ Anonymní uživatel
512 příspěvků
11. 5. 2017   #9
-
0
-

#4 hlucheucho
Převod Binary to BCD se dělá taky pomocí Karnaughovy mapy pokud hledáš jak HW tak SW řešení. Ale to se učí někde ve 2.-3. ročníku na SŠ....  jinak 51 neobsahuje 2 bitový registr takže 10bitu se tak jako tak musí uložit do dvou osmibitových registru

tady je třeba hezkej kod a funguje:

http://www.8051projects.net/download-d27-binary-to-bcd.html

tady tady je něco .... něco ... něco

http://www.onarm.com/forum/19129/

a taky tady ...

https://microcontrollergarden.blogspot.cz/2013/08/8051-program-for-binary-to-bcd.html

Nahlásit jako SPAM
IP: 194.228.128.–
Jerry
~ Anonymní uživatel
512 příspěvků
11. 5. 2017   #10
-
0
-

#1 hlucheucho

; Content of "U_b" before, during & after the conversion:
; (L/H stand for LOW/HIGH - Nibble)
;
;  positive argument:
;  adr  in          out
;------------------------------
;  +5         L0    D(100,000)
;  +4         H0    D(10,000)
;  +3   A3    L1    D(1,000)
;  +2   A2    H1    D(100)
;  +1   A1    L2    D(10)
; &U_b  A0          D(1)

;  negative argument:
;  adr  in          out
;------------------------------
;  +5               '-'
;  +4         L0    D(10,000)
;  +3   A3    H0    D(1,000)
;  +2   A2    L1    D(100)
;  +1   A1    H1    D(10)
; &U_b  A0    L2    D(1)

;  Content of the registers during conversion:
;  (main loop, "LOOP_DIGIT")
;
;  R0 ... "Nibble" Pointer
;  R1 ... "Digit" Pointer
;  R2 ... "Nibble" Counter
;  R3 ... "Digit" Counter

;  positive argument:
;  R0    R1    R2    R3
;  +1    0     5     6
;  +1    +1    5     5
;  +2    +2    4     4
;  +3    +3    3     3
;  +4    +4    2     2
;  +5    +5    1     1

;  negative argument:
;  R0    R1    R2    R3
;  0     0     5     5
;  +1    +1    4     4
;  +2    +2    3     3
;  +3    +3    2     2
;  +4    +4    1     1

;--------------------------------------

$XREF
$NOMOD51

B  DATA  0F0H
ACC   DATA  0E0H
NAME  BCD

?PR?bin2bcd?BCD      SEGMENT CODE
EXTRN DATA (U_b)
PUBLIC   bin2bcd

   RSEG  ?PR?bin2bcd?BCD
   USING 0

bin2bcd:

   MOV   A,U_b
   JNB   ACC.7,POSITIVE
   
   CLR   C                    ; negative argument
   CLR   A
   SUBB  A,U_b+3
   MOV   U_b+3,A
   CLR   A
   SUBB  A,U_b+2
   MOV   U_b+2,A
   CLR   A
   SUBB  A,U_b+1
   MOV   U_b+1,A
   CLR   A
   SUBB  A,U_b
   JNZ   ERROR             ; should be ZERO
   
   MOV   R3,#5             ;"Digit" Counter
   MOV   R1,#U_b           ;"Digit" Pointer
   MOV   R2,#5             ;"Nibble" Counter
   MOV   R0,#U_b           ;"Nibble" Pointer


   MOV   U_b+5,#0FH        ; 0x0F as '-' Character
                           ; (will be converted for
                           ;  7-seg. LCD)

   MOV   A,U_b+1           ; LSB2 LN -> 0
   MOV   U_b,A
   ANL   U_b,#0FH   

   ANL   A, #0F0H          ; should be ZERO
   JNZ   ERROR

   MOV   A,U_b+3           ; LSB0 LN -> 4
   MOV   U_b+4,A
   ANL   U_b+4,#0FH
   SWAP  A
   MOV   U_b+3,A           ; LSB0 HN -> 3
   ANL   U_b+3,#0FH

   MOV   A,U_b+2           ; LSB1 LN -> 2
   ANL   U_b+2,#0FH
   SWAP  A
   MOV   U_b+1,A           ; LSB1 HN -> 1
   ANL   U_b+1,#0FH

   CLR   A
   SJMP  LOOP_DIV    ; everything is in place now
   
POSITIVE:

   MOV   A,U_b+1
   ANL   A, #0F0H          ; should be ZERO
   JNZ   ERROR

   MOV   A,U_b+3           ; LSB0 LN -> 5
   MOV   U_b+5,A
   ANL   U_b+5,#0FH
   SWAP  A
   MOV   U_b+4,A           ; LSB0 HN -> 4
   ANL   U_b+4,#0FH

   MOV   A,U_b+2           ; LSB1 LN -> 3
   MOV   U_b+3,A
   ANL   U_b+3,#0FH
   SWAP  A
   MOV   U_b+2,A           ; LSB1 HN -> 2
   ANL   U_b+2,#0FH

   ANL   U_b+1,#0FH        ; LSB2 LN -> 1

   MOV   R3,#6             ;"Digit" Counter
   MOV   R1,#U_b           ;"Digit" Pointer
   MOV   R2,#5             ;"Nibble" Counter
   MOV   R0,#U_b+1         ;"Nibble" Pointer

   CLR   A
   SJMP  LOOP_DIV    ; everything is in place now

LOOP_DIGIT:     

   MOV   AR0,AR1
   MOV   AR2,AR3
   CLR   A

LOOP_DIV:
   XCHD  A,@R0
   MOV   B,#10       ; DIVISOR
   DIV   AB
   XCHD  A,@R0
   MOV   A,B
   SWAP  A           ; Remainder in AKKU HIGH NIBBLE
   INC   R0
   DJNZ  R2,LOOP_DIV

   MOV   A,@R1        ; should be ZERO
   JNZ   ERROR
   MOV   @R1,B
   INC   R1
   DJNZ  R3,LOOP_DIGIT

END1:
   RET

ERROR:
   MOV A,#0FH         ; 0x0F as '-' Character
   MOV U_b,A
   MOV U_b+1,A
   MOV U_b+2,A
   MOV U_b+3,A
   MOV U_b+4,A
   MOV U_b+5,A

END2:   
   RET

   END

union
{
   unsigned char buf[6];
   long in;
} idata U_b;  

void bin2bcd(void);

From fmayr@electronic.tu-graz.ac.at Thu Feb  6 10:24:30 1997
Date: Wed, 05 Feb 1997 15:36:00 +0100
From: Friedrich Mayr <fmayr@electronic.tu-graz.ac.at>
To: 8051code@keil.com
Subject: Fast LONG to BCD conversion

This function was written within the Keil C51 environment
by Dr. Roehrer (Inst. f. Elektronik, TU-Graz) and me
to be called from a C - Program as: "void bin2bcd(void)"

The following global variable (must be located in the
internal RAM of the processor, "data" or "idata" ) is
used both to pass the argument (a "long" value) to the
function, as well as to receive the result (6 digits):

union
{
   unsigned char buf[6];
   long in;
} idata U_b;  

The purpose of the code is to convert a signed long value
to BCD - code with leading sign if needed. Values exceeding
the range of 6(-:5) Digits should all be displayed by '-'.
The usage of memory was critical because no external RAM is
present in the system, so only the Accu, B, R1, R2, R3, R4
are used aside of the digit- (and argument-) buffer "U_b".

The trick applied in the function is to use a
"small" (nibble by nibble) division and the extensive
use of the '51 - opcodes XCHD and SWAP.
This results in very fast execution.
The function can easily be modified for example
to time-calculations or extended to the full "long"
range .

Nahlásit jako SPAM
IP: 194.228.128.–
11. 5. 2017   #11
-
0
-

Pro porovnání jednoúčelové řešení pro 10 bitů: 

;cislo ulozeno v DPTR

;ziska stovky delenim (4 x 25)
;deleni 4 jako bitovy posun
MOV	A, DPL
ANL	A, #0FCh
ORL	A, DPH
RR	A
RR	A

;deleni 25
MOV	B, #25
DIV	AB
MOV	R0, A	;stovky ulozi do R0

;ziskani zbytku po deleni
MOV	A,  #04
MUL	AB
ANL	DPL, #3
ORL	A, DPL	;zbytek po deleni DPTR/100 je v A

;ziska desitky a jednotky - zbytek predchoziho deleni podeli 10
MOV	B, #10
DIV	AB	;v A jsou desitky, v B jsou jednotky

Drobná nevýhoda: nezachovává původní číslo. Méně instrukcí, méně strojových cyklů. Asi efektivnější cesta pro tento konkrétní případ není.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
peter
~ Anonymní uživatel
4014 příspěvků
11. 5. 2017   #12
-
0
-

Jeste by slo dat vysledky do pameti, jestli se chces vyhnout deleni (pro moc opakovani prevodu).

Nahlásit jako SPAM
IP: 2001:718:2601:26c:51a1:40...–
peter
~ Anonymní uživatel
4014 příspěvků
11. 5. 2017   #13
-
0
-

Jeste by tam slo dat ifka. Ale i51 to deleni ma rychle.

if (cislo<10) {return [0,0,cislo]}
if (cislo<100) {spoc c10, c1; return [0,c10,c1]}
spoc c100, c10, c1; return [c100,c10,c1]

Nebo opacne
zbytek = cislo
zbytek>100 -> c100, zbytek
zbytek>10 -> c10, zbytek
-> c1
 

Nahlásit jako SPAM
IP: 2001:718:2601:26c:51a1:40...–
peter
~ Anonymní uživatel
4014 příspěvků
11. 5. 2017   #14
-
0
-

A samozrejme je tu ta soucastka, bsd prevodnik, asi 20 kc zalezitost, tusim. Nevim jestli to nema dokonce i51 v sobe zabudovane.

Nahlásit jako SPAM
IP: 2001:718:2601:26c:51a1:40...–
11. 5. 2017   #15
-
0
-

Ono pomocí podmínek by šlo udělat i půlení intervalu. Ale to je vhodnější na aproximační ADC. 

Součástka není asi 20,-Kč. Dostupná bůhvíkde - nenašel jsem ji ani u Farnella, ani u Digi Key... Aliexpress má cenu 19,80, ale USD a ke všemu už nedostupné. Na fotografii je Texas Instruments a ten ji nezná (už ji nevyrábí?). Kromě toho těch 74LS185 by muselo být podle datasheetu 6 ks. Doporučit "Obsolete Part" je geniální nápad.

Další HW přístup je "napálit" EPROM nebo EEPROM, pak by bylo šikovnější do ní dát rovnou i dekodér pro displej. Tyto HW postupy mají jeden drobný nedostatek: 8051 nedokáže na porty zapsat současně 10 bitů. Spoždění mezi Byty by bylo několik strojových cyklů.  A do třetice použít PAL, možná šikovnější než EEPROM, jde v nich udělat i záchytný registr pro data z MCU.

Dát výsledky do paměti - tuto možnost jsem zmínil jako tabulku dat.

Kdyby to měla 8051 vestavěné, neřeším to softwarově.

Díval jsem se na výsledek překladu dělení int/int u IDE EW8051. Docela zajímavé, ale pro tento účel ne moc efektivní.

Vše nasvědčuje tomu, že pro převod 10-bitového čísla na BCD asi efektivnější algoritmus než mnou uvedený není. 

hu

Nahlásit jako SPAM
IP: 195.178.67.–
Jerry
~ Anonymní uživatel
512 příspěvků
11. 5. 2017   #16
-
-1
-
Mimo téma

#1 hlucheucho
hele a víte že existujou aj integrovaný budiče LED ? třeba M5450 ?

http://www.st.com/content/ccc/resource/technical/document/datasheet/e1/1b/1d/f7/3c/33/40/6f/CD00020632.pdf/files/CD00020632.pdf/jcr:content/translations/en.CD00020632.pdf

Nahlásit jako SPAM
IP: 194.228.128.–
11. 5. 2017   #17
-
0
-

#16 Jerry

neumí převod na BCD. Budič, do kterého se to nasype segment po segmentu po sériové lince.
Opět obsolete.
Že je to 7-segmentový ještě neznamená, že je to LED. Existují i 3 1/2 místné LCD bez budiče. Neřeším dekodér a budič displeje, řeším převod dvojkového čísla na BCD

hu

Nahlásit jako SPAM
IP: 193.86.81.–
MilanL+1
Grafoman
14. 5. 2017   #18
-
0
-

#11 hlucheucho
pokud bys chtěl zachovat původní DPTR, tak není nic jednoduššího než malá úprava s využitím např R1


nahradit část kodu po "MUL AB" tímto
MOV	R1, A
MOV	A, DPL
ANL	A, #3
ORL	A, R1	;zbytek po deleni DPTR/100 je v A

jinak si myslím, že je ten algoritmus vymyšlený dobře pro 10bitová čísla, myslím že s menší úpravou by šlo použít i na  další číselné řády s DPTR max 16bit (65535) větší čísla už by museli jít bud přes registry nebo paměť.

Nahlásit jako SPAM
IP: 193.165.115.–
peter
~ Anonymní uživatel
4014 příspěvků
15. 5. 2017   #19
-
0
-

Nevim ted, jestli se to jmenuje bcd prevodnik nebo dekadicky citac, ale tady to ve vyprodeji maji za 3 kc / kus.
http://aesobchod.cz/hledat?…
Jinak, klavesnice pouziva tez bcd prevodnik.

Nahlásit jako SPAM
IP: 2001:718:2601:26c:74a9:9b...–
peter
~ Anonymní uživatel
4014 příspěvků
15. 5. 2017   #20
-
0
-
Nahlásit jako SPAM
IP: 2001:718:2601:26c:74a9:9b...–
peter
~ Anonymní uživatel
4014 příspěvků
15. 5. 2017   #21
-
0
-

https://cs.wikipedia.org/wiki/Seznam_logick%C3%BDch_integrovan%C3%BDch_obvod%C5%AF_%C5%99ady_7400
vyhledat bcd

a mozna hledas '74150: 16-kanálový selektor, multiplexor d'

Nahlásit jako SPAM
IP: 2001:718:2601:26c:74a9:9b...–
15. 5. 2017   #22
-
0
-

To nejsou převodníky binární - BCD. 7442 je dekodér BCD na 1 z 10, 7490 je dekadický čítač, existují i jejich LS, HC a HCT verze. 7447 je dekodér BCD na 7-segm. displej, vhodný např. pro led, TI ho nadále vyrábí.  A 74150 je tuším multiplexer. Klávesnice (obvykle maticová) pak používá zcela jiný převod. Vše úplně mimo téma

hu

Nahlásit jako SPAM
IP: 195.178.67.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 194 hostů

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý