|
Проблема с TWI |
|
|
|
Nov 4 2005, 17:14
|

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

|
Соединил 3 МК по TWI - Master передает данные на Slave 1, потом на Slave 2 (поочередно, друг за другом). Два из них общаются нормально (односторонняя передача от Master к Slave 1), а как только нужно передать от Master к Slave 2, один раз передача проходит и все зависает. Судя по всему, после этого не получается передать данные на Slave 1. В конце каждой передачи Master осуществляет условие STOP STOP: ldi temp,(1<<TWINT)|(1<<TWSTO)|(1<<TWEN) out TWCR,temp, а Slave 1/2, после приема переданных байт, просто переходят к дальнейшему выполнению основной программы, т.е. никаких стоповых функций нет. Должны ли они как-то обрабатывать функцию STOP?
Можно ли в режиме "slave приемник" узнать какой адрес передал "master передатчик", т.е. к кому в данный момент он обращается? Появляется ли этот адрес в TWDR?
Как правильно обратиться к конкретному "slave приемнику", чтобы второй "slave приемник" на вызов не реагировал?
|
|
|
|
19 страниц
1 2 3 > »
|
 |
Ответов
(1 - 14)
|
Nov 5 2005, 15:37
|

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

|
Попробовал отключать от линии приемник, к которому сейчас нет обращения: ldi temp,(0<<TWEA) out TWCR,temp Все равно где-то вся эта лабуда зависает! У меня Мастер-передатчик - mega32, первый приемник - тоже mega32, второй приемник - mega16. Выяснил вот что: когда мастер пытается обращаться ко второму приемнику, после посылки сигнала START, они оба зацикливаются: wait1: in temp,TWCR sbrs temp,TWINT rjmp wait1 дальше этого цикла ожидания у них дело не идет. То ли мастер не может START передать, то приемник не может его получить. В чем же тут проблема?
|
|
|
|
|
Nov 6 2005, 08:43
|

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

|
Резисторы по 4.7кОм стоят на каждой линии (соединяют с +5В). Привожу пример моих прог приема-передачи. Передатчик - mega32, приемник - mega16. Передатчик зависает на этапе передачи адреса + W, а приемник зацикливается в цикле wait1n: Как это все настроить?
Эта прога находится в передатчике:
;******************************************************************* ;Программа передачи байта от мастера подчиненному:
To_SR: ldi temp,$00 ;Установка скорости передачи=22727 Hz out TWSR,temp ldi temp,$14 out TWBR,temp
Pusk_Sr: ldi temp,(1<<TWINT)|(1<<TWSTA)|(0<<TWSTO)|(1<<TWEN) out TWCR,temp ;Посылка сигнала "START"
wait1r: in temp,TWCR ;Ожидаем ответ от SR-контроллера sbrs temp,TWINT rjmp wait1r
in temp,TWSR andi temp,$F8 cpi temp,$08 ;Проверка подтверждения приема от SR (START) brne Pusk_Sr
SLA_Wr: ldi temp,$04 ;Загрузка адреса SR-контроллера + "WRITE" out TWDR,temp ldi temp,(1<<TWINT)|(0<<TWSTA)|(0<<TWSTO)|(1<<TWEN) out TWCR,temp
wait2r: in temp,TWCR ;Ожидаем ответ от SR-контроллера sbrs temp,TWINT rjmp wait2r
in temp,TWSR andi temp,$F8 cpi temp,$18 brne SLA_Wr ;Переход, если ответ от SR неверный
;Начинаем передавать данные:
DATA_r: out TWDR,Byte ;Отправка байта данных rcall Writer rjmp STOP_r ;Передача данных завершена
;******************************************************************* Writer: ldi temp,(1<<TWINT)|(0<<TWSTA)|(0<<TWSTO)|(1<<TWEN) out TWCR,temp
wait3r: in temp,TWCR ;Ожидаем ответ от SR-контроллера sbrs temp,TWINT rjmp wait3r
in temp,TWSR andi temp,$F8 cpi temp,$28 brne Writer ;Переход, если ответ от SR неверный
ret ;******************************************************************* ;Все данные переданы - STOP (линия приема/передачи переходит в высокоимпедансное состояние)
STOP_r: ldi temp,(1<<TWINT)|(0<<TWSTA)|(1<<TWSTO)|(1<<TWEN) out TWCR,temp
;*******************************************************************
А эта прога находится в приемнике:
;******************************************************************* ;Программа приема байта от мастера:
From_MT: ldi temp,$04 ;Инициализация режима "Приемник" out TWAR,temp
TWINT_n: ldi temp,(1<<TWINT)|(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|(1<<TWEN) out TWCR,temp
wait1n: in temp,TWCR ;Ожидаем вызова от MT-контроллера sbrs temp,TWINT rjmp wait1n
in temp,TWSR andi temp,$F8 cpi temp,$60 ;Проверка принятого адреса от MT brne TWINT_n
;Прием данных:
Pr_data: rcall TW_NT_n ;Прием байта in Byte,TWDR
rjmp STOP_n
;******************************************************************* TW_NT_n: ldi temp,(1<<TWINT)|(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|(1<<TWEN) out TWCR,temp
wait2n: in temp,TWCR ;Ожидаем ответа от MT-контроллера sbrs temp,TWINT rjmp wait2n
in temp,TWSR andi temp,$F8 cpi temp,$80 brne TW_NT_n ;Переход, если данные от MT не получены
ret
;******************************************************************* ;Все данные приняты - STOP (линия приема/передачи переходит в высокоимпедансное состояние)
STOP_n: ldi temp,(1<<TWINT)|(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|(1<<TWEN) out TWCR,temp
wait4: in temp,TWCR ;Ожидаем ответа от MT-контроллера sbrs temp,TWINT rjmp wait4
in temp,TWSR andi temp,$F8 cpi temp,$A0 brne STOP_n ;Переход, если STOP от MT не получен
;*******************************************************************
|
|
|
|
|
Nov 6 2005, 10:41
|

Познающий...
     
Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125

|
Цитата SLA_Wr: ldi temp,$04 ;Загрузка адреса SR-контроллера + "WRITE" out TWDR,temp ldi temp,(1<<TWINT)|(0<<TWSTA)|(0<<TWSTO)|(1<<TWEN) out TWCR,temp Не нужно при передачи байта посылать условие старт, нужно заменить строку на эту: ldi temp,(1<<TWINT)|(1<<TWEN) это по программе в передатчике, по приемнику - не знаю. Но советую зайти на www.atmel.com и скачать примеры (application notes), там есть несколько довольно неплохих документов. Я по ним разбирал работу модуля TWI. Кстати где-то ниже должна быть моя ветка "Проблемы TWI".
--------------------
Выбор.
|
|
|
|
|
Nov 6 2005, 14:16
|

Познающий...
     
Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125

|
Цитата Pusk_Sr: ldi temp,(1<<TWINT)|(1<<TWSTA)|(0<<TWSTO)|(1<<TWEN) out TWCR,temp ;Посылка сигнала "START" Вы устанавливаете биты "старт" и "стоп" одновременно! так делать нелья, условие старт подается так; Pusk_Sr: ldi temp,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN) out TWCR,temp ;Посылка сигнала "START" Потом, условие стоп! Цитата ;Все данные переданы - STOP (линия приема/передачи переходит в высокоимпедансное состояние)
STOP_r: ldi temp,(1<<TWINT)|(0<<TWSTA)|(1<<TWSTO)|(1<<TWEN) out TWCR,temp Оно (условие) не отличается от условия "СТАРТ" выше. условие "стоп" передается так ;Все данные переданы - STOP (линия приема/передачи переходит в высокоимпедансное состояние) STOP_r: ldi temp,(1<<TWINT)|(1<<TWSTO)|(1<<TWEN) out TWCR,temp Я думаю, что еще есть ошибки! В общем весь текст программы практически не верный. Нужно искать примеры в интернете на асме. Могу посоветовать: www.avrfreaks.net В даташите на МК с аппаратным TWI есть вся необходимая информация. Там же есть примеры на асме, как передавать данные по этой шине. Удачи.
--------------------
Выбор.
|
|
|
|
|
Nov 7 2005, 00:12
|

Познающий...
     
Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125

|
Цитата STOP_r: ldi temp,(1<<TWINT)|(0<<TWSTA)|(1<<TWSTO)|(1<<TWEN) Так нельзя сбрасывать бит TWSTA. В левой части всегда должна быть 1, т.к. она сдвигается на определенное количество разрядов. Для бита TWINT=7, еденица сдвинется на 7 разрядов влево (операция <<) и в 7 разряде будет лог. 1. Для сброса бита можно воспользоваться инструкцией cbi. В общем нужно разобраться с самим ассемблером. И еще в форуме тяжело объяснять такие вещи. Если хотите, можно пообщаться в аське. Мой ICQ UIN 339085018. Я там обычно с 3-00 до 13-00 по Московскому времени. Обращайтесь!
--------------------
Выбор.
|
|
|
|
|
Nov 7 2005, 03:24
|
Участник

Группа: Свой
Сообщений: 25
Регистрация: 25-05-05
Пользователь №: 5 364

|
В VMLAB в папке AVR_demo есть рабочий проект TWI на асме. Удобно то, что на осциллографе можно просмотреть все сигналы. Советую посмотреть. Удачи.
|
|
|
|
|
Nov 7 2005, 05:32
|

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

|
Вы понимаете, я обнуление (например, 0<<TWSTA и пр.) везде повыкидывал, оставил только те биты, которые надо установить в 1. Программа работает, но передача осуществляется только с mega32 на mega32 или с mega16 на mega32. А с mega32 на mega16 - не работает. Вот в чем проблема. А программа работоспособная, на все сто. Может там fuse биты у МК настраивать надо?
To rmo: У меня, к сожалению, нет программы VMLAB, я был бы вам очень благодарен, если бы вы мне сказали где можно скачать полностью работоспособную версию этой проги. Я слыхал, там можно смоделировать работу двух МК - вот это мне бы подошло!
|
|
|
|
|
Nov 7 2005, 12:30
|

Профессионал
    
Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380

|
Ну я думаю во-первых, если не работает на разных кристаллах, проверить инициализацию меги 16. Во-вторых, есть подозрение, что в транзакция не закрываеться (не опознан адрес, не выставлен ACK etc) Посему скромная рекомендация: делаем некую переменную, в которую по окончанию каждого этапа транзакции, ложим число. По окончании всего выбрасываем это число на индикатор или в uart. И смотрим в какой момент автомат TWI понесло не в ту сторону.
--------------------
Вони шукають те, чого нема, Щоб довести, що його не існує.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|