Chapter 5: Built-in and Library Routines
Introduction
BASIC was designed with focus on simplicity of use. Great number of built-in and library routines are included to help you develop your applications quickly and easily.
5.1 Built-in Routines
BASIC incorporates a set of built-in functions and procedures. They are provided to make writing programs faster and easier. You can call built-in functions and procedures in any part of the program.
5.1.1 SetBit – Sets the specified bit
| Prototype | sub procedure SetBit(dim byref Reg as byte, dim Bit as byte) |
| Description | Sets <Bit> of register <Reg>. Any SFR (Special Function Register) or variable of byte type can pass as valid variable parameter, but constants should be in range [0..7]. |
| Example |
SetBit(PORTB,2) ' set bit RB2 |
5.1.2 ClearBit – Clears the specified bit
| Prototype | sub procedure ClearBit(dim byref Reg as byte, dim Bit as byte) |
| Description | Clears <Bit> of register <Reg>. Any SFR (Special Function Register) or variable of byte type can pass as valid variable parameter, but constants should be in range [0..7]. |
| Example |
ClearBit(PORTC,7) ' clear bit RC7 |
5.1.3 TestBit – Tests the specified bit
| Prototype | sub function TestBit(dim byref Reg as byte, dim Bit as byte) as byte |
| Description | Tests <Bit> of register <Reg>. If set, returns 1, otherwise 0. Any SFR (Special Function Register) or variable of byte type can pass as valid variable parameter, but constants should be in range [0..7]. |
| Example |
TestBit(PORTA,2) ' returns 1 if PORTA bit RA2 is 1, returns 0 otherwise |
5.1.4 Lo – Extract one byte from the specified parameter
| Prototype | sub function Lo(dim Par as byte..longint) as byte |
| Description | Returns byte 0 of <Par>, assuming that word/integer comprises bytes 1 and 0, and longint comprises bytes 3, 2, 1, and 0. |
| Example |
Lo(A) ' returns lower byte of variable A |
5.1.5 Hi – Extract one byte from the specified parameter
| Prototype | sub function Hi(dim arg as word..longint) as byte |
| Description | Returns byte 1 of <Par>, assuming that word/integer comprises bytes 1 and 0, and longint comprises bytes 3, 2, 1, and 0. |
| Example |
Hi(Aa) ' returns hi byte of variable Aa |
5.1.6 Higher – Extract one byte from the specified parameter
| Prototype | sub function Higher(dim Par as longint) as byte |
| Description | Returns byte 2 of <Par>, assuming that longint comprises bytes 3, 2, 1, and 0. |
| Example |
Higher(Aaaa) ' returns byte next to the highest byte of variable Aaaa |
5.1.7 Highest – Extract one byte from the specified parameter
| Prototype | sub function Highest(dim arg as longint) as byte |
| Description | Returns byte 3 of <Par>, assuming that longint comprises bytes 3, 2, 1, and 0. |
| Example |
Highest(Aaaa) ' returns the highest byte of variable Aaaa |
5.1.8 Delay_us – Software delay in us
| Prototype | sub procedure Delay_us(const Count as word) |
| Description | Routine creates a software delay in duration of <Count> microseconds. |
| Example |
Delay_us(100) ' creates software delay equal to 100 µs |
5.1.9 Delay_ms – Software delay in ms
| Prototype | sub procedure Delay_ms(const Count as word) |
| Description | Routine creates a software delay in duration of <Count> milliseconds. |
| Example |
Delay_ms(1000) ' creates software delay equal to 1s |
5.1.10 Inc – Increases variable by 1
| Prototype | sub procedure Inc(byref Par as byte..longint) |
| Description | Routine increases <Par> by one. |
| Example |
Inc(Aaaa) ' increments variable Aaaa by 1 |
5.1.11 Dec – Decreases variable by 1
| Prototype | sub procedure Dec(byref Par as byte..longint) |
| Description | Routine decreases <Par> by one. |
| Example |
Dec(Aaaa) ' decrements variable Aaaa by 1 |
5.1.12 StrLen – Returns length of string
| Prototype | sub function StrLen(dim Text as string) as byte |
| Description | Routine returns length of string <Text> as byte. |
| Example |
StrLen(Text) ' returns string length as byte |
5.2 Library Routines
A comprehensive collection of functions and procedures is provided for simplifying the initialization and use of PIC MCU and its hardware modules. Routines currently includes libraries for ADC, I2C, USART, SPI, PWM, driver for LCD, drivers for internal and external CAN modules, flexible 485 protocol, numeric formatting routines…
5.2.1 Numeric Formatting Routines
Numeric formatting routines convert byte, short, word, and integer to string. You can get text representation of numerical value by passing it to one of the routines listed below.
5.2.1.1 ByteToStr – Converts byte to string
| Prototype | sub procedure ByteToStr(dim input as byte, dim byref txt as char[6]) |
| Description |
Parameter <input> represents numerical value of byte type that should be converted to string; parameter <txt> is passed by the address and contains the result of conversion. Parameter <txt> has to be of sufficient size to fit the converted string. |
| Example |
ByteToStr(Counter, Message) ' Copies value of byte Counter into string Message |
5.2.1.2 WordToStr – Converts word to string
| Prototype | sub procedure WordToStr(dim input as word, dim byref txt as char[6]) |
| Description |
Parameter <input> represents numerical value of word type that should be converted to string; parameter <txt> is passed by the address and contains the result of conversion. Parameter <txt> has to be of sufficient size to fit the converted string. |
| Example |
WordToStr(Counter, Message) ' Copies value of word Counter into string Message |
5.2.1.3 ShortToStr – Converts short to string
| Prototype | sub procedure ShortToStr(dim input as short, dim byref txt as char[6]) |
| Description |
Parameter <input> represents numerical value of short type that should be converted to string; parameter <txt> is passed by the address and contains the result of conversion. Parameter <txt> has to be of sufficient size to fit the converted string. |
| Example |
ShortToStr(Counter, Message) ' Copies value of short Counter into string Message |
5.2.1.4 IntToStr – Converts integer to string
| Prototype | sub procedure IntToStr(dim input as integer, dim byref txt as char[6]) |
| Description |
Parameter <input> represents numerical value of integer type that should be converted to string; parameter <txt> is passed by the address and contains the result of conversion. Parameter <txt> has to be of sufficient size to fit the converted string. |
| Example |
IntToStr(Counter, Message) ' Copies value of integer Counter into string Message |
5.2.1.5 Bcd2Dec – Converts 8-bit BCD value to decimal
| Prototype | sub procedure Bcd2Dec(dim bcd_num as byte) as byte |
| Description |
Function converts 8-bit BCD numeral to its decimal equivalent and returns the result as byte. |
| Example |
dim a as byte dim b as byte ... a = 140 b = Bcd2Dec(a) ' b equals 224 now |
5.2.1.6 Bcd2Dec – Converts 8-bit decimal to BCD
| Prototype | sub procedure Dec2Bcd(dim dec_num as byte) as byte |
| Description |
Function converts 8-bit decimal numeral to BCD and returns the result as byte. |
| Example |
dim a as byte dim b as byte ... a = 224 b = Dec2Bcd(a) ' b equals 140 now |
5.2.1.7 Bcd2Dec – Converts 16-bit BCD value to decimal
| Prototype | sub procedure Bcd2Dec16(dim bcd_num as word) as word |
| Description |
Function converts 16-bit BCD numeral to its decimal equivalent and returns the result as byte. |
| Example |
dim a as word dim b as word ... a = 1234 b = Bcd2Dec16(a) ' b equals 4660 now |
5.2.1.8 Bcd2Dec – Converts 16-bit BCD value to decimal
| Prototype | sub procedure Dec2Bcd16(dim dec_num as word) as word |
| Description |
Function converts 16-bit decimal numeral to BCD and returns the result as word. |
| Example |
dim a as word dim b as word ... a = 4660 b = Dec2Bcd16(a) ' b equals 1234 now |
5.2.2 ADC Library
ADC (Analog to Digital Converter) module is available with a number of PIC MCU models. Library function ADC_Read is included to provide you comfortable work with the module. The function is currently unsupported by the following PIC MCU models: P18F2331, P18F2431, P18F4331, and P18F4431.
5.2.2.1 ADC_Read – Get the results of AD conversion
| Prototype | sub function ADC_Read(dim Channel as byte) as word |
| Description | Routine initializes ADC module to work with RC clock. Clock determines the time period necessary for performing AD conversion (min 12TAD). RC sources typically have Tad 4uS. Parameter <Channel> determines which channel will be sampled. Refer to the device data sheet for information on device channels. |
| Example |
res = ADC_Read(2) ' reads channel 2 and stores value in variable res |

ADC HW connection
5.2.3 CAN Library
The Controller Area Network module (CAN) is serial interface, used for communicating with other peripherals or microcontrollers. CAN module is available with a number of PIC MCU models. BASIC includes a set of library routines to provide you comfortable work with the module. More details about CAN can be found in appropriate literature and on mikroElektronika Web site.
5.2.3.1 CANSetOperationMode – Sets CAN to requested mode
| Prototype | sub procedure CANSetOperationMode(dim Mode as byte, dim Wait as byte) |
| Description |
The procedure copies <Mode> to CANSTAT and sets CAN to requested mode. Operation <Mode> code can take any of predefined constant values. If Wait is true, this is a blocking call. It won't return until requested mode is set. If Wait is false, this is a non-blocking call. It does not verify if CAN module is switched to requested mode or not. Caller must use CANGetOperationMode() to verify correct operation mode before performing mode specific operation. |
| Example |
CANSetOperationMode(CAN_MODE_LISTEN, TRUE) ' Sets CAN to Listen mode |
5.2.3.2 CANGetOperationMode – Returns the current operation mode of CAN
| Prototype | sub function CANGetOperationMode as byte |
| Description | The function returns the current operation mode of CAN. |
| Example |
CANGetOperationMode |
5.2.3.3 CANInitialize – Initializes CAN
| Prototype | sub procedure CANInitialize(dim SJW as byte, dim BRP as byte, dim PHSEG1 as byte, dim PHSEG2 as byte, dim PROPSEG as byte, dim CAN_CONFIG_FLAGS as byte) |
| Description |
The procedure initializes CAN module. CAN must be in Configuration mode or else these values will be ignored. Parameters: Output:
If (CAN_CONFIG_FLAGS and CAN_CONFIG_VALID_XTD_MSG) <> 0
Set all filters to XTD_MSG
Else if (config and CONFIG_VALID_STD_MSG) <> 0
Set all filters to STD_MSG
Else
Set half of the filters to STD, and the rest to XTD_MSG
Side Effects: |
| Example |
dim aa as byte
aa = CAN_CONFIG_SAMPLE_THRICE and ' form value to be used
CAN_CONFIG_PHSEG2_PRG_ON and ' with CANInitialize
CAN_CONFIG_STD_MSG and
CAN_CONFIG_DBL_BUFFER_ON and
CAN_CONFIG_VALID_XTD_MSG and
CAN_CONFIG_LINE_FILTER_OFF
CANInitialize(1, 1, 3, 3, 1, aa)
|
5.2.3.4 CANSetBaudRate – Sets CAN Baud Rate
| Prototype | sub procedure CANSetBaudRate(dim SJW as byte, dim BRP as byte, dim PHSEG1 as byte, dim PHSEG2 as byte, dim PROPSEG as byte, dim CAN_CONFIG_FLAGS as byte) |
| Description |
The procedure sets CAN Baud Rate. CAN must be in Configuration mode or else these values will be ignored. Parameters: Output: |
| Example |
CANSetBaudRate(1, 1, 3, 3, 1, aa) |
5.2.3.5 CANSetMask – Sets the CAN message mask
| Prototype | sub procedure CANSetMask(CAN_MASK as byte, val as longint, dim CAN_CONFIG_FLAGS as byte) |
| Description |
The procedure sets the CAN message mask. CAN must be in Configuration mode. If not, all values will be ignored. Parameters: Output: |
| Example |
CANSetMask(CAN_MASK_B2, -1, CAN_CONFIG_XTD_MSG) |
5.2.3.6 CANSetFilter – Sets the CAN message filter
| Prototype | sub procedure CANSetFilter(dim CAN_FILTER as byte, dim val as longint, dim CAN_CONFIG_FLAGS as byte) |
| Description |
The procedure sets the CAN message filter. CAN must be in Configuration mode. If not, all values will be ignored. Parameters: Output: |
| Example |
CANSetFilter(CAN_FILTER_B1_F1, 3, CAN_CONFIG_XTD_MSG) |
5.2.3.7 CANWrite – Queues message for transmission
| Prototype | sub function CANWrite(dim id as longint, dim byref Data : as byte[8], dim DataLen as byte, dim CAN_TX_MSG_FLAGS as byte) as byte |
| Description |
If at least one empty transmit buffer is found, given message is queued for the transmission. If none found, FALSE value is returned. CAN must be in Normal mode. Parameters: |
| Example |
aa1 = CAN_TX_PRIORITY_0 and ' form value to be used
CAN_TX_XTD_FRAME and ' with CANWrite
CAN_TX_NO_RTR_FRAME
CANWrite(-1, data, 1, aa1)
|
5.2.3.8 CANRead – Extracts and reads the message
| Prototype | sub function CANRead(dim byref id as longint, dim byref Data as byte[8], dim byref DataLen as byte, dim byref CAN_RX_MSG_FLAGS as byte) as byte |
| Description |
If at least one full receive buffer is found, the function extracts and returns the message as byte. If none found, FALSE value is returned. CAN must be in mode in which receiving is possible. Parameters: |
| Example |
res = CANRead(id, Data, 7, 0) |
5.2.3.9 CAN Library Constants
You need to be familiar with constants that are provided for use with the CAN module. All of the following constants are predefined in CAN library.
CAN_OP_MODE
These constant values define CAN module operation mode. CANSetOperationMode() routine requires this code. These values must be used by itself, i.e. they cannot be ANDed to form multiple values.
const CAN_MODE_BITS = $E0 ' Use these to access opmode bits const CAN_MODE_NORMAL = 0 const CAN_MODE_SLEEP = $20 const CAN_MODE_LOOP = $40 const CAN_MODE_LISTEN = $60 const CAN_MODE_CONFIG = $80
CAN_TX_MSG_FLAGS
These constant values define flags related to transmission of a CAN message. There could be more than one this flag ANDed together to form multiple flags.
const CAN_TX_PRIORITY_BITS = $03 const CAN_TX_PRIORITY_0 = $FC ' XXXXXX00 const CAN_TX_PRIORITY_1 = $FD ' XXXXXX01 const CAN_TX_PRIORITY_2 = $FE ' XXXXXX10 const CAN_TX_PRIORITY_3 = $FF ' XXXXXX11 const CAN_TX_FRAME_BIT = $08 const CAN_TX_STD_FRAME = $FF ' XXXXX1XX const CAN_TX_XTD_FRAME = $F7 ' XXXXX0XX const CAN_TX_RTR_BIT = $40 const CAN_TX_NO_RTR_FRAME = $FF ' X1XXXXXX const CAN_TX_RTR_FRAME = $BF ' X0XXXXXX
CAN_RX_MSG_FLAGS
These constant values define flags related to reception of a CAN message. There could be more than one this flag ANDed together to form multiple flags. If a particular bit is set; corresponding meaning is TRUE or else it will be FALSE.
e.g.
if (MsgFlag and CAN_RX_OVERFLOW) <> 0 then ' Receiver overflow has occurred. ' We have lost our previous message.
const CAN_RX_FILTER_BITS = $07 ' Use these to access filter bits const CAN_RX_FILTER_1 = $00 const CAN_RX_FILTER_2 = $01 const CAN_RX_FILTER_3 = $02 const CAN_RX_FILTER_4 = $03 const CAN_RX_FILTER_5 = $04 const CAN_RX_FILTER_6 = $05 const CAN_RX_OVERFLOW = $08 ' Set if Overflowed else cleared const CAN_RX_INVALID_MSG = $10 ' Set if invalid else cleared const CAN_RX_XTD_FRAME = $20 ' Set if XTD message else cleared const CAN_RX_RTR_FRAME = $40 ' Set if RTR message else cleared const CAN_RX_DBL_BUFFERED = $80 ' Set if this message was hardware double-buffered
CAN_MASK
These constant values define mask codes. Routine CANSetMask()requires this code as one of its arguments. These enumerations must be used by itself i.e. it cannot be ANDed to form multiple values.
const CAN_MASK_B1 = 0 const CAN_MASK_B2 = 1
CAN_FILTER
These constant values define filter codes. Routine CANSetFilter() requires this code as one of its arguments. These enumerations must be used by itself, i.e. it cannot be ANDed to form multiple values.
const CAN_FILTER_B1_F1 = 0 const CAN_FILTER_B1_F2 = 1 const CAN_FILTER_B2_F1 = 2 const CAN_FILTER_B2_F2 = 3 const CAN_FILTER_B2_F3 = 4 const CAN_FILTER_B2_F4 = 5
CAN_CONFIG_FLAGS
These constant values define flags related to configuring CAN module. Routines CANInitialize() and CANSetBaudRate() use these codes. One or more these values may be ANDed to form multiple flags
const CAN_CONFIG_DEFAULT = $FF ' 11111111 const CAN_CONFIG_PHSEG2_PRG_BIT = $01 const CAN_CONFIG_PHSEG2_PRG_ON = $FF ' XXXXXXX1 const CAN_CONFIG_PHSEG2_PRG_OFF = $FE ' XXXXXXX0 const CAN_CONFIG_LINE_FILTER_BIT = $02 const CAN_CONFIG_LINE_FILTER_ON = $FF ' XXXXXX1X const CAN_CONFIG_LINE_FILTER_OFF = $FD ' XXXXXX0X const CAN_CONFIG_SAMPLE_BIT = $04 const CAN_CONFIG_SAMPLE_ONCE = $FF ' XXXXX1XX const CAN_CONFIG_SAMPLE_THRICE = $FB ' XXXXX0XX const CAN_CONFIG_MSG_TYPE_BIT = $08 const CAN_CONFIG_STD_MSG = $FF ' XXXX1XXX const CAN_CONFIG_XTD_MSG = $F7 ' XXXX0XXX const CAN_CONFIG_DBL_BUFFER_BIT = $10 const CAN_CONFIG_DBL_BUFFER_ON = $FF ' XXX1XXXX const CAN_CONFIG_DBL_BUFFER_OFF = $EF ' XXX0XXXX const CAN_CONFIG_MSG_BITS = $60 const CAN_CONFIG_ALL_MSG = $FF ' X11XXXXX const CAN_CONFIG_VALID_XTD_MSG = $DF ' X10XXXXX const CAN_CONFIG_VALID_STD_MSG = $BF ' X01XXXXX const CAN_CONFIG_ALL_VALID_MSG = $9F ' X00XXXXX

Example of interfacing CAN transceiver with MCU and bus
5.2.4 CANSPI Library
The Controller Area Network module (CAN) is serial interface, used for communicating with other peripherals or microcontrollers. CAN module is available with a number of PIC MCU models. MCP2515 or MCP2510 are modules that enable any chip with SPI interface to communicate over CAN bus. BASIC includes a set of library routines to provide you comfortable work with the module. More details about CAN can be found in appropriate literature and on mikroElektronika Web site.
Note: CANSPI routines are supported by any PIC MCU model that has SPI interface on PORTC. Also, CS pin of MCP2510 or MCP2515 must be connected to RC0 pin.
5.2.4.1 CANSPISetOperationMode – Sets CAN to requested mode
| Prototype | sub procedure CANSPISetOperationMode(dim mode as byte, dim Wait as byte) |
| Description |
The procedure copies <mode> to CANSTAT and sets CAN to requested mode. Operation <mode> code can take any of predefined constant values. If Wait is true, this is a blocking call. It won't return until requested mode is set. If Wait is false, this is a non-blocking call. It does not verify if CAN module is switched to requested mode or not. Caller must use CANGetOperationMode() to verify correct operation mode before performing mode specific operation. |
| Example |
CANSPISetOperationMode(CAN_MODE_LISTEN, TRUE) ' Sets CAN to Listen mode |
5.2.4.2 CANSPIGetOperationMode – Returns the current operation mode of CAN
| Prototype | sub function CANSPIGetOperationMode as byte |
| Description |
The function returns the current operation mode of CAN. |
| Example |
CANGetOperationMode |
5.2.4.3 CANSPIInitialize – Initializes CANSPI
| Prototype | sub procedure CANSPIInitialize(dim SJW as byte, dim BRP as byte, dim PHSEG1 as byte, dim PHSEG2 as byte, dim PROPSEG as byte, dim CAN_CONFIG_FLAGS as byte) |
| Description |
The procedure initializes CAN module. CAN must be in Configuration mode or else these values will be ignored. Parameters: Output:
If (CAN_CONFIG_FLAGS and CAN_CONFIG_VALID_XTD_MSG) <> 0
Set all filters to XTD_MSG
Else if (config and CONFIG_VALID_STD_MSG) <> 0
Set all filters to STD_MSG
Else
Set half of the filters to STD, and the rest to XTD_MSG
Side Effects: |
| Example |
dim aa as byte
aa = CAN_CONFIG_SAMPLE_THRICE and ' form value to be used
CAN_CONFIG_PHSEG2_PRG_ON and ' with CANSPIInitialize
CAN_CONFIG_STD_MSG and
CAN_CONFIG_DBL_BUFFER_ON and
CAN_CONFIG_VALID_XTD_MSG and
CAN_CONFIG_LINE_FILTER_OFF
CANInitialize(1, 1, 3, 3, 1, aa)
|
5.2.4.4 CANSPISetBaudRate – Sets CAN Baud Rate
| Prototype | sub procedure CANSPISetBaudRate(dim SJW as byte, dim BRP as byte, dim PHSEG1 as byte, dim PHSEG2 as byte, dim PROPSEG as byte, dim CAN_CONFIG_FLAGS as byte) |
| Description |
The procedure sets CAN Baud Rate. CAN must be in Configuration mode or else these values will be ignored. Parameters: Output: |
| Example |
CANSPISetBaudRate(1, 1, 3, 3, 1, aa) |
5.2.4.5 CANSPISetMask – Sets the CAN message mask
| Prototype | sub procedure CANSPISetMask(CAN_MASK as byte, val as longint, dim CAN_CONFIG_FLAGS as byte) |
| Description |
The procedure sets the CAN message mask. CAN must be in Configuration mode. If not, all values will be ignored. Parameters: Output: |
| Example |
CANSPISetMask(CAN_MASK_B2, -1, CAN_CONFIG_XTD_MSG) |
5.2.4.6 CANSPISetFilter – Sets the CAN message filter
| Prototype | sub procedure CANSPISetFilter(dim CAN_FILTER as byte, dim val as longint, dim CAN_CONFIG_FLAGS as byte) |
| Description |
The procedure sets the CAN message filter. CAN must be in Configuration mode. If not, all values will be ignored. Parameters: Output: |
| Example |
CANSPISetFilter(CAN_FILTER_B1_F1, 3, CAN_CONFIG_XTD_MSG) |
5.2.4.7 CANSPIWrite – Queues message for transmission
| Prototype | sub function CANSPIWrite(dim id as longint, dim byref Data : as byte[8], dim DataLen as byte, dim CAN_TX_MSG_FLAGS as byte) as byte |
| Description |
If at least one empty transmit buffer is found, given message is queued for the transmission. If none found, FALSE value is returned. CAN must be in Normal mode. Parameters: |
| Example |
aa1 = CAN_TX_PRIORITY_0 and ' form value to be used
CAN_TX_XTD_FRAME and ' with CANSPIWrite
CAN_TX_NO_RTR_FRAME
CANSPIWrite(-1, data, 1, aa1)
|
5.2.4.8 CANSPIRead – Extracts and reads the message
| Prototype | sub function CANSPIRead(dim byref id as longint, dim byref Data as byte[8], dim byref DataLen as byte, dim byref CAN_RX_MSG_FLAGS as byte) as byte |
| Description |
If at least one full receive buffer is found, the function extracts and returns the message as byte. If none found, FALSE value is returned. CAN must be in mode in which receiving is possible. Parameters: |
| Example |
res = CANSPIRead(id, Data, 7, 0) |
5.2.4.9 CANSPI Library Constants
You need to be familiar with constants that are provided for use with the CAN module. All of the following constants are predefined in CANSPI library.
CAN_OP_MODE
These constant values define CAN module operation mode. CANSetOperationMode() routine requires this code. These values must be used by itself, i.e. they cannot be ANDed to form multiple values.
const CAN_MODE_BITS = $E0 ' Use these to access opmode bits const CAN_MODE_NORMAL = 0 const CAN_MODE_SLEEP = $20 const CAN_MODE_LOOP = $40 const CAN_MODE_LISTEN = $60 const CAN_MODE_CONFIG = $80
CAN_TX_MSG_FLAGS
These constant values define flags related to transmission of a CAN message. There could be more than one this flag ANDed together to form multiple flags.
const CAN_TX_PRIORITY_BITS = $03 const CAN_TX_PRIORITY_0 = $FC ' XXXXXX00 const CAN_TX_PRIORITY_1 = $FD ' XXXXXX01 const CAN_TX_PRIORITY_2 = $FE ' XXXXXX10 const CAN_TX_PRIORITY_3 = $FF ' XXXXXX11 const CAN_TX_FRAME_BIT = $08 const CAN_TX_STD_FRAME = $FF ' XXXXX1XX const CAN_TX_XTD_FRAME = $F7 ' XXXXX0XX const CAN_TX_RTR_BIT = $40 const CAN_TX_NO_RTR_FRAME = $FF ' X1XXXXXX const CAN_TX_RTR_FRAME = $BF ' X0XXXXXX
CAN_RX_MSG_FLAGS
These constant values define flags related to reception of a CAN message. There could be more than one this flag ANDed together to form multiple flags. If a particular bit is set; corresponding meaning is TRUE or else it will be FALSE.
e.g.
if (MsgFlag and CAN_RX_OVERFLOW) <> 0 then ' Receiver overflow has occurred. ' We have lost our previous message.
const CAN_RX_FILTER_BITS = $07 ' Use these to access filter bits const CAN_RX_FILTER_1 = $00 const CAN_RX_FILTER_2 = $01 const CAN_RX_FILTER_3 = $02 const CAN_RX_FILTER_4 = $03 const CAN_RX_FILTER_5 = $04 const CAN_RX_FILTER_6 = $05 const CAN_RX_OVERFLOW = $08 ' Set if Overflowed else cleared const CAN_RX_INVALID_MSG = $10 ' Set if invalid else cleared const CAN_RX_XTD_FRAME = $20 ' Set if XTD message else cleared const CAN_RX_RTR_FRAME = $40 ' Set if RTR message else cleared const CAN_RX_DBL_BUFFERED = $80 ' Set if this message was hardware double-buffered
CAN_MASK
These constant values define mask codes. Routine CANSetMask()requires this code as one of its arguments. These enumerations must be used by itself i.e. it cannot be ANDed to form multiple values.
const CAN_MASK_B1 = 0 const CAN_MASK_B2 = 1
CAN_FILTER
These constant values define filter codes. Routine CANSetFilter() requires this code as one of its arguments. These enumerations must be used by itself, i.e. it cannot be ANDed to form multiple values.
const CAN_FILTER_B1_F1 = 0 const CAN_FILTER_B1_F2 = 1 const CAN_FILTER_B2_F1 = 2 const CAN_FILTER_B2_F2 = 3 const CAN_FILTER_B2_F3 = 4 const CAN_FILTER_B2_F4 = 5
CAN_CONFIG_FLAGS
These constant values define flags related to configuring CAN module. Routines CANInitialize() and CANSetBaudRate() use these codes. One or more these values may be ANDed to form multiple flags
const CAN_CONFIG_DEFAULT = $FF ' 11111111 const CAN_CONFIG_PHSEG2_PRG_BIT = $01 const CAN_CONFIG_PHSEG2_PRG_ON = $FF ' XXXXXXX1 const CAN_CONFIG_PHSEG2_PRG_OFF = $FE ' XXXXXXX0 const CAN_CONFIG_LINE_FILTER_BIT = $02 const CAN_CONFIG_LINE_FILTER_ON = $FF ' XXXXXX1X const CAN_CONFIG_LINE_FILTER_OFF = $FD ' XXXXXX0X const CAN_CONFIG_SAMPLE_BIT = $04 const CAN_CONFIG_SAMPLE_ONCE = $FF ' XXXXX1XX const CAN_CONFIG_SAMPLE_THRICE = $FB ' XXXXX0XX const CAN_CONFIG_MSG_TYPE_BIT = $08 const CAN_CONFIG_STD_MSG = $FF ' XXXX1XXX const CAN_CONFIG_XTD_MSG = $F7 ' XXXX0XXX const CAN_CONFIG_DBL_BUFFER_BIT = $10 const CAN_CONFIG_DBL_BUFFER_ON = $FF ' XXX1XXXX const CAN_CONFIG_DBL_BUFFER_OFF = $EF ' XXX0XXXX const CAN_CONFIG_MSG_BITS = $60 const CAN_CONFIG_ALL_MSG = $FF ' X11XXXXX const CAN_CONFIG_VALID_XTD_MSG = $DF ' X10XXXXX const CAN_CONFIG_VALID_STD_MSG = $BF ' X01XXXXX const CAN_CONFIG_ALL_VALID_MSG = $9F ' X00XXXXX

Example of interfacing CAN transceiver MCP2551, and MCP2510 with MCU and bus
5.2.5 Compact Flash Library
Compact Flash Library provides routines for accessing data on Compact Flash card (abbrev. CF further in text). CF cards are widely used memory elements, commonly found in digital cameras. Great capacity (8MB ~ 2GB, and more) and excellent access time of typically few microseconds make them very attractive for microcontroller applications.
In CF card, data is divided into sectors, one sector usually comprising 512 bytes (few older models have sectors of 256B). Read and write operations are not performed directly, but successively through 512B buffer. Following routines can be used for CF with FAT16 and FAT32 file system.
Note: routines for file handling (CF_File_Write_Init, CF_File_Write_Byte, CF_File_Write_Complete) can be used only with FAT16 file system, and only with PIC18 family!

Before write operation, make sure you don’t overwrite boot or FAT sector as it could make your card on PC or digital cam unreadable. Drive mapping tools, such as Winhex, can be of a great assistance.
5.2.5.1 CF_Init_Port – Initializes ports appropriately
| Prototype | sub procedure CF_INIT_PORT(dim byref CtrlPort as byte, dim byref DataPort as byte) |
| Description |
The procedure initializes ports appropriately: <CtrlPort> is control port, and <DataPort> is data port to which CF is attached. |
| Example |
CF_Init_Port(PORTB, PORTD) ' Control port is PORTB, Data port is PORTD |
5.2.5.2 CF_Detect – Checks for presence of CF
| Prototype | sub function CF_DETECT(dim byref CtrlPort as byte) as byte |
| Description | The function checks if Compact Flash card is present. Returns true if present, otherwise returns false. <CtrlPort> must be initialized (call CF_INIT_PORT first). |
| Example |
do nop loop until CF_Detect(PORTB) = true ' wait until CF card is inserted |
5.2.5.3 CF_Write_Init – Initializes CF card for writing
| Prototype | sub procedure CF_WRITE_INIT(dim byref CtrlPort as byte, dim byref DataPort as byte, dim Adr as longint, dim SectCnt as byte) |
| Description |
The procedure initializes CF card for writing. Ports need to be initialized. Parameters: |
| Example |
CF_Write_Init(PORTB, PORTD, 590, 1) ' Initialize write at sector address 590
' of 1 sector (512 bytes)
|
5.2.5.4 CF_Write_Byte – Writes 1 byte to CF
| Prototype | sub procedure CF_WRITE_BYTE(dim byref CtrlPort as byte, dim byref DataPort as byte, dim BData as byte) |
| Description |
The procedure writes 1 byte to Compact Flash. The procedure has effect only if CF card is initialized for writing. Parameters: |
| Example |
CF_Write_Init(PORTB, PORTD, 590, 1) ' Initialize write at sector address 590
' of 1 sector (512 bytes)
for i = 0 to 511 ' Write 512 bytes to sector at address 590
CF_Write_Byte(PORTB, PORTD, i)
next i
|
5.2.5.5 CF_Write_Word – Writes 1 word to CF
| Prototype | sub procedure CF_WRITE_WORD(dim byref CtrlPort as byte, dim byref DataPort as byte, dim WData as word) |
| Description |
The procedure writes 1 word to Compact Flash. The procedure has effect only if CF card is initialized for writing. Parameters: |
| Example |
CF_Write_Word(PORTB, PORTD, Data) |
5.2.5.6 CF_Read_Init – Initializes CF card for reading
| Prototype | sub procedure CF_READ_INIT(dim byref CtrlPort as byte, dim byref DataPort as byte, dim Adr as longint, dim SectCnt as byte) |
| Description |
Parameters: |
| Example |
CF_Read_Init(PORTB, PORTD, 590, 1) ' Initialize write at sector address 590
' of 1 sector (512 bytes)
|
5.2.5.7 CF_Read_Byte – Reads 1 byte from CF
| Prototype | sub function CF_READ_BYTE(dim byref CtrlPort as byte, dim byref DataPort as byte) as byte |
| Description |
Function reads 1 byte from Compact Flash. Ports need to be initialized, and CF must be initialized for reading. Parameters: |
| Example |
PORTC = CF_Read_Byte(PORTB, PORTD) ' read byte and display on PORTC |
5.2.5.8 CF_Read_Word – Reads 1 word from CF
| Prototype | sub function CF_READ_WORD(dim byref CtrlPort as byte, dim byref DataPort as byte) as word |
| Description |
Function reads 1 word from Compact Flash. Ports need to be initialized, and CF must be initialized for reading. Parameters: |
| Example |
PORTC = CF_Read_Word(PORTB, PORTD) ' read word and display on PORTC |
5.2.5.9 CF_File_Write_Init – Initializes CF card for file writing operation (FAT16 only, PIC18 only)
| Prototype | sub procedure CF_File_Write_Init(dim byref CtrlPort as byte, dim byref DataPort as byte) |
| Description |
This procedure initializes CF card for file writing operation (FAT16 only, PIC18 only). Parameters: |
| Example |
CF_File_Write_Init(PORTB, PORTD) |
5.2.5.10 CF_File_Write_Byte – Adds one byte to file (FAT16 only, PIC18 only)
| Prototype | sub procedure CF_File_Write_Byte(dim byref CtrlPort as byte, dim byref DataPort as byte,dim Bdata as byte) |
| Description |
This procedure adds one byte (Bdata) to file (FAT16 only, PIC18 only). Parameters: |
| Example |
while i < 50000
CF_File_Write_Byte(PORTB, PORTD, 48 + index)
' demonstration: writes 50000 bytes to file
inc(i)
wend
|
5.2.5.11 CF_File_Write_Complete – Closes file and makes it readable (FAT16 only, PIC18 only)
| Prototype | sub procedure CF_File_Write_Complete(dim byref CtrlPort as byte, dim byref DataPort as byte,dim byref Filename as char[9]) |
| Description |
Upon all data has be written to file, use this procedure to close the file and make it readable by Windows (FAT16 only, PIC18 only). Parameters: |
| Example |
CF_File_Write_Complete(PORTB, PORTD, "example1", "txt") |

Pin diagram of CF memory card
5.2.6 EEPROM Library
EEPROM data memory is available with a number of PIC MCU models. Set of library procedures and functions is listed below to provide you comfortable work with EEPROM.
Notes:
Be aware that all interrupts will be disabled during execution of EEPROM_Write routine (GIE bit of INTCON register will be cleared). Routine will set this bit on exit.
Ensure minimum 20ms delay between successive use of routines EEPROM_Write and EEPROM_Read. Although EEPROM will write the correct value, EEPROM_Read might return undefined result.
5.2.6.1 EEPROM_Read – Reads 1 byte from EEPROM
| Prototype | sub function EEprom_Read(dim Address as byte) as byte |
| Description |
Function reads byte from <Address>. <Address> is of byte type, which means it can address only 256 locations. For PIC18 MCU models with more EEPROM data locations, it is programmer's responsibility to set SFR EEADRH register appropriately. Ensure minimum 20ms delay between successive use of routines EEPROM_Write and EEPROM_Read. Although EEPROM will write the correct value, EEPROM_Read might return undefined result. |
| Example |
TRISB = 0
Delay_ms(30)
for i = 0 to 20
PORTB = EEPROM_Read(i)
for j = 0 to 200
Delay_us(500)
next j
next i
|
5.2.6.2 EEPROM_Write – Writes 1 byte to EEPROM
| Prototype | sub procedure EEprom_Write(dim Address as byte, dim Data as byte) |
| Description |
Function writes byte to <Address>. <Address> is of byte type, which means it can address only 256 locations. For PIC18 MCU models with more EEPROM data locations, it is programmer's responsibility to set SFR EEADRH register appropriately. All interrupts will be disabled during execution of EEPROM_Write routine (GIE bit of INTCON register will be cleared). Routine will set this bit on exit Ensure minimum 20ms delay between successive use of routines EEPROM_Write and EEPROM_Read. Although EEPROM will write the correct value, EEPROM_Read might return undefined result. |
| Example |
for i = 0 to 20 EEPROM_Write(i, i + 6) next i |
5.2.7 Flash Memory Library
This library provides routines for accessing microcontroller Flash memory.
Note: Routines differ for PIC16 and PIC18 families.
5.2.7.1 Flash_Read – Reads data from microcontroller Flash memory
| Prototype |
sub function Flash_Read(dim Address as longint) as byte ' for PIC18sub function Flash_Read(dim Address as word) as word ' for PIC16
|
| Description |
Procedure reads data from the specified <Address>. |
| Example |
for i = 0 to 63 toRead = Flash_Read($0D00 + i) ' read 64 consecutive locations starting from 0x0D00 next i |
5.2.7.2 Flash_Write – Writes data to microcontroller Flash memory
| Prototype |
sub procedure Flash_Write(dim Address as longint, dim byref Data as byte[64]) ' for PIC18 |
| Description |
Procedure writes chunk of data to Flash memory (for PIC18, data needs to exactly 64 bytes in size). Keep in mind that this function erases target memory before writing <Data> to it. This means that if write was unsuccessful, your previous data will be lost. |
| Example |
for i = 0 to 63 ' initialize array toWrite[i] = i next i Flash_Write($0D00, toWrite) ' write contents of the array to the address 0x0D00 |
5.2.8 I2C Library
I2C interface is serial interface used for communicating with peripheral or other microcontroller devices. Routines below are intended for PIC MCUs with MSSP module. By using these, you can configure and use PIC MCU as master in I2C communication.
5.2.8.1 I2C_Init – Initializes I2C module
| Prototype | sub procedure I2C_Init(const Clock as longint) |
| Description |
Initializes I2C module. Parameter <Clock> is a desired I2C clock (refer to device data sheet for correct values in respect with Fosc). |
| Example |
I2C_Init(100000) |
5.2.8.2 I2C_Start – Issues start condition
| Prototype | sub function I2C_Start as byte |
| Description | Determines if I2C bus is free and issues START condition; if there is no error, function returns 0. |
| Example |
I2C_Start |
5.2.8.3 I2C_Repeated_Start – Performs repeated start
| Prototype | sub procedure I2C_Repeated_Start |
| Description |
Performs repeated start condition. |
| Example |
I2C_Repeated_Start |
5.2.8.4 I2C_Rd – Receives byte from slave
| Prototype | sub function I2C_Rd(dim Ack as byte) as byte |
| Description | Receives 1 byte from slave and sends not acknowledge signal if <Ack> is 0; otherwise, it sends acknowledge. |
| Example |
Data = I2C_Rd(1) ' read data w/ acknowledge |
5.2.8.5 I2C_Wr – Sends data byte via I2C bus
| Prototype | sub function I2C_Wr(dim Data as byte) as byte |
| Description |
After you have issued a start or repeated start you can send <Data> byte via I2C bus. The function returns 0 if there are no errors. |
| Example |
I2C_Wr($A2) ' send byte via I2C(command to 24cO2) |
5.2.8.6 I2C_Stop – Issues STOP condition
| Prototype | sub procedure I2C_Stop as byte |
| Description |
Issues STOP condition. |
| Example |
I2C_Stop |

Example of I2C communication with 24c02 EEPROM
5.2.9 LCD Library
BASIC provides a set of library procedures and functions for communicating with commonly used 4-bit interface LCD (with Hitachi HD44780 controller). Be sure to designate port with LCD as output, before using any of the following library procedures or functions.
5.2.9.1 LCD_Init – Initializes LCD with default pin settings
| Prototype |
sub procedure LCD_Init(dim byref Port as byte)
|
| Description |
Initializes LCD at <Port> with default pin settings (see the figure below). |
| Example |
LCD_Init(PORTB) ' Initializes LCD on PORTB (check pin settings in the figure below) |
5.2.9.2 LCD_Config – Initializes LCD with custom pin settings
| Prototype | sub procedure LCD_Config(dim byref Port as byte, const RS, const EN, const WR, const D7, const D6, const D5, const D4) |
| Description |
Initializes LCD at <Port> with pin settings you specify: parameters <RS>, <EN>, <WR>, <D7> .. <D4> need to be a combination of values 0..7 (e.g. 3,6,0,7,2,1,4). |
| Example |
LCD_Config(PORTD, 1, 2, 0, 3, 5, 4, 6) ' Initializes LCD on PORTD with our custom pin settings |
5.2.9.3 LCD_Chr – Prints char on LCD at specified row and col
| Prototype | sub procedure LCD_Chr(dim Row as byte, dim Column as byte, dim Character as byte) |
| Description |
Prints <Character> at specified <Row> and <Column> on LCD. |
| Example |
LCD_Chr(1, 2, "e") ' Prints character "e" on LCD (1st row, 2nd column) |
5.2.9.4 LCD_Chr_CP – Prints char on LCD at current cursor position
| Prototype | sub procedure LCD_Chr_CP(dim Character as byte) |
| Description |
Prints <Character> at current cursor position. |
| Example |
LCD_Chr_CP("k")
' Prints character "k" at current cursor position
|
5.2.9.5 LCD_Out – Prints string on LCD at specified row and col
| Prototype | sub procedure LCD_Out(dim Row as byte, dim Column as byte, dim byref Text as char[255]) |
| Description |
Prints <Text> (string variable) at specified <Row> and <Column> on LCD. Both string variables and string constants can be passed. |
| Example |
LCD_Out(1, 3, Text) ' Prints string variable Text on LCD (1st row, 3rd column) |
5.2.9.6 LCD_Out_CP – Prints string on LCD at current cursor position
| Prototype | sub procedure LCD_Out_CP(dim byref Text as char[255]) |
| Description |
Prints <Text> (string variable) at current cursor position. Both string variables and string constants can be passed. |
| Example |
LCD_Out_CP("Some text")
' Prints "Some text" at current cursor position
|
5.2.9.7 LCD_Cmd – Sends command to LCD
| Prototype | sub procedure LCD_Cmd(dim Command as byte) |
| Description |
Sends <Command> to LCD. List of available commands follows: LCD_First_Row ' Moves cursor to 1st row LCD_Second_Row ' Moves cursor to 2nd row LCD_Third_Row ' Moves cursor to 3rd row LCD_Fourth_Row ' Moves cursor to 4th row LCD_Clear ' Clears display LCD_Return_Home ' Returns cursor to home position, ' returns a shifted display to original position. ' Display data RAM is unaffected. LCD_Cursor_Off ' Turn off cursor LCD_Underline_On ' Underline cursor on LCD_Blink_Cursor_On ' Blink cursor on LCD_Move_Cursor_Left ' Move cursor left without changing display data RAM LCD_Move_Cursor_Right ' Move cursor right without changing display data RAM LCD_Turn_On ' Turn LCD display on LCD_Turn_Off ' Turn LCD display off LCD_Shift_Left ' Shift display left without changing display data RAM LCD_Shift_Right ' Shift display right without changing display data RAM |
| Example |
LCD_Cmd(LCD_Clear) ' Clears LCD display |

LCD HW connection
5.2.10 LCD8 Library (8-bit interface LCD)
BASIC provides a set of library procedures and functions for communicating with commonly used 8-bit interface LCD (with Hitachi HD44780 controller). Be sure to designate Control and Data ports with LCD as output, before using any of the following library procedures or functions.
5.2.10.1 LCD8_Init – Initializes LCD with default pin settings
| Prototype | sub procedure LCD8_Init(dim byref Port_Ctrl as byte, dim byref Port_Data as byte) |
| Description |
Initializes LCD at <Port_Ctrl> and <Port_Data> with default pin settings (see the figure below). |
| Example |
LCD8_Init(PORTB, PORTC)
' Initializes LCD on PORTB and PORTC with default pin settings
' (check pin settings in the figure below)
|
5.2.10.2 LCD8_Config – Initializes LCD with custom pin settings
| Prototype | sub procedure LCD8_Config(dim byref Port_Ctrl as byte, dim byref Port_Data as byte, const RS, const EN, const WR, const D7, const D6, const D5, const D4, const D3, const D2, const D1, const D0) |
| Description |
Initializes LCD at <Port_Ctrl> and <Port_Data> with pin settings you specify: parameters <RS>, <EN>, <WR> need to be in range 0..7; parameters <D7>..<D0> need to be a combination of values 0..7 (e.g. 3,6,5,0,7,2,1,4). |
| Example |
LCD8_Config(PORTC, PORTD, 0, 1, 2, 6, 5, 4, 3, 7, 1, 2, 0) ' Initializes LCD on PORTC and PORTD with our custom pin settings |
5.2.10.3 LCD8_Chr – Prints char on LCD at specified row and col
| Prototype | sub procedure LCD8_Chr(dim Row as byte, dim Column as byte, dim Character as byte) |
| Description |
Prints <Character> at specified <Row> and <Column> on LCD. |
| Example |
LCD8_Chr(1, 2, "e") ' Prints character "e" on LCD (1st row, 2nd column) |
5.2.10.4 LCD8_Chr_CP – Prints char on LCD at current cursor position
| Prototype | sub procedure LCD8_Chr_CP(dim Character as byte) |
| Description |
Prints <Character> at current cursor position. |
| Example |
LCD8_Chr_CP("k")
' Prints character "k" at current cursor position
|
5.2.10.5 LCD8_Out – Prints string on LCD at specified row and col
| Prototype | sub procedure LCD8_Out(dim Row as byte, dim Column as byte, dim byref Text as char[255]) |
| Description |
Prints <Text> (string variable) at specified <Row> and <Column> on LCD. Both string variables and string constants can be passed. |
| Example |
LCD8_Out(1, 3, Text) ' Prints string variable Text on LCD (1st row, 3rd column) |
5.2.10.6 LCD8_Out_CP – Prints string on LCD at current cursor position
| Prototype |
sub procedure LCD8_Out_CP(dim byref Text as char[255])
|
| Description |
Prints <Text> (string variable) at current cursor position. Both string variables and string constants can be passed. |
| Example |
LCD8_Out_CP("Test")
' Prints "Test" at current cursor position
|
5.2.10.7 LCD8_Cmd – Sends command to LCD
| Prototype |
sub procedure LCD8_Cmd(dim Command as byte)
|
| Description |
Sends <Command > to LCD. List of available commands follows: LCD_First_Row ' Moves cursor to 1st row LCD_Second_Row ' Moves cursor to 2nd row LCD_Third_Row ' Moves cursor to 3rd row LCD_Fourth_Row ' Moves cursor to 4th row LCD_Clear ' Clears display LCD_Return_Home ' Returns cursor to home position, ' returns a shifted display to original position. ' Display data RAM is unaffected. LCD_Cursor_Off ' Turn off cursor LCD_Underline_On ' Underline cursor on LCD_Blink_Cursor_On ' Blink cursor on LCD_Move_Cursor_Left ' Move cursor left without changing display data RAM LCD_Move_Cursor_Right ' Move cursor right without changing display data RAM LCD_Turn_On ' Turn LCD display on LCD_Turn_Off ' Turn LCD display off LCD_Shift_Left ' Shift display left without changing display data RAM LCD_Shift_Right ' Shift display right without changing display data RAM |
| Example |
LCD8_Cmd(LCD_Clear) ' Clears LCD display |

LCD HW connection
5.2.11 Graphic LCD Library
mikroPascal provides a set of library procedures and functions for drawing and writing on Graphical LCD. Also it is possible to convert bitmap (use menu option Tools > BMP2LCD) to constant array and display it on GLCD. These routines works with commonly used GLCD 128x64, and work only with the PIC18 family.
5.2.11.1 GLCD_Config – Initializes GLCD with custom pin settings
| Prototype |
sub procedure GLCD_Config(dim byref Ctrl_Port as byte, dim byref Data_Port as byte, dim Reset as byte, dim Enable as byte,dim RS as byte, dim RW as byte, dim CS1 as byte, dim CS2 as byte)
|
| Description |
Initializes GLCD at <Ctrl_Port> and <Data_Port> with custom pin settings. |
| Example |
GLCD_LCD_Config(PORTB, PORTC, 1,7,4,6,0,2) |
5.2.11.2 GLCD_Init – Initializes GLCD with default pin settings
| Prototype |
sub procedure GLCD_Init(dim Ctrl_Port as byte, dim Data_Port as byte)
|
| Description |
Initializes LCD at <Ctrl_Port> and <Data_Port>. With default pin settings Reset=7, Enable=1, RS=3, RW=5, CS1=2, CS2=0. |
| Example |
GLCD_LCD_Init(PORTB, PORTC) |
5.2.11.3 GLCD_Put_Ins – Sends instruction to GLCD.
| Prototype |
sub procedure GLCD_Put_Ins(dim Ins as byte)
|
| Description |
Sends instruction <Ins> to GLCD. Available instructions include: X_ADRESS = $B8 ' Adress base for Page 0 Y_ADRESS = $40 ' Adress base for Y0 START_LINE = $C0 ' Adress base for line 0 DISPLAY_ON = $3F ' Turn display on DISPLAY_OFF = $3E ' Turn display off |
| Example |
GLCD_Put_Ins(DISPLAY_ON) |
5.2.11.4 GLCD_Put_Data – Sends data byte to GLCD.
| Prototype |
sub procedure GLCD_Put_Data(dim data as byte)
|
| Description |
Sends data byte to GLCD. |
| Example |
GLCD_Put_Data(temperature) |
5.2.11.5 GLCD_Put_Data2 – Sends data byte to GLCD.
| Prototype |
sub procedure GLCD_Put_Data2(dim data as byte, dim side as byte)
|
| Description |
Sends data to GLCD at specified <side> (<side> can take constant value LEFT or RIGHT) . |
| Example |
GLCD_Put_Data2(temperature, 1) |
5.2.11.6 GLCD_Select_Side- Selects the side of the GLCD.
| Prototype |
sub procedure GLCD_Select_Side(dim LCDSide as byte)
|
| Description |
Selects the side of the GLCD: |
| Example |
GLCD_Select_Side(1) |
5.2.11.7 GLCD_Data_Read – Reads data from GLCD.
| Prototype |
sub function GLCD_Data_Read as byte
|
| Description |
Reads data from GLCD. |
| Example |
GLCD_Data_Read |
5.2.11.8 GLCD_Clear_Dot – Clears a dot on the GLCD.
| Prototype |
sub procedure GLCD_Clear_Dot(dim x as byte, dim y as byte)
|
| Description |
Clears a dot on the GLCD at specified coordinates. |
| Example |
GLCD_Clear_Dot(20, 32) |
5.2.11.9 GLCD_Set_Dot – Draws a dot on the GLCD.
| Prototype |
sub procedure GLCD_Set_Dot(dim x as byte, dim y as byte)
|
| Description |
Draws a dot on the GLCD at specified coordinates. |
| Example |
GLCD_Set_Dot(20, 32) |
5.2.11.10 GLCD_Circle – Draws a circle on the GLCD.
| Prototype |
sub procedure GLCD_Circle(dim CenterX as integer, dim CenterY as integer, dim Radius as integer)
|
| Description |
Draws a circle on the GLCD, centered at <CenterX, CenterY> with <Radius>. |
| Example |
GLCD_Circle(30, 42, 6) |
5.2.11.11 GLCD_Line – Draws a line
| Prototype |
sub procedure GLCD_Line(dim x1 as integer, dim y1 as integer, dim x2 as integer, dim y2 as integer)
|
| Description |
Draws a line from (x1,y1) to (x2,y2). |
| Example |
GLCD_Line(0, 0, 120, 50) GLCD_Line(0,63, 50, 0) |
5.2.11.12 GLCD_Invert – Inverts display
| Prototype |
sub procedure GLCD_Invert(dim Xaxis as byte, dim Yaxis as byte)
|
| Description |
Procedure inverts display (changes dot state on/off) in the specified area, X pixels wide starting from 0 position, 8 pixels high. Parameter Xaxis spans 0..127, parameter Yaxis spans 0..7 (8 text lines). |
| Example |
GLCD_Invert(60, 6) |
5.2.11.13 GLCD_Goto_XY – Sets cursor to dot(x,y)
| Prototype |
sub procedure GLCD_Goto_XY(dim x as byte, dim y as byte)
|
| Description |
Sets cursor to dot (x,y). Procedure is used in combination with |
| Example |
GLCD_Goto_XY(60, 6) |
5.2.11.14 GLCD_Put_Char – Prints <Character> at cursor position
| Prototype |
sub procedure GLCD_Put_Char(dim Character as byte)
|
| Description |
Prints <Character> at cursor position. |
| Example |
GLCD_Put_Char(k) |
5.2.11.15 GLCD_Clear_Screen – Clears the GLCD screen
| Prototype |
sub procedure GLCD_Clear_Screen
|
| Description |
Clears the GLCD screen. |
| Example |
GLCD_Clear_Screen |
5.2.11.16 GLCD_Put_Text – Prints text at specified position
| Prototype |
sub procedure GLCD_Put_Text(dim x_pos as word, dim y_pos as word, dim byref text as char[25], dim invert as byte)
|
| Description |
Prints <text> at specified position; y_pos spans 0..7. |
| Example |
GLCD_Put_Text(0, 7, My_text, NONINVERTED_TEXT) |
5.2.11.17 GLCD_Rectangle – Draws a rectangle
| Prototype |
sub procedure GLCD_Rectangle(dim X1 as byte, dim Y1 as byte, dim X2 as byte, dim Y2 as byte)
|
| Description |
Draws a rectangle on the GLCD. (x1,y1) sets the upper left corner, (x2,y2) sets the lower right corner. |
| Example |
GLCD_Rectangle(10, 0, 30, 35) |
5.2.11.18 GLCD_Set_Font – Sets font for GLCD
| Prototype |
sub procedure GLCD_Set_Font(dim font_index as byte)
|
| Description |
Sets font for GLCD. Parameter <font_index> spans from 1 to 4, and determines which font will be used: |
| Example |
GLCD_Set_Font(2) |
5.2.12 Manchester Code Library
mikroBasic provides a set of library procedures and functions for handling Manchester coded signal. Manchester code is a code in which data and clock signals are combined to form a single self-synchronizing data stream; each encoded bit contains a transition at the midpoint of a bit period, the direction of transition determines whether the bit is a 0 or a 1; second half is the true bit value and the first half is the complement of the true bit value (as shown in the figure below).

Note: Manchester receive routines are blocking calls (Man_Receive_Config, Man_Receive_Init). This means that PIC will wait until the task is performed (e.g. byte is received, synchronization achieved, etc)., Man_Receive
Note: Routines for receiving are limited to a baud rate scope from 340 ~ 560 bps.
5.2.12.1 Man_Receive_Init – Initialization with default pin
| Prototype | sub procedure Man_Receive_Init(dim byref Port as byte) |
| Description |
Procedure works same as |
| Example |
Man_Receive_Init(PORTD) |
5.2.12.2 Man_Receive_Config – Initialization with custom pin
| Prototype |
sub procedure Man_Receive_Config(dim byref Port as byte, dim RXpin as byte)
|
| Description |
This procedure needs to be called in order to receive signal by procedure |
| Example |
Man_Receive_Config(PORTD, 5) |
5.2.12.3 Man_Receive – Receives a byte
| Prototype | sub function Man_Receive(dim byref Error as byte) as byte |
| Description |
Function extracts one byte from signal. If format does not match the expected, <Error> flag will be set True. |
| Example |
dim ErrorFlag as byte temp = Man_Receive(ErrorFlag) ' Attempt byte receive |
5.2.12.4 Man_Send_Init – Initialization with default pin
| Prototype | sub procedure Man_Send_Init(dim byref Port as byte) |
| Description |
Procedure works same as |
| Example |
Man_Send_Init(PORTB) |
5.2.12.5 Man_Send_Config – Initialization with custom pin
| Prototype | sub procedure Man_Send_Config(dim byref Port as byte, dim TXpin as byte) |
| Description |
Procedure needs to be called in order to send signals via procedure |
| Example |
Man_Send_Config(PORTB, 4) |
5.2.12.6 Man_Send – Sends a byte
| Prototype | sub procedure Man_Send(dim Data as byte) |
| Description |
Procedure sends one <Data> byte. |
| Example |
for i = 1 to StrLen(s1) Man_Send(s1[i]) ' Send char Delay_ms(90) next i |
5.2.13 PWM Library
CCP (Capture/ Compare/ PWM) module is available with a number of PIC MCU models. Set of library procedures and functions is listed below to provide comfortable work with PWM (Pulse Width Modulation).
Note that these routines support module on PORTC pin RC2, and won't work with modules on other ports. Also, BASIC doesn't support enhanced PWM modules.
5.2.13.1 PWM_Init – Initializes PWM module
| Prototype | sub procedure PWM_Init(const PWM_Freq) |
| Description |
Initializes PWM module with (duty ratio) 0%. <PWM_Freq> is a desired PWM frequency (refer to device data sheet for correct values in respect with Fosc). |
| Example |
PWM_Init(5000) ' initializes PWM module, freq = 5kHz |
5.2.13.2 PWM_Change_Duty – Changes duty ratio
| Prototype |
sub procedure PWM_Change_Duty(dim New_Duty as byte)
|
| Description |
Routine changes duty ratio. <New_Duty> takes values from 0 to 255, where 0 is 0% duty ratio, 127 is 50% duty ratio, and 255 is 100% duty ratio. Other values for specific duty ratio can be calculated as (Percent*255)/100. |
| Example |
while true Delay_ms(100) j = j + 1 PWM_Change_Duty(j) wend |
5.2.13.3 PWM_Start – Starts PWM
| Prototype |
sub procedure PWM_Start
|
| Description |
Starts PWM. |
| Example |
PWM_Start |
5.2.13.4 PWM_Stop – Stops PWM
| Prototype |
sub procedure PWM_Stop
|
| Description |
Stops PWM. |
| Example |
PWM_Stop |

PWM demonstration
5.2.14 RS485 Library
RS485 is a multipoint communication which allows multiple devices to be connected to a single signal cable. BASIC provides a set of library routines to provide you comfortable work with RS485 system using Master/Slave architecture.
Master and Slave devices interchange packets of information, each of these packets containing synchronization bytes, CRC byte, address byte, and the data. In Master/Slave architecture, Slave can never initiate communication. Each Slave has its unique address and receives only the packets containing that particular address. It is programmer's responsibility to ensure that only one device transmits data via 485 bus at a time.
RS485 routines require USART module on port C. Pins of USART need to be attached to RS485 interface transceiver, such as LTC485 or similar. Pins of transceiver (Receiver Output Enable and Driver Outputs Enable) should be connected to port C, pin 2 (see the figure at end of the chapter).
Note: Address 50 is a common address for all Slave devices: packets containing address 50 will be received by all Slaves. The only exceptions are Slaves with addresses 150 and 169, which require their particular address to be specified in the packet.
5.2.14.1 RS485Master_Init – Initializes MCU as Master in RS485 communication
| Prototype |
sub procedure RS485master_init
|
| Description |
Initializes MCU as Master in RS485 communication. USART needs to be initialized. |
| Example |
RS485Master_Init |
5.2.14.2 RS485Master_Read – Receives message from Slave
| Prototype |
sub procedure RS485master_read(dim byref data as byte[5])
|
| Description |
Master receives any message sent by Slaves. As messages are multi-byte, this procedure must be called for each byte received (see the example at the end of the chapter). Upon receiving a message, buffer is filled with the following values:
Procedure automatically sets data[4] and data[5] upon every received message. These flags need to be cleared repeatedly from the program. Note: MCU must be initialized as Master in 485 communication to assign an address to MCU |
| Example |
RS485Master_Read(dat) |
5.2.14.3 RS485Master_Write – Sends message to Slave
| Prototype |
sub procedure RS485Master_Write(dim byref data as byte[2], dim datalen as byte, dim address as byte)
|
| Description |
Routine sends number of bytes (1 < datalen <= 3) from buffer via 485, to slave specified by <address>. MCU must be initialized as Master in 485 communication. It is programmer's responsibility to ensure (by protocol) that only one device sends data via 485 bus at a time. |
| Example |
RS485Master_Write(dat, 1) |
5.2.14.4 RS485Slave_Init – Initializes MCU as Slave in RS485 communication
| Prototype |
sub procedure RS485Slave_Init(dim address as byte)
|
| Description |
Initializes MCU as Slave in RS485 communication. USART needs to be initialized. <address> can take any value between 0 and 255, except 50, which is common address for all slaves. |
| Example |
RS485Slave_Init(160) ' initialize MCU as Slave with address 160 |
5.2.14.5 RS485Slave_Read – Receives message from Master
| Prototype | sub procedure RS485Slave_Read(dim byref data as byte[5]) |
| Description |
Only messages that appropriately address Slaves will be received. As messages are multi-byte, this procedure must be called for each byte received (see the example at the end of the chapter). Upon receiving a message, buffer is filled with the following values:
Procedure automatically sets data[4] and data[5] upon every received message. These flags need to be cleared repeatedly from the program. MCU must be initialized as Master in 485 communication to assign an address to MCU. |
| Example |
RS485Slave_Read(dat) |
5.2.14.6 RS485Slave_Write – Sends message to Master
| Prototype |
sub procedure RS485Slave_Write(dim byref data as byte[2], dim datalen as byte)
|
| Description |
Sends number of bytes (1 < datalen <= 3) from buffer via 485 to Master. MCU must be initialized as Slave in 485 communication. It is programmer's responsibility to ensure (by protocol) that only one device sends data via 485 bus at a time. |
| Example |
RS485Slave_Write(dat, 1) |

Example of interfacing PC to PIC MCU via RS485 bus
5.2.15 SPI Library
SPI (Serial Peripheral Interface) module is available with a number of PIC MCU models. You can easily communicate with other devices via SPI - A/D converters, D/A converters, MAX7219, LTC1290 etc. You need PIC MCU with hardware integrated SPI (for example, PIC16F877). Then, simply use the following functions and procedures.
5.2.15.1 SPI_Init – Standard initialization of SPI
| Prototype |
sub procedure SPI_Init
|
| Description |
Routine initializes SPI with default parameters:
|
| Example |
SPI_Init |
5.2.15.2 SPI_Init_Advanced – does smt
| Prototype |
sub procedure SPI_Init_Advanced(dim Master as byte, dim Data_Sample as byte, dim Clock_Idle as byte, dim Low_To_High as byte)
|
| Description |
For advanced settings, configure and initialize SPI using the procedure SPI_Init_Advanced. Allowed values of parameters: <Master> determines the work mode for SPI:
<Data_Sample> determines when data is sampled:
<Clock_Idle> determines idle state for clock:
<Low_To_High> determines transmit edge for data:
|
| Example |
SPI_Init_Advanced(Master_OSC_div4, Data_SAMPLE_MIDDLE, CLK_Idle_LOW,LOW_2_HIGH) ' This will set SPI to: ' master mode, ' clock = Fosc/4, ' data sampled at the middle of interval, ' clock idle state low, ' data transmitted at low to high edge. |
5.2.15.3 SPI_Read – Reads the received data
| Prototype |
sub function SPI_Read(dim Buffer as byte) as byte
|
| Description |
Routine provides clock by sending <Buffer> and reads the received data at the end of the period. |
| Example |
dim rec as byte ... SPI_Read(rec) |
5.2.15.4 SPI_Write – Sends data via SPI
| Prototype |
sub procedure SPI_Write(dim Data as byte)
|
| Description |
Routine writes <Data> to SSPBUF and immediately starts the transmission. |
| Example |
SPI_Write(7) |
5.2.16 USART Library
USART (Universal Synchronous Asynchronous Receiver Transmitter) hardware module is available with a number of PIC MCU models. You can easily communicate with other devices via RS232 protocol (for example with PC, see the figure at the end of this chapter - RS232 HW connection). You need a PIC MCU with hardware integrated USART (for example, PIC16F877). Then, simply use the functions and procedures described below.
Note: Some PIC micros that have two USART modules, such as P18F8520, require you to specify the module you want to use. Simply append the number 1 or 2 to procedure or function name, e.g. USART_Write2(Dat).
5.2.16.1 USART_Init – Initializes USART
| Prototype |
sub procedure USART_Init(const Baud_Rate)
|
| Description |
Initializes PIC MCU USART hardware and establishes communication at specified <Baud_Rate>. Refer to the device data sheet for baud rates allowed for specific Fosc. If you specify the unsupported baud rate, compiler will report an error. |
| Example |
USART_Init(2400) |
5.2.16.2 USART_Data_Ready – Checks if data is ready
| Prototype |
sub function USART_Data_Ready as byte
|
| Description |
Function checks if data is ready. Returns 1 if so, returns 0 otherwise. |
| Example |
USART_Data_Ready |
5.2.16.3 USART_Read – Receives a byte
| Prototype |
sub function USART_Read as byte
|
| Description |
Receives a byte; if byte is not received returns 0. |
| Example |
USART_Read |
5.2.16.4 USART_Write – Transmits a byte
| Prototype | sub procedure USART_Write(dim Data as byte) |
| Description |
Procedure transmits byte <Data>. |
| Example |
USART_Write(dat) |

RS232 HW connection
5.2.17 One-Wire Library
1-wire library provides routines for communicating via 1-wire bus, for example with DS1820 digital thermometer. Note that oscillator frequency Fosc needs to be at least 4MHz in order to use the routines with Dallas digital thermometers.
5.2.17.1 OW_Reset – Issues 1-wire reset signal for DS1820
| Prototype |
sub function OW_Reset(dim byref PORT as byte, dim Pin as byte) as byte
|
| Description |
Issues 1-wire reset signal for DS1820. Parameters <PORT> and <Pin> specify the location of DS1820; return value of the function is 0 if DS1820 is present, and 1 otherwise. |
| Example |
OW_Reset(PORTA, 5) |
5.2.17.2 OW_Read – Reads one byte via 1-wire bus
| Prototype |
sub function OW_Read(dim byref PORT as byte, Pin as byte) as byte
|
| Description |
Reads one byte via 1-wire bus. |
| Example |
temp = OW_Read(PORTA, 5) ' get result from PORTA |
5.2.17.3 OW_Write – Writes one byte via 1-wire bus
| Prototype |
sub procedure OW_Write(dim byref PORT as byte, dim Pin as byte, dim par as byte)
|
| Description |
Writes one byte (<par>) via 1-wire bus |
| Example |
OW_Write(PORTA, 5, $44) |
5.2.18 Software I2C
BASIC provides routines which implement software I2C. These routines are hardware independent and can be used with any MCU. Software I2C enables you to use MCU as Master in I2C communication. Multi-master mode is not supported.
5.2.18.1 Soft_I2C_Config – Configure the I2C master mode
| Prototype | sub procedure Soft_I2C_Config(dim byref Port as byte, const SDA,const SCL) |
| Description |
Configure the I2C master mode. Parameter <Port> specifies port of MCU on which SDA and SCL pins will be located; |
| Example |
Soft_I2C_Config(PORTD, 3, 4) |
5.2.18.2 Soft_I2C_Start – Issues START condition
| Prototype |
sub procedure Soft_I2C_Start
|
| Description |
Issues START condition. |
| Example |
Soft_I2C_Start |
5.2.18.3 Soft_I2C_Write – Send data byte via I2C bus
| Prototype |
sub function Soft_I2C_Write(dim Data as byte) as byte
|
| Description |
After you have issued a start signal you can send <Data> byte via I2C bus. The function returns 0 if there are no errors. |
| Example |
Soft_I2C_Write($A3) |
5.2.18.4 Soft_I2C_Read – Receives byte from slave
| Prototype |
sub function Soft_I2C_Read(dim Ack as byte) as byte
|
| Description |
Receives 1 byte from slave and sends not acknowledge signal if <Ack> is 0; otherwise, it sends acknowledge. |
| Example |
EE_data = Soft_I2C_Read(0) |
5.2.18.5 Soft_I2C_Stop – Issues STOP condition
| Prototype |
sub procedure Soft_I2C_Stop
|
| Description |
Issues STOP condition. |
| Example |
Soft_I2C_Stop |
5.2.19 Software SPI Library
BASIC provides routines which implement software SPI. These routines are hardware independent and can be used with any MCU. You can easily communicate with other devices via SPI - A/D converters, D/A converters, MAX7219, LTC1290 etc. Simply use the following functions and procedures.
5.2.19.1 Soft_SPI_Config – Configure MCU for SPI communication
| Prototype |
sub procedure Soft_SPI_Config(dim byref Port as byte, const SDI, const SD0, const SCK)
|
| Description |
Routine configures and initializes software SPI with the following defaults:
SDI pin, SDO pin, and SCK pin are specified by the appropriate parameters. |
| Example |
Soft_SPI_Config(PORTB, 1, 2, 3) ' SDI pin is RB1, SDO pin is RB2, and SCK pin is RB3. |
5.2.19.2 Soft_SPI_Read – Reads the received data
| Prototype |
sub function Soft_SPI_read(dim Buffer as byte) as byte
|
| Description |
Routine provides clock by sending <Buffer> and reads the received data at the end of the period. |
| Example |
Soft_SPI_Read(dat) |
5.2.19.3 Soft_SPI_Write – Sends data via SPI
| Prototype |
sub procedure Soft_SPI_Write(dim Data as byte)
|
| Description |
Routine writes <Data> to SSPBUF and immediately starts the transmission. |
| Example |
Soft_SPI_Write(dat) |
5.2.20 Software UART Library
BASIC provides routines which implement software UART. These routines are hardware independent and can be used with any MCU. You can easily communicate with other devices via RS232 protocol . Simply use the functions and procedures described below.
5.2.20.1 Soft_UART_Init – Initializes UART
| Prototype |
sub procedure Soft_UART_Init(dim byref Port as byte, const RX, const TX, const Baud_Rate)
|
| Description |
Initializes PIC MCU UART at specified pins establishes communication at <Baud_Rate>. If you specify the unsupported baud rate, compiler will report an error. |
| Example |
Soft_UART_Init(PORTB, 1, 2, 9600) |
5.2.20.2 Soft_UART_Read – Receives a byte
| Prototype |
sub function Soft_UART_Read(dim byref Msg_received as byte) as byte
|
| Description |
Function returns a received byte. Parameter <Msg_received> will take true if transfer was succesful. Soft_UART_Read is a non-blocking function call, so you should test <Msg_received> manually (check the example below). |
| Example |
Received_byte = Soft_UART_Read(Rec_ok) |
5.2.20.4 Soft_UART_Write – Transmits a byte
| Prototype |
sub procedure Soft_USART_Write(dim Data as byte)
|
| Description |
Procedure transmits byte <Data>. |
| Example |
Soft_UART_Write(Received_byte) |
5.2.21 Sound Library
BASIC provides a sound library which allows you to use sound signalization in your applications.
5.2.21.1 Sound_Init – Initializes sound engine
| Prototype |
sub procedure Sound_Init(dim byref Port, dim Pin as byte)
|
| Description |
Procedure |
| Example |
PORTB = 0 ' Clear PORTB TRISB = 0 ' PORTB is output Sound_Init(PORTB, 2) ' Initialize sound on PORTB.RB2 |
5.2.21.2 Sound_Play – Plays sound at specified port
| Prototype |
sub procedure Sound_Play(dim byref Port, dim Pin as byte)
|
| Description |
Procedure For example, if you want to play sound of 1KHz: |
| Example |
...
Sound_Init(PORTB,2) ' Initialize sound on PORTB.RB2
while true
adcValue = ADC_Read(2) ' Get lower byte from ADC
Sound_Play(adcValue, 200) ' Play the sound
wend
|
5.2.22 Trigonometry Library
BASIC provides a trigonometry library for applications which involve angle calculations. Trigonometric routines take an angle (in degrees) as parameter of type word and return sine and cosine multiplied by 1000 and rounded up (as integer).
5.2.22.1 SinE3 – Returns sine of angle
| Prototype |
sub function sinE3(dim Angle as word) as integer
|
| Description |
Function takes a word-type number which represents angle in degrees and returns the sine of <Angle> as integer, multiplied by 1000 (1E3) and rounded up to nearest integer: Note that parameter <Angle> cannot be negative. Function is implemented as lookup table, and the maximum error obtained is ±1. |
| Example |
dim angle as word dim result as integer angle = 45 result = sinE3(angle) ' result is 707 |
5.2.22.2 CosE3 – Returns cosine of angle
| Prototype |
sub function cosE3(dim Angle as word) as integer
|
| Description |
Function takes a word-type number which represents angle in degrees and returns the cosine of <Angle> as integer, multiplied by 1000 (1E3) and rounded up to nearest integer: Note that parameter <Angle> cannot be negative. Function is implemented as lookup table, and the maximum error obtained is ±1. |
| Example |
dim angle as word dim result as integer angle = 90 result = cosE3(angle) ' result is 0 |
5.2.23 Utilities
BASIC provides a utility set of procedures and functions for faster development of your applications.
5.2.23.1 Button – Debounce
| Prototype |
sub function Button(dim byref PORT as byte, dim Pin as byte, dim Time as byte, dim Astate as byte) as byte
|
| Description |
Function eliminates the influence of contact flickering due to the pressing of a button (debouncing). Parameters <PORT> and <Pin> specify the location of the button; parameter <Time> represents the minimum time interval that pin must be in active state in order to return one; parameter <Astate> can be only zero or one, and it specifies if button is active on logical zero or logical one. |
| Example |
if Button(PORTB, 0, 1, 1) then flag = 255 end if |