News:

Let's find out together what makes a PIC Tick!

Main Menu

ST7920 display with 18F25K20 using SPI control

Started by broderic, May 15, 2021, 02:17 PM

Previous topic - Next topic

broderic

Hello See_Mos.
In January, in old forum, you posted this piece of code:

' ST7920 display with 18F25K22 using SPI control
' Print At 1,x = $80 + x
' Print at 2,x = $90 + x
' Print At 3,x = $88 + x
' Print At 4,x = $98 + x


Include "Amicus18.inc"       
Include "18F25K22 Intosc 64.inc"
Include "Amicus18_SPI.inc"


' same port connections as SPI
Dim LCD_CS_Pin As PORTC.0               ' Brown pin 4 RS or CS (enable)
Dim LCD_Data_Pin As PORTC.5             ' Green pin 5 RW = data read / write
Dim LCD_Clock_PIn As PORTC.3            ' Yellow pin 6 E or clock
Dim LCD_RST_Pin As PORTC.1              ' Red pin 17 RST reset
Dim I As Byte


Symbol LCD_Data                = 1       ' Data Bit
Symbol LCD_Control             = 0       ' Control Bit
Symbol LCD_CLEAR_SCREEN        = 0x01    ' Clear screen
Symbol LCD_ADDRESS_RESET       = 0x02    ' The address Counter is Reset
Symbol LCD_BASIC_FUNCTION      = 0x30    ' Basic instruction Set
Symbol LCD_EXTEND_FUNCTION     = 0x34    ' Extended instruction Set


Start:                                 
    DelayMS 50
    OpenSPI(SPI_FOSC_64,MODE_01,SMPMID)   
    TRISC = $E0   
    Low LCD_CS_Pin                      ' RS pin on display
 
Init:
    LCD_RST_Pin = 0
    DelayUS 100
    LCD_RST_Pin = 1
   
    ST7920_Write(LCD_Control, LCD_BASIC_FUNCTION)   ' Function set
    ST7920_Write(LCD_Control, LCD_CLEAR_SCREEN)     ' Display clear
    ST7920_Write(LCD_Control, 0x06)                 ' Entry mode set
    ST7920_Write(LCD_Control, 0x0C)                 ' Display control
                                                    ' display On, Cursor off, blink off
    ST7920_Write(LCD_Control, 0x80)                 ' start address to write data to RAM
   
    For I = 65 To 75                                ' write A to K to LCD
    ST7920_Write(LCD_Data,I)
    Next
    DelayMS 2000
    Cls


    While 1 = 1
    Print At 1,1, 56
     Wend
   
Proc ST7920_Write(P_Control As Bit,P_DATA As Byte)
    OpenSPI(SPI_FOSC_64,MODE_01,SMPMID)
    High LCD_CS_Pin
   
    If P_Control = True Then            ' true = data, false = Control
        WriteSPI($FA)                   ' byte 2 set up for data
    Else
        WriteSPI($F8)                   ' byte 2 set up for control
    EndIf
    DelayMS 1
    WriteSPI(P_Data & $F0)              ' send byte 1
    DelayMS 1
    WriteSPI(P_Data & $0F <<4)          ' send byte 0   
   
    Low LCD_CS_Pin
'    CloseSPI()
EndProc

I tried to run it on my Amicus18, but I had no success.
Where's the print command to display character on the screen ?

And also I didn't find the "18F25K22 Intosc 64.inc".

Thank you in advance for any kind suggestion.

Regards.

broderic

Hello.
Starting from See_Mos example code for text, I added some graphics with the help of some C codes in the web (don't know if in an efficient way...).
'****************************************************************
'*  Name    : ST7920 SPI mode text and graphic example.bas      *
'*  Author  : changes to See_Mos _wellyboot codes               *
'*            and translation of C codes in web _eli.rodriguez  *
'*  Notice  : Copyright (c) 2020 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 22/05/2021                                        *
'*  Version : 1.0                                               *
'*  Notes   : ST7920 display with Amicus18 using SPI control.   *
'*          : Draws text, pixel, line and circle.               *
'****************************************************************
Include "Amicus18.inc"       
Include "Amicus18_SPI.inc"
Dim LCD_CS_Pin          As PORTC.0      ' Pin 4 RS or CS (enable)
Dim LCD_Data_Pin        As PORTC.5      ' Pin 5 RW = data read / write
Dim LCD_Clock_PIn       As PORTC.3      ' Pin 6 E or clock
Dim LCD_RST_Pin         As PORTC.1      ' Pin 17 RST reset
Dim glcd[512] As Word
Dim k As Byte
Dim P As Byte
Dim a As Byte
Dim b As Byte
Dim i        As Byte
Dim instr    As Byte                 'instruction to send
Dim sdata    As Byte                 'data to send
Dim count    As Byte                 'gen purpose counter
Dim v As Byte
Dim h    As Byte                     'data to send
Dim r    As Byte                     'gen purpose counter
Dim chard As Word
Dim horcount    As Byte
Dim c As Word
Dim lcdtemp As Word
Symbol LCD_Data                = 1       ' Data Bit
Symbol LCD_Control             = 0       ' Control Bit
Symbol LCD_CLEAR_SCREEN        = 0x01    ' Clear screen
Symbol LCD_ADDRESS_RESET       = 0x02    ' The address Counter is Reset
Symbol LCD_BASIC_FUNCTION      = 0x30    ' Basic instruction Set
Symbol LCD_EXTEND_FUNCTION     = 0x34    ' Extended instruction Set
Dim dy As Word
Dim dx As Word
Dim addx As Byte
Dim addy As Byte
Dim yerr As SWord
Dim diff As Word

Start:                                 
    DelayMS 50
    OpenSPI(SPI_FOSC_64,MODE_01,SMPMID) 
    TRISC = $00   
    Low LCD_CS_Pin
                         
Init:
    LCD_RST_Pin = 0
    DelayUS 100
    LCD_RST_Pin = 1
    ST7920_Write(LCD_Control, LCD_BASIC_FUNCTION)   ' Function set
    ST7920_Write(LCD_Control, LCD_CLEAR_SCREEN)     ' Display clear
    ST7920_Write(LCD_Control, 0x06)                 ' Entry mode set
    ST7920_Write(LCD_Control, 0x0C)                 ' Display control
    ST7920_Write(LCD_Control, 0x80)                 ' start address to write data to RAM
   
    For i = 65 To 68                                ' write text A to D to LCD
    ST7920_Write(LCD_Data,i)
    DelayMS 2
    Next
    DelayMS 2000
    Cls
   
    ST7920_Write(LCD_Control, 0x34)                 ' Enter graphic mode (extension)
    DelayMS 12
    ST7920_Write(LCD_Control, 0x36)
    DelayMS 12
   
    '---Clear screen---
    For count = 0 To 31                         'to increase vertical counter
instr = count + 128                             'set vertical address
ST7920_Write(LCD_Control,instr)
instr = %10000000                         'set horizontal adress
ST7920_Write(LCD_Control, instr)
For horcount = 0 To 15
sdata = 0
ST7920_Write(LCD_Data,sdata)
sdata = 0
ST7920_Write(LCD_Data,sdata)
Next horcount
    Next count
    DelayMS 12
    '---Clear screen---
    Clear glcd
   
   ST7920_line(0,63,127,0)                          'draw diagonal line
   ST7920_circle(63,31,30)                          'draw circle
   
   While 1 = 1: Wend

Proc ST7920_Write(P_Control As Bit,P_DATA As Byte)
    OpenSPI(SPI_FOSC_64,MODE_01,SMPMID)
    High LCD_CS_Pin   
    If P_Control = True Then            ' true = data, false = Control
        WriteSPI($FA)                   ' byte 2 set up for data
    Else
        WriteSPI($F8)                   ' byte 2 set up for control
    EndIf
    DelayMS 1
    WriteSPI(P_Data & $F0)              ' send byte 1
    DelayMS 1
    WriteSPI(P_Data & $0F <<4)          ' send byte 0     
    Low LCD_CS_Pin
EndProc

Proc ST7920_line(x1 As Byte,y1 As Byte,x2 As Byte,y2 As Byte)   
    addx = 1
    addy = 1   
    dx = Abs(x2 - x1)
    dy = Abs(y2 - y1)
    If x1 > x2 Then
        addx = -1
    EndIf
    If y1 > y2 Then
        addy = -1
    EndIf
    If dx >= dy Then
        dy =dy*2
        yerr = dy - dx
        diff = yerr - dx

        For i=0 To dx  Step 1         
            ST7920_pixel(x1,y1)
            If yerr < 0 Then
                yerr  = yerr + dy
                x1 =x1 + addx
             Else
                yerr = yerr + diff
                x1 = x1 + addx
                y1 =y1 + addy
             EndIf
             Next
     Else
        dx = dx*2
        yerr = dx - dy
        diff = yerr - dy
        For i=0 To dy  Step 1                             
            ST7920_pixel(x1,y1)
            If yerr < 0 Then
                yerr = yerr+ dx
                y1 =y1+ addy
             Else
                yerr = yerr + diff
                x1 = x1 + addx
                y1 = y1 + addy
              EndIf
              Next
      EndIf
EndProc

Proc ST7920_pixel(x As Byte,y As Byte)
 If y > 31 Then
        x = x + 128
        y=y-32
 EndIf
    v = y
    h = x / 16
    b = 15 - (x // 16)
    chard=glcd[y*16+h]
    lcdtemp=0x0001<< b
    chard=chard|lcdtemp
    glcd[y*16+h]=chard
    v=y|0x80
    h=h|0x80
    ST7920_Write(LCD_Control,v)
    ST7920_Write(LCD_Control,h)
    ST7920_Write(LCD_Data,chard.HighByte)
    ST7920_Write(LCD_Data,chard.LowByte)   
EndProc

Proc ST7920_circle(x As Byte,y As Byte,radius As Byte)
 a = 0
 r = radius
 P=1-radius
 While a <= r
            ST7920_pixel(a + x, r + y)
            ST7920_pixel(r + x, a + y)
            ST7920_pixel(x - a, r + y)
            ST7920_pixel(x - r, a + y)
            ST7920_pixel(r + x, y - a)
            ST7920_pixel(a + x, y - r)
            ST7920_pixel(x - a, y - r)
            ST7920_pixel(x - r, y - a)           
      If P < 0 Then
           P = P + 3 + 2 * a
           Inc a
      Else
            P= P + 5 + 2 * (a - r)     
            Inc a
            Dec r           
      EndIf               
   Wend
EndProc





Now I would try to write 8 line of text instead of 4 (smaller characters).

Thank you
Regards