|
|
  |
Проблема с TWI |
|
|
|
Nov 21 2005, 11:40
|
Местный
  
Группа: Свой
Сообщений: 242
Регистрация: 27-01-05
Пользователь №: 2 225

|
Цитата(James D. @ Nov 21 2005, 14:24)  Понял, вечерком попробую с такой комбинацией. Посмотрел даташит - "ведущий приемник" - там бит TWEA вообще не участвует. обшибся.конечно же TWSTA Цитата Как мастер-приемник должен отправлять "НЕТ ПОДТВерждения после приема последнего принятого байта данных"? Последняя команда: STOP - (1<<TWINT)|(1<<TWSTO)|(1<<TWEN) после приема последнего байта приемник должен выдать NACK- (1<<TWINT)|(1<<TWEN) а затем STOP
|
|
|
|
|
Nov 21 2005, 16:03
|

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

|
В приемнике убрал (1<<TWINT), оставил везде только (1<<TWEA)|(1<<TWEN). Приемник стопорит на этапе приема байта данных - в TWSR код отличный от $80. Передатчик, после посылки START (получен код $18), не может передать байт данных:
wait3: in temp,TWCR ;Ожидаем ответа от слэйв м32 sbrs temp,TWINT rjmp wait3
бит TWINT не устанавливается. Судя по всему, ошибка в мастере-передатчике, потому как он не может даже начать передачу. Почему же TWINT не устанавливается?
ЗЫ. Но, если вернуть в код приемника код (1<<TWINT), то данные на слэйв м32 передаются нормально. А вот на слэйв м16 данные не передаются в любом случае - если на него идет передача после м32. А если сначала передавать на м16 - передается нормально, но потом нет передачи на м32... Крыша едет.
Сообщение отредактировал James D. - Nov 21 2005, 16:19
|
|
|
|
|
Nov 21 2005, 17:10
|

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

|
Дык я так и делаю (прога передатчика целиком):
ldi temp,$03 ;Установка скорости передачи= ? kHz out TWSR,temp ldi temp,$FF out TWBR,temp
Pusk_Sq:ldi temp,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN) out TWCR,temp ;Посылка сигнала "START"
wait1q: in temp,TWCR ;Ожидаем ответа от приемника sbrs temp,TWINT rjmp wait1q
in temp,TWSR andi temp,$F8 cpi temp,$08 ;Проверка подтверждения приема от приемника (START) brne Pusk_Sq
SLA_Wq: ldi temp,$04 ;Загрузка адреса приемника + "WRITE" out TWDR,temp ldi temp,(1<<TWINT)|(1<<TWEN) out TWCR,temp
wait2q: in temp,TWCR ;Ожидаем ответа от приемника sbrs temp,TWINT rjmp wait2q
in temp,TWSR andi temp,$F8 cpi temp,$18 brne SLA_Wq
;Начинаем передавать данные:
DATA_q: out TWDR,BYTE1 ;Отправка: байт данных 1 rcall Writeq Pu_Menq:rjmp STOP_q ;Передача данных завершена
;******************************************************************* Writeq: ldi temp,(1<<TWINT)|(1<<TWEN) out TWCR,temp
wait3q: in temp,TWCR ;Ожидаем ответа от приемника sbrs temp,TWINT rjmp wait3q
in temp,TWSR andi temp,$F8 cpi temp,$28 brne Writeq ;Переход, если ответ от приемника неверный
ret
;******************************************************************* ;Все данные переданы - STOP (линия приема/передачи переходит в высокоимпедансное состояние)
STOP_q: ldi temp,(1<<TWINT)|(1<<TWSTO)|(1<<TWEN) out TWCR,temp
Inits: rjmp Inits
;***********************
Стопорит в цикле wait3q - ежели в проге приемника повыкидывать (1<<TWINT).
|
|
|
|
|
Nov 21 2005, 17:42
|
Местный
  
Группа: Свой
Сообщений: 242
Регистрация: 27-01-05
Пользователь №: 2 225

|
Цитата(James D. @ Nov 21 2005, 20:10)  Дык я так и делаю (прога передатчика целиком):
lSLA_Wq: ldi temp,$04 ;Загрузка адреса приемника + "WRITE" out TWDR,temp ldi temp,(1<<TWINT)|(1<<TWEN) out TWCR,temp
wait2q: in temp,TWCR ;Ожидаем ответа от приемника sbrs temp,TWINT rjmp wait2q
in temp,TWSR andi temp,$F8 cpi temp,$18 brne SLA_Wq SLA не может повторно выдаваться только через стоп или повстарт
;Начинаем передавать данные:
DATA_q: out TWDR,BYTE1 ;Отправка: байт данных 1 rcall Writeq Pu_Menq:rjmp STOP_q ;Передача данных завершена
;
Стопорит в цикле wait3q - ежели в проге приемника повыкидывать (1<<TWINT). а что в приемнике? код в студию
|
|
|
|
|
Nov 21 2005, 18:04
|

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

|
Приемник:
ldi temp,$04 ;Инициализация режима "Приемник" out TWAR,temp
TWINT_0:ldi temp,(1<<TWEA)|(1<<TWEN) out TWCR,temp
wait1: in temp,TWCR ;Ожидаем вызова от передатчика sbrs temp,TWINT rjmp wait1
in temp,TWSR andi temp,$F8 cpi temp,$60 ;Проверка принятого адреса от передатчика brne TWINT_0
;Прием данных:
Pr_data:rcall TW_NT_1 ;Прием: байт данных in temp,TWDR
rjmp STOP_1
;******************************************************************* TW_NT_1:ldi temp,(1<<TWEA)|(1<<TWEN) out TWCR,temp
wait21: in temp,TWCR ;Ожидаем ответа от передатчика sbrs temp,TWINT rjmp wait21
in temp,TWSR andi temp,$F8 cpi temp,$80 brne TW_NT_1 ;Переход, если данные от передатчика не получены
ret
;******************************************************************* ;Все данные приняты - STOP (линия приема/передачи переходит в высокоимпедансное состояние)
STOP_1: ldi temp,(1<<TWEA)|(1<<TWEN) out TWCR,temp
wait31: in temp,TWCR ;Ожидаем ответа от передатчика sbrs temp,TWINT rjmp wait31
in temp,TWSR andi temp,$F8 cpi temp,$A0 brne STOP_1 ;Переход, если данные от передатчика не получены
Inits: rjmp Inits
|
|
|
|
|
Nov 21 2005, 18:18
|
Местный
  
Группа: Свой
Сообщений: 242
Регистрация: 27-01-05
Пользователь №: 2 225

|
Цитата(James D. @ Nov 21 2005, 21:04)  Приемник:
ldi temp,$04 ;Инициализация режима "Приемник" out TWAR,temp вот и ошибочка : в 0-м разряде (TWGCE) сидит нолик что означает запрещение распознования общих вызовов на шине а должно быть
ldi temp,$05 ;Инициализация режима "Приемник" out TWAR,temp дальше не смотрел, пора домой .удачи совет дня закажи по почте книгу http://www.dodeca.ru/books/me9.php не пожалеешь
|
|
|
|
|
Nov 21 2005, 20:18
|

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

|
Урра!!! Заработало!!! Значит так: 1. в приемниках м32 и м16 оставил адреса $02 и $04 соответственно (без записи "1" в TWGCE). 2. в обоих приемниках пишется так: ldi temp,(1<<TWINT)|(1<<TWEA)|(1<<TWEN) out TWCR,temp бит TWINT должен присутствовать, иначе просто не работает! Ну и наконец, самое главное! 3. в приемнике м32, после команды STOP и получения кода $A0 пишем: ldi temp,(1<<TWINT)|(1<<TWEN) out TWCR,temp Спасибо, m16, за твою подсказку: "после приема последнего байта приемник должен выдать NACK- (1<<TWINT)|(1<<TWEN) а затем STOP". Я решил применить это в моем случае. Только я сначала даю STOP, а потом уже NACK. Попробовал после приема последнего байта выдавать NACK (после команды STOP убрал) - тоже работает. А теперь самое загадочное: убрал выдачу NACK везде в программах-приемниках - все равно работает. Но раньше-то не работало! Такое впечатление, как будто в контроллере после выдачи NACK сработала какая-то "защелка", которая наставила контроллер на путь истинный, и даже после удаления этой команды стало работать нормально. Но это мои домыслы. Теперь попробуем новую задачу: после передачи на м32, потом на м16, надо принять данные с м16. Ну как, одолеем?
|
|
|
|
|
Nov 22 2005, 12:58
|

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

|
М-да... Работать-то оно работает, но появились проблемы с записью в EEPROM - иногда (не всегда) при попытке что-либо записать в EEPROM все зависает. Задержку пришлось поставить в мастере-передатчике:
Pusk_Sn:ldi temp,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN) out TWCR,temp ;Посылка сигнала "START"
wait1n: in temp,TWCR ;Ожидаем ответа от слэйв м32 sbrs temp,TWINT rjmp wait1n
rcall Delay . . .
Delay:push r20 push r21 push r22
ldi r20,$FF ldi r21,$0F ldi r22,$01 D_r_2: dec r20 brne D_r_2 ldi r20,$FF dec r21 brne D_r_2 ldi r21,$FF dec r22 brne D_r_2
pop r22 pop r21 pop r20
ret
по-другому работать не хочет! Очень не нравится мне ента TWI. Капризная и нестабильная штука.
|
|
|
|
|
Dec 1 2005, 20:10
|
Участник

Группа: Участник
Сообщений: 66
Регистрация: 28-11-05
Из: Москва
Пользователь №: 11 510

|
Добрый вечер! Вот нужна какая помощь: Я передаю три байта как Master Transmitter , а вот четвёртый и пятый байты мне нужно принять как Master Receiver. После третьего байта только Acknowledge , а следующий такт уже я должен начать принимать данные. В регистре TWDR - последнее отосланное мной значение.
Ну не знаю я что делать. Помогите! Желательно на СИ!
|
|
|
|
|
Dec 2 2005, 12:50
|
Профессионал
    
Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886

|
Цитата(Igor26 @ Dec 2 2005, 09:21)  Цитата(Moks @ Dec 1 2005, 23:10)  Добрый вечер! Вот нужна какая помощь: Я передаю три байта как Master Transmitter , а вот четвёртый и пятый байты мне нужно принять как Master Receiver. После третьего байта только Acknowledge , а следующий такт уже я должен начать принимать данные. В регистре TWDR - последнее отосланное мной значение.
Ну не знаю я что делать. Помогите! Желательно на СИ!
Помоему, после передачи третьего байта Вам нужно давать STOP. Не обязательно выдавать STOP, необходимо выдать новый START+SLA-R. недавно боролся с slave-mode TWI. после того, как сделал всё по datasheet, всё прекрасно заработало. если надо могу поделиться кодом на CV для m16.
|
|
|
|
|
Dec 3 2005, 14:03
|
Местный
  
Группа: Участник
Сообщений: 358
Регистрация: 29-05-05
Пользователь №: 5 526

|
интересно, как кто решил TWI slave, я переписал twi_int от AVR311 в такои вид, нужен был максмалный скорость, в сеттингах ИАР надо резервировать R13,R14,R15 для TWI_int.
NAME twi_slave_asm #include "iom8.h" ; file must be within the module public TWI_statusReg public TWI_state public TWI_buf public byte_count ; RSEG TWIBUF TWI_buf DS 66 ; TWI buf is 64 bytes long + 2 byte aadress TWI_statusReg DS 1; TWI_buf must start from xx00 aadress ( low byte = 0) TWI_state DS 1;
twi_int_end MACRO OUT 0x3F,R13 LD R16,Y+ LD R30,Y+ LD R31,Y+ RETI ENDM
COMMON INTVEC:CODE:ROOT(1) ORG 0x22 RJMP TWI_ISR
RSEG CODE ; This code is relocatable, RSEG byte_count: ; returns how many bytes are in receive buffer MOVW R17 : R16,R15 : R14 RET
; ORG 0x1E00 ; lower adres byte must be 0 ! RSEG TWIASM
TWITAB: RJMP TWI_ISR_7 ;0x00 bus error , illegal START or STOP RJMP TWI_ISR_7 ;0x08 TWI_START, MASTER only RJMP TWI_ISR_7 ;0x10 TWI_REP_start , MASTER only RJMP TWI_ISR_7 ;0x18 MASTER only: SLA+W trx-d, ACK rec-d RJMP TWI_ISR_7 ;0x20 "" : SLA+W trx-d,NACK rec-d RJMP TWI_ISR_7 ;0x28 "" : DATA trx-d, ACK rec-d RJMP TWI_ISR_7 ;0x30 "" : DATA trx-d, NACK rec-d RJMP TWI_ISR_7 ;0x38 TWI_ARB_LOST RJMP TWI_ISR_7 ;0x40 MASTER only: SLA+R trx-d,ACK rec-d RJMP TWI_ISR_7 ;0x48 "" SLA+R trx-d, NACK rec RJMP TWI_ISR_7 ;0x50 "" DATA trx-d, ACK rec RJMP TWI_ISR_7 ;0x58 "" DATA trx-d, NACK rec-d RJMP TWI_ISR_6 ;0x60 own SLA+W rec-d,ACK ret-d RJMP TWI_ISR_7 ;0x68 "" in slave mode RJMP TWI_ISR_7 ;0x70 General call rec-d, ACK ret-d RJMP TWI_ISR_7 ;0x78 "" sama in slave mode RJMP TWI_ISR_0 ;0x80 data rec-d , ACK ret-d ( prevSLA) RJMP TWI_ISR_7 ;0x88 data rec-d ,NACK ret-d ( prevSLA) RJMP TWI_ISR_7 ;0x90 data rec-d , ACK ret-d ( prev Ceneral call) RJMP TWI_ISR_7 ;0x98 data rec-d , NACK ret-d (prev General call) RJMP TWI_ISR_2 ;0xA0 STOP for Slave RJMP TWI_ISR_3 ;0xA8 SLA+R rec-d,ACK ret-d RJMP TWI_ISR_7 ;0xB0 arb.lost in Master mode, SLA+R rec-d,ACK ret-d SL mode RJMP TWI_ISR_4 ;0xB8 TWDR transm-d, ACK rec-d RJMP TWI_ISR_5 ;0xC0 TWDR transm-d, NACK rec-d RJMP TWI_ISR_7 ;0xC8 TWDR transm-d, ACK rec-d RJMP TWI_ISR_7 ;0xD0 RJMP TWI_ISR_7 ;0xD8 RJMP TWI_ISR_7 ;0xE0 RJMP TWI_ISR_7 ;0xE8 NOP ;0xF0
TWI_ISR_7: IN R16,0x01 STS TWI_state,R16 TWI_ISR_2: LDI R16,4 OUT 0x36,R16 twi_int_end
TWI_ISR: ST -Y,R31 ;2 ST -Y,R30 ;2 ST -Y,R16 ;2 IN R13,0x3F ;1 SREG keep IN R30,0x01 ;1 TWI STatus reg LSR R30 ;1 LSR R30 ;1 LSR R30 ;1 LDI R31, TWITAB>>9 ;1 IJMP ;2
TWI_ISR_3: LDI R30,LOW(TWI_buf) LDI R31,(TWI_buf >> 8) LD R16,Z+ OUT 0x03,R16 LDI R16,197 OUT 0x36,R16 MOVW R15 : R14,R31 : R30 twi_int_end TWI_ISR_4: MOVW R31 : R30,R15 : R14 LD R16,Z+ OUT 0x03,R16 LDI R16,197 OUT 0x36,R16 ; ANDI R30,63 ; not actual for sending MOVW R15 : R14,R31 : R30 twi_int_end
TWI_ISR_5: LDI R30,LOW(TWI_statusReg) LDI R31,(TWI_statusReg) >> 8 LD R16,Z ORI R16,0x01 ; end flag, TX oli OK ST Z,R16 LDI R16,4 OUT 0x36,R16 twi_int_end
TWI_ISR_6: LDI R30,LOW(TWI_statusReg) LDI R31,(TWI_statusReg) >> 8 LD R16,Z ORI R16,0x02 ; Rx data in buf ST Z,R16 LDI R30,LOW(TWI_buf) LDI R31,(TWI_buf) >> 8 MOVW R15 : R14,R31 : R30 LDI R16,197 OUT 0x36,R16 twi_int_end TWI_ISR_0: IN R16,0x03 MOVW R31 : R30,R15 : R14 ST Z+,R1 ; if(R30>65 ) R30=0 CPI R30,66 BRCS noo LDI R30,0 noo: MOVW R15 : R14,R31 : R30 LDI R30,LOW(TWI_statusReg) LDI R31,(TWI_statusReg) >> 8 LD R16,Z ORI R16,0x01 ; ST Z,R16 LDI R16,197 OUT 0x36,R16 twi_int_end END
|
|
|
|
|
Dec 4 2005, 17:09
|
Участник

Группа: Участник
Сообщений: 66
Регистрация: 28-11-05
Из: Москва
Пользователь №: 11 510

|
Спасибо, но я просил на Си, к тому же моя микросхема работает как Master! Только в начале она используется как transmitter, а потом как receiver!
|
|
|
|
|
Dec 19 2005, 12:42
|

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

|
Продолжаю добивать TWI. Хочу разобраться в конце-концов. Вопрос такой: на вызов мастера-передатчика должны отвечать оба слэйва? Какие действия должен предпринимать тот слэйв, адрес которого не совпал с переданным мастером? Раньше я делал так: от мастера к каждому слэйву кроме линий TWI шли еще по одной линии - разрешение на связь с мастером. Соответствующая линия сбрасывается в "0", если мастер хочет передавать данные на этот слэйв; вторая линия в "1", т.е. второй слэйв вообще не заходит в программу приема данных по TWI. Так не заработало - могу передать только на первый слэйв, при попытке передать на второй - все зависало - окончательно и безнадежно. Теперь сделал по-другому. Должно, по идее, работать так: мастер сбрасывает в "0" обе линии (разрешение на связь с мастером). Тот слэйв, адрес которого не совпал, выходит из программы приема данных, и продолжает выполнять основную прогу. А тот слэйв, адрес которого совпал - принимает данные. Но и здесь не все гладко. Мастер (m32) передает данные на слэйв1 (m32) - тут все нормально. Но слэйв2 (m16) при этом висит! Нажимаю на кнопочку, чтобы начать передавать данные на слэйв2 - он при этом выходит из зависания, и данные передаются на оба контроллера - так и должно быть. При этом слэйв1 не зависает. При включении передачи на слэйв1 - слэйв2 опять зависает.
Как тут быть?
P.S. Кстати, описанная ситуация происходит, если при связи с обоими МК мастер выдает повторный старт. Если мастер дает сигнал старт - все безнадежно зависает (при попытке передать на слэйв2).
Сообщение отредактировал James D. - Dec 19 2005, 12:52
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|