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

зависание TWI

Прошу помощи в освоении шины TWI.

Связываю 2 атмеги 8535, подтяжка резисторы 3к3, длина мене 10см скрость 120 000 кварц 6мег, есть пауза 0.1с перед запуском интерфейса при включении.

Реализованно чтение (мастер читает данные на слейве). Контролирую состояния TWSR через терминалку на слейве и 7ми сегментом индикаторе на мастере.

В какой-то момент связь между мастером и слейвом прекращается, момент этот может прийти через 5с работы, а может всю ночь простоять (не устойчиво). Выражается это в пропадании прерываний, очень редко перед повисом слейв генерит состояние 0, чаще все зависает с нормальными последними состояниями TWSR на мастете 0x50, на слейве 0xB8. На шине SCL наблюдается 1 а на SDA 0 (чаще всего). Пытался оживить интерфейс вписывая TWCR=0x94 или TWCR=0x84 потом пробывал TWCR=0x00 пауза 1с TWCR=0x84. После этого условия старта (кажется 0xE5), потом пробывал перезагружать сторожевиком (при исчезновении прерываний) безтолку. Помогает восстановить связь только аппаратный резет. Тк самопроизвольное зависание контроллера можно ждать очень долго, то я его вешал коротя отверткой сигнальные линии.

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


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

Прошу помощи в освоении шины TWI.

В какой-то момент связь между мастером и слейвом прекращается, момент этот может прийти через 5с работы, а может всю ночь простоять (не устойчиво).

 

В одном из вариантов документации на TWI в AVR прочитал следующее:

 

.....

TWBR должен быть равен не менее 10, если TWI работает в ведущем режиме. Если TWBR меньше 10, то ведущий может генерировать некорректное состояние на линиях SDA и SCL. Проблема возникает при работе в ведущем режиме при передаче условий СТАРТ+ПОДЧИН_АДР+ ЧТЕНИЕ/ЗАПИСЬ подчиненному.

........

 

Речь идет о выборе одного из параметров определяющего SCL мастера. Не ваш ли это случай?

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


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

Это я конечно читал у меня стоит TWBR=0x15; , но и TWBR=0x30; ситуация координально не меняется. Очень сложно отлавить зависимость появления глюка от изменений в программе и на плате. Я повесил кондер по 40pF на SCK, субъективно стало лучше. Думаю попробовать не читать все время, а сделать на мастере так

старт

чтение байта

отправка NACK

при получении TWSR=58 стоп

 

и так в цикле, если левое состояние то выход из цикла и на индикатор, посмотрю скоко простоит

может быть вставлю паузу между прерыванием в котором вписываю стоп и стартом.

 

Есть еще ода фитча, на слейве идет прерывание таймера 1 в нем контроллер работает до 10мкС. Прерывание 100гц. Но его отключение не приводит к полному исчезновению глюка.

 

Вообще долго не мог запустить, пока не сделал паузы при инциализации мастера и слейва.

Но более всего меня беспокоит повисание без каких-либо аварийных кодов

 

Вообще конечно TWI меня не радует, возможно дело в хреновом камне, и надо купить что-нибудь покруче типа mega16.

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


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

В какой-то момент связь между мастером и слейвом прекращается, момент этот может прийти через 5с работы, а может всю ночь простоять (не устойчиво). Выражается это в пропадании прерываний, очень редко перед повисом слейв генерит состояние 0,

 

В таком случае надо отключить TWI модуль от ножек и вручнуню манипулируя SCL и SDA на мастере выдать 8 битов и выдать stop condition. Чтоб слейв отключился.

Помогает восстановить связь только аппаратный резет.

 

Тк самопроизвольное зависание контроллера можно ждать очень долго, то я его вешал коротя отверткой сигнальные линии.

 

:-)))

 

Вариации на тему ёмкости нагрузки, подскакивания земли из-за тока нагрузки, прилетание помехи по воздуху -- всё может быть. Как и некорректная обработка прерываний (пока флаг не сбросишь, внутренний автомат дальше не продвинется). Вообще у AVR вроде не глючит. Не то, что у AT91SAM7...

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


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

Выдать восемь битов - это пощелкать SCK при SDA=1? - это я еще не пробовал.

Ну флаг TWINT я вроде не забываю в 1 (те сбрасывать), да если бы забывал, то думаю висло гораздо чаще.

Вообще TWCR в обработчике прерывания обнавляю в последнюю очередь перед return;

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


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

Была проблема на меге16, не отрабатывался стоп

решил таким способом.

 

TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN); // стоп

watchdog = 0;

while(~PINC & 1<<PC1) // ждать стоп

if(++watchdog > 20) {

TWCR = 0;

PORTC |= 1<<PC1;

DDRC |= 1<<PC1;

PORTC &= ~(1<<PC1);

DDRC &= ~(1<<PC1);

}

 

Причем просто выключение TWI не помогает пришлось дергать ногами. Сброс по WDT помогал, но при этом рвалось IP соединение (слэйв w3100).

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


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

Посмотрите следующее:

 

Выдерживается ли пауза после посылки стопа и следующего старта ? В AVR стоп не привязан к

периоду шины - просто дерганье ног и все.

 

Если TWI построен на прерываниях, нет ли в основной программе установки или сброса

бита прерывания TWIE в TWCR ? Команды вроде TWCR |= (1<< TWIE) будут сделаны

как read-modify-write, если при этом бит TWINT был установлен, то он будет сброшен (записью

в него обратно единицы).

 

У меня было похожее поведение слейва: держит SDA в нуле и говорит, что bus idle.

Правда, слейв был только приемником. Если правильно помню, он не успевал отработать

стоп и продолжал держать SDA в нуле (от последнего ACK-а). Поведение сильно

зависело от загрузки процессора. Для проверки можно загрузить камешек таймерным

прерыванием на 90% - сбои должны быть чаще :-) Вылечилось отказом от получения Stop

вообще - последний пакет по-умолчанию NACK-ался.

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


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

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

 

Правда хотелось бы, чтобы интерфейс выдерживал тест отверткой, :).

Тест отверткой показал, что у мастера кроме его состояний с ACK и NACK вылезает потеря арбитрации (отвертка перехватывает орбитрацию), к сожалению обработка всех состояний не дает желаемого результата. Выдача пачки импульсов по SCL тоже не очень помагает против отвертки.

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

 

Вообщем безвыходные состояния в автомте TWI есть! А значит и ступор вполне вероятен даже для правильной программы.

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


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

Выдерживается ли пауза после посылки стопа и следующего старта ? В AVR стоп не привязан к

периоду шины - просто дерганье ног и все.

 

Спасибо за подсказку. Я что-то в дш просмотрел это... Надо перечитать внимательно.

Завтра же отрихтую прогу на предмет выдержки после стопа.

У меня зависания чрезвычайно редкие, одно на несколько дней работы, поэтому выловить трудно. Иногда их вообще не бывает. То есть один индикатор редко-редко, но зависает. Другие, а их большинство, работают всегда нормально. Попытки подобрать параметры обмена ни к чему не привели. Но до паузы я не додумался.

До теста отверткой, впрочем, тоже java script:emoticon(':biggrin:', 'smid_11').

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


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

Причину не понял, происходит следующее: после записи или чтения массива в/из шины I2C, линия SDA остается в нуле.

Вылечил путем принудительной выдачи импульсов на линию SCL. Схема: ATmega128 (master) + FM24CL64 + DS1307. Скорость 100 кбод.

void i2cSendStop(void)
{  
    TWCR = (i2cCheck() & TWCR_CMD_MASK) | _BV(TWINT) | _BV(TWEA) | _BV(TWSTO);
}

uint8_t i2cCheck(void){
    uint8_t temp = TWCR;
    if(!(PIND & _BV(PD1))){
        TWCR = 0;
        uint8_t i = 0;
        PORTD &= ~_BV(PD0);
        while(!(PIND & _BV(PD1))){
            DDRD |= _BV(PD0);
            Delay_5us();
            DDRD &= ~_BV(PD0);
            Delay_5us();
            i++;
            if(i > 15) break;    //Fatal error, число 15 от фонаря. В моем случае i не более 2
        }
        PORTD |= _BV(PD0);
    }
    return temp;
}

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


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

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

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

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

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

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

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

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

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

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