képzés

Amikor beállítja az mikrokontroller, hogy folyamatosan dolgoznak a denevérek. Telepíteni őket, reset, ellenőrzi ezek jelenlétét egy adott nyilvántartásban. Az AVR szerelő erre a célra, vannak csapatok számát. Először is, olyan műveleteket csapatok denevérek - azokat beállítani, vagy állítsa vissza a bitek a különböző nyilvántartások a mikrokontroller, másrészt a csoport átadása parancsokat - szánják őket a szervezet ág programokat. A C nyelv természetesen nincs ilyen utasítás, így a kezdők gyakran felmerül a kérdés, hogyan kell dolgozni a C bit. Ez a téma most, és mi meg fogjuk vizsgálni.

A C van 6 szolgáltatók manipulálni bit. Ők lehet alkalmazni bármely egész aláírt vagy aláíratlan változó típusokat.


<<- сдвиг влево
>> - jobb váltás

- bitenkénti inverzió
| - bitenkénti OR
- bitenkénti ÉS
^ - bitenkénti kizáró VAGY

Eltolódik a száma n bit, hogy a bal oldalon. Régebbi n bit így eltűnnek, és az alsó n bitek nullákkal töltjük fel.


unsigned char TMP = 3; // 0b00000011
TMP = tmp <<1;
// most a tmp változó szám 6 vagy 0b00000110

TMP = tmp <<3;
// most a TMP változó számú 48 vagy 0b00110000

Kifejezések, amelyek felett a változó egy tranzakció, majd a művelet eredményét rendelt ugyanazt a változót, akkor írj rövid felhasználásával összetett utasításokat.

tmp = 7; // 0b00000111
tmp <<= 2; //сокращенный вариант записи
// most a tmp változó számú 28 vagy 0b00011100

eltolási művelet balra n bit egyenértékű szorzás 2 az n változó.

Tolja a számot közvetlenül n bit. A fiatalabb n bit elveszett. Kitöltése a felső n bit típusától függ a változó és az értékét. Régebbi n bitet nullákkal töltjük két esetben - ha a változó előjel nélküli, vagy ha a jel változó, és a jelenlegi értéke pozitív. Ha egy változó jel, és az értéke negatív - jelentős bitek töltve egység.


Példa előjel nélküli változó

unsigned char TMP = 255; // 0b11111111
TMP = tmp >> 1;
// most a TMP változó számú 127 vagy 0b01111111

tmp >> = 3; // levelet rövidített változatát
// most a tmp változó számú 15 vagy 0b00001111

Példa típusú változó jel

int tmp = 3400; // 0b0000110101001000
tmp >> = 2;
// most egy változó számú 850 vagy 0b0000001101010010

tmp = -1200; // 0b1111101101010000
tmp >> = 2;
// most a tmp szám -300 vagy 0b1111111011010100
// lásd - két MSB töltött egységek

A jobbra eltolási műveletet n bitek egyenértékű osztást 2 n. Ugyanakkor vannak olyan árnyalatok. Ha elvesztette jelentős bitek egységgé, az eredmény ez a „szétválás” fordul durva.

Pl 9/4 = 2,5 és 9 >> 2 (1001 >> 2) egyenlő 2
04/11 = 2,75 és 11 >> 2 (1011 >> 2) egyenlő 2
28/4 = 7 és 28 >> ​​2 (11100 >> 2) 7


A második esetben a hiba nagyobb, mert a két fiatalabb számjegyet. A harmadik esetben nincs hiba, mert az elveszett bit nulla.

Bitenkénti megfordítja számát. Kibocsátások, amelyek nulla - teli egység. Kibocsátások, ami kevés volt - tele vannak nullák. Bitenkénti inverzió yavlyatsya egyoperandusú operátor, amely használható egy operandust.

tmp;
// most a tmp változó számú 161 vagy 0b10100001

tmp;
// most a TMP ismét száma 94 vagy 0b01011110

üzemeltető | végrehajt egy logikai VAGY művelet közötti megfelelő biteket a két operandus. Az eredmény a logikai VAGY művelet a két bit 0 lesz, ha mindkét bit értéke 0. Az összes többi esetben az eredmény nem lesz 1. Ezt illusztrálja a tabitse igazság.

üzemeltető | Ez általában használt beállítani bit változó egységet.

TMP = 155
tmp = tmp | 4; // állítani egy második bit változó tmp

155 11 0 0b10011
|
4 1 00 0b00000
159 január 11 0b10011

Használja a decimális számok beállításához bit elég kényelmetlen. Sokkal könnyebb csinálni a segítségével a balra eltolási műveletet <<.


tmp = tmp | (1<<4); //устанавливаем в единицу четвертый бит переменной tmp

Olvasás jobbról balra - váltás egység négy bit van a bal oldalon, hogy végre VAGY művelet között a kapott számot, és a változó értékét tmp, az eredmény meg, hogy egy változó tmp.


Állítsa néhány bitet az egység lehet, így

tmp = tmp | (1<<7)|(1<<5)|(1<<0);
// meghatározott egység a hetedik, az ötödik és a nulla bit tmp

A következő vegyületek értékadó operátor | = rögzíthet tömörebb.

operátor végrehajt egy logikai ÉS művelet közötti megfelelő bit két operandus. Az eredmény a logikai ÉS művelet a két bit 1 lesz, ha mindkét bit értéke 1. Minden más esetben az eredmény kerül 0. Ez illusztrálja az igazság táblázat.

operátor Ez tipikusan visszaállítani egy vagy több bit.

tmp = 155;
TMP = tmp 247; // nullára ki harmadik bit változó tmp


155 0b1001 1011

247 0b1111 0111
147 0b1001 0011

Lásd lesz a harmadik bit 0, és a többi bit nem változott.

Állítsa vissza a bitek segítségével tizedesjegyeket ez kényelmetlen. De lehet, hogy életük segítségével könnyebben szereplők <<и

tmp = 155;
TMP = tmp (

(1<<3)); //обнуляем третий бит

1<<3 0b0000 1 000

(1<<3) 0b1111 0 111
tmp (

(1<<3)) 0b1001 1 011 & 0b1111 0 111
eredményezhet 0b1001 0011

Olvasás jobbról balra - váltás egység három kategóriába balra, végre inverzió kapott számot, a művelet között változó értéke tmp és fordított száma, az eredmény meg, hogy egy változó tmp.


Visszaállítása több bitet lehet olyan

((1<<3)|(1<<5)|(1<<6))); //обнуляем третий, пятый и шестой биты

Itt, az első végre eltolási műveletet jelent, akkor a bitenkénti VAGY művelet, majd az inverzió, bitenkénti ÉS, az eredmény a feladat a változó TMP.


Egy vegyületet értékadó operátor =, Lehet írni a kifejezés sokkal kompaktabb

((1<<3)|(1<<5)|(1<<6)));

Hogyan lehet ellenőrizni, hogy egy kicsit be van állítva egy változó? Meg kell állítani az összes bit kivételével a csekket, majd hasonlítsa össze az értéket nullára

if ((tmp (1<<2)) != 0 ) // блок будет выполняться, только если установлен
// második bit változót TMP
>

if ((tmp (1<<2)) == 0 ) // блок будет выполняться, только если не установлен
// második bit változót TMP
>

^ Operátor végzi egy logikai művelet KIZÁRÓ közötti megfelelő biteket a két operandus. Az eredmény a logikai műveletet XOR 0 egyenlőség esetén a bitek. Minden más esetben az eredmény nem lesz 1. Ezt illusztrálja a tabitse igazság.

^ Operátor használata nem olyan gyakran, mint a többi bit szereplők, hanem egy feladat számára. Például, akkor megfordítható egy vagy több bit változó.


tmp = 155;
TMP = tmp ^ 8; // fordítsa a negyedik bit változás tmp

155 0b1001 1011
^
8 0b0000 1000
147 0b1001 0011

A negyedik bit változott annak értékét az ellenkezőjét, és a fennmaradó bitek változatlan marad.

TMP = tmp ^ 8; // ismét fordítsa a negyedik bit változás tmp

147 0b1001 0011
^
8 0 0b000 1000
155 0b1001 1011

Lásd ismét a negyedik kicsit megváltozott az értéket az ellenkezője.

Így sokkal könnyebb írni egy kifejezést

TMP = tmp ^ (1<<3); / / инвертируем третий бит переменой tmp

És így kényelmes és kompakt

TMP ^ = (1<<4); //инвертируем четверый бит

Meg lehet fordítani több bit egyidejű

TMP ^ = ((1<<4)|(1<<2)|(1<<1)); //инвертируем 4,2 и 1 биты

A bitenkénti XOR, van egy másik érdekes funkció. Ezt fel lehet használni, hogy módosítsa a két változó értékét helyeken. Ehhez általában egy harmadik változót.


tmp = var1;
var1 = var2;
var2 = tmp;

De a ^ operátor átrendezheti az értékeket az alábbiak szerint:

var1 ^ = var 2;
var ^ = var 2 1;
var 1 ^ = var 2;

Tiszta mágia, bár, hogy őszinte legyek, én még soha nem élvezte, mint a vétel.

Most már tudjuk, hogyan kell beállítani, reset és fordítsa bit, tudja, hogyan kell ellenőrizni, ha a bit be van állítva vagy sem. A fenti kifejezések meglehetősen nehézkes, de egy előfeldolgozó irányelv #define. lehetőség van arra, hogy még tetszetős megjelenésű.

A #define direktíva használnak ahhoz, hogy a szimbolikus nevek állandók és makrók. A szimbolikus nevek, hogy a program több módosítható és hordozható.

Például, ha használja a konstans a programban, és hirtelen meg akarja változtatni az értékét. Ha megállapítást nyer, csak három helyen, és meg tudod oldani, hogy kézzel, és mi a teendő, ha ez történik ötven sor? Nem csak, hogy a korrekció hosszú időt vesz igénybe, így egyre hibázik ebben az esetben egyszerű. Itt látható, hogy az idő, és segít #define direktíva. Kezdetben a program a szimbolikus nevet kapta az állandó, hogy használják a program során. Ha meg kell változtatni ezt az értéket, akkor mindig csak egy helyen. A preprocessor fordítás előtt kitölti az egész kifejezést, hanem egy konstans érték.

mikrokontroller programozás elválaszthatatlanul kapcsolódik a hardver és gyakran külső kábelköteg. Hogy legalább egy gomb - interjú őket a programjában, utalunk a tényleges MCU csapokat. És ha hirtelen kell használni felmérés szoftver gombok egy másik rendszer, ahol a gombok vannak kötve különböző következtetéseket? Mi lesz kijavítani a programot. Ismét a beállítást #define irányelvek szimbolikus neve a megfelelő következtetéseket, hogy módosítsa a program lesz olyan egyszerű, mint pite

// portot, amelyre a Connect gombra
#define PORT_BUTTON PORTA
#define PIN_BUTTON Pina
#define DDRX_BUTTON DDRA

// következtetéseket, amelyek össze vannak kötve egy gombot
#define DOWN 3
#define CANCEL 4
#define UP 5
#define ENTER 6

int main ()
// beállítani a port a bemeneti,
// és tartalmazza felhúzó ellenállások
DDRX_BUTTON = 0;
PORT_BUTTON = 0xff;


Amikor megadja egy szimbolikus név is használható, és a kifejezés

#define MASK_BUTTONS ((1<

Használati példa:
TMP = PORTB MASK_BUTTONS;

Használata #define nem bántam zárójelben egyértelműen meghatározza a sorozat számítás kifejezést!

Egyes kifejezések álcázott „funkciót”.

#define ADC_OFF () ADCSRA = 0

Használhatja többsoros definíció a végén minden karakterhez \

#define INIT_Timer () TIMSK = (1< TCCR0 = (1< TCNT0 = 0; \
OCR0 = 0x7d


Nos, a legerősebb használata a #define direktíva - ezt a munkát makrót (vagy makrók). Itt van, hogyan kell használni #define beállíthatja makrók műveletek korábban tárgyalt a denevérek

#define SetBit (reg, bites) reg | = (1< #define ClearBit (reg, bit) reg = (

(1< #define InvBit (reg, bites) reg ^ = (1< #define BitIsSet (reg, bit) ((reg (1< #define BitIsClear (reg, bit) ((reg (1<

Használati példa:
...
SetBit (PORTB, 0); // állítsa a nulla bit B port
InvBit (TMP, 6); // invert hatodik bites változó tmp

Mielőtt össze az elpárologtató helyett a vonal korábban bejelentett kifejezések, azok helyettesítése megfelelő érveket.

A makrók egy nagyon hatékony eszköz, de fel kell használni óvatosan. Íme néhány gyakori gereblye, amelyek meg vannak írva az összes programozási könyvek.

Mi határozza meg a makrót, amely kiszámítja a téren a szám:

#define SQUARE (x) x * x

kifejezés
TMP = SQUARE (my_var);
Ez adja meg a helyes eredményt.

És mi fog történni, ha használja a kifejezést my_var + 1 érvként, hogy a makro

TMP = SQUARE (my_var +1);

Az előfeldolgozó felváltja ezt vonalon

TMP = my_var + 1 * my_var +1;

de ez nem az az eredmény, hogy mi várható.


Ha nyilvánítja egy makrót, így

#define SQUARE (x) ((x) * (x))

kifejezés
TMP = SQUARE (my_var +1);
Ez ad helyes eredményt, mert az elpárologtató felváltja ezt vonalon
TMP = ((my_var + 1) * (my_var +1));

makrók dolgozó bitek

írd fel azokat a projekt mappába, és az elején main.c fájl hogy ezt #include „bits_macros.h”

Az első és a második tanulság. A harmadik (ha jól értettem, a számozást az oldalon valahogy nem nagyon világos) már „teáskanna” zavaros - alkalmazási példa nem elég. Tic Tac szép játék, ez csak, hogy miért. Úgy tűnik, és emlékszem, hogy a normál logika és OR. De volt egyértelmű jele annak, hogy hol és milyen futott. És itt úgy érzem, mint egy férfi sétál a képzeletbeli labirintus (falak nélkül) fordul sok zsákutcák is, de ez a végső cél nem világos. Elnézést a kritika, megpróbálom lépni. Most, ha az anyag még egyszer meg vannak számlálva. Aztán becsukta az oldalt, majd alig találtunk egy helyet, hogy maradjon.

Lessons elromlott, és nem írt minden témában, így a számozás még nem lehetséges.

Köszönöm szépen! Nagyon jó a tudás!

A „shift a megfelelő típusú jel (negatív)”
tmp = -1200;
tmp >> = 2;

Meg kell értékét -300 helyett -600.

A jobbra tolódása, az érték egyenlő -1200, számomra úgy tűnik, a bináris ábrázolása a szám nem felel meg a tizedes, ott kell lennie 0b1000010010110 000. váltást követően az értéket a változó kellene 0b1000000100101 100. Javítson ki, ha tévedek.

Tehát ez az, nagyon köszönöm, hogy magyarázza.

Vagy én vagyok hülye, vagy nem megy a síelés.
Itt ellenőrizze overlay egyetlen tömbjének egy másik (szilárd [15] CurrentFig [3])
Kód: for (i = 0; i<4; i++) if(solid[i+1+CurrentFigY] & CurrentFig> 0)
j ++;
>
ami azt jelenti, hogy ha egy napló szorzás megjelenik legalább egy egységnyi j növekszik.
de az állapota nem működik.

Egy makró, akkor ehelyett SetBitVal ha más is használja a háromkomponensű üzemeltetője. Akkor nem kell aggódnia a hibákat.
Kód: ((val 1)! = 0). reg | = (1<

(1<Azt is kihasználják a kizárólagos vagy. Akkor lehet ellenőrizni, hogy a bit megváltozik. Sokkal jobb, hogy használja csak ha.
Kód: (val<