Подписаться на получение новых статей на почту:

Шаг №28. Последовательный двухпроводный интерфейс TWI для AVR с одним ведущим

Всем привет. В этом посте мы продолжим наш цикл статей по разработке контроллера сбора данных, который мы с Вами начали проектировать в посте шаг № 16. Пришло время подключить часы к нашей плате, чтоб в дальнейшем записывать данные (температуру, влажность) по времени на Sd-карту (файловая система Petit FatFs), которую мы протестировали в одном из предыдущих постов.

Что бы идти далее немного разберем что из себя представляет данный протокол. Часто, при поиске данного интерфейса можно встретить библиотеки под названием i2c, все верно ведь I2C (компании Philips, разработанной в 1980-х годах) является полным аналогом, а точнее прародителем, но ввиду лицензионных причин имеем другое название TWI или TWSI (Two-wire Serial Interface ).

Что же такое TWI?  Интерфейс TWI – это двухпроводная шина, которая состоит из линии тактового сигнала (SCL – serial clock ) и линии данных(SDA – serial data), которые присутствуют на выводах микроконтроллера. Рис. ниже. Данный интерфейс позволяет объединить вместе до 128 устройств.

Подключение по интерфейсу TWI

Как Вы видите для использования данного протокола, линии необходимо подтянуть к источнику питания и управлять через открытый коллектор или сток, и данное схемное решение имеет название «Монтажное И». Сразу о технических характеристиках: подтягивающие сопротивление , как правило 4,7 кОм. Длина линии, чем меньше тем лучше, основное условие емкость на линии не более 400 пФ. Скорость, максимальная до 400кГц на шине. Мы будем использовать 50 и 100 кГц. В общем основные технические параметры приведены в справочнике, так что не стесняемся — читаем.

Сразу оговоримся, что данный протокол организовывает сам микроконтроллер аппаратно, имея внутри модуль TWI, и ниже мы его разберем. Но так же есть и библиотеки, которые программно организовывают данный интерфейс. Применяются в старых микроконтроллерах AVR, которые не имеют модуля TWI.

Основой данной технологии передачи данных является то, что все данные передаются поразрядно. Каждый бит на линии SDA сопровождается тактом на линии SCL, и не меняет свое состояние до окончание такта. Базовым для всех TWI совместимых устройств будет три состояния СТАРТ, СТОП, ПОВСТАРТ. Рис. ниже.

три условия интерфейса TWI

Как видно состояние СТАРТ и СТОП формируется при высоком уровне на SCL и смене сигнала SDA. И третье состояние ПОВСТАР, аналогично СТАРТ за исключением того что передается в момент уже соединения ведущего и ведомого по этому протоколу и используется когда ведущий хочет передать блок данных без потери контроля над шиной. На рисунке ниже пример данного условия ПОВСТАР.

Условие ПОВСТАР интерфейса TWI

Условие ПОВСТАР (Повтор условия начала передачи).

Очень часто данное условие используется при команде записи (как на рисунке выше), когда ведущее устройство запрашивает у ведомого определенные данные и далее что б не прерывать сеанс связи ведущее посылает повторный старт – ПОВСТАРТ и продолжает дальнейшие операции с ведомым. В следующей статье Вы увидите как используется данное условие при работе с часами(№29).

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

/*------------------------------ Формируем состояние СТАРТ ---------------------*/
 TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
/*---------------------------- Формируем состояние СТОП -----------------------*/
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
/*---------------------   Повторный старт ПОВСТАРТ -------------------------*/
/*Сначала СТАРТ*/
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
/*…………………….выполняем запись………………….*/
/*формируем повторный старт, например для чтения без потери контроля над линией*/
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);

 

Ниже мы с Вами все эти регистры разберем.

С основными условиями- состояниями мы разобрались, теперь рассмотрим принцип передачи данных. На рисунке ниже изображена диаграмма.

Передача данных по интерфейсу TWI

Общение по протоколу начинается с состояние СТАРТ и шина считается занятой до последующего состояния СТОП, которые мы рассмотрели выше. Данные два состояние формируются аппаратно, модулем микроконтроллера TWI (рис. ниже). В данном протоколе пакеты адресные и данные имеют длину 9 бит. Причем адресный пакет состоит из первых 7-ми битов адреса, начиная со старшего, 8-й бит управления, который отвечает за запись или чтения R/W (0-запись, 1-чтение) и 9-й – бит квитирования ACK (acknowledg (e) ment -подтверждение), например при подтверждении адреса ведомым устройством, на линии SDA формируется низкий сигнал. В случае если ведомый не смог принять адрес, то он удерживает SDA в высоком состоянии, т.е. сигнал NACK. Адреса могут быть в диапазоне 0000 001 – 1111 000. Адрес 0000 000 используется для общего вызова, передачи одного сообщения всем ведущим.

Пакет данных состоит из 8 – битов информации + бит ACK/NACK. При получении сигнала NACK ведущее устройство начинает формировать состояние STOP.

И последние для работы с протоколом необходимо рассмотреть настройку модуля TWI (на рисунке ниже).

Блок-схема модуля TWI микроконтроллера AVR

Структурная схема TWI
Для работы с модулем TWI, мы должны разобрать 5-ть регистров:
TWBR –регистр скорости передачи.
TWSR- регистр состояния.
TWCR- регистр управления.
TWAR- регистр адреса.
TWDR- регистр данных.

Первое, что необходимо, так это настроить скорость передачи данных, а также пред делитель контроля скорости передачи, как видно, на рисунке выше, для этого используется два регистра TWBR и TWSR (используется два младших разряда). TWBR – 8-битовый регистр, который принимает значение о 0 до 255. Частота сигнала SCL рассчитывать по формуле для Atmega8x, Atmega16x, Atmega32x, Atmega64x, Atmega128x.

Расчет частоты сигнала SCL интерфейса TWI

Для корректной передачи данных TWBR должен быть не менее 10. Я использовал значение 2 при частоте 1 МГц. Работает  отлично. Ниже, некоторые расчетные значения частоты для определенных значений TWBR, при 2-х байтовом регистре TWPS = 0.

Частота МК
TWBR
TWPS
Частота SCL, кГц
1
2
0
50
2
12
0
50
2
2
0
100

TWSR (регистр состояний) использует два младших разряда TWPS1 иTWPS0, которые задают значение пред делителя.

Ниже значение пред делителя:

TWPS1
TWPS0
TWPS01
Значение пред делителя
0
0
0
1
0
1
1
4
1
0
2
16
1
1
3
64

Разряды TWPS0 и TWPS1 доступны в любой момент времени как для записи , так и для чтения. В режиме ведомого эти регистры не выполняю никакую функцию и частота микроконтроллера должна быть в 16 и более раз выше частоты тактового сигнала SCL.

Регистр состояния TWSR входит в блок управления (рис. выше), который формирует код статуса, при наступлении событий и устанавливает флаг запроса на прерывание TWINT регистра управления TWCR. Пока флаг не сбросится на линии SCL — 0, т.е. передача данных приостанавливается. Ниже  разряды регистра состояния.

TWS7
TWS6
TWS5
TWS4
TWS3
TWPS1
TWPS0

Разряды TWS7-TWS3 – отвечают за состояние узлов, в них содержится код статуса от $00 до $F8. Для каждого режима используются свои коды, например режим ведущий передатчик код $18, что означает был передан пакет адреса и сформировано подтверждение, что выглядело бы следующим образом

После передачи адреса проверяем код состояния, и в зависимости от его значения определяем дальнейшее поведение программы.

if ((TWSR & 0xf8) == 0×18)
       return Ок;
else
        return Err;

f8 – это промежуточный код, который означает отсутствие какой либо информации (1111 1 — — -). В следующей поту где мы рассмотрим работу часов я использовать состояние кодов не буду.

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

void init_DS1307 (void)
{
       TWBR = 2;
       TWSR = (0 << TWPS1)|(0 << TWPS0); /*Пред делитель на 64*/
       TWCR |= (1 << TWEN); /*Включение модуля TWI*/
}

Следующий этап : рассмотрим регистр управления TWCR, который как и регистр состояния TWSR входит в блок шинного интерфейса. Данный регистр управляет всем блоком и информацией, которая к нему поступает.

Здесь важно выделить что при окончании выполнении контроллером условий состояний или передачей данных/адреса, блок интерфейса формирует код состояния и устанавливает флаг прерывания TWINT регистра TWCR. Мы будем использовать этот флаг для проверки окончания операции. Ниже пример кода формирование состояния СТАРТ и проверки его выполнения.

TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));

Ниже разряды регистра управления.

TWINT
TWEA
TWSTA
TWSTO
TWWC
TWEN
резерв
TWIE
7 R/W
6 R/W
5 R/W
4 R/W
3 R
2 R/W
1 R
0 R/W

TWINT – флаг прерывания. Устанавливается аппаратно (в 1), после очередной операции. Пока флаг установлен на линии SCL – 0. Сброс флага происходит при записи в него 1.

TWSTA — флаг состояния СТАРТ. При записи 1 , проверяется шина, если свободна, то формируется состояние СТАРТ. Если занята, то ждет состояние СТОП и далее формирует СТАРТ. Сбрасывается аппаратно.

TWSTO — флаг состояния СТОП. В режиме ведущего работает также как и СТАРТ. В режиме ведомого используется для выхода из ошибочной ситуации.

TWWC – флаг конфликта записи. Устанавливается в 1 при попытке записи в регистр TWDR, когда флаг прерывания TWINT будет сброшен. Флаг сбрасывается при записи в регистр TWDR , когда флаг прерывания TWINT установлен.

TWEN –разрешение работы модуля TWI. 1 – включен, 0 – выключен.

TWIE – разрешение прерывания от модуля TWI.

Далее рассмотрим блок шинного интерфейса. который контролирует состояние СТОП/СТАРТ, контроллер арбитража, когда контроллер в ведущем режиме, а также регистр данных TWDR, который принимает/отправляет пакеты данных/адресса. В этом регистре всегда содержится последний байт, имевшийся на шине, за исключением выхода контроллера из спящего режима.

Ниже пример кода работы с регистром TWDR.

/*Передаем пакет адреса, для ведущего передатчика. Содержимое пакета записываем в регистр TWDR*/
TWDR = 0xd0;  /*0b1101000 +0 – write . Адрес часов + бит записи*/ 
/*Сбросим флаг для начала записи*/
TWCR = (1<<TWINT)|(1<<TWEN);
/*После передачи адресного пакета и приема бита подтверждения ждем установки флага*/
while (!(TWCR & (1<<TWINT)));

Еще хочется добавить, что существует 4 режима работы модуля TWI в микроконтроллерах Mega: ведущий передатчик, ведущий приемник, ведомый передатчик, ведомый приемник. На примере следующей статьи работы с часами мы рассмотрим два режима это ведущий передатчик и ведущий приемник, т.к . устройство само по себе пассивное и не может быть ведомым передатчиком или приемником. Для работы с пассивным устройством выше приведенной информации достаточно.

Для данного интерфейса остались не рассмотрены вопросы синхронизации, приоритета, статус кодов а также блок контроля адреса TWAR, которые необходимы в случае нескольких ведущих на линии. Данные вопросы мы рассмотрим и попрактикуем в статье №34. На этом все. В следующей статье рассмотрим работу с часами DS1307, подключим, напишем программу и протестируем в симуляторе и в “железе”. Всем пока.

Просмотрено 5220 раз.

Я на Google+

Добавить комментарий

Ваш e-mail не будет опубликован.

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Subscribe without commenting