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