курс на обучение

При програмиране на микроконтролера да се работи постоянно с прилепи. Инсталирайте ги, нулиране, проверка присъствието им в определен регистър. В AVR асемблер за тези цели, има редица отбори. Първо, една група от операции екипи с прилепи - те се използват, за да настроите или нулиране на битовете в различните регистри на микроконтролера, и второ, на група от прехвърляне на контролни команди - те са предназначени за организирането на браншови програми. Езикът на C е естествено няма такива инструкции, така че начинаещите често възниква въпросът, как се работи с бита C. Тази тема сега сме и ние ще направим проверка.







В C има 6 оператори да манипулират бита. Те могат да се прилагат към всеки подписан цяло число или неподписани типове променливи.


<<- сдвиг влево
>> - отклонение в дясно

- побитовото инверсия
| - Побитова ИЛИ
- побитова
^ - побитовото ексклузивно

Промени в броя на п бита на ляво. Така стари п бита изчезват и долните п бита са запълнени с нули.


неподписан овъгляване ТМР = 3; // 0b00000011
ТМР = ТМР <<1;
// сега в ТМР променлив брой 6 или 0b00000110

ТМР = ТМР <<3;
// сега в променлив брой на ТМР 48 или 0b00110000

Изрази, че над променлива е сделка, а след това резултатът от операцията се определя на една и съща променлива, можете да напишете кратък, като се използват сложни отчети.

ТМР = 7; // 0b00000111
ПТУ <<= 2; //сокращенный вариант записи
// сега в променлив брой на ТМР от 28 или 0b00011100

смени операция наляво от п бита е еквивалентно на умножение с 2 на променливата п.

Променя броя точно до п бита. По-малките п бита се губят. Пълнене горните п бита в зависимост от вида на променливата и неговата стойност. По-стари н бита са пълни с нули в два случая - ако променливата не е подписана или ако променливата на знак и сегашната си стойност е положителна. Когато една променлива знак и неговата стойност е отрицателна - значими бита са пълни единици.


Пример неподписан променлива

неподписан овъгляване ТМР = 255; // 0b11111111
ТМР = ТМР >> 1;
// сега в променлив брой на ТМР 127 или 0b01111111

ТМР >> = 3; // напиши съкратена версия
// сега в променлив брой на ТМР от 15 или 0b00001111

Пример тип променлива знак

Int ТМР = 3400; // 0b0000110101001000
ТМР >> = 2;
// сега в променлив брой от 850 или 0b0000001101010010

ТМР = -1,200; // 0b1111101101010000
ТМР >> = 2;
// сега в номерата на ТМР -300 или 0b1111111011010100
// виж - две MSBs пълни единици

Правото на работа на смени на п бита е еквивалентно на делене на 2 п. В същото време има някои нюанси. Ако са загубили значителни бита, които се съдържат единица, в резултат на това "разделение" се оказва груб.

Напр 9/4 = 2.5 и 9 >> 2 (1001 >> 2) е равно на 2
4.11 = 2.75 и 11 >> 2 (1011 >> 2) е равно на 2
28/4 = 7 и 28 >> ​​2 (11100 >> 2) е 7


Във втория случай, грешката е по-голям, тъй като двете са по-млади от тях цифра. В третия случай няма грешка, защото изгубените бита на нула.

Побитовото обръща номер. Изхвърлянето, които бяха нула - пълни единици. Изхвърлянето, които бяха малцина - са пълни с нули. Побитовото инверсия yavlyatsya едноместно оператор, който се използва с един операнд.

ПТУ;
// сега в променлив брой на ТМР 161 или 0b10100001

ПТУ;
// сега в ТМР отново броят 94 или 0b01011110

оператор | изпълнява логическа операция ИЛИ между съответния бита на два операнда. В резултат на логическото ИЛИ операция между два бита ще бъде 0, само ако двата бита са 0. Във всички други случаи резултатът ще бъде 1. Това е илюстрирано на tabitse истина.

оператор | Обикновено се използва за задаване на бита, определени в променлив елемент.

ТМР = 155
TMP = ПТУ | 4; // зададете до една втора битова променлива ПТУ

155 11 0 0b10011
|
4 1 00 0b00000
159 11 януари 0b10011

Използване на десетични числа в с битове по-скоро неудобно. Тя е много по-лесно да го направите с помощта на операцията смяна ляв <<.


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

Четенето от дясно на ляво - изместване единица в четири бита на ляво, за извършване на операция ИЛИ между получената броя и стойността на променливата ТМР, резултатът настроен на променлива ТМР.


Разположен на няколко бита в устройството може да бъде толкова

TMP = ПТУ | (1<<7)|(1<<5)|(1<<0);
// разположен в единица на седмия, пети и нулеви бита на ТМР

Използвайте оператора за присвояване съединение | = може да записва по-компактен.

оператор изпълнява логическа И между съответния бита на два операнда. Резултатът от логично и между двете бита ще бъде 1, само ако и двете парчета са равни на 1. Във всички други случаи резултатът ще бъде 0. Това е илюстрирано в таблицата с истина.

оператор Обикновено се използва за възстановяване на един или повече бита.

ТМР = 155;
ТМР = ТМР 247; // нула, трета малко променлива ПТУ


155 0b1001 1011

247 0b1111 0111
147 0b1001 0011

Виж, става третата бит е 0, а другите бита не се променят.

Възстановяване на бита използване десетични цифри, това е неудобно. Но можете да направите живота си по-лесно с помощта на оператори <<и

ТМР = 155;
ТМР = ТМР (

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

1<<3 0b0000 1 000

(1<<3) 0b1111 0 111
ПТУ (

(1<<3)) 0b1001 1 011 & 0b1111 0 111
доведе 0b1001 0011

Четене от дясно на ляво - изместване единица в три категории напуснали, извършване на инверсия в резултат число, операцията между стойността на променливата ТМР и обърнати броя, резултатът настроен на променлива ТМР.








Reset няколко бита могат да бъдат толкова

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

Тук за първи път приложена работа на смени, а след това побитов или работа, а след това на инверсия, побитова, в резултат на прехвърлянето на променливата ПТУ.


Използване на оператор съединение задача =, Можем да пишете израза е по-компактен

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

Как да проверите дали малко се помещава в една променлива? Вие трябва да изчисти всички битове освен за извършване на проверката и след това сравни стойността на нула

ако ((ПТУ (1<<2)) != 0 ) // блок будет выполняться, только если установлен
// втори малко променлива ПТУ
>

ако ((ПТУ (1<<2)) == 0 ) // блок будет выполняться, только если не установлен
// втори малко променлива ПТУ
>

^ Оператор изпълнява операция EXOR логическа между съответните битове на два операнда. Резултатът от логическа операция XOR е 0 в случай на равенство на битовете. Във всички останали случаи резултатът ще бъде 1. Това е илюстрирано на tabitse истина.

^ Оператор се използва не толкова често, колкото останалата част от операторите на битови, но също така е работа за него. Например, може да се обърнат използват един или повече бита променлива.


ТМР = 155;
ТМР = ТМР ^ 8; // обърнете четвърти малко ПТУ промяна

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

Четвъртият малко се е променила стойността си до обратното, а останалите битове остават непроменени.

ТМР = ТМР ^ 8; // отново обърнете четвърти малко ПТУ промяна

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

Вижте, отново, четвъртото малко се е променила стойността си до обратното.

Така че много по-лесно да се напише израз

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

И така, компактно и удобно

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

Можете да се обърне няколко бита едновременно

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

В побитова XOR, има и друга интересна функция. Може да се използва за промяна на стойностите на две променливи в места. Това обикновено изисква трета променлива.


ТМР = var1;
var1 = var2;
var2 = ТМР;

Но с помощта на ^ операторът може да пренаредите стойности, както следва:

var1 ^ = Var 2;
Var ^ = Var 2 1;
Var 1 ^ = Var 2;

Чиста магия, макар че, честно казано, никога не съм се радваше такъв прием.

Сега ние знаем как да се създаде, нулиране и обърнете бита, знаят как да проверите дали бит е, или не. Посочените по-горе изрази са доста тромави, но с директива предпроцесорни #define а. е възможно да се придаде по-приятен външен вид.

Директивата #define се използва за присвояване на символични имена за константи и макроси. Използването на символични имена в програмата я правят по-приспособим и преносим.

Например, можете да използвате константи в програмата, и изведнъж искате да промените своята стойност. Ако се установи, само в три места, и можете да го оправя ръчно, и какво да направите, ако това се случи в петдесет линии? Не само това, корекцията ще отнеме много време, така че все повече и да се направи грешка в този случай е просто. Ето как времето и помага #define директива. В началото на програмата се дава символично име на константа, която се използва в хода на програмата. Ако трябва да промените тази стойност, тя се извършва само на едно място. А предпроцесорни преди съставянето той попълва от всички слова, вместо постоянно своята стойност.

микроконтролер програмиране е неразривно свързано с хардуер и често с външен колан. Вземете най-малко един бутон - да ги интервюира в програмата си, ние се позоваваме на действителните MCU щифтове. И ако изведнъж се наложи да използвате софтуерни бутони проучване в друга схема, където бутоните са свързани с различни заключения? Ще трябва да се определи програмата. Отново, настройка, като използвате #define директиви символично име за съответните изводи, да променя програмата ще бъде толкова лесно, колкото пай

// порт, към който бутона Connect
#define PORT_BUTTON PORTA
#define PIN_BUTTON PINA
#define DDRX_BUTTON DDRA

// заключения, които са свързани с един бутон
# определят НАДОЛУ 3
# определят ОТКАЗ 4
# определят с 5
# определят ENTER 6

INT главната ()
// конфигуриране на пристанището на входа,
// и включват гостилница резистори
DDRX_BUTTON = 0;
PORT_BUTTON = 0xff;


При задаване на символично име може да се използва, и изразяване

# определят MASK_BUTTONS ((1<

Пример за приложение:
ТМР = PORTB MASK_BUTTONS;

Използването #define не съжалявам скоби, за да е ясно за кои последователност от изчислителни изрази!

Някои изрази могат да бъдат маскирани като "функция".

# определят ADC_OFF () ADCSRA = 0

Можете да използвате дефиниция няколко реда, като се използва в края на всеки знак в низа \

# определят INIT_Timer () TIMSK = (1< TCCR0 = (1< TCNT0 = 0; \
OCR0 = 0x7d


Е, най-мощният използването на директивата за #define - тази работа макро (или макроси). Ето как можете да използвате #define, можете да зададете макроси за операции преди обсъдени с бухалки

#define SetBit (рег, битова) рег | = (1< #define ClearBit (рег, битова) рег = (

(1< #define InvBit (рег, битова) рег ^ = (1< #define BitIsSet (рег, битова) ((рег (1< #define BitIsClear (рег, битова) ((рег (1<

Пример за приложение:
...
SetBit (PORTB, 0); // задаване на нула малко пристанище Б
InvBit (ТМР, 6); // инвертна шести малко променлива ТМР

Преди да можете да компилирате Препроцесорът да замени линия съобщи по-рано изрази, поставете ги замества с подходящи аргументи.

Макросите много мощен инструмент, но те трябва да се използва внимателно. Ето някои често срещани гребла, които са написани на всички програмни книги.

Ние дефинираме макрос, който изчислява на квадрата на броя:

# определят квадрат (х) х * х

изразяване
ТМР = квадрат (my_var);
Тя дава правилния резултат.

А какво ще стане, ако използвате израз my_var + 1 като аргумент за макроса

ТМР = квадрат (my_var 1);

Препроцесорът замества този ред на

ТМР = my_var + 1 * my_var 1;

но това не е в резултат на което ние очакваме.


Ако декларирате макро, така

# определят квадрат (х) ((х) * (х))

изразяване
ТМР = квадрат (my_var 1);
Тя дава правилния резултат, защото Препроцесорът замества този ред на
ТМР = ((my_var + 1) * (my_var 1));

макроси за работа с битове

напишете ги в папката на проекта, както и в началото на Стартиране файл поставите този #include "bits_macros.h"

Първата и втората поука. Третият (ако разбрах правилно, с номерацията на сайта някак си не е много ясно) вече "чайник" объркан - пример за приложение не е достатъчно. Tic Tac красива игра, това е само защо. Изглежда, и си спомням как стандартната логика и OR. Но имаше ясен сигнал за това къде и какво се затича. И тук се чувствам като човек, ходене в имагинерната лабиринта (без стени) се оказва много задънени улици, също, но това е крайната цел не е ясно. Съжалявам за критиката, аз ще се опитам да продължа напред. Сега, ако материалът дори веднъж преброени. И тогава аз затворих страницата и след това едва намери място за престой.

Уроци от ред и не са написани по всички теми, така че номерирането все още не е възможно.

Благодаря ви много! Много добри познания!

Възможно е "изместването на правилния тип знак (отрицателно)"
ТМР = -1,200;
ТМР >> = 2;

Тя трябва да бъде стойността на -300 вместо -600.

Преминаването към правото, стойността е равна на -1200, струва ми се, двоичното представяне на числото, не отговаря на десетичната, трябва да има 0b1000010010110 000. След преместване на стойността на променливата трябва да 0b1000000100101 100. Поправете ме, ако греша.

Така че това е, благодаря ви много, че е обяснено.

Или аз съм глупав или не карат ски.
Тук се провери наслагване един масив на друг (твърдо вещество, [15] CurrentFig [3])
Код: за (I = 0; и<4; i++) if(solid[i+1+CurrentFigY] & CurrentFig> 0)
J ++;
>
което означава, че ако един дневник умножение се появява най-малко една единица й се увеличава.
но състоянието не работи.

В макро, можете да вместо SetBitVal ако друг да ползва третичния оператор. Тогава не може да се тревожи за грешки.
Код: ((Val 1)! = 0). рег | = (1<

(1<Можете също така да се възползвате от изключителна или. След това ще бъде възможно да се наблюдава дали битът се променя. По-добре е да се използва само ако.
Код: (Val<