не заводится TWI на Atmega168/328

Обсуждаем контроллеры компании Atmel.
Ответить
Аватара пользователя
radiolok
Первый раз сказал Мяу!
Сообщения: 37
Зарегистрирован: Пт июн 05, 2009 21:55:48
Откуда: Россия, Нижний Новгород
Контактная информация:

не заводится TWI на Atmega168/328

Сообщение radiolok »

Добре!

Написали мы код, где-то хороший, где-то не очень. Отладили его на атмега1280 с учетом того, что работать ему потом на 328 меге.

В итоге, пришли к тестам 168 меги и.. TWI не заводится... Проверили на 32 меге - пашет, на 128 меге - пашет, а на 168-й не пашет. Проверили уровни везде, добавляли, убирали резисторы подтяжки (у модуля свои) - толку ноль. Теперь по порядку.

В качестве библиотеки для доступа к TWI используется Wire+twi из пакета arduino. Особой любви к этой платформе не питаю, но либа сделана достаточно добротно.
К слову скажу, что официальная AVR-овская либа из AVR315 выдает те же самые результаты.

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

Код: Выделить всё

void twi_init(void)
{
  twi_state = TWI_READY;

  cbi(TWSR, TWPS0);
  cbi(TWSR, TWPS1);
  TWBR = ((CPU_FREQ / TWI_FREQ) - 16) / 2;//16МГц и 100кГц соответственно

  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA);
}


Прошивка зависает в следующей функции:

Код: Выделить всё

uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait)
{
        ///сброс буферов, проверка на границы  и копирование данных/// 

     // send start condition
     TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
     dbg_trace_val("wire:write:TWCR:",TWCR);
     dbg_trace_val("wire:write:TWSR:",TWSR);
     // wait for write operation to complete
     while((TWI_MTX == twi_state)){
      continue;//Виснем здесь
     }
  } 
}
ISR(TWI_vect){
//Тут управляется twi_state;
}


С одной стороны, строка TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);
запускает прерывания (глобальные разумеется разрешены - соседние прерывания пашут и не теряются).

Прерываний НИ РАЗУ не запускается. Вообще никак.

Строка практически идентична avr315 за разницей того, что там еще нули прописываются принудительно. Разумеется и это не помогает.
Перед тем как уйти в бесконечный цикл, ловим отладочное сообщение:
TWCR = 109
TWSR = 0xF8
Последний регистр хранит состояние статуса, статус 0xF8 означает - ничего не происходит! Модуль делает вид, что ему не надо работать. При этом если выводить состояние регистров изнутри бесконечного цикла, их состояние остается неизменным.

разумеется, что загнав код без изменений на плату с атмега1280 все работает сразу так как надо.

Взяли скетч - сканнер устройств I2C - не нашел ничего (прерывание также не дрогнуло).
Написали программу содержащую только с TWI и одним светодиод (даже без uart)- тоже тишина.

Написали производителю (ну а что?), молчат.

ЗЫ: в ERRATA на 168 контроллер можно потерять событие ISR если записывать 0x00 в регистры асинхронного таймера. Это единственное что удалось найти, но и здесь не то.

Дизассемблер показывает верные сеты в регистр TWCR..
Ответить

Вернуться в «AVR»