Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Аппаратные возможности МК серии STC8H1Kxxx » SPI (Аппаратный и Программный) и Графический дисплей


SPI (Аппаратный и Программный) и Графический дисплей

Сообщений 1 страница 2 из 2

1

Попался на глаза мой любимый дисплей ST7920!
Реализовал программный SPI
И после мелких правок мой старый код, написанный для AVR, заработал!

маш.код, по сравнению с версией для AVR, даже меньше!
Скорость такая, что пришлось раза в 2 замедлять, иначе медленный дисплей на длинных проводах не очень хотел работать!!
В коде указал что тактовая 11мгц, а сам МК настроил на 6 мгц - только тогда заработало без мусора на дисплее.

Оценить скорость не могу: моментально!
Потом как-нибудь соберу две платы рядом: на AVR и на STC и сравню на замедленной скорости воспроизведения :)

https://forumupload.ru/uploads/0000/25/b8/439/t438274.jpg

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)

0

2

Переписал с программного SPI в аппаратный.
Пришлось включать Делитель частоты SPI на 32, иначе при тактовой частоте 11,0952МГц на экране был мусор.
Код стал меньше на 100 байт :)

Код:
$regfile = "STC_8H.DAT"                   ' STC registers list
$crystal = 11059200                       ' CPU clock frequence
$ramsize = 128

$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

'-----------------------------------------
P1ie = &B11111111                         ' 1: Enable digital pins
P1pu = &B00000000                         ' 1: pull-up resistor
P1m0 = &B00101000 : P1m1 = &B00000000     ' output mode


'Графический ЖКИ 128*64 с контроллером ST7920
'Подключено последовательной шиной, вывод 15 (Psb) подключить на минус. Вывод 4 на +5в
P_sw1 = &H00                              'Ss/P1.2, Mosi/P1.3, Miso/P1.4, Sclk/P1.5
'P_sw1 = &h0c                             'SS_4/P3.5, MOSI_4/P3.4, MISO_4/P3.3, SCLK_4/P3.2


' ---  Инициализация ST7920
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$ = "6-05-2024 20:35" : Y_lcd = 6 : X_lcd = 0 : Invers_font = 1 : Gosub Print_lcd
Lcdstr$ = "РОССИЯ, С.ПОСАД" : Y_lcd = 7 : X_lcd = 0 : Gosub Print_lcd

End


'=========================================================
Spi_send:
  Spctl = &B1101_00_11                    'Включаем режим хоста Spi, SYSclk/32
  Spstat = &B1100_0000                    'Снимаем флаги
  Spdat = Temp                            'Отправить Данные
  Bitwait Spstat.7 , Set
Return


'=========================================================
Lcdcommand:                               ' Записать команду -----------------------
  Temp = &B11111000                       ' Команда RW=0 RS=0
  Gosub Spi_send

  Temp = Glcd_data
  Temp = Temp And &B11110000              ' Сбросим 4 бита LSB
  Gosub Spi_send

  Temp = Glcd_data
  Shift Temp , Left , 4 : Temp = Temp And &B11110000       ' Сбросим 4 бита LSB
  Gosub Spi_send
Return

'========================================================
Lcdwrite:                                 ' Записать данные -----------------------
  Temp = &B11111010                       ' данные RW=0 RS=1
  Gosub Spi_send

  Temp = Glcd_data
  Temp = Temp And &B11110000              ' Сбросим 4 бита LSB
  Gosub Spi_send

  Shift Glcd_data , Left , 4              ' Сбросим 4 бита LSB
  Temp = Glcd_data : Temp = Temp And &B11110000       '  младшие 4 бита LSB
  Gosub Spi_send
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"

0


Вы здесь » Программирование ATMEL в BASCOM. » Аппаратные возможности МК серии STC8H1Kxxx » SPI (Аппаратный и Программный) и Графический дисплей