Найти в Дзене

Орион-128. Интерфейс I2C. Работа с микросхемами ПЗУ EEPROM AT24Cxx с электрическим стиранием.

Всех приветствую! Существует очень много различных датчиков, микросхем ПЗУ с электрическим стиранием, индикаторов ЖКИ, модулей часов и т.д. с интерфейсом I2C, с которыми хотелось бы поработать, или просто "пощупать" их в работе. Для этого нужна программная поддержка. Штатно на Орионе её нет. Каждый первый скажет:"Возьми Arduino и не мучайся!". Взял. Но так неинтересно. Приобрёл я вот такой модуль с микросхемой ПЗУ AT24C04 объёмом 512 байт. Схема данного модуля: Как видно, на плате модуля присутствуют все необходимые элементы обвязки, поэтому нам не придётся городить всё это у себя. Схема подключения модуля к порту /F600h следующая: Подключение модуля к Ориону в железе: Из-за особенностей перепрограммирования КР580ВВ55 приходится отказываться от двух-проводного режима работы и использовать три линии для подключения к порту. Нужен диод для развязки. Подойдёт любой. И при этом КР580ВВ55 программируется один раз в начале работы. Теперь напишем протокол обмена данными. Требования: ОС DSDOS

Всех приветствую!

Существует очень много различных датчиков, микросхем ПЗУ с электрическим стиранием, индикаторов ЖКИ, модулей часов и т.д. с интерфейсом I2C, с которыми хотелось бы поработать, или просто "пощупать" их в работе. Для этого нужна программная поддержка. Штатно на Орионе её нет. Каждый первый скажет:"Возьми Arduino и не мучайся!". Взял. Но так неинтересно.

Приобрёл я вот такой модуль с микросхемой ПЗУ AT24C04 объёмом 512 байт.

Схема данного модуля:

-2

Как видно, на плате модуля присутствуют все необходимые элементы обвязки, поэтому нам не придётся городить всё это у себя.

Схема подключения модуля к порту /F600h следующая:

-3

Подключение модуля к Ориону в железе:

-4

Из-за особенностей перепрограммирования КР580ВВ55 приходится отказываться от двух-проводного режима работы и использовать три линии для подключения к порту. Нужен диод для развязки. Подойдёт любой. И при этом КР580ВВ55 программируется один раз в начале работы.

Теперь напишем протокол обмена данными.

Требования: ОС DSDOS, ASSM 2.7 + DSDOS SDK, текстовый редактор ED$.

Для работы с интерфейсом I2C нам понадобятся несколько основных процедур: инициализация, старт, стоп, отправка байта и приём байта, а также несколько вспомагательных.

Перво-наперво напишем процедуру инициализации порта и шины I2C:

PT_SDA_IN: EQU 0F602h
PT_I2C: EQU 0F603h
CHIP_ADDRESS: DB 0A0h

INIT_I2C:
MVI A,93h
STA PT_I2C
MVI A,0C0h
STA PT_SDA_IN
RET

Теперь напишем процедуры старт, стоп и строб сигнала SCL:

I2C_START:
MVI A,0Eh
STA PT_I2C
NOP
MVI A,0Ch
STA PT_I2C
RET

I2C_STOP:
MVI A,0Dh
STA PT_I2C
NOP
MVI A,0Fh
STA PT_I2C
RET

I2C_PULSE:
PUSH PSW
MVI A,0Dh
STA PT_I2C
NOP
MVI A,0Ch
STA PT_I2C
POP PSW
RET

Далее следуют процедуры отправки и приёма байта:

I2C_TRANSMIT:
;вх. [C] передаваемый байт
;вых.[A]=0 - OK
MVI B,8
TLOOP:
MOV A,C
ANI 80h
STA PT_I2C-1
CALL I2C_PULSE
MOV A,C
RAL
MOV C,A
DCR B
JNZ TLOOP
CALL SDA_1
LDA PT_SDA_IN ;READ ACK FROM SLAVE
ANI 1
CALL I2C_PULSE
CALL SDA_0
RET

I2C_RECIEVE:
;вых.[C] принятый байт
CALL SDA_1
LXI B,0800h
RLOOP:
MOV A,C
RAL
MOV C,A
LDA PT_SDA_IN ;READ BIT
ANI 1
ADD C
MOV C,A
CALL I2C_PULSE
DCR B
JNZ RLOOP
CALL SDA_1
CALL I2C_PULSE ;NACK FROM MASTER
RET

Осталось написать обслуживающие подпрограммы:

SDA_0:
PUSH PSW
MVI A,0Eh
STA PT_I2C
POP PSW
RET

SDA_1:
PUSH PSW
MVI A,0Fh
STA PT_I2C
POP PSW
RET

I2C_DELAY_5MS:
PUSH B
LXI B,500
LOOP_DELAY:
DCX B
MOV A,B
ORA C
JNZ LOOP_DELAY
POP B
RET

I2C_ERROR:
CALL I2C_STOP
MVI A,2
LXI H,I2C_T_ERRMSG
CALL 0F000h
MVI A,1
CALL 0F000h
RET

I2C_T_ERRMSG:
DB 13
DB 'Ошибка отправки данных ',7
DB 0

Всё это оборачиваем в библиотеку 24C16.L, которую можно будет скачать в конце статьи по прилагаемой ссылке.

А теперь самое интересное: работа с микросхемой!

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

WRITE_I2C:
;вх. [HL] адрес
; [A] данные;
PUSH H
PUSH PSW
MOV A,H
RAL
MOV H,A
LDA CHIP_ADDRESS
ADD H
MOV H,A
CALL I2C_START
MOV C,H
CALL I2C_TRANSMIT
ORA A
JNZ I2C_ERROR
MOV C,L
CALL I2C_TRANSMIT
ORA A
JNZ I2C_ERROR
POP PSW
MOV C,A
CALL I2C_TRANSMIT
ORA A
JNZ I2C_ERROR
CALL I2C_STOP
POP H
RET

READ_I2C:
;вх. [HL] адрес
;вых. [A] данные;
PUSH H
MOV A,H
RAL
MOV H,A
LDA CHIP_ADDRESS
ADD H
MOV H,A
CALL I2C_START
MOV C,H
CALL I2C_TRANSMIT
ORA A
JNZ I2C_ERROR
MOV C,L
CALL I2C_TRANSMIT
ORA A
JNZ I2C_ERROR
CALL I2C_STOP
CALL I2C_START
INR H
MOV C,H
CALL I2C_TRANSMIT
ORA A
JNZ I2C_ERROR
CALL I2C_RECIEVE
CALL I2C_STOP
MOV A,C
POP H
RET

Комментариев практически нет, но они есть в исходных текстах по прилагаемой ссылке.

Итак, библиотека написана. Теперь можно обмениваться с микросхемой данными, не думая ни об адресации чипа, ни о страницах. Задаём адрес и либо пишем, либо читаем.

Теперь напишем две небольших тестовых программы, которые будут пользоваться нашей библиотекой. Одна показывает дамп ПЗУ, вторая пишет и читает указанный байт по выбранному адресу. Тексты этих программ я приводить не буду, они есть в прилагаемом архиве, покажу только результаты их работы.

Предварительно с помощью стороннего программатора я записал в ПЗУ AT24С04 первые 512 байт МОНИТОРа-1 от Ориона. Всё-таки с существующей информацией легче работать, чем с кодами FFh.

Программа V2$.
Показывает дамп ПЗУ. Чтобы исключить скроллинг, показано 511 байт вместо 512.

-5

Обратим внимание на первый адрес. Его код С3. Теперь с помощью другой программы под названием V3$ изменим этот байт на FFh.

Укажем в исходном тексте адрес и байт:

-6

Запустим программу V3$. Видим результат работы.

-7

По алгоритму это слева направо: пишем FFh - читаем FFh. Работа прошла успешно. Теперь удостоверимся, что это действительно так. Запустим программу V2$.

-8

И мы видим, что первый байт действительно перезаписался с С3 на FF.
Библиотека работает! 👍

В случае какой-то неправильной работы выводится соответствующее сообщение.

-9

Поизучав даташиты, выяснилось, что данная библиотека может поддерживать ПЗУ от AT24C01 до AT24C16. Выше - нет. Для более ёмкостных ПЗУ нужны свои библиотеки. Впрочем, данная легко под это модифицируется.

На этом всё! Безбагового Вам программирования! 👻

Все материалы по статье можно скачать здесь https://disk.yandex.ru/d/uOEGd-l0vMRTgg

До новых встреч!