INT 21h

Домашняя страница самого страшного прерывания

EEPROM память через TWI (I2C) на примере 24LC16B и микроконтроллере Atmega16

№ 3070 В разделах: Программирование Электроника от June 28th, 2011,

Самая обычная микросхема памяти на 2 Кбайта. Есть в DIP-8, SOIC-8 и SOIC-14 корпусах. Работает по протоколу I2C. Если вы решили повесить несколько таких на 1 шину, то вынужден вас огорчить. Эта микросхема может быть только 1 на шине, т.к. ножки 1, 2 и 3 не используются. Если надо несколько, то выберите другую модель.

Для демонстрации я использую свою библиотеку для работы с TWI (он же I2C).

Создадим пару функций для чтения и записи. Традиционно я придерживаюсь атомарных операций, но если вам надо записывать больше, чем 1 байт, то можете легко дополнить эти функции циклом. Если не используете UART, уберите строки с printf_P().

    // Адрес микросхемы для чтения A1
    // Адрес микросхемы для записи A0

uint8_t mem_read(uint8_t address)
{
    uint8_t         data;

  restart:
    if (twi_start(0xA0)) {
        printf_P(PSTR("EEPROM: Started. Sending cell address %#x\n"), address);
        if (!twi_send(address))
            goto restart;
        twi_start(0xA1);
        data = twi_receive(1);
        printf_P(PSTR("EEPROM: Byte received %#x\n"), data);
        twi_stop();
        return data;
    } else {
        // ошибка
        printf_P(PSTR("EEPROM: Error while start\n"));
    }
}

void mem_write(uint8_t address, uint8_t data)
{
  restart:
    if (twi_start(0xA0)) {
        if (!twi_send(address))
            goto restart;
        twi_send(data);
        printf_P(PSTR("EEPROM: Byte sended: %#x\n"), data);
        twi_stop();
		return 1;
    } else {
        // ошибка
        printf_P(PSTR("EEPROM: Error while start\n"));
        return 0;
    }
}

На вид все просто. Особенно если вы правильно припаяли чип памяти к аппаратному TWI интерфейсу микроконтроллера и подтянули линии на +5 через резисторы на 4.7 кОм. Если все равно не знаете как припаять, то можете увидеть на этой схеме пример.

Алгоритм работы чтения традиционен:

  1. отправили стартовую последовательность
  2. отправили адрес устройства с битом записи
  3. отправили адрес ячейки памяти
  4. сделали повторный старт
  5. отправили адрес устройства с битом для чтения
  6. получили байт
  7. отправили стоповую последовательность

Также традиционна и запись:

  1. отправили стартовую последовательность
  2. отправили адрес устройства с битом записи
  3. отправили адрес ячейки памяти
  4. отправили байт
  5. отправили стоповую последовательность

Если уже знакомы с TWI (I2C), то ничего нового для вас не будет. Обращу внимание, что для того, чтобы можно было записать в микросхему, нужно подпаять ножку 7 к ножке 4. Если хотите наоборот запретить запись, то 7 припаяйте к 8. Конечно, можно сделать и программное управление, использовав 1 ножку от микроконтроллера.

Теперь давайте в вашей программе вызовем чтение, запись, а потом еще раз чтение. Записывать будем в ячейку 0x01 текущий час, который мы прочитали с часов DS1307 на этой же TWI шине.

printf_P(PSTR("SYS: Read from EEPROM\n"));
mem_read(0x01);

В UART видим:
SYS: Read from EEPROM
--> TWI Session starting...
--> sending start sequence
--> selecting status: TW_REP_START or TW_START
--> sending SLA 0xa0
--> selecting status: TW_MT_SLA_ACK
EEPROM: Started. Sending cell address 0x1
--> TWI Sending 0x1
--> selecting status: TW_MT_DATA_ACK
--> TWI Session starting...
--> sending start sequence
--> selecting status: TW_REP_START or TW_START
--> sending SLA 0xa1
--> selecting status: TW_MR_SLA_ACK
--> TWI Receive
--> Sending NACK
--> Waiting answer... got!
--> Received 0xff
EEPROM: Byte received 0xff
--> TWI Session stopping... done

В ячейке 0x01 лежит 0xFF.

А теперь запишем в нее текущее количество часов из часовой микросхемы:

printf_P(PSTR("SYS: Write to EEPROM\n"));
mem_write(0x01, (uint8_t) (time & 0x000000FF));

SYS: Write to EEPROM
--> TWI Session starting...
--> sending start sequence
--> selecting status: TW_REP_START or TW_START
--> sending SLA 0xa0
--> selecting status: TW_MT_SLA_ACK
--> TWI Sending 0x1
--> selecting status: TW_MT_DATA_ACK
--> TWI Sending 0x3
--> selecting status: TW_MT_DATA_ACK
EEPROM: Byte sended: 0x3
--> TWI Session stopping... done

Видим, что сейчас 3 часа ночи. Отправили это значение в микросхему памяти. А теперь попробуем ее опять прочитать.

SYS: Read from EEPROM
--> TWI Session starting...
--> sending start sequence
--> selecting status: TW_REP_START or TW_START
--> sending SLA 0xa0
--> selecting status: TW_MT_SLA_ACK
EEPROM: Started. Sending cell address 0x1
--> TWI Sending 0x1
--> selecting status: TW_MT_DATA_ACK
--> TWI Session starting...
--> sending start sequence
--> selecting status: TW_REP_START or TW_START
--> sending SLA 0xa1
--> selecting status: TW_MR_SLA_ACK
--> TWI Receive
--> Sending NACK
--> Waiting answer... got!
--> Received 0x3
EEPROM: Byte received 0x3
--> TWI Session stopping... done

Вот такой несложной библиотекой вы можете читать и сохранять информацию в память.

Традиционно файлы с функциями: eeprom.c eeprom.h

6 комментариев »

6 комментариев »

Comment by Евгений | June 7, 2012 @ 16:19:42

Уже несколько дней пытаюсь заставить работать TWI. Перепробовал кучу драйверов, но ни один не работает.
Попробовал записать в eeprom 24C16 и в 24C08 – не получилось, программа виснет на строке twi_start(0xA0). Микроконтроллер atmega32. С программным I2C (http://u.to/WAsbAg) епромка читается.
Где могут быть грабли зарыты, подскажите пожалуйста?
UART не использую, все вызовы функции printf_P закоментил, адрес епромки правильный.

Comment by 21h | June 9, 2012 @ 08:30:14

на выходных посмотрю код когда время будет. на первый взгляд там не TWI, а программное I2C.

Comment by Евгений | June 9, 2012 @ 17:34:43

Так я же про ваш код говорю, у вас же TWI.
Ваш код у меня не работает ни в какую, но вот программная реализация работает.

Comment by 21h | June 9, 2012 @ 17:56:27

а сам контроллер то поддерживает TWI? модель МК в студию

Comment by Евгений | June 9, 2012 @ 21:47:10

Я об этом уже писал в первом сообщении:
Микроконтроллер atmega32, TWI поддерживает.

Comment by 21h | June 10, 2012 @ 01:58:41

скорее всего неправильно подключаешь библиотеку. также могут быть проблемы из-за отсутствия резисторов 4.7 ком между 2 линиями TWI и +5В. также проблема может возникнуть из-за слишком маленькой частоты МК. частоту лучше поднять до 8 мгц. кроме того нужно выдерживать и задержки, которые указаны в даташите. можно увидеть код программы с моей библиотекой? у меня есть демоплата, где могу отладить чип твой.

Форма отправки комментария

CAPTCHA
*

Разрешенные HTML-теги:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

RSS RSS Feed только для этого поста |


Комментарии
  • Игорь: Все настроил, еще раз просмотрел видео и методом научного тыка все настроил и сохранил, все работает и обе...
  • 21h: Здравствуйте, Игорь! Я не знаю :) Думаю аналогично согласно инструкции к вашей радиостанции.
  • Игорь: Добрый день, просмотрел Ваше видео все доступно и ясно для 8 ми канальных радеек, но мне нада настроить 69...
  • Гоги: Есть инструкция к Моторолкам – она подходит к серии Motorola TLKR T4… Т8. В конце сетка частот и...
  • 21h: торчок давно уже не обновлял, как только закрыл сайт где он работал. да, это морда для opentracker. без...
  • Buter: Какова дальнейшая жизнь торчка? Он кстати веб-интерфейсом для OpenTracker выступает? Без OpenTracker работать...
  • 21h: понятия не имею. гуглите инструкцию к вашей радейке и сверяйтесь с ней.
  • Денис: хочу их подружить с uv5r
  • Денис: t-388 walkie talkie на эти шпаргалочек нет,или как приминить ваши к их настройке?
  • John: Стекла для электроник – техночас.ру