AVR Basic Compiler Reference Manual
 
 

The list of all Basic compiler keywords:
1WIRE_REG, 1WIRE_BIT, 1WIREINIT, 1WIRESENDBIT, 1WIREGETBIT, 1WIRESENDBYTE, 1WIREGETBYTE, ADCIN, ADC_CLOCK, ADC_SAMPLEUS, ADC_VREF, ALLOW_ALL_BAUDRATES, ALLOW_MULTIPLE_HSEROPEN, AND, AS, ASM, BIT, BREAK, BYTE, CALL, CASE, CLOCK_FREQUENCY, CONFIG, CONST, CRLF, DEFINE, DIM, DISABLE, DS18S20START, DS18S20READT, ELSE, ENABLE, END, END FUNCTION, END PROC, ENDIF, ENDSELECT, EXIT, FALSE, FOR, FREQOUT, FUNCTION, GLCD_DREG, GLCD_RSREG, GLCD_RSBIT, GLCD_EREG, GLCD_EBIT, GLCD_RWREG, GLCD_RWBIT, GLCD_CS1REG, GLCD_CS1BIT, GLCD_CS2REG, GLCD_CS2BIT, GLCDINIT, GLCDCLEAR, GLCDPSET, GLCDPRESET, GLCDCLEAN, GLCDPOSITION, GLCDWRITE, GLCDOUT, GLCDIN, GLCDCMDOUT, GOSUB, GOTO, HALT, HIGH, HSERGET, HSERIN, HSEROUT, HSEROPEN, I2CWRITE, I2CREAD, I2CREAD_DELAYUS, I2CCLOCK_STRETCH, I2CWRITE1, I2CREAD1, I2CPREPARE, I2CSTART, I2CSTOP, I2CSEND, I2CRECA, I2CRECEIVEACK, I2CRECN, I2CRECEIVENACK, IF, INPUT, LCD_BITS, LCD_DREG, LCD_DBIT, LCD_RSREG, LCD_RSBIT, LCD_EREG, LCD_EBIT, LCD_RWREG, LCD_RWBIT, LCD_COMMANDUS, LCD_DATAUS, LCD_INITMS, LCD_READ_BUSY_FLAG, LCD_LINES, LCD_CHARS, LCDINIT, LCDOUT, LCDCMDOUT, LCDCLEAR, LCDHOME, LCDDISPLAYON, LCDDISPLAYOFF, LCDCUROFF, LCDCURBLINK, LCDCURUNDERLINE, LCDCURBLINKUNDERLINE, LCDLEFT, LCDRIGHT, LCDSHIFTLEFT, LCDSHIFTRIGHT, LCDLINE1HOME, LCDLINE2HOME, LCDLINE3HOME, LCDLINE4HOME, LCDLINE1CLEAR, LCDLINE2CLEAR, LCDLINE3CLEAR, LCDLINE4CLEAR, LCDLINE1POS, LCDLINE2POS, LCDLINE3POS, LCDLINE4POS, LCDDEFCHAR, LF, LONG, LOOKUP, LOW, MOD, NAND, NEXT, NOR, NOT, NXOR, ON INTERRUPT, OR, OUTPUT, POINTER, PROC, READ, RESERVE, RESUME, RETURN, SELECT CASE, SERIN, SERININV, SEROUT, SEROUTINV, SEROUT_DELAYUS, SERVOIN, SERVOOUT, SHIFTLEFT, SHIFTRIGHT, SIMULATION_WAITMS_VALUE, SPI_CS_REG, SPI_CS_BIT, SPI_SCK_REG, SPI_SCK_BIT, SPI_SDI_REG, SPI_SDI_BIT, SPI_SDO_REG, SPI_SDO_BIT, SPICS_INVERT, SPICLOCK_INVERT, SPICLOCK_STRETCH, SPICSON, SPICSOFF, SPIPREPARE, SPISEND, SPISENDBITS, SPIRECEIVE, SQR, STARTFROMZERO, STEP, STEP_A_REG, STEP_A_BIT, STEP_B_REG, STEP_B_BIT, STEP_C_REG, STEP_C_BIT, STEP_D_REG, STEP_D_BIT, STEP_MODE, STEPHOLD, STEPCW, STEPCCW, SYMBOL, THEN, TO, TOGGLE, TRUE, WAITMS, WAITUS, WEND, WHILE, WORD, WRITE, XOR.
 

● Standard Basic language elements

Default extension for basic source files is BAS. The compiler output is assembler source file (with ASM extension) that can be translated to binary code using integrated assembler. Smart editor marks all reserved keywords in different color, that simplifies debugging process. BASIC compiler's assembler output has all necessary comment lines, that makes it very useful for educational purposes, also.

Four data types are supported:
- Bit (1-bit, 0 or 1)
- Byte (1-byte integers in the range 0 to 255)
- Word (2-byte integers in the range 0 to 65,535)
- Long (4-byte integers in the range 0 to 4,294,967,295) - optional module

Declarations may be placed anywhere in the program. All variables are considered global. The total number of variables is limited by the available microcontroller SRAM memory. Variables are declared using DIM statement:
DIM A AS BIT
DIM B AS BYTE
DIM C AS WORD
DIM D AS LONG

If necessary, variable address can be specified during declaration:
DIM B AS BYTE @ 0x062

It is also possible to use one-dimensional arrays. For example:
DIM A(10) AS BYTE

declares an array of 10 Byte variables with array index in the range [0-9].

RESERVE statement allows advanced usage by reserving some of the SRAM locations to be used by in-code assembler routines. For example:
RESERVE 0x065

High and low byte of a word variable can be addressed by .HB and .LB extensions. Individual bits can be addressed by .0, .1, ..., .14 and .15 extensions. It is possible to make conversions between Byte and Word data types using .LB and .HB extensions or directly:
DIM A AS BYTE
DIM B AS WORD
A = B.HB
A = B.LB 'This statement is equivalent to A = B
B.HB = A
B.LB = A
B = A 'This statement will also clear the high byte of B variable

High word (composed by bytes 3 and 2) and low word (composed by bytes 1 and 0) of a long variable can be addressed by .HW and .LW extensions. Byte 0 can be addressed by .LB and byte 1 by .HB extensions. For example:
DIM A AS BYTE
DIM B AS WORD
DIM C AS LONG
A = C.LB
B = C.HW

All general purpose working and I/O registers are available as Byte variables in basic programs. Individual bits of a Byte variable can be addressed by .0, .1, .2, .3, .4, .5, .6 and .7 extensions or using official names of the bits. The lists of these predefined variables and official bit names for the selected AVR device can be viewed by selecting Show System Variables and Show System Bit Names commands from the Options menu of the basic compiler window.
DIM A AS BIT
DIM B AS BYTE
A = B.7
B.6 = 1
R26 = 10
XH = R26
DDRD.1 = 1
DDRB = 255
PORTD.1 = 1
PORTB = 255
GIMSK.PCIE = 1
SREG.SREG_I = 1

Standard short forms for accessing port registers (PORTx) and individual chip pins (PORTx.n) are also available (PA, PB, PC, ... can be used as Byte variables; PA0, PA1, PA2, ..., PB7, PC0, ... are available as Bit variables). It should be noted that these short forms can not be used to address port and pin input states. PINx and PINx.n should be used for that purpose ('x' represents the port numbering letter; 'n' represents the bit number).
PB = 0xFF
PD5 = 1

Microcontroller ports and pins can be configured as inputs or outputs by assigning proper values to DDRx registers or their bits. That task can also be accomplished by a CONFIG statement. Its syntax is apparent from the following examples:
CONFIG PORTB = OUTPUT
CONFIG PA0 = OUTPUT
CONFIG PORTC.3 = INPUT
CONFIG PD = INPUT

Any variable that is declared as a Byte or Word variable using Dim statement can be used as a pointer to internal data SRAM memory when it is used as an argument of POINTER function. The value contained in the variable that is used as a pointer should be in the appropriate range. Here is one example:
DIM A AS WORD
DIM B AS BYTE
DIM C AS LONG
A = 0x070
B = POINTER(A) 'The content of SRAM location $070 will be loaded to variable B
B = B + 0x55
A = A - 1
POINTER(A) = B 'Modified B value will be stored to SRAM location $06F
A = 0x077
C = 0x12345678
POINTER(A) = C 'Four SRAM locations $077-$07A will be loaded with the 4-byte value contained in variable C

It is also possible to use symbolic names (symbols) in programs:
SYMBOL LED1 = PORTB.0
LED1 = 1
SYMBOL ADC_START = ADCSRA.ADSC
ADC_START = 1

Constants can be used in decimal number system with no special marks, in hexadecimal number system with leading 0x or leading $ notation (or with H at the end) and in binary system with leading % mark (or with B at the end). Keywords True and False are also available for Bit type constants. For example:
DIM A AS BIT
DIM B AS BYTE
A = TRUE
B = 0x55
B = %01010101

Constants can also be assigned to symbolic names using CONST directive:
DIM A AS WORD
CONST PI = 314
A = PI

There are three statements that are used for bit manipulation - HIGH, LOW and TOGGLE. If the argument of these statements is a bit in one of the PORT registers, then the same bit in the corresponding DDR register is automatically set, configuring the affected pin as an output pin. Some examples:
HIGH PORTB.0
LOW ADCSRA.ADEN
TOGGLE PB1

Five arithmetic operations (+, -, *, /, MOD) are available for Byte, Word and Long data types. The compiler is able to compile all possible complex arithmetic expressions. For example:
DIM A AS WORD
DIM B AS WORD
DIM C AS WORD
A = 123
B = A * 234
C = 2
C = (B * C - 12345) / (A + C)

Square root of a number (0-65535 range) can be calculated using SQR function:
DIM A AS WORD
A = 3600
A = SQR(A)

For Bit data type variables seven logical operations are available. It is possible to make only one logical operation in one single statement. Logical operations are also available for Byte and Word variables. For example:
DIM A AS BIT
DIM B AS BIT
DIM C AS BIT
C = NOT A
C = A AND B
C = A OR B
C = A XOR B
C = A NAND B
C = A NOR B
C = A NXOR B


DIM A AS WORD
DIM B AS WORD
A = A OR B
PORTB = PORTD AND %11110000

The clock frequency of the target device can be specified by setting the CLOCK_FREQUENCY parameter with the DEFINE directive (the value is expressed in MHz). This parameter should be setup at the beginning of the basic program. For example:
DEFINE CLOCK_FREQUENCY = 20

The GOTO statement uses line label name as argument. Line labels must be followed by colon mark ":". Here is one example:
DIM A AS WORD
A = 0
loop: A = A + 1
GOTO loop

WAITMS and WAITUS statements can be used to force program to wait for the specified number of milliseconds or microseconds. It is also possible to use variable argument of Byte or Word data type. These routines use Clock Frequency parameter that can be changed from the Options menu. WAITUS routine has minimal delay and step that also depend on the Clock Frequency parameter.
DIM A AS WORD
A = 100
WAITMS A
WAITUS 50

PLEASE NOTE: When writing programs for real AVR devices you will most likely use delay intervals that are comparable to 1 second or 1000 milliseconds. Many examples in this help file also use such 'real-time' intervals. But, if you want to simulate those programs you have to be very patient to see something to happen, even on very powerful PCs available today. For simulation of 'WaitMs 1000' statement on 4MHz you have to wait the simulator to simulate 4000000 instructions and it will take considerable amount of time even if 'extremely fast' simulation rate is selected. So, just for the purpose of simulation you should recompile your programs with adjusted delay intervals, that should not exceed 1-10ms. But, be sure to recompile your program with original delays before you download it to a real device. There is an easy way to change arguments of all WAITMS statements in a large basic program with a value in the range 1-10 for simulation purposes. With one line of code setting parameter SIMULATION_WAITMS_VALUE with DEFINE directive, the arguments of all WAITMS statements in the program will be ignored and the specified value will be used instead during compiling. Setting the value 0 (default) for this parameter (or omitting the whole line) will cancel its effect and the compiled code will be ready again for the real hardware.

FREQOUT statement can be used to generate a train of pulses (sound tone) on the specified pin with constant frequency and specified duration. It has three arguments. The first argument is the pin that the tone will be generated on. It should previously be setup as an output pin. The second argument specify the tone frequency and it must be a constant in the range 1-10000Hz. The third argument defines the tone duration and it also must be a numeric constant in the range 1-10000ms. Choosing higher tone frequencies with low microcontroller clock frequency used may result in somewhat inaccurate frequency of the generated tones. FREQOUT statement can be alternatively used in 'variable mode' with Word data type variables instead of constants for the last two arguments. In this mode of usage the second argument is supposed to hold the half-period of the tone (in microseconds) and the third argument must hold the total number of pulses that will be generated. The following code will generate one second long tone on PB0 pin with 600Hz frequency:
DDRB.0 = 1
FREQOUT PORTB.0, 600, 1000

Four standard BASIC structures are supported: FOR-TO-STEP-NEXT, WHILE-WEND, IF-THEN-ELSE-ENDIF and SELECT CASE-CASE-ENDSELECT. Here are several examples:
DIM A AS BYTE
DDRB = 255
A = 255
WHILE A > 0
   PORTB = A
   A = A - 1
   WAITMS 100
WEND
PORTB = A


DDRB.0 = 1
loop:
IF PINA.0 THEN
   PORTB.0 = 1
ELSE
   PORTB.0 = 0
ENDIF
GOTO loop


DIM A AS WORD
DDRB = 255
FOR A = 0 TO 10000 STEP 10
   PORTB = A.LB
NEXT A


DIM A AS BYTE
DIM B AS BYTE
DIM C AS BYTE
B = 255
C = 2
DDRB = 255
FOR A = B TO 0 STEP -C
   PORTB = A
NEXT A


DIM A AS BYTE
loop:
SELECT CASE A
CASE 255
   A = 1
CASE <= 127
   A = A + 1
CASE ELSE
   A = 255
ENDSELECT
GOTO loop

After IF-THEN statement in the same line can be placed almost every other possible statement and then ENDIF is not used. There are no limits for the number of nested statements of any kind. In the test expressions of IF-THEN and WHILE statements it is possible to use multiple ORed and multiple ANDed conditions. Multiple comma separated conditions can be used with CASE statements, also.

LOOKUP function can be used to select one from the list of Byte constants, based on the value in the index variable, that is supplied as the last separated argument of the function. The first constant in the list has index value 0. The selected Byte constant will be loaded into the result variable of the function. If the value in the index variable goes beyond the number of constants in the list, the result variable will not be affected by the function. Here is one small example for a 7-segment LED display:
DIM DIGIT AS BYTE
DIM MASK AS BYTE
loop:
DDRB = %11111111
FOR DIGIT = 0 TO 9
   MASK = LOOKUP(0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F), DIGIT
   PORTB = MASK
   WAITMS 1000
NEXT DIGIT
GOTO loop

If all constants in the list (or part of them) are ASCII values, then shorter form of the list can be created by using string arguments. For example:
MASK = LOOKUP("ABCDEFGHIJK"), INDEX

SHIFTLEFT and SHIFTRIGHT functions can be used to shift bit-level representation of a variable left and right. The first argument is input variable and the second argument is number of shifts to be performed. Here are two examples:
DDRB = 0xFF
PORTB = %00000011
goleft:
WAITMS 250
PORTB = SHIFTLEFT(PORTB, 1)
IF PORTB = %11000000 THEN GOTO goright
GOTO goleft
goright:
WAITMS 250
PORTB = SHIFTRIGHT(PORTB, 1)
IF PORTB = %00000011 THEN GOTO goleft
GOTO goright


DDRB = 0xFF
PORTB = %00000001
goleft:
WAITMS 250
PORTB = SHIFTLEFT(PORTB, 1)
IF PORTB.7 THEN GOTO goright
GOTO goleft
goright:
WAITMS 250
PORTB = SHIFTRIGHT(PORTB, 1)
IF PORTB.0 THEN GOTO goleft
GOTO goright

Structured programs can be written using subroutine calls with GOSUB statement that uses line label name as argument. Return from a subroutine is performed by RETURN statement. User need to take care that the program structure is consistent. When using subroutines, main routine need to be ended with END statement. END statement is compiled as an infinite loop. Here is an example:
SYMBOL adc_start = ADCSRA.ADSC
SYMBOL display = PORTB
DDRB = %11111111
ADMUX = 0x01 'Select ADC1 input channel
ADCSRB = 0x10 'Left adjust ADC result
ADCSRA.ADEN = 1
main:
GOSUB getadcresult
display = ADCH
GOTO main
END
getadcresult:
HIGH adc_start
WHILE adc_start
WEND
RETURN

If there is a need to insert an infinite loop in basic program, that can be done with HALT statement.

It is possible to insert breakpoints for the simulator directly in basic programs using BREAK statement. It is compiled as BREAK assembler instruction and the simulator will interpret this opcode as a breakpoint and switch the simulation rate to Step By Step.

It is possible to use comments in basic source programs. The comments must begin with single quote symbol (') and may be placed anywhere in the program.

Lines of assembler source code may be placed anywhere in basic source program and must begin with ASM: prefix. For example:
ASM:        NOP
ASM:LABEL1: LDI R16,0xFF

Symbolic names of declared variables can be used in assembler routines because proper variable address will be assigned to those names by EQU directive:
DIM VARNAME AS BYTE
ASM:        LDI R16,0xFF
ASM:        STS VARNAME,R16

● Structured language support (procedures and functions) - optional module

Procedures can be declared with PROC statement. They can contain up to 5 arguments (comma separated list) and all available data types can be used for argument variables. Argument variables are declared locally, so they do not need to have unique names in relation to the rest of user basic program, that makes very easy to re-use once written procedures in other basic programs. The procedures can be exited with EXIT statement. They must be ended with END PROC statement and must be placed after the END statement in program. Calls to procedures are implemented with CALL statement. The list of passed arguments can contain both variables and numeric constants. For example:
DIM A AS BYTE
DDRB = 255
FOR A = 0 TO 255
   CALL portb_display(A)
   WAITMS 100
NEXT A
END
 
PROC portb_display(arg1 AS BYTE)
PORTB = arg1
END PROC

All facts stated for procedures are valid for functions, also. Functions can be declared with FUNCTION statement. They can contain up to 5 arguments and argument variables are declared locally. Functions can be exited with EXIT statement and must be ended with END FUNCTION. The name of the function is declared as a global variable, so if the function is called with CALL statement, after its execution the function variable will contain the result. Standard way of function calls in assignment statements can be used, also. One simple example:
DIM A AS BYTE
DIM B AS WORD
FOR A = 0 TO 255
   B = square(A)
NEXT A
END
 
FUNCTION square(arg1 AS WORD) AS WORD
square = arg1 * arg1
END FUNCTION

● Using internal EEPROM data memory

Access to internal EEPROM data memory can be implemented using READ and WRITE statements. The first argument is the address of a byte in EEPROM memory and can be a constant or a variable. The second argument is data that is read or written (for READ statement it must be a variable argument; for WRITE statement it can also be a constant).
DIM A AS BYTE
DIM B AS BYTE
A = 10
READ A, B
WRITE 11, B

● Using internal A/D converter module

ADCIN statement is available as a support for internal A/D converter. It has two arguments. The first argument is ADC channel number and the second argument is a variable that will be used to store the result of A/D conversion. It is not only possible to convert single-ended inputs with ADCIN statement, but also differential inputs with various gain selections. For that purpose the appropriate value for MUX bits (ADMUX register) should be used as ACD channel number argument of ADCIN statement. If a Byte variable is used for the conversion result, 8-bit conversion will be performed (left adjusted result). ADCIN statement uses values of three parameters ADC_CLOCK, ADC_VREF and ADC_SAMPLEUS. Their default values can be changed using DEFINE directive. ADC_CLOCK parameter determines the choice for ADC input clock prescaler selection. Allowed range is 0-7 and the default value is 3 for 1:8 prescaler selection. ADC_VREF parameter defines the ADC voltage reference selection. Its value is used to setup REFS bits in ADMUX register. The default value is 0. ADC_SAMPLEUS parameter (default value 20) sets the desired ADC acquisition time in microseconds (0-255). Here is one example:
DIM V(5) AS BYTE
DIM VM AS WORD
DIM I AS BYTE
DEFINE ADC_CLOCK = 3
DEFINE ADC_VREF = 0
DEFINE ADC_SAMPLEUS = 50
DDRA = 0x00
DDRB = 0xFF
FOR I = 0 TO 4
   ADCIN 0, V(I)
NEXT I
VM = 0
FOR I = 0 TO 4
   VM = VM + V(I)
NEXT I
VM = VM / 5
PORTB = VM.LB

● Using interrupts

Interrupt routines should be placed as all other subroutines after the END statement. A separate routine should be implemented for every interrupt source used. The list of available interrupt sources for the selected AVR device with their official names can be viewed by selecting Show System Interrupt Names command from the Options menu of the basic compiler window. Interrupt routine should begin with ON INTERRUPT keyword followed by the official name of its interrupt source and it should end with RESUME statement. ENABLE and DISABLE statements followed by an interrupt source name can be used in the program to control the status of its enable flag. If used with no arguments they will control the status of the global interrupt enable flag (I-flag) in the SREG register. RESUME statement will automatically set the I-flag and enable new interrupts. One example:
DIM A AS BYTE
A = 255
DDRB = 0xFF
PORTB = A
DDRD.2 = 0 'configure INT0 pin as an input pin
MCUCR.ISC00 = 1
MCUCR.ISC01 = 1 'INT0 rising edge generates an interrupt
ENABLE INT0
ENABLE
END
ON INTERRUPT INT0
   A = A - 1
   PORTB = A
RESUME

● Serial communication using internal hardware USART

The support for both hardware and software serial communication is also available. HSEROPEN, HSEROUT, HSERIN and HSERGET statements can be used with AVR devices that feature internal hardware USART. HSEROPEN statement sets up the hardware USART. Its only argument is baud rate and allowed values are: 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 31250, 38400, 56000 and 57600. If the argument is omitted USART will be set up for 9600 baud rate. If parameter ALLOW_MULTIPLE_HSEROPEN is set to 1 using DEFINE directive, it will be possible to use HSEROPEN statement more than once in the program, for example to change the selected baud rate. If ALLOW_ALL_BAUDRATES parameter is set to 1 using DEFINE directive all baud rates in the range 100-200000 will be allowed. HSEROUT statement is used for serial transmission. HSEROUT statement may have multiple arguments separated by ','. You can use strings, LF keyword for Line Feed character or CRLF keyword for Carriage Return - Line Feed sequence, constants and variables. If '#' sign is used before the name of a variable then its decimal representation is sent to the serial port. HSERIN statement can be used to load a list of Byte, Word and Long variables with the values received on serial port. This statement will wait until the required number of bytes is received on serial port. HSERGET statement have one argument that must be a Byte variable. If there is a character waiting in the receive buffer it will be loaded in the variable, otherwise 0 value will be loaded. Here are some examples:
DIM I AS BYTE
HSEROPEN 38400
WAITMS 1000
FOR I = 20 TO 0 STEP -1
   HSEROUT "Number: ", #I, CrLf
   WAITMS 500
NEXT I


DIM I AS BYTE
HSEROPEN 19200
loop:
   HSERIN I
   HSEROUT "Number: ", #I, CrLf
GOTO loop


DIM I AS BYTE
HSEROPEN 19200
loop:
   HSERGET I
   IF I > 0 THEN
      HSEROUT "Number: ", #I, CrLf
      WAITMS 50
   ENDIF
GOTO loop

● Software UART implementation

On all supported AVR devices software serial communication can be implemented with SEROUT and SERIN statements. The first argument of both statements must be one of the microcontroller's pins, and the second argument is baud rate: 300, 600, 1200, 2400, 4800, 9600 or 19200. Using higher baud rates with low clock frequency could cause framing errors. For SEROUT statement then follows the list of arguments to be sent to serial port. You can use strings, LF keyword for Line Feed character or CRLF keyword for Carriage Return - Line Feed sequence, constants and variables. If '#' sign is used before the name of a variable then its decimal representation is sent to the serial port. SEROUT statement uses SEROUT_DELAYUS parameter that can be set by DEFINE directive and has default value of 1000 microseconds. This defines the delay interval before a character is actually sent to the port and it is used to increase the reliability of software SEROUT routine. For SERIN statement then follows the list of Byte, Word and Long variables to be loaded with the values received on serial port. This statement will wait until the required number of bytes is received on serial port. For serial interface with inverted logic levels there are SERININV and SEROUTINV statements available. Some examples:
DEFINE SEROUT_DELAYUS = 5000
SEROUT PORTD.1, 1200, "Hello world!", CrLf


DIM I AS BYTE
loop:
   SERIN PORTD.0, 9600, I
   SEROUT PORTD.1, 9600, "Number: ", #I, CrLf
GOTO loop

● I2C communication with external I2C devices

I2C communication can be implemented in basic programs using I2CWRITE and I2CREAD statements. The first argument of both statements must be one of the microcontroller's pins that is connected to the SDA line of the external I2C device. The second argument of both statements must be one of the microcontroller's pins that is connected to the SCL line. The third argument of both statements must be a constant value or Byte variable called 'slave address'. Its format is described in the datasheet of the used device. For example, for EEPROMs from 24C family (with device address inputs connected to ground) the value 0xA0 should be used for slave address parameter. Both statements will take control over bit 0 of slave address during communication. The forth argument of both statements must be a Byte or Word variable (this depends on the device used) that contains the address of the location that will be accessed. If a constant value is used for address parameter it must be in Byte value range. The last (fifth) argument of I2CWRITE statement is a Byte constant or variable that will be written to the specified address, and for I2CREAD statement it must be a Byte variable to store the value that will be read from the specified address. It is allowed to use more than one 'data' argument. For I2C devices that do not support data address argument there is short form of I2C statements (I2CWRITE1 and I2CREAD1) available where slave address argument is followed with one or more data arguments directly. For some I2C slave devices it is necessary to make a delay to make sure device is ready to respond to I2CREAD statement. For that purpose there is I2CREAD_DELAYUS parameter that can be set by DEFINE directive and has default value of 0 microseconds. Also, for slower I2C devices, it might be necessary to use longer clock pulses. That can be done by setting I2CCLOCK_STRETCH parameter using DEFINE directive. This parameter will set clock stretch factor. Its default value is 1. Here is one combined example with LCD module and 24C64 EEPROM (SDA connected to RC1; SCL connected to RC0):
DEFINE LCD_BITS = 8
DEFINE LCD_DREG = PORTB
DEFINE LCD_DBIT = 0
DEFINE LCD_RSREG = PORTD
DEFINE LCD_RSBIT = 1
DEFINE LCD_EREG = PORTD
DEFINE LCD_EBIT = 3
DEFINE LCD_RWREG = PORTD
DEFINE LCD_RWBIT = 2
DIM ADDR AS WORD
DIM DATA AS BYTE
SYMBOL SDA = PORTC.1
SYMBOL SCL = PORTC.0
LCDINIT 3
WAITMS 1000
FOR ADDR = 0 TO 31
   LCDCMDOUT LcdClear
   DATA = 255 - ADDR
   I2CWRITE SDA, SCL, 0xA0, ADDR, DATA
   LCDOUT "Write To EEPROM"
   LCDCMDOUT LcdLine2Home
   LCDOUT "(", #ADDR, ") = ", #DATA
   WAITMS 1000
NEXT ADDR
FOR ADDR = 0 TO 31
   LCDCMDOUT LcdClear
   I2CREAD SDA, SCL, 0xA0, ADDR, DATA
   LCDOUT "Read From EEPROM"
   LCDCMDOUT LcdLine2Home
   LCDOUT "(", #ADDR, ") = ", #DATA
   WAITMS 1000
NEXT ADDR

There is a set of low-level I2C communication statements available, if it is needed to have more control over I2C communication process. I2CPREPARE statement has two arguments that must be one of the microcontroller's pins. The first argument defines SDA line and second argument defines SCL line. This statement will prepare these lines for I2C communication. I2CSTART statement will generate start condition, and I2CSTOP statement will generate stop condition. One byte can be sent to the I2C slave using I2CSEND statement. After the statement is executed T bit in SREG register will hold the copy of the state on the SDA line during the acknowledge cycle. There are two statements that can be used to receive one byte from I2C slave. I2CRECA or I2CRECEIVEACK will generate acknowledge signal during acknowlegde cycle after the byte is received. I2CRECN or I2CRECEIVENACK will generate not acknowledge signal during acknowlegde cycle after the byte is received. One example:
DIM ADDR AS WORD
DIM DATA(31) AS BYTE
SYMBOL SDA = PORTC.1
SYMBOL SCL = PORTC.0
ADDR = 0
I2CPREPARE SDA, SCL
I2CSTART
I2CSEND 0xA0
I2CSEND ADDR.HB
I2CSEND ADDR.LB
I2CSTOP
I2CSTART
I2CSEND 0xA1
FOR ADDR = 0 TO 30
   I2CRECEIVEACK DATA(ADDR)
NEXT ADDR
I2CRECN DATA(31)
I2CSTOP

● Support for Serial Peripheral Interface (SPI) communication

Prior to using SPI related statements, SPI interface should be set up using DEFINE directives. There are eight available parameters to define the connection of SCK, SDI, SDO and (optionally) CS lines:
SPI_SCK_REG - defines the port where SCK line is connected to
SPI_SCK_BIT - defines the pin where SCK line is connected to
SPI_SDI_REG - defines the port where SDI line is connected to
SPI_SDI_BIT - defines the pin where SDI line is connected to
SPI_SDO_REG - defines the port where SDO line is connected to
SPI_SDO_BIT - defines the pin where SDO line is connected to
SPI_CS_REG - defines the port where CS line is connected to
SPI_CS_BIT - defines the pin where CS line is connected to
The assumed settings are active-high for Clock line and active-low for ChipSelect line. That can be changed by assigning the value 1 to SPICLOCK_INVERT and/or SPICS_INVERT parameters by DEFINE directive. For slower SPI devices, it might be necessary to use longer clock pulses. The default clock stretch factor (1) can be changed by setting SPICLOCK_STRETCH parameter.

SPIPREPARE statement (no arguments) will prepare interface lines for SPI communication. SPICSON and SPICSOFF statements will enable/ disable the ChipSelect line of the interface. One byte can be sent to the SPI peripheral using SPISEND statement. To receive a byte from the peripheral SPIRECEIVE statement should be used. To send the specified number of bits there is SPISENDBITS statement available. Its first argument should be the number of bits to be sent [1-8] and the second argument is a byte variable or constant. Here is one example for using 25C040 SPI eeprom:
Define SPI_CS_REG = PORTC
Define SPI_CS_BIT = 3
Define SPI_SCK_REG = PORTC
Define SPI_SCK_BIT = 2
Define SPI_SDI_REG = PORTC
Define SPI_SDI_BIT = 5
Define SPI_SDO_REG = PORTC
Define SPI_SDO_BIT = 4
SPIPrepare
 
DEFINE LCD_BITS = 8
DEFINE LCD_DREG = PORTB
DEFINE LCD_DBIT = 0
DEFINE LCD_RSREG = PORTD
DEFINE LCD_RSBIT = 1
DEFINE LCD_EREG = PORTD
DEFINE LCD_EBIT = 3
DEFINE LCD_RWREG = PORTD
DEFINE LCD_RWBIT = 2
Define LCD_READ_BUSY_FLAG = 1
Lcdinit
 
Dim addr As Byte
Dim data As Byte
 
For addr = 0 To 10
   data = 200 - addr
   SPICSOn
   SPISend 0x06
   SPICSOff
   SPICSOn
   SPISend 0x02
   SPISend addr
   SPISend data
   SPICSOff
   Lcdcmdout LcdClear
   Lcdout "Write To EEPROM"
   Lcdcmdout LcdLine2Home
   Lcdout "(", #addr, ") = ", #data
   WaitMs 500
Next addr
 
For addr = 0 To 10
   SPICSOn
   SPISend 0x03
   SPISend addr
   SPIReceive data
   SPICSOff
   Lcdcmdout LcdClear
   Lcdout "Read From EEPROM"
   Lcdcmdout LcdLine2Home
   Lcdout "(", #addr, ") = ", #data
   WaitMs 500
Next addr

Here is the same example written for 93C86 Microwire EEPROM:
Define SPI_CS_REG = PORTC
Define SPI_CS_BIT = 3
Define SPICS_INVERT = 1
Define SPI_SCK_REG = PORTC
Define SPI_SCK_BIT = 2
Define SPI_SDI_REG = PORTC
Define SPI_SDI_BIT = 5
Define SPI_SDO_REG = PORTC
Define SPI_SDO_BIT = 4
SPIPrepare
 
DEFINE LCD_BITS = 8
DEFINE LCD_DREG = PORTB
DEFINE LCD_DBIT = 0
DEFINE LCD_RSREG = PORTD
DEFINE LCD_RSBIT = 1
DEFINE LCD_EREG = PORTD
DEFINE LCD_EBIT = 3
DEFINE LCD_RWREG = PORTD
DEFINE LCD_RWBIT = 2
Define LCD_READ_BUSY_FLAG = 1
Lcdinit
 
Dim addr As Byte
Dim data As Byte
 
SPICSOn
SPISendBits 6, %100110
SPISendBits 8, %00000000
SPICSOff
 
For addr = 0 To 10
   data = 200 - addr
   SPICSOn
   SPISendBits 6, %101000
   SPISendBits 8, addr
   SPISend data
   SPICSOff
   SPICSOn
   SPISend 0x00
   SPICSOff
   Lcdcmdout LcdClear
   Lcdout "Write To EEPROM"
   Lcdcmdout LcdLine2Home
   Lcdout "(", #addr, ") = ", #data
   WaitMs 500
Next addr
 
For addr = 0 To 10
   SPICSOn
   SPISendBits 6, %110000
   SPISendBits 8, addr
   SPIReceive data
   SPICSOff
   Lcdcmdout LcdClear
   Lcdout "Read From EEPROM"
   Lcdcmdout LcdLine2Home
   Lcdout "(", #addr, ") = ", #data
   WaitMs 500
Next addr

● Interfacing character LCDs

Basic compiler also features the support for LCD modules based on HD44780 or compatible controller chip. Prior to using LCD related statements, user should set up LCD interface using DEFINE directives. Here is the list of available parameters:
LCD_BITS - defines the number of data interface lines (allowed values are 4 and 8; default is 4)
LCD_DREG - defines the port where data lines are connected to (default is PORTB)
LCD_DBIT - defines the position of data lines for 4-bit interface (0 or 4; default is 4), ignored for 8-bit interface
LCD_RSREG - defines the port where RS line is connected to (default is PORTB)
LCD_RSBIT - defines the pin where RS line is connected to (default is 3)
LCD_EREG - defines the port where E line is connected to (default is PORTB)
LCD_EBIT - defines the pin where E line is connected to (default is 2)
LCD_RWREG - defines the port where R/W line is connected to (set to 0 if not used; 0 is default)
LCD_RWBIT - defines the pin where R/W line is connected to (set to 0 if not used; 0 is default)
LCD_COMMANDUS - defines the delay after LCDCMDOUT statement (default value is 5000)
LCD_DATAUS - defines the delay after LCDOUT statement (default value is 100)
LCD_INITMS - defines the delay for LCDINIT statement (default value is 100)
The last three parameters should be set to low values when using integrated LCD module simulator. If R/W line is connected to microcontroller and parameter LCD_READ_BUSY_FLAG is set to 1 using DEFINE directive, then these delay parameters will be ignored by compiler and correct timing will be implemented by reading the status of the busy flag in the LCD.

LCDINIT statement should be placed in the program before any of LCDOUT (used for sending data) and LCDCMDOUT (used for sending commands) statements. Numeric constant argument of LCDINIT is used to define the cursor type: 0 = no cursor (default), 1 = blink, 2 = underline, 3 = blink + underline. LCDOUT and LCDCMDOUT statements may have multiple arguments separated by ','. Strings, constants and variables can be used as arguments of LCDOUT statement. If '#' sign is used before the name of a variable then its decimal representation is sent to the LCD module. Constants and variables can be used as arguments of LCDCMDOUT statement and the following keywords are also available: LcdClear, LcdHome, LcdLine2Home, LcdDisplayOn, LcdDisplayOff, LcdCurOff, LcdCurBlink, LcdCurUnderline, LcdCurBlinkUnderline, LcdLeft, LcdRight, LcdShiftLeft, LcdShiftRight, LcdLine1Clear, LcdLine2Clear, LcdLine1Pos() and LcdLine2Pos(). Argument of LcdLine1Pos() and LcdLine2Pos() can be a number in the range (1-40) or a variable. The value contained in that variable should be in the same range. LcdDisplayOn and LcdDisplayOff will turn the cursor off. Cursor related symbolic commands can be used as arguments of LCDINIT. Here are some examples:
DEFINE LCD_BITS = 8
DEFINE LCD_DREG = PORTB
DEFINE LCD_DBIT = 0
DEFINE LCD_RSREG = PORTD
DEFINE LCD_RSBIT = 1
DEFINE LCD_EREG = PORTD
DEFINE LCD_EBIT = 3
DEFINE LCD_RWREG = PORTD
DEFINE LCD_RWBIT = 2
LCDINIT LcdCurBlink
loop:
   LCDOUT "Hello world!"
   WAITMS 1000
   LCDCMDOUT LcdClear
   WAITMS 1000
GOTO loop


DEFINE LCD_BITS = 8
DEFINE LCD_DREG = PORTB
DEFINE LCD_DBIT = 0
DEFINE LCD_RSREG = PORTD
DEFINE LCD_RSBIT = 1
DEFINE LCD_EREG = PORTD
DEFINE LCD_EBIT = 3
DEFINE LCD_RWREG = PORTD
DEFINE LCD_RWBIT = 2
DIM A AS WORD
A = 65535
LCDINIT 3
WAITMS 1000
loop:
   LCDOUT "I am counting!"
   LCDCMDOUT LcdLine2Home
   LCDOUT #A
   A = A - 1
   WAITMS 250
   LCDCMDOUT LcdClear
GOTO loop

LCD related statements will take control over DDR registers connected with pins used for LCD interface.

You can setup up to eight user defined characters to be used on LCD. This can easily be done with LCDDEFCHAR statement. The first argument of this statement is char number and must be in the range 0-7. Next 8 arguments form 8-line char pattern (from the top to the bottom) and must be in the range 0-31 (5-bits wide). These 8 user characters are assigned to char codes 0-7 and 8-15 and can be displayed using LCDOUT statement. After LCDDEFCHAR statement the cursor will be in HOME position. For example:
LCDDEFCHAR 0, 10, 10, 10, 10, 10, 10, 10, 10
LCDDEFCHAR 1, %11111, %10101, %10101, %10101, %10101,
%10101, %10101, %11111
LCDOUT 0, 1, "Hello!", 1, 0

For LCDs with four lines of characters additional symbolic arguments of LCDCMDOUT statement can be used: LcdLine3Home, LcdLine4Home, LcdLine3Clear, LcdLine4Clear, LcdLine3Pos() and LcdLine4Pos(). Argument of LcdLine3Pos() and LcdLine4Pos() can be a number in the range (1-40) or a variable. The value contained in that variable should be in the same range. Prior to using these language elements, correct values determining LCD type should be assigned to LCD_LINES and LCD_CHARS parameters using DEFINE directives.
DEFINE LCD_LINES = 4
DEFINE LCD_CHARS = 16
DEFINE LCD_BITS = 8
DEFINE LCD_DREG = PORTB
DEFINE LCD_DBIT = 0
DEFINE LCD_RSREG = PORTD
DEFINE LCD_RSBIT = 1
DEFINE LCD_EREG = PORTD
DEFINE LCD_EBIT = 3
DEFINE LCD_RWREG = PORTD
DEFINE LCD_RWBIT = 2
LCDINIT 3
loop:
   LCDCMDOUT LcdClear
   LCDCMDOUT LcdLine1Home
   LCDOUT "This is line 1"
   LCDCMDOUT LcdLine2Home
   LCDOUT "This is line 2"
   LCDCMDOUT LcdLine3Home
   LCDOUT "This is line 3"
   LCDCMDOUT LcdLine4Home
   LCDOUT "This is line 4"
   WAITMS 1000
   LCDCMDOUT LcdLine1Clear
   LCDCMDOUT LcdLine2Clear
   LCDCMDOUT LcdLine3Clear
   LCDCMDOUT LcdLine4Clear
   LCDCMDOUT LcdLine1Pos(1)
   LCDOUT "Line 1"
   LCDCMDOUT LcdLine2Pos(2)
   LCDOUT "Line 2"
   LCDCMDOUT LcdLine3Pos(3)
   LCDOUT "Line 3"
   LCDCMDOUT LcdLine4Pos(4)
   LCDOUT "Line 4"
   WAITMS 1000
GOTO loop

● Interfacing graphical LCDs with 128x64 dot matrix

Interfacing graphical LCDs with dot matrix resolution 128x64 controlled by KS0107 or compatible chip is supported with the following list of Basic language elements: GLCDINIT, GLCDCLEAR, GLCDPSET, GLCDPRESET, GLCDPOSITION, GLCDWRITE, GLCDCLEAN, GLCDOUT, GLCDIN, GLCDCMDOUT. Prior to using Graphical LCDs related statements, user should set up the interface with the graphical LCD module using DEFINE directives. Here is the list of available parameters:
GLCD_DREG - defines the port where data lines are connected to (it has to be a full 8-pins port)
GLCD_RSREG - defines the port where RS line is connected to
GLCD_RSBIT - defines the pin where RS line is connected to
GLCD_EREG - defines the port where E line is connected to
GLCD_EBIT - defines the pin where E line is connected to
GLCD_RWREG - defines the port where R/W line is connected to
GLCD_RWBIT - defines the pin where R/W line is connected to
GLCD_CS1REG - defines the port where CS1 line is connected to
GLCD_CS1BIT - defines the pin where CS1 line is connected to
GLCD_CS2REG - defines the port where CS2 line is connected to
GLCD_CS2BIT - defines the pin where CS2 line is connected to

GLCDINIT statement should be placed somewhere at the beginning of the basic program before any other graphical LCD related stetements are used. Graphical LCD related statements will take control over DDR registers connected with pins used for LCD interface.

GLCDCLEAR statement will clear the whole display. It can be used with one optional constant argument in the range 0-255 that will be placed on every byte position on the display (128x64 graphical displays are internaly divided in two 64x64 halves; both halves are divided in eight 64x8 horizontal pages; every page has its addressing number in the range 0-15; page in upper-left corner has number 0; page in lower-left corner has number 7; page in upper-right corner has number 8; page in lower-right corner has number 15; every page has 64 byte positions addressed with numbers in the range 0-63; every byte position has 8 bits; the uppermost bit is LSB and the lowermost bit is MSB). For example:
GLCDINIT
loop:
   GLCDCLEAR 0xAA
   WAITMS 1000
   GLCDCLEAR 0x55
   WAITMS 1000
GOTO loop

GLCDPSET and GLCDPRESET statements are used to turn on and turn off one of the dots on the graphical display. The first argument is the horizontal coordinate and it must be a byte data type variable or constant in the range 0-127. The second argument is the vertical coordinate and it must be a byte data type variable or constant in the range 0-63. The dot in the upper-left corner of the display is the origin with coordinates 0,0. For example:
DIM I AS BYTE
DIM J AS BYTE
GLCDINIT
FOR I = 0 TO 127
FOR J = 0 TO 63
   GLCDPSET I, J
NEXT J
NEXT I

GLCDCLEAN statement is used to clear a section of the page on the display. It has three arguments. The first argument is page address and it must be a byte data type variable or constant in the range 0-15. The second argument is the first byte position on the page that will be cleaned and it must be a byte data type variable or constant in the range 0-63. The third argument is the last byte position on the page that will be cleaned and it must be a byte data type variable or constant in the range 0-63. If the last two arguments are omitted the whole page will be cleared. For example:
DIM I AS BYTE
GLCDINIT
GLCDCLEAR 0xFF
FOR I = 0 TO 15
   GLCDCLEAN I
   WAITMS 500
NEXT I

GLCDPOSITION statement is used to address a byte position on the display. It must be used before any of the GLCDWRITE, GLCDIN, GLCDOUT and GLCDCMDOUT statements. The first argument is page address and it must be a byte data type variable or constant in the range 0-15. The second argument is the target byte position on the page and it must be a byte data type variable or constant in the range 0-63. If the second argument is omitted, zero byte position is used.

GLCDWRITE statement is used to write text on the display. It will start writing from the current byte position on the display. It must be used carefully, because when the byte position (63) of the page is reached, the writing will continue from the byte position 0 staying on the same page. The width of every character written is 5 byte positions plus one clear byte position. After the statement is executed the current byte position will be at the end of the text written. GLCDWRITE statement may have multiple arguments separated by ','. Strings, constants and byte variables can be used as its arguments. Constants and variable values are interpreted as ASCII codes. If '#' sign is used before the name of a variable (byte, word or long data type) then its decimal representation is written. For example:
DIM I AS BYTE
GLCDINIT
FOR I = 0 TO 15
   GLCDPOSITION I, 0
   GLCDWRITE "Page: ", #I
   WAITMS 250
NEXT I

GLCDOUT statement is used to write the value of the byte variable or constant at the current byte position on the display. The current byte position will be incremented by one. GLCDIN statement will read the value from the current byte position on the display and put it in the byte variable specified as its argument. GLCDCMDOUT statement is used to send low-level commands to the graphical LCD. Its argument can be a constant or byte data type variable. All these three statements can be used with multiple arguments separated by ','.

● Interfacing Radio Control (R/C) servos

For writing applications to interface R/C servos there are two statements available: SERVOIN and SERVOOUT. R/C servo is controlled by a train of pulses (15-20 pulses per second) whose length define the position of the servo arm. The valid length of pulses is in the range 1-2ms. These two statements have two arguments. The first argument of both statements is the microcontroller pin where the servo signal is received or transmitted. For SERVOIN statement that pin should be previously setup as an input pin and for SERVOOUT statement the pin should be setup for output. The second argument of SERVOIN statement must be a Byte variable where the length of the pulse will be saved. The pulses are measured in 10us units, so it is possible to measure pulses in the range 0.01-2.55ms. The value stored in the variable for normal servos should be in the range 100-200. The second argument of the SERVOOUT statement should be a Byte variable or constant that determines the length of the generated pulse. For proper operation of the target servo SERVOOUT statement should be executed 15-20 times during one second. Here is an example of the servo reverse operation:
DIM length AS BYTE
DDRB.0 = 0
DDRB.1 = 1
loop:
   SERVOIN PORTB.0, length
   IF length < 100 THEN length = 100
   IF length > 200 THEN length = 200
   length = length - 100
   length = 100 - length
   length = length + 100
   SERVOOUT PORTB.1, length
GOTO loop

● Interfacing Stepper Motors

Prior to using stepper motor related statements, its connection and desired drive mode should be set up using DEFINE directives. There are eight available parameters to define the connection of A, B, C and D coils:
STEP_A_REG - defines the port where A coil is connected to
STEP_A_BIT - defines the pin where A coil is connected to
STEP_B_REG - defines the port where B coil is connected to
STEP_B_BIT - defines the pin where B coil is connected to
STEP_C_REG - defines the port where C coil is connected to
STEP_C_BIT - defines the pin where C coil is connected to
STEP_D_REG - defines the port where D coil is connected to
STEP_D_BIT - defines the pin where A coil is connected to
Coils A and C are actually parts of one single coil with common connection. The same is valid for B and D coil connections. There is also STEP_MODE parameter used to define the drive mode. If it is set to 1 (default) the motor will be driven in full-step mode. The value 2 should be used for half-step mode. The first basic statement that should be used is STEPHOLD. It will configure used pins as outputs and also energize A and B coils to fix the rotor in its initial position. For moving rotor in clockwise and counterclockwise directions there are STEPCW and STEPCCW statements available. Their first argument is the number of rotor steps that will be performed and it can be Byte data type constant or variable. The second argument defines the delay between consecutive steps expressed in microseconds by a Byte or Word data type variable or constant. If using STEPCW statement results in rotor movement in counterclockwise direction then connection settings for B and D coils should be exchanged. Here are two examples (the second example uses delays suitable for simulation in the simulator):
Define STEP_A_REG = PORTB
Define STEP_A_BIT = 7
Define STEP_B_REG = PORTB
Define STEP_B_BIT = 6
Define STEP_C_REG = PORTB
Define STEP_C_BIT = 5
Define STEP_D_REG = PORTB
Define STEP_D_BIT = 4
Define STEP_MODE = 2
 
WaitMs 1000
StepHold
WaitMs 1000
 
Dim an0 As Word
 
loop:
   Adcin 0, an0
   an0 = an0 * 60
   an0 = an0 + 2000
   StepCW 1, an0
Goto loop


Define STEP_A_REG = PORTB
Define STEP_A_BIT = 7
Define STEP_B_REG = PORTB
Define STEP_B_BIT = 6
Define STEP_C_REG = PORTB
Define STEP_C_BIT = 5
Define STEP_D_REG = PORTB
Define STEP_D_BIT = 4
Define STEP_MODE = 2
 
WaitUs 300
StepHold
WaitUs 1000
 
loop:
   StepCCW 16, 300
   WaitUs 1000
   StepCW 24, 300
   WaitUs 1000
Goto loop

● Interfacing 1-WIRE devices

Prior to using 1-WIRE related statements, user should define the pin where the device is connected to using DEFINE directives. Available parameters are 1WIRE_REG and 1WIRE_BIT. For example:
DEFINE 1WIRE_REG = PORTB
DEFINE 1WIRE_BIT = 0

Initialization sequence can be performed by 1WIREINIT statement. It can have an optional argument (Bit data type variable) that will be set to 0 if the presence of the device has been detected and set to 1 if there is no device on the line.
Individual bits (time slots) can be sent to and received from the device using 1WIRESENDBIT and 1WIREGETBIT statements. Both statements can have multiple arguments - comma separated list of Bit data type variables (or Bit constants for 1WIRESENDBIT statement).
1WIRESENDBYTE and 1WIREGETBYTE statements can be used to send to and receive bytes from the device. Both statements can have multiple arguments - comma separated list of Byte data type variables (or Byte constants for 1WIRESENDBYTE statement). Here is one example for measuring temperature using DS18S20 device:
DIM finish AS BIT
DIM temp AS BYTE
DIM sign AS BYTE
1WIREINIT
1WIRESENDBYTE 0xCC, 0x44
WAITMS 1
loop:
   1WIREGETBIT finish
IF finish = 0 THEN GOTO loop
1WIREINIT
1WIRESENDBYTE 0xCC, 0xBE
1WIREGETBYTE temp, sign

This example can be very short by using two DS18S20 specific high level basic statements. DS18S20START statement will initiate a single temperature conversion. According to the device datasheet the conversion will be completed in at most 750ms. After that period the measured value can be read by DS18S20READT statement that requires two Byte data type variables as arguments. The first argument will contain the temperature value in 0.5 degrees centigrade units (for example, the value 100 represents the temperature of 50 degrees). The second argument will contain the value 0x00 if the temperature is positive and 0xFF value if it is negative. For example:
DIM temp AS BYTE
DIM sign AS BYTE
DS18S20START
WAITMS 1000
DS18S20READT temp, sign

● Advanced features

If STARTFROMZERO directive is used the compiler will start the program from zero flash program memory location (reset vector) and use the available program memory continuously. Interrupt routines if used should be implemented by using inline assembler code. This advanced feature can be used when developing bootloader applications, for example.