Инструкция по работе Arduino с интерфейсом SPI
Нам понадобится:
- Arduino UNO или иная совместимая плата;
- сдвиговый регистр 74HC595;
- 8 светодиодов (к примеру, вот из такого набора);
- 8 резисторов по 220 Ом (рекомендую приобрести набор резисторов с номиналами от 10 Ом до 1 МОм);
- соединительные провода (например, вот такой хороший набор);
- макетная плата;
- персональный компьютер со средой разработки Arduino IDE.
1Описание последовательного интерфейса SPI
SPI – Serial Peripheral Interface или «Последовательный периферийный интерфейс» – это синхронный протокол передачи данных для сопряжения ведущего устройства (Master) с периферийными устройствами (Slave). Ведущим устройством часто является микроконтроллер. Связь между устройствами осуществляется по четырём проводам, поэтому SPI иногда называют «четырёхпроводной интерфейс». Вот эти шины:
Название | Назначение шины SPI |
MOSI (Master Out Slave In) | линия передачи данных от ведущего к ведомым устройствам; |
MISO (Master In Slave Out) | линия передачи от ведомого к ведущему устройству; |
SCLK (Serial Clock) | тактовые импульсы синхронизации, генерируемые ведущим устройством; |
SS (Slave Select) | линия выбора ведомого устройства; когда на линии логический «0», ведомое устройство «понимает», что сейчас обращаются к нему. |
Существует четыре режима передачи данных (SPI_MODE0, SPI_MODE1, SPI_MODE2, SPI_MODE3), обусловленные сочетанием полярности тактовых импульсов (работаем по уровню HIGH или LOW), Clock Polarity, CPOL, и фазой тактовых импульсов (синхронизация по переднему или заднему фронту тактового импульса), Clock Phase, CPHA. В последнем столбце таблицы приведены поясняющие иллюстрации. На них Sample обозначены моменты, когда данные на линии должны быть готовы и считываются устройствами. Буквой Z отмечено, что состояние данных на линии неизвестно или не важно.
Режим | Полярность тактовых импульсов (CPOL) | Фаза тактовых импульсов (CPHA) | Диаграмма режима |
SPI_MODE0 | 0 | 0 | |
SPI_MODE1 | 0 | 1 | |
SPI_MODE2 | 1 | 0 | |
SPI_MODE3 | 1 | 1 |
Интерфейс SPI предусматривает несколько вариантов подключения ведомых устройств: независимое и каскадное. При независимом подключении к шине SPI ведущее устройство обращается к каждому ведомому устройству индивидуально. При каскадном подключении ведомые устройства срабатывают поочерёдно, как бы каскадом.
Виды подключения устройств для работы по интерфейсу SPI: независимое и каскадное
Установка драйверов
В Windows драйверы будут установлены автоматически, при подключении платы, если вы использовали установщик. Если вы загрузили и распаковали Zip архив или по какой-то причине плата неправильно распознана, выполните приведенную ниже процедуру.
- Нажмите на меню «Пуск» и откройте панель управления.
- Перейдите в раздел «Система и безопасность» (System and Security). Затем нажмите «Система» (System). Затем откройте диспетчер устройств (Device manager).
- Посмотрите под Порты (COM и LPT) (Ports (COM & LPT)). Вы должны увидеть открытый порт с именем «FT232R USB UART». Если раздел COM и LPT отсутствует, просмотрите раздел «Другие устройства», «Неизвестное устройство».
- Щелкните правой кнопкой мыши по порту FT232R USB UART и выберите опцию «Обновить драйверы…».
- Затем выберите опцию «Выполнить поиск драйверов на этом компьютере».
- Наконец, найдите каталог FTDI USB Drivers, который находится в папке «Drivers» программы Arduino.
- После этого Windows завершит установку драйвера.
2Реализация интерфейса SPI на платах семейства Arduino
В Arduino шины интерфейса SPI находятся на определённых портах. У каждой платы своё соответствие выводов. Для удобства выводы продублированы и вынесены также на отдельный разъём ICSP (In Circuit Serial Programming, программирование устройства, включённого в цепь, по последовательному протоколу). Обратите внимание, что на разъёме ICSP отсутствует пин выбора ведомого – SS, т.к. подразумевается, что Arduino будет использоваться как ведущее устройство в сети. Но при необходимости вы можете назначить любой цифровой вывод Ардуино в качестве SS.
На рисунке приведено стандартное соответствие выводов шинам SPI для Arduino UNO и Nano.
Реализация интерфейса SPI на платах Arduino UNO и Arduino Nano
Пример использования SPI Ардуино в проекте с датчиком давления
Для реализации проекта нам нужны Ардуино, датчик давления макетная плата и провода. Пример подключения датчика изображен на рисунке.
При помощи датчика SCP1000 возможно узнавать такие параметры как давление и температура и передать эти значения через SPI.
Основные элементы скетча программы
В первую очередь в коде прописываются регистры датчика при помощи setup(). С устройства возвращаются несколько значений – одно в 19 бит для полученного давления, другое в 16 бит – для температуры. После этого происходит считывание двух температурных байтов и считывание давления в два этапа. Сначала программа берет три старших бита, затем следующие 16 бит, после чего при помощи побитового сдвига происходит объединение этих двух значений в одно. Настоящее давление – это 19-тиразрядное значение, деленное на 4.
const int PRESSURE = 0x1F; // первый этап определения давления (выявляются три старших бита)
const int PRESSURE_LSB = 0x20; // второй этап, в котором определяются 16 бит для давления
const int TEMPERATURE = 0x21; //16 бит для температуры
Для чтения данных температуры и преобразования ее в градусы Цельсия используется следующий элемент кода:
int tempData = readRegister(0x21, 2);
float realTemp = (float)tempData / 20.0; // чтобы определить реальное значение температуры в Цельсиях, нужно полученное число разделить на 20
Serial.print(“Temp
=»); Serial.print(realTemp); Считывание битов давления и объединение их: byte pressure_data_high = readRegister(0x1F, 1); pressure_data_high &= 0b00000111; unsigned int pressure_data_low = readRegister(0x20, 2); long pressure = ((pressure_data_high << 16) | pressure_data_low) / 4; //определение давления в Паскалях.
3Стандартная библиотека для работы по интерфейсу SPI
Для Arduino написана специальная библиотека, которая реализует протокол SPI. Она устанавливается вместе со средой разработки Arduino IDE. Подключается она так: в начале программы добавляем #include SPI.h.
Чтобы начать работу по протоколу SPI, нужно задать настройки и затем инициализировать протокол с помощью процедуры SPI.beginTransaction(). Можно выполнить это одной инструкцией: SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE0))
Это значит, что мы инициализируем протокол SPI на частоте 14 МГц, передача данных идёт, начиная с MSB (наиболее значимого бита), в режиме SPI_MODE0.
После инициализации выбираем ведомое устройство, переводя соответствующий пин SS в состояние LOW. Затем передаём ведомому устройству данные командой SPI.transfer(). После передачи возвращаем SS в состояние HIGH.
Временная диаграмма работы интерфейса SPI
Работа с протоколом завершается командой SPI.endTransaction().
Желательно минимизировать время выполнения передачи между инструкциями SPI.beginTransaction() и SPI.endTransaction(), чтобы не возникло накладок, если другое устройство попробует инициализировать передачу данных, используя другие настройки.
Если вы планируете в своём скетче использовать стандартные пины Arduino, можно не описывать их в начале программы, т.к. они уже определены в самой библиотеке и имеют следующие имена:
#define PIN_SPI_SS (10) #define PIN_SPI_MOSI (11) #define PIN_SPI_MISO (12) #define PIN_SPI_SCK (13)
Данные пины определены в файле pins_arduino.h , который находится по пути %programfiles%\arduino-(версия)\hardware\arduino\avr\variants\ (если вы устанавливали программу в стандартное расположение). То есть, например, чтобы опустить пин выбора ведомого в состояние «0», можно написать:
digitalWrite(PIN_SPI_SS, LOW);
Avrdudeprog
Avrdudeprog – утилита от русского программиста, являющаяся удобной оболочкой для avrdudue. Скачать AVRDUDE_PROG можно с официального сайта (прямая ссылка на загрузку, на всякий случай зеркало на моём ЯД и FTP этого сайта). В рамках этого урока, программа умеет следующее:
- Чтение/запись/очистка flash памяти
- Чтение/запись/очистка eeprom памяти
- Полная очистка чипа
- Калькулятор фьюзов и локбитов (чтение/запись)
Более подробный обзор на avrdudeprog можно посмотреть здесь. Давайте посмотрим на калькулятор фьюзов. Выбираем свой микроконтроллер и программатор (можно добавить другие модели микроконтроллеров и программаторов, читай тут). Переходим во вкладку Fuses, нажимаем прочитать. При успешном чтении увидим текущий набор настроек своего чипа. Можно их поменять и загрузить. Важно! Галку инверсные биты не трогаем! Лок-биты и отключение RST заблокирует микроконтроллер, не трогайте их, если такой цели нет! Можно загружать прошивку или загрузчик из .hex файла, указав путь к ней на первой вкладке в окне Flash. Очень удобная утилита для низкоуровневой работы с МК.
4Подключение сдвигового регистра к Arduino
Рассмотрим практическое применение интерфейса SPI. Будем зажигать светодиоды, управляя 8-битным сдвиговым регистром по шине SPI. Подключим к Arduino сдвиговый регистр 74HC595. К каждому из 8-ми выходов регистра через ограничительный резистор подключим по светодиоду номиналом 220 Ом. Схема приводится на рисунке.
Схема подключения сдвигового регистра 74HC595 к Arduino
Питание модуля
Arduino Nano может работать с разных источников питания, его можно подключить как через Mini-B USB компьютера, или от обычного нерегулируемого 6-20 вольт (pin 30), или регулируемого 5 вольт (pin 27). Плата автоматически выберет питание с самым высоким напряжением.
- Через mini-USB или microUSB при подключении к компьютеру;
- Через внешний источник питания, напряжение 6-20В.
Внешнее питание стабилизируется благодаря LM1117IMPX-5.0 с напряжением 5В. Когда подключение происходит через USB используется диод Шоттки.
5Скетч для управления сдвиговым регистром по интерфейсу SPI
Напишем скетч, реализующий «бегущую волну», последовательно зажигая светодиоды, подключённые к выходам сдвигового регистра.
#include const int pinSelect = 8; // пин выбора регистра
void setup() {
SPI.begin(); // инициализация интерфейса SPI pinMode(pinSelect, OUTPUT); // digitalWrite(pinSelect, LOW); // выбор ведомого устройств (регистра) SPI.transfer(0); // очищаем содержимое регистра digitalWrite(pinSelect, HIGH); // конец передачи Serial.begin(9600);
}void loop() {
for (int i=0; i}
Сначала подключим библиотеку SPI и инициализируем интерфейс SPI. Определим пин 8 как пин выбора ведомого устройства SS. Очистим сдвиговый регистр, послав в него значение «0». Инициализируем последовательный порт.
Чтобы зажечь определённый светодиод с помощью сдвигового регистра, нужно подать на его вход 8-разрядное число. Например, чтобы загорелся первый светодиод – подаём двоичное число 00000001, чтобы второй – 00000010, чтобы третий – 00000100, и т.д. Эти двоичные числа при переводе в десятичную систему счисления образуют такую последовательность: 1, 2, 4, 8, 16, 32, 64, 128 и являются степенями двойки от 0 до 7.
Соответственно, в цикле loop() по количеству светодиодов делаем пересчёт от 0 до 7. Функция pow(основание, степень) возводит 2 в степень счётчика цикла. Микроконтроллеры не очень точно работают с числами типа «double», поэтому для преобразования результата в целое число используем функцию округления round(). И передаём получившееся число в сдвиговый регистр. Для наглядности в монитор последовательного порта выводятся значения, которые получаются при этой операции: единичка «бежит» по разрядам – светодиоды загораются волной.
Числа, посылаемые в сдвиговый регистр 74HC595
Таймеры (ШИМ)
Выводы таймеров: в микроконтроллере, помимо обычного вычислительного ядра, с которым мы работаем, находятся также “хардварные” счётчики, работающие параллельно со всем остальным железом. Эти счётчики также называют таймерами, хотя к таймерам они не имеют никакого отношения: счётчики буквально считают количество тиков, которые делает кварцевый генератор, задающий частоту работы для всей системы. Зная частоту генератора (обычно 16 МГц) можно с очень высокой точностью определять интервалы времени и делать что-то на этой основе. Какой нам прок от этих счётчиков? “Из коробки” под названием Arduino IDE мы имеем несколько готовых, основанных на таймерах инструментов (функции времени, задержек, измерения длин импульсов и другие).
В этой статье речь идёт о пинах и выходах, о них и поговорим: у каждого счётчика есть два выхода на GPIO. У нано (у МК ATmega328p) три счётчика, соответственно 6 выходов. Одной из возможностей счётчиков является генерация ШИМ сигнала, который и выводится на соответствующие GPIO. Для нано это D пины 5 и 6 (счётчик 0), 9 и 10 (таймер 1) и 3 и 11 (таймер 2). ШИМ сигналу посвящен отдельный урок, сейчас просто запомним, что с его помощью можно управлять яркостью светодиодов, скоростью вращения моторчиков, мощностью нагрева спиралей и многим другим. Но нужно помнить, что ограничение по току в 40 мА никуда не делось и питать от пинов ничего мощнее светодиодов нельзя.
6«Бегущая волна» из светодиодов
Светодиоды загораются по очереди, и мы наблюдаем бегущую «волну» из огоньков. Управление светодиодами осуществляется с помощью сдвигового регистра, к которому мы подключились по интерфейсу SPI. В результате для управления 8-ю светодиодами задействованы всего 3 вывода Arduino. Если бы мы подключали светодиоды напрямую к цифровым портам Arduino, нам бы потребовалось для каждого светодиода использовать отдельный порт.
Мы изучили самый простой пример работы Arduino с шиной SPI. Более подробно рассмотрим работу нескольких сдвиговых регистров при независимом и каскадном подключениях в отдельной статье.
Выбор платы и порта
Откройте Arduino IDE. Из меню Инструменты>Плата выбирается Arduino/Genuino Mega or Mega 2560.
Выберите процессор/микроконтроллер платы, обычно это ATmega2560. Из меню Инструменты>Процессор выбирается ATmega2560 (Mega 2560).
Выберите последовательное устройство платы в меню Инструменты>Порт. Скорее всего, это COM3 (Arduino/Genuino Mega or Mega 2560) или выше (COM1 и COM2 обычно зарезервированы). Чтобы узнать, вы можете отключить свою плату и повторно открыть меню; запись, которая исчезает, должна быть Arduino или Genuino Mega. Подсоедините плату и выберите этот последовательный порт.
Если у вас модель Arduino Mega 2560 CH340G, то лучше использовать программатор Arduino as ISP.
Имеется возможность не использовать загрузчик и запрограммировать микроконтроллер через выводы ICSP (внутрисхемное программирование).
Программирование фьюз-битов на микроконтроллерах ATmega
Программатор Arduino ISP
можно использовать для программирования фьюз-битов микроконтроллеров
ATmega
. Программирование фьюз-битов позволяет конфигурировать встроенные периферийные устройства и поведение микроконтроллера. К примеру, можно задать тактовую частоту, запрограммировать сторожевой таймер и многое другое. Впрочем, это требует опыта и внимания, поскольку если настроить фьюз-биты неправильно, то микроконтроллер перестанет работать, а восстановить его может быть очень сложно.
- Getting Started with the Arduino ISP // Retired
iОнлайн
В прошлой статье про обзор рынка китайских ардуино я писал про китайские Arduino ProMini. Особенность этих плат состоит в том, что их нельзя подключить к компьютеру напрямую. Для подключения Arduino ProMini необходимо использовать USB-TTL преобразователь. Собственно этим устройствам и посвящена моя статья. Как всегда, я описываю только те устройства, которые покупал лично. Это не реклама. Просто делюсь информацией с миром, о том где их можно купить и какие я использовал. Это не истина в последней инстанции, у каждого может быть свое мнение. Кому интересно, добро пожаловать под кат.
И так. На сегодняшний день рынок USB-TTL преобразователей очень обширный. Есть куча разновидностей этих самых переходников. Основная их задача – подружить микроконтроллер и компьютер. Наиболее часто встречающиеся USB-FTDI и USB-TTL. Если говорить про платформу arduino, то иногда возникает надобность в USBASP / USBISP преобразователе. По большому счету USB-FTDI это тот же USB-TTL все они просто построены на базе разных чипов и по большому счету в большинстве случаев обладают одинаковым функционалом, что для обычного радиолюбителя делает их одинаковыми. Остановимся на USB-TTL преобразователях по подробнее.
И так. На сегодняшний день на нашем и китайском рынке USB-TTL преобразователи широко представлены на базе следующих чипов: MAX3232, FT232, CH340, CP2102. Мне довелось поработать с программаторами на последних двух чипах. Программаторы на чипе MAX меня не интересовали, т.к. попадались только с COM портом для подключения к ПК, что значительно сужало круг компов к которому его можно подключить. Про программаторы на FT232 я читал не очень хорошие отзывы, так что решил не рисковать. Не факт, что они такие уж и плохие, просто я решил с ними не связываться. Короче, дальше рассказ пойдет о программаторах на чипах CH340, CP2102.
Начнем с программатора на чипе CH340. Устройство примечательно тем, что данный чип используется на китайских клонах Arduino Nano, NodeMCU v3, Wemos D1 и прочих. Что позволяет в некотором роде назвать его родным для этой платформы. Хотя встречаются NodeMCU и Wemos и c USB-TTL на базе CP2102.
USB-TTL на базе CH340
USB-TTL на базе CH340
На фото представлены программаторы на базе чипа CH340 производства компании RobotDyn. Это российская компания, которая занимается разработкой устройств, а китайцы их для них делают. По большому счету нормальные качественные адаптеры. К отличительным особенностям данных образцов можно отнести возможность работы с логиками 3,3 и 5 Вольт. Наличие вывода RST для подключения к Arduino Promini чтобы осуществлять ввод ее в режим заливки прошивки. Это бывает полезно. Сами знаете, не всегда удается перезагрузить плату в нужный момент чтобы она начала шиться.
По умолчанию драйверов в операционной системе для данного адаптера нет. Так что Вам понадобится их дополнительно скачать и установить. Чтобы не заставлять вас заниматься поисками нужных драйверов, я обо всем позаботился. Нажмите “” и скачайте драйверы с моего репозитория на GITHUB. Подборка драйверов делалась с сайтов производителей. В подборке драйвера для Windows, Linux, Mac OS.
Для работы с данным модулем на Windows нужно ставить драйверы. В комплекте еще идут и драйверы на MAC OS X. Так вот, почему-то на MAC OS этот преобразователь заработал вообще без установки драйверов. Я просто подключил его к моему macbook и все заработало. Из чего я делаю вывод, что на mac OS X не всегда требуется установка драйвера. Есть шанс, что я ставил драйвер когда-то давно, а потом забыл. Так что рекомендую проверить, прежде чем плясать с бубном
Купить такие адаптеры можно по ссылкам:
USB-TTL адаптер на базе CH340 от RobotDYN c обычным USB USB-TTL адаптер на базе CH340 от RobotDYN c Micro USB
Теперь перейдем к адаптерам на базе чипа CP2102. Мой адаптер выглядит следующим образом:
USB-TTL на базе CP2102
USB-TTL на базе CP2102
У данного переходника. Я имею в виду конкретно мой экземпляр, а не все модули на таких чипах, отсутствует пин RST, ч помощью которого можно автоматом перезагружать ардуинки. В остальном по компоновке он схож с предыдущей моделью. Ну а по функциям, практически одинаков. Разве что это китайский нонейм. Но тем не менее прекрасно работает и свои функции выполняет. Забавно, я купил один такой модуль на пробу, а потом в том же магазине заказал второй. Так вот первый пришел в термоусадке, а второй уже без. По ходу китайцы решили чутка сэкономить.
Касаемо драйверов. Для работы на OS Windows 10 они мне не понадобились. Устройство определилось сразу. Но опять таки, может когда-то я их случайно поставил. Вот ссылка “” они тоже расположены в моем репозитории на GITHUB. Если с виндой проблем не возникло, то проблемы возникли с Mac OS X. Что я только не делал, какие мануалы не пробовал, переходник не определился. На всякий случай, в репозитории есть драйвера и под mac os. Может для Вас они будут полезны.
Купить такие адаптеры можно по ссылкам:
USB-TTL адаптер на базе CP2102 Магазин:GREAT WALL Electronics Co., Ltd. USB-TTL адаптер на базе CP2102 Магазин:WAVGAT Store
Выше я привел информацию о самых распространенных программаторах. Но есть и более специфические модели. Иногда так бывает, что ардуинки ломаются. Например, после неудачно перепрошивки слитает загрузчик (bootloader). Что в таком случае делать? Или вот вам еще задачка. У нас имеется 3Д принтер Ender 3, на который нужно залить прошивку, однако, на его плате загрузчик вовсе не прошит, что в таком случае делать? Ну и еще вариант. Вы решили осваивать новые горизонты и приобрели плату на базе чипа STM32F103C8T6, вам надо зашить правильный загрузчик для работы с Arduino IDE. Для таких задач обычные USB-TTL конвертеры не всегда подходят. Тогда приходится прибегать к колхозингу с Arduino Uno, либо обзаводиться нормальным программатором.
Для решения таких задач я приобрел 2 программатора:
Программатор ST-LINK
Этот программатор я приобретал для для прошивки плат с STM32. так называемый ST-Link
А вот этот программатор я приобретал для прошивки загрузчиков в ардуины и платы 3Д принтеров (например для прошивки Ender 3):
USB ASP программатор
Программатор шел в комплекте со шлейфом на 10 контактов, однако, не на всех платах есть выводы на 10 контактов. Для того чтобы не париться, я дополнительно приобрел переходник:
Как позже выяснилось, оба эти программатора взаимозаменяемы. И не просто взаимозаменяемы, но и могут быть перепрошиты друг в друга. Так что по большему счету достаточно одного. Однако прошивка этих штук, это уже другая история.
Кстати, применение этих программаторов позволяет зашивать в ардуины прошивки без загрузчика и работать с микроконтроллерами на более низких уровнях. Шифровать прошивки, а так же устанавливать разного рода защиты, но это уже функционал для гуру.
Должен предупредить, что для работы и этих программаторов нужны драйвера. .
К сожалению, у меня пока не дошли руки для того чтобы с ними серьезно поработать. Но я решил запастись ими заранее, если вдруг понадобится, то чтобы они были под рукой. Ибо у нас таких штук не найти, е если найдешь, то будут они стоить не дешево. Вот ссылки на покупку этих программаторов по нормальным ценам:
USBASP адаптер Магазин:GREAT WALL Electronics Co., Ltd. USBASP адаптер Магазин:WAVGAT Store Переходник для USBASP адаптера Магазин:WAVGAT Store ST-Link адаптер Магазин:GREAT WALL Electronics Co., Ltd. ST-Link адаптер Магазин:WAVGAT Store
Ну а теперь пара слов о подключении USB-TTL преобразователей на базе чипов CH340 и CP2102. Пускай мы будем подключать к компьютеру Arduino ProMini (с напряжением 5 Вольт). Для этого нужно подключить ардуинку как показано на схеме:
С питанием все просто. + программатора соединяем с + ардуины. – программатора (GND) соединяем с – ардуины (GND). RX программатора соединяем c TX ардуины, TX программатора соединяем с RX ардуины. Все, теперь можно подключать устройство к компьютеру и прошивать.
Я рассмотрел общую схему подключения. Ну а дальше, заходите в Arduino IDE и заливаете свой скетч.
Чистого Вам кода и стабильной работы вашего железа.