Robo.com.ua Портал любителей робототехники

Главная · Проекты на Робо · Форумы · Ссылки · Статьи · Файловый архив · Поиск November 24 2020 08:01:03
Навигация
Главная
Проекты на Робо
Форумы
Ссылки
Статьи
Файловый архив
ЧаВо
Поиск
Блоги
YouTube




Последние статьи
Новая система складс...
Эксперимент с ИК при...
Проект ROBER или роб...
Программатор STK200 ...
Схема программатора ...
Партнерские ссылки
Популярно про I2C
Отсебятина переводчика

Шина I2C была разработана в прошлом веке :) в недрах фирмы Philips и изначально предназначалась для использования в телевизорах. Но позднее, то ли авторитет этого "электронного монстра" сыграл свою роль, то ли дешевизна и простота реализации помогли, но факт остается фактом - I2C стал промышленным стандартом и его влияние распространилось далеко за пределы телевизоров.

Чем эта технология сможет быть полезна создателям роботов ? Очень просто - вы получаете универсальное средство построения модульной периферии. Которая, во-первых, совместима между собой на уровне обмена данными. А во-вторых, подключается к материнской плате (или друг к другу), буквально, двумя проводками. С учетом линий питания - четырьмя. И все ! Не устраивает инфракрасный датчик расстояния, нет проблем. Отсоединили его разъем, подключили туда же ультразвуковой сенсор и апгрейд робота закончен. Точно так же и с другими модулями стандарта I2C.

Кстати. многие микроконтроллеры, которые используются сейчас в качестве мозга робота, являются "I2C Ready". То есть имеют аппаратную поддержку этой шины. Но если вы решили создать свой собственный модуль, то можно добавить ему поддержку работы с I2C программным путем. Примеры программ есть в конце статьи. И, в заключение, скажу банальность: "уникальные, совместимые только сами с собой модули, нередко интересны только своему создателю. В то время, как стандартная периферия может заинтересовать многих".

Ссылка на оригинал источника:

http://www.robot-electronics.co.uk/htm/using_the_i2c_bus.htm

Разобраться с особенностями функционирования шины I2C для новичка бывает непросто. В Интернете есть много примеров использования этой шины, но в большинстве случаев, они используют контроллеры высокого уровня и не отражают в деталях - что же реально происходит в шине. Эта короткая статья пробует сбросить налет таинственности с шины I2C и, я надеюсь, не будет иметь противоположного эффекта!

Физическая реализация шины I2C

Физически шина представляет собой всего два провода, называемые SCL и SDA. SCL - линия синхронизирующих импульсов (Сlock Line). Она используется, чтобы синхронизировать все передачи данных по I2C шине. SDA - линия передачи данных (Data). SCL и SDA связаны по I2C шине со всеми устройствами на плате. Есть еще третий провод, который является землей (0 вольт). Может также быть 5 вольтовый провод, питающий все устройства. И SCL и SDA - линии управления с "открытой утечкой" . Это означает, что чип может управлять своим выводом, подавая только низкий уровень сигнала, но не может перевести сигнал на высокий уровень.

Для того, чтобы была возможность передавать высокий уровень сигнала, нужно обеспечить установку повышающих резисторов на линию питания 5 вольт. Там должены быть резистор, подключенный от линии SCL к линии питания +5 вольт и такой же от SDA. Нужно обеспечить установку этих резисторов только в одном месте на шине, а не для каждого устройства отдельно, как показано на рисунке ниже:

Значение резисторов - не принципиальные. Ставят резисторы в диапазоне от 1k8 (1800 ohms) до 47k (47000 ohms). 1k8, 4k7 и 10k - обычные значения, но любые резисторы с сопротивлением из этого диапазона должно работать нормально. Рекомендуется все-же 1k8, поскольку это сопротивление дает лучшие рабочие характеристики. Если резисторы отсутствуют, SCL и SDA всегда будут иметь низкий потенциал сигнала - в районе 0 вольт и шина I2C работать не будет.

Masters and Slaves

Устройства на I2C шине могут быть двух типов: или Мастер (главный) или Раб (подчиненный). Мастер - это устройство, которое управляет линией синхронизирующих импульсов SCL. Рабы - устройства, которые только отвечают на запросы Мастера. Раб по своей инициативе не может начать передачу по шине I2C, только Мастер может делать это. Может быть, и, обычно, бывает несколько Рабов на шине I2C, однако есть, обычно, только один Мастер . В принципе, встречаются ситуации, когда к шине подключено несколько устройств типа Мастер, но это неординарный случай и мы его в этой статье рассматривать не будем. На вашем роботе, роль Мастера будет выполнять ваш микроконтроллер, а Рабов - модули периферии (сенсоры типа SRF08 или CMPS03). Рабы никогда не начинают передачу информации. Раб также как и Мастер может передавать данные по I2C шине, но эта передача всегда проходит под управлением Мастера.

Физический протокол I2C

Когда Мастер (наш контроллер) желает "поговорить" с Рабом (сенсор CMPS03, например) этот процесс начинается со стартовой последовательности (start sequence) на шине I2C. Стартовая последовательность - одна из двух специальных последовательностей, определенных для I2C шины. Другой последовательностью, как не трудно догадаться, является завершающая последовательность (stop sequence). Особенность этих последовательностей сигнала заключается в том, что они - единственные места, где линия данных SDA может изменить свое состояние, во время высокого уровня линии SCL. Во время передачи данных, уровень линии SDA должен остаться стабильным и не должен изменяться, пока уровень SCL высок. Начальная и завершающая последовательности отмечают начало и конец порции передачи данных с подчиненным устройством - Рабом.

Данные передаются в последовательностях по 8 бит. Биты передаются в линию SDA, начинающуюся с MSB (Most Significant Bit) - Наибольший Значительный Бит. Линия SCL после передачи MSB переходит с высокого уровня на низкий. Помните, что чип не может реально установить высокий уровень сигнала. Он просто освобождает линию, а резистор фактически выставляет высокий уровень. После каждых 8 бит переданых данных, устройство, принимающее эти данные, отсылает обратно бит подтверждения. Поэтому для передачи 8 бит информации уходит 9 синхроимпульсов SCL. Если принимающее устройство посылает в ответ бит подтверждения (ACK) с низким уровнем сигнала, то это значит, что данные получены успешно и устройство готово к получению следующей порции данных. Если же назад отсылается бит подтверждения с высоким уровнем сигнала, то это означает, что устройство больше не может принимать информацию и Мастер должен закончить передачу отсылкой завершающей последовательности.

Скорость передачи данных

Стандартной частотой SCL для I2C является 100KHz. Фирма Philips дополнила стандарт I2C более быстрыми частотами: режим Fast - 400KHz и режим High speed - до 3.4MHz. Но на практике, в роботах, нет потребности использовать высокие частоты SCL. Установите SCL в 100KHz или ниже, и забудьте об этом.

Адрессация Устройств в I2C

Все адреса I2C являются 7 или 10 битными. Использование 10 битных адресов встречается редко и здесь не рассматривается. Обычно используются 7 битные адреса. Это означает, что Вы можете иметь до 128 устройств на I2C шине, так как в двуичной арифметике 7-ю битами можно задать номер от 0 до 127. При отсылке по шине 7 битного адреса, мы всегда посылаем 8 битов. Дополнительный бит используется, чтобы сообщить Рабу о том, что от него хочет Мастер: считывать данные или записывать. Если бит нулевой, Мастер отсылает данные для записи рабу. Если бит = 1, Мастер запрашивает данные на чтение от раба. 7 - битный адрес передается первым - в верхних 7 битах байта, а бит чтения/записи (R/W) передается в LSB (Least Significant Bit) - Наименьший Значащий Бит.

Размещение 7 битов адреса в верхних 7 битах байта - источник путаницы для новичков. Это означает, что для того, чтобы открыть на запись устройство с адресом, например адрес 21, Вы должны фактически отослать число 42 (101010), которое является числом 21 (10101) с добавленым в конец битом = 0 (открываем на запись). Если нужно читать, то в конец добавляем бит=1. И отсылаемое число уже равно 43 (101011)

Вероятно проще думать об адресах шины I2C как о 8 битных адресах , с четными адресами для записи в устройство, и нечетными для чтения из того же самого устройства. Так, например, устройство CMPS03 - магнитный компас фирмы Devantech Ltd. (www.robot-electronics.co.uk), выпускается прошитым с адресом 0xC0 ($C0). Вы можете записывать данные в CMPS03 по адресу 0xC0, и читать из него через 0xC1.

Программный Протокол I2C

Первое, что делает Мастер, начиная общение по шине - посылает стартовую последовательность. Это является сигналом для всех устройств-Рабов подключенных к шине, что начался сеанс передачи данных и они должны перестать ковыряться в носу, чтобы не пропустить свой адрес. Следующим делом, Мастер отсылает по шине адрес устройства с которым он хочет "поговорить". Раб, который узнал свой адрес обязан продолжить общение с Мастером, в то время как все остальные устройства должны игнорировать все данные, которые пересылаются по шине в пределах этого сеанса и ждать его окончания. Дальше Мастер посылает Рабу номер ячейки памяти - региста куда он хочет писать или читать. Понятно, что этот номер зависит от аппаратной конструкции Раба, от того, сколько внутренних регистров он имеет. Некоторые очень простые устройства не имеют ни одного, но большинство - имеют внутреннюю память. Например, наш любимый CMPS03 имеет 16 ячеек памяти пронумерованные 0-15. SRF08 - ультразвуковой сенсор имеет 36. После отсылки по шине I2C адреса устройства и адреса его внутреннего регистра, Мастер теперь может отсылать байт или байты данных. Мастер может посылать байт за байтом не объясняя Рабу - что делать с ними. Раб помещает вновь поступивший байт в следующий регистр за текущим автоматически. Когда Мастер заканчивает отсылку данных Рабу, он заканчивает сеанс обмена данных завершающей последовательностью. Итак, для того, чтобы записать какие-то данные Рабу, Мастер должен выполнить следующие операции:

1. Послать стартовую последовательность

2. Послать адрес I2C Раба с нулевым битом чтения/записи (четный адрес)

3. Послать внутренний номер регистра, в который Вы хотите записать

4. Послать байт данных

5. [Произвольно, послать определенное количество байт данных]

6. Послать завершающую последовательность.

Например, для SRF08, с фабричной прошивкой его I2C адреса по умолчанию 0xE0, чтобы запустить сканирование расстояния до препятствия, нужно записать 0x51 в регистр команд по адресу 0x00 по алгоритму:

1. Послать стартовую последовательность

2. Послать 0xE0 - I2C адрес SRF08 с нулевым битом чтения/записи (четный адрес)

3. Послать 0x00 (Внутренний адрес регистра команд)

4. Послать 0x51 (команда, чтобы запустить сканирование SRF08)

5. Послать завершающую последовательность.

Чтение данных от Раба

Это чуть сложнее, чем запись, но не намного. Перед тем как начинать читать данные от Раба, нужно сообщить ему - из какого его внутреннего регистра Мастер хочет читать. Поэтому процесс чтения данных от Раба всегда начинается с записи номера регистра из которого потом будут читать. Начало такое же как и во время записи - Мастер посылает стартовую последовательность, четный адрес I2C Раба (для записи) и внутренний адрес регистра в который нужно писать. А сейчас, (Внимание!) Мастер посылает другую стартовую последовательность (иногда ее называют restart) и снова адрес I2C - на этот раз нечетный (младший бит выставлен на чтение). Дальше Мастер читает столько байт сколько ему хочется и заканчивает сеанс завершающей последовательностью. Итак, для того, чтобы прочитать азимут в виде байта из устройства CMPS03 (магнитный компас) нужно:

1. Послать стартовую последовательность

2. Послать 0xC0 - I2C адрес SRF08 с нулевым битом чтения/записи (четный адрес)

3. Послать 0x01 (Внутренний адрес регистра азимута)

4. Послать стартовую последовательность снова (повторный старт)

5. Послать 0xC1 - I2C адрес SRF08 с единичным битом чтения/записи (нечетный адрес)

6. Читать байт данных от CMPS03

7. Послать завершающую последовательность.

Последовательность битов будет выглядеть следующим образом:

Одну минутку !

Это почти все, что нужно для простой I2C связи. Но есть одна неувязочка. Когда Мастер читает от Раба, последний должен выкладывать данные в линию SDA, но, в то же время, линию синхронизирующих импульсов - SCL, как мы помним, всегда контролирует Мастер. А что, если Раб не готов послать данные! С устройствами типа ППЗУ эта проблема не возникает. Но когда в качестве Раба выступает такое устройство, как микропроцессор, загруженый работой, может возникнуть проблема. Микропроцессор-Раб должен обработать прерывание, сохранить свои рабочие регистры, выяснить - какой адрес Мастер хочет читать, получать данные и поместить их в свой регистр. Это может отнять много тактов и в то время как Мастер будет воодушевленно генерировать синхро-импульсы в линии SCL, Раб будет молчать потому, что он не успевает на них ответить. Это называется удлинением синхро импульсов. Когда Раб получает команду на чтение от Мастера, он устанавливает в линии синхронизирующих импульсов SCL низкое значение сигнала. Микропроцессор-Раб достает нужные данные, помещает их в регистр для отправки и освобождает линию SCL позволяя повышающим резисторам поднять уровень сигнала. С точки зрения Мастера, это изменение уровня сигнала выглядит началом первого импульса чтения данных от Раба. До тех пор пока уровень сигнала в линии SCL низкий, Мастер ждет занятого Раба. К счастью, аппаратная реализация шины I2C на большинстве микропроцессоров решает эту проблему автоматически.

Иногда, правда, Мастер I2C выполнен в виде программной реализации протокола, представляющий собой коллекцию подпрограмм. Известно несколько "кривых" реализаций, которые работают с Рабами, как с ППЗУ, игнорируя удлинение синхро импульсов во время неготовности устройства. Результат - недостоверные данные, которые такой Мастер прочитывает преждевременно от Раба. Так что будьте начеку !

Пример программного кода Мастера I2C

Этот пример показывает, как написать программное обеспечение Мастера I2C , включающее поддержку длинных синхро импульсов. Он написан на Cи для процессора PIC, но может быть перенесен на большинство процессоров с минимальными изменениями.

Так как линии SCL и SDA имеют открытый тип утечки, мы используем регистр управления с тремя состояниями, чтобы управлять выводом, сохраняя на выходе низкий уровень сигнала. Выводы порта должны по-прежнему читаться, так как они определены через SCL_IN и SDA_IN. Эти определения и их инициализация, вероятно, все, что Вы должны изменить в программе для другого процессора.

*define SCL TRISB4 // шина I2C

*define SDA TRISB1 //

*define SCL_IN RB4 //

*define SDA_IN RB1 //

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

SDA = SCL = 1;

SCL_IN = SDA_IN = 0;

Мы используем маленькую подпрограмму задержки между изменениями в SDA и SCL, чтобы дать четкую последовательность на шине I2C. Это не больше чем просто вызов подпрограммы и возврат из нее.

void i2c_dly (Void)

{

}

Следующие 4 функции делают: примитивное начало, завершение, чтение и запись последовательности. Все транзакции по шине I2C могут быть выполнены на основе этих функций.

void i2c_start (void)

{

SDA = 1; // последовательность стартовых битов i2c

I2c_dly ();

SCL = 1;

I2c_dly ();

SDA = 0;

I2c_dly ();

SCL = 0;

I2c_dly ();

}

void i2c_stop (void)

{

SDA = 0; // последовательность завершающих битов i2c

I2c_dly ();

SCL = 1;

I2c_dly ();

SDA = 1;

I2c_dly ();

}

unsigned char i2c_rx(char ack)

{

char x, d=0;

SDA = 1;

for(x=0; x<8; x++) {

d <<= 1;

do {

SCL = 1;

}

while(SCL_IN==0); // ждем любые длинные синхроимпульсы SCL

i2c_dly();

if(SDA_IN) d |= 1;

SCL = 0;

}

if(ack) SDA = 0;

else SDA = 1;

SCL = 1;

i2c_dly(); // отсылаем (N)ACK бит

SCL = 0;

SDA = 1;

return d;

}

bit i2c_tx(unsigned char d)

{

char x;

static bit b;

for(x=8; x; x--)

{

if(d&0x80) SDA = 1;

else SDA = 0;

SCL = 1;

d <<= 1;

SCL = 0;

}

SDA = 1;

SCL = 1;

i2c_dly();

b = SDA_IN; // возможный ACK бит

SCL = 0;

return b;

}

4 простейшие функции, изображенные выше могут быть легко использованы вместе для формирования законченной транзакции I2C. А вот и пример работы с сенсором SRF08 для получения расстояния до препятствия в сантиметрах:

i2c_start(); // отсылка стартовой последовательности

i2c_tx(0xE0); // I2C адрес SRF08 с нулевым битом чтения/записи

i2c_tx(0x00); // отсылка адреса регистра SRF08

i2c_tx(0x51); // команда начала сканирования расстояния в см

i2c_stop(); // отсылка завершающей последовательности

А сейчас, после ожидания (65 милисекунд) окончания работы сканера (этот кусок программы напишете сами), следующий пример кода показывает как прочитать значение сенсора освещения из регистра 1 и величину расстояния из регистров 2 и 3.

i2c_start(); // отсылка стартовой последовательности

i2c_tx(0xE0); // I2C адрес SRF08 с нулевым битом чтения/записи

i2c_tx(0x01); // адрес регистра сенсора освещения SRF08

i2c_start(); // отсылка стартовой последовательности (делаем restart)

i2c_tx(0xE1); // I2C адрес SRF08 с установленым битом чтения/записи (читаем)

lightsensor = i2c_rx(1); // получение значения сенсора освещения и отсылка подтверждения. Адрес внутреннего регистра увеличится на единицу автоматически.

rangehigh = i2c_rx(1); // получение старшего байта расстояния и отсылка подтверждения

rangelow = i2c_rx(0); // получение старшего байта расстояния - внимание ! Мы не подтверждаем получение последнего байта.

i2c_stop(); // отсылка завершающей последовательности

Просто не так ли?

Официальные спецификации на шину I2C могут быть найдены на web-сайте Philips. Это в настоящее время здесь (http://www.semiconductors.philips.com/acrobat/literature/9398/39340011.pdf), но если их переместят то Ваш друг - Google. Ищите: "i2c bus specification".

Удачи !

С уважением, Владимир Канивец

Оригинал: www.robot-electronics.co.uk/htm/using_the_i2c_bus.htm


Опубликовал admin September 22 2004 - 00:00:000 Комментариев · 17468 Прочтений - Для печати
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Сейчас на сайте
Гостей: 1
На сайте нет зарегистрированных пользователей

Пользователей: 651
Не активированный пользователь: 2514
Посетитель: knevech
Last Seen Users
disop11 weeks
EpicOne58 weeks
overlocker83 weeks
Driver_UA84 weeks
knevech92 weeks
Petro99 weeks
admin126 weeks
BOBKA137 weeks
salavat150 weeks
nik22157 weeks
Мини-чат
Вам необходимо залогиниться.

Нет присланных сообщений.
robo.com.ua Copyright © 2004-2015. EMail admin_shs()robo.com.ua