News:

;) This forum is the property of Proton software developers

Main Menu

Find out if variable is BYTE or WORD

Started by Frizie, Jun 28, 2025, 09:12 PM

Previous topic - Next topic

Frizie

Is there a way to find out (in a 18F PIC) if a variable is declared as BYTE or as WORD?
I need it for a procedure that has to store the value in a FRAM (or external EEPROM), and for that I need to know if it has to save the value in 1 or in 2 addresses.
Ohm sweet Ohm | www.picbasic.nl

trastikata

#1
Quote from: Frizie on Jun 28, 2025, 09:12 PMIs there a way to find out (in a 18F PIC) if a variable is declared as BYTE or as WORD?
I need it for a procedure that has to store the value in a FRAM (or external EEPROM), and for that I need to know if it has to save the value in 1 or in 2 addresses.

Assuming you can achieve that, but then how would you know how many address you have to access when reading back the value?

Or you are looking for pre-processor directives?

Frizie

Well, that's not a problem, but I wrote the problem down too briefly, Tratikata.
But after a night's sleep I come to the conclusion that I can't get any further, even if I knew whether the variable is a BYTE or a WORD.

I'll try something else here, if I still can't figure it out I'll write extensively here what I'm struggling with.
Ohm sweet Ohm | www.picbasic.nl

top204

#3
There are a couple of ways to accomplish finding out the size of a variable, and using it appropriately, but they are not recommended.

The first way is to use the SizeOf directive, which will hold the amount of RAM bytes used for a standard variable. For example, a Byte will read as 1, a Word will read as 2, a Long will read as 3, and a Dword and Float will read as 4. Because it reads how many RAM bytes are used for the variable type. So somethng like below could be used:

    Dim MyVar As Dword                      ' Change the variable type to show the below comparisons working
   
    If SizeOf(MyVar) = 1 Then               ' Does the variable contain 1 RAM byte?
        HRSOutLn "MyVar is a Byte"          ' Yes. So it could be a Byte variable
    ElseIf SizeOf(MyVar) = 2 Then           ' Does the variable contain 2 RAM bytes?
        HRSOutLn "MyVar is a Word"          ' Yes. So it could be a Word variable
    ElseIf SizeOf(MyVar) = 3 Then           ' Does the variable contain 3 RAM bytes?
        HRSOutLn "MyVar is a Long"          ' Yes. So it could be a Long variable
    ElseIf SizeOf(MyVar) = 4 Then           ' Does the variable contain 4 RAM bytes?
        HRSOutLn "MyVar is a DWord"         ' Yes. So it could be a Dword variable
    Else
        HRSOutLn "Unknown variable size"
    EndIf

Very crude, and a bit inefficient, but it works. The comparisons are performed with constants to the compiler, so they are not too inefficient. However, arrays and Strings with the same amount of elements will also show as vraiable types, so it would need to be implemented with controls.


The second way is using the old "Macro" mechanism, that was used before Procedures were added to the compiler. For example, a pointless, macro is shown below, but it does shows the principle:

$define LoadVariable(pVarin, pVarout) _LoadVariable pVarin, pVarout

_LoadVariable Macro pVarin, pVarout      
    #if(Prm_1 == Byte)                   
        #if(Prm_2 == Byte)                
            Byte_Byte pVarin, pVarout            
        #endif                           
        #if(Prm_2 == Word)                
            Byte_Word pVarin, pVarout               
        #endif
        #if(Prm_2 == Dword)                
            Byte_Dword pVarin, pVarout               
        #endif                           
    #endif 
   
    #if(Prm_1 == Word)                   
        #if(Prm_2 == Byte)                
            Word_Byte pVarin, pVarout            
        #endif                           
        #if(Prm_2 == Word)                
            Word_Word pVarin, pVarout               
        #endif
        #if(Prm_2 == Dword)                
            Word_Dword pVarin, pVarout               
        #endif                           
    #endif                              
Endm

Than to use the macro: LoadVariable(MyByte, MyWord)

As can be seen, it can only operate inline, and the parameter variable names of the macro are not recognised by the compiler, so other macros need to be used to load and read them.

It is something that the compiler used for many years, so it does work, and can be extremely efficient, but is no longer required. However, I left it in place.

trastikata

Quote from: Frizie on Jun 29, 2025, 07:38 AMWell, that's not a problem, but I wrote the problem down too briefly, Tratikata.

Well, if you start writing in RAM sequentially random 1 or 2 byte variables could be a problem reading them back without any predetermined scheme and if there is such scheme then determining the variable size in order to write it in external RAM is not needed because the variable size has already been declared and therefore can be assigned the appropriate space in the external RAM according the predetermined scheme.

Quote from: Frizie on Jun 29, 2025, 07:38 AMBut after a night's sleep I come to the conclusion that I can't get any further,

If you describe the problem, maybe we can brainstorm some possible solutions?
 

Frizie

Problem solved.

The idea is to store the WORD variables on a different address part in FRAM than the BYTE variables.
That has now been achieved, WORDs are on FRAM address %10100000 and the BYTES on %101000010 (the last bit is the R/W bit)


$define FRAMWORD    %10100000 ;ID-slave adres FRAM FM24C16B for storing WORDs
$define FRAMBYTE    %10100010 ;ID-slave adres FRAM FM24C16B for storing BYTEs


;FRAM addresses to store WORDs in FRAM
SYMBOL EE_LosseBits0= (FRAMWORD << 8) + '+1 
SYMBOL EE_LosseBits1= (FRAMWORD << 8) + '+3 
SYMBOL EE_LosseBits2= (FRAMWORD << 8) + '+5 
SYMBOL EE_LosseBits3= (FRAMWORD << 8) + '+7 
SYMBOL EE_Druk1Boven= (FRAMWORD << 8) + '+9 
SYMBOL EE_Druk1Onder= (FRAMWORD << 8) + 10 '+11 
SYMBOL EE_Druk2Boven= (FRAMWORD << 8) + 12 '+13 
SYMBOL EE_Druk2Onder= (FRAMWORD << 8) + 14 '+15 
SYMBOL EE_EncIJking = (FRAMWORD << 8) + 16 '+17 
SYMBOL EE_PinCode  = (FRAMWORD << 8) + 18 '+19 
SYMBOL EE_PinKlant  = (FRAMWORD << 8) + 20 '+21 
SYMBOL EE_PotBoven  = (FRAMWORD << 8) + 22 '+23 
SYMBOL EE_PotOnder  = (FRAMWORD << 8) + 24 '+25 
SYMBOL EE_ProdMeters= (FRAMWORD << 8) + 26 '+27 
SYMBOL EE_ProdStuks = (FRAMWORD << 8) + 28 '+29 
SYMBOL EE_Thermo0  = (FRAMWORD << 8) + 30 '+31 
SYMBOL EE_Thermo1  = (FRAMWORD << 8) + 32 '+33 
SYMBOL EE_TotalCutH = (FRAMWORD << 8) + 34 '+35 
SYMBOL EE_TotalCutL = (FRAMWORD << 8) + 36 '+37 

;FRAM addresses to store BYTEs in FRAM
SYMBOL EE_AccSpeed  = (FRAMBYTE << 8) +
SYMBOL EE_DecSpeed  = (FRAMBYTE << 8) +
SYMBOL EE_DrukEenhd = (FRAMBYTE << 8) +
SYMBOL EE_FRAM      = (FRAMBYTE << 8) +
SYMBOL EE_MaatEenhd = (FRAMBYTE << 8) +
SYMBOL EE_MaxSpeed  = (FRAMBYTE << 8) +
SYMBOL EE_MaxTemp0  = (FRAMBYTE << 8) +
SYMBOL EE_MaxTemp1  = (FRAMBYTE << 8) +
SYMBOL EE_MinSpeed  = (FRAMBYTE << 8) +
SYMBOL EE_MinTemp0  = (FRAMBYTE << 8) +
SYMBOL EE_MinTemp1  = (FRAMBYTE << 8) + 10
SYMBOL EE_Offset0  = (FRAMBYTE << 8) + 11
SYMBOL EE_Offset1  = (FRAMBYTE << 8) + 12
SYMBOL EE_PowerOut  = (FRAMBYTE << 8) + 13
SYMBOL EE_SpeedInst = (FRAMBYTE << 8) + 14
SYMBOL EE_Taal      = (FRAMBYTE << 8) + 15
SYMBOL EE_TempEenhd = (FRAMBYTE << 8) + 16


In my procedure to write to the FRAM:

PROC FRAMwrite(BusAdres AS WORD, BusData AS WORD)
  IF BusAdres.HIGHBYTE < FRAMBYTE THEN                           
    I2COUT SDA2, SCL2, FRAMWORD, BusAdres.LOWBYTE, [BusData]   
  ELSE                                                           
    I2COUT SDA2, SCL2, FRAMBYTE, BusAdres.LOWBYTE, [BusData.LOWBYTE]   
  ENDIF
ENDPROC

And reading from the FRAM (in this case from address EE_Thermo0):

I2CIN SDA2, SCL2, FRAMWORD, EE_Thermo0.LOWBYTE, [MyWordVariable]

Reading the FRAM will also become a procedure later.
But the program is too big to explain the entire code and I´m still busy with it.

The problem I had for half a day is that it only worked halfway.
But that was because I forgot to put .HIGHBYTE after ´BusAdres´ in the FRAMwrite procedure in the line:

IF BusAdres.HIGHBYTE < FRAMBYTE THEN...

________________________

But I have another question:
Is it possible to use a meta-macro or the pre-processor to automate the assignment of constants to constant names, as above?
Because the constant numbering is only increased by 1 (or by 2 for the FRAM addresses for WORDs)
Ohm sweet Ohm | www.picbasic.nl