реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Не могу записать страницу в AT24C64B
kurtis
сообщение Jan 15 2010, 16:11
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205



Пытаюсь записать страницу (32 байта) в EEPROM с помощью atmega128.
Если коротко, то код отвечающий за запись значений в EEPROM такой
CODE
EEPROM.write_byte(0xAA, 0x520); /* 1 */
_delay_ms(10);
EEPROM.write_byte(0xAA, 0x600); /* 2 */
_delay_ms(10);

EEPROM.write_word(0xA5A5, 0x700); /* 3 */
_delay_ms(10);
EEPROM.write_word(0xA5A5, 0x800); /* 4 */
_delay_ms(10);

uint8_t temp_value[16];
for (i=0; i<15; i++)
temp_value[i] = 0xB5;

EEPROM.write_page(0x900, temp_value, 16); /* 5 */
_delay_ms(10);

for (i=0; i<15; i++)
temp_value[i] = 0xB6;

EEPROM.write_page(0x1000, temp_value, 16); /* 6 */
_delay_ms(10);

вариант 1 и 2, а также 3 и 4, записываются нормально, вариант 5 и 6 вроде пишутся, но по непонятным адресам. Дамп памяти выглядит следующим образом (звездочка ("*") значит что значения не меняются).
CODE
*
00000500 05 10 55 55 55 55 55 55 55 55 55 55 55 55 55 55 |..UUUUUUUUUUUUUU|
00000510 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 |UUUUUUUUUUUUUUUU|
00000520 aa 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 |.UUUUUUUUUUUUUUU|
00000530 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 |UUUUUUUUUUUUUUUU|
*
00000600 aa 55 55 55 55 55 55 55 55 00 b5 b5 b5 b5 b5 b5 |.UUUUUUUU.......|
00000610 00 b6 b6 b6 b6 b6 b6 b6 b6 b6 b6 b6 b6 b6 b6 b6 |................|
00000620 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 |UUUUUUUUUUUUUUUU|
*
00000700 a5 a5 55 55 55 55 55 55 55 55 55 55 55 55 55 55 |..UUUUUUUUUUUUUU|
00000710 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 |UUUUUUUUUUUUUUUU|
*
00000800 a5 a5 55 55 55 55 55 55 55 55 55 55 55 55 55 55 |..UUUUUUUUUUUUUU|
00000810 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 |UUUUUUUUUUUUUUUU|
*
вся память, изначально, заполнена значениями 0x55. Как видно из приведенного фрагмента (результат команды hexdump), значения пишутся по адресам 0x609-0x61F, хотя должны были по 0x900 и 0x1000. Еще не совсем понятно от куда взялись нули (0x00).

Исходный текст функции write_page():
CODE
uint8_t at24c64::write_page(const uint16_t addr,
const uint8_t * message,
const uint8_t size_of_message)
{
uint8_t i;

start_i2c();

/* Микросхема не на линии */
if (false == write_i2c(i2c_address)) {
stop_i2c();
return EXIT_FAILURE;
}

(void)write_i2c(i2c_address);

(void)write_i2c((uint8_t)(addr >> 8));
(void)write_i2c((uint8_t)addr);

for (i=0; i < size_of_message; i++, message++) {
(void)write_i2c(*message);
}

stop_i2c();

return EXIT_SUCCESS;
}

Развернутое описание класса at24c64 и Iic приводится в прикрепленном файле (исходники в utf8)



В чем может быть проблема?

П.С. Спасибо что дочитали до конца!:-))
Прикрепленные файлы
Прикрепленный файл  files.zip ( 3.34 килобайт ) Кол-во скачиваний: 21
 
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 15 2010, 17:57
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



В I2C криминала не видно. Подтяжки на SDA, SCL есть?
В at24c64.cpp вы не анализируете ответ (ACK) памяти - а вдруг предыдущая запись не окончилась? Или еще по какой-то причине память выдаст NACK. Все остально выглядит правильным.
Кроме подтяжек ничего в голову не приходит.

Функции чтения и записи я бы чуток оптимизировал:
Код
bool I2C::write_i2c(const uint8_t byte)
{
    int8_t bit_counter;

    for (bit_counter = 8; bit_counter > 0; bit_counter--) {
        if (byte & (1 << 7)) {
            SDA_1;
        }
        else {
            SDA_0;
        }
        byte <<= 1;

        SCL_1;
        _delay_us(5);
        SCL_0;
        _delay_us(5);
    }
    SDA_1;
    SCL_1;
    _delay_us(5);
    bool result = !(PIND & (1 << SDA));
    SCL_0;
    _delay_us(5);

    return result;
}
MSB/LSB поправил


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
SysRq
сообщение Jan 15 2010, 18:13
Сообщение #3


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Цитата(kurtis @ Jan 15 2010, 19:11) *
Код
    /* Микросхема не на линии */
    if (false == write_i2c(i2c_address)) {
        stop_i2c();
        return EXIT_FAILURE;
    }

    (void)write_i2c(i2c_address);
Дык, если на линии, второй раз i2c-адрес EEPROM'ки зачем передавать? smile.gif
Если адрес у вас 0xA6, то как раз получится запись с 0x609 вместо 0x900, а нули - младший байт адреса...

--

Цитата(Сергей Борщ @ Jan 15 2010, 20:57) *
Функции чтения и записи я бы чуток оптимизировал...
Было MSB first, стало LSB first. (Поправили.)
Go to the top of the page
 
+Quote Post
kurtis
сообщение Jan 15 2010, 18:55
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205



Цитата(Сергей Борщ @ Jan 15 2010, 19:57) *
Функции чтения и записи я бы чуток оптимизировал:

Спасибо, вроде компактней генерируемый код стал!


Цитата
Дык, если на линии, второй раз i2c-адрес EEPROM'ки зачем передавать? smile.gif
Если адрес у вас 0xA6, то как раз получится запись с 0x609 вместо 0x900, а нули - младший байт адреса...

Спасибо, а слона то, как всегда, и не заметил!))
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th June 2025 - 22:26
Рейтинг@Mail.ru


Страница сгенерированна за 0.01365 секунд с 7
ELECTRONIX ©2004-2016