не стартует TWI на Atmega168/328

Все о микроконтроллерах: AVR, PIC, STM8, STM32, Arduino, Altera, Xilinx, все что угодно. Этот раздел для всего что клацает байтиками.
radiolok
Сообщения: 4

Сообщение radiolok » 11 июл 2014, 14:46

Добре!

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

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

В качестве библиотеки для доступа к 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, мега128 и мега32 все работает сразу так как надо.

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

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

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

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

Вернуться в «Микроконтроллеры и ПЛИС»



Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и 6 гостей