Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблемы с TWI ATmega8-16PI
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
haker_fox
Условие "СТАРТ" передается нормально. Далее передается байт адреса и ожидается установка бита TWINT в регистре TWCR и здесь программа затыкается. В чем может быть дело? Если связь с термодатчиком AD7415 не в порядке, то этот бит все равно должен устанавливаться же?!

Вот подпрограммы:
Модуль для работы с шиной I2C


#include "i2c.h"

//Генерирует условие СТАРТ
void i2c_start(void)
{
TWCR=((1<<TWINT)+(1<<TWSTA)+(1<<TWEN));
i2c_wait();
}

//Генерирует условие СТОП
void i2c_stop(void)
{
TWCR=((1<<TWEN)+(1<<TWINT)+(1<<TWSTO)); //стоп условие
}

//Ожидание готовности шины
void i2c_wait(void)
{
while(!(TWCR&(1<<TWINT)));
}

//Передача байта
void i2c_tx(unsigned char data)
{
i2c_wait();
TWDR=data;
TWCR=((1<<TWINT)+(1<<TWEN));
i2c_wait();
}

//Примем байта
unsigned char i2c_rx(void)
{
i2c_wait();
TWCR|=(1<<TWINT);
i2c_wait();
return TWDR;
}



Вот фрагмент программы опроса датчика:
i2c_start(); //здесь все ОК
i2c_tx(THERMAL_H|WR); //здесь виснет

#define THERMAL 0x4A //address
#define WR 0

Вот инициализация TWI
TWBR=128;
TWCR=0;
TWSR=0;

Всем спасибо за ответы smile.gif
haker_fox
Все разобрался. Забыл резюки на шину +5В ткнуть, суббота че поделаешь, спать надо smile.gif
siriasis
А вообще не надо использовать этот глюкавый и2ц интерфейс. Напиши свой софтверный. Я тоже мучался. Он раьботает но с пременным успехом. А прграммный на все сто.
haker_fox
Неужели все-таки TWI глючит? Обидно smile.gif Все-таки хочется верить, что Atmel'овские МК идеальны smile.gifsmile.gifsmile.gif Вот USART там сделан не плохо (хотя буфер FIFO на 8-16 байт не помешал бы), а какие глюки с TWI? Может кто поделится??
Ёрген
У меня было в интерфейсе с DS1307 и ATmega16, что SCL сбрасывался в 0 навеки - I2C, соответственно переходил в неопределенно-занятое состояние, происходило довольно редко - видел раза 2-3. Сейчас повесил на SCL pullup (сначала думал, что это активный выход - на SDA был) - статистики пока не набрал.
m16
Цитата(haker_fox @ Oct 4 2005, 06:55)
Неужели все-таки TWI глючит? Обидно smile.gif Все-таки хочется верить, что Atmel'овские МК идеальны smile.gifsmile.gifsmile.gif Вот USART там сделан не плохо (хотя буфер FIFO на 8-16 байт не помешал бы), а какие глюки с TWI? Может кто поделится??
*


я вешал pcf8583(rtc) + at24c256 писал на асме режим ведущего перед и приемн. работает без глюков на меге16 и меге 128 на 400кгц хотя у pcf8583 макс частота 100 кгц. правда пршлось повозиться при написании драйверов . основное -после анализа состояния шины twi принять правильное решение на выдачу сооотв команды ack, nack, stop ,start.
Может твои глюки связаны с монтажем? плохим питанием?
почитай здесь http://gaw.ru/html.cgi/txt/doc/micros/avr/arh128/18_6.htm
Igor26
Цитата(siriasis @ Oct 3 2005, 18:19)
А вообще не надо использовать этот глюкавый и2ц интерфейс. Напиши свой софтверный. Я тоже мучался. Он раьботает но с пременным успехом. А прграммный на все сто.
*

А в чем его глючность? На каких кристаллах проявляется?
Olegovich
Цитата(Igor26 @ Oct 4 2005, 08:58)
Цитата(siriasis @ Oct 3 2005, 18:19)
А вообще не надо использовать этот глюкавый и2ц интерфейс. Напиши свой софтверный. Я тоже мучался. Он раьботает но с пременным успехом. А прграммный на все сто.
*

А в чем его глючность? На каких кристаллах проявляется?
*



В аппаратном I2C надо очень четко и подробно соблюдать/прописать последовательности действий, описанные в доке, иначе действительно можно долго пропариться.
NickB
Делал программный slave ATmega16 практически по аппноуту от Atmel
А также мастер на LPC2214.
Усе работает по уставу. Единственно что не реализовано в аппнотах - это
возможность зависаний мастера если нет ответа. Лечится программным таймером
khvostoff
Мужики!
Я ещё очень начинающий.
Мне надо присобачить AD5933 к Меге32! Пытаюсь писать на Си в ICC.
Делаю вроде всё по инструкциям а ничено не работает. На клоке ещё какая-то фигня лезет, а на дате даже старт не формируется. Да и то, что лезет на клоке не управляется по частоте! Писать софтовый TWI при живом аппаратном это уже верх отчаяния, но безуспешные попытки найти у кого-нибуть работающий модуль, приводят к мысли о том, что он настолько глюкавый, что им никто и не пользуется!

//ICC-AVR application builder : 22.10.2005 9:33:36
// Target : M32
// Crystal: 8.0000Mhz

#include <iom32v.h>
#include <macros.h>

void port_init(void)
{
PORTA = 0x00;
DDRA = 0x00;
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0x03;
DDRC = 0x03;
PORTD = 0x00;
DDRD = 0x00;
}

//TWI initialize
// bit rate:2
void twi_init(void)
{
TWCR= 0x00; //disable twi
TWBR= 0x02; //set bit rate
TWAR= 0x00; //set slave address
TWCR= 0x44; //enable twi

}

//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
twi_init();

MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x00; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}


// *************************************************
// Основная программа
// *************************************************

main()
{
a:


TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // посылка старт
while (!(TWCR & (1<<TWINT))); // ожидание
TWDR = 0x0D; // Это адрес приёмника (SLAVE) + признак записи
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA); // посылка адреса
while (!(TWCR & (1<<TWINT))); // ожидание
TWDR = 0x80; // это адрес регистра в приёмнике (SLAVE)
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA); // посылка адреса
while (!(TWCR & (1<<TWINT))); // ожидание
TWDR = 0x80; // это данные в регистр в приёмника (SLAVE)
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA); // посылка данных
while (!(TWCR & (1<<TWINT))); // ожидание
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); // Посылка STOP





goto a;
// End of main program
}


Гляньте прогу! Мож кто чего углядит. Я так понимаю, что эта проблема не только меня волнует!
haker_fox
Цитата
Писать софтовый 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);
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.