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

Добрый вечер,

 

у меня такая проблемка: mega8 и tiny2313 соединены по I2C. У меги8 интерфейс реализован на модуле TWI (Master), а у tiny2313 на USI(Slave). Оба МК работают от внешних кварцев на 8МГц.

 

Сделал я небольшой протокол по которому мега 8 отсылает байт tiny2313. Он принимает этот байт и решает че делать в зависимости от него: включить или выключить светодиод на одной из ног. Программа которую я зашил в мегу должна была в бесконечном цикле отправлять сначала байт включить светодиод, ждать секунду, затем отправлять выключить светодиод, потом опять ждать секунду и тд.

 

Проблема состоит в том что когда я все запустил, светодиод загорался и погасал в рэндомном порядке, так как практически через раз мастер пропускал ACK, слэйв пропускал или принимал с ошибками байт от мастера (все это я наблюдал на отладочных светодиодах). Вообщем мучался я мучался часа 4, все перепробовал и вот в конце решил сменить частоту шины со 100 Кгц до 400КГц. Врезультате все заработало.

 

Может кто объяснить почему мне помогла смена частоты? Неужели это все из за обрезанного по возможностям USI?

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


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

хм ну так то у меня все собрано на макетной плате, длина шины I2C не более 2 см(2 проводка витой пары), никакой пайки нет, так что я думаю что монтаж тут нипричем

 

ЗЫ модуль TWI меги работает прекрасно с термодатчиком, который тоже I2C (на любой скорости)

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


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

не вижу смысла тогда в создании I2C, это сейчас они у меня на расстоянии 2 см, а если мне потребуется 15 см или более метра? я же не смогу затактировать их от одного кварца. CKPOT фьюз ксати подключал/отключал разницы нет никакой на 100Кгц

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


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

не вижу смысла тогда в создании I2C, это сейчас они у меня на расстоянии 2 см, а если мне потребуется 15 см или более метра? я же не смогу затактировать их от одного кварца.

Понятно. Пересчёт частоты сами делаете или в теле программы?

Т.е. ldi temp,SYSCLK/(2*SCL_Freq)-8;TWI Bit Rate Register - TWBR

sts TWBR,temp ;+ Частота TWI=384 Кгц

Так автоматом , только значения подставляй

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


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

доверил это дело библиотечной функции, вот ее код

void i2cSetBitrate(u16 bitrateKHz)
{
    u08 bitrate_div;
    // set i2c bitrate
    // SCL freq = F_CPU/(16+2*TWBR))
    #ifdef TWPS0
        // for processors with additional bitrate division (mega128)
        // SCL freq = F_CPU/(16+2*TWBR*4^TWPS)
        // set TWPS to zero
        cbi(TWSR, TWPS0);
        cbi(TWSR, TWPS1);
    #endif
    // calculate bitrate division    
    bitrate_div = ((F_CPU/1000l)/bitrateKHz);
    if(bitrate_div >= 16)
        bitrate_div = (bitrate_div-16)/2;
    outb(TWBR, bitrate_div);
}

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


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

доверил это дело библиотечной функции, вот ее код

к сожалению тут не помогу, но по-моему у меня короче. Только наверное надо поменять в SYSCLK/(2*SCL_Freq)-8 . SYSCLK на F_CPU и SCL_Freq на bitrateKHz т.к. они у тебя наверняка описаны, но может кто-то и использовал и там всё в порядке. А так-то твои значения для 400 = 0x02 и для 100 = 0x20 Prescaler=0 Попробуй напрямую подставить

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


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

да я хотел уже было эту функцию основательно проверить, но времени пока нет на проверку

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


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

да я хотел уже было эту функцию основательно проверить, но времени пока нет на проверку

И кстати , не смотрел DS для меги8 , но у неё точно регистр TWBR расположен в области ввода-вывода?

 

P.S Посмотрел , там

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


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

Вы хотя бы код проложили к сообщению. А то гадать "почему не работает" сложно.

Хотя в модуле мастера TWI есть один подводный камень: Перед очередной посылкой условия "старт" нужно проверять, завершилось ли формирование на шине предыдущего условия "стоп", т.е. проверять бит TWSTO на равность "0". Так как контроллер устанавливает флаг TWINT сразу после того, как на шине началось формирование условия "стоп", не дожидаясь его завершения.

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


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

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

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

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

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

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

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

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

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

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