Подробнее об I²C

Этот раздел продолжает тему, начатую в разделе Передача и приём данных.

I²C (и множество его вариаций) использует для передачи данных в обоих направлениях одну линию данных (называется «SDA»). Линии DO и DI канала SSI необходимо соединить вместе. На устройствах с однонаправленными линиями ввода-вывода свойство ssi.zmode должно быть равно 1 - PL_SSI_ZMODE_ENABLED_ON_ZERO (на устройствах с двунаправленными линиями ввода-вывода это не требуется). Линия DO при этом работает так:

  • Чтобы установить на линии DO высокий уровень (HIGH), устройство отключает выходной буфер. Линия «всплывает» до HIGH (из-за «слабых подтяжек» к питанию в устройстве). В этом состоянии ведомое SSI-устройство может безопасно выдавать на SDA собственные данные.
  • Чтобы установить на линии DO низкий уровень (LOW), устройство включает выходной буфер и устанавливает на выходе LOW.

Отсюда следует: если линии DO и DI соединены и вы хотите принимать данные от ведомого устройства, на собственном выходе нужно держать «все единицы», пока ведомое устройство должно передавать данные, например так:

...
ssi.str("\x40\x12\xFF",1) 'we anticipate that the slave device will reply after we output two bytes of our own data
...

Каждый обмен по I²C требует так называемых стартовой и стоповой последовательностей - объект ssi. их не формирует, поэтому реализовать их нужно в коде. Ниже приведён фрагмент из реального приложения. Обратите внимание: необходимые переходы на линии SDA выполняются установкой на линии DO уровня LOW с последующим включением и отключением её выходного буфера.

...
i2c_start()
ssi.str("\x40\x12\xFF",1)		'output data, with acknowledgements enabled
i2c_stop()
...
'------------------------------------------------------------
Sub i2c_start()
	io.lineset(SSI_CLK,HIGH)
	io.num=SSI_DO			'set SDA to HIGH first so we can have HIGH->LOW transition
	io.state=LOW			'we are manipulating data line through the OE register
	io.enabled=NO
	io.enabled=YES		'this will set the data output to LOW
End Sub
'------------------------------------------------------------
Sub i2c_stop()
	io.lineset(SSI_CLK,LOW)	'this will remove the ack bit
	io.num=SSI_DO			'set SDA to LOW first so we can have LOW->HIGH transition
	io.state=LOW			'we are manipulating data line through the OE register
	io.enabled=YES
	io.lineset(SSI_CLK,HIGH)
	io.enabled=NO			'this will set the data output to HIGH
End Sub
Исходный материал Tibbo обновлён 15 августа 2022Оригинал на docs.tibbo.com · Сообщить об ошибке