реклама на сайте
подробности

 
 
19 страниц V  « < 7 8 9 10 11 > »   
Reply to this topicStart new topic
> Проблема с TWI
IgorKossak
сообщение Dec 21 2005, 10:10
Сообщение #121


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(m16 @ Dec 21 2005, 12:06) *
а чем ,простите, шит не устраивает . имхо все доходчиво

Ну, например, на русский его перевести. cool.gif
Хотя, ести перечитать всю эту тему, то это уже сделано.
Go to the top of the page
 
+Quote Post
Petka
сообщение Dec 21 2005, 10:57
Сообщение #122


Профессионал
*****

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



Цитата(IgorKossak @ Dec 21 2005, 13:10) *
Цитата(m16 @ Dec 21 2005, 12:06) *

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

Ну, например, на русский его перевести. cool.gif
Хотя, ести перечитать всю эту тему, то это уже сделано.


Уважаемый Games D.! Вы задаёте вопросы на которые ЕСТЬ однозначные ответы в datahsheet на AVR (если быть точнее в разделе "Two-wire Serial Interface"), поэтому у меня есть конструктивное предложение: задавайте вопросы в таком виде "в пункте таком-то даташита написано что надо делать так-то, что бы получить то-то а у меня выходит сяк-то.". просто практика показывает что если делать, как рекомендуется в datasheet, то всё работает с первого раза и с минимальными временами на отладку.

для общего ознакомления с I2C можно прочитать это (на русском).
Прикрепленные файлы
Прикрепленный файл  i2c.pdf ( 179.42 килобайт ) Кол-во скачиваний: 62
 
Go to the top of the page
 
+Quote Post
James D.
сообщение Dec 21 2005, 11:25
Сообщение #123


Местный
***

Группа: Участник
Сообщений: 315
Регистрация: 10-10-05
Пользователь №: 9 466



Я делаю так - передача одного байта (без обработки ошибок), пусть меня поправят, если я не прав:

1. Мастер производит установку скорости передачи (TWSR, TWBR);
2. Посылает сигнал START: (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
3. Ожидает, когда бит TWINT в TWCR установится в "1";

Слэйв работает по прерываниям TWI; как только происходит перепад из "1" в "0" на шине SDA (при "1" на шине SCL) - значит мастер послал сигнал START, при этом бит TWINT в слэйве уст. в "1"; происходит прерывание и переход на обработчик, в котором слэйв проверяет значение в регистре TWSR (только непонятно, выдает ли при этом слэйв аппаратно ACK?).

4. Мастер, дождавшись установки бита TWINT в "1", проверяет значение в TWSR - оно должно соответствовать $08;
5. Мастер загружает адрес слэйва, допустим $20 в TWDR, обновляет регистр TWCR: (1<<TWINT)|(1<<TWEN);
6. Ожидает, когда бит TWINT в TWCR установится в "1";

Если слэйв определил, что значение TWSR не соответствует $60, значит мастер обращается не к этому слэйву. Слэйв аппаратно выдает NACK и выходит из прерывания - выполняется далее основная программа.
Если значение соответствует $60 - слэйв аппаратно выдает ACK, записывает новое значение в TWCR: (1<<TWINT)|(1<<TWEA)|(1<<TWEN), и ждет, когда бит TWINT в TWCR установится в "1".

7. Мастер, дождавшись установки бита TWINT в "1", проверяет значение в TWSR - оно должно соответствовать $18 - адрес слэйвом принят, мастером получен ACK;
8. Заносит в TWDR передаваемый байт;
9. Обновляет TWCR: (1<<TWINT)|(1<<TWEN);
10. Ожидает, когда бит TWINT в TWCR установится в "1";

Слэйв, дождавшись, когда бит TWINT уст. в "1", проверяет рег. TWSR - должен быть код $80; выдает на шину ACK, и сохраняет принятый байт из TWDR в свою память. Далее готовится к приему команды STOP: обновляет TWCR: (1<<TWINT)|(1<<TWEA)|(1<<TWEN), и ждет, когда бит TWINT в TWCR установится в "1".

11. Мастер, дождавшись установки бита TWINT в "1", проверяет значение в TWSR - оно должно соответствовать $28 - данные слэйвом приняты, мастером получен ACK;
12. Мастер, обновляет TWCR: (1<<TWINT)|(1<<TWSTO)|(1<<TWEN), и выходит из программы передачи данных - продолжает выполняться основная программа.

Слэйв, дождавшись, когда бит TWINT уст. в "1", проверяет рег. TWSR - должен быть код $A0. После этого слэйв выходит из программы приема данных - продолжает выполняться основная программа.
Go to the top of the page
 
+Quote Post
Petka
сообщение Dec 21 2005, 11:32
Сообщение #124


Профессионал
*****

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



Цитата(James D. @ Dec 21 2005, 14:25) *
Я делаю так - передача одного байта (без обработки ошибок), пусть меня поправят, если я не прав:

1. Мастер производит установку скорости передачи (TWSR, TWBR);
2. Посылает сигнал START: (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
3. Ожидает, когда бит TWINT в TWCR установится в "1";

ВОТ ГДЕ ОШИБКА!!!
надо ждать не "1" а "0".
ибо: "The TWINT flag must be cleared by software by writing a logic one to it"
если флаг "cleared" - "by writing logic ONE" значит флаг имеет ИНВЕРСНУЮ логику!
исправляйте ошибку, будем дальше дебажить =)
Go to the top of the page
 
+Quote Post
James D.
сообщение Dec 21 2005, 13:13
Сообщение #125


Местный
***

Группа: Участник
Сообщений: 315
Регистрация: 10-10-05
Пользователь №: 9 466



Так, заменил на ожидание "0" (в цикле ожидания сразу после посылки START) - теперь мастер зависает здесь:

7. Мастер, дождавшись установки бита TWINT в "1", проверяет значение в TWSR - оно должно соответствовать $18 - адрес слэйвом принят, мастером получен ACK;

то есть код в TWSR не равен $18.

SLA_Wn: ldi temp,$20 ;Загрузка адреса слэйв + "WRITE"
out TWDR,temp
ldi temp,(1<<TWINT)|(1<<TWEN)
out TWCR,temp

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

in temp,TWSR
andi temp,$F8
cpi temp,$18
brne SLA_Wn ;Переход, если ответ от слэйв неверный

А раньше зависал в цикле wait2n.
Go to the top of the page
 
+Quote Post
James D.
сообщение Dec 21 2005, 13:30
Сообщение #126


Местный
***

Группа: Участник
Сообщений: 315
Регистрация: 10-10-05
Пользователь №: 9 466



Кстати, в даташите (в приведенном там примере) стоит ожидание "1" - после посылки START.

P.S. Прочитал PDF'ку, и сразу возник вопрос: надо ли в процессе работы TWI как-то коммутировать порты (PC0, PC1). У меня они настроены на ввод с вкл. подтягивающими резисторами.

Сообщение отредактировал James D. - Dec 21 2005, 13:57
Go to the top of the page
 
+Quote Post
Petka
сообщение Dec 21 2005, 14:00
Сообщение #127


Профессионал
*****

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



Цитата(James D. @ Dec 21 2005, 16:30) *
Кстати, в даташите (в приведенном там примере) стоит ожидание "1" - после посылки START.


Какой вы упёртый =)

цитата из даташита:

"while (!(TWCR & (1<<TWINT))); // Wait for TWINT flag set. This indicates that the START condition has been transmitted"

Сообщение отредактировал Petka - Dec 21 2005, 14:03
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Dec 21 2005, 14:24
Сообщение #128


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(James D. @ Dec 21 2005, 13:25) *
Я делаю так - передача одного байта (без обработки ошибок), пусть меня поправят, если я не прав:

1. Мастер производит установку скорости передачи (TWSR, TWBR);
2. Посылает сигнал START: (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
3. Ожидает, когда бит TWINT в TWCR установится в "1";

Слэйв работает по прерываниям TWI; как только происходит перепад из "1" в "0" на шине SDA (при "1" на шине SCL) - значит мастер послал сигнал START, при этом бит TWINT в слэйве уст. в "1"; происходит прерывание и переход на обработчик, в котором слэйв проверяет значение в регистре TWSR (только непонятно, выдает ли при этом слэйв аппаратно ACK?).

Нет такого события. Слейв не реагирует на START.
Зато есть событие
Код
0x60 Own SLA+W has been received; ACK has been returned

Это значит, что первое прерывание у слейва возникает только если его адрес совпал или было обращение по широковещательному адресу (событие 0x70) или их ошибочные варианты (0x68, 0x78).
Далее требуется коррекция Вашего алгоритма.
Go to the top of the page
 
+Quote Post
James D.
сообщение Dec 21 2005, 14:54
Сообщение #129


Местный
***

Группа: Участник
Сообщений: 315
Регистрация: 10-10-05
Пользователь №: 9 466



Цитата
Это значит, что первое прерывание у слейва возникает только если его адрес совпал или было обращение по широковещательному адресу (событие 0x70) или их ошибочные варианты (0x68, 0x78).
Далее требуется коррекция Вашего алгоритма.


Но ведь слэйв проверяет содержимое TWSR на соответствие $60 как раз в обработчике прерывания, значит само прерывание возникает до того.
У меня обработчик слэйва начинается так:

Код
;*******************************************************************
;Режим - подчиненный-приемник:

TWI_Obr:in  temp,TWSR
  andi temp,$F8
  cpi  temp,$60 ;Проверка принятого адреса
  breq Pr_data  ;Переход на прием данных
  reti
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Dec 21 2005, 15:19
Сообщение #130


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(James D. @ Dec 21 2005, 16:54) *
Код
;*******************************************************************
;Режим - подчиненный-приемник:

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

В таблице Status Codes for Slave Receiver Mode в поле Application Software Response To TWCR требуется обязательно сбросить TWINT записью в него 1 после завершения всех операций по TWI, но перед reti, чтобы иметь возможность воспринимать другие события.
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Dec 21 2005, 15:30
Сообщение #131


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Добавлю также, что надо анализировать ВСЕ события и делать все действия. Ничего не сокращая! Оптимизировать будете когда всё заработает.
Go to the top of the page
 
+Quote Post
bodja74
сообщение Dec 21 2005, 19:25
Сообщение #132


Знающий
****

Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984



Цитата
То bodja74:
"Если на шине не то что ему нужно,он просто не
выдаст прерывания"
А вот и нет - выдает постоянно, даже если к нему никто не обращается.


Это я вижу? Или это сон?

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


Зачем?

Цитата
"И ПОСЛЕДНЕЕ решаем выставлять нам АСК при следующем получении
данных или нет."
Что-то я не пойму все-таки, как слэйв должен выдавать ACK или NACK. Это же делается аппаратно? Как это сделать программно?


Аппаратно выставляется АСК при совпадении адресса.
Программно можно выставить NACK при получении данных елементарно TWEA=0

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


1 Арбитраж нужен когда два мастера ,а не два слейва.
2 Если адресс слейва не совпал ,слейв ничего не делает (NACK)
3 В таблице ничего и не будет описано.В таблице описаны ТОЛЬКО ТЕ СОБЫТИЯ при которых возникает прерывания.Поэтому и задал вопрос в начале поста


Теперь раскладка по регистрам что касается слейва

1 Инициализация TWI

1.1 #H00->TWBR
1.2 #H00->TWSR //Устанавливаем максимальную скороcть приема
1.3 #H40->TWAR //Адресс слейва 20НЕХ без учета последнего разряда
1.4 #H45->TWSR //Включение ,разрешение прерывания,ACK ,(TWINT=0)

2 Основная программа (ждем прерывание)

3 Прерывание по TWI (TWI_Finished)

3.1 <TWSR=#H60> //Если TWSR=#H60 ,устанавливаем TWINT=1 (#HC5->TWCR),Выходим из подпрограммы (RETI)
3.2 <TWSR=#H80> //Если TWSR=#H80 ,устанавливаем TWINT=1 (#HC5->TWCR),Извлекаем данные из TWDR,Выходим из подпрограммы (RETI)
3.1 <TWSR=#H88> //Если TWSR=#H88 ,устанавливаем TWINT=1 (#HC5->TWCR),Выходим из подпрограммы (RETI)

Все!!!

Сложно?
Go to the top of the page
 
+Quote Post
bbill
сообщение Dec 22 2005, 00:12
Сообщение #133


Частый гость
**

Группа: Участник
Сообщений: 76
Регистрация: 21-10-05
Пользователь №: 9 941



Немного не по теме. Кто-нибудь встречал русскоязычное описание USI для "тинек", для того же двухпроводного интерфейса?
Go to the top of the page
 
+Quote Post
James D.
сообщение Dec 22 2005, 13:16
Сообщение #134


Местный
***

Группа: Участник
Сообщений: 315
Регистрация: 10-10-05
Пользователь №: 9 466



Сделал следующее.
Убрал из программ мастера и слэйва передачу данных при включении обоих МК - там было не по прерываниям, а в основной программе.
Далее. Слэйв:

Код
;Инициализация TWI:

  ldi  temp,$00;Установка скорости передачи
  out  TWBR,temp
  ldi  temp,$00
  out  TWSR,temp
  ldi  temp,$40;Инициализация режима "Приемник"
  out  TWAR,temp
  ldi  temp,(1<<TWEA)|(1<<TWEN)|(1<<TWIE)
  out  TWCR,temp

  sei

;Обработчик прерывания TWI (слэйв):
TWI_Obr:in  temp,TWSR
  andi temp,$F8
  cpi  temp,$60;Проверка принятого адреса от мастера
  breq Address
  cpi  temp,$80;Прием данных
  breq Data
  cpi  temp,$88;Stop
  breq Stop
  reti


Address:ldi  temp,(1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE)
  out  TWCR,temp
  reti

;Прием данных:
Data:ldi  temp,(1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE);здесь пока ничего не делается
  out  TWCR,temp
  reti
;Стоп:
Stop:ldi  temp,(1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE)
  out  TWCR,temp
  reti


Программа мастера:

Код
sbi  PORTD,2;Временная индикация
  sbi  PORTD,3
  sbi  PORTC,2
  sbi  PORTC,3
  sbi  PORTC,4
  sbi  PORTC,5
  sbi  PORTC,6

  ldi  temp,$00;Установка скорости передачи= ? kHz
  out  TWBR,temp
  ldi  temp,$00
  out  TWSR,temp

Pusk_Sn:ldi  temp,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
  out  TWCR,temp;Посылка сигнала "START"

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

  in  temp,TWSR
  andi temp,$F8
  cpi  temp,$08;Проверка подтверждения приема от слэйва
  brne Pusk_Sn

SLA_Wn: ldi  temp,$20;Загрузка адреса слэйва + "WRITE"
  out  TWDR,temp
  ldi  temp,(1<<TWINT)|(1<<TWEN)
  out  TWCR,temp

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

  in  temp,TWSR;Переход, в зависимости от содержимого TWSR
  andi temp,$F8
  cpi  temp,$08
  breq Kod_08
  cpi  temp,$10
  breq Kod_10
  cpi  temp,$18
  breq Kod_18
  cpi  temp,$20
  breq Kod_20
  cpi  temp,$28
  breq Kod_28
  cpi  temp,$30
  breq Kod_30
  cpi  temp,$38
  breq Kod_38

ST_TWI: rjmp ST_TWI

Kod_08: cbi  PORTD,2;Индикация на светодиодах
  rjmp Kod_08
Kod_10: cbi  PORTD,3
  rjmp Kod_10
Kod_18: cbi  PORTC,2
  rjmp Kod_18
Kod_20: cbi  PORTC,3
  rjmp Kod_20
Kod_28: cbi  PORTC,4
  rjmp Kod_28
Kod_30: cbi  PORTC,5
  rjmp Kod_30
Kod_38: cbi  PORTC,6
  rjmp Kod_38


Так вот, слэйв в обработчик прерывания вообще не заходит, а мастер содержит в TWSR код $08 (по индикации).
На шине TWI оставил, для чистоты эксперимента, только два МК - мастер и слэйв.
И еще: скорость передачи устанавливается только в мастере, или в слэйве тоже?

Сообщение отредактировал James D. - Dec 22 2005, 13:20
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Dec 22 2005, 14:25
Сообщение #135


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



1. Скорость передачи устанавливается только в мастере и обязательно!
Цитата
Note: TWBR should be 10 or higher if the TWI operates in Master mode. If TWBR is lower than 10, the Master may produce an incorrect output on SDA and SCL for the reminder of the byte. The problem occurs when operating the TWI in Master mode, sending Start + SLA + R/W to a Slave (a Slave does not need to be connected to the bus for the condition to happen).
При тактовой 8МГц и скорости TWI 100кГц TWBR = 32.
2. Между этими командами у слейва
Цитата
breq Stop
reti
тоже надо вставить сброс TWINT на случай ошибочных ситуаций (может даже с какой-нибудь индикацией).
3. Мастер. При посылке СТАРТ мы ожидаем реакции не от слейва, а от интерфейса (но это только терминология). СТАРТ будет осуществлён и TWINT возникнет только тогда, когда шина будет свободна и вариантов здесь нет. Закольцовывать эту процедуру brne Pusk_Sn не нужно.
4. Байт адреса слейва, передаваемый мастером в Вашем случае должен быть 0x40, т. е. сдвинутым на 1 влево, т. к. младший бит это R/W. См. рисунок Typical Data Transmission.
Go to the top of the page
 
+Quote Post

19 страниц V  « < 7 8 9 10 11 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 04:59
Рейтинг@Mail.ru


Страница сгенерированна за 0.01496 секунд с 7
ELECTRONIX ©2004-2016