24lc64 как считать память
Перейти к содержимому

24lc64 как считать память

Nagits's Blog

AVR: РАБОТАЕМ С ВНЕШНЕЙ ПАМЯТЬЮ I2C EEPROM типа 24CXX

Для того чтобы полностью разобраться с Two-Wire Interface (TWI) , пишем с нуля в AVR STUDIO процедуры инициализации, чтения и записи. Подробно останавливаемся на каждом шаге и разбираемся. Затем промоделируем все в Proteus.

I. Кратко теория

Аппаратный модуль TWI и протокол I2C

В микроконтроллеры серии MEGA входит модуль TWI, с помощью которого мы будем работать с шиной I2C. Модуль TWI по сути является посредником между нашей программой и подключаемым устройством (память I2C EEPROM, например).

Структура модуля TWI в микроконтроллерах AVR

Шина I2C состоит из двух проводов:

  • SCL (Serial Clock Line) – линия последовательной передачи тактовых импульсов.
  • SDA (Serial Data Line) – линия последовательной передачи данных.

К этой шине мы можем одновременно подключить до 128 микросхем.

Подключения к шине TWI

Наш контроллер будем называть ведущим, а все подключаемые микросхемы ведомыми. Каждый ведомый имеет определенный адрес, зашитый на заводе в ходе изготовления (кстати, граница в 128 микросхем как раз и определяется диапазоном возможных адресов). С помощью этого адреса мы и можем работать с каждый ведомым индивидуально, хотя все они подключены к одной шине одинаковым образом. Из нашей программы мы управляем модулем TWI, а этот модуль берет на себя дергание ножками SCL и SDA.

Как видно на блок-схеме, TWI условно состоит из четырех блоков. Вначале нам нужно будет настроить Генератор скорости связи, и мы сразу забудем про него. Основная работа – с Блоком управления.

Блок шинного интерфейса управляется Блоком управления, т.е. непосредственно с ним мы контактировать не будем. А Блок сравнения адреса нужен, чтобы задать адрес на шине I2C, если тока наш контроллер будет подчиненным устройством(ведомым) от другого какого-то контроллера или будет приемником от другого ведущего (как в статье Налаживаем обмен данными между двумя контроллерами по шине I²C на моем блоге). В этой статье он нам не нужен. Если хотите, почитайте про него в любом даташите контроллера серии MEGA.

Итак, наша задача сейчас разобраться с регистрами, входящими в Генератор скорости связи и Блок управления:

 Регистр скорости связи TWBR

 Регистр управления TWCR

 Регистр статуса(состояния) TWSR

 Регистр данных TWDR

И все, разобравшись всего лишь с 4-мя регистрами, мы сможем полноценно работать с внешней памятью EEPROM и вообще, обмениваться данными по I2C с любым другим устройством.

Генератор скорости связи и Регистр скорости связи TWBR

Блок генератора скорости связи управляет линией SCL, а именно периодом тактовых импульсов. Управлять линией SCL может только ведущий. Период SCL управляется путем установки регистра скорости связи TWI (TWBR) и бит предделителя в регистре статуса TWI (TWSR).

Частота SCL генерируется по следующей формуле:

FSCL= FЦПУ/[16+2(TWBR) · 4 TWPS ],

  • TWBR — значение в регистре скорости связи TWI;
  • TWPS — значение бит предделителя в регистре статуса TWI (TWSR).
  • Fцпу – тактовая частота ведущего
  • FSCL – частота тактовых импульсов линии SCL

Настройка TWBR нужна, т.к. ведомая микросхема обучена обмениваться данными на определенной частоте. Например, в Proteus, введите в поиск I2CMEM, увидите обилие микросхем памяти, в основном у них указаны частоты 100 и 400Khz.

Ну вот, подставляя в формулу частоты FЦПУ и FSCL , мы сможем найти оптимальное значение для регистра TWBR.

TWPS – это 2-битное число [TWPS1: TWPS0], первый бит – это разряд TWPS0, второй – TWPS1 в регистре статуса TWSR. Задавая Предделитель скорости связи 4 TWPS , мы можем понижать значение TWBR (т.к. TWBR – это байт, максимальное значение 255). Но обычно это не требуется, поэтому TWPS обычно задается 0 и 4 TWPS = 1. Гораздо чаще, наоборот, мы упираемся в нижний диапазон регистра TWBR. Если TWI работает в ведущем режиме, то значение TWBR должно быть не менее 10. Если значение TWBR меньше 10, то ведущее устройство шины может генерировать некорректные сигналы на линиях SDA и SCL во время передачи байта.

TWPS1 TWPS0 TWPS10 Значение предделителя 4 TWPS
0 0 0 1
0 1 1 4
1 0 2 16
1 1 3 64
Частота ЦПУ, МГц TWBR TWPS Частота SCL, КГц
16.0 12 0 400
16.0 72 0 100
14.4 10 0 400
14.4 64 0 100
12.0 52 0 100
8.0 32 0 100
4.0 12 0 100
3.6 10 0 100

 задание значения предделителя ([TWPS1: TWPS0] в регистре статуса TWSR)

Регистр состояния TWI — TWSR

Разряд 7 6 5 4 3 2 1 0
TWS7 TWS6 TWS5 TWS4 TWS3 TWPS1 TWPS0
Чтение/запись Чт. Чт. Чт. Чт. Чт. Чт. Чт./Зп. Чт./Зп.
Исх. значение 1 1 1 1 1 0 0 0

 задание скорости связи (TWBR, Регистр скорости связи).

Регистр скорости связи шины TWI — TWBR

Разряд 7 6 5 4 3 2 1 0
TWBR7 TWBR6 TWBR5 TWBR4 TWBR3 TWBR2 TWBR1 TWBR0
Чтение/запись Чт./Зп. Чт./Зп. Чт./Зп. Чт./Зп. Чт./Зп. Чт./Зп. Чт./Зп. Чт./Зп.
Исх. значение 0 0 0 0 0 0 0 0

Блок управления

Регистр управления шиной TWI — TWCR

Регистр TWCR предназначен для управления работой TWI. Он используется для разрешения работы TWI, для инициации сеанса связи ведущего путем генерации условия СТАРТ на шине, для генерации подтверждения приема, для генерации условия СТОП и для останова шины во время записи в регистр TWDR. Он также сигнализирует о попытке ошибочной записи в регистр TWDR, когда доступ к нему был запрещен.

Регистр управления шиной TWI — TWCR

Разряд 7 6 5 4 3 2 1 0
TWINT TWEA TWSTA TWSTO TWWC TWEN TWIE
Чтение/запись Чт./Зп. Чт./Зп. Чт./Зп. Чт./Зп. Чт. Чт./Зп. Чт. Чт./Зп.
Исх. значение 0 0 0 0 0 0 0 0

 Разряд 7 — TWINT: Флаг прерывания TWI

Этот флаг устанавливается аппаратно, если TWI завершает текущее задание (к примеру, передачу, принятие данных) и ожидает реакции программы. Линия SCL остается в низком состоянии, пока установлен флаг TWINT. Флаг TWINT сбрасывается программно путем записи в него логической 1. Очистка данного флага приводит к возобновлению работы TWI, т.е. программный сброс данного флага необходимо выполнить после завершения опроса регистров статуса TWSR и данных TWDR.

 Разряд 6 — TWEA: Бит разрешения подтверждения

Бит TWEA управляет генерацией импульса подтверждения. Как видно в таблице, по умолчанию он сброшен. Останавливаться на нем не буду, он в данной статье не пригодится.

 Разряд 5 — TWSTA: Бит условия СТАРТ

Мы должны установить данный бит при необходимости стать ведущим на шине I2C. TWI аппаратно проверяет доступность шины и генерирует условие СТАРТ, если шина свободна. Мы проверяем это условие (по регистру статуса, будет далее) и если шина свободна, то мы можем начинать с ней работать. Иначе нужно будет подождать, пока шина освободится.

 Разряд 4 — TWSTO: Бит условия СТОП

Установка бита TWSTO в режиме ведущего приводит к генерации условия СТОП на шине I2C. Если на шине выполняется условие СТОП, то бит TWSTO сбрасывается автоматически и шина освобождается.

 Разряд 3 — TWWC: Флаг ошибочной записи

Бит TWWC устанавливается при попытке записи в регистр данных TWDR, когда TWINT имеет низкий уровень. Флаг сбрасывается при записи регистра TWDR, когда TWINT = 1.

 Разряд 2 — TWEN: Бит разрешения работы TWI

Бит TWEN разрешает работу TWI и активизирует интерфейс TWI. Если бит TWEN установлен, то TWI берет на себя функции управления линиями ввода-вывода SCL и SDA. Если данный бит равен нулю, то TWI отключается и все передачи прекращаются независимо от состояния работы.

 Разряд 1 — Резервный бит

 Разряд 0 — TWIE: Разрешение прерывания TWI

Если в данный бит записана лог. 1 и установлен бит I в регистре SREG (прерывания разрешены глобально), то разрешается прерывание от модуля TWI (ISR (TWI_vect)) при любом изменении регистра статуса.

Регистр состояния TWI – TWSR

Разряд 7 6 5 4 3 2 1 0
TWS7 TWS6 TWS5 TWS4 TWS3 TWPS1 TWPS0
Чтение/запись Чт. Чт. Чт. Чт. Чт. Чт. Чт./Зп. Чт./Зп.
Исх. значение 1 1 1 1 1 0 0 0

 Разряды 7..3 — TWS: Состояние TWI

Данные 5 бит отражают состояние логики блока TWI и шины I2C. Диапазон кодов состояния 0b0000 0000 – 0b1111 1000, или с 0x00 до 0xF8. Привожу их ниже:

Если мы работаем с пассивным ведомым (т.е. это не другой контроллер AVR, а микросхема памяти или например, часы RTC), то коды состояний из разделов Slave Transmitter (Ведомый в роли передающего) и Slave Receiver (Ведомый в роли принимающего) нам не понадобятся, поскольку единственная «разумная» микросхема у нас – это Ведущий (наш контроллер).

Проверяя регистр статуса после каждой выполненной операции с шиной, мы можем контролировать обмен информацией. Например, будем точно знать – записались ли данные во внешнюю память или нет.

Регистр данных шины TWI — TWDR

Разряд 7 6 5 4 3 2 1 0
TWD7 TWD6 TWD5 TWD4 TWD3 TWD2 TWD1 TWD0
Чтение/запись Чт./Зп. Чт./Зп. Чт./Зп. Чт./Зп. Чт./Зп. Чт./Зп. Чт./Зп. Чт./Зп.
Исх. значение 1 1 1 1 1 1 1 1

В режиме передатчика регистр TWDR содержит байт для передачи. В режиме приемника регистр TWDR содержит последний принятый байт. Будьте внимательны, после аппаратной установки флага TWINT, регистр TWDR не содержит ничего определенного.

Ну вот, этих знаний более чем достаточно, чтобы работать с I2C EEPROM. Теперь переходим непосредственно к программной части. Я решил пояснения писать прямо в коде в виде комментариев.

II. Программа

Все функции (инициализация TWI, чтение, запись внешней памяти) я вынесу в отдельные файлы, как это и принято делать, i2c_eeprom.c и i2c_eeprom.h.

Содержание i2c_eeprom.h следующее:

Чтобы было легче воспринимать нижеследующий код, приведу здесь теоретические примеры осциллограмм при обмене данными между Ведущим и Ведомым по шине I2C (взял в книжке [1], в более высоком разрешении найдете по адресу, указанном в конце статьи):

Примеры обмена данными между Ведомым и Ведущим

Далее привожу листинг файла i2c_eeprom.c с подробными комментариями:

Ну вот, самые главные функции мы написали. На этой базе можно написать функции для чтения\записи массива байтов. Также можно добавить прерывание ISR(TWI_INT), которое будет срабатывать при каждом изменении регистра статуса. Я скажу только пару слов об этом, поскольку разобравшись в вышеизложенном, вам не составит труда реализовать их самому.

Итак, пару слов о чтении\записи массива байтов. Очень просто взять и вогнать в цикл функции eeReadByte\eeWriteByte. Это даже будет работать  . Но, посмотрите, TWI каждый раз будет формировать условие СТАРТ, устанавливать связь с ведомым, отсылать адрес чтения\записи… Словом, огромная потеря времени. Вы же не покупаете продукты в магазине по частям  , нет — вы складываете все продукты (байты) в кулек (в массив) и несете домой. Дак давайте также сложим все наши байты в кулек! Изменения в новой функции eeWriteByte s

будут следующими, часть кода затаскиваем в цикл:

В процедуре чтения изменения будут чуточку сложнее, поскольку между считыванием байтов данных должно быть подтверждение от ведущего, а после считывания последнего байта подтверждения быть не должно, далее идет условие завершения передачи (условие СТОП).

Про прерывание ISR(TWI_INT) говорить ничего не буду, просто приведу пример использования (обычно этого достаточно, сразу становится все понятно):

Все, остается создать проект в AVR STUDIO:

В настройках проекта укажите какой-нибудь MEGA (atmega16 например), подключите файлы i2c_eeprom.c и i2c_eeprom.h.

В программе я явно указал частоту тактирования моего контроллера 16 Mhz. Далее, в Proteus, мы выберем какую-нибудь микросхему внешней памяти I2C EEPROM. Не забудьте после этого сравнить настройки в i2c_eeprom.h с параметрами выбранной микросхемы (slaveF_SCL, slaveAddressConst – достоверную информацию всегда можно узнать из даташитов).

Итак, остается собрать проект и переходим к моделированию..

III. Моделируем работу с I2C EEPROM в Proteus

Добавляем на схему ATmega16, 2 резистора для подтяжки шины I2C (см. схему в начале статьи). Из вкладки виртуальные инструменты возьмите Осциллограф и I2C-Отладчик. Для выбора памяти введите в поиск I2CMEMS в окне выбора устройств:

Из всего списка я выбрал 24LC64 с объемом памяти 64 КБ и частотой работы с шиной I2C 400 КГц.

У микросхемы 8 ножек. Все, кроме питания и земли, отображены на скриншоте слева. С SCK и SDA мы знакомы, WP – Write Protect (защита от записи), A0:A2 используются для выбора переменной части адреса ведомой микросхемы (для чего нужны, уже писал где-то выше). Даташит на эту микросхему можете найти по запросу 24XX64 в гугле. Там можете проверить постоянную часть адреса и частоту, а также посмотреть, как использовать ножки WP, A0:A2.

В настройках контроллера укажите прошивку, частоту тактирования 16 МГц и не забудьте выставить CKSEL-фьюзы для кристалла. В настройках I2C-отладчика укажите, что тактовая частота импульсов шины 400 КГц.

Видно, что в PORTA записалось число 0b0000’1010 или 0x0A или 10, т.е. переменная uint8_t byte содержит верное значение после чтения памяти 24LC64 по адресу 0х19. Давайте посмотрим подробнее, что делает наша программа, взглянем на лог I2C-отладчика:

Теперь можно опуститься еще на уровень ниже и посмотреть на осциллограмму:

Логика, думаю, понятна. Так можно просмотреть и всю осциллограмму, проверить работу I2C в реальной ситуации, а не в режиме симуляции.

HT24LC64

память ЭСППЗУ технологии КМОП объемом 64 Кбит с 2-проводным последовательным интерфейсом

  • Напряжение питания — 2,4-5,5 В;
  • Малое энергопотребление: — рабочий режим — 5 мА макс.; — дежурный режим — 5 мкА макс.;
  • Внутренняя структура — 8192х8;
  • 2-проводный последовательный интерфейс;
  • Режим записи со встроенным таймером;
  • Максимальное время 1-го цикла записи — 5 мс;
  • Режим страничной записи по 32 байта;
  • Режим частичной записи страницы;
  • Аппаратная защита от записи;
  • Автоматическое стирание ячейки перед записью;
  • 1 млн. циклов перезаписи на слово;
  • Срок сохранности информации — 40 лет;
  • Коммерческий температурный диапазон — от 0°С до +70 °С;
  • 8-выводный корпус DIP или SSOP.

HT24LC64 — это ИС энергонезависимой памяти с электрическим стиранием (ЭСППЗУ) фирмы Holtek Semiconductor, выпускаемая по технологии КМОП с плавающим затвором объемом 64 Кбит с 2-проводным последовательным интерфейсом. 65536 бит памяти организовано в 8192 8-битных слова. Изделие оптимизировано для использования в различных промышленных и потребительских устройствах, где важны малое энергопотребление и низкое напряжение питания. HT24LC64 гарантирует надежную работу в течение 1 млн. циклов стирания/записи и срок сохранности информации 40 лет.

Портативное устройство копирования микросхем памяти серии 24Схх

Данное устройство предназначено для клонирования микросхем EEPROM серии 24Cxx (последовательный доступ, интерфейс I2C) в автономном режиме (то есть без наличия компьютера). Управление устройством осуществляется с помощью контроллера PIC12F629.

Конструкция, в общем-то, довольно простая: управляющий контроллер, две кроватки для микросхем 24Схх (в одну вставляется микросхема "источник" — из которой копируются данные, в другую вставляется микросхема "приёмник" — в которую копируются данные), стабилизатор напряжения +5В, кнопка, несколько резисторов и конденсаторов.

Поскольку некоторые микросхемы серии 24Cxx предполагают присутствие на шине только в единственном числе (почему — читайте ниже), то для возможности их копирования у нашего интерфейса I2C не совсем стандартная реализация. Линия Clock сделана общей, а линия Data у каждой микросхемы своя (Data_T — линия Data микрухи "источника", Data_R — линия Data микрухи "приёмника"). То есть, здесь у нас получается как бы две шины I2C, но с общей линией Clock. Всё время, пока управляющий контроллер общается с одной микросхемой (по той шине, к которой она подключена), — на линии Data другой микросхемы просто висит "1".

Схема устройства копирования микросхем EEPROM

  1. 7805 — стабилизатор напряжения +5В.
  2. С1, С2 — электролиты по 100 мкФ х 16В
  3. R1=1 кОм
  4. R2=1,5 кОм
  5. R3, R4, R5, R6=4,7 кОм
  6. S1 — кнопка
  7. JP1 — джампер для выбора размера адреса внутри микросхемы (замкнут — один байт, разомкнут — два байта)

Резисторы R2-R6 можно, в общем-то, взять любые от 1 до 6,8 кОм и рекомендую повесить по керамическому конденсатору на 0,1 мкФ прямо между ногами VCC и GND у каждой микрухи и у контроллера.

Для питания устройства можно использовать, например, батарейку "Крона".

Устройство копирования микросхем EEPROM, фото

Программа написана таким образом, что мигание светодиода сообщает о завершении процесса копирования. После завершения копирования программа в исходное состояние не возвращается, то есть чтобы скопировать ещё одну микруху — надо сначала выключить и включить питание (собственно, это в любом случае необходимо, поскольку втыкать и вынимать микросхемы всё равно надо из обесточенного девайса).

Немного поясню про JP1. Первые микросхемы серии 24Схх (24С01, 24С02) содержали до 256 8-битных ячеек памяти и для адресации произвольной ячейки внутри микросхемы было достаточно однобайтного счётчика адреса (один байт кодирует как раз 256 различных адресов). Однако, с увеличением объёма памяти производители микрух попали в засаду. Для микросхем с объёмом больше 256 байт адресовать все ячейки однобайтным счётчиком невозможно.

Выход был найден простой. Для того, чтобы всё-таки иметь возможность обратиться к любой ячейке внутри микросхемы и сохранить совместимость с первыми микросхемами, память внутри микрухи стали делить на банки по 256 байт, а для адресации банков брать взаймы биты 7-ми битного адреса I2C.

Для микросхем серии 24Схх этот адрес имеет вид 1010A2A1A0, где старшие 4 бита (1010) зарезервированы для обозначения микросхем памяти 24Схх, а младшие 3 бита определялись аппаратно и позволяли подключить до 8 микросхем памяти на шину. Так вот из младших трёх битов по одному биту стали брать взаймы для адресации банков. Ценой за это стало уменьшение количества микросхем, которые можно подключить на одну шину. Например, микросхема 24С08 имеет организацию 4х256х8 — 4 банка по 256 байт. У неё только один бит (А2) определяется аппаратно, а биты А1 и А0 используются для выбора банка. Соответственно, таких микрух на шину можно подключить только 2. Но, с появлением микросхем 24С16 производители попали в засаду второй раз.

24C16 состояла из 8 банков по 256 байт, то есть все биты, которые брали взаймы, на ней закончились, на шину её можно было повесить только в единственном экземпляре и дальше увеличивать объём памяти было невозможно.

Решение как всегда было найдено простое. Размер счётчика адреса просто взяли да увеличили до 2-х байт (кстати, 24С16 так и существуют в двух вариантах: с однобайтным счётчиком и с двухбайтным). Теперь стало возможно адресовать 64 кбайта, отпала необходимость брать взаймы биты из адреса I2C, снова стало можно вешать по 8 микрух на шину, но пропала совместимость с младшими моделями.

В этой идиллии понаделали микрух от 2 до 64 кбайт (от 24С16 до 24С512). Когда понадобилось производить микросхемы больше 64 кбайт — применили старый трюк с банками и заимствованием битов. У 24С1024 два банка по 64 кбайта, но на шине таких микрух может быть не больше 4-х штук.

Нетрудно посчитать, что с 2-х байтным счётчиком адреса максимально можно адресовать 8 банков по 64 кбайта, то есть 512 кбайт или 4 мегабита (4096 кбит), дальше придётся опять увеличивать размер счётчика.

Сейчас производители как раз опять упёрлись в верхнюю границу, самые большие микрухи серии 24Схх — это 24С4096, а поскольку скорости обмена по I2C растут, то видимо можно ожидать появления микрух и с трёх- и с четырёхбайтными счётчиками адреса.

В общем-то, существуют алгоритмы автоматического определения размера счётчика адреса, но в данном случае выбор осуществляется джампером.

На форуме есть прошивка, лёгким движением руки превращающая это устройство в чип-ресеттер картриджей для принтеров.

Добавить комментарий

Ваш адрес email не будет опубликован.