Rozložení typu int na jednotlivé byte v C

Zdravím. Mám tu nyní takový pro mě zapeklitý problém. Mám integerové číslo, standardní 16bitový znaménkový “int”. Tohle číslo potřebuju procpat sériovou linkou, a tedy ho musím rozložit na dva byte. Existuje nějaký jdnoduchý/efektivní způsob, jak přistoupit k jednotlivým byte, ze kterých se tento integerový typ skládá?

S tím ještě malinko souvisí jeden můj dotaz. Mám například

#define cislo 547

Jak toto číslo rozložím do dalších dvou maker tak, abych v nich měl právě ty jednotlivé byte?

#define hi 2 #define lo 35
Tedy jak místo ručního přepočtení na ty dvě hodnoty přinutit kompiler aby mi to sm rozložil?
V AVR studiu v ASM programovacím prostředí se daly krásně používat jakási “makra”

low(), high(), byte2(), byte3(), byte4()

nebo tak nějak to mohlo být. Existuje něco podobného i v tom C? Nemyslím realtimové řešení, toho se týká první dotaz, mám na mysli něco, s čím lze definovat makro jakoby takto

#define cislo 967 #define bla high(cislo)
Kde ve výsledku bla = 3.

Díky za rady, Honza
PS: Omlouvám se za to asi trochu krkolomné formulování druhého dotazu.

:arrow_right: administrator: přesunuto z "Elektronika s mikrokontroléry, procesory"

Myslím, že nějak takto:

#define BYTE1 (unsigned char)(cislo)
#define BYTE2 (unsigned char)(cislo >> 8)
#define BYTE3 (unsigned char)(cislo >> 16)
#define BYTE4 (unsigned char)(cislo >> 24)

int a = -1587; odesli((char)(a & 0x00ff)); odesli((char)(a >> 8));
Nezkoušel jsem to, ale snad to pofrčí. Na druhé straně je to samozřejmě nutné ve správném pořadí složit.

int b = 0; b = nacti(); b += (nacti() << 8)Tady uvidíš, zda to půjde napsat nějak takhle přímo.

Akorát tématicky asi nejsi ve správném fóru :wink:

piityy: Maskovat to mě nenapadlo. Zkusím to.
Zpátky skládat to budu až na PC, kde je to OK.
Ještě mě napadlo přetypovat ten integer na pole charů - možná to je blbost, nevím.

Nesprávné forum tematicky? No… žádnou sekci kde je pouze programování software jsem zde nenašel. A dát to do sekce AVR znamená, že si to přečte jen část lidí. Tak promiňte, pokud tu taková sekce je.

Tento problem mozes riesit dvoma sposobmmi:
(budem uvazovat nad tym, ze vo vseobecnosti chces posielat vela udajov, nie iba jeden int)

  1. cez ukazatele
    vytvor si pole bajtov (ortodoxni vy pouzili malloc :slight_smile: ). Adresu zaciatku vloz do ukazatela.
    Ukazatel pretypuj na int, alebo na co chces, to moze byt ukazatel i na typ struct.

cez tento ukazatel pole bajtov napln.

Pri vysielani si bud cez index pola, alebo cez char ukazatel ukazuj na jednotlive pozicie v poli a postupne si ich odvysielavaj na linku.

  1. pouzi union

union umoznunje do jedneho pamatoveho priestoru nastrkat cez seba rozne typy. Tak mozes zapisat hodnotu napr. AD vystupu do premennej int a potom postupne nacitat hodnoty dvoch bajtov.

Pri prijme si musis uvedomit jednu vec. Ci pracujes v systeme low endian alebo big endian. Ak posielas viac bajtove cislo medzi dvoma systemami pricom maju rozny endian, vysledne cislo bude mat poprehadzovane bajty v poradi.
Teraz som si neni isty, ktory system je ktory, ale jeden na nizsiu adresu uklada nizsi bajt z cisla a druhy na najnizsiu adresu zapise najvyssi bajt ktory tvori cislo. To ale pri prijme lahko zistis.

Takze netreba ziadne rotovanie, i ked i to sa da pouzit.

Jo díky Martine. Až se v C prohrabu k práci s pamětí, tak to budu dělat přes to pole/ukazatel na to pole. (Však jsem říkal že to s tím polem mě napadlo). Práci s pamětí mám už tak nějak nacvičenou třeba z pascalu, v C to je to samé, ale nevím jak tam spoustu věcí napsat, atd. Časem se k tomu prohrabu. Zatím mi postačí to maskování. Rotování použít nechci, že až budu posílat třeba 32bitový int, tak si spočtěte, kolikrát bude muset uC provést instrukci SHR. Pro 32bitový int to bude hodněkrát. Vychází mi to až na 48x, záleží jak bude blbý překladač. A to je zatracený šnek. až mi půjde o ryhclest, je nejvýhodnější to pole. Ale zatím jak říkám, neumím to.

EDIT: Nyní jsem si uvědomil, že u toho maskování se bez rotace neobejdu. No, zatím mi to nevadí, o rychlost mi nejde. Už abych se naučil s tou RAMkou zacházet…

Překladač zas tak blbej neni, shift o 8 pozic pozná(alespoň když jsem to před nějakým časem zkoumal tak poznal) a pracuje přímo se správným registrem.