Урок 4. Основы программирования Ардуино на языке C.
02.04.2016 Автор: ЭДУАРД
C/C++
Этот урок дает минимальные знания, необходимые для программирования систем Ардуино на языке C. Можно только просмотреть его и в дальнейшем использовать как справочную информацию. Тем, кто программировал на C в других системах можно пропустить статью.
Повторю, что это минимальная информация. Описание указателей, классов, строковых переменных и т.п. будет дано в последующих уроках. Если что-то окажется непонятным, не беспокойтесь. В дальнейших уроках будет много примеров и пояснений.
Структура программы Ардуино.
Структура программы Ардуино достаточно проста и в минимальном варианте состоит из двух частей setup() и loop().
void setup() {
// код выполняется один раз при запуске программы
}
void loop() {
// основной код, выполняется в цикле
}
Функция setup() выполняется один раз, при включении питания или сбросе контроллера. Обычно в ней происходят начальные установки переменных, регистров. Функция должна присутствовать в программе, даже если в ней ничего нет.
|
|
После завершения setup() управление переходит к функции loop(). Она в бесконечном цикле выполняет команды, записанные в ее теле (между фигурными скобками). Собственно эти команды и совершают все алгоритмические действия контроллера.
Первоначальные правила синтаксиса языка C.
; точка с запятой Выражения могут содержать сколь угодно много пробелов, переносов строк. Признаком завершения выражения является символ ”точка с запятой ”.
z = x + y;
z= x
+ y;
{ } фигурные скобки определяют блок функции или выражений. Например, в функциях setup() и loop().
/* … */ блок комментария, обязательно закрыть.
/* это блок комментария */
// однострочный комментарий, закрывать не надо, действует до конца строки.
// это одна строка комментария
Переменные и типы данных.
Переменная это ячейка оперативной памяти, в которой хранится информация. Программа использует переменные для хранения промежуточных данных вычислений. Для вычислений могут быть использованы данные разных форматов, разной разрядности, поэтому у переменных в языке C есть следующие типы.
Тип данных Разрядность, бит Диапазон чисел
boolean 8 true, false
char 8 -128 … 127
unsigned char 8 0 … 255
byte 8 0 … 255
int 16 -32768 … 32767
unsigned int 16 0 … 65535
word 16 0 … 65535
long 32 -2147483648 … 2147483647
|
|
unsigned long 32 0 … 4294967295
short 16 -32768 … 32767
float 32 -3.4028235+38 … 3.4028235+38
double 32 -3.4028235+38 … 3.4028235+38
Типы данных выбираются исходя из требуемой точности вычислений, форматов данных и т.п. Не стоит, например, для счетчика, считающего до 100, выбирать тип long. Работать будет, но операция займет больше памяти данных и программ, потребует больше времени.
Объявление переменных.
Указывается тип данных, а затем имя переменной.
int x; // объявление переменной с именем x типа int
float widthBox; // объявление переменной с именем widthBox типа float
Все переменные должны быть объявлены до того как будут использоваться.
Переменная может быть объявлена в любой части программы, но от этого зависит, какие блоки программы могут ее использовать. Т.е. у переменных есть области видимости.
Переменные, объявленные в начале программы, до функции void setup(), считаются глобальными и доступны в любом месте программы.
Локальные переменные объявляются внутри функций или таких блоков, как цикл for, и могут использоваться только в объявленных блоках. Возможны несколько переменных с одним именем, но разными областями видимости.
int mode; // переменная доступна всем функциям
void setup() {
// пустой блок, начальные установки не требуются
}
void loop() {
long count; // переменная count доступна только в функции loop()
for (int i=0; i < 10;) // переменная i доступна только внутри цикла
{
i++;
}
}
При объявлении переменной можно задать ее начальное значение (проинициализировать).
int x = 0; // объявляется переменная x с начальным значением 0
char d = ‘a’; // объявляется переменная d с начальным значением равным коду символа ”a”
При арифметических операциях с разными типами данных происходит автоматическое преобразование типов данных. Но лучше всегда использовать явное преобразование.
int x; // переменная int
char y; // переменная char
int z; // переменная int
z = x + (int) y; // переменная y явно преобразована в int
Арифметические операции.
= присваиваниее
+ сложение
- вычитание
* произведение
/ деление
% остаток от деления
Операции отношения.
== равно
!= не равно
< меньше
> больше
<= меньше или равно
>= больше или равно
Логические операции.
&& логическое И
|| логическое ИЛИ
! логическое НЕ
Операции над указателями.
* косвенная адресация
& получение адреса переменной
Битовые операции.
& И
| ИЛИ
^ ИСКЛЮЧАЮЩЕЕ ИЛИ
~ ИНВЕРСИЯ
<< СДВИГ ВЛЕВО
>> СДВИГ ВПРАВО
Операции смешанного присваивания.
++ + 1 к переменной
-- - 1 к переменной
+= сложение
-= вычитание
*= умножение
/= деление
%= остаток от деления
&= битовое И
|= битовое ИЛИ
Выбор вариантов, управление программой.
Оператор IF проверяет условие в скобках и выполняет последующее выражение или блок в фигурных скобках, если условие истинно.
if (x == 5) // если x=5, то выполняется z=0
z=0;
if (x > 5) // если x > 5, то выполняется блок z=0, y=8;
{ z=0; y=8; }
IF … ELSE позволяет сделать выбор между двух вариантов.
if (x > 5) // если x > 5, то выполняется блок z=0, y=8;
{
z=0;
y=8;
}
else // в противном случае выполняется этот блок
{
z=0;
y=0;
}
ELSE IF – позволяет сделать множественный выбор
if (x > 5) // если x > 5, то выполняется блок z=0, y=8;
{
z=0;
y=8;
}
else if (x > 20) // если x > 20, выполняется этот блок
|
|
{
}
else // в противном случае выполняется этот блок
{
z=0;
y=0;
}
SWITCH CASE - множественный выбор. Позволяет сравнить переменную (в примере это x) с несколькими константами (в примере 5 и 10) и выполнить блок, в котором переменная равна константе.
switch (x) {
case 5:
// код выполняется если x = 5
break;
case 10:
// код выполняется если x = 10
break;
default:
// код выполняется если не совпало ни одно предыдущее значение
break;
}
Цикл FOR. Конструкция позволяет организовывать циклы с заданным количеством итераций. Синтаксис выглядит так:
for (действие до начала цикла;
условие продолжения цикла;
действие в конце каждой итерации) {
// код тела цикла
}
Пример цикла из 100 итераций.
for (i=0; i < 100; i++) // начальное значение 0, конечное 99, шаг 1
{
sum = sum + I;
}
Цикл WHILE. Оператор позволяет организовывать циклы с конструкцией:
while (выражение)
{
// код тела цикла
}
Цикл выполняется до тех пор, пока выражение в скобках истинно. Пример цикла на 10 итераций.
x = 0;
while (x < 10)
{
// код тела цикла
x++;
}
DO WHILE – цикл с условием на выходе.
do
{
// код тела цикла
} while (выражение);
Цикл выполняется пока выражение истинно.
BREAK – оператор выхода из цикла. Используется для того, чтобы прервать выполнение циклов for, while, do while.
x = 0;
while (x < 10)
{
if (z > 20) break; // если z > 20, то выйти из цикла
// код тела цикла
x++;
}
GOTO – оператор безусловного перехода.
goto metka1; // переход на metka1
………………
metka1:
CONTINUE - пропуск операторов до конца тела цикла.
x = 0;
while (x < 10)
{
// код тела цикла
if (z > 20) continue; // если z > 20, то вернуться на начало тела цикла
// код тела цикла
x++;
}
Массивы.
Массив это область памяти, где последовательно хранятся несколько переменных.
Объявляется массив так.
int ages[10]; // массив из 10 переменных типа int
float weight[100]; // массив из 100 переменных типа float
При объявлении массивы можно инициализировать:
int ages[10] = { 23, 54, 34, 24, 45, 56, 23, 23, 27, 28};
Обращаются к переменным массивов так:
|
|
x = ages[5]; // x присваивается значение из 5 элемента массива.
ages[9] = 32; // 9 элементу массива задается значение 32
Нумерация элементов массивов всегда с нуля.
Функции.
Функции позволяют выполнять одни и те же действия с разными данными. У функции есть:
имя, по которому ее вызывают;
аргументы – данные, которые функция использует для вычисления;
тип данных, возвращаемый функцией.
Описывается пользовательская функция вне функций setup() и loop().
void setup() {
// код выполняется один раз при запуске программы
}
void loop() {
// основной код, выполняется в цикле
}
// объявление пользовательской функции с именем functionName
type functionName(type argument1, type argument1, …, type argument)
{
// тело функции
return();
}
Пример функции, вычисляющей сумму квадратов двух аргументов.
int sumQwadr (int x, int y)
{
return(x* x + y*y);
}
Вызов функции происходит так:
d= 2; b= 3;
z= sumQwadr(d, b); // в z будет сумма квадратов переменных d и b
Функции бывают встроенные, пользовательские, подключаемые.
Очень коротко, но этих данных должно хватить для того, чтобы начать писать программы на C для систем Ардуино.
Последнее, что я хочу рассказать в этом уроке, как принято оформлять программы на C. Думаю, если вы читаете этот урок в первый раз, стоит пропустить этот раздел и вернутся к нему позже, когда будет что оформлять.