[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