Перейти к содержанию
    

Продолжаю добивать TWI. Хочу разобраться в конце-концов.

Вопрос такой: на вызов мастера-передатчика должны отвечать оба слэйва? Какие действия должен предпринимать тот слэйв, адрес которого не совпал с переданным мастером?

Раньше я делал так: от мастера к каждому слэйву кроме линий TWI шли еще по одной линии - разрешение на связь с мастером. Соответствующая линия сбрасывается в "0", если мастер хочет передавать данные на этот слэйв; вторая линия в "1", т.е. второй слэйв вообще не заходит в программу приема данных по TWI. Так не заработало - могу передать только на первый слэйв, при попытке передать на второй - все зависало - окончательно и безнадежно.

Теперь сделал по-другому. Должно, по идее, работать так:

мастер сбрасывает в "0" обе линии (разрешение на связь с мастером). Тот слэйв, адрес которого не совпал, выходит из программы приема данных, и продолжает выполнять основную прогу. А тот слэйв, адрес которого совпал - принимает данные.

Но и здесь не все гладко.

Мастер (m32) передает данные на слэйв1 (m32) - тут все нормально. Но слэйв2 (m16) при этом висит!

Нажимаю на кнопочку, чтобы начать передавать данные на слэйв2 - он при этом выходит из зависания, и данные передаются на оба контроллера - так и должно быть. При этом слэйв1 не зависает.

При включении передачи на слэйв1 - слэйв2 опять зависает.

 

Как тут быть?

 

P.S. Кстати, описанная ситуация происходит, если при связи с обоими МК мастер выдает повторный старт.

Если мастер дает сигнал старт - все безнадежно зависает (при попытке передать на слэйв2).

ИМХО вы не разобрались с протоколм I2C. Зачем вы ведёте линии разрешения если в протокол заложена АДРЕСАЦИЯ? вероятно у вас с этим и глюки связаны. Слэйв, адрес которого не совпадает, с адресом, который передаётся по шине НИЧЕГО С ШИНОЙ ДЕЛАТЬ НЕ ДОЛЖЕН.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

TWI у меня работает не по своим прерываниям, а в основной программе (в обработчике таймера). Линии разрешения я сделал для того, чтобы слэйвы не ждали, когда к ним обратится мастер, из-за этого прога будет работать очень медленно.

Начало обработки TWI (слэйв):

 

 

Fr_M:  sbic  PIND,6;Проверка: мастер готов передавать данные?
     rjmp Go_prog;Если нет - прога выполняется дальше

Fr_M_n: ldi temp,$20;Инициализация режима "Приемник"
      out TWAR,temp

TWINT_n:ldi temp,(1<<TWINT)|(1<<TWEA)|(1<<TWEN)
       out TWCR,temp

wait1n:  in temp,TWCR;Ожидаем вызова от мастера
            sbrs temp,TWINT
            rjmp wait1n

            in temp,TWSR
            andi temp,$F8
            cpi temp,$60;Проверка принятого адреса от мастера
            breq Pr_data

            ldi temp,(1<<TWINT)|(1<<TWEN)
            out TWCR,temp

            rjmp Go_prog

;Прием данных:

Pr_data:

Изменено пользователем James D.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

TWI у меня работает не по своим прерываниям, а в основной программе (в обработчике таймера). Линии разрешения я сделал для того, чтобы слэйвы не ждали, когда к ним обратится мастер, из-за этого прога будет работать очень медленно.

 

сделайте как полагается, по своим прерываниям. а потом можете говорить что TWI не работает. Мне кажется из-за этих разрешений-запрещений шина и виснет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

TWI у меня работает не по своим прерываниям, а в основной программе (в обработчике таймера). Линии разрешения я сделал для того, чтобы слэйвы не ждали, когда к ним обратится мастер, из-за этого прога будет работать очень медленно.

Начало обработки TWI (слэйв):

 

Тут не просто кажеться ,тут 200% будут глюки.

Если мастера еще можно сделать в основной программе,то подчиненного только по прерыванию.

Слейв выдает NACK если адресс не совпадает и наоборот ACK если совпадает.

По этому и ориентируется мастер,а слейв выдает по TWSR &h60 если к нему обратились и

&h80 если после адресса пошли данные.

Если делать по прерыванию,не нужно ничего ждать и проверять.

В подпрограмме обработки прерывания достаточно проверять значения TWSR и

соответственно реагировать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В подпрограмме обработки прерывания достаточно проверять значения TWSR и

соответственно реагировать.

 

Что должен делать слэйв, адрес которого не совпал?

Должен ли он выдавать NACK (см. ниже - я так понял, так выдается NACK):

ldi temp,(1<<TWINT)|(1<<TWEN)

out TWCR,temp

 

Потом он выходит из прерывания - это понятно.

 

В основной проге я сделал обработку TWI, потому что так было удобнее. Если это не правильно, тогда, конечно, придется делать по спец. прерываниям.

На вызов мастера-передатчика должны отвечать ВСЕ слэйвы? В даташите написано, что все МК должны быть просто запитаны. Вот я и делал, что у меня отвечал только один, а второй вообще игнорировал вызов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что должен делать слэйв, адрес которого не совпал?

........

На вызов мастера-передатчика должны отвечать ВСЕ слэйвы?

НАСТОЯТЕЛЬНО рекомендую перечитать информацию о I2C и TWI в частности.

 

в неккоторых AVR'ках присутствует АППАРАТНЫЙ I2C~TWI. это обозначает что большинство действий с протоколом возложено на плечи железа, например генерация NACK(а точнее отсутствие генерации ACK) если адрес не совпал... т.е. ваши действия по работе с TWI (slave):

1) на каждое устройство придумать УНИКАЛЬНЫЙ адрес из диапазона 1-127. (0 адрес используется для массовых сообщений его выставлять НЕ надо).

2) записать адрес в регистр TWAR выбранный адрес сдвинутый на один бит влево.

3) настроить контрольный регистр TWI (TWСR) TWIE=1, TWEN=1, TWEA=1.

 

4) ждать прерывание.

 

5) при прирывании в зависимости от регистра TWSR выполнить соответствуюшие действия (какие именно расписано в даташите)

 

6) поблагодарить меня за то что научил уму-разуму =)

 

7) получить пилюлей от IgorKossak за п. 6) :twak:

Изменено пользователем IgorKossak

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2) записать адрес в регистр TWAR выбранный адрес сдвинутый на один бит влево.

 

Зачем?

 

3) настроить контрольный регистр TWI (TWСR) TWIE=1, TWEN=1, TWEA=1.

 

А TWINT не надо сбрасывать(в слэйве) при настройке, и в процессе работы (а также при выходе из обработчика прерывания)?

 

Пока что у меня мастер зависает при попытке что-либо передать на любой из слэйвов...

А слэйвы работают.

Изменено пользователем James D.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2) записать адрес в регистр TWAR выбранный адрес сдвинутый на один бит влево.

 

Зачем?

 

3) настроить контрольный регистр TWI (TWСR) TWIE=1, TWEN=1, TWEA=1.

 

А TWINT не надо сбрасывать(в слэйве) при настройке, и в процессе работы (а также при выходе из обработчика прерывания)?

 

Пока что у меня мастер зависает при попытке что-либо передать на любой из слэйвов...

А слэйвы работают.

 

1) конктретизуй вопрос. Зачем адрес записывать или зачем сдвигать на бит его.

2) мастер зависает скорее всего НЕ дожидаясь ACK от устройства.

3) TWINT надо сбрасывать только в обработчике прерываний, после того, как необходимая реакция на прерывание будет выполнена.

Изменено пользователем Petka

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1) конктретизуй вопрос. Зачем адрес записывать или зачем сдвигать на бит его.

"Сдвиг на бит" это если не сказать "записать адрес слейва в поле адреса".

Делать это надо, чтобы слейв реагировал только на СВОЙ адрес, записанный в указанный регистр

2) мастер зависает скорее всего НЕ дожидаясь ACK от устройства.

И не дождётся, т. к. у слейва не прописан свой адрес по которому его мастер спрашивает.

3) TWINT надо сбрасывать только в обработчике прерываний, после того, как необходимая реакция на прерывание будет выполнена.

Или в фоновой программе если прерывания не применяются (тогда опрашивать надо быстро, чтобы не пропустить события).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Установил адрес слэйва - $40, а мастер вызывает адресом - $20. Так?

При запуске контроллеров мастер передает слэйву несколько байт в фоновом режиме (в основной программе), до разрешения общих прерываний, настройки таймеров и т.д. Проходит нормально, даже если у слэйва адрес $20, или $40 (мастер передает адрес $20).

Вот, что получается потом.

 

;Инициализация TWI:

  ldi  temp,$40 ;Инициализация режима "Приемник"
  out  TWAR,temp
  ldi  temp,(1<<TWEA)|(1<<TWEN)|(1<<TWIE)
  out  TWCR,temp

  sei

 

Слэйв-приемник постоянно входит в обработчик прерывания TWI, производит проверку адреса (код $60 не соответствует, и выходит из прерывания), даже если мастер вообще передачу по TWI не начинает.

Если мастер пытается что-либо передать, то зависает после загрузки адреса + WR (TWDR) на этапе ожидания, когда TWINT уст. в "1".

 

wait: in  temp,TWCR;Ожидаем ответа от слэйва
  sbrs temp,TWINT
  rjmp wait

 

А этот бит устанавливаться не хочет.

В чем же тут дело?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Установил адрес слэйва - $40, а мастер вызывает адресом - $20. Так?

........

Слэйв-приемник постоянно входит в обработчик прерывания TWI, производит проверку адреса (код $60 не соответствует, и выходит из прерывания), даже если мастер вообще передачу по TWI не начинает.

...........

В чем же тут дело?

 

1) Адреса должны совпадать.

2) В прерывании вы ДОЛЖНЫ обрабатывать все события, не только $60. у меня, например сеть висла, если я не обрабатывал $F8 и $00.

3) успехов!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хорошо,обьясняю популярнее.

 

Слейву вообще по барабану что твориться на шине,

все гораздо проще чем вы думаете.

Если на шине не то что ему нужно,он просто не

выдаст прерывания

 

Первое прерывание возникнет только после того,когда

проидет СТАРТ и совпадет адресс слейва,TWSR выдаст НЕХ 60,

кричим УРА ,устанавливаем TWINT=1 и дружно выходим из прерывания.

TWI при этом АППАРАТНО выдает АСК.

 

Второе и ДАЛЕЕ прерывание возникнет после того,когда

прибудут данные ЕСЛИ ПЕРЕД ЭТИМ СОВПАЛ АДРЕСС

( то есть уже прошли первое прерывание)

TWSR выдаст НЕХ 80.устанавливаем TWINT=1 и

в TWDR имеем полученные данные,отправляем их куда хотим.

выходим из прерывания.

 

И ПОСЛЕДНЕЕ решаем выставлять нам АСК при следующем получении

данных или нет.

ЕСЛИ НЕТ тогда в следующем прерывании TWSR выдаст НЕХ 88

а МАСТЕР должен выдать СТОП.

Соответственно мастер должен определять NACK и выдавать СТОП на шину.

 

ПОСЛЕДНЕЕ в принципе не обязательно.

Просто если охота делать так как книжка пишет.

 

Сложно?

Я думаю проще некуда.

 

У меня при таком раскладе слев легко берет пакеты со скоростью

800Кбит в сек ,при частоте проца 8Мгц

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Установил адрес слэйва - $40, а мастер вызывает адресом - $20. Так?

........

Слэйв-приемник постоянно входит в обработчик прерывания TWI, производит проверку адреса (код $60 не соответствует, и выходит из прерывания), даже если мастер вообще передачу по TWI не начинает.

...........

В чем же тут дело?

 

1) Адреса должны совпадать.

2) В прерывании вы ДОЛЖНЫ обрабатывать все события, не только $60. у меня, например сеть висла, если я не обрабатывал $F8 и $00.

3) успехов!

 

1. А кто мне говорил, что адрес в слэйве надо сдвигать на 1 бит?

2. Что нужно делать, если выпадет $F8 и $00?

3. Спасибо! Хорошо бы, чтоб они появились!

 

То bodja74:

"Если на шине не то что ему нужно,он просто не

выдаст прерывания"

А вот и нет - выдает постоянно, даже если к нему никто не обращается.

 

А если слэйву из прерывания не выходить, при приеме адреса, данных, а принимать все в пределах одного прерывания по TWI? Просто ждать, когда TWINT уст. в "1"?

 

"И ПОСЛЕДНЕЕ решаем выставлять нам АСК при следующем получении

данных или нет."

Что-то я не пойму все-таки, как слэйв должен выдавать ACK или NACK. Это же делается аппаратно? Как это сделать программно?

 

Мастер на шине один, и два подчиненных. Значит обработку ошибок касательно арбитража можно откинуть? Что должен делать слэйв, если его адрес не совпал с переданным мастером? В даташитовской таблице для подч-приемника это не описано.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Добрый день

 

Вот бы кто из действительно шарящих людей описал бы подробно процесс обмена

в случае с однирм мастером (приемником и передатчиком) и 2 слейвами

 

Ну типа там

1. Мастер посылает АСК ....

2. .....

 

Всем Спасибо

 

De}{teR

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот бы кто из действительно шарящих людей описал бы подробно процесс обмена

в случае с однирм мастером (приемником и передатчиком) и 2 слейвами

а чем ,простите, шит не устраивает . имхо все доходчиво

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...