Вторая попытка доступа к индикатору МК-152: неуспешна.

Записал в ПЗУ W78test2.bin, запуск МК-152 показал себя никак. ИЧСХ, симптомы те же самые. При первом включении весь экран тёмный. При втором и последующих — полностью светлый.

; Тест № 2. Проверка W78E516D-PG в «Электронике МК-152»
; Исследовательская задача № 1. Открыть доступ к индикатору МЭЛТ MT-12864J

; W77LE516P работает на частоте 22,1184 МГц.
; Один такт W77LE516P составляет 45,2112 нс.
; 1 цикл = 12 тактов = 542,535 нс

; Задержка  1 мкс =  1000 нс =  22 такта
;       a3              INC     DPRT            ; 24 такта = 1,085 мкс или
;       00 00           NOP, NOP                ; 24 такта

; Задержка  8 мкс =  8000 нс = 177 такт
; При n=7 задержка 12+24*7 = 180 тактов = 8,138 мкс
;       7b 07           MOV     R3,#07          ; 12 тактов
; dely: db fe           DJNZ    R3,dely         ; 24*n тактов

; Задержка 10 мкс = 10000 нс = 221 такт
; При n=9 задержка 12+24*9 = 228 тактов = 10,308 мкс
;       7b 09           MOV     R3,#09          ; 12 тактов
; dely: db fe           DJNZ    R3,dely         ; 24*n тактов
;

; ------------ Порты
;    DISP_PORT          EQU     0xB100
;    DISP_RST           EQU     P1.1    ; регистр 90H (SFR P1), маска 02H, бит 91H (T2EX)
;    DISP_RW            EQU     P2.1    ; регистр a0H (SFR P2), маска 02H, бит a1H (A9)
;    DISP_E1            EQU     P2.6    ; регистр a0H (SFR P2), маска 40H, бит a6H (A14)
;    DISP_E2            EQU     P2.0    ; регистр a0H (SFR P2), маска 01H, бит a0H (A8)
;    DISP_A0            EQU     P2.2    ; регистр a0H (SFR P2), маска 04H, бит a2H (A10)
;    DISP_E             EQU     P4.1    ; регистр d8H (SFR P4), маска 02H
;
; ------------ Команды (Таблица 3 из datasheet)
;    SetDisplayOn       0x3F            ; 11'1111b
;    SetDisplayOff      0x3E            ; 11'1110b
;    SetStartLine       (0xC0 or (0x3F and StartLine))
;    SetPage            (0xB8 or (0x07 and Page))
;    SetAddres          (0x40 or (0x3F and Address))
;

; Переход за пределы таблицы прерываний
0000+   02 00 70        LJMP start
0003+   32              RETI                    ; заблокировать прерывание
000B+   32              RETI                    ; заблокировать прерывание
0013+   32              RETI                    ; заблокировать прерывание
001B+   32              RETI                    ; заблокировать прерывание
0023+   32              RETI                    ; заблокировать прерывание
002B+   32              RETI                    ; заблокировать прерывание
0033+   32              RETI                    ; заблокировать прерывание
003B+   32              RETI                    ; заблокировать прерывание
0043+   32              RETI                    ; заблокировать прерывание
004B+   32              RETI                    ; заблокировать прерывание
0053+   32              RETI                    ; заблокировать прерывание
005B+   32              RETI                    ; заблокировать прерывание
0063+   32              RETI                    ; заблокировать прерывание

start:
; Сбросить прерывания IE.0-IE.6 и особенно IE.7 (адрес A8)
0070+   75 a8 00        MOV     IE,#00          ; Обнулить регистр a8H (IE)

; Установить P4 в mode 0 -- регистры c2H (P4CONA) и c3H (P4CONB)
0073+   75 c2 00        MOV     P4CONA,#00
0076+   75 c3 00        MOV     P4CONB,#00

; Обнулить P4.0 P4.1 P4.2 P4.3 -- регистр d8H
; Выбираем индикатор
; Подать единицу на P4.1 -- регистр d8H (SFR P4), записать 02
0079+   75 d8 02        MOV     P4,#02

;
; Для  начальной установки модуля необходимо подать сигнал RES
; равный  логическому  «0»  длительностью не менее 1 мкс. При этом
; модуль выполняет команды установки Display Start Line в 0,
; DisplayOff.  После деактивации  сигнала  RES (переключения в
; логическую  «1» с временем  фронта  не более 200  нс) необходимо
; дождаться сброса битов BUSY и  RESET в регистре состояния обоих
; кристаллов или выдержать паузу не менее 10  мкс. После этого
; модуль нормально функционирует. Чтение статуса можно выполнять
; даже при активном сигнале RES (равном логическому «0»).
;
; --- Cброс индикатора

;    Clr     DISP_RST
007c+   c2 91           CLR     91              ; сбросим бит 91H = T2EX = P1.1 = DISP_RST

;    Delay   1
007e+   a3              INC     DPTR            ; задержка 1,085 мкс

;    Set     DISP_RST
007f+   d2 91           SETB    91              ; установим бит 91H = T2EX = P1.1 = DISP_RST

;    Delay   10
0081+   7b 09           MOV     R3,#09
0083+   db fe           DJNZ    R3,$-2          ; задержка 10,308 мкс

;
; Выбираем 1-й кристалл, левую половину отображаемого поля точек
; E1=1
; E2=0
;
0085+   c2 a0           CLR     a0              ; сбросим бит a0H = A8 = P2.0 = DISP_E2
0087+   d2 a6           SETB    a6              ; установим бит a6H = A14 = P2.6 = DISP_E1

;
; Чтение (запись) информации из (в) модуль осуществляется по страницам
; (64х8 бит или 64х1 байт). Каждая страница представлена как 64 байта.
; Для чтения или записи байта данных по произвольному адресу необходимо
; предварительно установить страницу ОЗУ и установить адрес внутри
; страницы ОЗУ. Это осуществляется командами «Set Page» и «Set Address»
; соответственно. После этого можно прочитать или записать байт данных.
; В режиме чтения данных после команд «Set Page» и «Set Address» необходимо
; однократно выполнить «пустую» операцию чтения, результат которой не
; использовать.
; Модуль поддерживает непрерывную последовательность операций чтения или
; записи: после чтения (записи) одного байта счетчик адреса автоматически
; увеличивается  на 1 и  модуль  готов  к  новой  операции  чтения (записи)
; по  следующему  адресу  без  предварительной  установки  страницы ОЗУ и
; адреса. Счетчик  адреса считает  только  внутри  одной  страницы!
; При  достижении  адреса  63  следующим  значением  счетчика  будет 0 и т.д.
; Между любыми двумя передачами данных или команд, необходимо выдержать
; паузу не менее 8 мкс. Или ожидать сброса флага BUSY в регистре состояния
; того кристалла, к которому будет обращение.
;
; --- Запись байта 0xAA в начало экранного ОЗУ

;       Clr                     DISP_A0
;       Clr                     DISP_RW
0089+   c2 a2           CLR     a2              ; сбросим бит a2H = A10 = P2.2 = DISP_A0
008b+   c2 a1           CLR     a1              ; сбросим бит a1H = A9 = P2.1 = DISP_RW

008d+   90 b1 00        MOV     DPTR,#b100      ; Адрес b100H в DPTR

;       SetDisplayOn
;       Delay                   8

0090+   74 3f           MOV     A,#3f           ; SetDisplayOn
0092+   f0              MOVX    @DPTR,A         ; Отдать команду МЭЛТ MT-12864J
0093+   7b 07           MOV     R3,#07          ; задержка 8,138 мкс
0095+   db fe           DJNZ    R3,$-2

;       SetPage                 0
;       Delay                   8

0097+   74 b8           MOV     A,#b8           ; SetPage 0
0099+   f0              MOVX    @DPTR,A         ; Отдать команду МЭЛТ MT-12864J
009a+   7b 07           MOV     R3,#07          ; задержка 8,138 мкс
009c+   db fe           DJNZ    R3,$-2

;       SetAddres               0
;       Delay                   8

009e+   74 40           MOV     A,#40           ; SetAddres 0
00a0+   f0              MOVX    @DPTR,A         ; Отдать команду МЭЛТ MT-12864J
00a1+   7b 07           MOV     R3,#07          ; задержка 8,138 мкс
00a3+   db fe           DJNZ    R3,$-2

;       Set                     DISP_A0

00a5+   d2 a2           SETB    a2              ; установим бит a2H = A10 = P2.2 = DISP_A0

;       Write                   DISP_PORT       0xAA
;       Delay                   8

00a7+   74 aa           MOV     A,#aa           ; Битовая картинка aaH
00a9+   f0              MOVX    @DPTR,A         ; Записать байт в МЭЛТ MT-12864J
00aa+   7b 07           MOV     R3,#07          ; задержка 8,138 мкс
00ac+   db fe           DJNZ    R3,$-2

;
; Конец выбора индикатора
; Обнулить P4.0 P4.1 P4.2 P4.3 -- регистр d8H (SFR P4), записать 00
00ae+   75 d8 00        MOV     P4,#00

stop:
00b1+   80 fe           SJMP    stop             ; перейти на stop
00b3    ff
; конец

В документации написано, что E является стробом. Не нужно ли дёргать P4.1 туда-сюда каждый раз после того, как записываешь в индикатор по адресу b100H команду/данные?

Также мы начали использовать P1 и P2. Возможно, их стоит настроить перед использованием. Переключив, например, в нужный режим. Меня удивляет, что индикатор различно себя ведёт после первого и после второго включения питания МК-152. Это может означать, что даже начальная установка индикатора не выполняется.

Ещё есть идея, что P2 потому и подключён к индикатору, что через него выводится старший байт адреса b1H = 1011'0001b — если это так, программно дёргать биты P2 нет необходимости, это сделает команда MOVX автоматически. В этом случае потребуется лишь подобрать адреса, по которым MOVX будет обращаться к индикатору.

Undefined

Комментарии

Я как раз прокомментировал про строб данных Е, не видел этого поста. Посмотри еще раз обновленный псевдокод

---------------------------
Истина где-то рядом
www.litres.ru/vitaliy-samurov/dozvonitsya-do-devy/

Следующей ночью попробую дёргать строб. Но не проходит ощущение, что занимаемся ерундой.

Где в схемотехнике отражён порт b100 ? Моё предположение, что это и есть сигналы с P2, куда выводится старшая часть адресной шины (A8…A15). Больше же этот адрес никуда не выводится, только в P2.

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

По поводу строба. Команда MOVX используется также для записи в ОЗУ DD10. Обращение к индикатору не должно менять содержимое ОЗУ. Если DD10 выбирается при нулях в P4.0…P4.3 — как бы дёрганье строба P4.1 не приводило к активации ОЗУ.

Возможно, за это отвечает адресная линия A15. И именно поэтому у нас b100, а не 3100.

Ну и последняя мысль. P2 и P0 используют дефицитные ножки кристалла, у которых своя временная диаграмма. Сигналы, которые мы сейчас устанавливаем и сбрасываем, висят на этих ножках не всегда (для такого их необходимо буферизировать), а только в некоторые фазы машинного цикла.

В некоторых фазах там адрес A8…A15, если выполняется команда MOVX. В других фазах там P2.0…P2.7, которые мы сейчас вручную дёргаем. Интересно, дёргается ли строб P4.1 самостоятельно камнем или висит там всегда, никогда не меняясь в течении машинного цикла?

P0 используется, как шина данных. Но туда же, надо это перепроверить, идут младшие биты адресной шины.

То есть в момент, когда мы обращаемся к b100 и старший байт адреса в P2 выбирает нужный набор команд индикатора, "шина данных" может содержать младший байт этого адреса.

Итого команда вывода байта AA может выглядеть, как запись чего угодно по адресу вроде b1aa. Это всё реально отследить по схеме, какое из предположений верно?

Есть предложение по регламенту, перенести эту и предыдущую записи на форум, если не будет возражений. Форум - для предварительных обсуждений, блог - для готовых статей.

Технически это и есть блог, запись экспериментов с обсуждениями каждого. И работы тут на пару лет, устройств внутри МК-152 много. Одна файловая система чего стоит!

Можно эти две записи в моём блоге оставить, а дальше я переведу исследование в livejournal, где проще отслеживать, к какому ответу какой комментарий идёт?

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

Файловая система в современном мире ничего не стоит, они идёт из коробки :-)
Насчёт обсуждения и экспериментов, согласен, всякой всячины минимум на пару лет, и не только в МК-152. Возникают вопросы расковыривания прошивки HP 48-50g, как они решали разные вопросы от управления памятью до принципов опроса клавиатуры. В МК-1XX ещё не исследован вопрос замены контроллера на какой нибудь современный, например через специальный переходник типа
https://www.ebay.com/itm/PLCC44-PLCC44-Connector-for-programmer-8051-emu...

ну или

https://www.chipdip.ru/product/pomona-5281

для отладки ещё хорошо смотрится

http://www.isystem.com/files/products/InCircuit/8051/IC10020adapterT_PLC...

Если сверху прицепить этот переходник к какому нибудь контроллеру, который будет связан с компом, то как минимум вы прямо с компьютера могли бы прозванивать всю периферию МК-1XX !!!
А в идеале надо вообще выкинуть этот убогий 8052 и воткнуть туда нормальный микроконтроллер, типа STM32.

Кстати я не стал его покупать там, потому что увидел, что используются обычные ноги от гребёнки PLS. Следовательно можно напечатать на 3D принтере шаблон куда вставить эти ноги, и получится такой же переходник.

Выбор большой.

Файловую систему можно взять из МК-152 путём обратной разработки — она недокументирована. Также можно реализовать зарубежную, хотя бы и FAT. Многие, к счастью, документированы. Есть файловые системы у сообщества свободных программ, лицензионно чистые. Можно реализовать фортовские «блоки» напрямую в секторах — они уже работают в Каллисто поверх файловой системы ЭКВМ.

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


Схема взята из МК-152. Делал на АВР, потому что есть все среды разработки под него.
Вот вам обращение к индикатору по шине. Должно подойти. По крайней мере схема включения идентичная к МК-152. Адреса теже.

void MT12864_Reset(void)
{	u8*p=(u8*)0xc300;
	/*PORTC=0xC3;
	PORTC=0x00;*/
	*p=2;
	WAIT20uS;
}
 
//==========================================================
//Чтенние байта с модуля MT12864
// In- 	cs-chip select number
//			cd-command(0)/data(1) 
//Out-	value
u8 MT12864_RDByte(u8 cs, u8 cd)
{	u8 d;
	u8*p;
	DDRA=0;
	PORTA=0xff;
	if(cs==0)
		p=(u8*)0xb600;
	else
		p=(u8*)0xba00;
	p+=(cd<<8);
	d=*p;
	return d;
}
 
//==========================================================
//Запись байта в модуль MT12864
// In- 	cs-chip select number
//			cd-command(0)/data(1) 
//			d-data
void MT12864_WRByte(u8 cs, u8 cd, u8 d)
{	u8 *p;
	if(cs==0)
		p=(u8*)0xb400;
	else
		p=(u8*)0xb800;
	p+=(cd<<8);
	*p=d;
}
 
u8 MT12864_ReadSTATUS(u8 cs)
{	return MT12864_RDByte(cs, 0);
}
 
void MT12864_WriteCMD(u8 cs, u8 cmd)
{
}
 
C_task void main(void)
{	u8 i;
	u8 d[2],t;
	SysTimer=1;
	Init();
	//i2cInit();
	MT12864_Reset();
	MT12864_WRByte(0, 0, 0x3f);
	MT12864_WRByte(1, 0, 0x3f);
	d[0]=MT12864_ReadSTATUS(0);
	d[1]=MT12864_ReadSTATUS(1);
 
	MT12864_WRByte(0, 0, 0xb8);
	MT12864_WRByte(1, 0, 0xb8);
	for(i=0;i<64;i++)
	{	MT12864_WRByte(0, 1, i);
		MT12864_WRByte(1, 1, 64-i);
	}
 
	MT12864_WRByte(0, 0, 0xb9);
	for(i=0;i<64;i++)
		MT12864_WRByte(0, 1, Text[i]);
 
	MT12864_WRByte(1, 0, 0xbe);
	for(i=0;i<64;i++)
		MT12864_WRByte(1, 1, Text[i]);
 
	MT12864_WRByte(0, 0, 0xbf);
	MT12864_WRByte(1, 0, 0xbf);
	for(i=0;i<64;i++)
	{	MT12864_WRByte(0, 1, 64-i);
		MT12864_WRByte(1, 1, i);
	}
 
	while(1)
	{__watchdog_reset();
		if(SEC)
		{
		}
		if((SS100/10)!=i)
		{	ProcessUI(0xff);
			i=SS100/10;
		}
		if(Key!=0xff)
		{	ProcessUI(GetKey());
			ProcessUI(0xff);
		}
		__sleep();
	}//while(1)
}

Да, еще, в МК-152 порт P4 не используется для адресации индикатора. Только в МК-161, насколько я помню.

попробовать это в 161й.

---------------------------
Истина где-то рядом
www.litres.ru/vitaliy-samurov/dozvonitsya-do-devy/