Цитата
Писать софтовый TWI при живом аппаратном это уже верх отчаяния, но безуспешные попытки найти у кого-нибуть работающий модуль, приводят к мысли о том, что он настолько глюкавый, что им никто и не пользуется!
Да нет, вроде работает TWI, сбоев не было. Сейчас на нем висят два термодатчика AD7415, и ничего - все отлично. Хотя да, действительно если не соблюать некоторых правил, то TWI доставит проблемы. Например, как я уже писал, если не поставить резисторы, то флаг прерывания TWINT не устанавливается. А т.к. я опрашиваю этот модуль не по прерываниям, а по установке флага (в цикле), то элементарная неисправность линии может повесить всю программу, но это уже дело техники.
Кстати, софтовый TWI или I2C написать совсем не сложно и даже полезно.
Дальше, примеры применения TWI (мне здорово помогли) есть здесь:
http://www.atmel.com/dyn/products/app_note...p?family_id=607и еще сходите на
http://www.avrfreaks.netтам море прогамм для AVR, большинство на СИ, есть там и TWI. Только нужно бесплатно зарегистрироваться на сайте.
Вот я выкладываю готовые модули подпрограмм для работы с TWI, у меня все работает, ошибок быть не должно. Извиняюсь, что прямо в формум а не прикрепленными файлами. Будут вопросы, можете спросить по ICQ339085018, я там обычно (не всегда) с 03-00 до 13-00 по Московскому времени, кроме воскресенья.
Вот хедер:
********************************************************************************
***********
* Объявление констант и включения заголовочных файлов для системы TWI *
* Версия 0.1 *
* Начато 27 августа 2005 года *
* Окончено *
* Автор *
********************************************************************************
***********/
#ifndef TWI_H
#define TWI_H
#define WR 0 //Запись данных
#define RD 1 //Чтение данных
#define TWI_TWBR 64 //Делитель скорости шины
//Прототипы функций
void i2c_init(void);
void i2c_start(void);
void i2c_stop(void);
void i2c_tx(unsigned char byte);
unsigned char i2c_rx(unsigned char last_byte);
void i2c_delay(void);
#endif
Вот сишник:
/********************************************************************************
***********
* Подпрограммы управления шиной I2C *
* Версия 0.1 *
* Начато 27 августа 2005 года *
* Окончено *
* Автор *
********************************************************************************
***********/
#include "twi.h"
//Инициализация программы I2C
void i2c_init(void)
{
TWBR = TWI_TWBR; //установить скорость шины i2c
TWCR = (1<<TWEN); //включить модуль i2c
}
//Формирует условие "СТАРТ"
void i2c_start(void)
{
TWCR=((1<<TWEN)|(1<<TWINT)|(1<<TWSTA));
i2c_delay();
}
//Формирует условие "СТОП"
void i2c_stop(void)
{
TWCR = ((1<<TWEN)+(1<<TWINT)+(1<<TWSTO));
}
//Посылка байта
void i2c_tx(unsigned char byte)
{
i2c_delay();
TWDR = byte;
TWCR = ((1<<TWINT)+(1<<TWEN));
i2c_delay();
}
//Прием байта, если last_byte=0, то принимаем последний байт и подтверждение от мастера не нужно
unsigned char i2c_rx(unsigned char last_byte)
{
i2c_delay();
if(last_byte) //если принимаем не последний байт, то
TWCR = ((1<<TWINT)+(1<<TWEN)+(1<<TWEA)); //посылаем подтвержение приема
else TWCR=((1<<TWINT)|(1<<TWEN)); //иначе - нет
i2c_delay();
return TWDR;
}
//Задержка
void i2c_delay(void)
{
while(!(TWCR&(1<<TWINT)));
}
Компилятор IAR EWAVR 4.11A, но это не важно. Важна сама суть.
Цитата
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA); // посылка адреса
Для посылки байта нужно писать: TWCR = (1<<TWINT)|(1<<TWEN);