Arduino:Хакинг/Добавление последовательных интерфейсов (SERCOM’ов) на SAMD-плату Arduino
Содержание | Знакомство с Arduino | Продукты | Основы | Справочник языка Arduino | Примеры | Библиотеки | Хакинг | Изменения | Сравнение языков Arduino и Processing |
Добавление последовательных интерфейсов (SERCOM’ов) на SAMD-плату Arduino[1]
В этом руководстве мы объясним, как добавить больше последовательных интерфейсов (SERCOM’ов) на плату Arduino, оснащенную микропроцессором SAMD. Эти интерфейсы являются аппаратными и могут быть типов I2C, UART и SPI. Подключение дополнительных интерфейсов возможно, поскольку микроконтроллер SAMD имеет шесть встроенных модулей для последовательной коммуникации, которые можно настраивать отдельно друг от друга. На момент покупки платы настроены лишь четыре из этих модулей, поэтому оставшиеся два можно вывести на контакты платы. Это руководство как раз и объясняет, как это сделать.
Необходимое оборудование
Плата Arduino/Genuino Zero, MKRZero или MKR1000
Цепь
Для этого примера нужна только плата Arduino/Genuino.
Функции контактов
Одно из преимуществ платформы Arduino – в возможности назначить каждому контакту микроконтроллера одну из множества различных функций. Посмотреть назначения для каждого контакта можно в файле «variant.cpp». Давайте взглянем, к примеру, на такой файл к плате MKR1000.
В этой таблице за SERCOM отвечают следующие контакты:
/*
+------------+------------------+---------+---------+----------+
| Pin number | MKR Board pin | Perip.C | Perip.D | Periph.G |
| | | SERCOMx | SERCOMx | COM |
| | | (x/PAD) | (x/PAD) | |
+------------+------------------+---------+---------+----------+
| 00 | D0 | 3/00 | 5/00 | |
| 01 | D1 | 3/01 | 5/01 | USB/SOF |
| 02 | D2 | 0/02 | 2/02 | I2S/SCK0 |
| 03 | D3 | 0/03 | 2/03 | I2S/FS0 |
| 04 | D4 | | 4/02 | I2S/MCK1 |
| 05 | D5 | | 4/03 | I2S/SCK1 |
| 06 | D6 | 5/02 | 3/02 | I2S/SCK0 |
| 07 | D7 | 5/03 | 3/03 | I2S/FS0 |
+------------+------------------+---------+---------+----------+
| | SPI | | | |
| 08 | MOSI | *1/00 | 3/00 | |
| 09 | SCK | *1/01 | 3/01 | |
| 10 | MISO | *1/03 | 3/03 | I2S/SD0 |
+------------+------------------+---------+---------+----------+
| | Wire | | | |
| 11 | SDA | *0/00 | 2/00 | I2S/SD1 |
| 12 | SCL | *0/01 | 2/01 | I2S/MCK0 |
+------------+------------------+---------+---------+----------+
| | Serial1 | | | |
| 13 | RX | | *5/03 | |
| 14 | TX | | *5/02 | |
+------------+------------------+---------+---------+----------+
| 16 | A1 | | 5/00 | |
| 17 | A2 | | 5/01 | |
| 18 | A3 | | 0/00 | |
| 19 | A4 | | 0/01 | |
| 20 | A5 | | 0/02 | |
| 21 | A6 | | 0/03 | I2S/SD0 |
+------------+------------------+---------+---------+----------+
| | ATWINC1501B SPI | | | |
| 26 | WINC MOSI | *2/00 | 4/00 | |
| 27 | WINC SCK | *2/01 | 4/01 | |
| 28 | WINC SSN | 2/02 | 4/02 | |
| 29 | WINC MISO | *2/03 | 4/03 | |
+------------+------------------+---------+---------+----------+
| | ATWINC1501B PINS | | | |
| 32 | WINC WAKE | | 4/00 | |
| 33 | WINC IRQN | | 4/01 | |
+------------+------------------+---------+---------+----------+
*/
Как видите, SERCOM’ы можно вывести практически всюду. Кроме того, у вас одновременно может быть настроено более одного SERCOM’а и при этом задействовано больше одного контакта.
Как SERCOM’ы назначены по умолчанию
На гребешках платы MKR1000 можно найти интерфейсы SPI, I2C и UART, назначенные следующим образом:
- SPI / SERCOM 1:
- MOSI на контакте 8
- SCK на контакте 9
- MISO на контакте 10
- I2C / SERCOM 0:
- SDA на контакте 11
- SCL на контакте 12
- UART / SERCOM 5:
- RX на контакте 13
- TX на контакте 14
Также по умолчанию подключен еще один интерфейс SPI – он внутренне соединен с модулем WINC1500, и его контакты подключены следующим образом:
- WINC1500 SPI / SEERCOM 2:
- MOSI на контакте 26
- SCK на контакте 27
- MISO на контакте 29
Итак, убираем из таблицы уже назначенные интерфейсы, потому что наша задача – это добавление новых интерфейсов, а не изменение уже настроенных. В результате у нас остается следующее:
/*
+------------+------------------+---------+---------+----------+
| Pin number | MKR Board pin | Perip.C | Perip.D | Periph.G |
| | | SERCOMx | SERCOMx | COM |
| | | (x/PAD) | (x/PAD) | |
+------------+------------------+---------+---------+----------+
| 00 | D0 | 3/00 | 5/00 | |
| 01 | D1 | 3/01 | 5/01 | USB/SOF |
| 02 | D2 | 0/02 | 2/02 | I2S/SCK0 |
| 03 | D3 | 0/03 | 2/03 | I2S/FS0 |
| 04 | D4 | | 4/02 | I2S/MCK1 |
| 05 | D5 | | 4/03 | I2S/SCK1 |
| 06 | D6 | 5/02 | 3/02 | I2S/SCK0 |
| 07 | D7 | 5/03 | 3/03 | I2S/FS0 |
+------------+------------------+---------+---------+----------+
| 16 | A1 | | 5/00 | |
| 17 | A2 | | 5/01 | |
| 18 | A3 | | 0/00 | |
| 19 | A4 | | 0/01 | |
| 20 | A5 | | 0/02 | |
| 21 | A6 | | 0/03 | I2S/SD0 |
+------------+------------------+---------+---------+----------+
*/
Добавление нового интерфейса
Теперь давайте попробуем воспользоваться таблицей выше и добавить на плату MKR1000 новый интерфейс.
Добавление интерфейса через создание нового экземпляра класса Wire
Как видно из таблицы, контакты 0 и 1 могут управляться двумя SERCOM’ами – SERCOM3 и SERCOM5. Заглянув в даташит SAMD21, мы увидим, что SERCOM PAD0 можно использовать в качестве SDA, а SERCOM PAD1 – в качестве SCL. В скетче ниже показано, как это можно сделать:
/*
Ведомое отправляющее устройство на контактах 0 и 1 (MKR1000)
с помощью библиотеки Wire
Демонстрирует использование библиотеки Wire и создание
дополнительного экземпляра класса Wire.
Отправляет данные как ведомое устройство через интерфейс I2C/TWI.
Код написан на базе скетча «Ведущий считывает / Ведомый отправляет».
Создан 20 июня 2016 года.
Авторы:
Артуро Гуадалупи (Arturo Guadalupi; <a.guadalupi@arduino.cc>)
Сандип Мистри (Sandeep Mistry; s.mistry@arduino.cc)
*/
#include <Wire.h>
#include "wiring_private.h"
TwoWire myWire(&sercom3, 0, 1); // создаем новый экземпляр класса Wire, назначая ему контакты 0 и 1
void setup()
{
myWire.begin(2); // подключаем шину I2C с адресом #2
pinPeripheral(0, PIO_SERCOM); // назначаем контакту 0 функцию SDA
pinPeripheral(1, PIO_SERCOM); // назначаем контакту 1 функцию SCL
myWire.onRequest(requestEvent); // регистрируем событие
}
void loop()
{
delay(100);
}
// Эта функция будет выполняться, когда ведущее устройство будет
// запрашивать данные. Она зарегистрирована как событие,
// подробнее смотрите в блоке setup().
void requestEvent()
{
myWire.write("hello "); // отвечаем сообщением из 6 байтов, которые ждет ведущее устройство
}
// подключаем к SERCOM’у обработчик прерываний:
extern "C" {
void SERCOM3_Handler(void);
void SERCOM3_Handler(void) {
myWire.onService();
}
}
Здесь в двух строчках используется внутренняя функция pinPeripheral(), у которой первый аргумент – это номер контакта, а второй – функция. С ее помощью осуществляется переназначение контактов:
pinPeripheral(0, PIO_SERCOM); // назначаем контакту 0 функцию SDA
pinPeripheral(1, PIO_SERCOM); // назначаем контакту 1 функцию SCL
Эти строчки нужно поместить в блок setup(), чтобы переписать стандартное назначение контактов на плате и, образно говоря, вручить бразды правления цифровыми контактами в руки SERCOM.
Также в скетче используется функция обратного вызова:
void SERCOM3_Handler(void) {
myWire.onService();
}
Она нужна для того, чтобы добавить в скетч возможность для коммуникации по I2C, поскольку библиотеке Wire требуются прерывания.
Добавление интерфейса через создание нового экземпляра класса Serial
/*
Считывание аналоговых данных через UART на контактах 0 и 1
Считывает входные аналоговые данные на контакте A0,
печатает результат на мониторе порта.
Графическая репрезентация процесса доступна в меню,
которое открывается при нажатии в IDE Arduino на
Инструменты > Плоттер по последовательному соединению.
Подключите центральный контакт потенциометра к A0,
а боковые контакты – к +3.3V и «земле».
При помощи перемычки соедините друг с другом контакты 0 и 1.
Создан 20 июня 2016
Автор:
Артуро Гуадалупи (Arturo Guadalupi a.guadalupi@arduino.cc)
Этот пример не защищен авторским правом.
*/
#include <Arduino.h>
#include "wiring_private.h"
Uart mySerial (&sercom3, 0, 1, SERCOM_RX_PAD_1, UART_TX_PAD_0); // создаем новый экземпляр класса Uart на контактах 0 и 1
// Блок setup() запускается, когда вы нажимаете на сброс:
void setup() {
// Инициализируем последовательную коммуникацию
// на скорости 9600 бит/сек:
Serial.begin(9600);
mySerial.begin(9600);
pinPeripheral(0, PIO_SERCOM); // назначаем контакту 0 функцию RX
pinPeripheral(1, PIO_SERCOM); // назначаем контакту 1 функцию TX
}
// Блок loop() будет запускаться снова и снова:
void loop() {
// Считываем входные данные на аналоговом контакте 0:
int sensorValue = analogRead(A0);
// Печатаем считанное значение на канал mySerial,
// подключенный с зацикливанием:
mySerial.write(sensorValue);
while (mySerial.available()) {
Serial.print(mySerial.read());
}
Serial.println();
delay(1); // задержка между считываниями для стабильности
}
// Подключаем к SERCOM обработчик прерываний:
void SERCOM3_Handler()
{
mySerial.IrqHandler();
}
Как и в случае с библиотекой Wire, пишем две строчки:
pinPeripheral(0, PIO_SERCOM); // назначаем контакту 0 функцию RX
pinPeripheral(1, PIO_SERCOM); // назначаем контакту 1 функцию TX
Они нужны для того, чтобы переписать стандартные назначения для цифровых I/O контактов Arduino и вручить бразды правления в руки SERCOM.
Также в скетче используется функция обратного вызова:
void SERCOM3_Handler()
{
mySerial.IrqHandler();
}
Она нужна, чтобы добавить в скетч возможность для коммуникации по I2C, поскольку библиотека Serial тоже работает при помощи прерываний.
См.также
Внешние ссылки
Arduino продукты | |
---|---|
Начальный уровень | Arduino Uno • Arduino Leonardo • Arduino 101 • Arduino Robot • Arduino Esplora • Arduino Micro • Arduino Nano • Arduino Mini • Arduino Starter Kit • Arduino Basic Kit • MKR2UNO • TFT-дисплей Arduino |
Продвинутые функции | Arduino Mega 2560 • Arduino Zero • Arduino Due • Arduino Mega ADK • Arduino Pro • Arduino Motor Shield • Arduino USB Host Shield • Arduino Proto Shield • MKR Proto Shield • MKR Proto Large Shield • Arduino ISP • Arduino USB 2 Serial Micro • Arduino Mini USB Serial Adapter |
Интернет вещей | Arduino Yun • Arduino Ethernet • Arduino MKR1000 • Arduino WiFi 101 Shield • Arduino GSM Shield V2 • Arduino WiFi Shield • Arduino Wireless SD Shield • Arduino Wireless Proto Shield • Arduino Ethernet Shield V2 • Arduino Yun Shield • Arduino MKR1000 Bundle |
Носимые устройства | Arduino Gemma • Lilypad Arduino Simple • Lilypad Arduino Main Board • Lilypad Arduino USB • LilyPad Arduino SimpleSnap |
3D-печать | Arduino Materia 101 |
Устаревшие устройства | - |
Примеры Arduino | |
---|---|
Стандартные функции | |
Основы |
|
Цифровой сигнал |
|
Аналоговый сигнал |
|
Связь |
|
Управляющие структуры |
|
Датчики |
|
Дисплей |
Примеры, объясняющие основы управления дисплеем:
|
Строки |
|
USB (для Leonardo, Micro и Due плат) |
В этой секции имеют место примеры, которые демонстрируют использование библиотек, уникальных для плат Leonardo, Micro и Due.
|
Клавиатура |
|
Мышь |
|
Разное |