Positron Compiler Documentation

Conditional Directives ($ifdef, $ifndef, $if, $endif, $else and $elseif)

Positron8 · Revision 4.0.6.5 · PDF pages 478–480

Conditional directives allow parts of the code to be included or discarded if a certain condition is met.

$ifdef allows a section of a program to be compiled only if the macro that is specified as the parameter has been defined, no matter what its value is. For example:-

$ifdef TableSize
  Dim Table[TableSize] as Byte
$endif

In the above condition, the line of code Dim Table[TableSize] as Byte is only compiled if TableSize was previously defined with $define, independent of its value. If it was not defined, the line will not be included in the program compilation.

$ifndef serves for the exact opposite: the code between $ifndef and $endif directives is only compiled if the specified identifier has not been previously defined. For example:-

$ifndef TableSize
  $define TableSize 100
$endif
Dim Table[TableSize] as Byte
View original PDF page 478Open page in PDFOriginal PDF page 478

In the previous code, when arriving at this piece of code, the TableSize directive has not been defined yet. If it already existed it would keep its previous value since the $define directive would not be executed.

A valuable use for $ifdef is that of a code guard with include files. This allows multiple insertions of a file, but only the first will be used.

A typical code guard looks like:

$ifndef IncludeFileName
  $define IncludeFileName
  { BASIC Code goes Here }
$endif

The logic of the above snippet is that if the include file has not previously been loaded into the program, the $define IncludeFileName will not have been created, thus allowing the inclusion of the code between $ifndef and $endif. However, if the include file has been previously loaded, the $define will have already been created, and the condition will be false, thus not allowing the code to be used.

IncludeFileName must be unique to each file. Therefore, it is recommended that a derivative of the Include File’s name is used.

$if expression This directive invokes the arithmetic evaluator and compares the result in order to begin a conditional block. In particular, note that the logical value of expression is always true when it cannot be evaluated to a number.

The $if directive as well as the $elseif directive can use quite complex logic. For example:-

$if _device = _18F452 or _device = _18F4520 and _core = 16
  { BASIC Code Here }
$endif

There are several built in user defines that will help separate blocks of code. These are:-

• _device. This holds the microcontroller device name, as a string. i.e. _18F452,

_12F508, _16F684 etc. Notice the preceding underscore

• _core. This holds the device’s core. i.e. 12 for 12-bit core devices, 14 for 14-bit core

(16F) devices, and 16 for 18F devices.

•_ecore This is valid if the device is an enhanced 14-bit core type
•_ram.This holds the amount of RAM contained in the device (in bytes).
•_code. This holds the amount of flash memory in the device. In words for 12 and 14-bit

core devices, and bytes for 18F devices.

•_eeprom. This holds the amount of EEPROM memory the device contains.
•_ports. This holds the amount of I/O ports that the device has.
•_adc.This holds the amount of ADC channels the device has.
•_adcres. This holds the resolution of the device’s ADC. i.e. 8, 10, or 12.
•_uart.This holds the amount of UARTs or USARTS the device has. i.e. 0, 1, or 2
•_usb.This holds the amount of USB peripherals the device has. i.e. 0 or 1
•_flash. This informs of the ability for the device to access its own flash memory. 0 = no

access, 1 = read and write, and 2 = read only

View original PDF page 479Open page in PDFOriginal PDF page 479

The values for the user defines are taken from the compiler’s PPI files, and are only available if the compiler’s Device directive is included within the BASIC program.

Also within the compiler's .def files are all the device's SFRs (Special Function Registers) and SFR bit names. The SFR names are preceded by an underscore so they do not clash with the assembler's SFR names. For example:

STATUS is _STATUS ADRESL is _ADRESL

The SFR names are useful for compiling a piece of code only if that particular SFR is present in the device being used:

$ifdef  _T1CON
  { BASIC Code Here }
$endif
View original PDF page 480Open page in PDFOriginal PDF page 480