MicroConverter в Technical Замечание uC001

MicroConverter в I2C в Compatible Interface

Ver 2.0 October 2000 www.analog.com/microconverter в I2C is a Registered Trademark of Philips Semiconductors Inc в MicroConverter is a Registered Trademark of Analog Devices Inc

1.0 ВВЕДЕНИЕ.

Это Техническое описание излагает применение интерфейса I2C, аппаратное (в режиме ведомого) и программное (в режиме ведущего), используя Микроконвертор. Это техническое описание также содержит пример кода, каким образом ведущий и ведомый могут общаться друг с другом, используя I2C совместимый интерфейс.

Основные особенности шины I2C следующие:

· Требуется только две линии; линия данных (SDATA) и линия синхроимпульсов (SCLOCK). Обе эти линии двунаправленные, что означает, как ведущий, так и ведомый выступают и в роли передатчика и в роли приемника.

· Ведущий I2 C может связываться со многими ведомыми устройствами. Поскольку каждое ведомое устройство имеет уникальный 7-битовый адрес, следовательно, одно отношение master/slave может существовать все время даже в многоведомом окружении.

· Программное обеспечение ведущего может выводить данные со скоростью примерно 140 kbit/s используя 12MHz частоту синхронизации. Аппаратное обеспечение ведомого, может принимать синхросигнал и данные с частотой выше 3.4Mbit/s.

· Микросхема фильтрует выбросы длительностью< 50ns на линиях SDATA и SCLOCK , чтобы сохранить целостность данных.

Типовая схема включения интерфейса I2C показана на рисунке 1 ниже.

Рисунок 1. Один ведущий и несколько ведомых I2C.

1.1 ОБЗОР ИНТЕРФЕЙСА I2C.

Двух проводная система последовательного интерфейса I2C, разработанная фирмой Philips, предоставляет возможность иметь много ведущих и много ведомых связанных между собой двумя линиями (SCLOCK и SDATA). Интерфейс I2C должен иметь как минимум одного ведущего и одного ведомого.

Линия SCLOCK управляет передачей данных между ведущим и ведомым. Сигнал SCLOCK всегда передается от ведущего к ведомому. (Ведомый, тем не менее, имеет возможность удерживать линию в низком состоянии, если он не готов начать прием следующей передачи. Это называется УДЕРЖАНИЕ СИНХРОИМПУЛЬСА ‘Clock Stretching’ (смотри раздел 1.7)). Для передачи каждого бита должен использоваться один синхроимпульс.

Линия SDATA используется для передачи и приема данных. Сигнал SDATA должен быть неизменным во время HIGH периода SCLOCK. Переключение линии SDATA при высоком уровне линии SCLOCK означает условие START или STOP (fig 2a & 2b).

Замечание: Для ADuC812 требуются подтягивающие резисторы для обеих линий SCLOCK и SDATA. А для ADuC812S/ADuC816/ADuC824 подтягивание уровня реализовано на аппаратном уровне.

1.2 ПОСЛЕДОВАТЕЛЬНОСТЬ ПЕРЕДАЧИ ДАННЫХ I2C.

СТАРТ.

Последовательность передачи данных для интерфейса I2C начинается с состояния START (НАЧАЛО). Состояние START, осуществляется переводом линии SDATA из ВЫСОКО в НИЗКОЕ, в момент времени, когда линия SCLOCK находится в состоянии ВЫСОКО (рисунок 2a). За формирование состояния НАЧАЛА всегда отвечает ведущий.

Замечание: состояния НАЧАЛО (и ОСТАНОВ) - единственное время, когда линия SDATA должна измениться в течение высокого периода линии SCLOCK. Во время передачи данных (включая обращение ведомых) данные на линии SDATA должны находиться в одном и том же состоянии во время, когда линия SCLOCK находится в состоянии ВЫСОКО.

 

 

Рисунок 2a: Условие СТАРТ. Рисунок 2b: Условие СТОП.

АДРЕС ВЕДОМОГО.

После того, как ведущий выдает старт, он посылает байт (MSB первый) по линии SDATA (в сопровождении восьми импульсов SCLOCK ). Первые семь битов этого байта - 7-разрядный Адрес ведомого. Ведомый отвечает ведущему, если этот 7-разрядный адрес соответствует его уникальному адресу устройства (раздел 1.3). Восьмой разряд (МЛАДШИЙ БИТ) - R/W бит состояния. R/W бит определяет направление передачи сообщения. Если этот бит 0, тогда ведущий передает (запись) данные, выбранному ведомому.

Если ведомый принимает свой адрес, тогда он возвращает ACK (более низкий), перемещает линию SCLOCK, в ноль и устанавливает прерывание бит I2CI, (генерирует прерывание, если оно правильно сконфигурировано). Линия SCLOCK удерживается внизу для того, чтобы ведущий знал, что ведомый пока не готов принять следующий байт. Сброс бита I2CI разъединит линию SCLOCK.

Подтверждение / Неподтверждение

ACKNOWLEDGE (ACK) / NO ACKNOWLEDGE (NACK)

Если адрес ведомого, соответствует адресу, который посылает ведущий, тогда ведомый автоматически пошлет Подтверждение (ACK), иначе он пошлет Неподтверждение (NACK). ACK показан как НИЗКИЙ УРОВЕНЬ на линии(строке) SDATA на 9-ом тактовом импульсе. NACK показан как ВЫСОКИЙ УРОВЕНЬ на линии SDATA на 9-ом тактовом импульсе (рисунок 3).

Рисунок 3. Подтверждение (ACK) и неподтверждение (NACK) по линии I2C.

Во время передачи данных ACK или NACK всегда генерируется приемником. Однако тактовый синхроимпульс, требующийся для формирования ACK всегда генерируется ведущим. Передатчик должен разъединить линию SDATA (высоко) в течение тактового импульса ACK. Для формирования ACK приемник должен удерживать линию SDATA, на нижнем уровне для действительного ACK.

Если Микроконвертор сконфигурирован в режиме ведомого, тогда и ACK, и NACK автоматически формируются аппаратно, в конце каждого принятого байта. Если Микроконвертор сконфигурирован в режиме ведущего тогда, выполнение ACK ложится на программное обеспечение пользователя, в конце каждого принятого байта.

Если ведущий принимает NACK от ведомого приемника (если адрес не соответствует или не может передать данные) тогда ведущий должен выдать STOP (более низкий) для прекращения передачи.

Ведущий – приемник должен сигнализировать о завершении приема ведомому – передатчику сигналом (NACK) после того как последний байт был послан ведомым. Когда ведомый получает NACK, он обнуляет линию SDATA, предлагая ведущему выдать STOP.

ПЕРЕДАЧА ДАННЫХ.

В I2C ISR (или в голосованном выполнении or in a polled implementation) ведомый решает, можно ли передать или принять в соответствии с состоянием R/W бита, который посылает ведущий. Ведомый тогда или передает или принимает информационный бит на каждый синхроимпульс, который посылает ведущий. Ведущий обеспечивает выработку 9 синхроимпульсов (8 для данных и 1 для ACK) для того, чтобы ведомый мог передать / получить данные на/из ведущего. I2CI бит будет устанавливаться каждый раз, когда байт достоверных данных передан / получен ведомым.

Вновь заметим, что в режиме ведомый - передающей ведущий – принимающий, ведущий должен сообщить о конце последовательности данных ведомому, посылая NACK после последнего байта, переданного ведомым. Как только ведомый принимает NACK, он разрывает линию SDATA, чтобы позволить ведущему генерировать состояние ОСТАНОВА.

ОСТАНОВ.

Последовательность передачи данных завершается передачей состояния ОСТАНОВ. Состояние ОСТАНОВ определяется по переходу с НИЗКОГО в ВЫСОКОЕ на линии SDATA, в то время как SCLOCK в ВЫСОКОМ (рисунок 2b).

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

Типичная последовательность передачи данных показана на фигуре 4.

Рисунок 4. Типовая последовательность передачи по I2C.

1.3 7-БИТНЫЙ АДРЕС ВЕДОМОГО.

Ведущий посылает 7-бит адреса ведомому в первых семи передаваемых битах 7 MSBs после выдачи последовательности START. (Восьмой бит определяет направление передачи данных R/W). Ведомый сравнивает только 7 старших битов со своим адресом. Старший бит дополняется нулем (позиция MSB). Полученный результат сравнивается с содержимым регистра I2CADD.

Во время всего обмена по I2C, ведомый автоматически распознает адресацию. Для выбора ведомого устройства с адресом 44h (I2CADD для ведомого устройства = 44h) ведущий должен выдать байт 88h (ведущий - передатчик, ведомый - приемник) или 89h (ведущий – приемник, передатчик- ведомый) после выдачи START.

Поскольку 7-битный адрес расположен в семи старших битах мастера. LSB в высоком или низком состоянии в зависимости от того, будет ли ведущий передавать данные ведомому, или принимать данные от него. Ведомый преобразует данные 7 MSBs переданных мастером в 7 LSBs адрес для ведомого с нулем в старшей позиции. Это показано на Рисунок 5 ниже.

Рисунок 5: 7-bit Преобразование адреса ведомым.

1.4 РЕАЛИЗАЦИЯ I2C В МИКРОКОНВЕРТОРЕ.

Этот раздел описывает I 2 C реализацию Микроконвертор. Микроконвертор позволяет осуществлять оба режима: аппаратно для ведомого и программно для ведущего. Для управления I 2 C интерфейсом используются три SFRs:

I2CADD: содержит 7-bit адрес устройства (по умолчанию = 55H).

Замечание: Этот регистр SFR используется только в режиме ведомого. Смотри секцию 1.3 как опознается адрес ведомого.

I2CDAT: В режиме ведомый приемник принимает данные по линии SDATA и пересылает в этот SFR.

Успешно принятые данные читаются из него командой в аккумулятор.

MOV A, I2CDAT

В режиме ведомого передатчика запись в данный регистр делает данные доступными для передачи по линии SDATA под управлением ведущего.

MOV I2CDAT, #60h

Запись кода 60h выдает по линии SDATA, когда приходят синхроимпульсы от ведущего.

Замечание: Для ADuC812S/ADuC816/ADuC824 запись или чтение регистра I2CDAT SFR автоматически сбрасывает флаг прерывания I2CI. Сброс этого флага в другое время может привести к потере данных. Для ADuC812 флаг прерывания I2CI должен быть сброшен программно.

I2CCON: Хранит конфигурационные и управляющие биты для режимов ведущего и ведомого как описано в таблице 1.

Мнемоника

Описание

MDO

Software Master Data Out Bit (MASTER ONLY)

Этот бит используется для осуществления программной передачи данных в режиме ведущего по интерфейсу I2C. Информация, записанная в этот бит, выдается по линии SDATA, если установлен бит (MDE).

MDE

Software Master Data Out Enable Bit (MASTER ONLY)

Этот бит используется для осуществления программной передачи данных в режиме ведущего по интерфейсу I2C. Установка этого бита разрешает работу линии SDATA в режиме выдачи output (TX). Сброс этого бита переводит линию SDATA в режим приема input (RX).

MCO

Software Master Clock Out Bit (MASTER ONLY)

Этот бит используется для осуществления программной передачи данных в режиме ведущего по интерфейсу I2C. Данные, записанные в этот бит, выдаются на линию SCLOCK.

MDI

Software Master Data In Bit (MASTER ONLY)

Этот бит используется для осуществления программной передачи данных в режиме ведущего по интерфейсу I2C. Данные с линии SDATA запоминаются здесь по установке SCLOCK, если бит разрешения выдачи (MDE) сброшен.

I2CM

I2C Mode Bit

Установка этого бита переводит интерфейс в режим программного управления в режим ведущего, сброс этого бита переводит интерфейс в аппаратный режим ведомого.

I2CRS

I2C Serial Port Reset (SLAVE ONLY)

Установка этого бита сбрасывает интерфейс I2C.

I2CTX

I2C Transmission Direction Status (SLAVE ONLY)

Этот бит индицирует направление передачи. Бит устанавливается, если ведущий читает данные от ведомого. Бит сбрасывается, если ведущий записывает данные ведомому. Этот бит автоматически загружается из бита R/W после адреса ведомого и состояния старт.

I2CI

I2C Interrupt Flag (SLAVE ONLY)

Флаг прерывания последовательного порта I2C. Этот бит устанавливается после того, как байт был передан или принят. Его необходимо сбрасывать программно. Как это сделать смотри раздел 1.8.

Таблица 1: Определение бит регистра I2CCON.

1.5 ПРОГРАММНАЯ РЕАЛИЗАЦИЯ РЕЖИМА ВЕДУЩИЙ.

В Микроконвертор интерфейс I2C в режиме ведущего осуществляется программным путем. Пользователь должен программировать побитно линии SDATA и SCLOCK. Режим ведущего задается установкой бита I2CM в регистре I2CCON.

Передача данных по линии SDATA, бит MDE должен быть установлен. В бит MDO регистра I2CCON записывается выдаваемый бит. Выходной драйвер линии SDATA устанавливает уровень линии SDATA в высокое или низкое состояние в зависимости от состояния бита MDO установлен он или сброшен.

Бит MCO регистра I2CCON является выходным битом синхроимпульса. Выходной драйвер сигнала SCLOCK всегда разрешен в режиме ведущего и зависит от состояния бита MCO.

Замечание: ADuC812 не имеет подтягивающих резисторов в составе своих выходных драйверов на линиях SDATA/SCLOCK и пользователь должен предусмотреть их внешнюю установку. ADuC812S/ ADuC816/ADuC824 имеют внутренние подтягивающие резисторы, так что во внешних резисторах нет необходимости.

Для приема данных MDE бит должен быть сброшен для запрета выдачи по линии SDATA. Программа использует установку и сброс (toggle ) бита MCO (send out a clock pulse) и читает состояние линии SDATA бит MDI.

Бит MDI устанавливается если SDATA в высоком состоянии и сбрасывается если SDATA в низком состоянии (provided MDE is cleared).

Программа должна управлять битами MDO, MCO и MDE соответственно для выработки состояний START, адреса ведомого, бита подтверждения, байта данных и состояния STOP соответственно. Данные заносятся в MDI по фронту SCLOCK только если MDE сброшен. Используйте функции из примера (I2Cmstr.asm) для передачи и приема сигналов они разные.

Замечание:

1.6 АППАРАТНАЯ РЕАЛИЗАЦИЯ РЕЖИМА ВЕДОМОГО.

В Микроконвертор ведомый реализован аппаратно. По умолчанию микросхема находится в режиме ведомого. Работа интерфейса I2C (в противоположность интерфейсу SPI) активизируется по сбросу бита SPE регистра SPICON SFR (SPE=0 по умолчанию). Адрес I2C хранится в регистре I2CADD. Принимаемые или передаваемые данные хранятся в регистре I2CDAT.

Режим ведомого устанавливается сбросом бита I2CM регистра I2CCON. По умолчанию состояние ведомого I2C находится в ожидании состояния START. Микроконвертор установит бит I2CI, когда он опознает условие старта с последующим действительным адресом и битом направления R/W (то есть I2CI установит 8 bits после условия start если адрес соответствует).

Порт I2C не генерирует прерывание пока пользователь не сконфигурирует должным образом систему прерываний I2C, установив бит регистра IE2/IEIP2 SFR а также общее прерывание бит EA в регистре IE SFR. i.e.

; Разрешение I2C прерываний для theADuC812

MOV IE2,#01h ; разрешение I2C прерывания

SETB EA

; разрешение прерывания для I2C ADuC812S/ADuC816/ADuC824

MOV IEIP2,#01h ; разрешение прерывания для I2C

SETB EA

Замечание: Для ADuC812 очень важно чтобы бит I2CI сбрасывался только один раз за время обработки прерывания. Если по каким то причинам пользователь попытается сбросить его еще раз, то это может привести к потере данных.

CLR I2CI ; сброс бита прерывания для ADuC812

ADuC812S/ADuC816/ADuC824 : Авто сброс бита I2CI реализован так, что бит автоматически сбрасывается после чтения или записи регистра I2CDAT SFR.

MOV I2CDAT, A ; I2CI cleared by transmission (812S/816/824)

MOV A, I2CDAT ; I2CI cleared by reception (812S/816/824)

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

Пользователь может выбирать: опрашивать ли ему бит I2CI, или установить режим прерываний. По прерыванию в счетчик команд заносится адрес вектора 003BH по завершении заполнении байта. Первый принятый байт будет I2CI ISR 7-bit адрес и бит R/W будет находиться в регистре I2CDAT SFR то есть, только что полученный байт.

Бит I2CTX содержит бит R/W посланный ведущим. Если бит I2CTX установлен, ведомый передаст данные записанные в регистр I2CDAT. Если же бит I2CTX сброшен, ведомый будет принимать данные в регистр I2CDAT. Программное обеспечение может опрашивать состояние бита I2CTX для того, чтобы определить, является ли, надо ли записывать в регистр или читать из регистра I2CDAT.

Ведомый может удерживать линию SCLOCK в низком состоянии пока бит I2CI не будет сброшен программой. Этот момент описан в разделе “clock stretching” 1.7. Удержание линии SCLOCK позволяет быть уверенным что ведущий не передаст следующий байт пока ведомый не готов его принять.

Прерывание I2CI будет возбуждаться каждый раз, после того как будет передан или принят полный байт и следующий за ним действительный ACK. Если же за байтом следует NACK, прерывание не возбуждается. Микроконвертор будет продолжать возбуждать прерывания по завершении каждого байта пока не получит условие STOP или не будет сброшен интерфейс.

Замечание: Нет различия в возбуждении прерывания по приему START + действительный адрес и прерыванию по приему байта данных. Для различения между прерываниями пользователь должен помнить момент выполнения последовательности. (возможно установкой /сбросом флага как обычно)

Когда принято условие STOP, интерфейс сбрасывается в состояние, в котором ожидается прием адреса (idle). Также, если принимается NACK в конце последовательности, то также происходит возврат к состоянию по умолчанию (idle state). Бит I2CRS может быть использован для сброса интерфейса I2C. Этот бит может использоваться для возврата интерфейса в состояние по умолчанию.

1.7 I2C ДОПОЛНИТЕЛЬНЫЕ ВОЗМОЖНОСТИ НЕ РЕАЛИЗОВАННЫЕ В МИКРОКОНВЕРТОРЕ

РЕЖИМ ВЕДОМОГО:

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

В Микроконвертор условие STOP должно быть послано ведомому для завершения обмена или для изменения направления передачи данных (то есть, для смены с master-transmitter на master receiver (or vice versa)). После передачи условия STOP, новый START должен быть послан для начала нового обмена.

РЕЖИМ ВЕДУЩЕГО:

Удержание синхроимпульса (CLOCK STRETCHING).

· Clock stretching используется для связи быстрого ведущего с медленным ведомым. Когда ведомый принимает свой адрес или достоверные данные линия SCLOCK автоматически удерживается на нижнем уровне. После того как бит I2CI будет сброшен программой, ведомый отпускает линию SCLOCK. Для использования clock stretching ведущий должен иметь возможность читать состояние линии SCLOCK и задерживать выдачу новых данных до тех пор, пока ведомый не освободит линию SCLOCK.

Микроконвертор в режиме ведущего не может читать состояние линии SCLOCK интерфейса I2C. Для чтения состояния линии SCLOCK, линия SCLOCK должна быть соединена с каким то другим цифровым вводом и, читая его, можно будет определить, освободил ли ведомый линию SCLOCK или нет.

Арбитраж (ARBITRATION).

Арбитраж, как сказано, возможен на линии SDATA, пока линия SCLOCK в высоком состоянии, так что ведущий, который передает высокий уровень, пока другой ведущий передает данные переходит в режим ожидания и ждет пока линия не освободится.

Для арбитража необходимо читать содержимое линии SDATA для сравнения с тем, что выдано и что есть на самом деле, на линии SDATA. В Микроконвертор ведущий не может читать состояние линии SDATA и интерфейса I2C. Для чтения состояния линии SDATA, необходимо линию SDATA подключить к другому цифровому входу ведущего.

1.8 РАЗЛИЧИЯ МЕЖДУ РЕАЛИЗАЦИЯМИ I2C ADUC812

ADUC812S/ADUC816/ADUC824

· Слабое подтягивание (примерно 20mA) на выходах SDATA/SCLOCK. Это подтягивание включается только когда выбран режим I2C. Для режима SPI эти подтягивающие резисторы отключаются. В системе со многими ведомыми внешнее подтягивание может быть необходимо.

· Бит прерывания I2CI автоматически сбрасывается при чтении или записи регистра I2CDAT SFR выполняемого программой. Повторный сброс этого бита может привести к потере данных соответственно надо быть уверенным, что только раз за прерывание он сбрасывается.

· Прерывание I2C устанавливается битом (ESI) и битом приоритета прерывания I2C (PSI) оба в регистре IEIP2 SFR (SFR адрес A9h) IEIP2.0 и IEIP2.4 соответственно.

2.0 I2C MASTER OPERATION CODE EXAMPLE

Здесь описывается программа ведущего I2C mstr.asm. Эта программа может использоваться совместно с программой I2Cslave.asm на двух микропроцессорах и показывает работу ведущего и ведомого Микроконвертор. Этот код демонстрирует работу (I2Cmstr.asm) интерфейса I2C в режиме ведущего.

Ведущий посылает условие START, адрес ведомого, и бит R/W (устанавливая для начала ведущего приемником) ведомому. Затем он принимает один байт от ведомого, посылает ему NACK и условие STOP. NACK показывает ведомому, что ведущий принял последний байт переданный ведомым. Затем он посылает условие START, адрес ведомого и бит R/W (сброшенный для обозначения передачи) ведомому опять. Затем ведущий передает ведомому байт. После передачи байта он проверяет ACK и посылает условие STOP. Ведущий затем посылает принятый байт через UART на PC, где он может быть просмотрен на мониторе. Программа возвращается на начало и принимает символ от ведомого опять.

Если символ принятый от UART (нажатием клавиши), тогда ведущий посылает значение ASCII ассоциированное с этим символом для ведомого устройства. По нажатию клавиши INT0 на отладочной плате данные передаются от ведущего к ведомому с наращиванием.

Схема программы показана для master (Рисунок 6). Подпрограммы RCVDATA и SENDDATA показаны на 7a и 7b.

PROGRAM VARIABLES

SLAVEADD: Slaveadd содержит адрес ведомого, к которому мы обращаемся. В данном случае ведомый имеет адрес 44h, это означает, что ведущий должен посылать 88h (или 89h) как описано в разделе 1.3.

OUTPUT: Output содержит значение передаваемое ведомому, здесь оно 0h.

INPUT: Input значение принятое от ведомого. Это значение посылается на UART.

NOACK: Устанавливается если NACK получен когда ACK ожидался.

ERR: Флаг ERR устанавливается, если NOACK устанавливается где то в программе, и позволяет флагу NOACK быть сброшенным в программе. Если флаг ERR устанавливается в конце программы, сообщение об ошибке посылается на UART.

DESCRIPTION OF CODE

Следующее описание работы программы I2Cmstr.asm смотрите в соответствии с Рисунком 6 и также две отдельных диаграммы RCVDATA aи SENDDATA Рисунок 7a и Рисунок 7b.

Configuratio n: конфигурируются UART и Внешнее прерывание External Interrupt 0 (INT0).
UART: UART конфигурируется на скорость 9600.
External Interrupt 0: Устанавливается EX0/IT0 для разрешения прерывания INT0.
Установка EA разрешает прерывания.

Инициализация: Инициализируются регистры I2C и флаги.

I2CCON = A8h => Режим ведущего
Выклюсение выходного драйвера SDATA
SCLOCK в высокий
OUTPUT = 0 Инициализация байта передачи в ‘0’.

Замечание: Поскольку интерфейс I2C в режиме ведущего не требует установки прерывания I2C, или засылки значения в I2CADD.

Прием: Прием байта выполняется в следующей последовательности (смотри RCVDATA Рисунок 7a)

1) Посылка START BIT
2) Посылка адреса ведомому Slave address (R/
W бит установлен на прием)
3) Проверка ACK.
4) Если принят NACK, посылается STOP бит и устанавливается флаг E
RR
5) Если принят ACK посылается 8 синхроимпульсов на ведомое устройство, читая бит MDI после каждого переданного синхроимпульса. После 8 синхроимпульса принятый байт записывается в INPUT
6) Посылка NACK показывает, что был принят последний байт
7) Посылка STOP BIT.
8) Если принят NACK устанавливается флаг ERR.

Передача: Передача байта происходит в следующей последовательности (смотри SENDDATA Рисунок 7b)

1) Посылается START BIT
2) Посылается
адреса ведомому Slave address (R/W бит сброшен для передачи)
3) Проверяется ACK
4) Если принят NACK, посылается STOP бит и устанавливается флаг ERR
5) Если принят ACK тогда посылаются 8 синхроимпульсов ведомому устройству. На каждый бит MDO в I2CCON должен быть загружено соответствующее значение из байта данных OUTPUT.
6) Проверка ACK
8) Если принят NACK, устанавливается флаг ERR.
8) Посылка STOP BIT
Опрос ошибки: Проверка флага ошибки ERR для проверки наличия ошибки. Если имеется ошибка, то посылается сообщение через UART на PC.

Transmit i/p: Передается введенный байт через UART на PC.

Задержка: Эта большая задержка (примерно 1s) используется только для того, чтобы замедлить работу программы и сделать видимой моргание светодиода LED.

Toggle LED: Каждая вспышка LED соответствует приему байта от ведомого и что байт переданный ведущим возвращен ведомым.

Check RI: Если байт принят ведущим из UART, тогда байт грузится в OUTPUT и в дальнейшем будет передавать это значение как новый OUTPUT.

Байт может быть послан мастеру через evaluation board от PC через последовательный порт нажатием клавиши. В этом случае ASCII представляющий символ будет загружен в OUTPUT.

E.g. Если нажат ‘0’ тогда в OUTPUT загрузится 30h. Если нажата ‘a’ тогда в OUTPUT загрузится 61h.

Программа возвращается назад и ожидает приема следующего байта данных.

INTO ISR: Нажатие клавиши INT0 на отладочной плате (evaluation board) (causing an INT0 interrupt) вызовет наращивание выдаваемого байта.

 

 

2.3 I2C MASTER EXAMPLE CODE

;============================================================

; Автор : ADI – Apps www.analog.com/MicroConverter
; Дата : Oct 2000
; Файл : i2Cmstr.asm
; Платформа : ADuC812 (закомментировано для = ADuC824/ADuC816)
; Описание : Программа для режима ведущего I2C. Этот код
; постоянно принимает и передает байт через интерфейс I2C,
; затем посылает принятый байт через UART,
; затем проверяется, введен ли символ через UART,
; если это так, он посылает значение ASCII символов
; вводятся ведомому, затем передает байт.
; Ссылка : Tech Note, uC001: "MicroConverter I2C Compatible
; Interface" находится на www.analog.com/MicroConverter
;===========================================================

$MOD812 ; использует ADuC812 & 8052 предопределенные имена
;$MOD816
;$MOD824

;____________________________________________________________________

; ОПРЕДЕЛЕНИЕ ПЕРЕМЕННЫХ ВО ВНУТРЕННЕЙ ПАМЯТИ (RAM)

BITCNT DATA 30h ; счетчик бит для I2C процедур
SLAVEADD DATA 31h ; адрес ведомого для I2C процедур
INPUT DATA 32h ; данные принятые от ведомого
OUTPUT DATA 33h ; данные передаваемые ведомому
NOACK BIT 00h ; I2C флаг неподтверждения
ERR BIT 00h ; I2C флаг ошибки
LED EQU P3.4

;____________________________________________________________________

; НАЧАЛО КОДА

CSEG
ORG 0000h
JMP MAIN

;____________________________________________________________________

; Обработчик прерывания INT0 ISR

ORG 0003h

INC OUTPUT

RETI

;____________________________________________________________________

; ГЛАВНАЯ ПРОГРАММА MAIN PROGRAM

ORG 0060h
MAIN:
; конфигурирование UART ADuC812
MOV SCON,#52h ; конфигурирование скорости UART 9600
MOV TMOD,#20h ; подразумевается частота 11.0592MHz
MOV TH1,#-3
SETB TR1

; конфигурирование & разрешение прерываний
SETB EX0 ; установка разрешения INT0
SETB IT0 ; установка бита INT0
SETB EA ; разрешение прерываний
; инициализация
MOV SLAVEADD,#88H ; сброс бита RW
MOV I2CCON,#0A8h ; установка SDATA & SCLOCK, и
; выбор режима ведущего
MOV OUTPUT,#0 ; TX 0 по умолчанию
CLR NOACK
CLR ERR
RXTXLOOP:
; код для режима чтения ( ведущий принимает один байт от ведомого )
CALL RCVDATA ; посылка start
; посылка адреса
; опрос подтверждения
; прием байта в ACC
; опрос ACK
; посылка stop
; код для режима записи ( ведущий передает один байт ведомому )
CALL SENDDATA ; посылка start
; посылка байта адреса
; опрос подтверждения
; передача ACC
; опрос ACK
; посылка
stop
; Проверка сообщения об ошибке
JB ERR,SENDERR ; если есть ошибка, послать сообщение об ошибке
; Передача принятого байта (INPUT) через UART на PC (гипертерминал)
MOV A,INPUT ; передпть принятое значение в ACC
CALL SENDVAL ; отправить полученное значение через UART
JMP SKIP
SENDERR:
CALL ERROR ; отправить сообщение об ошибке через UART
CLR ERR ; сброс флага ошибки
SKIP:
MOV A,#10 ; посылка LF+CR
CALL SENDCHAR
MOV A,#13
CALL SENDCHAR
; Моргание LED (1s задержка чтобы было видно вспышку LED)
MOV A, #10
CALL DELAY
CPL LED
; Опрос нового OUTPUT
JNB RI, RXTXLOOP ; повторять пока (UART принимает данные)
; Если приняты данные из UART, сохранить их в OUTPUT
MOV OUTPUT,SBUF ; обновление байта данных OUTPUT на новое
; значение
CLR RI ; RI надо сбросить
JMP RXTXLOOP ; возврат к главному ожиданию

;============================================================
; ПОДПРОГРАММЫ
;============================================================

; SENDDATA

; посылка всей последовательности ведомому ; (slave address + data (OUTPUT)) SENDDATA:
; посылка start
CALL STARTBIT ; активация линии и посылка адреса ведомому
; посылка адреса ведомого
MOV A, SLAVEADD
CALL SENDBYTE ; установка NOACK если NACK принят
JB NOACK, STOPSEND ; если нет подтверждения, то посылка stop
; посылка байта OUTPUT
MOV A, OUTPUT
CALL SENDBYTE ; установить NOACK если принят NACK
STOPSEND:
CALL STOPBIT ; посылка stop
JNB NOACK, SENDRET ; если ведомый посылает NACK послать ошибку
SETB ERR ; установить флаг ошибки
SENDRET:
RET

;____________________________________________________________________

; RCVDATA

; прием одного или более байтов данных от ведомого по I2C.
RCVDATA:
INC SLAVEADD ; Установить RW на прием
; послать start
CALL STARTBIT ; активация линии и посылка адреса ведомому
; послать адрес ведомого
MOV A, SLAVEADD
CALL SENDBYTE ; установить NOACK если принят NACK
DEC SLAVEADD ; вернуть прежний адрес SLAVEADD в 88h (после INC)
JB NOACK, STOPRCV ; Проверить соответствие ведомого.
CALL RCVBYTE ; Принять следующий байт данных.
MOV INPUT,A ; Сохранить байт данных в буфере.
STOPRCV:
CALL STOPBIT
JNB NOACK, RCVRET ; если ведомый послал NACK послать ошибку
SETB ERR ; установить флаг ошибки
RCVRET:
RET

;____________________________________________________________________

; STARTBIT
; Посылка start для инициализации обмена по I2C
STARTBIT:
SETB MDE ; установить линию SDATA на выдачу
CLR NOACK
CLR MDO ; обнуление O/P на SDATA
CLR MCO ; start bit
RET

;____________________________________________________________________

; STOPBIT
; Послать stop для завершения передачи по I2C
STOPBIT:
SETB MDE ; установить линию SDATA на выдачу
CLR MDO ; подготовить SDATA для stop
SETB MCO ; установить синхро для stop
SETB MDO ; Это stop
RET

;____________________________________________________________________

; SENDBYTE
; Send 8-bits in ACC ведомому
SENDBYTE:
MOV BITCNT,#8 ; 8 бит в байте
SETB MDE ; установка линии SDATA на выдачу
CLR MCO ; убеждаемся в том что линия clock в низком состоянии
SENDBIT:
RLC A ; сдвигаем бит данных для выдачи в перенос (carry)
MOV MDO,C ; выдача бита данных на линию SDATA
SETB MCO ; выдаем синхроимпульс
CLR MCO ; сбрасываем синхроимпульс
DJNZ BITCNT,SENDBIT ; возвращаемся назад пока не выданы все 8 бит
CLR MDE ; сбрасываем линию данных для подтверждения
SETB MCO ; посылаем синхроимпульс для подтверждения
JNB MDI,NEXT ; опрос подтверждения
SETB NOACK ; нет подтверждения, устанавливаем флаг
NEXT:
CLR MCO ; сбрасываем синхроимпульс
RET

;____________________________________________________________________
; RCVBYTE
; получение байта данных по I2C от ведомого. Результат приема
; возвращается в A
RCVBYTE:
MOV BITCNT,#8 ; Установить число бит.
CLR MDE ; установить разрешение линии SDATA на ввод CLR MCO ; убеждаемся что линия синхроимпульса в низком состоянии
RCVBIT:
SETB MCO ; синхроимпульс на прием бита
CLR MCO ; сброс синхроимпульса
MOV C,MDI ; чтение бита информации в carry.
RLC A ; Сдвиг бита в байт результата.
DJNZ BITCNT,RCVBIT ; Повторение пока принимаются биты.
; принятый байт в аккумуляторе
SETB MDE ; Data pin =Output for NACK
SETB MDO ; Send NACK (всегда посылается NACK для
; последнего переданного байта)
SETB MCO ; Послать NACK синхроимпульс.
CLR MCO
RET

;____________________________________________________________________

; DELAY
; DELAY ROUTINE FOR THE ADuC812/ADuC816/ADuC824
DELAY: ; Задержка на 100ms * A
; ADuC812 100ms based on 11.0592MHz Core Clock
; ADuC824 100ms based on 1.573MHz Core Clock
MOV R2,A ; Acc содержит величину задержки
DLY0: MOV R3,#200 ; Установка delay loop0
DLY1: MOV R4,#229 ; Установка delay loop1
DJNZ R4,$ ; Dec R4 & Jump here until R4 is 0
; wait here for 131*15.3us=2ms
DJNZ R3,DLY1 ; Dec R3 & Jump DLY1 until R3 is 0
; Wait for 50*2ms
DJNZ R2,DLY0 ; Dec R2 & Jump DLY0 until R2 is 0
; wait for ACC*100ms
RET ; возврат из подпрограммы

;____________________________________________________________________

; ERROR
; эта подпрограмма посылает если NACK принято от ведомого
ERROR:
MOV A,#45h
CALL SENDCHAR ; посылка символа E через UART RET

;____________________________________________________________________

; SENDCHAR
; sends ASCII value contained in A to UART
SENDCHAR:
JNB TI,$ ; ожидание передачи символа
CLR TI ; сброс TI
MOV SBUF,A
RET

;____________________________________________________________________

; HEX2ASCII
; преобразование A в hex символа, представляющего значение A's
; младшего полубайта
HEX2ASCII:
ANL A,#00Fh
CJNE A,#00Ah,$+3
JC IO0030
ADD A,#007h
IO0030: ADD A,#'0'
RET

;____________________________________________________________________

; SENDVAL
; преобразование hex значения A в два символа ASCII, и выдача их
; через UART. Значение A не изменяется.
SENDVAL:
PUSH ACC
SWAP A
CALL HEX2ASCII
CALL SENDCHAR ; посылка старшего полубайта
POP ACC
PUSH ACC
CALL HEX2ASCII
CALL SENDCHAR ; посылка младшего полубайта
POP ACC
RET

;____________________________________________________________________

END

2.4 I2C SLAVE EXAMPLE CODE

;============================================================

; Автор: ADI - Apps www.analog.com/MicroConverter
; Дата : Oct 20
00
; Файл : i2cslave.asm
; Hardware : ADuC812 (commented out = ADuC816/ADuC824)
;Описание: Код для ведомого I2C. Этот код
; постоянно принимает и передает байт через интерфейс I2C
;, затем посылает принятый байт через UART,
; затем проверяет введен ли симвл с UART.
; Если введен, то посылает его ASCII значение
; ведомому, далее передает байт.
; Ссылка : Tech Note, uC001: "MicroConverter I2C Compatible
; Interface" находится на www.analog.com/MicroConverter

;============================================================

$MOD812 ; использует ADuC812 & 8052 предопределенные имена
;$MOD816
;$MOD824

;____________________________________________________________________

; ОПРЕДЕЛНИЕ ПЕРЕМЕННЫХ ВО ВНУТРЕННЕЙ ПАМЯТИ
BYTECNT DATA 30h ; счетчик байт для I2C процедур
INPUT DATA 31h ; данные полученные от ведущего
OUTPUT DATA 32h ; данные для передачи ведущему
GO BIT 00h ; флаг ожидания прерывания
FIRST BIT 01h ; флаг индицирующий первое принятое прерывание Int
LED EQU P3.4 ; P3.4 управляет LED на отладочной плате

;____________________________________________________________________

; Начало кода
CSEG
ORG 0000h
JMP MAIN

;____________________________________________________________________

; обработчик прерывания NT0 ISR
ORG 0003h
INC OUTPUT
RETI

;____________________________________________________________________

; I2C ISR обработчик прерывания
ORG 003Bh
JB I2CTX, SLAVE_TRANSMITTER
SLAVE_RECEIVER:
JB FIRST, ENDINT1 ; если первый INT тогда ждем следующего прерывания
SETB GO ; прием завершен
MOV INPUT, I2CDAT ; запись принятых данных в INPUT
JMP ENDINT1
SLAVE_TRANSMITTER:

SETB GO ; передача завершена
MOV I2CDAT, OUTPUT ; занесение данных для передачи в I2CDAT
ENDINT1:
CLR I2CI ; сброс бита I2C прерывания (только для 812)
; JMP ENDINT2 ; Note: для ADuC824/816 чтение или
; запись регистра I2CDAT
; автоматически сбрасывает i2ci. Если
; I2CI сбросить дважды это
; вызовет ошибку MicroConverter.)

ENDINT2:
CLR FIRST ; адрес уже был принят
RETI

;____________________________________________________________________

; Главная программа MAIN PROGRAM
ORG 0060h
MAIN:
; конфигурирование UART ADuC812
MOV SCON,#52h ; конфигурация UART для скорости 9600
MOV TMOD,#20h ; подразумевается частота кристалла 11.0592MHz
MOV TH1,#-3
SETB TR1

; MOV RCAP2H,#0FFh ; config UART for 9830baud
; MOV RCAP2L,#-5 ; (close enough to 9600baud)
; MOV TH2,#0FFh
; MOV TL2,#-5
; MOV SCON,#52h
; MOV T2CON,#34h

; конфигурирование и установка прерывания
MOV IE2,#01h ; установка прерывания I2C

; MOV IEIP2,#01h ; enable I2C interrupt

SETB EX0 ; установка INT0
SETB IT0 ; INT0 edge triggered
SETB EA ; разрешает все прерывания
;начальные установки
MOV I2CADD,#044h ; адрес ведомого 44h
MOV I2CCON,#00h ; режим ведомого (по умолчанию=>не необходимое)
CLR GO ; сброс флага ожидания прерывания
; GO устанавливается однажды для данных TX'd или RX'd
SETB FIRST ; FIRST сбрасывается после приема
; первого принятого ведомым прерывания
MOV OUTPUT,#0 ; первый байт для передачи 40h
CLR LED
WAITFORDATA:
JNB GO,$ ; ----- ожидание прерывания i2c ------
; Если он в режиме приема, он
; ждет здесь второго прерывания (так как
; первое прерывание содержит только
; адрес ведомого в I2CDAT
; В режиме передачи
; производится выдача после первого прерывания.
SETB FIRST ; реинициализация флага
CLR GO
JB I2CTX,WAITFORDATA
; если ведомый только что передал данные, тогда
; ожидание приема байта данных
; если ведомый только что принял данные, тогда
; посылает принятый байт на UART
SENDUART:
CPL LED ; LED изменяется каждый раз как один байт
; принят и другой передан
MOV A,INPUT ; принятое значение посылается на UART
CALL SENDVAL
MOV A,#10
CALL SENDCHAR ; посылка LF + CR
MOV A,#13
CALL SENDCHAR
JNB RI, WAITFORDATA ; повторять (пока UART принимает данные)
; WHEN UART DATA RECEIVED, MOVE DATA TO I2C OUTPUT...
MOV OUTPUT, SBUF ; изменить OUTPUT на новое значение
CLR RI ; must clear RI
JMP WAITFORDATA ; возврат на главное ожидание
;============================================================
; SUBROUTINES
;============================================================
;____________________________________________________________________

; SENDCHAR

; посылает ASCII значение содержащееся в A в UART
SENDCHAR:
JNB TI,$ ; ожидает отправки символа
CLR TI ; должен сбросить TI
MOV SBUF,A
RET
;____________________________________________________________________

; HEX2ASCII

; преобразует A в hex символ представляющий значение A's
; least значение полубайта
HEX2ASCII:
ANL A,#00Fh
CJNE A,#00Ah,$+3
JC IO0030
ADD A,#007h
IO0030: ADD A,#'0'
RET

;____________________________________________________________________

; SENDVAL

; преобразует hex значение A в два ASCII символа, и затем передает
; эти два символа в UART. Не изменяет значение A.

SENDVAL:
PUSH ACC
SWAP A
CALL HEX2ASCII
CALL SENDCHAR ; пересылает старший полубайт
POP ACC
PUSH ACC
CALL HEX2ASCII
CALL SENDCHAR ; пересылает младший полубайт
POP ACC
RET
;____________________________________________________________________

END

 

ГЛАВНАЯ СТРАНИЦА |  ТЕКУЩАЯ СТРАНИЦА;

 

Hosted by uCoz