News:

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

Main Menu

How to pass a string to a proc

Started by TimB, Jul 02, 2023, 06:58 PM

Previous topic - Next topic

TimB

Hi all

I'm Working on my i2c LCD routines that do not use Print.

I have the basics like CLS and SetCursor as proc's but now want to be easily able to replicate the Positron commands like

Print Hex2 etc

As Print is already used to handle a GLCD display I need to find another way. I probably could use something like rsout dec4 xyz but then my code would look odd. eg

i2cLCD_Int()
i2cLCD_CLS()
i2cLCD_SetCursor(2,10)

then I would need

RSout Dec2 bMydata

It is not cohesive with the other i2cLCD commands.
I would prefer i2cLCD_Print Dec2 bMydata But until Les implements a system like that I have to work with strings

I have in my GLCD Code that Les wrote this
'-------------------------------------------------------------------------------------------------
' Write a string directly to the display buffer array
'           : pText holds the test to print
' Output    : None
' Notes     : Does not send the display buffer to the LCD
'           : ST_UpdateDisplay() must be called after the write
'
Proc ST_Shad_PrintString(pString As Global_ST_StringParam)
    Print pString                                                   ' Write the string to the display buffer
EndProc

But here is where I get confused on how to use it and how to know how many bytes to send from the string.

I presume I would need to make the string big enough to cope with 16 chars + the null

Then parsing it do I work my way from string#0 sending what is in there until I reach the null?

Is there a better way?
 

TimB

I managed to write some (bad) code to do the job

I aim to make all the code clearer and better commented and publish it. The i2cLCD routines that can use Hbus or Busout or software i2c routines.

Here is an example of some of the routines.

'*******************************************************************************
'* Title  :  i2cLCD_CLS
'* Input  :  <InputParams>
'* Notes  :  Clears the screen
'*******************************************************************************
    Proc i2cLCD_CLS()

        i2cLCDWrCommand(ci2cLCD_CLS)
        delayms 2                                                              ' This delay is needed or there are issues
    EndProc


'*******************************************************************************
'* Title  :  i2cLCD_SetCursor
'* Input  :  pYdata as byte
'*        :  pXdata as Byte
'* Notes  :  Moves the cursor to the point as specified
'*******************************************************************************
    Proc i2cLCD_SetCursor(pYdata as byte, pXdata as Byte)

        dim cPrintAtCmnd as $80

        Dec pXdata

        bI2CPrint_Temp = cPrintAtCmnd + pXdata
        if pYdata = 2 then
            bI2CPrint_Temp = bI2CPrint_Temp + $40
        Endif

        i2cLCDWrCommand(bI2CPrint_Temp)

    Endproc





'*******************************************************************************
'* Title  :  i2cLCDPrintDecFlt
'* Input  :  pDigits as Byte
'*        :  pData as Float
'* Notes  :  <RoutineNotes>
'*******************************************************************************
    Proc i2cLCDPrintDecFlt(pDigits as Byte, pData as Float)

        Dim bIndex1 as byte
        Dim bTemp as Byte
        Dim bDigitCntr as Byte
        DIm cNull as 0
        Dim xCntDigits as bit

        sGlobal_i2cLCDString = str$(Dec pData)

        bIndex1 = 0
        bDigitCntr = 0
        xCntDigits = 0

        repeat
            bTemp = sGlobal_i2cLCDString[bIndex1]                              ' Read the data

            if bTemp = cNull then Break                                        ' Exit if we reach the end of the string

            inc bIndex1                                                        ' inc char pointer

            i2cLCDWrData(bTemp)                                                ' Print the data


            if bTemp = "." then xCntDigits = 1                                  ' Once we see the "." we start counting

            if xCntDigits = 1 then inc bDigitCntr                              ' If we are counting inc the digit counter

            if bDigitCntr > 5 then break                                        ' we have a max of 5 digits we display to so incase issues break out and return



        Until bDigitCntr > pDigits


    EndProc



'*******************************************************************************
'* Title  :  i2cLCDPrintStr
'* Input  :  pString as String
'* Notes  :  Prints the contents of the string until > 17 or Null is seen
'*******************************************************************************
    Proc i2cLCDPrintStr(pString as String * 17)

        Dim bIndex as byte = 0
        Dim bTemp1 as Byte
        DIm cNull as 0

        DO

            bTemp1 = pString[bIndex]                                            ' Get the data from the string
            if bTemp1 = CNull then Break                                        ' Break if null
            i2cLCDWrData(bTemp1)                                                ' Print the data

            Inc bIndex
            If bIndex > 17 then Break

        Loop


    EndProc


And here is the code calling the procs



        i2cLCD_SetCursor(1,1)

        i2cLCDPrintDecFlt(3,fMyFloat)

        sMyString = "Result = " + str$(Dec2 fMyFloat)

        i2cLCD_SetCursor(2,1)

        i2cLCDPrintStr(sMyString)


I will need to learn more about string handling in procedures so I can just pass the string address not the whole contents Although looking at the ASM Les has made it very compact


F1_000372 equ $ ; in [I2C LCD TEST 2.BAS] i2cLCDPrintStr(sMyString)
    lfsr 0,i2cLCDPrintStrpString
    lfsr 1,sMyString
    movlw 17
_pblb__15
    movf INDF1,F,0
    bz _pblb__16
    movff POSTINC1,POSTINC0
    decfsz WREG,F,0
    bra _pblb__15