Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Суммирование, вычитание, умножение, деление.

Поиск

Что такое Arduino?

 

Arduino - открытая платформа для создания электронных устройств, основными компонентами которой являются плата с микроконтроллером ATmega и интегрированная среда разработки (IDE) на языке Wiring.

С помощью Arduino можно разрабатывать различные интерактивные устройства. Обрабатывать данные датчиков и переключателей, управлять двигателями и т.д. Устройства могут быть автономными или взаимодействовать с программным обеспечением вашего компьютера (Processing, Flash, MaxMSP и др.).

Язык Arduino основан на C/C++ и поддерживает все стандартные конструкции языка C и некоторые из функций языка C++. Он также ссылается на библиотеку AVR libc и может использовать любые из ее возможностей.

 

Структура:

 

Void setup()

Функция setup() вызывается при старте программы. Ее можно использовать для инициализации переменных, назначения пинов, вызова стартовых функций библиотек и другого. Функция вызывается лишь однажды, после каждой подачи питания или перезагрузки платформы.

Пример:

 

int buttonPin = 3;

void setup()

{

Serial.begin(9600);

pinMode(buttonPin, INPUT);

}

 

void loop()

{

//...

}

 

Void loop()

Функция loop() - это основной цикл программы. Данная функция выполняется бесконечное число раз. Платформа управляется через эту функцию

Пример:

int buttonPin = 3;

//инициализуем последовательный порт и входной пин

void setup()

{

beginSerial(9600);

pinMode(buttonPin, INPUT);

}

// Через определенный промежуток времени проверяем состояние пина,

// и отсылаем данные в порт

void loop()

{

if (digitalRead(buttonPin) == HIGH)

serialWrite('H');

else

serialWrite('L');

delay(1000);

}

 

Управляющие операторы

 

if (условие) и ==,!=, <, > (сравнение)

if, В сочетании с операторами сравнения проверяет, выпролняется ли условие, и выбирает алгоритм для того или иного случая.

if (someVariable > 50)

{

// тело условия

}

В случае, если someVariable будет меньше 50 программа пропустит список операторов, заключенный в фигурные скобки. Если же условие верно, то сначала выполнятся команды в фигурных скобках а затем уже пойдет выполнение основного цикла программы.

Фигурные скобки могут закрываться в той же строке, что и опрераторы. Если оператор всего один, то скобки опускаются.

if (x > 120) digitalWrite(LEDpin, HIGH);

if (x > 120)

digitalWrite(LEDpin, HIGH);

if (x > 120){ digitalWrite(LEDpin, HIGH); }

if (x > 120){

digitalWrite(LEDpin1, HIGH);

digitalWrite(LEDpin2, HIGH);

}//Все варианты верны

 

Операторы сравнения:

x == y (x равен y)

x!= y (x неравен y)

x < y (x меньше y)

x > y (x больше y)

x <= y (x меньше или равно y)

x >= y (x больше или равно y)

Внимание:

Остерегайтесь использования символа одиночного равенства (if (x=10)). В этом случае выполниться присваивание переменной x значения, равного 10. Вместо этого необходимо использовать символ двойного равенства (if x==10), который как раз и сравнивает, равно значение переменной 10 или нет. Предыдущая запись будет всегда верной.

Учтите, что if возвращает TRUE при любом ненулевом значении.

if может использоваться в виде полной структуры if...else

 

if / else

if/else дает больший контроль над выполнением кода, поскльку в случае верного условия выполняется только один блок операторов и в другом случае - только другой блок операторов.

if (pinFiveInput < 500)

{

// Действие А

}

else

{

// действие B

}

 

Также, возможно расширение количества вариантов за счет использования else if помимо блока else.

if (pinFiveInput < 500)

{

// Действие A

}

else if (pinFiveInput >= 1000)

{

// Действие B

}

else

{

// Действие C

}

 

Конструкция for

Описание: Конструкция for позволяет повторять выполнение определенного участка кода - тело цикла. Счетчик обычно икрементируется при каждом повторе и служит для выхода из цикла. Данная конструкция позволяет более просто выполнять какие-либо повторяющиеся действия, и часто используется, например, с массивами, или выводами МК.

Имеется три управляющих значения для данной конструкции:

 

for (initialization; condition; increment) {

//statement(s);

}

 

initialization случается первой и всего один раз. Каждый раз проверяется условие condition; Если оно верно, цикл продолжает работу, после чего выполняется increment, и снова проверяется condition. Когда условие condition становится ложным происходит выход из цикла.

Пример:

// Dim an LED using a PWM pin

int PWMpin = 10; // LED in series with 1k resistor on pin 10

void setup()

{

// no setup needed

}

void loop()

{

for (int i=0; i <= 255; i++){

analogWrite(PWMpin, i);

delay(10);

}

}

 

Совет программисту:

Язык C предоставляет большую гибкость для программиста, чем другие языки программирования. В частности, любое из трех условий может быть опущено.

 

Switch / case

Также как и оператор if, switch...case позволяют направлять программу по различным участкам кода.На практике switch сравнивает значение переменной с тестовым и если они равны, то запускает опеределенный участок кода на выполнение.

Оператор break позволяет выходить из условия switch, и используется в конце каждого из вариантов. Без break,switch будет выполнять все варианты подряд, вызывая ошибку.

Пример

switch (var) {

case 1:

//do something when var equals 1

break;

case 2:

//do something when var equals 2

break;

default:

// if nothing else matches, do the default

// default is optional

}

Синтаксис:

switch (var) {

case label:

// statements

break;

case label:

// statements

break;

default:

// statements

}

Параметры:

var: переменная, которую собираемся сравнивать

label: значение, с которым сравниваем переменную

 

Цикл while

Описание:

Цикл while позволяет выполняться сколь угодно долго время вплоть до бесконечности, пока условие внутри () не станет ложным. Что- В теле цикла что-то должно менять значение, иначе из кцикла мы никогда не выйдем.

Синтаксис:

while(expression){

// statement(s)

}

Параметры:

expression - Выражение, возвращающее true или false

Пример:

var = 0;

while(var < 200){

// Делаем что-то повторяющееся 200 раз

var++;

}

 

Do - while

Цикл do работает по тому же принципу чтои while, однако сначала выполняется тело цикла, а уже потом проверяется условие. Таким образом, цикл выполнится у нас хотя бы один раз.

do

{

// statement block

} while (test condition);

Пример:

do

{

delay(50); // wait for sensors to stabilize

x = readSensors(); // check the sensors

} while (x < 100);

 

Break

break используется для выхода из циклов do, for, или while. Он также используется для выхода из switch.

Пример:

for (x = 0; x < 255; x ++)

{

digitalWrite(PWMpin, x);

sens = analogRead(sensorPin);

if (sens > threshold){ // bail out on sensor detect

x = 0;

break;

}

delay(50);

}

 

Continue

continue пропускает текущую итерацию циклов (do, for, or while).

Пример:

for (x = 0; x < 255; x ++)

{

if (x > 40 && x < 120){ // create jump in values

continue;

}

 

digitalWrite(PWMpin, x);

delay(50);

}

 

Return

Прекращает выполнение функции и возвращает значение в родительскую функцию, если таковое имеется.

Синтаксис:

return;

return value; // both forms are valid

Параметры:

value: переменная любого типа или константа

Пример:

Фукнция сравнивающая входное напряжение с определенным значением.

int checkSensor(){

if (analogRead(0) > 400) {

return 1;

else{

return 0;

}

}

Весь программный код, написанный после оператора return; будет висеть мертвым грузом в памяти программ, поскольку никогда не будет выполнен.

void loop(){

// гениальный код

return;

// бесполезный код

//он никогда не познает, что такое жизнь...

}

 

Goto

Переносит точку выполнения программы к определенной метке

Ситаксис:

label:

goto label; // посылает программу к нашей метке

Совет:

Использование этого оператора в настоящее время является дурным тоном программирования, хотя и делает некоторые программы более легкими. Однако, легкость алгоритма предоставляет возможную невозможность (:)) последующего дебаггинга такой программы.

Одним из вариантов использование оператора goto является выход из вложенных циклов, к примеру:

for(byte r = 0; r < 255; r++){

for(byte g = 255; g > -1; g--){

for(byte b = 0; b < 255; b++){

if (analogRead(0) > 250){ goto bailout;}//как только выполняется условие бежим из этой тьма-тараканьи...

// больше параметров...

}

}

}

bailout;

Прочий синттаксис

 

; точка с запятой

Используется для обозначения когда выражения

Пример

int a = 13;

Совет:

Опущение точки с запятой приведет к ошибке компилятора. Ошибка может быть явной и вести на требуемую строку, а может и не вести. Если логика вывода ошибок вам не понятна - первым делом ишите упущенный символ; в строках до той, которую подсвечивает компилятор.

 

{} Фигурные скобки

Фигурные скобки являются одними из главных в языке C. Они используются для разделения конструкций и часто вводят в смущение начинающих программистов.

Открытая скобка обязательно должна иметь в качетве пары закрыващую скобку.

Поскольку использование фигурных скобок двольно разнообразно, хорошим стилем программирования станет научиться сразу же ставить закрывающую скобку и продолжать писать код между ними.

Фигурные скобки определяют основную логику программы поэтому забыв поставить одну из скобок, найти ошибку будет весьма затруднительно.

 

Основное использование фигурных скобок:

функции

void myfunction(datatype argument){

statements(s)

}

Циклы

while (boolean expression)

{

statement(s)

}

do

{

statement(s)

} while (boolean expression);

for (initialisation; termination condition; incrementing expr)

{

statement(s)

}

Операторы условия

if (boolean expression)

{

statement(s)

}

else if (boolean expression)

{

statement(s)

}

else

{

statement(s)

}

 

Комментарии

Комментарии используются для инфомрмирования программиста о смысловой нагрузке участков кода. Они игнорируются компилятором и не занимают места в МК.

Комментарии помогают понять или запомнить логику работы программы. В случае, если ваш код будет разбирать кто-то другой, или же вы сами после долгого от него отлучения - комментарии весьма полезны. Существует два способа определения комментариев в программе:

Пример

x = 5; // Однострочны комментарий. Заканчивается переводом строки

/* Это многострочный комментарий.

if (gwb == 0){ // однострочный комментарий правильно работает внутри многострочного

x = 3; /* но многострочный внутри многострочного - нет */

}

// не забываем закрыть - соблюдаем баланс!

*/

Совет:

При экспериментировании с кодом весьма практично комментировать участки кода, но не удалять их. В этом случае гораздо проще починить код, и отпадает необходимость набирать его заново.W

 

Define

Дирректива препроцессора #define это удобный компонент C позволяющий программисту использовать макроопределения. Макроопределения не занимают места в памяти программ. При компиляции объявленные макроопределения просто заменяются на строку символов, таким образом имеется возможность указания какого-либо параметра (константы) сразу в нескольких местах кода.

Синтаксис:

#define constantName value

Помни, что символ # обязательный

Пример:

#define ledPin 3

// Компилятор заменит встречающее в коде ledPin на 3 во время компиляции программы.

Совет:

После директив препроцессора отсутсвует точка запятой. Если вы влепите ее туда то компилятор вылетит с ошибкой. page.

#define ledPin 3; // эта запись ошибочна

Также использование знака присваивания ошибочно.

#define ledPin = 3 // тоже ошибка

 

#include

Директива препроцессора #include используется ля подключению к проекту внешних библиотек. Это дает программисту все возможности библиотек языка C/C++, а также специальных, написанных для платформы Arduino.

Помни, что #include, как #define, не требуют точки с запятой, и компилятор вылетит с ошибкой если вы влепите ее туда.

Пример:

Этот пример подклчюает библиотеку, позволяющую класть данные в память программ, тем самым экономя оперативную память. Эдакий - свап-раздел на свободном месте флеша МК.

#include <avr/pgmspace.h>

prog_uint16_t myConstants[] PROGMEM = {0, 21140, 702, 9128, 0, 25764, 8456,

0,0,0,0,0,0,0,0,29810,8968,29762,29762,4500};

 

Арифметические операции

 

= оператор присваивания

Сохраняет значение правого выражения в переменной, стоящей в левой части.

Одиночное равно в языке C называется оператором присваивания. Он имеет отличное от стандартного алгебраического значения присваивания и сравнения. Для языка C одиночное равно означает присвоить значение справа от знака равно переменной слева.

Например:

int sensVal; // объявляем целочисслительную переменную sensVal

senVal = analogRead(0); // сохраняем в ней значение АЦП, снятое с аналоговой ножки 0.

 

Советы программистам:

переменная слева от знака должна вместить присваиваемое ей значение. В другом случае сохраненное в ней значение может быть некорректным.

Не путайте оператор присваивания (=) с оператором сравнения (==), который проверяет, равны ли две переменные.

 

If / else

if/else дает больший контроль над выполнением кода, поскльку в случае верного условия выполняется только один блок операторов и в другом случае - только другой блок операторов.

if (pinFiveInput < 500)

{

// Действие А

}

else

{

// действие B

}

 

Также, возможно расширение количества вариантов за счет использования else if помимо блока else.

if (pinFiveInput < 500)

{

// Действие A

}

else if (pinFiveInput >= 1000)

{

// Действие B

}

else

{

// Действие C

}

 

Логические операции

Могут быть использованы в оператjрах условия.

 

&& (логическое И)

 

Истинно только при выполнении обоих условий, например:

if (digitalRead(2) == HIGH && digitalRead(3) == HIGH) {

//...

}

 

|| (логическое ИЛИ)

Истинно, если хотя бы одно из условий выполняется:

if (x > 0 || y > 0) {

//...

}

 

! (НЕ)

Истинно если оператор ложен (false)

if (!x) {

//...

}

 

Внимание:

Логическое И &&(двойной амперасанд) и побитовое И &(одинарный амперсанд) - разные операторы

Также, не стоит путать логическое ИЛИ || (двойная черта) и побитовое ИЛИ operator | (одинарная черта).

Побитовое НЕ ~(тильда) выглядит иначе, чем логическое НЕ!(знак восклицания), но вы должны быть уверены, какой именно использовать.

 

Указатели и ссылки

 

& (ссылка) и * (указатель)

Указатели и ссылки являются одними из самых сложных предметов для новичков в программировании. Однако умение манипулировать указателями позволяет существенно упростить код при работе с определенными структурами.

Битовые операции

 

Побитовое И (&), Побитовое ИЛИ (|), Побитовое исключающее ИЛИ (^)

Битовые операции с переменными проводятся на битовом уровне. Данные операции позволяют решать многие проблемы программирования. Представленный материал поможет долстаточно полно разобраться с битовыми операциями.

Описание и синтаксис

 

Побитовое И (&)

Побитовое И в языке C это одиночный амперсанд (&), используется между двух выражений. Побитовое И оперирует с каждым битом переменных по отдельности, руководствуся правилом - если оба бита перменных одного разряда равны 1, то результатом также будет 1 в данном разряде. В любом другом случае в результате получится ноль.

0 0 1 1 операнд1

0 1 0 1 операнд2

----------

0 0 0 1 (операнд & операнд2) - возвращаемый результат

 

В Arduino, тип данных int занимает 16-бит, поэтому использование & между двумя переменными типа int вызывает одновременное сравнение 16 бит. Рассмотрим этот код:

int a = 92; // в битовом виде: 0000000001011100

int b = 101; // в битовом виде: 0000000001100101

int c = a & b; // результат: 0000000001000100, или 68 в десятичной системе счисления.

Одним из мест применения побитового И является маскирование переменной для выделения какого-либо бита.

 

Побитовое ИЛИ (|)

Побитовое ИЛИ в языке C обозначается вертикальной чертой. Также как и & | работает с отдельными битами. Однако алгоритм его работы конечно же отличается. Побитовое ИЛИ вернет 1 в результате если хотя бы один из бит входных операндов будет равен 1.

0 0 1 1 операнд1

0 1 0 1 операнд2

----------

0 1 1 1 (операнд1 | операнд2) - возвращаемый результат

Пример:

int a = 92; // в битовом виде: 0000000001011100

int b = 101; // в битовом виде: 0000000001100101

int c = a | b; // результат: 0000000001111101, или 125 в десятичной системе счисления.

 

побитовое исключающее ИЛИ (^)

Данный оператор использует весьма редко в языке C. Побитовое исключающее ИЛИ работает по следующему принципу - Реузльтат будет 1, если только один из входных битов будет 1. В случае, если оба бита будут 1, то оператор возвращает 0.

0 0 1 1 операнд1

0 1 0 1 операнд2

----------

0 1 1 0 (операнд1 ^ операнд2) - возвращаемый результат

По другому алгоритм можно описать так - если биты различны, возвращается 1 и возвращается 0 если они одинаковы.

 

побитовый сдвиг влево (<<), побитовый сдвиг вправо(>>)

Описание:

Данные два оператора сдвигают влево или вправо значения битов переменной слева на количество, указанное в переменной справа.

Синтаксис:

переменная << число бит

переменная >> число бит

Параметры:

переменная - (byte, int, long) число <= 32

Пример:

int a = 5; // в битовом виде: 0000000000000101

int b = a << 3; // в битовом виде: 0000000000101000, или 40 в десятичной системе счисления

int c = b >> 3; // в битовом виде: 0000000000000101, или 5 с чего мы и начали

Вы можете легко потерять биты, слишком много сдвинув их влево:

int a = 5; // binary: 0000000000000101

int b = a << 14; // binary: 0100000000000000 - старшая 1 в 101 была потеряна

Самым простым способом применения операторов сдвига является нахождение степени числа 2.

1 << 0 == 1

1 << 1 == 2

1 << 2 == 4

1 << 3 == 8

...

1 << 8 == 256

1 << 9 == 512

1 << 10 == 1024

...

Если вы сдвигаете биты отрацительной переменной, то старший бит при сдвиге вправо копируется:

int x = -16; // binary: 1111111111110000

int y = x >> 3; // binary: 1111111111111110

Данный пример выдает не то что нам нужно. Чтобы старший бит не копировался, необходимо указать это:

int x = -16; // binary: 1111111111110000

int y = (unsigned int)x >> 3; // binary: 0001111111111110

Если вы осторожны в своих действиях, то можете применять сдвиг вправо для деления переменных на степень двойки.

Например:

int x = 1000;

int y = x >> 3; // целочисленное деление 1000 на 8, возвратит y = 125.

Советы программисту:

данные операции выполняются с высоким быстродействием, так как работа идет с целочисленными переменными. В результате умножение и деление на 2 выполняется едва ли не за 1 такт.

 

 

Побитовое НЕ (~)

Побитовое НЕ в C++ обозначается символом тильды ~. В отличие от & и |, побитовое НЕ не сравнивает биты, а просто инвертирует их. Все что было 1 становится 0 и наоборот, Например:

0 1 операнд1

----------

1 0 ~ операнд1

 

int a = 103; // binary: 0000000001100111

int b = ~a; // binary: 1111111110011000 = -104

 

Регистры портов

 

Регистры портов разрешают низкоуровневые высокоскоростные манипуляции с выводами микроконтроллера. Используемые в Arduino чипы имеют три порта:

B (цифровые выводы от 8 до 13)

C (аналоговые входы)

D (цифровые выводы от 0 до 7)

 

Каждый порт контроллируется тремя регистрами, каждый из которых отвечает за определенное состояние. Регистр DDR определяет, какой вывод входной, а какой выходной (INPUT OUTPUT). Регистр PORT устанавливает вывод в соответствующее состояние HIGH или LOW, и регистр PIN читает состояние входного вывода.

Регистры DDR и PORT могут быть как прочитаны, так и записаны. Регистр PIN отвечает за состояние входных портов, поэтому может быть лишь прочитан.

 

PORTD отвечает за выводы 0 - 7

DDRD - Регистр направления порта D -чтение/запись

PORTD - Регистр данных порта D - чтение/запись

PIND - Регистр входных данных порта D - чтение/запись

 

PORTB отвечает за выводы 8 - 13 Два старших бита (6 и 7), отвечающие за выводы кварца незадействованы.

DDRB - Регистр направления порта B -чтение/запись

PORTB - Регистр данных порта B - чтение/запись

PINB - Регистр входных данных порта B - чтение/запись

 

PORTC отвечает за аналоговые выводы 0 - 5. Выводы 6 & 7 доступны только на Arduino Mini

DDRC - Регистр направления порта C -чтение/запись

PORTC - Регистр данных порта C - чтение/запись

PINC - Регистр входных данных порта C - чтение/запись

 

Каждый бит в этих регистрах отвечает за соответствующий вывод, т.е. младший бит у DDRB, PORTB, и PINB ссылается на вывод PB0 (цифровой вывод 8). Для полного соответствия регистровых битов выводам МК посмотрите назначение выводов вашего МК.

Примеры:

Следует помнить, что выводы 0 и 1 задействованы последовательным портом и работа с ними возможна только в том случае, если отладки и последовательный порт не требуются.

DDRD это регистр направления выводов для порта D (Arduino цифровые выводы 0-7). Биты этого регистра контролируют, как вывод регистра PORTD будет сконфигурирован - input или output, например:

 

DDRD = B11111110; // устанавливает выводы от 1 до 7 как выходные, вывод 0 - входной

//Ознакомьтесь с битовыми операциями

PORTB это регистр для установки выходных портов;

PORTD = B10101000; // устанавливает цифровые выводы 7,5,3 HIGH

Вы сможете видеть только 5В на выводе всегда, не вжно, использовали ли вы регистр DDRD или функцию pinMode().

PINB это регистр состояния входных выводов. Он может прочесть одновременно прочесть состояние всех выводов порта.

Конечно, с одной стороны данный мометод работы с портами имеет ряд мутных недостатков:

Программный код становится более сложным для поиска ошибок и менее понятным для остальных людей. Эти операции выполняются за считанные такты микропроцессора, однако вам может потребоваться несколько часов, чтобы найти, что рабоотает неправильно и исправить это!.

Код становится менее переносимым - сказывается привязка к конкретному микроконтроллеру. Используя функции digitalRead() и digitalWrite(), очень просто перенести код на другой микроконтроллер. Одним из способов решения могут стать макроопределения #ifdef, с помощью которых возможно написание универсального кода, который, в зависимости от МК, будет сам решать - как ему компилироваться.

При прямом доступе к портам можно совершить ошибки. Например,строка DDRD = B11111110; оставит вывод 0 как входной. Мы помним, что на нем у нас висит приемная линия последовательного порта. Вы представляете что может случиться если мы возьмем и сделаем его как выходной? Мы нарушим работу нашего порта.

Разумеется, чтобы работать с прямым доступом к портам надо разбираться, как это работает. Ведь прямой доступ имеет определенные преимущества:

Вы можете изменить состояние сразу всех портов одновременно, не прибегая ко всяким изощренным циклам и проч. Если вы посмотрите на исходники Arduino в lib/targets/arduino/wiring.c, вы увидите, что digitalRead() и digitalWrite() представляют собой кучу строк кода, которые буду скомпилированы в несколько команд процессора. Каждая команда процессора требует один такт тактового генератора 16Мгц. Прямой доступ в портам позволяет выполнить те же операии за много меньшее количество тактов, обеспечивая высокое быстродействие.

Иногда требуется одновременно изменить состояние каких-то выводов и любая задержка, обеспечиваемая функцией digitalWrite() может привести к каким-либо проблемам. Используя регистры прямого доступа вы избегаете этих проблем.

Если вас стесняют рамки имеющейся памяти программ, то можно использовать трюки, уменьшающие итоговый размер программы. Описание цикла, изменяющего состояние портов требует большого количества строк кода. Иногда подобные вещи критичны, и именно из-за них зависит - влезет программа в МК или нет.

 

Compound Operators

 

++ (инкремент) / -- (декремент)

Описание:

Инкрементирует или декрементирует переменную

Синтаксис:

x++; // инкрементирует x на один и Возвращает: старое значение x

++x; // инкрементирует x на один и Возвращает: новое значение x

x--; // декрементирует x на один и Возвращает: старое значение x

--x; // декрементирует x на один и Возвращает: новое значение x

Параметры:

x: int или long (возможно unsigned)

Возвращает:

Оригинальное или инкрементированное/декрементированное значение переменной.

Пример:

x = 2;

y = ++x; // x теперь равен 3, y равен 3

y = x--; // x снова равен 2, y еще равен 3

 

+=, -=, *=, /=

Описание:

совершает математические действие над переменной и другой переменной или константой.

Синтаксис:

x += y; // эквивалентно выражению x = x + y;

x -= y; // эквивалентно выражению x = x - y;

x *= y; // эквивалентно выражению x = x * y;

x /= y; // эквивалентно выражению x = x / y;

Параметры:

x: либой тип переменной

y: любой тип переменной или константа

Пример:

x = 2;

x += 4; // x теперь равно 6

x -= 3; // x теперь равно 3

x *= 10; // x теперь равно 30

 

Побитовое И (&=), Побитовое ИЛИ (|=)

Битовые операторы позволяют производить вычисления на битовом уровне переменных. Они часто используются для сброса или установки определенных бит переменной. Аналогичны операторам Bitwise AND (&), Bitwise OR (|), Bitwise XOR (^) и отличаются лишь укороченным синтаксисом.

 

Побитовое И (&=)

Описание:

Оператор битовое И (&=) часто используется вместе с переменной или константой для сброса определенных битв нулевое состояние. В программировании это частенько называется сбросом битов.

Синтаксис:

x &= y; // эквивалентно x = x & y;

Параметры:

x: char, int или long

y: целочислительная константа или char, int, or long

Пример:

Для начала разберем оператор побитовое И (&)

0 0 1 1 операнд 1

0 1 0 1 операнд 2

----------

0 0 0 1 (операнд1 & операнд2) - возвращаемый результат

 

переменная побитово умноженная на 0 обнулится

myByte & B00000000 = 0;

переменная побитово умноженная на 1 останется исходной,

myByte & B11111111 = myByte;

 

Примечание: Приченяя пободные операторы удобно форматировать переменные с константами используя маску.

например: побитовое И (&=) с константой B11111100

1 0 1 0 1 0 1 0 переменная

1 1 1 1 1 1 0 0 маска

----------------------

1 0 1 0 1 0 0 0

 

x x x x x x x x переменная

1 1 1 1 1 1 0 0 маска

----------------------

x x x x x x 0 0

 

собственно:

myByte = 10101010;

myByte &= B1111100 == B10101000;

 

Побитовое ИЛИ (|=)

Описание:

Побитовое ИЛИ часто используется длу установки определенных битов в переменной.

Синтаксис::

x |= y; // эквивалентно x = x | y;

Параметры:

x: char, int или long переменные

y: целочислительные константы или char, int, long

Пример:

Рассмотрим работу оператора побитовое ИЛИ (|)

0 0 1 1 операнд1

0 1 0 1 операнд2

----------

0 1 1 1 (операнд1 | операнд2) - возвращаемый результат

 

Биты побитово сложенные с 0 не будут изменены, например:

myByte | B00000000 = myByte;

Биты, побитово сложенные с 1 будут установлены в 1:

myByte & B11111111 = B11111111;

 

Таким образом, используя маску можно устанвливать часть переменной неименяемой, например:

побитовое ИЛИ(&=) с константой B00000011

1 0 1 0 1 0 1 0 переменная

0 0 0 0 0 0 1 1 маска

----------------------

1 0 1 0 1 0 1 1

 

x x x x x x x x переменная

0 0 0 0 0 0 1 1 маска

----------------------

x x x x x x 1 1

 

Константы

 

Константы - это предопределенные значения в языке Arduino. Они делают программу более удобочитаемой.

Булевы константы: Объявленные логические уровни, верно (true), неверно (false).

Эти две константы используются для отображения правды и лжи в языке Arduino: true или false.

false определено как 0

true обычно подразумевается как 1, однако это не совсем корректно - true - это НЕ ноль. т.е. в булевом понимании -1, 2, -200 - это тоже true

Следует помнить, что true и false набираются в нижнем регистре в отличие от HIGH, LOW, INPUT, и OUTPUT.

 

Определение уровня на выводах, HIGH и LOW

При чтении/записи в цифровой вывод, состояние вывода может быть только один из двух возможных - HIGH или LOW

HIGH

Значение HIGH зависит от выбранного режима работы порта INPUT или OUTPUT. Когда вывод сконфигурирован как входной, digitalRead вернет HIGH в случае, если на выводе будет более 3В.

В случае, если вывод сконфигурирован как входной, установка HIGH при помощи digitalWrite подтянет внутренним резистором в 20к ввод к плюсу питания. Таким образом функция чтения будет возвращать HIGH до тех пор пока на вывод внешне не будет подан LOW.

В случае, если пин сконфигурирован как выходной, установка HIG с помощью digitalWrite, даст +5В на выводе. В этом случае вывод можно нагрузить, например, светодиодом, повесив его между этим выводом и землей через токоограничивающий резистор, либо между этим выводом и другим, с установленным уровнем LOW.

LOW

З начение LOW зависит от выбранного режима работы порта. Когда вывод сконфигурирован как входной, digitalRead вернет LOW при уровне напряжения на выводе менее 2В.

Когда вывод сконфигурирован как выходной, вывод подключается внутренне к 0В. Это дает возможность подключить к выводу нагрузку, например светодиод, подключенный через резистор между этим выводом и +5В.

Целочислительные константы

Обычно, цифровые константы имеют основание 10, однако в некоторых случаях требуется другая система счисления

Основание Пример Формат Комментарий

10 (десятичное) 123 нет

2 (двоичное) B1111011 добавляем 'B' работает только с 8-бит значениями(0 до 255), допустимые символы 0 и 1

8 (восьмеричное) 0173 добавляем "0" допустимые символы 0-7

16 (шестнадцатеричное) 0x7B добавляем "0x" допустимые символы 0-9, A-F, a-f

 

Пример:

101 // равен числу 101 в десятичной системе счисления ((1 * 10^2) + (0 * 10^1) + 1)

B101 // равен числу 5 в десятичной системе счисления ((1 * 2^2) + (0 * 2^1) + 1)

Двоичный формат работает только для байт (8 бит), от 0 (B0) до 255 (B11111111). Если необходимо обработать в двоичном формате int (16бит) это можно сделать в два шага:

myInt = (B11001100 * 256) + B10101010; // B11001100 старший байт

0101 // равен числу 65 в десятичной системе счисления ((1 * 8^2) + (0 * 8^1) + 1)

 

Внимание:

Возможно создание труднонаходимой ошибки, записывая незначащие нули в старших разрядах - компилятор может ошибчно принять ваше число за восьмеричное.

0x101 // равен числу 257 в десятичной системе счисления ((1 * 16^2) + (0 * 16^1) + 1)

 

U & L форматы

По умолчанию, целочислительные константы объявлены как int с соответствующими ограничесниями. Для определения таких константс другим типом данных пользуются следующими форматами записи:

'u' или 'U' определяет константу как положительную (unsigned). Например: 33u

'l' или 'L' определяет костанту в формат long. Пример: 100000L

'ul' или 'UL' определяет константу в формат unsigned long. Пример: 32767ul

 

Типы данных

 

Void

Тип void используется только для объявления функций. Он показывает, что функция не возвращает никакого значения вызвавшей ее функции.

Boolean

Может принимать одно из двух состояний - true или false (хотя и занимает целый байт ОЗУ)

От переводчика - поскольку тип boolean характерен для флагов, целесообразно использовать определенные биты какой-то переменной, етм самым более полно используя оперативную память.

 

Char

Описание:

Даный тип данных занимает 1 байт ОЗУ и хранит символ. Единичные символы выделяются в одинарные кавычки, например 'A'. Для объявления многобуквенных символьных переменных используются вдойные кавычки "ABC".

Символы хранятся в виде числа, соответсвующего по таблице ASCII определенному символу. Это значит, что с символьными переменнымии можно совершать арифметические операции. Таким образом 'A'+1 имеет значение 66, когда символу A по ASCII соответсвует 65.

Тип данных char кодирует в диапазоне от -128 до 127, т.к. является переменной типа signed. Для использования 8-бит переменной типа unsigned, используйте тип данных byte.

 

Unsigned char

Описание

символьная переменная типа unsigned занимает 1 байт памяти также как и byte.

unsigned char КОдирует числа в диапазоне от 0 до 255.

Предпочтительнее использовать тип byte вместо этого типа.

 

Byte

Описание:

byte хранит 8-бит положительное число, от 0 до 255.

 


Int

Описание:

Целочисленный тип данных. Занимает 2 байта и может хранить значения от -32 768 до 32767.

Отрицательные значения хранятся в т.н. дополнительном коде, когда старший бит показывает, что число отрицательное. При этом биты переменной инвертируются и прибавляется 1.

Unsigned int

Описание

Unsigned ints (положительное целочислительное) такая же переменная что и int, также занимает 2 байта. Однако она хранит только положительные числа, поэтому вмещает диапазон чисел от 0 до 65,535 (2^16) - 1).

 

Word

Описание

word хранит 16-бит положительное число, от 0 до 65536. Также как и unsigned int.

 

Long

Описание:

Long это расширенный тип данных целочислительной переменной. Занимает 32 бит (4 байта и может хранить числа от -2,147,483,648 до 2,147,483,647.

 

Unsigned long

Описание:

Unsigned long это расширенный тип данных положительной целочислительной переменной, занимающий 32 бит (4 байт).Может хранить положительные значения от 0 до 4,294,967,295 (2^32 - 1).

 

Float

Описание:

Тип данных для хранения чисел с плавающей точкой. Числа с плавающей точкой имеют гораздо большее разрешение чем целочисленные переменные. Такие числа могут быть величиной до 3.4028235E+38 от -3.4028235E+38. Они занимают 32 бит (4 байт) данных.

Числа с плавающей точкой не точны и операция 6,0/2,0 не всегда вернет 2,0. Вы должны учитывать погрешность при сравнении двух чисел.

Числа с плаващей точкой вычисляются гораздо медленнее чем целочисленные, поэтому при написании время-критичного кода остерегайтесь большого количества операций над переменными с плавающей точкой. Используйте функции конвертирования чисел с плавающей точкой в целочсленные для увеличения скорости работы программы.

 

Double

Описание

Double это тип данных переменной с плавающей точкой двойной точности. Однако, в Arduino на данный момент, точность double аналогична точности float - т.е. занимает 4 байта.

 

String

Описание

Строки это массивы символов, завершающиеся нулевым сиволом

Пример

Ниже представлены все правильные объявления переменных типа char.

char Str1[15];

char Str2[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o'};

char Str3[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o', '\0'};

char Str4[ ] = "arduino";

char Str5[8] = "arduino";

char Str6[15] = "arduino";

Возможности для объявления массивов

Объявление массива символов без занесения в него данных, Str1

Объявление массива символов с одной свободной ячейкой - компилятор автоматически добавит туда нулевой символ, Str2

Явное добавление нулевого символа, Str3

Инициализация массива без указания длинны, компилятор сам посчитает необходимое количество ячееек, плюс поставит нулевой символ, Str4

Инициализация массива я явным указанием длины массива и занесением в массив строковой константы, Str5

Инициализация массива, со свободным местом для более длинных строк, Str6

 

Нулевой символ

Как правило, строки заканчиваются нулевым символом (ASCII код 0). Этот симвлол указывает функции (например, Serial.print ()), что строка закончилась. В противном случае, функция будет продолжать чтение последующих байт памяти, которые фактически не являются частью строки.

Это означает, что ваша строка должна иметь место для еще одного символа, чем необходимое для умещения вашей строки. Вот почему Str2 и str5 необходимо восемь символов, хотя в "Arduino" только семь - последнее место автоматически заполняется нулевым символом. STR4 станет автоматически строкой с 8 симв<



Поделиться:


Последнее изменение этой страницы: 2016-08-15; просмотров: 610; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.221.183.34 (0.019 с.)