Mohl by být rozdíl v případě rotací vpravo, kdy u neznaménkového čísla se doplňuje do nejvyššího bitu 0, ale u znaménkového se opakuje nejvyšší bit (tedy podle překladače, některé rotují signed také s 0). Ale vzhledem k tomu že tady se výsledek maskuje & 1, tak by rozdíl neměl být.
Panda38:
E je nějaké makro - definice bitu SFR ( nebo jak se u picu jmenují) registru - buď PORT, nebo LAT - (to ví jen autor) - něco jako:
#define E PORTCbits.RC3
to je v C18 - ten XC8 neznám
nevím jak by se toto dalo definovat jako volatile
Navíc v takovém Codevisionu pro AVRka bych si v tomto případě s volatile moc nepomohl - tam to funguje tak, že prefix volatile jenom řekne překladači, aby nepoužil pro proměnnou jeden ze 32 pracovních registrů - aby nedošlo k jeho přepsání během přerušení.Obsahuje ale direktivy, opt+ a opt-, kterými vyloučím z optimalizace části kódu, které potřebuju. Přiznám, že u piců jsem to až tak detailně zatím nezkoumal.C18 nic takového neumí - snad jen vypnout optimalizaci úplně - proto ta nutnost vkládat do “nelogické” posloupnosti příkazů alespoň ten nop .
Stejně bych ale viděl zádrhel v tom, že pokud by měl “logicky” propojené
piny portu a LCD nějak takto:
teď budu trochu OT, ale už jsem viděl, že hlavně u větších datových typů (long atd) používá autor místo bitového posunu třeba(1>>15) radši dělení
/32768 - ale nezkoumal jsem jaký to má efekt
Díval jsem se do příkladu >> definice <<, PORTCbits je struktura s bitovým polem (RC0…) a celá struktura je označená jako volatile, takže to by mělo být v pořádku.
Rozumný překladač to má umět rozpoznat že to má nahradit optimálnějším bitovým posunem - alespoň GCC a MSVC to dělají (tj. místo word/32768 by udělal ((word rol 1) and 1) ).
proc ?? nejak nechapu (jen ma nechapavost). Pokud je unsigned bez znamenka tzn. (9 je 0b00001001) - 1 = (8 je 0b00001000). Signed je tedy (9 je 0b00001001) to je totez nebo ne ?? Prosim blizsi info . Nezalezi spise na kompilatoru (manualu ke kompilatoru) ?
Taky tomu nějak nerozumím - problém by snad mohl být při dekrementaci z nuly - u unsigned char bude hodnota 255 - nebude tedy menší než nula, ale k tomu by snad nemělo dojít??
Já osobně tedy radši přičítám “for(u8 i=0; i<9; i++)” a nemám problém s použitým datovým typem
Protože při poslední iteraci se program dostane z 0 na 255 místo na -1, to znamená že podmínka je vždy splněna a cyklus se nikdy neukončí. Překladač to i sám pozná že je to blbost a nahradí to nekonečnou smyčkou. … tahle chyba se stane snadno, když se “i” deklaruje někde dřív jako unsigned a pak se na to zapomene a chce se využít v nějakém jiném cyklu, který indexuje do 0.
Je-li to z funkce programu jedno, bývá odečítání efektivnější. K testu dosažení nuly stačí využít Zero flag z poslední dekrementace (i když pravda že některé překladače tohle zefektivnění nevyužívají). U inkrementace se musí provádět další komparační instrukce. Pokud je zarážkou výraz nebo proměnná, tak tam je to už úplně jasné, protože při přičítání se musí po každé iteraci vyhodnocovat stále znovu koncová hodnota nebo načítat obsah proměnné.
jj tak to … me jen nejak neslo do hlavy jak by se to mohlo stat . Ja na to pouzivam jiny mechanizmus. Pokud pouzivam nejakou promennou ve smyckach tak pokazde ji pricitam, jinak pointery ale myslim, ze jsem asi nikdy nepouzil – u cekacich smycek… Ale kdyz to tak pisu tak mozna jsem s tim uz mel problem. Ve smyckach kde se pracovalo s dat.pol[unsigned char]… asi fakt jo …
tvar “for(u8 i=9; i>0; i–)” by tedy měl problém vyřešit
Nevím v čem děláš, ale většina překladačů pro osmibity - aspoň ty co jsem s nima došel do styku vyžaduje deklaraci “někde dřív” - minimálně na začátku funkce u lokálních proměnných ten ukázkový for o kterém se bavíme by ti vyhodily jako chybu - to jen pro ty co začínají s C - což je asi i případ zakladatele vlákna - a chtěli by si to brát jako příklad.
Dojet do nuly je potřeba když to “i” má být indexem v poli.
Jasně, deklarace ve for() není správná, dříve se upřednostňovala v Microsoft VC než zjistili že je to nesprávně, ale zatím ji nezakázali (resp. jen volitelně).
…uz dost OT Ale nevadi, zaujimave veci tu pisete. Ako stale opakujem dookola, ono to RAZ IDE a RAZ NEIDE. Nechapem tomu. Datove typy s tym nemaju vobec nic. Nefunguje ani odoslanie prikazu 0x00. Budem sa opakovat, ale este raz… Na vymazanie displaya mam jedinu funkciu, ktora sa proste zavola. Ak ju zavolam raz, ide vsetko OK. Ak ju zavolam druhykrat, vsetko je zle. Znova: Ako je mozne, ze sa TA ISTA funkcia vykona ROZNE? Skor nie ako to je mozne, ale preco to display neakceptuje. Nula je v akomkolvek datovom type nulou. Vsetko bezi, teda tie prikazy niesu nespravne optimalizovane. Nemam nikde nekonecnu slucku. Na zapis pouzivam LAT a pre citanie PORT. IO je PIC18F2550. Berte prosim v uvahu tieto fakty a neopakujte sa s tym stale. Zhrniem to:
Optimalizaciou sa nepreskakuju instrukcie (dokaz? display funguje).
Mam spravne casovania (dokaz? display funguje).
Na datovom type nezalezi (dokaz? nula je stale nulou).
A na zaver axioma: funkcia nech je volana nespocetnevela krat, stale je vykonavana rovnako.
“Moj” char “pojme” aj vecsie cisla (dokaz? Odoslanie 0xC2 funguje spravne a je to cislo 194)
Znova k mojmu problemu…preco nefunguje odoslanie “nuly” (jedneho z mnoha) 2x po sebe?
Schéma a celý program by pomohl k řešení problému.
Já jsem zkusil napsat program pro připojení LCD(typ HD44780) k PIC18F2550. Rozdíl řady PIC18 a (PIC16,PIC12) je v různém přístupu k datům v RAM a ROM(flash). Alespoň v překladači co používám, proto mám v programu funkce Lcd_Out_RAM(…) a Lcd_Out_ROM(…).
Program je jen pro test, takže přesnost měření času nic moc. PIC18F2550_LCD44780_4bit.zip (28.8 KB)