Думаю, что рассказ про этот цирк будет небесполезен

MT-10T11 -это семисегментный дисплей, 10 разрядов, собран на контроллере PCF8576C. Подключается по интерфейсу I2C, что меня и привлекло; требует только двух линий, помимо питания.
Выпускает эту сборку отечественная фирма "МЭЛТ". Выпускает в двух вариантах: с трехвольтовым питанием и с 5-вольтовым. (Собственно, контроллер работоспособен от 2 до 6 вольт, на 3 или 5V расчитывается стекло с жидкими кристаллами).
Особый прикол заключается в том, что у 3-вольтового дисплея питание подсветки- 5 вольт! Из двух светодиодов последовательно; от трех вольт не зажигается. Смотрите, чтоб не нарваться на такое сочетание. Эти дисплеи имеют маркировку с дополнительным индексом "3V0".
Например:
MT-10T11-3TLA пятивольтовый (оранж. подсветка);
MT-10T11-3TLA-3V0 трехвольтовый.
В "Чип-И-Дип"е персонал достаточно адекватен, они продают полностью 5-вольтовый вариант.
Но и тут, блин не обошлось без поднаколки! Скачиваю на сайте "Чип-И-Дип"а описание на дисплей, ПДФка от производителя. И в ней, без указания типов, однозначно написано: питание - 3 вольта, точка.
Ну-дык, я не ожидая подвоха, распроектировал схему на 3 вольта, натравил платку, спаял, подключаю - фигушки! - ничего не работает (дисплей-то 5-вольтовый!)
Прошерстил кучу сайтов, в том числе весь МЭЛТ-овский форум, пока разобрался с этой чехардой с питаниями. В этом году - 11 лет, как производитель не удосуживается поправить документацию! Какое, ббблин, тут "импортозамещение"?!!..
Пришлось всю плату переделывать((((
Теперь про программирование.
Даташит на контроллер найти несложно. Но во-первых, он на инглише, и не всем будет легко прочесть. А во-вторых, имеет кучу режимов, и не ясно какие именно из них производитель задействовал в дисплее. В сопроводиловке об этом нет ни слова.
Выяснил, что режимы следующие:
I2C-адрес устройства: 70h
bias=1/2,
mux=1:2
выбор устройства: 0
банк: 0
Программирую я на PBP (PicBasic PRO). А примеры в Инете - все на Си, либо на Ардуино. Пришлось разбираться самому...
В PBP есть команда передачи по I2C: называется I2CWRITE. Она предназначена для работы с внешним ЗУ по I2C, и под это распланированы ее аргументы. Для нас она может сделать только две вещи: кинуть на шину байт из параметра Control, и опционально перейти на метку, если устройство не отвечает.
У меня семь потов сошло, пока я заставил дисплей все же заработать... Пожалуй не буду объяснять в словах, а выложу полный листинг тестовой программы. Всё подробно откомментировал.
Добавлю только еще следующее.
На шине I2C обязательно должны быть подтягивающие резисторы к питанию. У меня стояли 4.7 кОм, как рекомендовано в хелпе команды I2CWRITE.
Но потом я попробовал, оказалось что все работает и на внутренней подтяжке PORTB МК:
OPTION_REG.7 = 0
делайте, как вам удобнее.
Итак, код тестовой программы. Может быть я управляю контроллером не самым оптимальным образом, но, по крайней мере, так - работает.
Код
'====================================================================
' PIC16F84 программа: Тест дисплея MT-10T11
'====================================================================
'
'
' конт PIN что подключается
' -------------------------------------------------------
' 17: PORTA.0 -
' 18: PORTA.1 -
' 1: PORTA.2 -
' 2: PORTA.3 -
' 3: PORTA.4 -
'
' 6: PORTB.0 -
' 7: PORTB.1 -
' 8: PORTB.2 -
' 9: PORTB.3 -
' 10: PORTB.4 -
' 11: PORTB.5 -
' 12: PORTB.6 - MT-10T11, SDA (конт. 1)
' 13: PORTB.7 - MT-10T11, SCL (конт. 2)
'
' ------------+-----------------------------------------
' 15: CLKOUT | R C Режим
' 16: CLKIN | 8.2 к 15 пФ RC
' _____ +-----------------------------------------
' 4: сброс | 4.7 к
' ------------+-----------------------------------------
' 14: +5V | MT-10T11 конт: 3, 5
' ------------+------------------------
' 5:земля,общ.| MT-10T11 конт: 4, 6
' -------------------------------------
'================================================================
'Инициализация портов
TRISB = %11000000
PORTB = %11000000
' Объявление переменных
'I2C
SDA VAR PORTB.6 'данные
SCL VAR PORTB.7 'тактирование
LCDpos VAR byte 'счетчик позиций вывода на дисплей
LCDchr VAR byte 'код для вывода на дисплей
i VAR byte
PAUSE 10 'раскрутка контроллера дисплея
maincycle:
GOSUB CLS
FOR i=0 TO 9
PAUSE 500
LCDchr = i
GOSUB CHR7
GOSUB PRINT 'вывод очередного знака
NEXT i
GOSUB endprn
PAUSE 1000
LCDpos=2 'вывод с позиции номер 2.
GOSUB LOCATE
FOR i=1 TO 6 'вывод шести знаков
LCDchr = i+9 'hex-буквы
GOSUB CHR7
GOSUB PRINT
NEXT i
GOSUB endprn
PAUSE 2000
goto maincycle
'==================================================
' ПОДПРОГРАММЫ
'==================================================
' УПРАВЛЕНИЕ ПО I2C ДИСПЛЕЕМ MT10T11
'---------------------------------------
CLS:
'очистка дисплея.
'Подготавливает дисплей к выводу.
'Если была нужна только очистка, без вывода,
'все равно надо вызвать завершающую подпрограмму endprn.
LCDpos=10
LOCATE:
'инициализирует дисплей; подготавливает к последующему выводу,
'устанавливает начало вывода на позицию LCDpos.
'Если LCDpos превышает 9, то производит очистку всего дисплея
'и устанавливает начальную позицию LCDpos=0
'(Изменяет переменную LCDchr).
I2CWRITE SDA,SCL,$70 'старт, адрес устройства
I2CWRITE SDA,SCL,%11001110 'вкл, bias=1/2, mux=1:2
I2CWRITE SDA,SCL,%11100000 'выбор устройства 0
I2CWRITE SDA,SCL,%11111000 'банк 0
I2CWRITE SDA,SCL,%11110000 'режим мерцания: normal, off
IF LCDpos>9 then
FOR LCDpos=0 TO 11
I2CWRITE SDA,SCL,0
NEXT LCDpos
LCDpos=0
GOTO LOCATE
ENDIF
LCDchr=LCDpos<<2
I2CWRITE SDA,SCL,LCDchr
Return
CHR7:
'Знакогенератор для формирования семисегментных знаков.
' побитовая раскладка (старший бит слева): abfgecd.
'LCDchr содержит знак, который будет конвертирован в код для вывода.
' 0 1 2 3 4 5 6 7 8 9 A b C d E F
LOOKUP LCDchr,[$EE,$44,$DA,$D6,$74,$B6,$BE,$C4,$FE,$F6,$FC,$3E,$AA,$5E,$BA,$B8],LCDchr
Return
SPC:
'Вывод одного пробела на дисплей.
LCDchr=0
PRINT:
'Вывод кода, содержащегося в LCDchr на дисплей.
IF LCDpos<10 then
I2CWRITE SDA,SCL,LCDchr
LCDpos=LCDpos+1
ENDIF
Return
endprn:
'Завершение вывода.
'Следует обязательно вызывать после вывода нужного количества символов.
'Дополняет вывод пробелами до последнего знакоместа,
'обеспечивает команду Стоп I2C.
FOR LCDpos=LCDpos TO 10
I2CWRITE SDA,SCL,0
NEXT LCDpos
Return
END
' PIC16F84 программа: Тест дисплея MT-10T11
'====================================================================
'
'
' конт PIN что подключается
' -------------------------------------------------------
' 17: PORTA.0 -
' 18: PORTA.1 -
' 1: PORTA.2 -
' 2: PORTA.3 -
' 3: PORTA.4 -
'
' 6: PORTB.0 -
' 7: PORTB.1 -
' 8: PORTB.2 -
' 9: PORTB.3 -
' 10: PORTB.4 -
' 11: PORTB.5 -
' 12: PORTB.6 - MT-10T11, SDA (конт. 1)
' 13: PORTB.7 - MT-10T11, SCL (конт. 2)
'
' ------------+-----------------------------------------
' 15: CLKOUT | R C Режим
' 16: CLKIN | 8.2 к 15 пФ RC
' _____ +-----------------------------------------
' 4: сброс | 4.7 к
' ------------+-----------------------------------------
' 14: +5V | MT-10T11 конт: 3, 5
' ------------+------------------------
' 5:земля,общ.| MT-10T11 конт: 4, 6
' -------------------------------------
'================================================================
'Инициализация портов
TRISB = %11000000
PORTB = %11000000
' Объявление переменных
'I2C
SDA VAR PORTB.6 'данные
SCL VAR PORTB.7 'тактирование
LCDpos VAR byte 'счетчик позиций вывода на дисплей
LCDchr VAR byte 'код для вывода на дисплей
i VAR byte
PAUSE 10 'раскрутка контроллера дисплея
maincycle:
GOSUB CLS
FOR i=0 TO 9
PAUSE 500
LCDchr = i
GOSUB CHR7
GOSUB PRINT 'вывод очередного знака
NEXT i
GOSUB endprn
PAUSE 1000
LCDpos=2 'вывод с позиции номер 2.
GOSUB LOCATE
FOR i=1 TO 6 'вывод шести знаков
LCDchr = i+9 'hex-буквы
GOSUB CHR7
GOSUB PRINT
NEXT i
GOSUB endprn
PAUSE 2000
goto maincycle
'==================================================
' ПОДПРОГРАММЫ
'==================================================
' УПРАВЛЕНИЕ ПО I2C ДИСПЛЕЕМ MT10T11
'---------------------------------------
CLS:
'очистка дисплея.
'Подготавливает дисплей к выводу.
'Если была нужна только очистка, без вывода,
'все равно надо вызвать завершающую подпрограмму endprn.
LCDpos=10
LOCATE:
'инициализирует дисплей; подготавливает к последующему выводу,
'устанавливает начало вывода на позицию LCDpos.
'Если LCDpos превышает 9, то производит очистку всего дисплея
'и устанавливает начальную позицию LCDpos=0
'(Изменяет переменную LCDchr).
I2CWRITE SDA,SCL,$70 'старт, адрес устройства
I2CWRITE SDA,SCL,%11001110 'вкл, bias=1/2, mux=1:2
I2CWRITE SDA,SCL,%11100000 'выбор устройства 0
I2CWRITE SDA,SCL,%11111000 'банк 0
I2CWRITE SDA,SCL,%11110000 'режим мерцания: normal, off
IF LCDpos>9 then
FOR LCDpos=0 TO 11
I2CWRITE SDA,SCL,0
NEXT LCDpos
LCDpos=0
GOTO LOCATE
ENDIF
LCDchr=LCDpos<<2
I2CWRITE SDA,SCL,LCDchr
Return
CHR7:
'Знакогенератор для формирования семисегментных знаков.
' побитовая раскладка (старший бит слева): abfgecd.
'LCDchr содержит знак, который будет конвертирован в код для вывода.
' 0 1 2 3 4 5 6 7 8 9 A b C d E F
LOOKUP LCDchr,[$EE,$44,$DA,$D6,$74,$B6,$BE,$C4,$FE,$F6,$FC,$3E,$AA,$5E,$BA,$B8],LCDchr
Return
SPC:
'Вывод одного пробела на дисплей.
LCDchr=0
PRINT:
'Вывод кода, содержащегося в LCDchr на дисплей.
IF LCDpos<10 then
I2CWRITE SDA,SCL,LCDchr
LCDpos=LCDpos+1
ENDIF
Return
endprn:
'Завершение вывода.
'Следует обязательно вызывать после вывода нужного количества символов.
'Дополняет вывод пробелами до последнего знакоместа,
'обеспечивает команду Стоп I2C.
FOR LCDpos=LCDpos TO 10
I2CWRITE SDA,SCL,0
NEXT LCDpos
Return
END
С пожеланиями успехов,
Меджикивис.