Страница 2 из 3

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

Добавлено: 09 окт 2015, 10:03
Arcanum
rhf-admin писал(а):Да-а-а. Вроде должно работать... но это только при условии, что в момент, когда мы пытаемся читать PCF-ка уже успела запуститься.
Итак, я предлагаю, во-первых сделать проверку Ack от PCF-ки после того как мастер выдал в шину адрес микрухи и ячейки памяти. И если Ack не получен - стоп на шину, пауза и потом следующая попытка.
Второе. Я в проге вижу, где устанавливается что Ack после последнего байта не нужен. Но не вижу где устанавливается, что до этого он нужен. Если конечно в ответ на установку адреса микрухи и адреса ячейки памяти от слэйва получены Ack, то во флагах так и останется ноль и при считывании будет считаться что мастеру нужно посылать Ack... Так, опять упёрлись в то, что нужно проверять, что отвечает слэйв на адресацию...

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

; подпрограма считывания  времени из pcf8583 НАЧАЛО
GetTimeI2C:
cbr   	I2C_flags,0b00000001   			; ack - НУЖЕН. НЕ последний байт
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									; отправили результат работы
так? как проверить что ответил слейв?
проверить бит регистра I2C_flags на предмет поднят или нет, после адресации?
ещё как быть с мультимастерным режимом? проверять есть ли нули на шине перед началом карусели с адресацией/записью/считыванием?
просто помимо тини2313 у меня будет ещё 3 мастера минимум, и каждый из них будет обращаться к pcf8583. каждый из них будет уже с аппаратным и2ц (тиньку использую как случайный памятник своей жмотистости)

з.ы. и чё я мегу8 пожмотил(

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

Добавлено: 09 окт 2015, 10:42
rhf-admin
Ну да, идея такая. Когда слэйв принимает адреса, он же должен акнолиджами отвечать. Если не отвечает, то и смысла в дальнейшем обмене нет, он значит пока не готов.
Насчёт реализации - не совсем так. Никакой флаг перед старт условием устанавливать не нужно. Этот флаг самому нужно выставлять только перед приёмом (тогда он будет посылаться слэйву после приёма, это у тебя правильно делается в конце). При отсылке байта слэйву в этот флаг пишется ответ от слэйва (процедура Send_byte после того как все биты послала, анализирует ответ и переписывает этот флаг).
То есть нужно после выполнения rcall Send_Byte проверять флаг и если он поднят - значит Ack не получен и... и надо что-то делать, например, то, что я предложил в первом посте (то есть stop, пауза и всё по-новой - start, посылка адреса, проверка Ack...)

P.S. Про мультимастерный режим - в упор не помню как это делается, боюсь наврать. :)

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

Добавлено: 09 окт 2015, 12:00
Arcanum
rhf-admin писал(а):Ну да, идея такая. Когда слэйв принимает адреса, он же должен акнолиджами отвечать. Если не отвечает, то и смысла в дальнейшем обмене нет, он значит пока не готов.
Насчёт реализации - не совсем так. Никакой флаг перед старт условием устанавливать не нужно. Этот флаг самому нужно выставлять только перед приёмом (тогда он будет посылаться слэйву после приёма, это у тебя правильно делается в конце). При отсылке байта слэйву в этот флаг пишется ответ от слэйва (процедура Send_byte после того как все биты послала, анализирует ответ и переписывает этот флаг).
То есть нужно после выполнения rcall Send_Byte проверять флаг и если он поднят - значит Ack не получен и... и надо что-то делать, например, то, что я предложил в первом посте (то есть stop, пауза и всё по-новой - start, посылка адреса, проверка Ack...)

блин, совсем запутался...

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

GetTimeI2C:
cbr   	I2C_flags,0b00000001   			; ack - НУЖЕН. НЕ последний байт	
rcall 	Start_uslovie					; старт шины
ldi		BTS, 0xA0						; выдали адрес часов на запись
rcall 	Send_Byte

sbic  I2C_flags,0b00000001             ; проверяем "ack"
как правильно проверить? я туплю на sbic I2C_flags,0b00000001 ; проверяем "ack"
если ack есть то пропускается или что? совсем запустался...
P.S. Про мультимастерный режим - в упор не помню как это делается, боюсь наврать. :)
насчёт этого: принял волевое решение: доделываю эту платку с этим контроллером и приступаю к следующей плате. той же по назначению но с на меге8.
это пока пускай работает на программном и2ц. каждые 30 секнд считывать байт минут и часов. всё.

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

Добавлено: 09 окт 2015, 13:31
rhf-admin
Должно быть так:

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

GetTimeI2C:
   rcall    Stop_uslovie              ; стоп
   rcall    Pause_tbuf                ; чтобы до всех дошло, что шина свободна

   rcall    Start_uslovie             ; старт шины
   ldi      BTS, 0xA0                  ; выдали адрес часов на запись
   rcall    Send_Byte                 ; после этого в нулевом флаге у нас ответ от пцф-ки
   
   sbic  I2C_flags,0b00000001   ; проверяем "ack" (если ноль - всё пучком, ответ есть)
       rjmp GetTimeI2C              ; облом, акнолиджа нет - попробуем ещё раз

   ldi    BTS, 0x02                     ; выдали адрес ячейки памяти байт
   rcall    Send_Byte
   sbic  I2C_flags,0b00000001   ; проверяем "ack" (если ноль - всё пучком, ответ есть)
       rjmp GetTimeI2C              ; облом, акнолиджа нет - попробуем ещё раз
   ...
   ...

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

Добавлено: 09 окт 2015, 13:35
Arcanum
благодарю, сейчас начну изощьраться!
прежде чем залью, вопрос : стоит ли делать счётчик данного цикла чтоб в бесконечность не уйти? а то может вполне и оказаться что адресата то и нет...
upd: ну это уже паранойя

смущает другое: неужели проверка акнолиджа после каждого отосланного байта должна быть?

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

Добавлено: 09 окт 2015, 13:50
rhf-admin
Ну может и не после каждого байта, но по крайней мере после адресования устройства точно. Возможно пцф-ке надо больше времени для старта, чем контроллеру и поэтому она ещё не ожила, а он уже ей байты пихает.
А иногда девайс не отвечает потому что ещё предыдущую команду не успел выполнить. Ты, например, напихал пачку байтов в память I2C-шную на запись, а писать она начинает только когда "СТОП" увидит и пока не запишет - на новые обращения отвечать не будет.

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

Добавлено: 09 окт 2015, 13:54
Arcanum
странно...
D:\EWorkNow\MC_Sourcers\Clock_1Drive_Board\Clock_1Drive_Board.asm(462): error: Invalid number
ругается на sbic I2C_flags,0b00000001

не sbis а sbrc
я невнимателен(

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

Добавлено: 09 окт 2015, 14:14
rhf-admin
точно, надо написать:

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

sbrc I2C_flags,0
вместо

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

sbic I2C_flags,0b00000001

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

Добавлено: 09 окт 2015, 15:36
Arcanum
сделал так:

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

GetTimeI2C:

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

	sbrc  I2C_flags,0   ; проверяем "ack" (если ноль - всё пучком, ответ есть)
	rjmp GetTimeI2C_1              ; облом, акнолиджа нет - попробуем ещё раз


ldi 	BTS, 0x02						; выдали адрес ячейки памяти байт
rcall 	Send_Byte
  	sbrc  I2C_flags,0   ; проверяем "ack" (если ноль - всё пучком, ответ есть)
	rjmp GetTimeI2C_2              ; облом, акнолиджа нет - попробуем ещё раз
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
RET

GetTimeI2C_1:
LDI		tmp2, '1'
rcall 	Load_Buff_TX
GetTimeI2C_2:
LDI		tmp2, '2'
rcall 	Load_Buff_TX

TX_RUN									; отправили результат работы

RET
то есть если нет первого акнолиджа нет то всё пропускается и записывается 12, только второго то 2.сделал для отладки. однакоже у меня в буфер записывается ff ff ff. ничего не понимаю(

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

Добавлено: 09 окт 2015, 17:19
Arcanum
привожу рабочий код который только что запустился:

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

GetTimeI2C:

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



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

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

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
RET
кому не лень может поискать в чём мобака была зарыта!
Админу форума: БОЛЬШАЯ БЛАГОДАРНОСТЬ!

з.ы. как быть с мультимастером? ещё одну подпрограмму рисовать для проверки состяния шины или как?