Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

8051, ассемблер, HD44780. Чтение Busy Flag

Вс окт 20, 2019 16:49:52

Подключил к МК AT89C1051U экран на основе HD44780, и пытаюсь им управлять в 4-битном режиме. DВ4-DB7 экрана подключены к P1.0-P1.3 MK, RS - P3.7 R/W - P3.4; E- P3.5. Все выводы подтянуты к плюсу резисторной сборкой на 1К, т.к выходы МК с открытым коллектором.
Делал по даташиту, и в общем, получилось. Но я использую программные задержки, которые заведомо дольше чем возможная занятость контроллера экрана. На одном форуме прочитал, что так делать неправильно, а правильно ждать пока экран снимет Busy Flag. Но, ничего не получилось, по крайней мере так, как я придумал.
Код:
check_busy:
setb bf_pin ; убеждаемся что P1.3 (DB7 экрана) - вход
clr rs_pin ;RS=0, выбран Instruction Register экрана
setb rw_pin ;Читаем из экрана
loop:
call en_toggle ;вызываем подпрограмму выдачи такта на Е
jb bf_pin, loop ;проверяем, не прижал ли экран DB7 к корпусу. Если нет, сначала
clr rw_pin
setb rs_pin ;Data Register
ret ;досвидос


Вызываю как подпрограмму с того места, где должна быть программная задержка.
Но реальный экран молчит, а в протеусе пишет ошибку, что читаю из занятого экрана. Что-то делаю не так, но что - не пойму, прошагать программу вместе с экраном не получается.
Как правильно прочитать этот BF, и вообще, как выглядит последовательность действий?

Re: 8051, ассемблер, HD44780. Чтение Busy Flag

Пн окт 21, 2019 14:30:47

Библиотека из старого проекта
Спойлер
Код:
;
;         "wh1602.txt" ; файл утилит работы с дисплеем
;
 rdbfadr:   ; чтение BF и текущего адреса позиции курсора
   mov P0,#0xFF
   mov P2,#0b01011111
 pt_wh0:
   nop
   mov P2,#0b01111111
   nop
    mov a,P0
    mov P2,#0b11011111
   nop
  ret
;----------
 rddat:
   mov P0,#0xFF ; чтение данных по текущему адресу
   mov P2,#0b11011111
  sjmp pt_wh0
;----------
 wrdat:
   mov P0,#0xFF ; запись данных по текущему адресу
   mov P2,#0b10011111
   nop
   mov P0,a
    nop
     mov P2,#0b10111111
      nop
      mov P2,#0b10011111
  pt_wh1:
      nop
     mov P0,#0xFF
    nop
   mov P2,#0b11011111
  ret
;----------
 wrslus:
   mov P0,#0xFF ; запись слова управления
   mov P2,#0b00011111
   nop
   mov P0,a
    nop
     mov P2,#0b00111111
     nop
    mov P2,#0b00011111
   sjmp pt_wh1
;----------
 wait_wrt:
   acall rdbfadr
    jbc ACC.7,wait_wrt ; ждать BF=0
  ret
;----------
;----------
    ; печать строки сообщения в frame строке дисплея
    ; адрес сообщения в DPTR адрес вывода = refram+frame (refram+r0)
    ; курсор невидимый с автодекрементом адреса, дисплей неподвижен
;
 prints_1:
    mov a,#0b00001100 ; курсор невидимый
    acall wrslus
    acall wait_wrt
     mov a,#0b00000110 ; курсор с автоинкрементом адреса, дисплей неподвижен
    acall wrslus
    acall wait_wrt
    mov a,refram
    add a,r0 ; получить адрес начала текущего окна вывода
    setb ACC.7
    acall wrslus ; установить курсор на первую позицию текущего окна вывода
    acall wait_wrt
    push DPL
    push DPH
    mov DPL,r3
    mov DPH,r4 ; указатель начала символьной строки в ПЗУ размещен в DPTR
    mov r2,#0x10
    mov r1,#0 ; смещение относительно адреса начала символьной строки в ПЗУ
  pt_prt0:
      mov a,r1
      movc a,@a+dptr
       acall wrdat ; грузим ОЗУ строки дисплея из строки символов ПЗУ
        acall wait_wrt
       inc r1
      djnz r2,pt_prt0
    pop DPH
    pop DPL
    ret
;----------
    ; печать строки сообщения в frame строке дисплея
    ; адрес сообщения = bufos_0 адрес вывода = refram+frame (refram+r0)
    ; курсор невидимый с автодекрементом адреса, дисплей неподвижен
    ; по завершении курсор в виде мерцающего знакоместа размещен по
    ; адресу из kursadr
;
 printb_1:
    mov a,#0b00001100 ; курсор невидимый
    acall wrslus
    acall wait_wrt
     mov a,#0b00000110 ; курсор с автоинкрементом адреса, дисплей неподвижен
    acall wrslus
    acall wait_wrt
    mov a,refram
    add a,r0 ; получить адрес начала текущего окна вывода
    setb ACC.7
    acall wrslus ; установить курсор на первую позицию текущего окна вывода
    acall wait_wrt
    mov r1,#bufos_0 ; указатель на начало буфера ОЗУ спецфункций
    mov r2,#0x10
  pt_prt1:
       mov a,@r1
        acall wrdat ; грузим ОЗУ строки дисплея из буфера ОЗУ спецфункций
        acall wait_wrt
       inc r1
      djnz r2,pt_prt1
     mov a,kursadr ; восстановить позицию курсора из ранее записанной в kursadr
     setb ACC.7
     acall wrslus
    acall wait_wrt
    mov a,#0b00001111 ; курсор в виде мерцающего знакоместа
    acall wrslus
    acall wait_wrt
    ret
;----------
 l40:
     mov r0,#bufos_0
     mov r1,#0
     mov r2,#16
   l40_1:
        mov a,r1
            movc a,@a+dptr ; /в данный момент включен dptr1 !!!/
        mov @r0,a
        inc r0
        inc r1
      djnz r2,l40_1
;     sdptr 0 ; включить dptr0
    ret
 ;----------

правда там байтовый интерфейс был...
:sleep:
Ответить