Рейтинговые книги
Читем онлайн Программируем Arduino. Основы работы со скетчами - Монк Саймон

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 12 13 14 15 16 17 18 19 20 ... 47

Этот пример генерирует точно такой же сигнал в форме синусоиды, но уже с частотой 4,38 кГц, то есть работает более чем в 14 раз быстрее.

Таблицу синусов можно рассчитать разными способами. Можно сгенерировать числа по обычной формуле в электронной таблице или написать скетч, который будет выводить числа в монитор последовательного порта, откуда их можно скопировать и вставить в другой скетч. Далее приводится версия скетча sketch_04_03_sin, которая выводит значения один раз в монитор последовательного порта:

// sketch_-4_05_sin_print

float angle = 0.0;

float angleStep = PI / 32.0;

void setup()

{

  Serial.begin(9600);

  Serial.print("byte sin64[] = {");

  while (angle < 2 * PI)

  {

    int x = (int)(sin(angle) * 127) + 127;

    Serial.print(x);

    angle += angleStep;

    if (angle < 2 * PI)

    {

      Serial.print(", ");

    }

  }

  Serial.println("};");

}

void loop()

{

}

Открыв окно монитора порта, вы увидите сгенерированную последовательность чисел (рис. 4.1).

Рис. 4.1. Использование скетча для получения массива чисел

Быстрый ввод/вывод

В этом разделе мы посмотрим, как увеличить скорость включения и выключения цифровых выходов. Мы увеличим максимальную частоту с 73 кГц почти до 4 МГц.

Простая оптимизация кода

Начнем с простого кода, включающего и выключающего цифровой выход с помощью digitalWrite:

// sketch_04_05_square

int outPin = 10;

int state = 0;

void setup()

{

  pinMode(outPin, OUTPUT);

}

void loop()

{

  digitalWrite(outPin, state);

  state = ! state;

}

Если запустить этот скетч и подключить осциллограф или частотомер к цифровому контакту 10, вы получите частоту чуть выше 73 кГц (мой осциллограф показал 73,26 кГц).

Прежде чем сделать большой шаг в направлении непосредственного управления портом, можно попробовать немного оптимизировать программный код скетча. Прежде всего, ни одна из переменных не обязана иметь тип int, их вполне можно объявить с типом byte. Это изменение увеличит частоту до 77,17 кГц. Далее переменную с номером контакта можно сделать константой, добавив слово const перед объявлением переменной. Это изменение увеличит частоту до 77,92 кГц.

В главе 2 вы узнали, что функция loop — это не просто цикл while, так как дополнительно проверяет наличие входящих данных в последовательном порте. То есть следующим шагом в направлении увеличения производительности может стать отказ от функции loop и перенос кода в setup. Скетч, в котором выполнены все описанные изменения, приводится ниже:

// sketch_04_08_no_loop

const byte outPin = 10;

byte state = 0;

void setup()

{

  pinMode(outPin, OUTPUT);

  while (true)

  {

    digitalWrite(outPin, state);

    state = ! state;

  }

}

void loop()

{

}

В результате всего этого мы получили увеличение максимальной частоты до 86,39 кГц.

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

Таблица 4.2. Увеличение производительности простого программного кода

Действие

Скетч

Частота, кГц

Исходная версия

04_05

72,26

Объявление с типом byte вместо int

04_06

77,17

Использование константы с номером контакта вместо переменной

04_07

77,92

Перенос содержимого loop в setup

04_08

86,39

Байты и биты

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

На рис. 4.2 показано, как связаны биты и байты.

Рис. 4.2. Биты и байты

Бит (в английском языке bit, происходит от binary digit — двоичная цифра) может иметь одно из двух значений — 0 или 1. Байт — это коллекция из 8 битов. Так как каждый из битов в байте может иметь значение 1 или 0, всего возможно 256 разных комбинаций битов в байте. Байт можно использовать для представления любых чисел в диапазоне от 0 до 255.

Каждый бит можно использовать также для обозначения состояния «включено» или «выключено». То есть, чтобы включить или выключить подачу напряжения на какой-то контакт, нужно установить или сбросить некоторый бит.

Порты в ATmega328

На рис. 4.3 изображены порты в микроконтроллере ATmega328 и то, как они связаны с контактами на плате Arduino Uno.

Рис. 4.3. Порты в ATmega328

Каждый порт не случайно имеет по 8 бит (байт), хотя в портах B и C используется только по 6 бит. Каждый порт управляется тремя регистрами. Регистр можно считать специальной переменной, позволяющей присваивать ей значения и читать значение из нее. На рис. 4.4 изображены регистры для порта D.

Рис. 4.4. Регистры для порта D

Регистр DDRD (Data Direction Register D — регистр D направления передачи данных) имеет 8 бит, каждый из которых определяет режим работы соответствующего контакта — вход или выход. Если бит установлен в значение 1, контакт работает как выход, в противном случае — как вход. Этим регистром управляет функция pinMode. Регистр PORTD используется для установки выходного напряжения на выходе, то есть digitalWrite устанавливает соответствующий бит, 1 или 0, чтобы установить на указанном контакте уровень напряжения HIGH или LOW.

Последний регистр называется PIND (Port Input D — вход порта D). Читая содержимое этого регистра, можно определить, на какие контакты подано напряжение HIGH, а на какие — LOW.

Каждый из трех портов имеет свои три регистра, для порта B они называются DDRB, PORTB и PINB, а для порта C — DDRC, PORTC и PINC.

Очень быстрый вывод цифровых сигналов

Следующий скетч обращается к портам напрямую, без применения pinMode и digitalWrite:

// sketch_04_09_square_ports

byte state = 0;

void setup()

{

  DDRB = B00000100;

  while (true)

  {

    PORTB = B00000100;

    PORTB = B00000000;

  }

}

void loop()

{

}

Скетч должен переключать контакт D10, который связан с портом B, поэтому вначале контакт настраивается на работу в режиме выхода, для чего третий бит справа в регистре DDRB устанавливается в 1. Обратите внимание на то, что B00000100 — это двоичная константа. В главном цикле мы сначала устанавливаем тот же бит в 1, а затем сбрасываем его в 0. Установка бита производится как простое присваивание значения регистру PORTB, как если бы это была обычная переменная.

Этот скетч способен генерировать сигнал с частотой 3,97 МГц (рис. 4.5) — почти 4 млн импульсов в секунду, что почти в 46 раз быстрее, чем с использованием digitalWrite.

Рис. 4.5. Сигнал с частотой 4 МГц, сгенерированный платой Arduino

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

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

1 ... 12 13 14 15 16 17 18 19 20 ... 47
На этой странице вы можете бесплатно читать книгу Программируем Arduino. Основы работы со скетчами - Монк Саймон бесплатно.
Похожие на Программируем Arduino. Основы работы со скетчами - Монк Саймон книги

Оставить комментарий