Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: I2C память.
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
at90
Прилепил к меге 24с256. Адресные ноги подтянуты к земле.
Но попытки чтения и записи в память не увенчались успехом.
Пишу в КодеВижен. Доэтого работал с ds1307. Работает нормально.

Использую встроенный в компилятор I2C.
#define EEPROM_BUS_ADDRESS 0xA0

bit i2c_error;

unsigned char at24c08_read(unsigned int address)
{
unsigned char data;
unsigned char temp_i;
temp_i = SREG.7;
#asm("cli")

i2c_error=0;
data = ((unsigned char)(address>>7))&0x0e;
if (!(i2c_start()&&
i2c_write(EEPROM_BUS_ADDRESS | data)&&
i2c_write((unsigned char)(address))&&
i2c_start()&&
i2c_write(EEPROM_BUS_ADDRESS | data | 1)))
{ i2c_error=1; }
else data=i2c_read(0);
i2c_stop();

SREG.7 = temp_i;
return data;
}



void at24c08_write(unsigned int address, unsigned char data)
{
unsigned char temp_i;
temp_i = SREG.7;
#asm("cli")
i2c_error=0;

if (!(i2c_start()&&
i2c_write(EEPROM_BUS_ADDRESS | (((unsigned char)(address>>7))&0x0e))&&
i2c_write((unsigned char)(address))&&
i2c_write(data))) { i2c_error=1; }
i2c_stop();

delay_ms(10);
SREG.7 = temp_i;
}
m16
посмотри апноту
at90
У меня I2C программный. Ножки Twi заняты. Плата уже готовая.
at90
Никто не поделится рабочим примерчиком работы с eeprom,
для СV или IAR!!!
Rash
Цитата(at90 @ Dec 12 2005, 14:33) *
У меня I2C программный. Ножки Twi заняты. Плата уже готовая.

Зачем над собой издеваться, если есть апаратный TWI. Если уж плата разведена, обреж дорожки да переподключи, намного быстрее будет, чем самому писать или искать.
proba
organizatsija pamjaati u 2408 i 24256 raznoe, 256 trebujet 2 baitnöi adres, smotrii datasheet.
primerno
{
U8 i;
i =i2c_start();
i&=i2c_write(EEPROM_BUS_ADDRESS );
i&=i2c_write(address>>8);
i&=i2c_write( aaddress &0xFF);
if ( i==0) ... net ACK
else .. chip otvetshal ACK
}
at90
Аппаратный TWI глюченный. Мне бысто и не нада. Хватит и медленно. Главное чтобы работало!
m16
Цитата(at90 @ Dec 12 2005, 15:27) *
Аппаратный TWI глюченный. Мне бысто и не нада. Хватит и медленно. Главное чтобы работало!

это кто ж Вам такое сказал , киньте в него камнем
bodja74
Пардон ,что не в тему,не хотелось создавать отдельную.

У меня тут вопрос насчет аппаратной реализации TWI и глюков на меге16

Вот какая ерунда,вроде нормально все работает,и передаем и получаем
и переадресуем,все класс,но все хорошо до команды СТОП.
После этого шина затыкается.
Программка простенькая,проверяет только флаг TWINT.
Но я после СТОПа и вырубал и инициализировал заново TWI,ни в какую
работать не хочет.
Кто мне скажет, какого оно не пашет?
haker_fox
Цитата
Программка простенькая,проверяет только флаг TWINT.
Но я после СТОПа и вырубал и инициализировал заново TWI,ни в какую
работать не хочет.


А после уловия "СТОП" флаг TWINT случайно не проверяете? Если проверяете, то шина вполне может зависнуть. По крайней мере мне так кажется, потому, что в application note от atmel полсе "СТОП" ни "чего нет".
Если можно, то покажите, пожалуйста исходник. И еще... Вы сами писали функции работы с TWI?
at90
Цитата(proba @ Dec 12 2005, 14:58) *
organizatsija pamjaati u 2408 i 24256 raznoe, 256 trebujet 2 baitnöi adres, smotrii datasheet.
primerno
{
U8 i;
i =i2c_start();
i&=i2c_write(EEPROM_BUS_ADDRESS );
i&=i2c_write(address>>8);
i&=i2c_write( aaddress &0xFF);
if ( i==0) ... net ACK
else .. chip otvetshal ACK
}

Пробовал ещё так
Код
void write_byte_eeprom (unsigned int address, unsigned char data)
{
unsigned char sSREG;

sSREG = SREG; // ?aaeno? Noaoona IE

#asm ("cli")
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS | ((unsigned char)(address>>8)<<1));
i2c_write((unsigned char)address);
i2c_write(data);
i2c_stop();

SREG = sSREG;
delay_ms(10);

}



unsigned char read_byte_eeprom (unsigned int address)
{
unsigned char data;
unsigned char sSREG;

sSREG = SREG;
#asm ("cli")
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS | ((unsigned char)(address>>8)<<1));
i2c_write((unsigned char)address);
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS | ((unsigned char)(address>>8)<<1) | 1);
data = i2c_read(0);
i2c_stop();
SREG = sSREG;
return data;
}


всё равно не пашет!
bodja74
***А после уловия "СТОП" флаг TWINT случайно не проверяете? Если проверяете, то шина вполне может зависнуть. По крайней мере мне так кажется, потому, что в application note от atmel полсе "СТОП" ни "чего нет".***

Флаг TWINT и проверял и не проверял,поровну.

Программа экспрессом идет дальше,но реакции на ногах нет.
То есть в первый раз все ОК.По второму кругу ничего.
Прога не виснет, получаеться сторожевого таймера тоже не поставить.
Единственный вариант проверять TWSR на отсутствие АСК и врубать сторожевого таймера на сброс.
Но тогда вопрос ,сохраняються ли значения регистров и оперативки при таком сбросе?
Чтобы программа могла успешно продолжать передачу а не циклиться на одном и том же.
Да и такие маневры программы меня не очень радуют.
Кроме того не все устройства поддерживают АСК а остальные бывает при окончании связи
выставляют NACK.
Даже не знаю что здесь делать

Второй вариант держать постоянно шину занятой,но тогда два мастера на шину не поцепить.

***Если можно, то покажите, пожалуйста исходник. И еще... Вы сами писали функции работы с TWI?***


Пишу на графическом асме,его здесь не нарисовать,хотя код в пол мизинца,опишу.

Здесь без использования прерывания по TWI

#H02->TWBR // Устанавливаем SCL 100000Гц
#H02->TWSR //
#HA4->TWCR // Включение и старт TWI
<TWINT=0> // Ждем пока TWINT=0 если TWINT= 1 идем дальше
#H40->TWDR // Записываем адресс устройства (40 HEX) в TWDR
#H84->TWCR // Отправляем адресс устройства
<TWINT=0> // Ждем пока TWINT=0 если TWINT= 1 идем дальше
#HFF->TWDR // Записываем данные для передачи (FF HEX) в TWDR
#H84->TWCR // Отправляем данные
<TWINT=0> // Ждем пока TWINT=0 если TWINT= 1 идем дальше
#H94->TWCR // Стоп

Все,если прога по второму кругу идет ,в ответ тишина.
haker_fox
Цитата
Единственный вариант проверять TWSR на отсутствие АСК и врубать сторожевого таймера на сброс.
Но тогда вопрос ,сохраняються ли значения регистров и оперативки при таком сбросе?
Чтобы программа могла успешно продолжать передачу а не циклиться на одном и том же.
Да и такие маневры программы меня не очень радуют.

Я тоже думаю, что это не нужно... полная кривизна программы получится wink.gif

Цитата
Пишу на графическом асме,его здесь не нарисовать,хотя код в пол мизинца,опишу.

Здесь без использования прерывания по TWI

#H02->TWBR // Устанавливаем SCL 100000Гц
#H02->TWSR //
#HA4->TWCR // Включение и старт TWI
<TWINT=0> // Ждем пока TWINT=0 если TWINT= 1 идем дальше
#H40->TWDR // Записываем адресс устройства (40 HEX) в TWDR
#H84->TWCR // Отправляем адресс устройства
<TWINT=0> // Ждем пока TWINT=0 если TWINT= 1 идем дальше
#HFF->TWDR // Записываем данные для передачи (FF HEX) в TWDR
#H84->TWCR // Отправляем данные
<TWINT=0> // Ждем пока TWINT=0 если TWINT= 1 идем дальше
#H94->TWCR // Стоп

Все,если прога по второму кругу идет ,в ответ тишина.

Тяжело мне это все понять (мой комп на работе в ремонте, а там все даташиты и исходники, так что не могу сверится с документацией sad.gif )
Единственное как вариант, могу посоветовать поискать ниже по форуму ветки по TWI... их было около 2-3... там я выкладывал рабочие, прокомментированные исходники на Си. Правда в текстах отсутствует проверка на ошибки шины. Если Вы не знаете Си, то все равно там все должно быть понятно, код очень простой.
Igor26
Тяжело мне это все понять (мой комп на работе в ремонте, а там все даташиты и исходники, так что не могу сверится с документацией sad.gif )
Единственное как вариант, могу посоветовать поискать ниже по форуму ветки по TWI... их было около 2-3... там я выкладывал рабочие, прокомментированные исходники на Си. Правда в текстах отсутствует проверка на ошибки шины. Если Вы не знаете Си, то все равно там все должно быть понятно, код очень простой.
[/quote]
И, проверенно, полностью рабочий a14.gif
at90
Заработало так. Как в даташите?

Код
#define  EEPROM_BUS_ADDRESS 0xa0
void write_byte_eeprom (unsigned int address, unsigned char data)
{
unsigned char sSREG;

sSREG = SREG; // регистр Статуса МК

#asm ("cli")
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS);
i2c_write((unsigned char)address>>7);
i2c_write((unsigned char)address);
i2c_write(data);
i2c_stop();

SREG = sSREG;
delay_ms(10);

}



unsigned char read_byte_eeprom (unsigned int address)
{
unsigned char data;
unsigned char sSREG;

sSREG = SREG;
#asm ("cli")
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS);
i2c_write((unsigned char)address>>7);
i2c_write((unsigned char)address);
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS | 1);
data = i2c_read(0);
i2c_stop();
SREG = sSREG;
return data;
}
bodja74
Ужасно извиняюсь ,что беспокоил по своей проблеме.

Проблема решена и все работает прекрасно.
Все оказалось абсолютно банально.
Асм оказался слишком быстр для WTI.
Так как на меге толком нельзя было проверить выполнение
команды СТОП ,прога по быстрячку обрабатывала данные
и залетала на СТАРТ еще до того как TWI успевал
сформировать сигнал СТОП,из за чего и был глюк начиная
со второго захода.
Достаточно было установить паузу длиной в 1 SCL,
как все стало в норме.
При частоте шины 100кГц достаточно паузы для
надежности в 10 микросекунд.

Желаю тем кто любит писать "быстрый" код ,не
наступать на эти грабли.
haker_fox
Цитата
Ужасно извиняюсь ,что беспокоил по своей проблеме.

Проблема решена и все работает прекрасно.
Все оказалось абсолютно банально.
Асм оказался слишком быстр для WTI.
Так как на меге толком нельзя было проверить выполнение
команды СТОП ,прога по быстрячку обрабатывала данные
и залетала на СТАРТ еще до того как TWI успевал
сформировать сигнал СТОП,из за чего и был глюк начиная
со второго захода.
Достаточно было установить паузу длиной в 1 SCL,
как все стало в норме.
При частоте шины 100кГц достаточно паузы для
надежности в 10 микросекунд.

Желаю тем кто любит писать "быстрый" код ,не
наступать на эти грабли.


Вот это да! Огромный Вам респект за это!!! a14.gif
Действительно, такая ситуация может быть... но не так-то просто во всем разобраться rolleyes.gif

Инетерсно, а компилятор с языка Си учитывает такие траблы? Например код (для примера):
i2c_start();
i2c_tx(23);
i2c_tx(24);
i2c_stop();

//Будет ли здесь вставлена пауза?

i2c_start();
i2c_tx(25);
i2c_tx(26);
i2c_stop();

Надо будет посмотреть листинг...
bodja74
То: Haker_fox

Ничего толкового не могу сказать по Си ,так как недавно его начал изучать
под АРМ.
Но лично мое мнение, если компиллятор асма выполняет роль перекодировщика
елементарных комманд в элементарный код,то компилятор Си выполняет роль
некоего интелектуала для тех кто не любит или не хочет вникать в суть и назначение
работы регистров ввода-вывода,(или по другому служебных регистров)
И про его интеллект можно только догадываться.
Хотя я думаю на Си можно напямую работать с регистрами.

To: at90

Для записи в память нужно указывать адресс А0 (НЕХ),
а для чтения А1 (НЕХ),(может это делает компилятор автоматом не знаю).
Кроме того гляньте на ножки 1,2,3 они могут менять адресс.
Кроме того обратите внимание на ножку 7,иногда разрешает запись "0"
а иногда "1"
haker_fox
Цитата
Ничего толкового не могу сказать по Си ,так как недавно его начал изучать
под АРМ.
Но лично мое мнение, если компиллятор асма выполняет роль перекодировщика
елементарных комманд в элементарный код,то компилятор Си выполняет роль
некоего интелектуала для тех кто не любит или не хочет вникать в суть и назначение
работы регистров ввода-вывода,(или по другому служебных регистров)
И про его интеллект можно только догадываться.
Хотя я думаю на Си можно напямую работать с регистрами.


1. Не совсем согласен на счет "выполняет роль
некоего интелектуала для тех кто не любит или не хочет вникать в суть и назначение
работы регистров ввода-вывода"...

Не всегда возможно написать прогамму на ассембере, когда например очень много сложных структур данных для обработки или алгоритм программы достаточно сложен и запутан для программирования на ассемблере. Хотя не спорю, можно и на ассемблере много чего хорошего сделать smile.gif

2. Да на Си можно работать напрямую с регистрами.
bodja74
To: haker_fox

Полностью согласен с Вами.

Самое оптимальное решение для меня - знать несколько языков.
Георгий
К сожалению для меня sad.gif интеллект компилятора пока выше моего. Пробовал реализовывать идин и тот же алгоритм на асме и на Си, код на Си оказался на 300 байт! короче. Иногда вообще, напишу кусок кода, смотрю в листинге, а части кода нет, оказывается, компилятор лучше меня просчитал, что этого не может быть никогда. так что пока я у него учусь cheers.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.