[elektro] megint C
Móczik Gábor
pm_levlista at progzmaster.hu
Tue Dec 4 13:17:13 CET 2012
2012.12.04. 10:34 keltezéssel, Skandar Graun írta:
> A kódrészlet (már kicsit túlbonyolítva, mert küzdök.
>
> void DataOut(BYTE kimegy)
> {
> int nCount = 8;
> char kiki;
> SCLK = 0;
> kiki = kimegy;
> while(nCount--)
> {
> (kiki && 1) ? SDO = 0 : SDO = 1;
> SCLK = 1;
> kiki = (kiki >> 1);
> SCLK = 0;
>
> }
>
> A hibás sor: (kiki && 1) ? SDO = 0 : SDO = 1;
A ?: egy operátor, mint mások írták, inkább célszerű
SDO = (kiki & 1) ? 0 : 1
formában használni.
Ha értéadást akarsz belül, akkor inkább írj if/else szerkezetet.
Egyébként nagy valószínűséggel ugyanarra a kódra fordul majd, csak
sokkál tisztább a forrás.
Vegyük észre, hogy a fenti feltétel gyakorlatilag a kiki 0-ik bitjének
inverzét másolja ki a kimenetre, tehát
SDO = (kiki & 1)^1
is jó lehetne helyette, tuti hogy kevesebb gépi utasítás mint az if/else
feltételvizsgálat.
Mivel az összes bitet ki kell küldeni, és láthatóan a kiki értéke
elrontható, a ciklus előtt is lehet negálni
kiki^=0xFF
utána a ciklusban csak
SDO = kiki&1
kell.
Lehet, hogy ez még mindig nem elég gyors, mert a ciklusban van egy
shiftelés, ciklusváltozó dekrementálás, és kilépési feltétel vizsgálat
is, ez mind lefut 8-szor.
Tovább gyorsítható a kódméret növelése árán:
#define DOCLK(buf,bitno) \
SCLK=0; \
if (buf&bitno) SDO=1; else SDO=0; \
SCLK=1;
void spi_send(BYTE kiki)
{
DOCLK(kiki,0x80);
DOCLK(kiki,0x40);
DOCLK(kiki,0x20);
DOCLK(kiki,0x10);
DOCLK(kiki,0x08);
DOCLK(kiki,0x04);
DOCLK(kiki,0x02);
DOCLK(kiki,0x01);
}
Ez mondjuk már bitfaragás, de talán nem csúnya, nekem PIC18F-en gyorsabb
volt mindennél mint amit a fordító tudott generálni a ciklusból (mondjuk
nem pont ez, nekem az SDI-t is olvasni kellett szimultán).
More information about the Elektro
mailing list