Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Display TFT ST7789 (OshonSoft Basic).

DogFlu66

Member
I leave the library to use ST7789 TFT display, I have translated one that is in C language. But unfortunately I have not been able to get it to work yet. I leave the files in case someone with more experience with these displays can review it.
 

Attachments

  • Main_ST7789.bas
    1.5 KB · Views: 201
  • ST7789_240X240.bas
    15 KB · Views: 179
  • _SPI_Library.bas
    6 KB · Views: 191
  • _Pic18F26K22Library.bas
    46.4 KB · Views: 179
  • _SetUpAmicus18.bas
    2.9 KB · Views: 172
If you are referring to the SPI bus it does not need pull-up resistors, and the only pull-up resistor I use is the MCLR pin bias resistor. If you don't use MCLR it is disabled in bit configuration. I was looking for a Pic18F46K20 at home but I don't have one to test.
Hi D,
The Pickit3 uses the MCLR pin, then it is pulled up by the resistor.

If I have spare 18F46K20 I can post one to you if you PM me your address.
C.
 
I said in a previous thread.. When you are using an external MCLRE be wary that the pic NEVER hard boots if you keep the pickit 3 in place.. If you change the driver and then upload without removing power afterwards you only soft boot so "variables" are still intact, and then can give erroneous boots.
Hi I,
I do keep the Pickit3 in place, after reprogramming, is this incorrect?
While developing an internal MCLRE is best.. Once you are happy, by all means swap it back.
?
C.
 
Hola D,
El Pickit3 utiliza el pin MCLR, luego es levantado por la resistencia.

Si tengo un 18F46K20 de repuesto, puedo enviarte uno si me envías tu dirección por mensaje privado.
DO.

Gracias por la oferta, pero he pedido dos Pic18F46K20. De todas formas, te recomiendo que te decantes por el Pic18F46K22, que es muy parecido y tiene algunos de los módulos internos duplicados. Además tiene algo muy importante, y es que puede trabajar a 3,3 y 5v (1,8 a 5,5v), mientras que el 46K20 solo te permite trabajar a 3,3v (1,8 a 3,6v), al menos en las versiones que he visto.
 
Last edited:
Thanks for the offer, but I've ordered two Pic18F46K22. Anyway, I recommend you go for the Pic18F46K22, which is very similar and has some of the internal modules duplicated. It also has something very important, and that is that it can work at 3.3 and 5v (1.8 to 5.5v), while the 46K20 only allows you to work at 3.3v (1.8 to 3.6v), at least in the versions I've seen.
Hi D,
As I use the 46K20 with 3.3V exclusively, and there is a second PIC on my PCB. I'll leave it as is.
C
 
Hi I,
I think this is the program that was on the 18F46K20 PIC, which showed changing colours and TEXT on the screen.
C
Code:
'18F46K20 32MHz XTL PCB_9 BASE_MASTER TFT ME #164 291124 1100
Define CONFIG1L = 0x00
Define CONFIG1H = 0x06  '6= EXT8 MHz XPLL = 32 MHZ
Define CONFIG2L = 0x06 'BORV Set to 3.0V  (SBOREN?)
Define CONFIG2H = 0x00
Define CONFIG3L = 0x00
Define CONFIG3H = 0x81  'Set for HVP
Define CONFIG4L = 0x80
Define CONFIG4H = 0x00
Define CONFIG5L = 0x0f
Define CONFIG5H = 0xc0
Define CONFIG6L = 0x0f
Define CONFIG6H = 0xe0
Define CONFIG7L = 0x0f
Define CONFIG7H = 0x40
Define CLOCK_FREQUENCY = 32

'OSH config
Define SINGLE_DECIMAL_PLACES = 2
Define STRING_MAX_LENGTH = 20

'IO MAP
'SET BITS ON/OFF before TRIS!
Const LATAinit = %00000000  'ON/OFF
Const LATBinit = %00000000
Const LATCinit = %00000000
Const LATDinit = %00000000
Const LATEinit = %00000000

'SET PIN IN/OUT
Const TRISAinit = %00000000
Const TRISBinit = %00000000
Const TRISCinit = %00010000
Const TRISDinit = %00000000
Const TRISEinit = %00000000

'Define SIMULATION_WAITMS_VALUE = 1  'Comment in for SIM out for PIC

Define SEROUT_DELAYUS = 1000

Disable High
Disable Low

'###############################################
'lcd driver

Const ILI9341_NOP = 0x00
Const ILI9341_SWRESET = 0x01
Const ILI9341_RDDID = 0x04
Const ILI9341_RDDST = 0x09

Const ILI9341_SLPIN = 0x10
Const ILI9341_SLPOUT = 0x11
Const ILI9341_PTLON = 0x12
Const ILI9341_NORON = 0x13

Const ILI9341_INVOFF = 0x20
Const ILI9341_INVON = 0x21
Const ILI9341_DISPOFF = 0x28
Const ILI9341_DISPON = 0x29
Const ILI9341_CASET = 0x2a
Const ILI9341_RASET = 0x2b
Const ILI9341_RAMWR = 0x2c
Const ILI9341_RAMRD = 0x2e

Const ILI9341_PTLAR = 0x30
Const ILI9341_COLMOD = 0x3a
Const ILI9341_MADCTL = 0x36
Const ILI9341_DISP_FUNC = 0xB6


Const ILI9341_MADCTL_MY = 0x80
Const ILI9341_MADCTL_MX = 0x40
Const ILI9341_MADCTL_MV = 0x20
Const ILI9341_MADCTL_ML = 0x10
Const ILI9341_MADCTL_RGB = 0x00

Const ILI9341_RDID1 = 0xda
Const ILI9341_RDID2 = 0xdb
Const ILI9341_RDID3 = 0xdc
Const ILI9341_RDID4 = 0xdd


Const LCD_BLACK = 0x0000
Const LCD_RED = 0x001f
Const LCD_BLUE = 0xf800
Const LCD_GREEN = 0x07E0
Const LCD_YELLOW = 0x07ff
Const LCD_MAGENTA = 0xf81f
Const LCD_CYAN = 0xffe0
Const LCD_WHITE = 0xffff

Dim LCD_width As Word  ///< Display width as modified by current rotation
Dim LCD_height As Word  ///< Display height as modified by current rotation

Dim LCD_rotation As Byte  ///< Display rotation (0 thru 3)

Symbol TFT_RST = LATC.0  'RST RESET pin
Symbol TFT_DC = LATC.1  'DC (SS) Data/Command pin
Symbol TFT_CS = LATC.2  'CS Chip Select pin
Symbol TFT_SCK = LATC.3  'SCK as output
Symbol TFT_SDI = LATC.4  'SDI as input -> SDO
Symbol TFT_SDO = LATC.5  'SDO as output -> SDI

Symbol TFT_LED = LATD.3 'Screen backlight
Symbol rled = LATE.2 'Red LED
'*************************************************
Dim str As String
Dim x As Byte
'OSCCON = 0x60

'OSCTUNE.PLLEN = 1
TRISA.1 = 0
TRISC = 0
TRISD = 0
TRISE = 0
ADCON1 = 15

TFT_LED = 1 'Switch screen light on

'START UP LED
rled  = 1
WaitMs 1000
rled = 0
WaitMs 1000
rled  = 1
WaitMs 1000
rled = 0
WaitMs 1000


Call init_spi() 'Call SPI_init()
Call LCD_init()

str = "Hi Ian"
Main:

Toggle rled
WaitMs 100

    x = 1
    While x = 1
    WaitMs 300
    LATA.1 = 1
    Call fillScreen(LCD_BLACK)
    'Call fillScreen(LCD_WHITE)
    WaitMs 300
    LATA.1 = 0
    Call fillwindow(10,10,310,230, LCD_BLUE) 'L,T,R,B
    'Call fillwindow(10,10,310,230, LCD_BLUE)
    WaitMs 300
    LATA.1 = 1
    'Call fillwindow(10,10,230,230, LCD_GREEN)
    Call fillwindow(10,10,310,230, LCD_GREEN)
    WaitMs 300
    LATA.1 = 0
    Call fillScreen(LCD_WHITE)
    Call LCD_DrawLine(10,10,310,230,LCD_BLACK)'L,T,R,B
    'Call LCD_DrawLine(230,10,10,230,LCD_BLACK)
    Call LCD_DrawLine(10,230,310,10,LCD_BLACK)
    Call LCD_DrawLine(10,120,310,120,LCD_BLACK)
    Call LCD_DrawLine(160,10,160,230,LCD_BLACK)

    Call LCD_Circle(160,120,100,LCD_BLUE)
    'Call fillwindow(60,50,180,190, LCD_WHITE)
    Call LCD_DrawRectangle(70,30,250,210,LCD_BLUE)
    Call LCD_String( str,110,110, LCD_BLACK, LCD_WHITE)

    WaitMs 2000

Wend
End
'Proc SPI_init()
    'SSPSTAT = 0x40
    'SSPCON1 = 0x30
'End Proc

Proc LCD_WRITE_COM(dat As Byte)
    TFT_CS = 0
    TFT_DC = 0
    SSPBUF = dat
    While SSPSTAT.BF = 0
    Wend
    TFT_DC = 1
    TFT_CS = 1

End Proc

Proc LCD_WRITE_DATA(dat As Byte)
    TFT_CS = 0
    TFT_DC = 1
    SSPBUF = dat
    While SSPSTAT.BF = 0
    Wend
    TFT_DC = 1
    TFT_CS = 1

End Proc

Proc LCD_init()

Dim idx As Byte
Dim cmd As Byte
    High TFT_RST
    'ConfigPin TFT_RST = Output
    WaitMs 100
    Low TFT_RST
    WaitMs 100
    High TFT_RST
    WaitMs 200

    Call LCD_WRITE_COM(ILI9341_SWRESET)
    WaitMs 150
    Call LCD_WRITE_COM(ILI9341_DISPOFF)
    Call LCD_WRITE_COM(0xCB)     //Power control a
    Call LCD_WRITE_DATA(0x39)
    Call LCD_WRITE_DATA(0x2C)
    Call LCD_WRITE_DATA(0x00)
    Call LCD_WRITE_DATA(0x34)
    Call LCD_WRITE_DATA(0x02)
    WaitMs 1
    Call LCD_WRITE_COM(0xCF)    //Power control b
    Call LCD_WRITE_DATA(0x00)
    Call LCD_WRITE_DATA(0XC1)
    Call LCD_WRITE_DATA(0X30)
    WaitMs 1
    Call LCD_WRITE_COM(0xE8)    //Timing control a
    Call LCD_WRITE_DATA(0x85)
    Call LCD_WRITE_DATA(0x10)
    Call LCD_WRITE_DATA(0x78)
    WaitMs 1
    Call LCD_WRITE_COM(0xEA)    //Timing control b
    Call LCD_WRITE_DATA(0x00)
    Call LCD_WRITE_DATA(0x00)
    WaitMs 1
    Call LCD_WRITE_COM(0xED)    //Power on seq control
    Call LCD_WRITE_DATA(0x64)
    Call LCD_WRITE_DATA(0x03)
    Call LCD_WRITE_DATA(0X12)
    Call LCD_WRITE_DATA(0X81)

    //WaitMs 1
    Call LCD_WRITE_COM(0xC0)    //Power control 1
    Call LCD_WRITE_DATA(0x26)  //VRH[5:0]
    //WaitMs 1
    Call LCD_WRITE_COM(0xC1)    //Power control 2
    Call LCD_WRITE_DATA(0x11)   //SAP[2:0];BT[3:0]
    //WaitMs 1
    Call LCD_WRITE_COM(0xC5)    //VCM control
    Call LCD_WRITE_DATA(0x3e)   //Contrast
    Call LCD_WRITE_DATA(0x28)
   // WaitMs 1
    Call LCD_WRITE_COM(0xF7)
    Call LCD_WRITE_DATA(0x20)
    //WaitMs 1
    Call LCD_WRITE_COM(ILI9341_MADCTL)
    'Call LCD_WRITE_DATA(0x8) 'Top To Bottom-Left To Right CORRECT ORIENTATION
    Call LCD_WRITE_DATA(0xC8) 'Top To Bottom-Left To Right CORRECT ORIENTATION |
    Call LCD_WRITE_COM(ILI9341_INVOFF)
    //WaitMs 1
    Call LCD_WRITE_COM(ILI9341_NORON)
    WaitMs 1
    Call LCD_WRITE_COM(ILI9341_COLMOD )
    Call LCD_WRITE_DATA(0x55)
    //WaitMs 1
    Call LCD_WRITE_COM(0xB7) //emtry mode
    Call LCD_WRITE_DATA(0x07)
    Call LCD_WRITE_COM(0x3A) //pixel format
    Call LCD_WRITE_DATA(0x55) //16bit
    Call LCD_WRITE_COM(ILI9341_DISP_FUNC)    // Display Function Control
    Call LCD_WRITE_DATA(0x08)
    Call LCD_WRITE_DATA(0x82)
    Call LCD_WRITE_DATA(0x27)
    WaitMs 1
    Call LCD_WRITE_COM(ILI9341_SLPOUT)
    WaitMs 120
    Call LCD_WRITE_COM(ILI9341_DISPON)
    WaitMs 1

    LCD_height = 240
    LCD_width = 320 '240

End Proc

'/**************************************************************************/
'@brief  SPI displays set an address window rectangle For blitting pixels
'@param  x  Top left corner x coordinate
'@param  y  Top left corner x coordinate
'@param  W  Width of window
'@param  h  Height of window
'/**************************************************************************/
Proc setAddrWindow(x1 As Word, y1 As Word, x2 As Word, y2 As Word)

Call LCD_WRITE_COM(ILI9341_CASET)  //Column addr set
Call LCD_WRITE_DATA(x1.HB)
Call LCD_WRITE_DATA(x1.LB)
Call LCD_WRITE_DATA(x2.HB)
Call LCD_WRITE_DATA(x2.LB)
Call LCD_WRITE_COM(ILI9341_RASET)  //Row addr set
Call LCD_WRITE_DATA(y1.HB)
Call LCD_WRITE_DATA(y1.LB)
Call LCD_WRITE_DATA(y2.HB)
Call LCD_WRITE_DATA(y2.LB)

Call LCD_WRITE_COM(ILI9341_RAMWR)  //write to RAM
End Proc
Proc LCD_DrawLine(x1 As Word, y1 As Word, x2 As Word, y2 As Word, color As Word)

    Dim t As Word
    Dim xerr, yerr, delta_x, delta_y, distance As Integer
    Dim incx, incy, xPix, yPix As Integer
    xerr = 0
    yerr = 0

    delta_x = x2 - x1
    delta_y = y2 - y1
    xPix = x1
    yPix = y1

    If delta_x > 0 Then    incx = 1
    If delta_x = 0 Then incx = 0
    If delta_x < 0 Then
        incx = -1
        delta_x = -delta_x
    Endif

    If delta_y > 0 Then    incy = 1
    If delta_y = 0 Then incy = 0
    If delta_y < 0 Then
        incy = -1
        delta_y = -delta_y
    Endif


    If delta_x > delta_y Then
        distance = delta_x
    Else
        distance = delta_y
    Endif

    For t = 0 To distance + 1 Step 1
         Call LCD_DrawPoint(xPix, yPix, color)
        xerr = xerr + delta_x
        yerr = yerr + delta_y
        If xerr > distance Then
            xerr = xerr - distance
            xPix = xPix + incx
        Endif
        If  yerr > distance Then
            yerr = yerr - distance
            yPix = yPix + incy
        Endif
    Next t
End Proc
Proc LCD_Char( char As Byte, x As Word, y As Word, fcol As Word , bcol As Word)

    Dim  x0 As Integer
    Dim idx, idx2 As Byte
    Dim mask As Byte

    For idx = 0 To 9 Step 1
        mask = _LCDFnt(char, idx)
        For idx2 = 0 To 13 Step 2
            If mask And 0x80 Then
                Call LCD_DrawPoint(x+idx2, y, fcol)
                Call LCD_DrawPoint(x+idx2+1, y, fcol)
                Call LCD_DrawPoint(x+idx2, y+1, fcol)
                Call LCD_DrawPoint(x+idx2+1, y+1, fcol)
            Else
                Call LCD_DrawPoint(x+idx2, y, bcol)
                Call LCD_DrawPoint(x+idx2+1, y, bcol)
                Call LCD_DrawPoint(x+idx2, y+1, bcol)
                Call LCD_DrawPoint(x+idx2+1, y+1, bcol)
            Endif
            mask = ShiftLeft(mask,1)
        Next idx2
        y = y + 2
    Next idx

End Proc
Proc LCD_String( str As String, x As Word, y As Word, fcol As Word , bcol As Word)

Dim idx As Byte
Dim x0 As Word
idx = 0

    While str(idx) <> 0
        Call LCD_Char(str(idx), x, y,fcol,bcol)
        x = x+18
        idx = idx + 1
    Wend

End Proc
// Rectangle

Proc LCD_DrawRectangle( x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer, color As Word)

    Call LCD_DrawLine(x1, y1, x2, y1, color)
    Call LCD_DrawLine(x1, y1, x1, y2, color)
    Call LCD_DrawLine(x1, y2, x2, y2, color)
    Call LCD_DrawLine(x2, y1, x2, y2, color)

End Proc
//   Circle routine

Proc LCD_Circle(x1 As Word, y1 As Word, rad As Word, color As Word)
Dim xPix, yPix, di As Integer
xPix = 0
yPix = rad
di = 3 - ShiftLeft(rad,1)
    While xPix <= yPix

    Call LCD_DrawPoint(x1+xPix, y1-yPix, color)
    Call LCD_DrawPoint(x1+yPix, y1-xPix, color)
    Call LCD_DrawPoint(x1+yPix, y1+xPix, color)
    Call LCD_DrawPoint(x1+xPix, y1+yPix, color)
    Call LCD_DrawPoint(x1-xPix, y1+yPix, color)
    Call LCD_DrawPoint(x1-yPix, y1+xPix, color)
    Call LCD_DrawPoint(x1-xPix, y1-yPix, color)
    Call LCD_DrawPoint(x1-yPix, y1-xPix, color)
    xPix = xPix + 1

    If di < 0 Then
        di= (4 * xPix + 6) + di
    Else
        di= (10 + 4 * (xPix-yPix)) + di
        yPix = yPix - 1
    Endif
    Wend

End Proc
// line drawing

Proc LCD_DrawPoint(x1 As Word, y1 As Word ,color As Word)

    Call LCD_WRITE_COM(ILI9341_CASET)  //Column addr set
    Call LCD_WRITE_DATA(x1.HB)
    Call LCD_WRITE_DATA(x1.LB)
    Call LCD_WRITE_COM(ILI9341_RASET)  //Row addr set
    Call LCD_WRITE_DATA(y1.HB)
    Call LCD_WRITE_DATA(y1.LB)
    Call LCD_WRITE_COM(ILI9341_RAMWR)  //write to RAM

    Call LCD_WRITE_DATA(color.HB)
    Call LCD_WRITE_DATA(color.LB)

End Proc

'/**************************************************************************/
Proc fillRect(x1 As Word, y1 As Word, x2 As Word, y2 As Word, color As Word)
Dim px As Long
Dim tmp As Word
If x2 > 0 And y2 > 0 Then      //Nonzero width and height?

    Call setAddrWindow(x1, y1, x2, y2)

    px = x2
    px = px * y2
    TFT_CS = 0
    TFT_DC = 1
    While px > 1
        SSPBUF = color.HB
        While SSPSTAT.BF = 0
        Wend
        SSPBUF = color.LB
        While SSPSTAT.BF = 0
        Wend
        px = px - 1
    Wend
    TFT_DC = 1
    TFT_CS = 1
    Endif
End Proc

'/**************************************************************************/
'@brief    Fill the screen completely with one color. Update in subclasses If desired!
'@param    color 16-Bit 5-6-5 Color To fill with
'/**************************************************************************/
Proc fillScreen(color As Word)
Call fillRect(0, 0, LCD_width, LCD_height, color)
End Proc
Proc fillwindow(x1 As Word,y1 As Word,x2 As Word,y2 As Word,color As Word)
Call fillRect(x1, y1, x2, y2, color)
End Proc
Function _LCDFnt(ch As Byte, idx As Byte) As Byte
    Symbol Retval = _LCDFnt

            Select Case ch
                Case " "
                    Retval = LookUp(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), idx  //SPACE
                Case "!"
                    Retval = LookUp(0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x00), idx  //!
                Case 34
                    Retval = LookUp(0x00, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), idx  // "
                Case "#"
                    Retval = LookUp(0x00, 0x12, 0x12, 0x7f, 0x24, 0x24, 0xfe, 0x48, 0x48, 0x00), idx  //#
                Case "$"
                    Retval = LookUp(0x00, 0x10, 0x7c, 0x92, 0x70, 0x1c, 0x92, 0x7c, 0x10, 0x00), idx  //$
                Case "%"
                    Retval = LookUp(0x00, 0x41, 0xa2, 0x44, 0x08, 0x10, 0x22, 0x45, 0x82, 0x00), idx  //%
                Case "&"
                    Retval = LookUp(0x00, 0x10, 0x28, 0x10, 0x28, 0x44, 0x43, 0x42, 0x39, 0x00), idx  //&
                Case "'"
                    Retval = LookUp(0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), idx  //'
                Case "("
                    Retval = LookUp(0x00, 0x08, 0x10, 0x20, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00), idx  //(
                Case ")"
                    Retval = LookUp(0x00, 0x08, 0x04, 0x02, 0x02, 0x02, 0x20, 0x04, 0x08, 0x00), idx  //)
                Case "*"
                    Retval = LookUp(0x00, 0x08, 0x2a, 0x1c, 0x7f, 0x1c, 0x2a, 0x08, 0x00, 0x00), idx  //*
                Case "+"
                    Retval = LookUp(0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x08, 0x08, 0x00, 0x00), idx  //+
                Case ","
                    Retval = LookUp(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00), idx  //,
                Case "-"
                    Retval = LookUp(0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00), idx  //-
                Case "."
                    Retval = LookUp(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00), idx  //.
                Case "/"
                    Retval = LookUp(0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00), idx  ///
                Case "0"
                    Retval = LookUp(0x00, 0x3c, 0x46, 0x4a, 0x4a, 0x52, 0x52, 0x62, 0x3c, 0x00), idx  //0
                Case "1"
                    Retval = LookUp(0x00, 0x08, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00), idx  //1
                Case "2"
                    Retval = LookUp(0x00, 0x3c, 0x42, 0x02, 0x0c, 0x30, 0x40, 0x40, 0x7e, 0x00), idx  //2
                Case "3"
                    Retval = LookUp(0x00, 0x3c, 0x42, 0x02, 0x0c, 0x02, 0x02, 0x42, 0x3c, 0x00), idx  //3
                Case "4"
                    Retval = LookUp(0x00, 0x09, 0x18, 0x28, 0x48, 0x48, 0x7e, 0x08, 0x08, 0x00), idx  //4
                Case "5"
                    Retval = LookUp(0x00, 0x7e, 0x40, 0x40, 0x7c, 0x02, 0x02, 0x42, 0x3c, 0x00), idx  //5
                Case "6"
                    Retval = LookUp(0x00, 0x3c, 0x42, 0x40, 0x7c, 0x42, 0x42, 0x42, 0x3c, 0x00), idx  //6
                Case "7"
                    Retval = LookUp(0x00, 0x7e, 0x02, 0x02, 0x04, 0x08, 0x10, 0x10, 0x10, 0x00), idx  //7
                Case "8"
                    Retval = LookUp(0x00, 0x3c, 0x42, 0x42, 0x3c, 0x42, 0x42, 0x42, 0x3c, 0x00), idx  //8
                Case "9"
                    Retval = LookUp(0x00, 0x3c, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x42, 0x3c, 0x00), idx  //9
                Case ":"
                    Retval = LookUp(0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x08, 0x08, 0x00, 0x00), idx  //:
                Case ";"
                    Retval = LookUp(0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x08, 0x08, 0x10, 0x00), idx  //;
                Case "<"
                    Retval = LookUp(0x00, 0x04, 0x08, 0x10, 0x20, 0x20, 0x10, 0x08, 0x04, 0x00), idx  //<
                Case "="
                    Retval = LookUp(0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x00, 0x00), idx  //=
                Case ">"
                    Retval = LookUp(0x00, 0x10, 0x08, 0x04, 0x02, 0x02, 0x04, 0x08, 0x10, 0x00), idx  //>
                Case "?"
                    Retval = LookUp(0x00, 0x3c, 0x42, 0x02, 0x04, 0x08, 0x08, 0x00, 0x08, 0x00), idx  //?
                Case "@"
                    Retval = LookUp(0x00, 0x7e, 0x81, 0x9b, 0xa5, 0xa6, 0x9c, 0x81, 0x7e, 0x00), idx  //@
                Case "A"
                    Retval = LookUp(0x00, 0x18, 0x24, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x00), idx  //A
                Case "B"
                    Retval = LookUp(0x00, 0x7c, 0x42, 0x42, 0x7c, 0x42, 0x42, 0x42, 0x7c, 0x00), idx  //B
                Case "C"
                    Retval = LookUp(0x00, 0x3c, 0x42, 0x40, 0x40, 0x40, 0x40, 0x42, 0x3c, 0x00), idx  //C
                Case "D"
                    Retval = LookUp(0x00, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7c, 0x00), idx  //D
                Case "E"
                    Retval = LookUp(0x00, 0x7e, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x7e, 0x00), idx  //E
                Case "F"
                    Retval = LookUp(0x00, 0x7e, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x40, 0x00), idx  //F
                Case "G"
                    Retval = LookUp(0x00, 0x3c, 0x42, 0x40, 0x40, 0x46, 0x42, 0x42, 0x3c, 0x00), idx  //G
                Case "H"
                    Retval = LookUp(0x00, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00), idx  //H
                Case "I"
                    Retval = LookUp(0x00, 0x7e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x7e, 0x00), idx  //I
                Case "J"
                    Retval = LookUp(0x00, 0x7e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x48, 0x30, 0x00), idx  //J
                Case "K"
                    Retval = LookUp(0x00, 0x42, 0x44, 0x48, 0x70, 0x48, 0x44, 0x42, 0x42, 0x00), idx  //K
                Case "L"
                    Retval = LookUp(0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00), idx  //L
                Case "M"
                    Retval = LookUp(0x00, 0x42, 0x42, 0x66, 0x5a, 0x42, 0x42, 0x42, 0x42, 0x00), idx  //M
                Case "N"
                    Retval = LookUp(0x00, 0x42, 0x42, 0x62, 0x52, 0x4a, 0x46, 0x42, 0x42, 0x00), idx  //N
                Case "O"
                    Retval = LookUp(0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00), idx  //O
                Case "P"
                    Retval = LookUp(0x00, 0x7c, 0x42, 0x42, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x00), idx  //P
                Case "Q"
                    Retval = LookUp(0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x4a, 0x46, 0x3e, 0x00), idx  //Q
                Case "R"
                    Retval = LookUp(0x00, 0x7c, 0x42, 0x42, 0x7c, 0x48, 0x44, 0x42, 0x42, 0x00), idx  //R
                Case "S"
                    Retval = LookUp(0x00, 0x3c, 0x42, 0x40, 0x30, 0x0c, 0x02, 0x42, 0x3c, 0x00), idx  //S
                Case "T"
                    Retval = LookUp(0x00, 0x7e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00), idx  //T
                Case "U"
                    Retval = LookUp(0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00), idx  //U
                Case "V"
                    Retval = LookUp(0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00), idx  //V
                Case "W"
                    Retval = LookUp(0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x5a, 0x66, 0x42, 0x00), idx  //W
                Case "X"
                    Retval = LookUp(0x00, 0x42, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x42, 0x00), idx  //X
                Case "Y"
                    Retval = LookUp(0x00, 0x42, 0x42, 0x24, 0x18, 0x05, 0x08, 0x08, 0x08, 0x00), idx  //Y
                Case "Z"
                    Retval = LookUp(0x00, 0x7e, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x7e, 0x00), idx  //Z
                Case "["
                    Retval = LookUp(0x00, 0x3c, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x00), idx  //[
                Case "\"
                    Retval = LookUp(0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00), idx  //\
                Case "]"
                    Retval = LookUp(0x00, 0x3c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x3c, 0x00), idx  //]
                Case "^"
                    Retval = LookUp(0x00, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), idx  //^
                Case "_"
                    Retval = LookUp(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00), idx  //_
                Case "`"
                    Retval = LookUp(0x00, 0x10, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), idx  //`
                Case "a"
                    Retval = LookUp(0x00, 0x00, 0x00, 0x1c, 0x02, 0x1e, 0x22, 0x22, 0x1e, 0x00), idx  //a
                Case "b"
                    Retval = LookUp(0x00, 0x20, 0x20, 0x3c, 0x22, 0x22, 0x22, 0x22, 0x3c, 0x00), idx  //b
                Case "c"
                    Retval = LookUp(0x00, 0x00, 0x00, 0x1c, 0x22, 0x20, 0x20, 0x22, 0x1c, 0x00), idx  //c
                Case "d"
                    Retval = LookUp(0x00, 0x02, 0x02, 0x1e, 0x22, 0x22, 0x22, 0x22, 0x1e, 0x00), idx  //d
                Case "e"
                    Retval = LookUp(0x00, 0x00, 0x00, 0x1c, 0x22, 0x3e, 0x20, 0x22, 0x1c, 0x00), idx  //e
                Case "f"
                    Retval = LookUp(0x00, 0x0c, 0x10, 0x10, 0x3c, 0x10, 0x10, 0x10, 0x10, 0x00), idx  //f
                Case "g"
                    Retval = LookUp(0x00, 0x00, 0x00, 0x1e, 0x22, 0x22, 0x22, 0x1e, 0x02, 0x3c), idx  //g
                Case "h"
                    Retval = LookUp(0x00, 0x20, 0x20, 0x3c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00), idx  //h
                Case "i"
                    Retval = LookUp(0x00, 0x08, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00), idx  //i
                Case "j"
                    Retval = LookUp(0x00, 0x08, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x30), idx  //j
                Case "k"
                    Retval = LookUp(0x00, 0x20, 0x20, 0x22, 0x24, 0x38, 0x24, 0x22, 0x22, 0x00), idx  //k
                Case "l"
                    Retval = LookUp(0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x18, 0x00), idx  //l
                Case "m"
                    Retval = LookUp(0x00, 0x00, 0x00, 0x22, 0x36, 0x2a, 0x22, 0x22, 0x22, 0x00), idx  //m
                Case "n"
                    Retval = LookUp(0x00, 0x00, 0x00, 0x3c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00), idx  //n
                Case "o"
                    Retval = LookUp(0x00, 0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00), idx  //o
                Case "p"
                    Retval = LookUp(0x00, 0x00, 0x00, 0x7c, 0x14, 0x14, 0x14, 0x08, 0x00, 0x00), idx  //p
                Case "q"
                    Retval = LookUp(0x00, 0x00, 0x00, 0x3c, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x20), idx  //q
                Case "r"
                    Retval = LookUp(0x00, 0x00, 0x00, 0x2e, 0x30, 0x20, 0x20, 0x20, 0x20, 0x00), idx  //r
                Case "s"
                    Retval = LookUp(0x00, 0x00, 0x00, 0x1c, 0x22, 0x10, 0x0c, 0x22, 0x1c, 0x00), idx  //s
                Case "t"
                    Retval = LookUp(0x00, 0x10, 0x10, 0x38, 0x10, 0x10, 0x10, 0x12, 0x0c, 0x00), idx  //t
                Case "u"
                    Retval = LookUp(0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00), idx  //u
                Case "v"
                    Retval = LookUp(0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x14, 0x08, 0x00), idx  //v
                Case "w"
                    Retval = LookUp(0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x2a, 0x36, 0x22, 0x00), idx  //w
                Case "x"
                    Retval = LookUp(0x00, 0x00, 0x00, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00), idx  //x
                Case "y"
                    Retval = LookUp(0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x1e, 0x02, 0x3c), idx  //y
                Case "z"
                    Retval = LookUp(0x00, 0x00, 0x00, 0x3e, 0x02, 0x04, 0x08, 0x10, 0x3e, 0x00), idx  //z
                Case "{"
                    Retval = LookUp(0x00, 0x04, 0x08, 0x08, 0x08, 0x10, 0x08, 0x08, 0x08, 0x04), idx  //{
                Case "|"
                    Retval = LookUp(0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00), idx  //|
                Case "}"
                    Retval = LookUp(0x00, 0x10, 0x08, 0x08, 0x08, 0x04, 0x08, 0x08, 0x08, 0x10), idx  //}
                Case "~"
                    Retval = LookUp(0x00, 0x00, 0x00, 0x00, 0xcc, 0x33, 0x00, 0x00, 0x00, 0x00), idx  //~
                Case 165 '"Ñ" + chr(165) +
                    Retval = LookUp(0x00, 0x00, 0x00, 0x7e, 0x05, 0x09, 0x11, 0x7e), idx  //Ñ
                Case 164'"ñ" + chr(164) +
                    Retval = LookUp(0x00, 0x00, 0x00, 0x78, 0x12, 0x0a, 0x0a, 0x70), idx  //ñ
            EndSelect

End Function
'*******************************************************
'*                                                     *
'*            START UP SPI ROUTINE                     *
'*                                                     *
'*******************************************************
Proc init_spi()  'PIC 18F46K20
TRISC.3 = 0  'SCK to Slave ****** output *******
TRISC.5 = 0  'MOSI  ****** output *******
TRISC.4 = 1  'MISO  ****** input *******

'MODE 0,0???
SSPSTAT.SMP = 0  'Input data sampled at middle of data output time ** not about clock generation **
SSPSTAT.CKE = 1  'CHANGED to 1 [0 Output data changes on clock transition from active to idle ** AS ABOVE **]
SSPSTAT.5 = 0  'I2C only
SSPSTAT.4 = 0  'I2C only
SSPSTAT.3 = 0  'I2C only
SSPSTAT.2 = 0  'I2C only
SSPSTAT.1 = 0  'I2C only

SSPCON1 = 0  'RESET THE CONTROL REGISTER **************************************ADDED
SSPCON1.WCOL = 0  'Collision detect
SSPCON1.SSPOV = 0  'Overflow
SSPCON1.SSPEN = 1  'Configure SCK,SD0,SDI,/SS ** HAS TO BE 1. To reset or reconfigure SPI mode, clear the SSPEN bit,
'reinitialize the sspcon registers And Then set the SSPEN Bit from the datasheet !!!!!!!!!!!!!!!!
SSPCON1.CKP = 1  '= idle state For clock is A HIGH level
SSPCON1.SSPM3 = 0  '0000 = SPI Master mode, clock = FOSC/4
SSPCON1.SSPM2 = 0
SSPCON1.SSPM1 = 0  ''SPI Master mode, clock = F OSC/4
SSPCON1.SSPM0 = 0
End Proc
 
Hi I,
I think this is the program that is on the 18f4431 PIC. (Try a verify)
C.
Code:
'18F4431 32MHz XTL PCB8 BASE_SLAVE NOMatch E 010424 1000

'array buf removed, losing 50 bytes of program memory from use
'parse routinr modified to cope with gps() which now integrates
'the gps parse routine into the main program rather than having it as a separate
'stand alone module
'????copy into the sspbuf array module removed as it is not needed anymore -?????
'I am in 2 minds about tidying up the serial print the diagnostic string data
'but have Not DONE anything with  it yet
'TRIS direction information

Define CONFIG1L = 0x00
Define CONFIG1H = 0x06  '8mHz x4 =32
Define CONFIG2L = 0x0c
Define CONFIG2H = 0x20
Define CONFIG3L = 0x04
Define CONFIG3H = 0x80
Define CONFIG4L = 0x80  'Set for HVP
Define CONFIG4H = 0x00
Define CONFIG5L = 0x0f
Define CONFIG5H = 0xc0
Define CONFIG6L = 0x0f
Define CONFIG6H = 0xe0
Define CONFIG7L = 0x0f
Define CONFIG7H = 0x40

'OSH config
Define CLOCK_FREQUENCY = 32
Define SINGLE_DECIMAL_PLACES = 2
Define STRING_MAX_LENGTH = 45  '20 too short@
Define SEROUT_DELAYUS = 1000

'**********************************************************************
'*                                                                    *
'*      Register configuration                                        *
'*                                                                    *
'**********************************************************************
'------------- TARGET SETUP  ------------------
Const PR2set = 125  'use this for the live board: gets 5ms per interrupt
'Const PR2set = 2  'use this for fast timing to speed up simulator
'Define SIMULATION_WAITMS_VALUE = 1  'Comment in for SIM out for PIC

ANSEL0 = %00000000
ANSEL1 = %00000000

Disable High  'Disable interrupts
Disable Low  'Disable interrupts

'**********************************************************************
'*                                                                    *
'*          IO Port configuration                                     *
'*                                                                    *
'**********************************************************************
'IN or OUT
Const TRISAinit = %11011000  '7=OSC, 6=OSC, 4=QEIB 3=QEIA 2=TEMP SEROUT
Const TRISBinit = %00000000
Const TRISCinit = %11000100  '7=1-RX, 6=1-slave4431_cs, 2=MOSI'RX<<<<<<<<<<<<<<<<<<<<<
Const TRISDinit = %00100000  '6=led, 7=led, 5=synch'D2=MOSI ??£
Const TRISEinit = %00000000  '2=TEST INDICATOR, 0= S2M_BUF_FULL

TRISA = TRISAinit
TRISB = TRISBinit
TRISC = TRISCinit
TRISD = TRISDinit
TRISE = TRISEinit

'SET BITS ON/OFF before TRIS!
Const LATAinit = %00000000  'ON/OFF
Const LATBinit = %00000000
Const LATCinit = %00000000
Const LATDinit = %00000000
Const LATEinit = %00000000  'POSS MCLR RE3

'*******************************************************
'*                                                     *
'*       GLOBAL VARIABLE DECLARATIONS                  *
'*                                                     *
'*******************************************************
'Comms

Const rxbufsize = 50  'keep this the same as the buffer size, check this.
Dim gnrmcpsn As Byte  'POSITION of character in UART RX buffer STRING.
Dim RXerr As Bit  'Errors in receiving $DATA

Dim RXIRQchar As Byte
Dim dumpchar As Byte  'For clearing Over run errors

Dim spipsn As Byte  'VARIABLE USED IN SSPBUF SEND/RECEIVE ROUTINE
Dim spichar As Byte

'SLAVE GPS
Dim strtim As String
Dim strlat As String
Dim strlong As String

Dim qeideg As Word  ' Byte

QEICON.VELM = 1  '1 = Velocity mode disabled
QEICON.QEIM2 = 1  '110 = QEI enabled in 4x Update mode; position counter is reset on period match (POSCNT = MAXCNT)
QEICON.QEIM1 = 1
QEICON.QEIM0 = 0
QEICON.PDEC1 = 1  '11=1:64 Velocity Pulse Reduction Ratio bits
QEICON.PDEC1 = 1


PIR3.IC2QEIF = 0  'Has reached the MAXCNT value, INT QEI MODULE Interrupt flag bit
PIR3.IC3DRIF = 0  'clr in s/w   REG file motion feedback filter
PIE1.RCIE = 0  '0= 'EUSART Receive Interrupt Enable bit

CAP2BUFL = 0x00
CAP2BUFH = 0x00
CAP3BUFL = 0x9f  'CAP3BUFL = 0x67
CAP3BUFH = 0x05  'CAP3BUFH = 0x01

''PIC18F4431

'FLAGS to indicate updated data
Symbol slave4431_cs = PORTC.6  'The port used as chip select
Dim gnrmc_buf_filling As Bit  'Message loading
Dim gnrmc_buf_full As Bit  'GPS-Buffer $ to W   1 = FULL 0 = Not FULL
'Dim gnrmc_buf_parsed As Bit  'parser found a GNRMC sentence and updated data
'gnrmc_buf_parsed = 0  'init new data flags (compiler may do this automatically)

'Dim s2m_buf_done As Bit  'S2M-buffer after PARSE
Symbol spi_pin_rdy = PORTE.0  'READY to send SPI DATA.
spi_pin_rdy = 0
Dim slave4431_cs_data As Bit  'The data state of the chip select line D added

Dim gnrmc_buf As String  '(45) As String'Byte  'received message comes to buf'Check size (Only for GNRMC)
Dim s2m(34) As Byte  '(34) As Byte  'Used to transfer data via SPI
'from the ssp buffer for receiving via the spi bus. The array has to be the same length as s2m buffer.
'onto the ssp buffer for transmitting via the spi bus. data includes the gps string,
'battery voltage and spare info.
Dim m2s(34) As Byte  'Used to transfer data to SLAVE via SPI

Dim batvolt As Byte  'TEST Battery voltage from BASE-SLAVE
Dim sparedata As Byte  'TEST Spare data from BASE-SLAVE.

Symbol yled = PORTD.6
Symbol rled = PORTD.7

'*******************************************************
'*                                                     *
'*            End of variable declarations             *
'*                                                     *
'*******************************************************
'*******************************************************
'*                                                     *
'*            START UP CODE BEGINS HERE                *
'*                                                     *
'*******************************************************

'START UP LEDS
rled = 1
WaitMs 1000
rled = 0
WaitMs 1000
yled = 1
WaitMs 1000
yled = 0
WaitMs 1000

'setup USART for 9600 baud receive
RCSTA = %10010000  '7=SPEN: Serial Port Enable bit, 6=RX9: 9-Bit Receive Enable bit, 5=SREN: Single Receive Enable bit, 4=CREN: Continuous Receive Enable bit
TXSTA.BRGH = 1  'BRGH: High Baud Rate Select bit
BAUDCON.BRG16 = 1  '16-Bit Baud Rate Register Enable bi
SPBRG = 207
PIR1.RCIF = 0  'RCIF: EUSART Receive Interrupt Flag bit
PIE1.RCIE = 1  'EUSART Receive Interrupt Enable bit
PIE1.CCP1IE = 1  'CCP1IE: CCP1 Interrupt Enable bit
INTCON.PEIE = 1  'PEIE/GIEL: Peripheral Interrupt Enable bit
INTCON.GIE = 1  'GIE/GIEH: Global Interrupt Enable bit

Gosub irqinitbuf  'INIT RX'<<<<<<<<<<<<<<<¦
Serout PORTB.0, 9600, "RDY  ", CrLf  '"slave ready", CrLf  'USART?<<<<<<<<<<<<<<<<<<<<<<<<<<

'fire up the UART
Enable High  'enable the high interrupts

'INITIALIZE SPI
Call init_spi()  'initialise spi -here SSPEN=1 sets the pin directions for SPI

'ms20_reporttimer = 0  'force reports on entry to main loop

''*******************************************************
''*                                                     *
''*            Main loop BEGINS                         *
''*                                                     *
''*******************************************************

'$GNRMC,111111.00,A,3723.02837,N,00150.39853,W,0.820,188.36,110706,,,A*74
'$GNRMC,000000.00,A,3723.02837,N,00150.00000,W,0.820,188.36,110706,,,A*74$GNRMC,111111.00,A,3723.02837,N,00150.11111,W,0.820,188.36,110706,,,A*74$GNRMC,222222.00,A,3723.02837,N,00150.22222,W,0.820,188.36,110706,,,A*74$GNRMX,333333.00,A,3723.02837,N,00150.33333,W,0.820,188.36,110706,,,A*74$GNRMC, 444444.00, A, 3723.02837, N, 00150.55555, W, 0.820, 188.36, 110706,,, A * 74$GNRMC, 555555.00, A, 3723.02837, N, 00150.39853, W, 0.820, 188.36, 110706,,, A * 74$GNRMC,666666.00,A,3723.02837,N,00150.66666,W,0.820,188.36,110706,,,A*74$GNRMX,777777.00,A,3723.02837,N,00150.77777,W,0.820,188.36,110706,,,A

main_loop:  '/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

Toggle rled

If gnrmc_buf_full = 1 Then
    'Break  '<<<<<<<<<<<

    Gosub gnrmc_parse

    'Update the transmit to master buffer with current data
    batvolt = 12
    sparedata = 123
Endif

If spi_pin_rdy = 1 Then  'Tell MASTER SPI ready.<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    Serout PORTB.0, 9600, "SLAVE GNRMC PARSED  ", s2m(0), s2m(1), s2m(2), s2m(3), s2m(4), s2m(5), s2m(6), s2m(7), s2m(8), s2m(9), s2m(10), s2m(11), s2m(12), s2m(13), s2m(14), s2m(15), s2m(16), s2m(17), s2m(18), s2m(19), s2m(20), s2m(21), s2m(22), s2m(23), s2m(24), s2m(25), s2m(26), s2m(27), s2m(28), s2m(29), s2m(30), s2m(31), #s2m(32), #s2m(33), CrLf
    WaitMs 1  'Lower till not work
    'Gosub irqinitbuf

    'If gnrmc_buf_parsed = 0 Then  'parse tried but string was unknown, corrupt or wrong length
        'Hserout "Parse fail ", CrLf
        'Gosub IRQinitBuf  '++++++¦
    'endif
    'Return
    yled = 1
    While slave4431_cs = 1  'If 1 then it waits till the CS makes it 0 then it LOOPs
        For spipsn = 0 To 33  'GPS=0to29-$toW INC, QEI=30,31 BATVOLT=32 SPARE DATA=33
            SSPBUF = s2m(spipsn)  'Transfer S2M(spipsn) into SSPBUF
            While SSPSTAT.BF = 0
            Wend
            m2s(spipsn) = SSPBUF  'Transfer M2S(spipsn) BYTE from SSPBUF into M2S(spipsn)
        Next spipsn
            spi_pin_rdy = 0
            Break  '<<<<<<<<<<<<<<<<<<<<< CS=RC6 OFF@
    Wend
    spipsn = 0
    yled = 0
    RCSTA.CREN = 1
    PIE1.RCIE = 1
Endif

Goto main_loop

End

'*******************************************************
'*                                                     *
'*            Functions BEGIN                          *
'*                                                     *
'*******************************************************
'---------------------- RX/TMR2 INTERRUPT SERVICE  ----------------------
'Captures one sentence from '$' to 'W' in buf.
'Sentences must fit entirely in buf from $ to W
'Re-inits buf on any error and when any $ is received, even if in middle of sentence
'Stops UART and sets gps_buf_done when 'W' is received.

'Sentence in progress will be discarded, buffer reset and UART re-enabled when:
'Any UART error occurs
'A new '$' in the middle of a reception is found
'The buffer overflows before a 'W' is received. Non-fatal, it will just begin looking for the next
'sentence.  err will be set when this happens so that main knows about it.

'Returns gps_buf_done=1 and buffer loaded with $,data,W on successful receipt of a complete sentence.
'Requires:
'rxBufSize defined as the size of buf in bytes.  Declare the buffer like this:
'Const rxBufSize = 50
'Dim buf(50) As Byte  'Valid buf index range is 0 to rxBufSize-1.  After $, index points to last character stored

'Expects:
'Call IRQinitBuf with PIE1.RCIE = 0 to set up for next sentence
'$GNRMC,111111.00,A,3723.02837,N,00159.39853,W,0.820,188.36,110706,,,A*74'For SIM

On High Interrupt
Save System

'OVERRUN ERROR
If PIE1.RCIE = 1 Then  'EUSART Receive Interrupt Enable bit
    If RCSTA.OERR = 1 Then
        Gosub irqinitbuf  're-init buffer, discard bad sentence
        Goto RXIRQdone  'done, wait for next character
    Endif  'OERR

    'FRAMING ERROR
    If RCSTA.FERR = 1 Then
        dumpchar = RCREG  'Read char to clear RCIF and FERR
        Gosub irqinitbuf  'Re-init buffer, discard bad sentence
        Goto RXIRQdone  'wait for next
    Endif  'FERR

    'No UART errors, process character
    If PIR1.RCIF = 1 Then
        RXIRQchar = RCREG  'read the received char, clears RCIF

        'Look for $, start/restart filling buf when found
        If RXIRQchar = "$" Then  'Start (re)filling buf on any $
            Gosub irqinitbuf  'init buffer, index and flags@
            gnrmc_buf(gnrmcpsn) = RXIRQchar  'store $ $ ADDED instead of RXIRQchar, because no $ was being stored
            gnrmc_buf_filling = 1  'start storing the sentence
            Goto RXIRQdone  'done with this character
        Endif  'char was $

        'no UART errors and character was not $
        'If $ was found previously, process character looking for W and no buffer overflow.
        'If haven't found $ yet, just ignore character.

        If gnrmc_buf_filling = 1 Then  'if filling buffer, see if there is room in buf
        'Break  '<<<<<<<<<<<,
            If gnrmcpsn >= (rxbufsize - 1) Then  'last char was at end of buf - buffer overflow so..
                Gosub irqinitbuf  'restart buffer, discard sentence
                RXerr = 1  'let main know that the buffer overflowed and is restarting
                Goto RXIRQdone  'done, resume looking for next $
            Endif  'buffer overflow

            gnrmcpsn = gnrmcpsn + 1  'else, there's room in buf so bump index and store character, might be W
            gnrmc_buf(gnrmcpsn) = RXIRQchar

            If RXIRQchar = "W" Then  'if end of sentence..
                RCSTA.CREN = 0  'shut down UART
                PIE1.RCIE = 0  'Enable off
                gnrmc_buf_filling = 0
                gnrmc_buf_full = 1
                Goto RXIRQdone  'and bye!
            Endif  'RXIRQchar was W
        Endif  'If gnrmc_buf_filling = 1
    Endif  'RCIF=1
Endif  'RCIE=1

    'Exit point for each RXinterrupt. Process timers
    RXIRQdone:

Resume

'--------------- PARSE COMPLETE SENTENCE IN BUFFER -------------------------
'parse: extracts the main values from GPS,REMOTE and QEIDEG sentences in RXbuf
'into named value messages using the parse utilities above.
'Flags:
'returns prsed_gnrmc =1 if it found A good sentence
'if prsed_gnrmc =0, has bad sentence
'posted to respective string(s).?¦

'Expects: gnrmcpsn = index in buffer of the termininating 'W' char (one less than number of chars):
'Const ixGNRMC_W = 15  '$gnrmc,025,4,75,W
Const ixGNRMC_W = 44

gnrmc_parse:
    'Break  '<<<<<<<<<<<<<<<<<<<<<<<<<
    gnrmc_buf_full = 0
    'Dim tempIX As Byte  'used as index for building/adding to strings
    'tempIX = 0  'string building begins at 0 for any

    If gnrmcpsn <> ixGNRMC_W Then Goto gnrmc_buf_parsed  '-->
    'Endif
    s2m(0) = "&"  '  [TOT 34 BYTES ] $TEST¦
    s2m(1) = gnrmc_buf(7)  'Time
    s2m(2) = gnrmc_buf(8)  'Time
    s2m(3) = gnrmc_buf(9)  'Time
    s2m(4) = gnrmc_buf(10)  'Time
    s2m(5) = gnrmc_buf(11)  'Time
    s2m(6) = gnrmc_buf(12)  'Time
    s2m(7) = gnrmc_buf(14)  'Time
    s2m(8) = gnrmc_buf(15)  'Time
    s2m(9) = gnrmc_buf(19)  'Lat
    s2m(10) = gnrmc_buf(20)  'Lat
    s2m(11) = gnrmc_buf(21)  'Lat
    s2m(12) = gnrmc_buf(22)  'Lat
    s2m(13) = gnrmc_buf(24)  'Lat
    s2m(14) = gnrmc_buf(25)  'Lat
    s2m(15) = gnrmc_buf(26)  'Lat
    s2m(16) = gnrmc_buf(27)  'Lat
    s2m(17) = gnrmc_buf(28)  'Lat
    s2m(18) = gnrmc_buf(30)  'N
    s2m(19) = gnrmc_buf(32)  'Lon
    s2m(20) = gnrmc_buf(33)  'Lon
    s2m(21) = gnrmc_buf(34)  'Lon
    s2m(22) = gnrmc_buf(35)  'Lon
    s2m(23) = gnrmc_buf(36)  'Lon
    s2m(24) = gnrmc_buf(38)  'Lon
    s2m(25) = gnrmc_buf(39)  'Lon
    s2m(26) = gnrmc_buf(40)  'Lon
    s2m(27) = gnrmc_buf(41)  'Lon
    s2m(28) = gnrmc_buf(42)  'Lon
    s2m(29) = gnrmc_buf(44)  'W
    s2m(30) = POSCNTL  'QEIDEGLB
    s2m(31) = POSCNTH  'QEIDEGHB
    s2m(32) = batvolt  'Bat volt
    s2m(33) = sparedata  'Spare DATA

    gnrmc_buf_parsed:  '<-- <--

    spi_pin_rdy = 1  'S2M Buffer ready to SPI to MASTER
    Break  '<<<<<<<<<<<<  CS RC6 OFF
    'ms20_gnrmcguard = gnrmcguardset  '??????????
Return


'------------- UART SETUP UTILITIES  -----------------

'Stops UART, selects channel indicated by datasw (0-2)
'Inits RX buffer then restarts UART and enables RX interrupt
'Expects:
'GIE is enabled
'port directions and basic TX/RX

''--------------------  INIT SENTENCE BUFFER  ------------------
''Sets up index and flags for next sentence.  Overwrites
''old buffer data
''May be used by main (non-interrupt code) when PIR1.RCIE = 0

irqinitbuf:
    gnrmcpsn = 0  'init index
    RXerr = 0  'no error
    RCSTA.CREN = 1
    dumpchar = RCREG  '1    'clear UART RX registers
    dumpchar = RCREG  '2
    PIE1.RCIE = 1
Return

'*******************************************************
'*                                                     *
'*            START UP SPI ROUTINE                     *
'*                                                     *
'*******************************************************

Proc init_spi()  'PIC 18F4431
'4431
TRISC.6 = 1  '4431_CS=1
TRISD.3 = 1  'SCK from MASTER ******INPUT*****
TRISD.1 = 0  'MISO  ****** OUTPUT *******
TRISD.2 = 1  'MOSI  ****** INPUT *******

'MODE 0,0
SSPSTAT.SMP = 0  'Input data sampled at middle of data output time ** not about clock generation **
SSPSTAT.CKE = 0  '0 Output data changes on clock transition from active to idle ** AS ABOVE **
SSPSTAT.5 = 0  'I2C only
SSPSTAT.4 = 0  'I2C only
SSPSTAT.3 = 0  'I2C only
SSPSTAT.2 = 0  'I2C only
SSPSTAT.1 = 0  'I2C only

SSPCON = 0  'RESET THE CONTROL REGISTER
SSPCON.WCOL = 0  'Collision detect
SSPCON.SSPOV = 0  'Overflow
SSPCON.SSPEN = 1  'Configure SCK,SD0,SDI,/SS ** HAS TO BE 1. To reset or reconfigure SPI mode, clear the SSPEN bit,
'reinitialize the sspcon registers And Then set the SSPEN Bit from the datasheet !!!!!!!!!!!!!!!!
SSPCON.CKP = 1  '0 = Idle state for clock is a HIGH level
SSPCON.SSPM3 = 0  '0100 = SPI SLAVE mode, clock = FOSC/64
SSPCON.SSPM2 = 1
SSPCON.SSPM1 = 0  'SLAVE MODE
SSPCON.SSPM0 = 0
End Proc
 
I can get a pic.. I will get one next time I order from RS..

Do you have another board you can test? Leave off the pic18f4431 and watch the SCL.. at the moment I do not get proper switching ... Here is the clock at 4Mhz

20241213_093449.jpg


Look at the data signal (bottom) rise and fall more than half the clock.. This is either the chip itself or stray capacitance... Now both these signals are on the same port.. I also see the peak to peak IS 3,3v so we are getting neg to pos... I wonder if there is a slew issue here.. let me divulge the datasheet see it there is a setting.. I do not use the 3v3 devices..
 
Turned off the slew control.. The data was far better but no affect on the clock...

Reading more... see you later
Hi I,
My guess is CKE or CKP. There's a setting for beginning, middle or end of the clock. This took me quite a lot of understanding.
Anyway one of those settings could have got changed copy and pasting you and 'D''s CODE.
C
 
Last edited:
Yeah! but slow.. If I jack it any higher than 4Mhz the signal slowly disappears..

@4Mhz you can see we'll get something..

On Monday I will take a scope reading of my pic18f46k22 scl and data you can decide..
 
Yeah! but slow.. If I jack it any higher than 4Mhz the signal slowly disappears..

@4Mhz you can see we'll get something..

On Monday I will take a scope reading of my pic18f46k22 scl and data you can decide..
Hi I,
Can you clarify please?
You say "yeah" but is that with the program I posted, because that was set to 8MHz x4PLL so 32 MHz.
C
 
I can get a pic.. I will get one next time I order from RS..

Do you have another board you can test? Leave off the pic18f4431 and watch the SCL.. at the moment I do not get proper switching ... Here is the clock at 4Mhz

View attachment 148036

Look at the data signal (bottom) rise and fall more than half the clock.. This is either the chip itself or stray capacitance... Now both these signals are on the same port.. I also see the peak to peak IS 3,3v so we are getting neg to pos... I wonder if there is a slew issue here.. let me divulge the datasheet see it there is a setting.. I do not use the 3v3 devices..
Hi I,
Hopefully, I'll get chance to test a PCB with an oscilloscope, and let you know.

Did you look at the settings I guessed in #251?
C.
 
My ILI is running at 8Mhz just fine.. Now I know the SLRCON set to 0 helps I'll give that a go..

Also!! There is an SPI setting (SMP) to drag the data read to better the read performance... I'm giving that a go.

We'll see As for those settings... I know full well abut the SPI MODES CKE and CKP set the mode.
 

New Articles From Microcontroller Tips

Back
Top