Jak v C zachazet hromadne s porty?

Jakub Ladman ladmanj na volny.cz
Pátek Duben 13 22:32:59 CEST 2018


Takhle jsem to na ATmega64 vyřešil když jsem měl cca o 15 let méně 
zkušeností.

Tedy tohle je jen čtení pinů, ale opačná úloha by byla analogická.

hw.c

unsigned long read_inputs() {
         register unsigned char tmp_B, tmp_C, tmp_D, tmp_E, tmp_G;
         cli();
         tmp_B = ~PINB;
         tmp_C = ~PINC;
         tmp_D = ~PIND;
         tmp_E = ~PINE;
         tmp_G = ~PING;
         sei();

         return (SIN_20 | SIN_19 | SIN_18 | SIN_17 | SIN_16 | SIN_15 | 
SIN_14 | SIN_13 | SIN_12 | SIN_11 | SIN_10 | SIN_09 | SIN_08 | SIN_07 | 
SIN_06 | SIN_05 | SIN_04 | SIN_03 | SIN_02 | SIN_01);
}

hw.h

#define RIN_01 ((tmp_G >> 2) & 1)
#define RIN_02 ((tmp_C >> 7) & 1)
#define RIN_03 ((tmp_C >> 6) & 1)
#define RIN_04 ((tmp_C >> 5) & 1)
#define RIN_05 ((tmp_C >> 4) & 1)
#define RIN_06 ((tmp_C >> 3) & 1)
#define RIN_07 ((tmp_C >> 2) & 1)
#define RIN_08 ((tmp_C >> 1) & 1)
#define RIN_09 ((tmp_C >> 0) & 1)
#define RIN_10 ((tmp_G >> 1) & 1)
#define RIN_11 ((tmp_G >> 0) & 1)
#define RIN_12 ((tmp_D >> 7) & 1)
#define RIN_13 ((tmp_D >> 6) & 1)
#define RIN_14 ((tmp_D >> 5) & 1)
#define RIN_15 ((tmp_D >> 4) & 1)
#define RIN_16 ((tmp_B >> 5) & 1)
#define RIN_17 ((tmp_E >> 7) & 1)
#define RIN_18 ((tmp_E >> 6) & 1)
#define RIN_19 ((tmp_E >> 5) & 1)
#define RIN_20 ((tmp_E >> 4) & 1)

#define SIN_01 (((unsigned long)(RIN_01)) << 0)
#define SIN_02 (((unsigned long)(RIN_02)) << 1)
#define SIN_03 (((unsigned long)(RIN_03)) << 2)
#define SIN_04 (((unsigned long)(RIN_04)) << 3)
#define SIN_05 (((unsigned long)(RIN_05)) << 4)
#define SIN_06 (((unsigned long)(RIN_06)) << 5)
#define SIN_07 (((unsigned long)(RIN_07)) << 6)
#define SIN_08 (((unsigned long)(RIN_08)) << 7)
#define SIN_09 (((unsigned long)(RIN_09)) << 8)
#define SIN_10 (((unsigned long)(RIN_10)) << 9)
#define SIN_11 (((unsigned long)(RIN_11)) << 10)
#define SIN_12 (((unsigned long)(RIN_12)) << 11)
#define SIN_13 (((unsigned long)(RIN_13)) << 12)
#define SIN_14 (((unsigned long)(RIN_14)) << 13)
#define SIN_15 (((unsigned long)(RIN_15)) << 14)
#define SIN_16 (((unsigned long)(RIN_16)) << 15)
#define SIN_17 (((unsigned long)(RIN_17)) << 16)
#define SIN_18 (((unsigned long)(RIN_18)) << 17)
#define SIN_19 (((unsigned long)(RIN_19)) << 18)
#define SIN_20 (((unsigned long)(RIN_20)) << 19)

Už si to moc nepamatuju, ale myslím si že to kompilátor zoptimalizoval 
poměrně použitelně.

Ale fígl to moc není, spíš brute force. Chtěl jsem maximum zařídit 
preprocesorem C.

Za zmínku by pro začátečníka, (což vy nejste, jen co se týká C a to není 
totéž) stálo to, že se mezi čteními portů vypíná přerušení, abych je 
načetl pokud možno v co nejkratším sledu.

J. Ladman


Dne 13.4.2018 v 14:55 Pavel Kutina napsal(a):
> Zdravim,
>
> mam takovy zadrhel, a protoze nejsem Cckar, asi mi neco duleziteho unika.
>
> Mam ATmega128 (s arduinovskym bootloaderem a cele to pisu na Arduinu, 
> ale to je pro tenhle ucel asi jedno), na ni pouzivam skupinu pinu, se 
> kterymi bych chtel zachazet nejak hromadne - potrebuju nastavit 
> sestnactibitove cislo, co bit, to jeden pin. Piny jsou ale rozhezeny 
> pomerne nahodne, prakticky nikde nemuzu pouzit cely port, takze neco 
> jednoducheho, jako PORTA = 0x45; PORTB = 0xDE; neprojde, protoze nemam 
> cely PORTA ani PORTB a doplnuji to dalsimi piny z jinych portu.
>
> Poteboval bych tedy vytvorit nejake 'cosi', k cemu se budu chovat jako 
> k sestnactibitovemu portu, tedy tak, abych mohl pouzit konstrukci jako 
> PORTQ = 0xDE45;, to cislo inkrementovat, porovnavat atd. Docela dost 
> by mi to zjednodusilo zivot dale v kodu :)
>
> Napadaji mne ruzna reseni, jen jsou dosti krkolomna - predpokladam, ze 
> zkuseny Cckar si ted klepe na hlavu a rika si "nadefinuj to jako NNN a 
> nemusis nad tim premyslet" - ale ja nejsem zkuseny Cckar :)
>
> Poradite figl?
>
> Diky.
>
> Pavel Kutina
> _______________________________________________
> HW-list mailing list  -  sponsored by www.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list



Další informace o konferenci Hw-list