Привет, недавно мне совершенно случайно попалась в руки такая железка:
![image](https://habrastorage.org/r/w780q1/getpro/habr/post_images/bb9/ba6/295/bb9ba6295271fce2fede487a4a3d4d9a.jpg)
Ну железка и железка, подумал я… На плате присутствует микроконтроллер РВЕ035, расширитель IO m5l8243p, ИР12 между РФ5 и контроллером и там еще где-то ЛН1 в стороне болтается. Мне сразу понравилась хорошая раритетная ПЗУ на 2Кб РФ5 в панельке в золоте. Думаю, сниму ее, а остальное смело в утиль, бо вся плата залита лаком по самое небалуйся..А потом все-таки стало интересно, а что это такое вообще?
Выяснилось, что это плата управления от советской микроволновки типа Электроника 23 (aka БУВИ-2 aka Фея aka Днепрянка). В интернете быстро нашлась даже схема девайса: http://www.elremont.ru/small_rbt/bt_rem32.php Теперь, когда стало понятно, что это такое, одна рука уверенно потянулась к мусорке, а другая нечаянно вбила в гугле «РВЕ035» и… И я заинтересовался и внимательно вгляделся в плату. Раз есть контроллер, значит для него можно писать программы. Еще прямо на плате есть какой-никакой экран (4 цифры) куда можно выводить всякие матерные ругательства (BABA, SISI, ну, вы поняли). Так же здесь еще есть пьезоэлемент, а значит можно пищать. Ко всему прочему можно 4x4 клавиатуру подключить. Это же прямо девборда какая-то получается, обрадовался я!
Как уже было сказано, на плате установлен контроллер РВЕ035. В России он больше известен по названию КР1816ВЕ35, а вообще, это великий и ужасный Intel 8035 серии MSC-48. Первые экземпляры начали производить в 1976, то есть примерно 40 лет назад. В контроллере нет своей памяти для программ, поэтому он общается по внешней шине с ПЗУ, откуда и читает инструкции на выполнение. Зато есть 64 байта ОЗУ, из которых примерно 32 байта можно использовать как угодно, а остальные предназначены для регистров и стека. Есть таймер, есть прерывание от таймера, есть внешнее прерывание, есть система приоритетов. Короче нормальный олдскульный контроллер, не чета жирным PIC'ам. То, что так долго ждали большевики. Сразу захотелось под него что-нибудь закодить.
Но сперва предстояло решить одну трудность, а именно подключить плату. Как видно из схемы, для питания цифровой части требуется просто +5V, а вот для питания индикатора нужно 2,5V и 30V переменного напряжения.
![](https://habrastorage.org/r/w1560/getpro/habr/post_images/144/096/935/144096935a8b8ef29523c4dd1f2911c0.png)
Кстати про индикатор — это же лампа! Да, теплая ламповая радиолампа, а не какие-то там попсовые светодиоды. И как у лампы у нее есть катод анод и сетка. Такой тип индикаторов называется люминесцентно-вакумный индикатор. Немного подумав над схемой, я увидел, что 30В переменки идут на диодный мостик, значит они выпрямляются. И даже 2.5В тоже идут на диоды и после них на сетку, значит они тоже выпрямляются. Значит, можно попробовать подключить плату к постоянному напряжению. Вместо 30V я подал 12V, вместо 2.5V я подал 3.3V со стандартного блока питания формата ATX. Для этого подпаялся проводками к плате. Получилось так:
![](https://habrastorage.org/r/w1560/getpro/habr/post_images/f5e/840/c64/f5e840c646fe5dc119eb55e47e443c58.png)
Но включив плату, я сначала было разочаровался. Некоторые сегменты на дисплее не светились. Сначала я думал, что 12 вольт не достаточно, но потом внимательно осмотрев плату обнаружил непропай в двух местах рядом с индикатором. Прозвонил, пропаял. Плата завелась, на экране появились цифры для установки времени и выбора режима программы. Вот так, хотел выкинуть, а в итоге починил. Настало время жарить.
Я воспользовался свободным кросс-платформенным ассемблером Asm48. Прикольно, что есть версия для MacOS, видимо авторы не обделены чувством юмора, по крайней мере я оценил. Ну значит скачиваем ассемблер, там все просто: ASM48 <имяфайла.asm> Первое, что я сделал, это «поморгал светодиодом», только вместо светодиода я дергал ногу динамика (пьезоэлемента) в бесконечном цикле с задержкой. Динамик подключен к порту 1, старший бит:
Скомпилировав программу и зашив ее на программаторе в ПЗУ 2716, запускаю плату и слышу периодические щелчки с интервалом около секунды. Работает! Теперь предстояло разобраться с экраном. По схеме видно, что «маска» символа ABCDEFG подключена к порту 1. Причем сигнал инвертированный, то есть когда 1 — палочка не горит, когда 0 — горит. Для того, чтобы задать маску буквы «H» посмотрим картинку:
![](https://habrastorage.org/r/w1560/getpro/habr/post_images/a2a/e3f/6c3/a2ae3f6c386940ea43cb597b7382a734.png)
Начинаем обходить букву с G до A, так как здесь обратный порядок следования бит: G закрашена, значит 1; F закрашена, значит 1; E закрашена, значит 1; D не закрашена, значит 0 и тд. В итоге получается: 1110110b. Мы помним, что сигналы инвертированные, поэтому нужно проинвертировать саму маску: not 1110110b = 0001001b. Или 9h. Послав это число в порт 1 мы установим маску для буквы. Сложнее с выбором символа. Здесь применена динамическая индикация. Вкратце суть сводится к тому, что мы постоянно должны задать маску, зажечь первый символ, задать маску, зажечь второй символ и тд. За разрешение свечения символа отвечает второй порт, который с помощью микросхемы m5l8243p расширен до 4-ех четырех битных портов. Для обращения к таким портам служит команда MOVD, а сами порты имеют номера P4, P5, P6, P7. P4 по замыслу авторов отвечает за сканирование клавиатуры, а вот P5 как раз устанавливает один из четырех символов для отображения.
![image](https://habrastorage.org/r/w780q1/getpro/habr/post_images/a84/8a7/fa5/a848a7fa55dc14c3ee627fac500305d9.jpg)
Сперва я пытался сделать динамическую индикацию в основном цикле программы, но потом использовал для этого таймер. А в основном цикле программы меняется буфер индикатора, отображающий с периодичностью в 1 секунду надписи «HELO» и «2014»
Коротенькая видео-демонстрация работы девайса:
Пытливый хабраюзер наверняка заметил баг в конце ролика, когда вместо HELO высветилось не совсем то, что надо. Я его тоже заметил, да. А все потому, что когда в основной программе происходит пересылка в буффер дисплея я забыл остановить таймер. Перед call copy_buf нужно сделать DIS TCNTI а после EN TCNTI. Так то!
Теперь только остается сыграть на девайсе «в лесу родилась елочка» и миссию буду считать удачно завершенной. Всем добра!
1) MCS-48 AND UPI-41 ASSEMBLER LANGUAGE MANUAL 1976
2) 2 том Справочника Шахнова (Микропроцессоры и микропроцессорные комплекты интегральных микросхем)
3) Сташин В.В. и др. — Проектирование цифровых устройств на однокристальных микроконтроллерах
4) Знакосинтезирующие индикаторы: Справочник/ Под ред. В. П. Балашова
5) Быстров Ю.А. Сто схем с индикаторами
![image](https://habrastorage.org/getpro/habr/post_images/bb9/ba6/295/bb9ba6295271fce2fede487a4a3d4d9a.jpg)
Ну железка и железка, подумал я… На плате присутствует микроконтроллер РВЕ035, расширитель IO m5l8243p, ИР12 между РФ5 и контроллером и там еще где-то ЛН1 в стороне болтается. Мне сразу понравилась хорошая раритетная ПЗУ на 2Кб РФ5 в панельке в золоте. Думаю, сниму ее, а остальное смело в утиль, бо вся плата залита лаком по самое небалуйся..А потом все-таки стало интересно, а что это такое вообще?
Выяснилось, что это плата управления от советской микроволновки типа Электроника 23 (aka БУВИ-2 aka Фея aka Днепрянка). В интернете быстро нашлась даже схема девайса: http://www.elremont.ru/small_rbt/bt_rem32.php Теперь, когда стало понятно, что это такое, одна рука уверенно потянулась к мусорке, а другая нечаянно вбила в гугле «РВЕ035» и… И я заинтересовался и внимательно вгляделся в плату. Раз есть контроллер, значит для него можно писать программы. Еще прямо на плате есть какой-никакой экран (4 цифры) куда можно выводить всякие матерные ругательства (BABA, SISI, ну, вы поняли). Так же здесь еще есть пьезоэлемент, а значит можно пищать. Ко всему прочему можно 4x4 клавиатуру подключить. Это же прямо девборда какая-то получается, обрадовался я!
Как уже было сказано, на плате установлен контроллер РВЕ035. В России он больше известен по названию КР1816ВЕ35, а вообще, это великий и ужасный Intel 8035 серии MSC-48. Первые экземпляры начали производить в 1976, то есть примерно 40 лет назад. В контроллере нет своей памяти для программ, поэтому он общается по внешней шине с ПЗУ, откуда и читает инструкции на выполнение. Зато есть 64 байта ОЗУ, из которых примерно 32 байта можно использовать как угодно, а остальные предназначены для регистров и стека. Есть таймер, есть прерывание от таймера, есть внешнее прерывание, есть система приоритетов. Короче нормальный олдскульный контроллер, не чета жирным PIC'ам. То, что так долго ждали большевики. Сразу захотелось под него что-нибудь закодить.
Но сперва предстояло решить одну трудность, а именно подключить плату. Как видно из схемы, для питания цифровой части требуется просто +5V, а вот для питания индикатора нужно 2,5V и 30V переменного напряжения.
![](https://habrastorage.org/getpro/habr/post_images/144/096/935/144096935a8b8ef29523c4dd1f2911c0.png)
Кстати про индикатор — это же лампа! Да, теплая ламповая радиолампа, а не какие-то там попсовые светодиоды. И как у лампы у нее есть катод анод и сетка. Такой тип индикаторов называется люминесцентно-вакумный индикатор. Немного подумав над схемой, я увидел, что 30В переменки идут на диодный мостик, значит они выпрямляются. И даже 2.5В тоже идут на диоды и после них на сетку, значит они тоже выпрямляются. Значит, можно попробовать подключить плату к постоянному напряжению. Вместо 30V я подал 12V, вместо 2.5V я подал 3.3V со стандартного блока питания формата ATX. Для этого подпаялся проводками к плате. Получилось так:
![](https://habrastorage.org/getpro/habr/post_images/f5e/840/c64/f5e840c646fe5dc119eb55e47e443c58.png)
Но включив плату, я сначала было разочаровался. Некоторые сегменты на дисплее не светились. Сначала я думал, что 12 вольт не достаточно, но потом внимательно осмотрев плату обнаружил непропай в двух местах рядом с индикатором. Прозвонил, пропаял. Плата завелась, на экране появились цифры для установки времени и выбора режима программы. Вот так, хотел выкинуть, а в итоге починил. Настало время жарить.
Я воспользовался свободным кросс-платформенным ассемблером Asm48. Прикольно, что есть версия для MacOS, видимо авторы не обделены чувством юмора, по крайней мере я оценил. Ну значит скачиваем ассемблер, там все просто: ASM48 <имяфайла.asm> Первое, что я сделал, это «поморгал светодиодом», только вместо светодиода я дергал ногу динамика (пьезоэлемента) в бесконечном цикле с задержкой. Динамик подключен к порту 1, старший бит:
jmp main
nop
nop
nop
nop
nop
nop
main:
mov r6,#0 ; в регистре r6 - 0 или 80h
forever:
mov a,r6 ; пересылаем из регистра в ALU
xrl a,#080h ; a = a xor 80h
outl p1,a ; выводим в порт 1
mov r6,a ; сохраняем значение в r6
call onesec ; секундная задержка
jmp forever ; бесконечный цикл
;---PROCEDURES
;;;;;;;;
delay100:
mov r1,#84
loopex: mov r2,#236
loopin: djnz r2,loopin
djnz r1,loopex
mov r3,#4
loopad: djnz r3,loopad
ret
;;;;;;;;
onesec:
mov r4,#10
loop_d: call delay100
djnz r4,loop_d
ret
Скомпилировав программу и зашив ее на программаторе в ПЗУ 2716, запускаю плату и слышу периодические щелчки с интервалом около секунды. Работает! Теперь предстояло разобраться с экраном. По схеме видно, что «маска» символа ABCDEFG подключена к порту 1. Причем сигнал инвертированный, то есть когда 1 — палочка не горит, когда 0 — горит. Для того, чтобы задать маску буквы «H» посмотрим картинку:
![](https://habrastorage.org/getpro/habr/post_images/a2a/e3f/6c3/a2ae3f6c386940ea43cb597b7382a734.png)
Начинаем обходить букву с G до A, так как здесь обратный порядок следования бит: G закрашена, значит 1; F закрашена, значит 1; E закрашена, значит 1; D не закрашена, значит 0 и тд. В итоге получается: 1110110b. Мы помним, что сигналы инвертированные, поэтому нужно проинвертировать саму маску: not 1110110b = 0001001b. Или 9h. Послав это число в порт 1 мы установим маску для буквы. Сложнее с выбором символа. Здесь применена динамическая индикация. Вкратце суть сводится к тому, что мы постоянно должны задать маску, зажечь первый символ, задать маску, зажечь второй символ и тд. За разрешение свечения символа отвечает второй порт, который с помощью микросхемы m5l8243p расширен до 4-ех четырех битных портов. Для обращения к таким портам служит команда MOVD, а сами порты имеют номера P4, P5, P6, P7. P4 по замыслу авторов отвечает за сканирование клавиатуры, а вот P5 как раз устанавливает один из четырех символов для отображения.
![image](https://habrastorage.org/getpro/habr/post_images/a84/8a7/fa5/a848a7fa55dc14c3ee627fac500305d9.jpg)
Сперва я пытался сделать динамическую индикацию в основном цикле программы, но потом использовал для этого таймер. А в основном цикле программы меняется буфер индикатора, отображающий с периодичностью в 1 секунду надписи «HELO» и «2014»
Исходный текст программы
;DATA
.equ disp_buf, 030h ; 4 bytes buffer
;;; reset vector
.org 0
dis i ; disable interrupts
jmp main
;;; external interrupt vector--trap
.org 3
jmp $ ; nop
;;; timer interrupt vector
.org 7
sel rb1
mov a,#0d5h
mov t,a
mov a,#00FH
orld p5,a
mov a,disp_buf-1
add a,r5
mov r0,a
mov a,@r0
outl p1,a
mov a,r4
movd p5,a
rl a
mov r4,a
djnz r5,exit_tmr
mov r4,#0feh
mov r5,4
exit_tmr:
sel rb0
mov a,#0d8h
mov t,a
; strt t
retr
;MAIN
main:
;initialize
dis tcnti ; turn off counter
mov r1,#0
mov r5,#0
call copy_buf
sel rb1 ; timer variables
mov r4,#0feh ; 1110h - CT position
mov r5,4 ; R5 = buf offset
sel rb0
mov a,#0e5h
mov t,a
strt t
en tcnti
mov a,#0ffh
movd p6,a
main_loop:
call onesec
mov a,r5
xrl a,#4
mov r5,a
mov r1,a
call copy_buf
jmp main_loop
msg_table:
.db #0c0h ;O
.db #0c7h ;L
.db #086h ;E
.db #089h ;H
.db #099h ;4
.db #0f9h ;1
.db #0c0h ;0
.db #0a4h ;2
;;;;;;;;
delay100:
mov r6,#84
loopex: mov r2,#236
loopin: djnz r2,loopin
djnz r6,loopex
mov r6,#4
loopad: djnz r6,loopad
ret
;;;;;;;;
onesec:
mov r3,#10
loop_d: call delay100
djnz r3,loop_d
ret
;;;;;;;;
;copy from msg_table to display buffer 4 bytes
; R1 = msg_table offset
;;;;;;;;
copy_buf:
mov r0,disp_buf
mov r2,4
copy_lp:
mov a,r1
add a,#msg_table
movp a,@a
mov @r0,a
inc r0
inc r1
djnz r2,copy_lp
ret
Коротенькая видео-демонстрация работы девайса:
Пытливый хабраюзер наверняка заметил баг в конце ролика, когда вместо HELO высветилось не совсем то, что надо. Я его тоже заметил, да. А все потому, что когда в основной программе происходит пересылка в буффер дисплея я забыл остановить таймер. Перед call copy_buf нужно сделать DIS TCNTI а после EN TCNTI. Так то!
Теперь только остается сыграть на девайсе «в лесу родилась елочка» и миссию буду считать удачно завершенной. Всем добра!
Литературка:
1) MCS-48 AND UPI-41 ASSEMBLER LANGUAGE MANUAL 1976
2) 2 том Справочника Шахнова (Микропроцессоры и микропроцессорные комплекты интегральных микросхем)
3) Сташин В.В. и др. — Проектирование цифровых устройств на однокристальных микроконтроллерах
4) Знакосинтезирующие индикаторы: Справочник/ Под ред. В. П. Балашова
5) Быстров Ю.А. Сто схем с индикаторами