- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Программируем Arduino. Основы работы со скетчами - Монк Саймон
Шрифт:
Интервал:
Закладка:
Таблица 9.3. Вспомогательные функции
Функция
Описание
SPI.setClockDivider(SPI_CLOCK_DIV64)
Выполняет деление тактовой частоты (по умолчанию равна 4 МГц) на 2, 4, 8, 16, 32, 64 или 128
SPI.setBitOrder(LSBFIRST)
Устанавливает порядок передачи битов LSBFIRST (от младшего к старшему) или MSBFIRST (от старшего к младшему). По умолчанию используется порядок MSBFIRST
SPI.setDataMode(SPI_MODE0)
Возможные значения аргументов этой функции от SPI_MODE0 до SPI_MODE3. Определяют полярность и фазу тактового сигнала. Обычно нет необходимости изменять эту настройку, если только документация не требует установить какой-то определенный режим работы для организации обмена с ведомым устройством
Объединенные передача и прием происходят в функции transfer. Эта функция посылает байт данных и возвращает байт данных, принятый в процессе передачи:
byte sendByte = 0x23;
byte receiveByte = SPI.transfer(sendByte);
Поскольку диалог с периферией обычно имеет форму запроса со стороны ведущего и ответа со стороны ведомого, часто последовательно выполняются две передачи данных: одна — запрос, другая (возможно, во время передачи нулей) — ответ периферийного устройства. Вы увидите, как это происходит, в следующем примере.
Пример SPI
Этот пример демонстрирует взаимодействие платы Arduino с интегральной микросхемой восьмиканального АЦП MCP3008, добавляющего еще восемь 10-битных аналоговых входов. Эта микросхема стоит очень недорого и легко подключается к плате. На рис. 9.6 изображена схема подключения микросхемы к плате Arduino с использованием макетной платы и нескольких проводов. Переменное сопротивление служит для изменения уровня напряжения на аналоговом входе 0 между 0 и 5 В.

Рис. 9.6. Схема соединения компонентов для примера SPI
Ниже приводится скетч для этого примера:
// sketch_09_01_SPI_ADC
#include <SPI.h>
const int chipSelectPin = 10;
void setup()
{
Serial.begin(9600);
SPI.begin();
pinMode(chipSelectPin, OUTPUT);
digitalWrite(chipSelectPin, HIGH);
}
void loop()
{
int reading = readADC(0);
Serial.println(reading);
delay(1000);
}
int readADC(byte channel)
{
unsigned int configWord = 0b11000 | channel;
byte configByteA = (configWord >> 1);
byte configByteB = ((configWord & 1) << 7);
digitalWrite(chipSelectPin, LOW);
SPI.transfer(configByteA);
byte readingH = SPI.transfer(configByteB);
byte readingL = SPI.transfer(0);
digitalWrite(chipSelectPin, HIGH);
// printByte(readingH);
// printByte(readingL);
int reading = ((readingH & 0b00011111) << 5)
+ ((readingL & 0b11111000) >> 3);
return reading;
}
void printByte(byte b)
{
for (int i = 7; i >= 0; i--)
{
Serial.print(bitRead(b, i));
}
Serial.print(" ");
}
Функция printByte использовалась на этапе разработки для вывода двоичных данных. Несмотря на то что Serial.print может выводить двоичные значения, она не добавляет ведущие нули, что немного усложняет интерпретацию данных. Функция printByte, напротив, всегда выводит все 8 бит.
Чтобы увидеть данные, поступающие от микросхемы MCP3008, уберите символы // перед двумя вызовами printByte, и данные появятся в окне монитора последовательного порта.
Наиболее интересный для нас код сосредоточен в функции readADC, которая принимает номер канала АЦП (от 0 до 7). Прежде всего нужно выполнить некоторые манипуляции с битами, чтобы создать конфигурационный байт, определяющий вид преобразования аналогового сигнала и номер канала.
Микросхема поддерживает два режима работы АЦП. В одном выполняется сравнение двух аналоговых каналов, а во втором, несимметричном режиме (который используется в этом примере), возвращается значение, прочитанное из указанного канала, как в случае с аналоговыми входами на плате Arduino. В документации к MCP3008 (http://ww1.microchip.com/downloads/en/DeviceDoc/21295d.pdf) указывается, что в настроечной команде должны быть установлены четыре бита: первый бит должен быть установлен в 1, чтобы включить несимметричный режим, следующие три бита определяют номер канала (от 0 до 7).
Микросхема MCP3008 не поддерживает режим побайтовой передачи, в котором действует библиотека SPI. Чтобы MCP3008 распознала эти четыре бита, их нужно разбить на два байта. Далее показано, как это делается:
unsigned int configWord = 0b11000 | channel;
byte configByteA = (configWord >> 1);
byte configByteB = ((configWord & 1) << 7);
Первый байт конфигурационного сообщения содержит две единицы, первая из которых может не понадобиться, а вторая — это бит режима (в данном случае несимметричного). Другие два бита в этом байте — старшие два бита номера канала. Оставшийся бит из этого номера передается во втором конфигурационном байте как самый старший бит.
Следующая строка устанавливает уровень LOW в линии выбора ведомого устройства, чтобы активировать его:
digitalWrite(chipSelectPin, LOW);
После этого отправляется первый конфигурационный байт:
SPI.transfer(configByteA);
byte readingH = SPI.transfer(configByteB);
byte readingL = SPI.transfer(0);
digitalWrite(chipSelectPin, HIGH);
Аналоговые данные не будут передаваться обратно, пока не будет отправлен второй байт. 10 битов данных из АЦП разбиты на два байта, поэтому, чтобы подтолкнуть отправку оставшихся данных, выполняется передача нулевого байта.
Затем в линии выбора ведомого устанавливается уровень HIGH как признак того, что передача завершена.
Полученное 10-битное значение пересчитывается, как показано в следующей строке:
int reading = ((readingH & 0b00011111) << 5)
+ ((readingL & 0b11111000) >> 3);
Каждый из двух байт содержит пять бит данных из десяти. Первый байт содержит данные в пяти младших битах. Все остальные биты, кроме этих пяти, маскируются, и затем выполняется сдвиг 16-битного значения int влево на пять разрядов. Младший байт содержит остальные данные в пяти старших битах. Они также выделяются маской, сдвигаются вправо на три разряда и прибавляются к 16-битному значению int.
Для проверки откройте монитор последовательного порта. Вы должны увидеть, как в нем появляются некоторые данные. Если повернуть шток переменного сопротивления по часовой стрелке, чтобы увеличить напряжение на аналоговом входе с 0 до 5 В, вы должны увидеть картину, похожую на рис. 9.7. Первые два двоичных числа — это два байта, полученных от MCP3008, а последнее десятичное число — это аналоговое значение между 0 и 1023.

Рис. 9.7. Просмотр сообщений в двоичном виде
В заключение
Организовать взаимодействие через интерфейс SPI без применения библиотеки очень непросто. Вам придется пройти тернистый путь проб и ошибок, чтобы добиться нужного результата. Занимаясь отладкой любого кода, всегда начинайте со сбора информации и исследования принимаемых данных. Шаг за шагом вы нарисуете полную картину происходящего и затем сможете сконструировать код, помогающий достичь желаемого результата.
В следующей главе мы исследуем последний стандартный интерфейс, поддерживаемый Arduino, — последовательный порт ТТЛ. Это стандартный вид связи «точка–точка», а не шина, но тем не менее очень удобный и широко используемый механизм обмена данными.
10. Программирование последовательного интерфейса