MPLABX, 18F-Neni mozne zadat delsi zpozdeni nez delay_ms(29)

Cawte, mam nasledujuci problem. Som zaciatocnik, tak mozno sa pytam sprostost, tak ma nebite. Proste ide o to, ze ked som zacinal s procesormi pred niekolkymi rokmi, tak sa mi do ruk dostal 16F648A, s ktorym som robil vsetko. Stal sa samozrejme oblubenym a s nim som sa pokusal napisat aj moj prvy program v C-cku. Samozrejme som objavil velmi zaujimavu funkciu, a teda “__delay_ms” a “__delay_us”. Sice mi ich MPLABX podciarkoval, ale boli spravne prelozene a nebol problem cakat sekundu “__delay_ms(1000)”. No ale ked som siahol po niecom vecsom, co splna moje poziadavky - 18F2550, tak sa vyskytli problemy s touto funkciou, a teda nieje mozne zadat vecsie cislo, ako 29 ci ako pri takte 8 MHz. Pri preklade dostanem nieco taketo:

error: inline delay argument too large

To je strasne obmedzujuce a myslim si, ze s lepsim procakom by to malo byt bezproblemove. Tak k mojej otazke: ako je mozne, ze predtym to slapalo ako hodinky a teraz, ked mi to aj MPLABX berie ako definovanu funkciu su s nou taketo problemy? Chcel by som vediet dovod tohto spravania. Dakujem pekne za odpoved.

:arrow_right: administrator: přejmenováno z "MPLABX problem s funkciou delay"

A na co potřebuješ výkonnější procesor, když mu pak dáš k práci jenom čekání ? Už jedna milisekunda je pro procesor téměř věčnost. Uvědom si, že pomocí delay se dá řešit čekání maximálně pár milisekund. Všechno delší už je vhodné řešit jinak - čítače, přerušení apod. a ne zabíjet procesorový čas zvrhlostma typu delay(1000) …

Tak napriklad na obycajnu komunikaciu s displayom 1602 sa odporuca po kazdej instrukcii cakat 4 ms a to je este vecsia vecnost. Je mi jasne, ze sa oplatia na tak velky cas prerusenia, to ti neberiem. Ide mi o to, ze kym sa zoznamujem s ceckom a s pripadnymi periferiami, niekedy je super pockat napriklad spominanu sekundu a nasledne urobit nejaky krok, ktory chces vnimat ako zbehnutie nejakej funkcie a podobne. Nechcem cakat sekundu vo final programe, to urcite nie. Ide mi o to, ze co som v 16F648A dokazal bez problemov, v 18F2550 je nemozne v jednej instrukcii. Nehladam prakticke vyuzitie, ktoreho nahlad si mi poskytol. Hladam riesenie mojho problemu. Ale diky za odpoved.

Při komunikaci s LCD 1602( řadič HD44780) se čeká tak do 100us - vyjímkou je proces inicializace. Nauč se používat přerušení a naprogramuj si čekací funkce využívající časovače. Současně budeš schopen řešit snadno timeouty a podobné věci…

Problém bude v knihovně pro řadu PIC18. Např. v MPLABC 18 v_3.40 není definována funkce delay. Zde je možné použít po připojení knihovny delays.h funkce:

Delay1TCY() == NOP
Delay10TCYx(x)
Delay100TCYx(x)
Delay1KTCYx(x)
Delay10KTCYx(x)

x v rozsahu(1…255)

Takže čas si musíš vypočítat podle kmitočtu procesoru(TCY = 4/Fcpu).

Jsem rád, že máš dostatek rozumu a necheš takové dlouho delaye používat v hlavním programu. Sice v Cčku pro mikrokontrolery nepíšu (a s PICy nedělám vůbec - moc přepínání, když potřebuješ něco udělat, velice omezené možnosti použití registrů pro operace atd.), takže blíž Ti k Cčku, ale myslím, že Standa33 dal vyčerpávající odpověď.

A teďka k tem časům pro komunikaci s LCD (1602 apod. s řadičem 44780). Nevím, kde jsi vzal ty časy (4ms po každé instrukci), ale stačí se podívat do datasheetu a zjistíš, že je vše úplně jinak :

  1. Na začátku je potřeba počkat alespoň 30ms do zahájení komunikace s LCD - při startu MCU čekávám alespoň 100ms, než začnu komunikaci.
  2. Nejdéle trvají instrukce “Clear display” a “Cursor home” - 1,53ms
  3. Zápis a čtení dat do/z RAM (CGRAM/DDRAM) - 43us
  4. Ostatní instrukce (kromě těch z bodu 1) - 39us
  5. Čtení BF a adresy - 0us

Napsal jsem si knihovnu pro LCD displej a po každém zápisu do LCD mám čekání 50us (samozřejmě až na 2 výše uvedené výjimky). Funguje to úplně v pohodě. Na většinu aplikací to stačí. Přepis celého LCD 20x4 vychází cca na 4 ms.

Místo “Cursor home” raději používám nastavení kursoru na 0,0 (což je cursor home, ale trvá jenom 39us). Cursor home však navíc nascroluje displej na výchozí pozici, pokud používáš scroll displeje.

“Clear display” používám jenom zřídka a to většinou jen na začátku programu. Většinou texty a menu stavím tak, abych s ním přepsal celý displej. Raději tedy na LCD zapíšu o pár mezer navíc, než zbytečně dlouho čekat.

Souhlas s Radius … no ja nevim ale pokud ma procik cekat cca 100 ms je to opravdu vecnost… preruseni te spasi :smiley:! Ne to byla sranda samozrejme … Zkus se malinko zamyslet- Dnes je kazdy LCD 1x1px a vic z Ciny… tam se udava cca 270kH. Ale kdo si tim je jisty, a ty datasheety?? :smiley: Ber to tak, ze musis inicializaci presunout ke konci Tveho init() pak muzes rici 100ms (150ms “treba”). A kdyz mas stesti a ta tvoje knihovna funguje na vice jak 70 LCD tak si borec a mas talent … vic nemuzu rict nic … Lucky Boy …

je hloupe dzet procik na 48MHz (12MHz[8bit]) 0.1s na jednom miste bez vysledku… (plati i pro C)

Nebite ma tolko :slight_smile: Tak dobre, sorry, 4 ms cakam na zaciatku, potom mam pre istotu iba 100 us, sekol som sa no. Ako som spominal, vo final programe nikdy nepouzivam take dlhe cakacie loopy. Ide mi cisto o to, ze PRECO to pri tomto procesore neide. Tak velky loop mam iba preto, lebo skusam na displayi rozne veci, ako napriklad scroll a podobne. No a je fajn si nieco vypisat, pockat sekundu a zavolat funkciu scroll a sledovat, ci sa mi text posunie, alebo nie. Kniznicu delays.h som uz pouzival, ale tam su iba “instrukcie”, nie “meratelny cas”. Je viac user friendly napisat prikaz na cakanie urcity cas, ako isty pocet instrukcii. Proste nebite ma, ja chcem iba vediet, preco je to tak. Asi si budem musiet vygenerovat par instrukcii v nastaveniach pre 16F648A a potom ako asm kod prekopirovat do programu pre 18F2550. Sorry, ze som sa pytal.

Kašli na ně, oni jsou tu někdy zbytečně prudérní a protivní. To že ses zeptal rozhodně nic špatného není, chytří lidé se ptají (jen blbci si myslí, že nepotřebujou)… Mě by to osobně taky zajímalo. 18F2550 čekám každým dnem, takže jediný co můžu udělat je, že až dorazí, tak vezmu C kompilátor a zkusím taky - nicméně pokud nebude vadit, že “můj” C kompilátor je SDCC

Jen pro doplnění - pro LCD je 4ms na začátku málo, pokud v datasheetu píšou minimálně 30ms po dosažení poté, co napájení dosahne 4,5V (teda alespoň v tom datasheetu, do kterého tu koukám já). Nicméně nevidím jako problém při startu MCU počkat třeba i půl vteřiny. A když se vrátím k té knihovně, tak bych neřešil, proč to nejde. Prostě je to knihovna, která má nějaké vlastnosti. Pokud chceš, aby knihovna měla Tebou požadované vlastnosti, musíš si napsat svojí (třeba i s využitím téhle). Těžko tady někdo vidí do hlavy autorů zmiňované knihovny, aby Ti napsal proč to tak je …

Nikdo Tě nechce bít za to, že ses zeptal - každý nějak začínal, ale pravdou je, že nemá smysl řešit, proč knihovna nepodporuje něco, co stará uměla. Pokud nefunguje část Tvého vlastního kódu, je na místě se zeptat. Nikdo není neomylný a přehlédnout nějakou chybu může každý a když dotaz není úplně nesmyslný, tak se tu k řešení v drtivé většině dopracuješ. Proto tady to fórum je, aby ses mohl zeptat.

No a ja sa pytam konkretnu otazku a najprv som bol poslany kade lahsie a nikto sa nevenoval mojmu problemu. Konecne zmysluplnejsie odpovede, dakujem. Ked som to skumal blizsie, zistil som, ze aj v prvom, aj v druhom pripade pochadzaju funkcie z rovnakej kniznice, a to pic18.h.

nemyslim, ze je to primo “chyba” spis se vyvojari snazi dokopat lidi aby se snazili pozivat mensi data u 8-bitu (misto long int).
podle definice: #define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))

tvoje zadani je = 8MHz a 29ms = 58000 (int)
ale kdyz das 30ms tak se nevejdes do int ale uz do Long … proto mas problem… 8MHz a 30ms = 1740000 (long)

zkus pouzit nejkou smycku

for(;x;x)
{
_delay_ms(x);
}

Ještě jsem to nezkoušel, ale v manuálu k XC8 jsem se dočetl, že pro PIC18 je to skutečně jinak než pro ostatní (strana 59):

Zajímavý příklad, kte se nepoužívá __delay_ms(), ale pouze __delay() (strojové cykly):

batchloaf.wordpress.com/2013/04/ … ic18f4620/

Už se těším až to zkusím :slight_smile: