Модуль Metro - Расширитель выводов.
Техническое описание: Данная страница содержит подробное техническое описание модуля Metro - Расширитель выводов и раскрывает работу с модулем через его регистры.
Ознакомиться с пользовательским описанием модуля и примерами работы с библиотекой iarduino_Metro можно на странице Wiki - Расширитель выводов (Metro-модуль).
Аналоги: Аналогом модуля Metro - Расширитель выводов является Trema модуль - Расширитель выводов I2C-flash который построен на том же чипе, имеет те же регистры и принцип работы, но выполнен в другом формфакторе, использует только выводы шины I2C и работает с другой библиотекой.
Основным отличием модуля Metro от Trema модуля заключается в том, что у первого модуля 4 вывода GPIO, а у второго 8.
Назначение:
Модуль Metro - Расширитель выводов - является устройством ввода/вывода с подключением по шине I2С.
К одной шине I2C можно подключить более 100 модулей.
Модуль можно использовать в любых проектах где требуется большое число выводов, как цифровых, так и аналоговых. Модуль может управлять сервоприводами.
Описание:
Модуль построен на базе микроконтроллера STM32F030F4 и снабжен собственным стабилизатором напряжения. У модуля Metro имеются 4 вывода GPIO, (у Trema модуля их 8) каждый из которых может работать в качестве: цифрового входа, цифрового выхода или аналогового входа. Первые 4 вывода позволяют устанавливать сигнал ШИМ, они же могут работать с сервоприводами. Управление выводами, их конфигурирование, запись и чтение, осуществляется через регистры модуля. Доступ к регистрам модуля осуществляется по шине I2C.
С помощью регистров модуля можно:
- Изменить адрес данного модуля, обнаружить наличие следующего модуля и изменить адрес следующего модуля.
- Изменить частоту ШИМ от 1 до 12'000 Гц (по умолчанию 490 Гц).
- Изменить направление работы вывода (вход / выход).
- Изменить тип вывода (цифровой / аналоговый).
- Включить / отключить подтягивающий резистор для каждого вывода.
- Включить / отключить прижимающий резистор для каждого вывода.
- Выбрать схему работы выхода (двухтактная / с общим стоком).
- Прочитать логический уровень (0 / 1) с любого вывода.
- Записать логический уровень (0 / 1) на любой вывод.
- Прочитать аналоговый уровень (12 бит АЦП) с любого вывода.
- Записать аналоговый уровень (12 бит ШИМ) на первые 4 вывода.
Выводы модуля Metro:
По центру платы расположены 4 штыревых разъемов GVS пронумерованных от 0 до 3.
- G (GND) - общий вывод питания.
- V (VCC) - выход питания 5В (используется для питания подключённых устройств).
- S (Signal) - вывод GPIO (цифровой/аналоговый вывод для чтения/записи).
По бокам модуля имеются две колодки выводов: IN - штыревой разъем (вход модуля) и OUT гнездовой разъем (выход для подключения входа следующего модуля Metro). На каждой колодке имеется по пять выводов:
- SCL - вход/выход линии тактирования шины I2C.
- SDA - вход/выход линии данных шины I2C.
- 5V - вход питания.
- GND - общий вывод питания.
- ADR (на колодке IN) - вход установки адреса данного модуля.
- ADR (на колодке OUT) - вывод (вход/выход) обнаружения следующего модуля и установки его адреса.
Выводы SCL, SDA, 5V и GND внутрисхемно соединены с одноимёнными выводами колодок IN и OUT, и предназначены для передачи данных по шине I2C. Выводы SCL и SDA внутрисхемно НЕ подтянуты в модуле до уровня логической 1.
Вход ADR на колодке IN используется для сброса/записи адреса модуля на шине I2C. Данный вход внутрисхемно прижат к GND через резистор номиналом в 1 кОм. Если на вход ADR подать уровень логической 1, то адрес модуля сбросится в значение по умолчанию 0x09, но этот адрес не сохранится во FLASH памяти модуля, а значит после отключения питания, установится прежний адрес. Если при наличии логической 1 на входе ADR, записать адрес в регистр «ADDRESS» с установленным битом «IF_PIN_ADDRESS» то данный адрес станет новым адресом модуля на шине I2C и сохранится во FLASH памяти модуля, а значит сохранится и после отключения питания.
Вывод ADR на колодке OUT является двунаправленным выводом и используется для обнаружения наличия следующего модуля Metro, а также сброса/записи адреса следующего модуля. Данный вывод внутрисхемно подтянут до уровня 3,3 В через резистор в 100 кОм, что позволяет определить наличие следующего модуля Metro. Если вывод сконфигурирован как вход и на нём уровень логической 1 (3,3 В) - значит следующих модулей нет, а если на нём уровень логического 0 (GND) - значит следующий модуль есть. Если вывод сконфигурирован как выход, то установив на нём уровень логической 1 можно сбросить/записать адрес следующего модуля.
Конфигурация, чтение и установка уровней выводов ADR осуществляется через регистры модуля.
Примечание: У Trema-модуля (аналог Metro) 8 выводов GPIO, а вместо колодок IN и OUT, есть только колодка I2C.
Характеристики:
- Напряжение питания: 5 В (постоянного тока)
- Потребляемый ток: до 35 мА.
- Напряжение логических уровней: 3,3 В.
- Напряжение аналоговых уровней: до 3,3 В.
- Разрешение АЦП: 12 бит (значение от 0 до 4095).
- Разрешение ШИМ: 12 бит (значение от 0 до 4095).
- Частота ШИМ: 1 - 12'000 Гц (по умолчанию 490 Гц).
- Количество цифровых выводов: 4 (работают как на вход, так и на выход).
- Количество аналоговых входов: 4 (АЦП).
- Количество выходов с поддержкой ШИМ: 4 (выводы № 0 - 3).
- Интерфейс: I2C.
- Скорость шины I2C: 100 кбит/с.
- Адрес на шине I2C: устанавливается программно (по умолчанию 0x09).
- Уровень логической 1 на линиях шины I2C: 3,3 В (толерантны к 5 В).
- Уровень логической 1 на выводах ADR: 3,3 В (толерантны к 5 В).
- Рабочая температура: от -40 до +65 °C.
- Габариты: 35,56 х 25,40 мм (1400 x 1000 mil).
- Вес: 7 г.
Установка адреса:
Сброс адреса (без сохранения):
Если физически подать уровень логической 1 на вход модуля ADR, то адрес модуля сбросится в значение по умолчанию 0x09, но этот адрес не сохранится во FLASH памяти, а значит после отключения питания, установится прежний адрес модуля.
Установка адреса (без сохранения):
Если в регистр 0x06 «ADDRESS» записать значение из 7 бит адреса и младшим битом «IF_PIN_ADDRESS» равным 0, то указанный адрес станет адресом модуля на шине I2C, но он не сохранится во FLASH памяти, а значит после отключения питания, установится прежний адрес модуля.
Установка адреса (с сохранением):
Для установки адреса с его сохранением в FLASH память модуля необходимо выполнить два действия:
- Установить уровень логической 1 на входе ADR колодки IN (при этом адрес модуля сбросится в значение по умолчанию 0x09), или установить в 1 бит «SET_PIN_ADDRES» в регистре 0x01 «BITS_0» (при этом адрес модуля останется прежним).
- Записать в регистр 0x06 «ADDRESS» значение из 7 бит адреса и младшим битом «IF_PIN_ADDRESS» равным 1. ВАЖНО: запись адреса занимает не менее 30 мс.
Если в регистр 0x06 «ADDRESS» записать значение из 7 бит адреса и младшим битом «IF_PIN_ADDRESS» равным 1, при сброшенном бите «SET_PIN_ADDRES» и наличии уровня логического 0 на входе ADR, то указанный адрес проигнорируется и у модуля останется прежний адрес.
Установка адреса для Trema-модуля (аналог модуля Metro):
Так как у Trema-модуля нет выводов ADR, то сбросить адрес Trema-модуля нельзя, а установка адреса осуществляется только через регистры модуля.
- Установка адреса (без сохранения) осуществляется так же как и для модуля Metro.
- Установка адреса (с сохранением) осуществляется так же, в два действия, как и для модуля Metro, но первое действие осуществляется только установкой бита в регистре «BITS_0» (в отличии от модуля Metro, где первое действие можно осуществить, либо установкой бита, либо подачей уровня логической 1 на вход ADR).
Обнаружение следующего модуля Metro:
Модули Metro подключаются друг к другу (вход к выходу) как вагоны метро.
Вход ADR колодки IN внутрисхемно прижат к GND через резистор 1 кОм, значит если данный вход ни к чему не подключён, то на нем присутствует уровень логического 0.
Вывод ADR колодки OUT внутрисхемно подтянут к 3,3 В через резистор 100 кОм, значит если данный вывод сконфигурирован как вход и ни к чему не подключен, то на нем присутствует уровень логической 1.
Следовательно, если вывод ADR колодки OUT сконфигурирован как вход и на нём присутствует уровень логической 1, значит колодка OUT свободна, а если присутствует уровень логического 0, значит к колодке OUT подключена колодка IN следующего модуля.
За конфигурацию вывода ADR колодки OUT отвечает бит «SET_PIN_OUTPUT» регистра 0x01 «BITS_0», а считать логический уровень с этого входа можно через флаг «GET_PIN_OUTPUT» регистра 0x00 «FLAGS_0».
Значит для обнаружения модуля нужно сбросить бит «SET_PIN_OUTPUT» в регистре 0x01 «BITS_0» и считать бит «GET_PIN_OUTPUT» из регистра 0x00 «FLAGS_0». Если считана 1 значит колодка OUT свободна (следующих модулей нет), а если считан 0, значит к колодке OUT подключен следующий модуль.
Регистры:
Карта регистров модуля:
Регистры с адресами 0x02, 0x03, 0x0E, 0x0F зарезервированы, их биты сброшены в 0. Попытка записи данных в эти регистры будет проигнорирована модулем.
Регистр 0x00 «FLAGS_0» - содержит флаги чтения состояния модуля:
Регистр только для чтения.
- FLG_RESET - Флаг указывает на факт выполнения успешной перезагрузки модуля. Флаг самостоятельно сбрасывается после чтения регистра 0x00 «FLAGS_0».
- FLG_SELF_TEST - Флаг указывает на результат выполнения самотестирования модуля (0-провал, 1-успех). Не поддерживается данным модулем.
- FLG_GET_NAME - Если флаг установлен, значит модуль поддерживает вывод своего названия установкой бита «SET_GET_NAME» в регистре 0x01 «BITS_0».
- RAND_ADR - Если флаг установлен, значит модуль поддерживает генерацию случайного адреса для шины I2C регистрами 0x64 «RANDOM_NUM», «RANDOM_ADR», «BUN_ADR».
- FLG_I2C_UP - Если флаг установлен, значит модуль позволяет управлять подтяжкой линий шины I2C при помощи бита «SET_I2C_UP» регистра 0x01 «BITS_0».
- GET_PIN_ADDRES - Бит повторяет логический уровень считанный со входа ADR колодки IN модуля.
- GET_PIN_OUTPUT - Бит повторяет логический уровень считанный с вывода ADR колодки OUT модуля.
- Примечание: У Trema-модуля (аналог Metro) отсутствуют флаги «GET_PIN_ADDRES» и «GET_PIN_OUTPUT», так как у этого модуля нет выводов ADR.
Регистр 0x01 «BITS_0» - содержит биты установки состояния модуля:
Регистр для записи и чтения.
- SET_RESET - Бит запускает программную перезагрузку модуля. О завершении перезагрузки свидетельствует установка флага «FLG_RESET» регистра 0x00 «FLAGS_0».
- SET_SELF_TEST - Бит запускает самотестирование модуля. При успешном завершении самотестирования устанавливается флаг «FLG_SELF_TEST » регистра 0x00 «FLAGS_0». Не поддерживается данным модулем.
- SET_GET_NAME - Бит указывает использовать регистр 0x04 «MODEL» для посимвольного вывода названия модуля. Бит сбрасывается автоматически через 300 мс после его установки. Если флаг «FLG_GET_NAME» регистра 0x00 «FLAGS_0» сброшен, значит модуль не поддерживает посимвольный вывод своего названия.
- RESERVED - Третий бит регистра «BITS_0» который не используется у модулей Metro, но у Trema-модулей (аналог Metro) этот бит носит название «BLOCK_ADR», он блокирует смену и сохранение адреса для шины I2C. Бит устанавливается автоматически при попытке записи данных в регистры предназначенные только для чтения. Это защищает чип от ненамеренной смены адреса шумами на шине I2C.
- SET_I2C_UP - Бит управляет внутрисхемной подтяжкой линий шины I2C. Значение бита сохраняется в FLASH память модуля. Установка бита в «1» приведёт к подтяжке линий SDA и SCL до уровня 3,3 В. На линии I2C допускается устанавливать внешние подтягивающие резисторы и иные модули с подтяжкой до уровня 3,3 В или 5 В, вне зависимости от состояния текущего бита. Если флаг «FLG_I2C_UP» регистра 0x00 «FLAGS_0» сброшен, значит управление подтяжкой не поддерживается модулем.
- SET_PIN_ADDRES - Бит является альтернативой входа ADR колодки IN. Установка бита в 1 расценивается как наличие логической 1 на входе ADR колодки IN, но не устанавливает этот уровень физически на входе, что позволяет установить и сохранить адрес модуля во FLASH память не используя вход ADR. Бит самостоятельно сбрасывается после сохранения адреса во FLASH память. Установка бита в 1 не сбрасывает адрес модуля в значение по умолчанию (0x09), как это делает физическая «1» на входе ADR колодки IN.
- SET_PIN_OUTPUT - Бит конфигурации вывода ADR колодки OUT. Установка бита в 1 сконфигурирует вывод ADR колодки OUT модуля в режим выхода и установит на нём уровень логической 1. Сброс бита в 0 сконфигурирует вывод ADR колодки OUT в режим входа, логический уровень которого можно считать через бит «GET_PIN_OUTPUT» регистра 0x00 «FLAGS_0».
- Примечание: У Trema-модуля (аналог Metro) отсутствует бит «SET_PIN_OUTPUT», так как у этого модуля нет выхода ADR, а бит «SET_PIN_ADDRES» имеет другое название - «SAVE_ADR_EN».
Регистр 0x04 «MODEL» - содержит идентификатор типа модуля:
Регистр только для чтения.
- MODEL[7-0] - Для модуля Metro - Расширитель выводов - идентификатор равен 0x07.
- Если установлен флаг «FLG_GET_NAME» регистра 0x00 «FLAGS_0» значит модуль поддерживает посимвольный вывод своего названия.
- Установка бита «SET_GET_NAME» регистра 0x01 «BITS_0» включает режим посимвольного вывода названия модуля. При этом в регистре 0x04 «MODEL» появится первый символ названия модуля. В процессе чтения регистра 0x04 «MODEL» он будет возвращать очередной символ названия, вплоть до символа конца строки имеющего код 0x00. Далее цикл повторится.
- Сброс бита «SET_GET_NAME» регистра 0x01 «BITS_0» отключает режим посимвольного вывода названия модуля. Регистр 0x04 «MODEL» вновь будет содержать идентификатор.
Регистр 0x05 «VERSION» - содержит версию прошивки модуля:
Регистр только для чтения.
- VERSION[7-0] - Версия прошивки (от 0x01 до 0xFF).
Регистр 0x06 «ADDRESS» - отвечает за чтение/установку адреса модуля на шине I2C:
Регистр для чтения и записи.
- ADDRESS[6-0] - 7 бит адреса модуля на шине I2C. При чтении возвращается текущий адрес модуля, при записи устанавливается указанный адрес модулю.
- IF_PIN_ADDRES - Флаг проверки состояния входа ADR колодки IN для записи адреса в FLASH память модуля.
Флаг имеет значение только при записи данных в регистр.
Если флаг сброшен, то адрес в битах ADDRESS[6-0] будет установлен временно (до отключения питания, или сброса/записи нового адреса). Если флаг «IF_PIN_ADDRES» установлен, то адрес в битах ADDRESS[6-0] будет сохранён в FLASH память модуля (останется и после отключения питания), но только если на входе ADR колодки IN, или в бите «SET_PIN_ADDRES» регистра 0x01 «BITS_0» установлена логическая 1. Если флаг «IF_PIN_ADDRES» установлен, бит «SET_PIN_ADDRES» сброшен и на входе ADR колодки IN установлен уровень логического 0, то адрес в битах ADDRESS[6-0] не будет установлен ни временно, ни постоянно. - Примечание: У Trema-модуля (аналог Metro) флаг «IF_PIN_ADDRES» имеет другое название - «SAVE_FLASH».
Регистр 0x07 «CHIP_ID» - содержит идентификатор общий для всей линейки Metro:
Регистр только для чтения.
У всех модулей линейки метро в регистре «CHIP_ID» содержится значение 0xC3. Если требуется отличить модули Metro на шине I2C от сторонних модулей, то достаточно прочитать значение регистров 0x06 «ADDRESS» и 0x07 «CHIP_ID» всех модулей на шине I2C. Если 7 старших битов регистра 0x06 «ADDRESS» хранят адрес совпадающий с адресом модуля, а в регистре 0x07 «CHIP_ID» хранится значение 0xC3, то можно с большой долей вероятности утверждать, что данный модуль является модулем Metro.
Примечание: У Trema-модуля (аналог Metro), регистр «CHIP_ID» содержит значение 0x3C.
Регистры 0x08-0x09 «FREQUENCY» - содержат частоту ШИМ:
Регистр только для записи.
- FREQUENCY[15-0] - Частота ШИМ в диапазоне от 1 до 12'000 Гц. Значение по умолчанию 0x01EA = 490 Гц. Частота записанная в регистры «FREQUENCY[15-8]», «FREQUENCY[7-0]» применяется после записи старшего байта «FREQUENCY[15-8]».
Если записать значение < 0x0001 то в регистрах появится 0x0001 и частота будет 1 Гц.
Если записать значение > 0x2EE0 то в регистрах появится 0x2EE0 и частота будет 12 кГц.
Регистры 0x0A-0x0B «LEVEL» - содержат значение для расчёта логических уровней:
Регистр только для записи.
- LEVEL[11-0] - Значение для расчёта логических уровней на аналоговых входах. Для выводов сконфигурированных в качестве аналоговых входов, доступно не только чтение их аналоговых значений (из регистров «ANALOG-x»), но и чтение рассчитанных логических уровней (из битов регистра «DIGITAL»).
Если аналоговый уровень «ANALOG-x» больше чем «LEVEL» + «HYSTERESIS» то соответствующий бит регистра «DIGITAL» будет установлен в «1».
Если аналоговый уровень «ANALOG-x» меньше чем «LEVEL» - «HYSTERESIS» то соответствующий бит регистра «DIGITAL» будет сброшен в «0».
Если аналоговый уровень «ANALOG-x» находится в диапазоне «LEVEL» ± «HYSTERESIS» то соответствующий бит регистра «DIGITAL» будет сохранять предыдущее значение.
Таким образом можно считывать данные с устройств, логические уровни которых отличаются от 3,3 В
Стоит учесть тот факт, что уровень регистра «LEVEL» применяется для всех выводов сконфигурированных в качестве аналоговых входов. Значение по умолчанию 0x07FF = 50%.
Регистры 0x0C-0x0D «HYSTERESIS» - содержат гистерезис уровня «LEVEL»:
Регистр только для записи.
- HYSTERESIS[11-0] - Значение определяющее зону бездействия возле уровня «LEVEL».
Если аналоговый уровень «ANALOG-x» больше чем «LEVEL» + «HYSTERESIS» то соответствующий бит регистра «DIGITAL» будет установлен в «1».
Если аналоговый уровень «ANALOG-x» меньше чем «LEVEL» - «HYSTERESIS» то соответствующий бит регистра «DIGITAL» будет сброшен в «0».
Если аналоговый уровень «ANALOG-x» находится в диапазоне «LEVEL» ± «HYSTERESIS» то соответствующий бит регистра «DIGITAL» будет сохранять предыдущее значение.
Гистерезис позволяет избежать эффект «дребезга» битов «DIGITAL» при сближении уровня «ANALOG-x» к уровню «LEVEL». Значение по умолчанию 0x00CD = 5%.
Регистр 0x0E «AVERAGING» - содержит коэффициент усреднения показаний АЦП:
Регистр только для записи.
- AVERAGING[7-0] - Значение от 0 до 255 определяющее сглаживание данных считанных с аналоговых входов. Значение регистра по умолчанию 0x3F = 25%.
Чем выше значение данного регистра, тем плавнее будут меняться показания на всех аналоговых входах. Значение 0 означает что усреднение АЦП отключено.
Задав требуемое усреднение можно качественно улучшить показания многих аналоговых датчиков. Усреднение позволит читать не только уровни аналоговых сигналов, но и сигналов ШИМ.
Регистр 0x10 «DIRECTION» - содержит биты определяющие направление работы выводов:
Регистр для чтения и записи.
- DIR[7-0] - Каждый бит регистра отвечает за направление работы вывода, номер которого совпадает с номером бита: 0-вход, 1-выход. Значение по умолчанию 0x00 (все выводы - входы).
Если вывод работает в качестве входа, то с него можно считывать значения, а если он работает в качестве выхода, то на него можно записывать значения.
Регистр 0x11 «TYPE» - содержит биты определяющие тип выводов (логический/аналоговый):
Регистр для чтения и записи.
- TYPE[7-0] - Каждый бит регистра отвечает за тип вывода, номер которого совпадает с номером бита: 0-логический, 1-аналоговый. Значение по умолчанию 0x00 (все выводы - логические).
Если вывод является логическим, то он может принимать только уровни логического 0 или 1, а если вывод является аналоговым, то он может принимать значения от 0 до 4095 (12 бит).
Регистр 0x12 «PULL_UP» - содержит биты подключения подтягивающих резисторов:
Регистр для чтения и записи.
- PULL_UP[7-0] - Каждый бит регистра отвечает за подключение внутреннего подтягивающего резистора к выводу, номер которого совпадает с номером бита: 0-не подключать резистор, 1-подключить подтягивающий резистор. Значение по умолчанию 0x00 (все выводы свободны от подтягивающих резисторов).
Внутренний подтягивающий резистор позволяет считывать уровень логической «1» с неподключённого входа или установить уровень логической «1» на выходе работающем по схеме с открытым стоком.
Регистр 0x13 «PULL_DOWN» - содержит биты подключения прижимающих резисторов:
Регистр для чтения и записи.
- PULL_DW[7-0] - Каждый бит регистра отвечает за подключение внутреннего прижимающего резистора к выводу, номер которого совпадает с номером бита: 0-не подключать резистор, 1-подключить прижимающий резистор. Значение по умолчанию 0x00 (все выводы свободны от прижимающих резисторов).
Внутренний прижимающий резистор позволяет считывать уровень логического «0» с неподключённого входа.
Регистр 0x14 «OUT_MODE» - содержит биты определяющие режим работы схемы выхода:
Регистр для чтения и записи.
- MODE[7-0] - Каждый бит регистра отвечает за режим работы схемы выхода, номер которого совпадает с номером бита: 0-выход работает по двухтактной схеме, 1-выход работает по схеме с открытым стоком. Значение по умолчанию 0x00 (все выводы работают по двухтактной схеме).
Двухтактная схема позволяет устанавливать на выходе уровни логического «0» или «1».
Схема с открытым стоком позволяет установить на выходе либо логический «0», либо состояние высокого импеданса (высокоомное состояние). Для получения, на выходе с открытым стоком, уровня логической «1» его нужно подтянуть через резистор. В качестве подтягивающего резистора можно использовать внутренний резистор (подключается битами регистра «PULL_UP»), тогда уровень логической «1» будет равен 3,3В. А можно использовать внешний подтягивающий резистор, задав требуемый Вам логический уровень (например 5В).
Регистр 0x15 «DIGITAL» - позволяет читать и записывать логические уровни выводов:
Регистр для чтения и записи.
- DIGITAL[7-0] - Каждый бит регистра определяет логический уровень того вывода, номер которого совпадает с номером бита.
Если вывод сконфигурирован как логический выход, то его логический уровень будет повторять значение соответствующего бита регистра «DIGITAL».
Если вывод сконфигурирован как логический вход, то значение бита регистра «DIGITAL» будет повторять логический уровень на соответствующем входе.
Если вывод сконфигурирован как аналоговый выход, то он не зависит от регистра «DIGITAL».
Если вывод сконфигурирован как аналоговый вход, то значение соответствующего бита регистра «DIGITAL» будет зависеть от уровня на аналоговом входе и значений регистров «LEVEL» и «HYSTERESIS» (более подробно см. в описании этих регистров).
Если регистром «DIRECTION» переконфигурировать вывод со входа на выход, без записи данных в регистр «DIGITAL», то соответствующие биты этого регистра будут сброшены в «0».
ВАЖНО: Наличие уровня превышающего 4 В на любом выводе, может привести к непредсказуемому поведению регистра «DIGITAL» и привести к повреждению модуля.
Регистр 0x16 «WRITE_HIGH» - устанавливает биты регистра «DIGITAL»:
Регистр для чтения и записи.
- WRITE_HIGH[7-0] - Каждый установленный бит этого регистра приводит к установке соответствующего бита в регистре «DIGITAL». Все биты регистра «WRITE_HIGH» автоматически сбрасываются в «0», что свидетельствует о применении новых значений.
Пример: «DIGITAL»=(10101010)2, «WRITE_HIGH»=(11110000)2 => «DIGITAL»=(11111010)2.
Регистр 0x17 «WRITE_LOW» - сбрасывает биты регистра «DIGITAL»:
Регистр для чтения и записи.
- WRITE_LOW[7-0] - Каждый установленный бит этого регистра приводит к сбросу соответствующего бита в регистре «DIGITAL». Все биты регистра «WRITE_LOW» автоматически сбрасываются в «0», что свидетельствует о применении новых значений.
Пример: «DIGITAL»=(10101010)2, «WRITE_LOW»=(11110000)2 => «DIGITAL»=(00001010)2.
Регистры 0x18-0x19 «ANALOG-0» - позволяют читать/записывать аналоговые значения вывода 0:
Регистры 0x1A-0x1B «ANALOG-1» - позволяют читать/записывать аналоговые значения вывода 1:
Регистры 0x1C-0x1D «ANALOG-2» - позволяют читать/записывать аналоговые значения вывода 2:
Регистры 0x1E-0x1F «ANALOG-3» - позволяют читать/записывать аналоговые значения вывода 3:
Регистры 0x20-0x21 «ANALOG-4» - позволяют читать/записывать аналоговые значения вывода 4:
Регистры 0x22-0x23 «ANALOG-5» - позволяют читать/записывать аналоговые значения вывода 5:
Регистры 0x24-0x25 «ANALOG-6» - позволяют читать/записывать аналоговые значения вывода 6:
Регистры 0x26-0x27 «ANALOG-7» - позволяют читать/записывать аналоговые значения вывода 7:
Регистры для чтения и записи.
- ANALOG-X[11-0] - Значение определяющее уровень аналогового сигнала на выводе «X».
Если вывод «X» сконфигурирован как цифровой, то он не зависит от значения «ANALOG-X».
Если вывод «X» сконфигурирован как аналоговый вход, то в регистре «ANALOG-X» будет целое значение от 0 (0x0000) до 4095 (0x0FFF), пропорциональное напряжению поданному на аналоговый вход «X». Значение регистра «ANALOG-X» = UВХ * 4095 / 3,3 В.
Если вывод «X» сконфигурирован как аналоговый выход, то на нём будет установлен сигнал ШИМ c коэффициентом заполнения пропорциональным значению регистра «ANALOG-X» от 0 (0x0000) до 4095 (0x0FFF). Коэффициент заполнения K% = «ANALOG-X» * 100% / 4095. - Примечания:
Сигнал ШИМ способны генерировать только выводы с номерами 0, 1, 2 и 3.
Частота сигнала ШИМ задаётся для всех выводов в диапазоне от 1 до 12'000 Гц через регистр «FREQUENCY».
Для управления сервоприводами нужно указать в регистре «FREQUENCY» частоту 50 Гц, а значения регистров «ANALOG-X» менять в диапазоне от 184 до 430, что соответствует изменению коэффициента ШИМ от 4,5% до 10,5%. В указанном диапазоне, длительность импульсов ШИМ меняется от 900 мкс до 2100 мкс, что приводит к повороту ротора большинства сервоприводов на угол от 0° до 180°.
При работе ШИМ на частотах выше 500 Гц падает разрешение:
При F = 1...500 Гц, разрешение ШИМ = 12 бит, «ANALOG-X» = 0...4095.
При F = 501...1000 Гц, разрешение ШИМ = 11 бит, «ANALOG-X» = 0...2048 << 1.
При F = 1001...3000 Гц, разрешение ШИМ = 10 бит, «ANALOG-X» = 0...1048 << 2.
При F = 3001...6000 Гц, разрешение ШИМ = 9 бит, «ANALOG-X» = 0...512 << 3.
При F = 6001...12000 Гц, разрешение ШИМ = 8 бит, «ANALOG-X» = 0...256 << 4.
Так как выравнивание значений «ANALOG-X» происходит по старшему значащему биту, то допускается указывать ШИМ в 12 битном формате при любой частоте (от 1 Гц до 12 кГц).
Если регистром «DIRECTION» переконфигурировать вывод со входа на выход, без записи данных в регистр «ANALOG-X», то значение регистра «ANALOG-X» будет сброшено в «0».
ВАЖНО: Наличие уровня превышающего 4 В на любом выводе, может привести к непредсказуемому поведению регистров «ANALOG-X» и привести к повреждению модуля.
Примеры значений регистров:
- Работа вывода №0 в режиме цифрового входа:
«DIRECTION» = (xxxxxxx0)2 - Конфигурируем вывод № 0 на работу в режиме входа.
«TYPE» = (xxxxxxx0)2 - Конфигурируем тип вывода № 0 как цифровой.
«PULL_DOWN» = (xxxxxxx1)2 - Прижимаем вывод № 0 к GND (не обязательно).
Логический уровень = «DIGITAL» & (xxxxxxx1)2. - Работа вывода №1 в режиме цифрового выхода:
«DIRECTION» = (xxxxxx1x)2 - Конфигурируем вывод № 1 на работу в режиме выхода.
«TYPE» = (xxxxxx0x)2 - Конфигурируем тип вывода № 1 как цифровой.
«OUT_MODE» = (xxxxxx0x)2 - Выбираем двухтактную схему работы выхода № 1.
«DIGITAL» = (xxxxxx1x)2. - Устанавливаем на выходе №1 уровень логической «1».
«DIGITAL» = (xxxxxx0x)2. - Устанавливаем на выходе №1 уровень логического «0» - Работа вывода №2 в режиме аналогового входа:
«DIRECTION» = (xxxxx0xx)2 - Конфигурируем вывод № 2 на работу в режиме входа.
«TYPE» = (xxxxx1xx)2 - Конфигурируем тип вывода № 2 как аналоговый.
Аналоговый уровень = «ANALOG-2». - Работа вывода №3 в режиме аналогового выхода:
«DIRECTION» = (xxxx1xxx)2 - Конфигурируем вывод № 3 на работу в режиме выхода.
«TYPE» = (xxxx1xxx)2 - Конфигурируем тип вывода № 3 как аналоговый.
«ANALOG-3» = 1023 - Устанавливаем ШИМ с 25% коэффициентом заполнения.
«ANALOG-3» = 2047 - Устанавливаем ШИМ с 50% коэффициентом заполнения.
«ANALOG-3» = 3071 - Устанавливаем ШИМ с 75% коэффициентом заполнения. - Работа вывода №3 в режиме управления сервоприводом:
«DIRECTION» = (xxxx1xxx)2 - Конфигурируем вывод № 3 на работу в режиме выхода.
«TYPE» = (xxxx1xxx)2 - Конфигурируем тип вывода № 3 как аналоговый.
«FREQUENCY» = 50 - Задаём частоту ШИМ равной 50 Гц.
«ANALOG-3» = 184 - Поворачиваем сервопривод на угол 0°.
«ANALOG-3» = 307 - Поворачиваем сервопривод на угол 90°.
«ANALOG-3» = 430 - Поворачиваем сервопривод на угол 180°.
Регистры 100+:
У младших версий модулей линейки «FLASH-I2C» нет блока регистров «100+», так же этого блока нет у модулей линейки «Metro», о его наличии свидетельствует установленный флаг «RAND_ADR» в регистре 0x00 «FLAGS_0».
Блок регистров «100+» с адресами от 0x64 (100)10 до 0x75 (117)10 не участвует в работе модуля, он предназначен только для обнаружения модулей с одинаковыми адресами и назначения этим модулям разных адресов, не отключая их от шины I2C.
Карта регистров 100+:
Регистры 0x64-0x65 «RANDOM_NUM» - содержат случайное число:
Регистры только для чтения.
- RANDOM_NUM[15-0] - Содержит двухбайтное случайное число позволяющее определить наличие нескольких устройств с одинаковым адресом.
- Значение из регистров читается одним пакетом (младший и старший байт). После чтения старшего байта, модуль на 5мс перейдёт в режим «молчания». В этом режиме модуль будет отправлять NACK мастеру после получения номера регистра в любых запросах.
- Если прочитать регистры 0x64-0x65 «RANDOM_NUM» дважды, с промежутком между чтениями менее 5мс, то первый раз мы получим два байта случайного числа, а второй раз модуль откажет в чтении, так как отправит NACK. Но это только в том случае, если адрес модуля уникален.
- Если адрес принадлежит нескольким устройствам, то и отвечать на запрос чтения будут несколько устройств. При первом чтении регистров 0x64-0x65 «RANDOM_NUM», биты случайного числа у разных модулей не совпадут, в результате чего один модуль передаст оба байта случайного числа и перейдёт в режим «молчания», а другой модуль (или модули) зафиксирует потерю арбитража и не передаст старший байт, следовательно, и не перейдёт в режим «молчания». Значит при повторном чтении регистров, мы опять получим два байта случайного числа от того модуля который не перешёл в режим «молчания», что будет свидетельствовать о наличии нескольких устройств на одном адресе.
Регистр 0x66 «RANDOM_ADR» - случайный адрес:
Регистр для чтения и записи.
- RANDOM_ADR[7-0] - Позволяет задавать модулю случайный временный адрес, подтверждать временный адрес и получать информацию о состоянии временного адреса.
- Запись 0x0F - Назначить модулю случайный временный адрес на 50 мс.
В регистре 0x06 «ADDRESS» останется значение постоянного адреса. - Запись 0xF0 - Подтвердить назначенный временный адрес до отключения питания.
В регистре 0x06 «ADDRESS» появится назначенный временный адрес. - Чтение 0x55 - Назначен временный случайный адрес на 50 мс.
- Чтение 0xFF - Назначенный временный адрес подтверждён до отключения питания.
- Чтение 0x00 - Временный адрес не назначался или отменён по истечении 50 мс.
- Если на шине несколько устройств имеют одинаковый адрес, то запись значения 0x0F в регистр 0x66 «RANDOM_ADR» этих устройств, приведёт к тому, что каждый модуль сам себе назначит временный случайный адрес на 50 мс. За указанное время следует найти все новые временные адреса устройств и подтвердить их отправив в регистр 0x66 «RANDOM_ADR» значение 0xF0.
- Примечание: Случайный адрес модуль выбирает сам из диапазона от 0x08 до 0x7E включительно, кроме адресов запрещённых регистрами 0x67-0x75 «BUN_ADR».
Регистры 0x67-0x75 «BUN_ADR» - запрещают назначать адреса:
Регистры для чтения и записи.
- BUN_ADR_08 - Бит запрещает назначать адрес 0x08 регистром 0x66 «RANDOM_ADR».
- BUN_ADR_09 - Бит запрещает назначать адрес 0x09 регистром 0x66 «RANDOM_ADR».
- ...
- BUN_ADR_7D - Бит запрещает назначать адрес 0x7D регистром 0x66 «RANDOM_ADR».
- BUN_ADR_7E - Бит запрещает назначать адрес 0x7E регистром 0x66 «RANDOM_ADR».
- Если бит регистров 0x67-0x75 «BUN_ADR» установлен, то модуль не назначит себе случайный временный адрес соответствующий установленному биту.
- Если на шине есть несколько устройств с одинаковым адресом, то отправка команды 0x0F в регистр 0x66 «RANDOM_ADR» этих устройств, приведёт к тому, что каждый модуль сам себе назначит временный случайный адрес на 50 мс. Но вновь назначенный адрес может совпасть с адресом другого модуля на шине I2C, особенно если их много. По этому перед назначением случайного временного адреса рекомендуется записать в регистры 0x67-0x75 «BUN_ADR» все найденные на шине I2C уникальные адреса.
Доступ к данным регистров:
Каждый регистр модуля хранит 1 байт данных. Так как модуль использует интерфейс передачи данных I2C, то и доступ к данным охарактеризован им.
Обмен данными по шине I2C происходит по одному биту за один такт, после каждых переданных 8 бит (1 байта) принимающее устройство отвечает передающему одним битом: «ACK» в случае успешного приёма, или «NACK» в случае ошибки. Пакет приёма/передачи данных начинается сигналом «START» и завершается сигналом «STOP». Первый байт пакета всегда состоит из 7 бит адреса устройства и одного (младшего) бита R/W.
Сигналы интерфейса передачи данных I2C:
- Для удобства восприятия сигналов они выполнены в следующих цветах:
- Зелёный - сигналы формируемые мастером.
- Красный - данные отправляемые мастером.
- Синий - данные отправляемые модулем Metro.
- Фиолетовый - данные отправляемые мастером или модулем Metro.
- «START» - отправляется мастером в начале пакета приема/передачи данных. Сигнал представляет переход уровня линии «SDA» из «1» в «0» при наличии «1» на линии «SCL».
- «STOP» - отправляется мастером в конце пакета приёма/передачи данных. Сигнал представляет переход уровня линии «SDA» из «0» в «1» при наличии «1» на линии «SCL».
- БИТ - значение бита считывается с линии «SDA» по фронту импульса на линии «SCL».
- «ACK» - бит равный 0, отправляется после успешного приёма байта данных.
- «NACK» - бит равный 1, отправляется после байта данных в случае ошибки.
- ПЕРВЫЙ БАЙТ - отправляется мастером, состоит из 7 бит адреса и бита «RW».
- «R/W» - младший бит первого байта данных указывает направление передачи данных пакета, 1 - прием (от модуля к мастеру), 0 - передача (от мастера в модуль).
- «RESTART» - повторный старт, отправляется мастером внутри пакета. Сигнал представляет из себя «START» отправленный не на свободной шине, а внутри пакета.
ВАЖНО: Все изменения на линии «SDA» должны происходить только при наличии «0» на линии «SCL» за исключением сигналов «START», «STOP» и «RESTART».
Запись данных в регистры:
- Отправляем сигнал «START».
- Отправляем первый байт: 7 бит адреса модуля и бит «R/W» равный 0 (запись).
Получаем ответ от модуля в виде одного бита «ACK». - Отправляем второй байт: адрес регистра в который будет произведена запись.
Получаем ответ от модуля в виде одного бита «ACK». - Отправляем третий байт: данные для записи в регистр.
Получаем ответ от модуля в виде одного бита «ACK». - Далее можно отправить четвёртый байт данных для записи в следующий по порядку регистр и т.д.
- Отправляем сигнал «STOP».
Пример записи в один регистр:
Запись значения 0x2A в регистр 0x06 модуля с адресом 0x09:
// Запись в регистр методами библиотеки Wire.h Wire.beginTransmission(0x09); // Инициируем передачу данных в устройство с адресом 0x09. Wire.write(0x06); // Записываем в буфер байт адреса регистра. Wire.write(0x26); // Записываем в буфер байт который будет записан в регистр. Wire.endTransmission(); // Выполняем передачу адреса и байтов из буфера. Функция возвращает: 0-передача успешна / 1 - переполнен буфер для передачи / 2 - получен NACK при передаче адреса / 3 - получен NACK при передаче данных / 4 - другая ошибка.
Пример записи в несколько регистров подряд:
Запись в модуль с адресом 0x09 нескольких значений начиная с регистра 0x12:
В регистр 0x12 запишется значение 0x0F, в следующий по порядку регистр (0x13) запишется значение 0x30 и в следующий по порядку регистр (0x14) запишется значение 0xB1.
// Запись в регистры методами библиотеки Wire.h byte data[3] = {0x0F,0x30,0xB1}; // Определяем массив с данными для передачи. Wire.beginTransmission(0x09); // Инициируем передачу данных в устройство с адресом 0x09. Wire.write(0x12); // Записываем в буфер байт адреса первого регистра. Wire.write(data, 3); // Записываем в буфер 3 байта из массива data. Wire.endTransmission(); // Выполняем передачу адреса и байт из буфера. Функция возвращает: 0-передача успешна / 1 - переполнен буфер для передачи / 2 - получен NACK при передаче адреса / 3 - получен NACK при передаче данных / 4 - другая ошибка.
Чтение данных из регистров:
- При чтении пакет делится на 2 части: запись № регистра и чтение его данных.
- Отправляем сигнал «START».
- Отправляем первый байт: 7 бит адреса модуля и бит «R/W» равный 0 (запись).
Получаем ответ от модуля в виде одного бита «ACK». - Отправляем второй байт: адрес регистра из которого нужно прочитать данные.
Получаем ответ от модуля в виде одного бита «ACK». - Отправляем сигнал «RESTART».
- Отправляем первый байт после «RESTART»: 7 бит адреса и бит «R/W» равный 1 (чтение).
Получаем ответ от модуля в виде одного бита «ACK». - Получаем байт данных из регистра модуля.
Отвечаем битом «ACK» если хотим прочитать следующий регистр, иначе отвечаем «NACK». - Отправляем сигнал «STOP».
Пример чтения одного регистра:
Чтение из модуля с адресом 0x09 байта данных регистра 0x05:
(в примере модуль вернул значение 0x01).
// Чтение регистра методами библиотеки Wire.h byte data; // Объявляем переменную для чтения байта данных. Wire.beginTransmission(0x09); // Инициируем передачу данных в устройство с адресом 0x09. Wire.write(0x05); // Записываем в буфер байт адреса регистра. Wire.endTransmission(false); // Выполняем передачу без установки состояния STOP. Wire.requestFrom(0x09, 1); // Читаем 1 байт из устройства с адресом 0x09. Функция возвращает количество реально принятых байтов. Так как предыдущая функция не установила состояние STOP, то состояние START установленное данной функцией будет расценено как RESTART. data=wire.read(); // Сохраняем прочитанный байт в переменную data.
Пример чтения нескольких регистров подряд:
Чтение из модуля с адресом 0x09 нескольких регистров начиная с регистра 0x05:
(в примере модуль вернул значения: 0x01 из рег. 0x05, 0x13 из рег. 0x06, 0xC3 из рег. 0x07).
// Чтение регистров методами библиотеки Wire.h byte data[3]; // Объявляем массив для чтения данных. Wire.beginTransmission(0x09); // Инициируем передачу данных в устройство с адресом 0x09. Wire.write(0x05); // Записываем в буфер байт адреса регистра. Wire.endTransmission(false); // Выполняем передачу без установки состояния STOP. Wire.requestFrom(0x09, 3); // Читаем 3 байта из устройства с адресом 0x09. Функция возвращает количество реально принятых байтов. Так как предыдущая функция не установила состояние STOP, то состояние START установленное данной функцией будет расценено как RESTART. int i=0; // Определяем счётчик номера прочитанного байта. while( Wire.available() ){ // Выполняем цикл while пока есть что читать из буфера. if(i<3){ // Лучше делать такую проверку, чтоб не записать данные за пределы массива data! data[i] = wire.read(); i++; // Читаем очередной байт из буфера в массив data. } // } //
Примечание:
- Если на линии I2C только один мастер, то сигнал «RESTART» можно заменить на сигналы «STOP» и «START».
- Рекомендуется не выполнять чтение или запись данных чаще 200 раз в секунду.
- Обратите внимание на сигналы «RESTART» и «STOP» в пакетах чтения данных:
- Между фронтом и спадом сигнала «RESTART» проходит фронт импульса на линии «SCL», что расценивается как передача бита равного 1.
- Между сигналом «NACK» и сигналом «STOP» проходит фронт импульса на линии «SCL», что расценивается как передача бита равного 0.
- Эти биты не сохраняются в модулях и не расцениваются как ошибки.
Модуль не поддерживает горячее подключение: Подключайте модуль только при отсутствии питания и данных на шине I2C. В противном случае потребуется отключить питание при уже подключённом модуле.
Пример плавного изменения ШИМ на выходе №0:
Следующий скетч демонстрирует пример вывода ШИМ на вывод №0. В начале скетча были определены адреса модуля и его регистров, а так же начальное значение ШИМ. В коде setup() был сконфигурирован вывод №0 на работу в качестве аналогового выхода. В коде loop с промежутками в 1 миллисекунду, в регистр «REG_PWM» отправляется новое значение ШИМ, которое постоянно инкрементируется или декрементируется (зависит от флага «flg_PWM»).
#include <Wire.h> // Подключаем библиотеку Wire для работы с шиной I2C. const int ADDRESS = 0x09; // Определяем адрес модуля Metro - расширитель выводов. const int REG_DIR = 0x10; // Определяем адрес регистра DIRECTION. const int REG_PWM = 0x18; // Определяем адрес младшего байта регистра ANALOG-0. double val_PWM = 2; // Определяем начальное значение ШИМ. bool flg_PWM = 1; // Определяем флаг нарастания ШИМ (0-убывает, 1-растёт). // void setup(){ // Wire.setClock(100000L); // Устанавливаем скорость передачи данных по шине I2C. Wire.begin(); // Инициируем работу c шиной I2C в качестве мастера. delay(500); // Wire.beginTransmission(ADDRESS); // Инициируем передачу данных по шине I2C к устройству с адресом ADDRESS и битом RW=0 (запись). При этом сама передача не начнётся. Wire.write(REG_DIR); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это номер регистра DIRECTION. Wire.write(1); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это значение для регистра DIRECTION. Wire.write(1); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это значение для регистра TYPE (он следует сразу за DIRECTION). Wire.endTransmission(); // Выполняем инициированную ранее передачу данных. } // // void loop(){ // В коде loop выполняем поворот изображения меняя значения битов TURN регистра REG_DATA. if(flg_PWM){val_PWM*=1.05;}else{val_PWM/=1.05;} // Увеличиваем или уменьшаем значение ШИМ. if(val_PWM<=2 ){val_PWM=2; flg_PWM=1;} // Меняем спад ШИМ на рост. if(val_PWM>=4095){val_PWM=4095; flg_PWM=0;} // Меняем рост ШИМ на спад. Wire.beginTransmission(ADDRESS); // Инициируем передачу данных по шине I2C к устройству с адресом ADDRESS и битом RW=0 (запись). При этом сама передача не начнётся. Wire.write(REG_PWM); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это номер регистра ANALOG-0. Wire.write(uint16_t(val_PWM)); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это младший байт значения ШИМ. Wire.write(uint16_t(val_PWM)>>8); // Функция write() помещает значение своего аргумента в буфер для передачи. В данном случае это старший байт значения ШИМ. Wire.endTransmission(); // Выполняем инициированную ранее передачу данных. delay(10); // Добавляем задержку в 10 мс. } //
Обсуждение