Ako zobraziť desatinné číslo na displeji s HD44780 v C?

Dobry den.

Troska som tu hladal ale neansiel. Potrebujem zobrazit desatine cislo (2.55) na disleji klasika z radiscom hd8870. v Ccku

TAk ze obsluhu displeja mam napisanu, aj som obslehol kusok kodu na vypisovanie retazcov na displej o co ide.

Potreboval by som kusok zdrojaku na vypisanie retazca znakov a aby dokazal vypisat aj desatine cislo… aby to bolo nejake efektne a hlavne jasne pre pochopenie funkcie.

dakujem.

:arrow_right: administrator: přejmenováno z "Desatine cislo na displej"

bud pouzijes klasicke funkce ako sprintf(…), alebo si vygenerujes z cisla znaky a tu bodku vlozis tam kde treba, ostatne znaky posunies rucne. Trochu neohrabane, ale velmi malo zrave na pamat. Hlavne, ked v MCU mas vsetko napriklad na jednu desatinu (napr. teplota), ale je nezmysel kvoli tomu pouzivat float.

Pre konverziu z cisla na pole char netreba obslahavat ziadny rozsiahly kod ( :slight_smile: ), ale pouzivat standartne funkcie na to urcene. Konkretne pre konverziu “int to char” je urcena standartna funkcia itoa()
Doporucujem si prezriet pred zapocatim programovania zakladnych funkcii help k avr-lib.

Pokud jsem to pochopil, chceš zobrazit na display proměnnou float i s desetinnou čárkou.
Pokud tvůj překladač umí pracovat s float ve sprintf,pak je to jednoduché:

unsigned char disp_buff[33]; //
float číslo;
sprintf(disp_buff,"%1.2f",číslo);

ne každý překladač to ale umí (samozřejmě ten můj to neumí:( ) pak je nutné si vypomoct takto:

sprintf(disp_buff,"%1u.%02u",(int)číslo,(int)(číslo-((int)číslo*100)));

v pricipu tedy zkonvertuješ float na int, čímž se ořeže vše za desetinnou čárkou a zobrazíš jako celé číslo, ten zbytek pak vynásobíš 10 (100,1000 - podle toho kolik míst za čárkou chceš zobrazit) a vypíšeš na disp. opět jako celé číslo.

u čísla 2,55 to bude:

                           (**int**) 2,55= 2
                            2,55-2 =0,55     
                            0,55*100=55

Ovšem 3 výpočty ve float budou na avrku trvat hodně dlouho. Převedl bych to na int(s vynásobením) v prvnim kroku a dál pracoval jen s int, popř. char kdyby stačil, nejlépe unsigned.
Samozřejmě nelepší by bylo se floatu úplně vyhnout, pisatel nám ovšem nesdělil, v jakém formátu jsou vstupní data, případně jak jsou vytvářena takže se ani nemůžem pokusit o optimalizaci.

Suhlasim. Asi tak 3ms, mozno i menej. :slight_smile:

Ale urcite by som si spravil pre tento pripad rutinu vkladajucu desatinnu bodku tam kde treba. Kod vyjde kratsi, rozhodne rychlejsi a rychlejsie uplynie i par peknych zimnych vecerov :slight_smile:

3ms je na 1 operaci pro mne dlouho. Obvykle musí totiž dělat mcu i něco jiného…

Proboha, co to máš za překladač! Když jsem psal násobení pro Z80, která běžela na 4MHz (odpovídá 1MIPS), tak to trvalo pod 1ms. Manitsa 24b exponent 8b. AVR na 16MHz to musí zvládnout pod 100us a proti Z80 má navíc HW násobičku a 32 akumulátorů. Z80 má jen jeden a 7 registrů + 1 virtuální HL.

Asi ano, ja som to nemeral a nechcel som sa blamovat, tak som dal jeden vypocet na jednu ms :slight_smile:
Moj odhad bol skoro ako Tvoj, aj ked to delenie bude trvat trochu dlhsie. Ale nie zas o tolko , aby to bolo citit.

:arrow_right: administrator: příspěvek byl upraven

DAujem uz sa totho pustim. Proste spustim prevodnik na atmega8 dostanem nejake cislo a to potrebujem previest na napatie tj 1024 je 2,56v lebo intrena referencia. A potrebujem vlastne merat napatie v rozsahu 0,5-2V na 2 desatine miesta napr 1,55V, mimo to este nejake to prerusenie minutove.(priamo to asi nepojde ale podelim to programom). pre pocitanie casu.

Help pre winavr mi nejako nespusti. A mohli by ste mi nieco zosmoli pripadne poradit este ked uz viete z coho a naco mi to treba.

DAjkujem

Tak zbuchal som to tak>

t1=(ad()/4);

	j=0;
	        while (t1>=100) {t1-=100;j++;}
		d=t1; 

j jednotky voltov, d desatiny voltov

mozes to zobrazovat aj v mV, zbavis sa desatin :slight_smile:

ale potom zaberiem cas a kapacitu v mozgu pre citani :laughing:

Asi to nechápu, ale na : viewtopic.php?t=1119&postdays=0&postorder=asc&start=15 se doporučuje vzorkovat AD 16krát po 1ms a tady vám je líto 300us na výpočet? U zařízení, které jen měří napětí bych to vůbec neřešil.

Na druhou stranu i mě by zajímalo jak zobrazovat hodnotu s desetinnou čárkou bez toho abych výsledek AD převodu násobil float konstantou.

toto je sice dobré řešení:

ale nepoužitelné při referenci 5V (1024/2=512 ne 500)

uint32_t Uvst;
uint16_t vysledok;

Uvst = 1023*10000/2046;
vysledok = (uint16_t)Uvst; // = 5000 :slight_smile:; 1023 je max. pocet nameranych dielikov

// desatinnu bodku nie je problem vlozit do pola char, ktore naplni funkcia atoi()

// help v AVRstudiu pre avr-lib a pre GCC samozrejme funguje
// ale kludne si ho stiahni z
// mirror.lihnidos.org/GNU/savannah/avr-libc/
//
// nongnu.org/avr-libc/
//
// samotny jazyk C je vo svojej podstate velmi jednoduchy (nastastie). Caro mu davaju kniznice :slight_smile: