Попался на глаза мой любимый дисплей ST7920!
Реализовал программный SPI
И после мелких правок мой старый код, написанный для AVR, заработал!
маш.код, по сравнению с версией для AVR, даже меньше!
Скорость такая, что пришлось раза в 2 замедлять, иначе медленный дисплей на длинных проводах не очень хотел работать!!
В коде указал что тактовая 11мгц, а сам МК настроил на 6 мгц - только тогда заработало без мусора на дисплее.
Оценить скорость не могу: моментально!
Потом как-нибудь соберу две платы рядом: на AVR и на STC и сравню на замедленной скорости воспроизведения 
bascom 8051 2.0.16.0
$regfile = "STC_8H.DAT" ' STC registers list
$crystal = 11059200 ' CPU clock frequence
$ramsize = &H400 ' 1024
$large
Dim Temp As Byte , Temp2 As Byte
Dim Temp_w As Word
Dim Font_bold As Byte , Invers_font As Byte
Dim Lcd_m As Byte , Lcd_lf As Byte , Lcd_rt As Byte , Glcd_data As Byte , Lcd_cnt As Byte
Dim Lcdstr$ As String * 16
Dim Simvol_1$ As String * 1 , Simvol_2$ As String * 1
Dim Lcd_w1 As Word , Lcd_w2 As Word
Dim Lcdx As Byte , Lcdy As Byte , X_lcd As Byte , Y_lcd As Byte , Lcd_temp As Byte
'Графический ЖКИ 128*64 с контроллером ST7920
'Подключено последовательной шиной, вывод 15 (Psb) подключить на минус. Вывод 4 на +5в
Sid_glcd Alias P3.5 ' 16 : Config Sid_glcd = Output ' data
Sclk_glcd Alias P3.4 ' 15 : Config Sclk_glcd = Output ' clock
P3ie = &B11001111 ' 1: Enable digital signal input
P3m1 = 0 : P3m0 = &B00110000 ' Push-pull output mode
P3pu = &B00000000 ' 1: pull-up resistor
' --- Инициализация ST7920
Sclk_glcd = 0 : Sid_glcd = 0
Waitms 100 ' обязательно
Glcd_data = &B00110100 : Gosub Lcdcommand ' EXTENDEN instruction
Glcd_data = &B00110000 : Gosub Lcdcommand ' GRAGIC display Off
Glcd_data = &B00000110 : Gosub Lcdcommand ' Entry Mode Set
Glcd_data = &B00001100 : Gosub Lcdcommand ' Выкл Курсор и мигание символа
Glcd_data = &B00000001 : Gosub Lcdcommand ' Clear Text Display
Waitms 3
Glcd_data = &B00110100 : Gosub Lcdcommand ' EXTENDEN instruction
Glcd_data = &B00110110 : Gosub Lcdcommand ' GRAGIC display On
' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Gosub Lcdimgcls ' очистка графической памяти ЖКИ
Lcdstr$ = "ПРИВЕТИК ВСЕМ!" : Y_lcd = 0 : X_lcd = 0 : Gosub Print_lcd
Lcdstr$ = "ПРОВЕРКА ST-7920" : Y_lcd = 2 : X_lcd = 0 : Font_bold = 1 : Gosub Print_lcd
Lcdstr$ = "MCU: STC8H1K08" : Y_lcd = 4 : X_lcd = 0 : Font_bold = 1 : Gosub Print_lcd
Lcdstr$ = "НУ ОЧЕНЬ БЫСТРО!" : Y_lcd = 5 : X_lcd = 0 : Gosub Print_lcd
Lcdstr$ = "29-04-2024 23:45" : Y_lcd = 6 : X_lcd = 0 : Invers_font = 1 : Gosub Print_lcd
Lcdstr$ = "РОССИЯ, С.ПОСАД" : Y_lcd = 7 : X_lcd = 0 : Gosub Print_lcd
End
'=========================================================
Lcdcommand: ' Записать команду -----------------------
Temp = &B11111000
Shiftout Sid_glcd , Sclk_glcd , Temp , 1 ' Команда RW=0 RS=0
Temp = Glcd_data
Temp = Temp And &B11110000 ' Сбросим 4 бита LSB
Shiftout Sid_glcd , Sclk_glcd , Temp , 1 ' передаём
Temp = Glcd_data
Shift Temp , Left , 4 : Temp = Temp And &B11110000 ' Сбросим 4 бита LSB
Shiftout Sid_glcd , Sclk_glcd , Temp , 1 ' передаём
Return
'========================================================
Lcdwrite: ' Записать данные -----------------------
Temp = &B11111010 : Shiftout Sid_glcd , Sclk_glcd , Temp , 1 ' данные RW=0 RS=1
Temp = Glcd_data
Temp = Temp And &B11110000 ' Сбросим 4 бита LSB
Shiftout Sid_glcd , Sclk_glcd , Temp , 1 ' передаём
Shift Glcd_data , Left , 4
Temp = Glcd_data : Temp = Temp And &B11110000 ' Сбросим 4 бита LSB
Shiftout Sid_glcd , Sclk_glcd , Temp , 1 ' передаём младшие 4 бита LSB
Return
'======================================================================
Print_lcd: ' по вертикали 0-7 симв., по гориз.- 0-7 блоков
' Преобразуем номера позиции в физический адрес памяти ЖКИ
If Y_lcd > 3 Then ' нижняя половина ЖКИ
X_lcd = X_lcd + 8
Y_lcd = Y_lcd - 4
End If
Lcdx = X_lcd + 128
Y_lcd = Y_lcd * 8 : Y_lcd = Y_lcd + 128
Temp2 = Len(lcdstr$)
For Lcd_cnt = 1 To Temp2
Simvol_1$ = Mid(lcdstr$ , Lcd_cnt , 1) : Lcd_m = Asc(simvol_1$) -32 ' До "пробела" нет символов
If Lcd_m > 159 Then Lcd_m = Lcd_m - 101 ' Убрали из таблицы маленькие английские и русские
Lcd_w1 = Lcd_m * 8 ' Адрес левого символа
Incr Lcd_cnt
Simvol_2$ = Mid(lcdstr$ , Lcd_cnt , 1) : Lcd_m = Asc(simvol_2$) -32
If Lcd_m > 159 Then Lcd_m = Lcd_m - 101 ' Убрали из таблицы маленькие английские и русские
Lcd_w2 = Lcd_m * 8 ' Адрес правого символа
Lcdy = Y_lcd
For Lcd_temp = 0 To 7 ' 8 по вертикали
Lcd_lf = Lookup(lcd_w1 , Shrift_8x8)
If Font_bold = 1 Then ' делаем символы жирными - копируем точку правее
Lcd_m = Lcd_lf : Shift Lcd_m , Right , 1
Lcd_lf = Lcd_lf Or Lcd_m
End If
If Invers_font = 1 Then Lcd_lf = 255 - Lcd_lf ' Инверсия символа и фона
Lcd_rt = Lookup(lcd_w2 , Shrift_8x8)
If Font_bold = 1 Then ' делаем символы жирными - копируем точку правее
Lcd_m = Lcd_rt : Shift Lcd_m , Right , 1
Lcd_rt = Lcd_rt Or Lcd_m
End If
If Invers_font = 1 Then Lcd_rt = 255 - Lcd_rt ' Инверсия символа и фона
' левая половина блока - Lf, правая половина блока = Rt
Glcd_data = Lcdy : Gosub Lcdcommand
Glcd_data = Lcdx : Gosub Lcdcommand ' X=16 16 точек по горизонтали
Glcd_data = Lcd_lf : Gosub Lcdwrite
If Simvol_2$ <> "" Then
Glcd_data = Lcd_rt
Gosub Lcdwrite
End If
Incr Lcdy
Incr Lcd_w1 : Incr Lcd_w2
Next
Incr Lcdx
Next
Font_bold = 0
Invers_font = 0
Return
'=========================================================
Lcdimgcls: ' -- Очистка графической памяти ST7920 --
Lcd_m = 0
For Lcdx = &H80 To &H8F
For Lcdy = &H80 To &H9F
Glcd_data = Lcdy : Gosub Lcdcommand
Glcd_data = Lcdx : Gosub Lcdcommand
Glcd_data = 0 : Gosub Lcdwrite
Glcd_data = Lcd_m : Gosub Lcdwrite
Next
Next
Return
'=========================================================
$include "font-8x8_big_eng_rus.inc"
Отредактировано Александр Д. (2024-04-30 00:05:06)
