• Контроллер прямого доступа к памяти: схема, логика, состояния и режим работы. Контроллер динамической памяти Вопросы и задания

    Функции контроллера динамической памяти:

      Преобразование команд МП в последовательность специальных сигналов, обеспечивающих запись/чтение в модуль динамической памяти.

      Обеспечение режима регенерации модуля динамической памяти.

      Обеспечение расслоения обращений к динамической памяти.

    Контроллер управляет четырьмя модулями DRAM. Уменьшается время цикла обращения к памяти. Общая емкость 4 модулей = 1 Мб * 32 разр.слов = 4 Мб. Используется 22 разряда адреса:

    А0 А1 - используются для внутреннего пользования МП. Определяют используемый байт, во вне не выдаются.

    BE3 . . . BE0 - byte enable

    A3 A2 - обеспечивают расслоение

    A21 A4 - на адресные входы модуля

    Так как память строится на четырех модулях памяти, контроллер должен формировать четыре пары стробирующих сигналов.

    M0 M1 ... M3




    9 разрядов адреса должны формироваться контроллером и выдаваться частями

    Должен быть сформирован сигнал записи WE - write enable

    DEN - data enable

    Модуль памяти подключается непосредственно к магистрали процессора.

    Сигналы состояния МП:

    - сигнал, активизирующий микросхему контроллера

    CLK - по этому сигналу происходят все изменения в микросхеме

    Рассмотрим взаимодействие МП, контролера и блока динамической памяти

      1. Конроллер dram (кдп)

      КЭШ-память

    В настоящее время организуется двухуровневый КЭШ: внутренний (КЭШ1), внешний (КЭШ2). КЭШ построен на статической памяти - SRAM. Существует контроллер КЭШ памяти.

      1. Характеристика внешней кэш – памяти

      Емкость до 512 Кбайт

      Большое быстродействие (обеспечивается использованием SRAM)

      Информация хранится блоками. Блок - набор смежных байтов (4...64 байт). Длина блока обычно существенно превышает длину слова.

    Разновидности КЭШ:

      associative cache - ассоциативный КЭШ

      direct mapped cache - КЭШ с прямым отображением

      two way associative cache - двухканальный ассоциативный КЭШ

      1. Функции контроллера кэш - памяти

      Анализ физического адреса . Если фиксируется КЭШ - попадание по чтению , требуемая информация поступает в процессор из КЭШа. Если произошел КЭШ - промах по чтению , то информация извлекается из ОП. При КЭШ - попадании по записи , текущий результат заносится в КЭШ. При КЭШ - промахе по записи , реакция контроллера КЭШ может различаться в зависимости от типа используемого типа КЭШа:

      сквозная запись - запись осуществляется в ОП.

      обратная запись - запись осуществляется в КЭШ. Модифицированная информация попадает в ОП при выгрузке из КЭШ.

      Snooping - «подслушивание» шины адреса. КЭШ отслеживает изменение содержимого памяти, инициируемое МП. Все обращения к ОП, при двухуровневой организации, идут через КЭШ. Первое обращение идет в КЭШ. Если изменение содержимого ОП инициируется другим задатчиком, КЭШ об этих изменениях не знает. Происходит рассогласование информации, хранимой в ОП и в КЭШ. Чтобы этого избежать используется «подслушивание» шины адреса. Если контроллер обнаружил, что идет обращение по адресу, копия содержимого которого хранится в КЭШ, соответствующую ячейку КЭШа объявляют недостоверной.

      Поддержка каталога КЭШ . Поддержка реализации принципов отображения информации ОП в КЭШ.

    В наши дни в цивилизованном мире вы с трудом найдёте человека, который никогда бы не пользовался компьютером и не имел представление о том, что это такое. Поэтому, вместо того чтобы в очередной раз рассказывать обо всем известных частях этой сложной системы, мы расскажем вам о чём-то, что вы ещё не знаете. Мы обсудим и дадим небольшую характеристику контроллерам памяти, без которых работа компьютера была бы невозможна. Если вы хотите вникнуть в систему работы вашего персонального компьютера или ноутбука, то вы обязательно должны знать это. И так, давайте обсудим сегодня, что же такое контроллеры памяти.

    Задача, которая стоит перед контроллерами памяти компьютера является очень важной для работы компьютера. Контроллер памяти – это чип, который расположен на материнской плате или на центральном процессоре. Главной функцией, которую выполняет этот крохотный чип, является управление потоками данных, как входящих, так и исходящих. Второстепенной функцией контроллера памяти является увеличение потенциала и работоспособности системы, а так же равномерное и правильное размещение информации в памяти, которое доступно благодаря новым разработкам в области новых технологий.

    Размещение контроллера памяти в компьютере зависит от определённых моделей материнских плат и центральных процессоров. В некоторых компьютерах дизайнеры поместили этот чип на северном параллельном присоединении материнской платы, в то время как в других компьютерах они размещены на центральном процессоре типа «die». Те системы, которые рассчитаны на установку контроллера в материнской плате, имеют большое количество новых различных физических гнёзд. Оперативная память, которая используется в компьютерах такого типа, так же имеют новый современный дизайн.

    Главная цель использования контроллера памяти в компьютере заключается в том, чтобы система могла считывать и записывать изменения в оперативной памяти, а также обновлять её при каждой загрузке. Это происходит благодаря тому, что контроллер памяти посылает электрические заряды, которые в свою очередь, являются сигналами для выполнения тех или иных действий. Не углубляясь в техническую терминологию, мы можем утвердить тот факт, что контроллеры памяти являются одной из самых важных деталей в компьютере, позволяющих использовать оперативную память, и без которой его работа была бы невозможной.

    Контроллеры памяти бывают разных типов. Они различаются на:
    - контроллеры памяти с двойной скоростью передачи данных (DDR);
    - полностью буферизованные контроллеры памяти (FB);
    - двуканальные контроллеры (DC).

    Функции, которые могут выполнять контроллеры памяти разных типов, отличаются друг от друга. Например, контроллеры памяти с двойной скоростью передачи данных используются, чтобы передавать данные, в зависимости от увеличения или уменьшения темпа часов памяти. В то время как в двуканальной памяти используется два контроллера памяти параллельно друг от друга. Это позволяет компьютеру увеличить быстродействие системы, создавая больше каналов, но, несмотря на трудности, которые возникают в результате использования кучи проводов, данная система работает довольно эффективно. Однако возникают трудности при создании новых каналов, поэтому данный вид контроллера памяти не безупречен.

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

    Как вы уже убедились, контроллеры памяти очень нужны для стабильной работы компьютера, и разные типы используются для разных целей. Цены на линейки памяти варьируются от очень высоких до очень низких, что зависит от типа и функций, которые выполняет тот или иной контроллер памяти.

    Обычно промышленный контроллер состоит из: центрального процессора, сетевых интерфейсов, модулей памяти и различных устройств ввода-вывода.

    В состав процессорного модуля ПЛК входят следующие комплектующие: микропроцессор или ЦПУ (центральное процессорное устройство), часы реального времени, запоминающие устройства и watchdog.

    К основным характеристикам микропроцессора относятся: тактовая частота, разрядность, поддержка портов для различных устройств ввода-вывода, архитектура, параметры работоспособности при определенных температурных диапазонах, выполнение операций с плавающей точкой, уровень потребляемой мощности.

    Показатели производительности микропроцессоров с одинаковой архитектурой пропорциональны тактовой частоте. В большинстве контроллеров применяются микропроцессоры реализованные на RISC (Reduced Instruction Set Computing) архитектуре, которые имеют сокращенное количество команд. В этом случае микропроцессор использует определенное число команд, обладающих одинаковой длиной, и множество регистров. Благодаря сокращенному набору команд можно создавать компиляторы с большими показателями эффективности, а так же конвейер процессора, который за один такт может выдать результат выполнения действий одной из команд.

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

    Емкость памяти характеризуется количеством переменных, которые можно обработать за время функционирования ПЛК. Время доступа к памяти микропроцессора - один из наиболее существенных показателей, способных ограничить быстродействие. Из-за этого происходит деление памяти на уровни иерархии, с учетом частоты и скорости использования, имеющихся в ней данных Иерархия памяти – это еще один существенный показатель архитектуры процессора, позволяющий снизить уровень возможного отрицательного воздействия медленной памяти на скорость работы микропроцессора.

    Основные типы памяти промышленных контроллеров (ПЛК):

    • ПЗУ – постоянное запоминающее устройство;
    • ОЗУ – оперативное запоминающее устройство;
    • Набор регистров.

    Набор регистров - самые быстродействующие элементы памяти, так как их использует АЛУ (арифметико-логическое устройство) для выполнения простейших команд процессора. ПЗУ применяется как место хранения информации, которая редко подвергается изменению – операционная система, загрузчик, драйверы устройств, либо исполняемый модуль какой-либо программы. ОЗУ хранит в себе непосредственно данные подвергающиеся многократному изменению в период работы контроллера. К примеру, информация о проведении диагностики, отображаемые на дисплее переменные, значения тегов, промежуточные вычисления, выводимые на графики данные. В роли ПЗУ (ROM - Read Only Memory), как правило, выступает перепрограммируемая электрически стираемая память (EEPROM - Electrically Erasable Programmable ROM). Кстати, флеш-память по сути - разновидность EEPROM. Принцип действия её заключается в хранении определенного заряда в конденсаторе, который образован подложкой МОП-транзистора и плавающим затвором. Главная особенность флеш памяти – её абсолютная энергонезависимость, т.е. возможность сохранения данных при отсутствии питания. Обновление данных во флеш-памяти происходит не отдельно взятыми ячейками, а за счет применения больших блоков. Все ПЗУ обладают большим недостатком - низким уровенем быстродействия.

    Количество циклов ввода информации во флеш-память ограничено всего несколькими десятками тысяч раз. Современными микропроцессорами в качестве ОЗУ применяется статическая память (SRAM - Static Random Access Memory), динамическая память (DRAM- Dynamic Random Access Memory), и синхронная динамическая память (SDRAM - Synchronous DRAM). Выполнение SRAM происходит на триггерах, которые способны хранить информацию неограниченно долгое время при условии наличия питания. Динамическая память промышленного контроллера сохраняет принадлежащие ей данные на конденсаторах, из-за чего требуется периодическая перезарядка конденсаторов. Основным недостатком триггерной памяти является высокий уровень стоимости и отношения цены к емкости. Это связано с тем, что на одном кристалле помещается относительно небольшое число триггеров. К достоинствам можно отнести высокий уровень быстродействия, исчисляемый гигагерцами, в то время как конденсаторная память не может преодолеть планку в несколько сотен герц. Все виды оперативной памяти отличаются тем, что при отсутствии питания все имеющаяся в них информация не сохраняется. Именно поэтому в некоторых типах ПЛК используется батарейное питание, позволяющее сохранить работоспособность системы при условии кратковременного прерывания питания системы.

    В модульных и моноблочных промышленных контроллерах используется параллельная шина, позволяющая обмениваться информацией с модулями ввода-вывода, благодаря чему быстродействие опроса значительно выше в сравнении с последовательной шиной. Виды параллельных шин: VME, PCI, ISA, CXM, ComactPCI, PC/104. Последовательная же шина, например RS-485 необходима для подключения удаленных модулей ввода-вывода.

    Процессорное ядро микроконтроллеров:
    – арифметико-логическое устройство
    – организация памяти

    Доброго дня уважаемые радиолюбители!
    Приветствую вас на сайте “ “

    Сегодня (точнее – в течении нескольких статей) мы с вами более подробно рассмотрим основу любого микроконтроллера процессорное ядро .

    Основные элементы:

    1. Арифметико-логическое устройство

    АЛУ – сердце (а может быть и ум, с честью и совестью) микроконтроллера.
    Здесь мы не будем входить в роль “маньяка-расчленителя” и ковыряться во внутренностях этого устройства. Усвоим только, что благодаря АЛУ происходит вся работа микроконтроллера. Если у вас когда-нибудь появится желание более глубже узнать как работает “сердце” микроконтроллера (а будет неплохо, если оно появится), то в книгах замечательных авторов Белова, Рюмика, Евстифеева, Ревича, Баранова и многих других, вы всегда найдете подробный ответ.

    2. Память микроконтроллера (организация памяти)

    Прежде чем рассматривать память микроконтроллера, немного поговорим о памяти вообще.
    Человеческая память – с ней все понятно, – она бывает “твердой” (когда находишься в твердой памяти, а иногда еще и в здравом уме) и, как не прискорбно, – “дырявой”. А вся информация хранится в так называемых “нейронах” – маленьких ячейках памяти.
    У микроконтроллеров почти все также. Только, если у человека самая маленькая ячейка для хранения информации называется “нейрон”, то для микроконтроллера самая маленькая ячейка памяти для хранения информации называется “бит “.
    В одном бите может храниться или одна логическая единица, или один логический ноль.
    Бит минимальная единица измерения объема памяти в микропроцессорной технике .
    Следующая основная, или самая распространенная, единица измерения памяти – байт .
    Байт это восемь бит информации. В одном байте может храниться только восемь нулей и единиц.
    Максимальное число которое можно записать в байт – 255. Если в программе вы будете оперировать большими числами то следует знать (чтобы знать сколько байт потребуется для хранения числа), что максимальное число, которое можно записать в:
    – один байт = 255
    – два байта = 65 535
    – три байта = 16 777 215
    – четыре байта – число величиной более 4 миллиардов (если вы не входите хотя бы в сотню журнала “Форбс”, то четыре байта памяти для хранения чисел вам не понадобятся).
    Запись в память и чтение из памяти происходит байтами (нельзя записать или считать один бит информации).
    Следующая единица измерения – килобайт .
    В килобайте помещается 1024 байт информации (именно 1024, а не 1000 байт).
    Есть еще и большие величины измерения объема памяти (мегабайт, гигабайт), но в микроконтроллерах они пока не применяются.
    Я надеюсь, что с единицами измерения электронной памяти нам все понятно:

    Организация памяти в микроконтроллере

    Микросхемы AVR имеют три вида памяти:
    память программ, она же FLASH-память
    память данных, она же ОЗУ (оперативно-запоминающее устройство) , она же SRAM
    энергонезависимая память, она же ЭСППЗУ, она же EEPROM
    В микроконтроллере выделяется три адресных пространства в которых располагаются вышеперечисленные разновидности памяти. Память данных при этом (в смысле выделенного адресного пространства) оказалась немного обделенной – ей приходится делить свое адресное пространство с ячейками памяти в которых хранятся регистры общего назначения и регистры ввода/вывода (о них вы подробно узнаете в следующей статье). Эти регистры физически не относятся к памяти данных, но находятся в том же адресном пространстве. Если начальные адреса памяти программ и энергонезависимой памяти начинаются с нулевого адреса, то начальный адрес памяти данных не начинается с нулевого адреса – с нулевого адреса занимают места регистры общего назначения и регистры ввода/вывода, и только за ними следуют адреса ячеек памяти программ.
    В некоторых видах МК ATiny память данных отсутствует.

    Память программ (FLASH память)

    Память программ предназначена для хранения в ней наших программ, а также любых нужных нам данных, которые не меняются в ходе выполнения программы (константы). При выключении питания микроконтроллера, все данные в памяти программ сохраняются.
    Память программ , естественно, имеют все микроконтроллеры. Размер памяти программ, в зависимости от типа МК, варьируется от 1 килобайта до 256 килобайт.
    Доступ к памяти программ имеет только программист при программировании МК, у самого МК доступ к памяти программ тоже имеется, но только для чтения данных из памяти, записать туда он ничего не может (мало ли что, вдруг захочет испортить нашу программу). Правда, у МК семейства Mega есть возможность (с разрешения программиста) вносить изменения в памяти программ, но это отдельная история.
    Для памяти программ есть еще два вида измерения объема памяти – “слово ” и “страница “.
    Дело в том, что память программ состоит из ячеек состоящих из двух байт . Такая ячейка называется “словом” . А сделано это так потому, что почти все команды МК состоят из двух байт, и, соответственно, для их записи нужно два байта в памяти программ. Каждая команда МК – это одно “слово” . Есть несколько команд, для записи которых требуется 4 байта в памяти – два слова, но такие команды встречаются в МК у которых память программ больше 8 килобайт.
    Таким образом, в одну ячейку памяти программ можно записать :
    – любую команду, состоящую из двух байт
    – половину команды, состоящей из 4 байт
    – две константы, каждая из которых умещается в один байт, или одну шестнадцатиразрядную константу. При этом, если вы записываете в память три однобайтовых константы, они все равно займут в памяти четыре байта (два слова).
    Кроме того, запись в память программ осуществляется не только “словами”, но еще и “страницами” . Размер “страницы” составляет от 64 до 256 байт (чем больше объем памяти программ, тем больше объем “страницы”). Что это значит. Если вы создали маленькую программку, объем которой составляет 11 слов (22 байта), в памяти программ она все равно займет место в одну страницу, т.е. как минимум 64 байта. “Лишние” 42 байта при этом будут заполнены или нулями, или единицами. Вот такие вот, пироги.
    Но и это еще не все.
    Память программ может иметь три состояния (если можно так выразиться):
    1. Вся память находится в распоряжение программиста
    В этом случае мы можем забить всю память полностью своей программой и данными. А программа будет стартовать с нулевого адреса памяти.
    2. Часть памяти забирает МК
    В случае, если при работе МК используются (а я надеюсь – вы помните, что это такое), часть памяти МК забирает для нужд обработки прерываний и хранит в ней “векторы прерываний “.
    Что это такое.
    Когда мы разрешаем МК обрабатывать прерывания, он, начиная с нулевого адреса памяти, забирает часть ячеек для хранения в них адресов, по которым надо перейти МК для выполнения подпрограммы прерывания. Для каждого прерывания МК выделяет два байта памяти (одно слово) в которых хранятся адреса подпрограмм обработки прерываний. Вот эти адреса, которые указывают где находится в памяти подпрограмма обработки того, или иного прерывания, называются “векторами прерываний “. А вся область памяти, в которой хранятся “векторы прерываний”, называется таблицей векторов прерываний . Количество занятых ячеек памяти под прерывания зависит напрямую от количества возможных прерываний данного микроконтроллера (от нескольких штук, до нескольких десятков). Все прерывания располагаются в начале памяти программ, с нулевого адреса, и имеют четкую последовательность. По нулевому адресу всегда располагается вектор прерывания по “сбросу” (Reset). Когда мы включаем устройство, или производим сброс кнопкой, срабатывает прерывание по сбросу. МК считывает с нулевого адреса (с ячейки) адрес, который указывает где в памяти находится начало нашей программы, и перейдя по этому адресу начинает выполнять программу. Сама программа в этом случае будет располагаться в памяти программ сразу за таблицей прерываний.
    3. МК забирает еще одну часть памяти программ (точнее не забирает, а выделяет область в конце памяти, в которой программист размещает специальную программу – “загрузчик”).
    Такое возможно в МК семейства “MEGA”, у которых есть возможность разрешить МК вносить изменения в памяти программ. Что это значит.
    Некоторые МК имеют возможность самопрограммироваться . В практике любителей такая возможность МК используется крайне редко. Возможность перепрограммироваться (самопрограммироваться) нужна, в основном, в случаях промышленного производства какого-то устройства на микроконтроллере, для которого потом может выпускаться обновление программного обеспечения. Мы эту возможность рассматривать не будем, по крайней мере пока. Нам достаточно только знать, что в МК, которые поддерживают самопрограммирование, память программ разделяется на две части :
    - верхняя – секция прикладной программы , где располагается наша программа и векторы прерываний
    - нижняя – секция загрузчика (Boot Loader Section – по английски), где программист располагает свою программу-загрузчик. Размер секции загрузчика зависит от общего размера памяти программ МК, и может составлять от 128 байт до 4096 байт. Если возможность самопрограммирования МК мы не используем, то эта секция отдается для нашей программы и данных.
    Ну а FLASH-памятью память программ называют потому, что она делается по так называемой Flash-технологии (как и всем нам привычные компьютерные “флешки”)
    Память программ допускает 10 тысяч циклов перепрограммирования.

    Память данных (Статическое ОЗУ, SRAM)

    Оперативно-запоминающее устройство , оно же память данных типа SRAM , предназначена для хранения в ней различных данных, получаемых в результате работы программы.
    При выключении питания микроконтроллера, все данные хранящиеся в ней теряются.
    Память данных есть почти во всех микроконтроллерах (отсутствует у простейших МК семейства Tiny).
    Во всех МК семейства Mega (и части МК семейства Tiny) объем встроенной памяти данных колеблется от 128 байт до 8 килобайт, и почти вся она отдана в наше полное распоряжение. Только немножко забирает себе МК для организации стека (что это такое узнаем позднее). В некоторых МК предусмотрено подключение внешней памяти (она может быть любого типа – FLASH, SRAM, EEPROM) объемом до 64 килобайт. В случае подключения внешней памяти в таких МК, она становится как-бы продолжением памяти данных.
    Запись в память данных и чтение из нее происходит побайтно, и в отличии от памяти программ в ней нет деления на страницы и слова.

    Энергонезависимая память (EEPROM)

    Энергонезависимая память также относится к памяти данных, но в отличие от последней имеет несколько особенностей. Предназначена она для хранения данных и констант, которые должны сохраняться при отсутствии питания.
    EEPROM имеют все микроконтроллеры.
    При выключении питания микроконтроллера все данные, хранящиеся в энергонезависимой памяти сохраняются (поэтому она и называется энергонезависимой).
    Объем энергонезависимой памяти , в зависимости от типа МК, колеблется от 64 байт до 4 килобайт.
    Запись и чтение информации в память производится побайтно. Однако в старших моделях семейства MEGA, энергонезависимая память, так же как и память программ, имеет страничную запись. Объем страницы небольшой, составляет всего 4 байта. На практике эта особенность не имеет значения – и запись, и чтение осуществляется все равно побайтно.
    Число циклов записи и стирания памяти достигает 100 000.
    Главная особенность EEPROM заключается в том, что при записи в нее данных она становится очень “медленной” – запись одного байта может продолжаться от 2 до 4 миллисекунд (это очень низкая скорость), и может случиться, к примеру, что во время записи сработает какое-либо прерывание и в этом случае процесс записи данных будет загублен.
    Кроме того, не рекомендуется записывать данные в энергонезависимую память с нулевого адреса (не помню источника этих сведений, но точно помню, что где-то читал) – возможно повреждение данных в ходе работы МК. Иногда программисты отступают на несколько байт от начала памяти, и только в следующих ячейках начинают запись данных.

    Иногда при разработке устройства возникает потребность сохранять какие-либо данные в энергонезависимую память. В таких случаях обычно используют внутреннюю EEPROM микроконтроллера. Если её недостаточно, то как правило применяются внешние микросхемы EEPROM из серии 24lxx. Микросхемы этой серии очень популярны. Чаще всего их можно встретить в старых мобильных телефонах, некоторых материнских платах, картриджах от принтеров да еще много где. Цена данных микросхем тоже очень привлекательная. Например 24LC16 у нас стоит 11 рублей.
    Данная микросхема выпускается в различных корпусах, самые популярные из которых это DIP и SOIC. Микросхема имеет следующую распиновку:

    Как видите выводов совсем немного. Итак попробуем разобраться для что к чему.
    A0, A1, A2 — в данной микросхеме не используются. Их можно подсоединить к земле или к плюсу питания. В некоторых других микросхемах серии 24lxx, этими выводами можно задавать адрес микросхемы, для того чтобы можно было подсоединить на одну шину i2c аж сразу 8 микрух памяти.
    Vss — земля.
    SDA — линия данных
    SCL — линия тактовых импульсов
    WP — Защита от записи. Когда на данном выводе логический 0, то запись в память разрешена. Если подать логическую единицу, то возможно только чтение из памяти.
    Vcc — питание микросхемы. Согласно даташиту питается она напряжением от 2.5 вольта до 5.5 вольта.

    Подключение к контроллеру.
    Подключить память к МК очень просто. Из обвязки потребуются только пара резисторов сопротивлением около 4.7 кОм.

    Программное обеспечение

    Для работы с памятью была разработана библиотека реализующая следующие функции:

    i2c_init — настраивает скорость тактовых импульсов идущих по линии SCL.

    Микросхема 24LC16 поддерживает частоту до 400 кГц. Рассчитать частоту можно так:

    CPU Clock frequency — частота на которой работает микроконтроллер

    TWBR — число записанное в одноименный регистр.

    TWPS — предделитель. Значения предделителя задаются битами TWPS1 и TWPS0 в регистре TWSR

    Для контроллера Atmega 32 справедлива такая таблица:

    i2c_start — отсылает стартовую посылку

    i2c_stop — отсылает стоповую посылку

    i2c_send — отсылает байт

    i2c_recive — принимает байт

    i2c_recive_last — принимает последний байт. Отличие от предыдущей функции состоит в том, что когда байт принят, микроконтроллер не отсылает бит подтверждения. Если при приёме последнего байта использовать i2c_recive то линия SDA останется прижатой к земле.

    Запись данных в микросхему памяти

    Записывать данные можно как в произвольном порядке так и постранично. Поскольку на шине i2c могут быть сразу несколько устройств, то для того чтобы обратится к какому либо устройству нужно знать его семибитный адрес. Адрес микросхемы 24LC16 в двоичном виде выглядит так:

    Биты A,B,C служат для выбора блока памяти. Блоков памяти в микросхеме 8 штук по 256 байт каждый. Соответственно биты ABC принимают значения от 000 до 111.

    Для того чтоб записать в микросхему байт нужно выполнить следующую последовательность действий:

    1. Инициализировать интерфейс i2c
    2. Отослать стартовую посылку
    3. Отослать адрес микросхемы+адрес блока памяти
    4. Отослать адрес ячейки памяти в которую будет производится запись
    5. Отослать байт данных
    6. Отослать стоповую посылку

    Пример: Нужно записать байт 0xFA по адресу 0x101 .

    rcall i2c_init
    rcall i2c_start
    ldi temp,0b 1010 001 0 //Адрес микросхемы где:
    // 1010 - адрес микросхемы
    // 001 - адрес блока памяти (Ячейка 0x101 принадлежит блоку 1)
    // 0
    rcall i2c_send
    ldi temp,1 //Адрес ячейки памяти. (блок 1, ячейка 1)
    rcall i2c_send
    ldi temp,0xFA //Загружаем в регистр байт который нужно записать
    rcall i2c_send //Записываем байт
    rcall i2c_stop

    Записывать данные в память можно не только побайтно но и постранично. Размер страницы — 16 байт. Постараничная запись подразумевает следующее: Отправляем адрес нулевого байта нужной страницы и после этого 16 раз отправляем нужные данные. Счётчик адреса будет увеличивать на единицу автоматически. Если отправить данные в 17-й раз, то будет перезаписан нулевой байт, если отправить байт 18-й раз, то он затрет байт номер 1 итд.

    Пример : Требуется записать первую страницу блока 0.

    rcall i2c_init //Инициализируем интерфейс i2c
    rcall i2c_start // Отправляем стартовую посылку
    ldi temp,0b 1010 000 0 //Адрес микросхемы где:
    // 1010 - адрес микросхемы
    // 000 - адрес блока памяти (нас интересует нулевой блок)
    // 0 - бит чтения/записи. 0 - запись, 1 - чтение
    rcall i2c_send
    ldi temp,16 //Адрес первой страницы
    rcall i2c_send
    ldi temp,0x01 //Загружаем в регистр байт номер 0
    rcall i2c_send //Записываем байт
    ldi temp,0x02 //Загружаем в регистр байт номер 1
    rcall i2c_send //Записываем байт
    /// тут пишем остальные байты.....
    ldi temp,0x0E //Загружаем в регистр байт номер 14
    rcall i2c_send //Записываем байт
    ldi temp,0x0F //Загружаем в регистр байт номер 15
    rcall i2c_send //Записываем байт
    rcall i2c_stop //Отправляем стоповую посылку

    Чтение данных из микросхемы
    С записью вроде разобрались, теперь приступим к чтению. Чтобы прочитать байт нужно сделать следующее:

    1. Инициализировать интерфейс i2c (если он не инициализировался ранее)
    2. Отправить стартовую посылку
    3. Отправить адрес микросхемы и адрес блока памяти откуда будем читать
    4. Отправить адрес ячейки памяти
    5. Отправить стартовую посылку повторно
    6. Отправить адрес микросхемы и адрес блока памяти с битом «чтение»
    7. Получить байт
    8. Отправить стоповую посылку

    rcall i2c_init //Инициализируем интерфейс i2c
    rcall i2c_start // Отправляем стартовую посылку
    ldi temp,0b1010 011 0 //Адрес микросхемы + адрес 3-го блока памяти.
    //Бит чтение/запись по прежнему 0 !
    rcall i2c_send
    ldi temp,0x41 //Адрес ячейки памяти
    rcall i2c_send
    rcall i2c_start //Повторная отправка стартовой посылки
    ldi temp,0b1010 011 1 //Адрес микросхемы+адрес блока памяти+бит чтения/записи стал 1
    rcall i2c_send //теперь можно читать данные
    rcall i2c_recive_last //Читаем байт. Первый и последний.
    rcall i2c_stop //Отправляем стоповую посылку

    Чтение может производится последовательно байт за байтом, т.е. просто вызывать i2c_recive столько сколько нужно. Команду увеличения адреса на единицу посылать не нужно. Переключать адреса блоков при последовательном чтении так же не нужно. Т.е. можно взять и разом прочитать всю микросхему без всяких проблем.

    Библиотека для работы с i2c разрабатывалась и была испытана на микроконтроллере Atmega32. Я думаю что она будет работать на многих других контроллерах без каких либо изменений. Естественно в контроллере должна быть аппаратная поддержка i2c или как его еще называют TWI. Конечно реализовать i2c можно и программно, но я не стал заморачиваться да и не было нужды. Демонстрационный пример представляет собой программу которая записывает по первым 16 адресам байты от 0 до 15, а после записи выводит их в порт A. Наблюдать как это работает можно не только в живую но и в Proteus’е.

    Ну и напоследок прикладываю осциллограмму:

    Вот так выглядит шина i2c глазами моего :-)
    Все вопросы и предложения жду в комментариях.