Рекомендации по использованию TWI
TWI ориентирован на передачу данных в байтном формате с управлением по прерываниям. Прерывания возникают после обнаружения одного из событий на шине, например, прием байта или передача условия СТАРТ. Управление TWI по прерываниям позволяет освободить программное обеспечение на выполнение других задач во время передачи байта данных. Обратите внимание, что установка флага TWINT приводит к генерации запроса на прерывание только в том случае, когда установлен бит разрешения прерывания TWIE в регистре TWCR, а также разрешена работа прерываний установкой бита в регистре SREG. Если бит TWIE сброшен, то состояние TWINT должно отслеживаться программно для оценки ситуации на шине TWI.
После установки флага TWINT интерфейс TWI приостанавливает работу и ожидает реакции программы. В этом случае регистр статуса TWI (TWSR) содержит значение, которое индицирует текущее состояние шины TWI. Исходя из этого программа задает дальнейшее поведение шины TWI, манипулируя регистрами TWCR и TWDR.
На рисунке 95 показан простой пример подключения к шине TWI. Здесь предполагается, что мастер желает передать один байт данных подчиненному. Данное описание весьма общее, а более подробно объяснение приводится далее в этом разделе.
Рисунок 95. Последовательность обслуживания TWI при типичной передаче
- Первым шагом работы TWI является передача условия СТАРТ. Это инициируется путем записи специфического значения в TWCR. О значении, которое необходимо записать будет сказано позже. Однако, необходимо следить, чтобы в записываемом в регистр значении был установлен бит TWINT. Запись лог. 1 в TWINT сбрасывает этот флаг. TWI не начнет работу до тех пор пока будет установлен флаг TWINT в регистре TWCR. Сразу после сброса TWINT начинается передача условия СТАРТ.
- После передачи условия СТАРТ устанавливается флаг TWINT в регистре TWCR, а содержимое TWSR обновляется значением кода состояния, индицирующего об успешной передачи условия СТАРТ.
- В программе необходимо выполнить проверку значения TWSR, чтобы убедится в том, что условие СТАРТ было успешно передано. Если TWSR индицирует прочую ситуацию, то программа выполняет особые действия, например, вызывает процедуру обработки ошибочных ситуаций. Если код состояния имеет ожидаемое значение, то выполняется загрузка условия ПОДЧИН_АДР + ЗАПИСЬ в TWDR. Необходимо помнить, что TWDR используется для хранения как адреса, так и данных. После загрузки в TWDR желаемого значения ПОДЧИН_АДР + ЗАПИСЬ в регистр TWCR должно быть записано специфическое значение, которое служит командой для передачи значения ПОДЧИН_АДР + ЗАПИСЬ, хранящегося в TWDR. Какое именно значение необходимо записать будет сказано позже. Однако необходимо следить, чтобы в записываемом в регистр значении был установлен бит TWINT. Запись лог. 1 в TWINT приводит к сбросу этого флага. TWI не начнет работу до тех пор пока установлен бит TWINT в регистре TWCR. Сразу после сброса флага TWINT инициируется передача адресного пакета.
- После передачи адресного пакета устанавливается флаг TWINT в регистре TWCR, а содержимое регистра TWSR обновляется кодом состояния, индицирующего успешность передачи адресного пакета. В коде состояния также отражается было ли подтверждение приема адресного пакета со стороны подчиненного или нет.
- Выполняется программная проверка значения TWSR, чтобы убедиться в успешности передачи адресного пакета и что бит подтверждения ПОДТВ имеет ожидаемое значение. Если TWSR индицирует иную ситуацию, то при необходимости выполняются особые действия, например, вызывается процедура обработки ошибочных ситуаций. Если же код состояния имеет ожидаемое значение, то программа записывает пакет данных в TWDR. Впоследствии в регистр TWCR записывается специфическое значение, которое служит командой для TWI и вызывает аппаратную передачу данных, записанных в TWDR. Какое именно значение необходимо записать, будет сказано позже. Однако необходимо учесть, что в записываемом значении должен быть установлен бит TWINT. Запись лог. 1 в TWINT приводит к сбросу этого флага. TWI не начнет работу до тех пор пока будет установлен бит TWINT в регистре TWCR. Сразу после сброса TWINT начинается передача пакета данных.
- После передачи пакета данных устанавливается флаг TWINT в регистре TWCR, а содержимое регистра TWSR обновляется значением кода состояния, который сигнализирует об успешной передачи пакета данных. В коде состояния также отражается было ли принято подтверждение от подчиненного или нет.
- Выполняется программная проверка значения в TWSR, чтобы убедиться в успешности передачи пакета данных и в том, что бит ПОДТВ имеет ожидаемое значение. Если TWSR индицирует иную ситуацию, то программа выполняет особые действия, в т.ч. вызывает процедуру обработки прерывания. Если код состояния имеет ожидаемое значение, то выполняется запись специального значения в TWCR, которое служит командой для TWI и инициирует передачу условия СТОП. Какое именно значение необходимо записать, сказано далее. Однако следует учесть, что во время записи должна быть произведена установка бита TWINT. Запись лог. 1 в TWINT приводит к очистке этого флага. TWI не начнет работу до тех пор, пока установлен бит TWINT в регистре TWCR. Сразу после сброса флага TWINT инициируется передача условия СТОП. Обратите внимание, что флаг TWINT НЕ устанавливается по завершении передачи условия СТОП.
Не смотря на простоту изложенного примера, он показывает принципы, положенные в основу любой передачи через TWI. Из вышеизложенного можно сделать следующие выводы:
- По завершении работы TWI устанавливается флаг TWINT и далее ожидается реакция со стороны программы. Линия находится в низком состоянии, пока сброшен флаг TWINT.
- Если флаг TWINT установлен, то пользователь может обновлять любой из регистров TWI значением, которое относится к следующему этапу работы шины TWI. Например, в TWDR загружается значение, которое необходимо передать на следующем цикле шины.
- После обновления всех регистров TWI и завершении других задач выполняется запись в TWCR. Во время записи TWCR необходимо, чтобы был установлен бит TWINT. В этом случае запись лог. 1 в TWINT приведет к сбросу данного флага. TWI выполняет действия в соответствии установкой регистра TWCR.
Далее показан пример на Ассемблере и Си. В примере предполагается, что все символьные обозначения определены в присоединенном файле.
№ |
Пример кода на Ассемблере |
Пример кода на Си |
Комментарий |
1 |
ldi r16,
(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
out TWCR, r16 |
TWCR = (1<<TWINT)|
(1<<TWSTA)|(1<<TWEN) |
Передача условия СТАРТ |
2 |
wait1:
in r16,TWCR
sbrs r16,TWINT
rjmp wait1 |
while (!(TWCR & (1<<TWINT)))
; |
Ожидание установки флага TWINT. Этим индицируется завершение передачи условия СТАРТ |
3 |
in r16,TWSR
andi r16, 0xF8
cpi r16, START
brne ERROR |
if ((TWSR & 0xF8) != START)
ERROR(); |
Проверка кода состояния TWI. Маскир. бит предделителяЕсли код состояния не равен СТАРТ, то переход на ERROR |
ldi r16, SLA_W
out TWDR, r16
ldi r16, (1<<TWINT) | (1<<TWEN)
out TWCR, r16 |
TWDR = SLA_W;
TWCR = (1<<TWINT) | (1<<TWEN); |
Загрузка ПОДЧИН_АДР + ЗАПИСЬ в регистр TWDR. Сброс бита TWINT в TWCR для начала передачи адреса |
4 |
wait2:
in r16,TWCR
sbrs r16,TWINT
rjmp wait2 |
while (!(TWCR & (1<<TWINT)))
; |
Ожидание установки флага TWINT. Этим сигнализируется завершение передачи ПОДЧИН_АДР + ЗАПИСЬ и получение/неполучение подтверждения (ПОДТВ/НЕТ ПОДТВ). |
5 |
in r16,TWSR
andi r16, 0xF8
cpi r16, MT_SLA_ACK
brne ERROR |
if ((TWSR & 0xF8) != MT_SLA_ACK)
ERROR(); |
Проверка значения регистра состояния.Маскирование бит предделителяЕсли состояние отличается от MT_SLA_ACK, то переход на ERROR |
ldi r16, DATA
out TWDR, r16
ldi r16, (1<<TWINT) | (1<<TWEN)
out TWCR, r16 |
TWDR = DATA;
TWCR = (1<<TWINT) | (1<<TWEN); |
Загрузка данных в TWDRСброс флага TWINT в TWCR для начала передачи данных |
6 |
wait3:
in r16,TWCR
sbrs r16,TWINT
rjmp wait3 |
while (!(TWCR & (1<<TWINT)))
; |
Ожидание установки флага TWINTЭтим индицируется, что данные были переданы и принято/не принято подтверждение (ПОТДВ/НЕТ ПОДТВ). |
7 |
in r16,TWSR
andi r16, 0xF8
cpi r16, MT_DATA_ACK
brne ERROR |
if ((TWSR & 0xF8) != MT_DATA_ACK)
ERROR(); |
Проверка значения регистра состояния TWI. Маскирование бит предделителя. Если состояние отличается от MT_DATA_ACK, то переход на ERROR |
ldi r16, (1<<TWINT)|(1<<TWEN)|
(1<<TWSTO)
out TWCR, r16 |
TWCR = (1<<TWINT)|(1<<TWEN)|
(1<<TWSTO); |
Передача условия СТОП |
Прим.: Если фактический регистр расположен в расширенной памяти ввода-вывода, то инструкции "IN", "OUT", "SBIS", "SBIC", "CBI" и "SBI" необходимо заменить теми инструкциями, которые эффективны для данной области памяти. Обычно это инструкции "LDS" и "STS" в сочетании с "SBRS", "SBRC", "SBR" и "CBR".
|