I2C шлюз для компьютера

Всё об интерфейсах, протоколах, подключении к МК разных устройств, подключении контроллеров к ПК...
Аватара пользователя
rhf-admin
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
Сообщения: 3060
Зарегистрирован: 25 авг 2009, 23:19
Откуда: Уфа
Контактная информация:

I2C шлюз для компьютера

Сообщение rhf-admin »

С уважением, администрация сайта.
molyman
спонсор, инженер, идеолог, читатель
спонсор, инженер, идеолог, читатель
Сообщения: 362
Зарегистрирован: 15 май 2011, 17:03
Откуда: г.Москва
Контактная информация:

Re: I2C шлюз для компьютера

Сообщение molyman »

Вот это круто это я наверно слеплю по вашей схеме надо чипы по I2C погонять некие.
Если хочешь что-то сделать, сделай это сам!
Аватара пользователя
rhf-admin
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
Сообщения: 3060
Зарегистрирован: 25 авг 2009, 23:19
Откуда: Уфа
Контактная информация:

Re: I2C шлюз для компьютера

Сообщение rhf-admin »

Фу, наконец удалось программку оформить. Она-то как раз и делает описанный кусок железа шлюзом, умеющим общаться по I2C в режиме мастера.
Предполагается, что это только начало, дальше планирую на той же базе I2C-сниффер и I2C-slave, а потом всё запихать в одну прогу. Получится идеальный шпиён за I2C, который и покомандовать сможет, и подсмотреть, и прикинуться кем-нибудь.
С уважением, администрация сайта.
Аватара пользователя
rhf-admin
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
Сообщения: 3060
Зарегистрирован: 25 авг 2009, 23:19
Откуда: Уфа
Контактная информация:

Re: I2C шлюз для компьютера

Сообщение rhf-admin »

Эхэй, вот и продолжение, - программка, позволяющая шлюзу прикинуться slave-устройством.
Заодно тут можно посмотреть - как программно сделать I2C-Slave режим (я почему-то в инете так ничего приличного на эту тему и не нашёл - пришлось лепить самому). Это оказалось чуть сложнее, чем Master, но всё же вполне себе реализуемо. 8-)
Чуть переделав прогу, можно даже и посниферить. :)
Дальше наверное сделаю из двух прог одну и напишу какую-нить прогу для компа, чтоб эмулировать всякие разные слэйвы (или мож кто другой напишет?).
С уважением, администрация сайта.
sherr
Читатель
Читатель
Сообщения: 1
Зарегистрирован: 21 мар 2013, 13:16

Re: I2C шлюз для компьютера

Сообщение sherr »

А можно готовый HEX или почищенный исходник для I2c сниффера ?
johnic
Читатель
Читатель
Сообщения: 1
Зарегистрирован: 28 мар 2013, 17:49

Re: I2C шлюз для компьютера

Сообщение johnic »

Зачем нужен выход CS 9 вывод МК? И можно выложить прошивку для сниффера.
Аватара пользователя
rhf-admin
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
Сообщения: 3060
Зарегистрирован: 25 авг 2009, 23:19
Откуда: Уфа
Контактная информация:

Re: I2C шлюз для компьютера

Сообщение rhf-admin »

CS - это сигнал chip select. Просто он у многих I2C микрух присутствует, поэтому и был реализован (ну и потом я подумал - пусть будет на всякий случай, можно ведь им и не пользоваться, если не надо, а для SPI всё равно пригодится).

Сниффер на днях выложу, раз народ требует :) (вот времени найду чуток и сразу выложу).
С уважением, администрация сайта.
Аватара пользователя
rhf-admin
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
Сообщения: 3060
Зарегистрирован: 25 авг 2009, 23:19
Откуда: Уфа
Контактная информация:

Re: I2C шлюз для компьютера

Сообщение rhf-admin »

Вот что получилось со сниффером:
com-i2c_sniffer.7z
(3.73 КБ) 785 скачиваний
Не проверял, но должно работать.
С уважением, администрация сайта.
Arcanum
Читатель
Читатель
Сообщения: 32
Зарегистрирован: 04 окт 2015, 19:43

Re: I2C шлюз для компьютера

Сообщение Arcanum »

Всем привет! Начну со слов благодарности: круто когда есть подобные сайты где всё разжёвано и можно с включением мозгов использовать под свои нужды!
Я взял код из статьи шлюза и встроил его в свой проект.
что есть: attiny2313, pcf8583. напряжение питания 3.3В. Кварц на тиньку 8МГц.
что я сделал(заранее извиняюсь за длинные листинги), привожу те куски кода что не работает, ибо остальное работает:
взял процедурки "как есть"

Код: Выделить всё

; i2c линии
.equ I2C_P = PortB
.equ I2C_D = DdrB
.equ I2C_N = PinB

.equ Clock = 7	; PortB7/PinB7/DdrB7 - clock SCL
.equ Data = 5	;  PortB5/PinB5/DdrB5 - data SDA
;****************************
.def   w			= r26			; это будет наш аккумулятор
.def   Bit_counter	= r27			; счётчик бит
.def   I2C_flags	= r28			; флаги I2C
;-- флаг 0 - ack, при сброшенном флаге - посылаем ack
;-- флаг 1 - rcv, поднятый флаг - признак ожидания второго байта от компа
;-- (если флаг поднят - значит комп передаёт шлюзу
;-- двухбайтное сообщение и мы ждём второй байт)
.def   BTS			= r29			; байт для передачи
.def   RDB			= r30			; принятый байт

;**************************** 
;конфигуригуем выводы IIC шины.
CBI I2C_D, Clock
CBI I2C_D, Data
CBI I2C_P, Clock
CBI I2C_P, Data
;конфигуригуем выводы IIC шины.

;=============================================================================
;--- Процедуры I2C ---------------------------------------
;-- сигнал ack - инвертированный, т.е. если он -----------
;-- ноль - есть ack, если 1 - нет ack --------------------
Clock_null:                ; установка нуля на линии Clock
	  sbi  I2C_D,Clock      ; переключаем ногу на выход
	  ret                  ; (ноль в защёлку мы записали ещё при старте)
Clock_one:             ; установка единицы на линии Clock
	  cbi  I2C_D,Clock    ; переключаем ногу в Z-состояние
	  ret
Data_null:             ; установка нуля на линии Data
	  sbi  I2C_D,Data     ; переключаем ногу на выход
	  ret                  ; (ноль в защёлку мы записали ещё при старте)
Data_one:              ; установка единицы на линии Data
	  cbi  I2C_D,Data     ; переключаем ногу в Z-состояние
	  ret
 ;--- start ----------
Start_uslovie:            ; формирование старт-условия
	  rcall Clock_one
	  rcall Pause_tbuf     ; "свободная шина" (4,7 мкс)
	  rcall Data_null
	  rcall Pause_thdsta   ; "фиксация старт-условия" (4 мкс)
	  rcall Clock_null
	  ret
;--- stop -----------
Stop_uslovie:             ; формирование стоп-условия
	  rcall Data_null
	  rcall Clock_one
	wait_clock_p:
	  sbis  I2C_N,Clock     ; проверяем шину Clock
	  rjmp  wait_clock_p   ; ждём, пока отпустится шина Clock
	  rcall Pause_tsusto   ; "готовность стоп-условия" (4 мкс)
	  rcall Data_one
	  ret
;--- transmit -------
Send_Byte:
	  cbr   I2C_flags,0b00000001  ; сбрасываем флаг подтверждения
	  ldi   Bit_counter,8         ; устанавливаем счётчик бит
	next_bit_s:
	  sbrc  BTS,7
	  rcall Data_one              ; если передаваемый бит = 1
	  sbrs  BTS,7
	  rcall Data_null             ; если передаваемый бит = 0
	  rcall Pause_tsudat          ; "готовность данных" (250 нс)
	  rcall Clock_one
	wait_clock_s1:
	  sbis  I2C_N,Clock
	  rjmp  wait_clock_s1
	  rcall Pause_thigh           ; длительность полупериода считывания (4 мкс)
	  rcall Clock_null
	  lsl   BTS                   ; сдвиг влево
	  dec   Bit_counter           ; уменьшаем счётчик
	  brne  next_bit_s            ; если счётчик не равен нулю - шлём ещё
	  rcall Data_one              ; если всё - отпускаем линию Data
	  rcall Pause_tlow            ; длительность полупериода установки (4 мкс)
	  rcall Clock_one
	wait_clock_s2:
	  sbis  I2C_N,Clock            ; проверяем - отпустилась ли линия Clock
	  rjmp  wait_clock_s2
	  sbic  I2C_N,Data             ; проверяем "ack"
	  sbr   I2C_flags,0b00000001  ; если нет - поднимаем флаг
	  rcall Pause_thigh           ; длительность полупериода считывания (4 мкс)
	  rcall Clock_null            ; снова занимаем шину
	  ret
;--- recieve --------
Recieve_Byte:
	  clr   RDB                   ; очищаем приёмник
	  ldi   Bit_counter,8         ; устанавливаем счётчик
	next_bit_r:
	  lsl   RDB                   ; сдвигаем влево приёмный регистр
	  rcall Data_one              ; отпускаем линию Data
	  rcall Pause_tlow            ; длительность полупериода установки (4 мкс)
	  rcall Clock_one             ; отпускаем clock
	wait_clock_r1:
	  sbis  I2C_N,Clock            ; ждём когда отпустится clock
	  rjmp  wait_clock_r1
	  sbic  I2C_N, Data            ; если Data=1 - пишем в младший бит приёмника 1,
	  sbr   RDB,0b00000001        ; если нулю - пропускаем эту команду
	  rcall Pause_thigh           ; длительность полупериода считывания (4 мкс)
	  rcall Clock_null            ; роняем clock
	  dec   Bit_counter           ; уменьшаем счётчик
	  brne  next_bit_r            ; если результат не равен нулю - читаем дальше
	  sbrs  I2C_flags,0
	  rcall Data_null             ; если надо посылать ack - роняем Data
	  sbrc  I2C_flags,0
	  rcall Data_one              ; если не надо посылать ack - отпускаем Data
	  rcall Pause_tlow            ; длительность полупериода установки (4 мкс)
	  rcall Clock_one             ; отпускаем Clock
	wait_clock_r2:
	  sbis  I2C_N,Clock            ; ждём, пока установится Clock
	  rjmp  wait_clock_r2
	  rcall Pause_thigh           ; даём время slav-у увидеть наш ack
								  ; (или его отсутствие)
	  rcall Clock_null            ; роняем Clock
	  ret
;--- Конец процедур I2C -------------------------------
		;--- Задержки для частоты шины 100 кГц ------
 ;-- свободная шина (4,7 мкс) --
	Pause_tbuf:
		  ldi w,27
		wait_tbuf:
		  dec w
		  brne wait_tbuf
ret
;-- фиксация старт-условия (4 мкс) --
	Pause_thdsta:
		  ldi w,23
		wait_thdsta:
		  dec w
		  brne wait_thdsta
		  ret
;-- готовность стоп-условия (4 мкс) --
	Pause_tsusto:
		 ldi w,23
		wait_tsusto:
		  dec w
		  brne wait_tsusto
		  ret
;-- готовность данных (250 нс) --
	Pause_tsudat:
		  nop
		  ret
;-- длительность полупериода считывания (4 мкс) --
	Pause_thigh:
		  ldi w,23
		wait_thigh:
		  dec w
		  brne wait_thigh
		  ret
;-- длительность полупериода установки (4 мкс) --
	Pause_tlow:
		  ldi w,23
		wait_tlow:
		  dec w
		  brne wait_tlow
		  ret
		;---------------------------------------------------------
;=============================================================================

как я это использую у себя в проекте:

Код: Выделить всё

; подпрограма считывания  времени из pcf8583 НАЧАЛО
GetTimeI2C:

rcall 	Start_uslovie					; старт шины
ldi		BTS, 0xA0						; выдали адрес часов на запись
rcall 	Send_Byte

ldi 	BTS, 0x02						; выдали адрес ячейки памяти байт
rcall 	Send_Byte

rcall 	Start_uslovie					; повторный старт
ldi 	BTS, 0xA1						; выдали адрес часов на чтение

rcall 	Recieve_Byte					; забрали байт секунд
mov 	tmp2,RDB						; сохранили байт в буфере
rcall 	Load_Buff_TX

rcall 	Recieve_Byte					; забрали байт минут
mov 	tmp2,RDB						; сохранили байт в буфере
rcall 	Load_Buff_TX

sbr   	I2C_flags,0b00000001   			; ack - НЕ нужен. ПОСЛЕДНИЙ байт
rcall	Recieve_Byte					; забрали байт часов
mov 	tmp2,RDB						; сохранили байт в буфере
rcall 	Load_Buff_TX

rcall 	Stop_uslovie					; Стоп шины

TX_RUN								; отправили результат работы
при запуске кода он выдаёт мне в терминал FF FF FF, то есть считывает единицы с линии и всё. два дня уже мозги морщю, понять не могу. сама микруха pcf8583 рабочаяя - считывал с неё байты через мегу 32 (у неё аппаратный и2ц) - байты показываются корректно.
Аватара пользователя
rhf-admin
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
администратор, спонсор, писатель, дизайнер, инженер, программист, идеолог
Сообщения: 3060
Зарегистрирован: 25 авг 2009, 23:19
Откуда: Уфа
Контактная информация:

Re: I2C шлюз для компьютера

Сообщение rhf-admin »

Да-а-а. Вроде должно работать... но это только при условии, что в момент, когда мы пытаемся читать PCF-ка уже успела запуститься.
Итак, я предлагаю, во-первых сделать проверку Ack от PCF-ки после того как мастер выдал в шину адрес микрухи и ячейки памяти. И если Ack не получен - стоп на шину, пауза и потом следующая попытка.
Второе. Я в проге вижу, где устанавливается что Ack после последнего байта не нужен. Но не вижу где устанавливается, что до этого он нужен. Если конечно в ответ на установку адреса микрухи и адреса ячейки памяти от слэйва получены Ack, то во флагах так и останется ноль и при считывании будет считаться что мастеру нужно посылать Ack... Так, опять упёрлись в то, что нужно проверять, что отвечает слэйв на адресацию...
С уважением, администрация сайта.
Ответить

Вернуться в «Интерфейсы / Протоколы / Периферия»