Stránka 1 z 3

zobrazení obsahu čítačů

Napsal: 16 lis 2022, 23:04
od petula
v mikropočítači spojím, za sebou dva 16-bitové čítače a vytvořím tak jeden 32 bitový čítač. Do tohoto čítače vstupují pulzy. Po ukončení načítání pulzů je potřeba tento 32-bitový obsah převést na desítkovou soustavu a odeslat na displej.
Příklad:
stav čítače 01100101010101000010000111011001 nutno převést na 1700012505 a odeslat na displej.

Otázka jak to udělat co nejrychleji a kolik času takováto operace zabere v 8-bitovém mikropočítači Microchip (pokud to vůbec je na 8bitovém miropočítači proveditelné)?
Našl jsem googlováním toto:

příklad konverze 16-bitového kódu zkoušená na PIC24

https://www.microchip.com/forums/m853241-p9.aspx#857650

otázka je, jak ji rozšířit na 32-bit kód a jak dlouho taková konverze potrvá.

void itoa16asm(uint16_t Value, uint8_t Decimal[]) { //Assembly conversion from
//16 bit unsigned integer to 5 decimal digits.
//Initial code from here: http://www.microchip.com/forums/FindPost/855132
//correction idea from here: http://www.microchip.com/forums/FindPost/694830
//W0 contains the value to convert, W1 contains the destination for decimal
//digits.
asm("mul.uu w0,#0x0006,w2");
asm("mov #0x8DB9,w4");
asm("mul.uu w0,w4,w4");
asm("add w5,w2,w2");
asm("addc.b w3,#0,[w1++]");
asm("inc w2,w2");
asm("mul.uu w2,#10,w2");
asm("mov.b w3,[w1++]");
asm("mul.uu w2,#10,w2");
asm("mov.b w3,[w1++]");
asm("mul.uu w2,#10,w2");
asm("mov.b w3,[w1++]");
asm("mul.uu w2,#10,w2");
asm("mov.b w3,[w1++]");
}

Zde je jiná diskuze, jen o 16-bit kódu, ale i ta konverze má potíže:

https://www.microchip.com/forums/m322713.aspx

Všichni s tím mají problém a vypadá to, že nutno použít 32-bitový MCU :( Nějaký nápad místních odborníků?

Napsal: 17 lis 2022, 09:33
od petrfilipi
Proč chceš ty dva 16b registry spojovat? Každý jejich bit má svůj význam v desítkové soustavě (0. bit prvního registru je 1, 1. bit je 2, 2. bit je 4, 3. bit je 8 atd, 0. bit druhého registru má hodnotu 256 atd). Tak jen v cyklu projdi ty 4 registry a když je na konkrétním bitu 1, přičti váhu tohoto bitu v desítkové soustavě k výsledku. A máš výsledek v desítkové soustavě.

Myslím, že každý lepší kompiler si s tímhle poradí i pro 8b MCU

PF

Napsal: 17 lis 2022, 09:38
od nokijec
Samozřejmě ,že to jde i na 8bitovém stroji.Používá se na to Hornerovo schema.Kdysi jsem
si to psal v assembleru ,ale ne na PICu.

Napsal: 17 lis 2022, 11:00
od nokijec
Pro začátek je třeba si ujasnit co je třeba .Převádí se 32bitů na 10ti místné v BCD to pak odeslat na display,další převod na ASCI nebo 7segment.
Ten presentovaný kód je 16bitový na procesoru s 16ti bitovou instrukcí dělení.
Neznám stroják PiCů ,ale je zde použita metoda dělení.Dělíš jednotlívé řády.
65535/10000=6 zbytek
5535/1000=5 zbytek
535/100=5 zbytek
35/10=3 zbytek 5
takto vytvoříš ze dvou bajtů dekadické číslo.
8bitový procesor má pouze 8bitovou instrukci pro dělení,

Napsal: 17 lis 2022, 11:44
od ZdenekHQ
Na 8-bit Atmelu je to jednoduchá a rychlá záležitost, protože má funkci div a hlavně pokud se dělí číslem menším než 16, v tomto případě 10.

Pak jen ve zkráceném dělení dělíš 32-bit registr 10, zbytek posíláš na displej a dělíš dál, dokud není nulový. Já to používám u minohledu na 16-bit, teď jsem to používal i na 32-bit, ale tomu dělení je to jedno, klidně 64-bit registr.

Napsal: 17 lis 2022, 11:51
od petula
:arrow: nokijec ano,přesně tak, algoritmus je správný. Zbývá vyřešit na čem tento algoritmus naprogramovat a na čem jej spustit.
Je tu celá řada hledisek pro a proti. Vysvětlím nejprve k čemu to potřebuji.
Projekt je starý, ale jádro projektu je v tomto vlákně:
http://www.ebastlirna.cz/modules.php?na ... ic&t=96075
Je to hardwarový čítač, měřič kmitočtu. Nedostatek hardwarového, tedy BEZ-mikropočítačového řešení je v tom, že obsahuje mnoho, cca 40-50 pouzder TTL obvodů (počítám-li také obvody časové základny a displeje a obsluhu tlačítek), což vede na velkou desku 4-vrstvého plošného spoje. Taková deska je finančně nákladná. Zejména v malém počtu kusů.
Druhý extrém je kompletně softwarové řešení v mikropočítači. Těch je na netu mraky. Nedostatek takového řešení je, že do měřiče kmitočtu má čistě sofwarové řešení hodně moc daleko.
Včera jsem dokreslil desku hardwarového řešení (viz konec vlákna http://www.ebastlirna.cz/modules.php?na ... ic&t=96075 ). Vychází mi to na desku 4-vrstvy 6.5" x 5". Cena součástek, tedy obvodů je pod 2000 Kč, ale deska je drahá. Přitom jsem oddělil tři nejrychlejší dekády zvlášť na malou destičku, protože chci udělat upgrade čítače pomocí CPLD a tím zvýšit mezní kmitočet čítače. Protože čítač je 10-místný, zbylo mi na velké desce 7 dekád. To odpovídá 24-bitovému binárnímu číslu. Napadlo mne, vrátit se zpět k původní myšlence někdy do roku 2008 a použít binární 32-bitový hardwarový synchronní čítač. Jemu předřadit tu destičku se třemi nejrychlejšími dekádami a tím zredukovat počet pouzder obvodů na desce čítače (zbude jen časová základna a displej).
Toto řešení je OK, jen nutno vyřešit ten přepočet 32-bitového čísla na dekadické. To vyžaduje mikropočítač. Když se toto vyřeší, postup bude nádsledující: po skončení hradlování (měření kmitočtu hardwarovým čítačem) mikropočítač přečte tři nejrychlejší dekády čítače, pak přečte 4x 8bitů z 32 bitového binárního čítače. Následně spustí nové měření, protože data již přečetl. Nyní musí mikropočítač těch 32 bitů, rozdělených do 4x 8 bitů co nejrychleji převést na dekadické číslo. Pak odešle přepočtené číslo na displej a doplní údajem 3 nejrychlejších dekád. Na tuto činnost, tedy přepočtení 32 bit binárního kódu a odeslání na displej + odeslání 3 čísel z nejrychlejších dekád, má mikropočítač max. 10 milisec. :D

V podstatě tedy mikropočítač musí umět násobit a dělit 32-bit integer. Před chvílí mne napadlo použít dsPIC3034A (signálový MCU) který by to snad mohl umět. S jinými MCU než Microchip zkušenosti nemám. Mám v šupleti ještě 32 bitový mikropočítač Parallax, ale zatím jsem se nedostal k tomu jej vyzkoušet. Chce to někoho, kdo v této oblasti (software MCU) má více zkušeností. Když budu 2 měsíce bádat nad softwarovým řešením jak přepočíst 32 bit binární číslo, nemůžu přitom řešit hardware čítače. :D Nelze dělat vše najednou, protože "mnoho zajíců = psova smrt" :D

Napsal: 17 lis 2022, 12:00
od petula
Takže po přečtení 32 binárního čísla musím dostat nejprve dekadickou hodnotu.
Tedy vezmu nejvyšší bit (31.bit) a pokud je 1, provedu 31x násobení číslem 2, čili mocninu 2^31. Pak vezmu bit 30 a pokud je nulový, přeskočím, pokud je 1, provedu 30x násobení čísla 2, tedy mocninu 2^30 a výsledek připočtu k hodnotě získané z mocniny 2^31. A tak dále až do nejnižšího bitu. Tak dostanu dekadické číslo z 32-bitového binárního čísla. V krajním řešení, když všech 32 bitů bude "1", dostanu číslo: 4 294 967 295 tedy 10 místné číslo. Pak jednotlivé číslice 4, 2, 9, ... musím odeslat na displej. K tomu se použije algoritmus, co uvedl nokijec nahoře. Úvodní nuly odesílat nebudu. Nicméně dekadické 10-místné číslo (max. 4 294 967 295) musím začít postupně dělit 1000 000 000 , pak 100 000 000 atd. Odělovat integer a fragment a integer odesílat na displej a fragment opět dělit. Mám na to 10 milisec.
Obávám se, že 8-bitový mikropočítač pro to není to pravé "ořechové".

Napsal: 17 lis 2022, 12:17
od nokijec
Jenže na to tvoje počítání si bude muset naprogramovat 10ti místnou celočíselnou dekadickou kalkulačku-sčítačku.

Napsal: 17 lis 2022, 12:18
od petula
a nakonec, info na doplnění pro výběr vhodného mikropočítače. Pro snadné hw připojení MCU je potřeba napájení +5V, pokud možno ne 3.3V :D protože TTL logika je +5V (ačkoliv CPLD má 3.3V resp. 1.8V ale to bude až někdy daleko). Dále bude vhodné, aby MCU měl také UART, SPI, I2C a ideálně ještě alespoň jeden kanál CANbus 2. AD. DA převodníky nejsou potřeba. K tomu musí mít několik 8-bit portů. Pro ovládání časové základny je potřeba 1x 8-bit port a pro čtení dat z hw čítačů 32 bit a 3 nejrychlejší dekády je potřeba 20 bitů (které lze zredukovat na 6x čtení po 8 bitech. Bude-li mít MCU málo portů, musí se přidat expandery. To zase zvýší počet obvodů. K tomu je potřeba vstup pro hw interrupt který indukuje, že MCU může začít číst data a naopak další bit výstup, ktrerý spustí nové měření. :D

Napsal: 17 lis 2022, 12:19
od petula
nokijec píše:Jenže na to tvoje počítání si bude muset naprogramovat 10ti místnou celočíselnou dekadickou kalkulačku-sčítačku.
no dobře a který MCU tedy použít?

Napsal: 17 lis 2022, 12:22
od ZdenekHQ
Proč se tak tvrdošíjně držíš PICu, kterej je na matiku poněkud prkennej a proto jsem ho nikdy nezačal používat?

Vždyť tohle jde nacpat do Atmelu za dvacku. Nakonec obojí je dnes Microchip.

Napsal: 17 lis 2022, 12:22
od rnbw
Neser sa s tym a pouzi C:

Kód: Vybrat vše

sprintf(s, "%u", hi << 16 | lo);

Napsal: 17 lis 2022, 12:24
od petula
:arrow: rnbw trochu to rozveď, popiš, co to přesně dělá :D To je tisk unsigned integer 16 bit, ne? A co s tím?
:arrow: ZdenekHQ, který Atmel, přesně? Třeba ATSAMC20J18A by se dal použít. Pro mne to ale znamená investice do vývojového prostředí a vývojového kitu :( Největší malér není až tak vymyslet matematický algoritmus, řešení problému, ale pochopit ovládání vývojového prodstředí, kterým se program zkompiluje do kódu. Ty vývojová prostředí mají katastrofální ovládání...

Napsal: 17 lis 2022, 12:45
od nokijec
To co navrhuje petrfilipi je nesmysl,ne že by to nešlo.
To násobení není třeba ,uděláš si tabulku.
31bit má váhu 2 147 483 648
30bit 1 073 741 824 a tak dále, při každé 1 musíš udělat součet dvou 10ti místných čísel,všech řádů.
Tudy cesta nevede.To Hornerovo schema je opravdu dokonalejší.Akorát to pochopit a přeložit to do jazyka ,kterému rozumí zvolený mikropočítač.

Napsal: 17 lis 2022, 12:49
od ZdenekHQ
Tak já bych použil dostupný AT89C4051, který má dost pinů na to, aby mohl řídit i LCD displej. Na to stačí PsPad a libovolný programátor. Ale běhá to i v DOSu.

To dělení 32-bit Mat_reg deseti pak vypadá takto (r3=10):

Kód: Vybrat vše

	
        ;prepnu banku
	;proto musim zalohovat r3
	;------------------
	mov	a,r3
	
	push    psw             
	setb	rs0       
	clr	rs1
	
	mov	r3,a

        ;deli Mat_reg
	;v R3 je delitel 1..15
	;podil v Mat_reg, v B zbytek
	
	
	mov	r1,#(Mat_reg+3)    
	mov	r2,#4             
	mov	b,#0

Deln_1:
	mov	a,@r1
	anl	a,#0f0h
	add	a,b
	swap	a
	mov	b,r3
	div	ab
	swap	a
	xch	a,@r1
	anl	a,#0fh
	swap	a
	add	a,b
	swap	a
	mov	b,r3
	div	ab
	add	a,@r1
	mov	@r1,a
	dec	r1
	djnz	r2,Deln_1
	
      pop psw
      ret