Return Variable as an Alias to an SFR or Global Variable
As with parameters, a procedure can return an alias to a global variable or SFR (Special Function Register). This can be useful in some programs, and especially if the return variable needs to be a microcontroller SFR.
Example.
' A simple demo to show a return from a procedure placed in a global variable
'
Device = 24EP128MC202 ' Select the device to compile for
Declare Xtal = 140.03 ' Tell the compiler the device will be running at 140.03MHz
Declare Hserial_Baud = 9600 ' UART1 Baud rate
Declare Hrsout1_Pin = PORTB.11 ' Select pin to be used for USART1 TX
Dim MyWord as Word ' Create a global Word variable
'
' Create a demo procedure to multiply 2 parameter values and return the result
' in a global variable
'
Proc TestProc(pValue1 as Word, pValue2 as Word), MyWord
Result = pValue1 * pValue2
EndProc
' Setup the Oscillator to operate the device at 140.03MHz
' Fosc = (7.37 * 76) / (2 * 2) = 140.03MHz
PLL_Setup(76, 2, 2, $0300)
RPOR4.Byte1 = 1 ' Make PPS Pin RB11 U1TX
TestProc(2000, 10) ' Call the procedure to multiply the 2 parameters
HRSoutLn Dec MyWord ' Display the value held in MyWord (The procedure's return)
Notes
Procedures are a powerful feature of the language when used appropriately. Procedures are not supported in every instance of the compiler and if one is not supported within a particular command, a syntax error will be produced. In which case, an intermediate variable will need to be created to hold the procedure’s return result:
MyTemp = MyProc()
The compiler does not, yet, re-cycle RAM for parameters or local variables.
A parameter that is passed ByRef can only ever be a Byte, Word or Dword type, because it will hold the address of the variable passed to it and not its value. This is then used by either Ptr8, Ptr16, Ptr32 and Ptr64 in order to manipulate the address indirectly. An example of this mechanism is shown below:
' Demonstrate a procedure for finding the length of a word array
' given a particular terminator value
'
Device = 24FJ64GA002 ' Select the device to compile for
Declare Xtal = 16 ' Tell the compiler the device will be running at 16MHz
'
' USART1 declares
'
Declare Hserial_Baud = 9600 ' UART1 Baud rate
Declare Hrsout1_Pin = PORTB.14 ' Select the pin for TX with USART1
Dim MyLength As Word
Dim MyArray[20] As Word = 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,0
'---------------------------------------------------------------------------
' Find the length of a word array with a user defined terminator
' Input : pArrayIn holds the address of the word array
' : pTerminator holds the terminator value
' Output : Returns the length of the word array up to the terminator
' Notes : Uses indirect addressing using ByRef and Ptr16
'
Proc LengthOf(ByRef pInAddress As Word, pTerminator As Word), Word
Result = 0 ' Clear the result of the procedure
Do ' Create an infinite loop
'
' Increment up the array and exit the loop when the terminator is found
'
If Ptr16(pInAddress++) = pTerminator Then Break
Inc Result ' Increment the count
Loop
EndProc
'---------------------------------------------------------------------------
Main:
RPOR7 = 3 ' Make PPS Pin RP14 U1TX
'
' Find the length of a null terminated word array
'
MyLength = LengthOf(MyArray, 0)
HRSOutLn Dec MyLength ' Display the result on a serial terminal
See Also: Ptr8, Ptr16, Ptr32, Ptr64

