INT 21h

Hi, I am Vladimir Smagin, sysadmin. Telegram Email

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 responses to “EEPROM память через TWI (I2C) на примере 24LC16B и микроконтроллере Atmega16”

  1. Евгений says:

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

  2. 21h says:

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

  3. Евгений says:

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

  4. 21h says:

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

  5. Евгений says:

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

  6. 21h says:

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

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Комментарии

  • 21h: нене ) без меня )
  • Серегй: Не совсем грабить)) если грабить можно и без рации, есть...
  • 21h: магазин грабить собрались? ) не, тут я не помощник ;)
  • Серегй: А что бы мне поймать чужую волну, что мне для этого нужно...
  • 21h: слушать никто не запрещает. нет закона, который запрещает...
  • Серегй: Я хотел узнать могу ли я просто прийти с данной рацией baofeng...
  • 21h: У меня есть только эти 2. По другим ничего не знаю. В интернете...

© Vladimir Smagin, 2005-2017. Копирование материалов без разрешения запрещено.
Яндекс.Метрика