PIC18 Basic Compiler Library Support
The library support is a new way for the basic statements implementation.
This is indeed an advanced feature, however that is a way that can be used by both the author and the users to extend the compiler language from the external library files.
The information is loaded by the compiler from the external textual .lib files stored in the OshonSoft application data folder.
OshonSoft .lib files are well documented with comments covering all the currently available features of the library support compiler engine.
Library files can be edited by Notepad, or any other plain text editor.
Library files selection:
• oshonsoftpic18.lib
• oshonsoftpic18-adc.lib
• oshonsoftpic18-uart.lib
oshonsoftpic18.lib file:
//the concept is that one library group contains the implementation of one new language functionality - one or more related statements or functions
//library items contain different implementations of the same functionality for different groups of microcontrollers
//#lib_item_begin must be followed by #processor
//#statement_begin, #statement_type, #argument sequence must be fulfilled for proper library load
//#processor comma-separated list of processors, x can be used as a wild card character
//#processor can be used in multiple lines to quote all devices if needed
//#parameter is used to implement #define parameters needed for the statement implementation
//#parameter const, parameter_name, allowed_range, default_value
//#parameter symbol, parameter_name, type (pin, bit, byte, address of), system_bit or system_register
//'pin' type is used for the bits in the PORT registers
//'address of' type will implement a constant parameter
//#variable is used to declare global system variables
//#variable variable_name, type (byte, word, long, single, string)
//#statement_begin statement_name [argument1_name[, argument2_name[, ...]]]
//#statement_type type (procedure; inline; function, f_type (byte, word, long, single, string))
//#argument argument_name, type (const xx, byte, byte system xx, word, word system xx, long, long system xx, single, string), passing_type
//the default type of the system variables can not be changed with #argument
//passing_type (byval, byval allowed_constant_range, byref, byrefout) for statement_type procedure and inline
//passing_type (byval, byval allowed_constant_range) for statement_type function
//allowed_constant_range can contain arithmetic expressions in brackets, like 0-[EEPROM_Num-1]
//used to define parameters and statements that are not available or not applicable for the current item devices
//#parameter n/a, parameter_name
//#statement n/a, statement_name
//used to define alternative names for the parameter and statement names defined in the library group
//#alias_for <library_defined_element_name>, <new_alternative_name>
//used to define code variations among processors when only one or more register names in the code should be replaced with their alternatives
//#alternate_reg_name <register_name_used_in_code>, <alternate_register_name>
//code section can contain both inline assembler and basic language lines of code
//symbol and const parameters can be used directly in the assembler lines of code
//calculate[] or calc[] macro is available for double precision calculations
//calculate[] must be used to enter the parameter value in the basic code, will be replaced with the value of the parameter
//calculate[] can be used to perform one arithmetic operation, will be replaced with the value of the result
//calc[] arithmetic operators: +, -, *, /, % (modulus or remainder operator), \ (division returning integer result)
//calc[] macros can be nested
//reg_addr[] macro will be replaced with the register address; if not found, -1 is returned
//Clock_Freq in MHz is available as an argument
//Flash_Num and EEPROM_Num (total number of memory locations) are available as arguments
//int_val() and abs_val() functions are available for getting integer or absolute values of the argument
//int_val() and abs_val() can be used on one or both arguments in calc[] expression, and/or on the whole expression
//#if [], #endif macro is available
//#if comparison operators: ==,<>,<,>,<=,>=
//#if [] macro can be used without #endif when followed by one operation in the same line
//for example: #if [libtemp3 > 0.5] #math libtemp2 = calc[libtemp2 + 1]
//for example: #if [ADC_Clk > 3] bsf ADCON1,ADCS2
//'const' statement argument type can be used to load the numeric value into one of the library engine temp variables libtemp0-libtemp99
//for const arguments only 'byval' and 'byval allowed_constant_range' passing types are allowed
//#math directive is used to assign numeric value or the result of calc[] expression to one libtempxx variable
//for example: #math libtemp8 = calc[calc[Clock_Freq * 1000000] / calc[calc[libtemp2 + 1] * 4]] //exact baud rate achieved
//#if macro also works with libtemp0-libtemp99 variables
//desired info can be inserted as a comment in the generated assembler source with the #echo directive
//#echo is followed by a string that can contain temp variable names to be replaced with their numeric values
//for example: #echo "exact baud rate achieved = libtemp8; bit period = libtemp7µs; baud rate error = libtemp6%"
//when calling 'procedure' type statements with one 'byval' byte argument declared, library engine will accept multiple comma-separated arguments
//for that purpose #statement_accept_multiple_arguments directive should be placed after #statement_type
//variables are passed byte by byte starting from the lowest byte; string constants can be used, along with symbolic constants Qt, CrLf, Cr, Lf
//decimal representation of a variable can be passed to the procedure by using the # prefix before the variable name
//#break_for_string_argument directive
//for string variables and decimal representations (argument in the form #variable_name)
//library engine will load FSR1 register with address of zero-terminated string prepared in memory
//and call the procedure at position of the #break_for_string_argument directive in the procedure code
//when calling 'procedure' type statements with one 'byrefout' byte argument declared, library engine will also accept multiple comma-separated arguments
//variables are filled in byte by byte starting from the lowest byte
//be careful that basic statements like WaitUs also make use of the system registers and can alter those values
//when using inline assembler code, be careful that basic statements expect to be called with BANK zero selected
//#banksel register_name_or_address
//#banksel directive should be used before any register access with assembler code, in order to use the compiler internal memory banking optimizations
//special function registers are declared in basic code as byte variables; if needed, this byte variable type can be changed with #redim directive
//#redim register_name new_type (byte, word, long, single)
//list of available compiler system byte registers (bank 0): R0L, R0H, R1L, R1H, R2L, R2H, R3L, R3H, R4L, R4H
//list of available compiler system byte registers (bank 0): R5L, R5H, R6L, R6H, R7L, R7H, R8L, R8H, R9L, R9H
//list of available compiler system word registers (bank 0): R0HL, R1HL, R2HL, R3HL, R4HL, R5HL, R6HL, R7HL, R8HL, R9HL
//list of available compiler system long registers (bank 0): R1HL0HL, R3HL2HL, R5HL4HL, R7HL6HL, R9HL8HL
oshonsoftpic18-adc.lib file:
#lib_name OshonSoft ADC Module Library
//ADC_Read statement
#lib_group_begin
//for backward compatibility
#alias_for ADC_Sample_uS, ADC_SAMPLEUS
#alias_for ADC_Clk, ADC_CLOCK
#alias_for ADC_Read, Adcin
#lib_item_begin
//ADCON0
//ADCS1 ADCS0 CHS2 CHS1 CHS0 GO/DONE — ADON
//ADCON1
//ADFM ADCS2 — — PCFG3 PCFG2 PCFG1 PCFG0
//ADRESL
//ADRESH
//PIR1.ADIF
#processor 18f242, 18f252, 18f442, 18f452
#processor 18f248, 18f258, 18f448, 18f458
#parameter const, ADC_Sample_uS, 0-255, 20
#parameter const, ADC_Clk, 0-7, 3
#statement_begin ADC_Read adc_channel, adc_result
#statement_type procedure
#argument adc_channel, byte system R0L, byval 0-7
#argument adc_result, word system ADRESL, byrefout
#code_begin
//
#redim ADRESL word
bsf ADCON1,ADFM
#if [ADC_Clk > 3] bsf ADCON1,ADCS2
#if [ADC_Clk <= 3] bcf ADCON1,ADCS2
rlcf R0L,f
rlcf R0L,f
rlcf R0L,f
movlw 0x38
andwf R0L,f
movlw calc[calc[calc[ADC_Clk * 64] % 256] + 1] //1-ADON
iorwf R0L,w
movwf ADCON0
//
WaitUs calculate[ADC_Sample_uS]
//
bsf ADCON0,GO
btfsc ADCON0,GO
bra $-2
bcf ADCON0,ADON
bcf PIR1,ADIF
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
//ADCON0
//VCFG1 VCFG0 — CHS2 CHS1 CHS0 GO/DONE ADON
//ADCON1
//— PCFG6 PCFG5 PCFG4 PCFG3 PCFG2 PCFG1 PCFG0
//ADCON2
//ADFM — ACQT2 ACQT1 ACQT0 ADCS2 ADCS1 ADCS0
//ADRESL
//ADRESH
//PIR1.ADIF
#processor 18f1220, 18f1320
#parameter const, ADC_Sample_uS, 0-255, 20
#parameter const, ADC_Clk, 0-7, 3
#statement_begin ADC_Read adc_channel, adc_result
#statement_type procedure
#argument adc_channel, byte system R0L, byval 0-7
#argument adc_result, word system ADRESL, byrefout
#code_begin
//
#redim ADRESL word
bsf ADCON2,ADFM
movlw 0x80
andwf ADCON2,f
movlw 0xc0
andwf ADCON0,f
movlw calculate[ADC_Clk]
iorwf ADCON2,f
rlcf R0L,f
rlcf R0L,f
movlw 0x1c
andwf R0L,w
iorwf ADCON0,f
bsf ADCON0,ADON
//
WaitUs calculate[ADC_Sample_uS]
//
bsf ADCON0,GO
btfsc ADCON0,GO
bra $-2
bcf ADCON0,ADON
bcf PIR1,ADIF
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
//ADCON0
//SEVTEN — — — CHS1 CHS0 GO/DONE ADON
//ADCON1
//— — — VCFG0 PCFG3 PCFG2 PCFG1 PCFG0
//ADCON2
//ADFM — ACQT2 ACQT1 ACQT0 ADCS2 ADCS1 ADCS0
//ADRESL
//ADRESH
//PIR1.ADIF
#processor 18f1230, 18f1330
#parameter const, ADC_Sample_uS, 0-255, 20
#parameter const, ADC_Clk, 0-7, 3
#statement_begin ADC_Read adc_channel, adc_result
#statement_type procedure
#argument adc_channel, byte system R0L, byval 0-3
#argument adc_result, word system ADRESL, byrefout
#code_begin
//
#redim ADRESL word
bsf ADCON2,ADFM
movlw 0x80
andwf ADCON2,f
movlw calculate[ADC_Clk]
iorwf ADCON2,f
rlcf R0L,f
rlcf R0L,f
movlw 0x0c
andwf R0L,w
movwf ADCON0
bsf ADCON0,ADON
//
WaitUs calculate[ADC_Sample_uS]
//
bsf ADCON0,GO
btfsc ADCON0,GO
bra $-2
bcf ADCON0,ADON
bcf PIR1,ADIF
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
//ADCON0
//— — CHS3 CHS2 CHS1 CHS0 GO/DONE ADON
//ADCON1
//— — VCFG1 VCFG0 PCFG3 PCFG2 PCFG1 PCFG0
//— — VCFG1 VCFG0 — — — — //v3
//— — — — PVCFG1 PVCFG0 NVCFG1 NVCFG0 //v4
//ADCON2
//ADFM — ACQT2 ACQT1 ACQT0 ADCS2 ADCS1 ADCS0
//ADFM — — — — ADCS2 ADCS1 ADCS0 //v2
//ADRESL
//ADRESH
//PIR1.ADIF
#processor 18f2420, 18f2520, 18f4420, 18f4520
#processor 18f2220, 18f2320, 18f4220, 18f4320
#processor 18f2455, 18f2550, 18f4455, 18f4550
#processor 18f2525, 18f2620, 18f4525, 18f4620
#processor 18f6520, 18f6620, 18f6720, 18f8520, 18f8620, 18f8720 //v2
#processor 18f2410, 18f2510, 18f2515, 18f2610, 18f4410, 18f4510, 18f4515, 18f4610
#processor 18f2480, 18f2580, 18f4480, 18f4580
#processor 18f6527, 18f6622, 18f6627, 18f6722, 18f8527, 18f8622, 18f8627, 18f8722
#processor 18f2221, 18f2321, 18f4221, 18f4321
#processor 18f2585, 18f2680, 18f4585, 18f4680
#processor 18f2682, 18f2685, 18f4682, 18f4685
#processor 18f6525, 18f6621, 18f8525, 18f8621
#processor 18f6585, 18f8585, 18f6680, 18f8680
#processor 18f2423, 18f2523, 18f4423, 18f4523
#processor 18f2458, 18f2553, 18f4458, 18f4553
#processor 18f23k20, 18f24k20, 18f25k20, 18f26k20, 18f43k20, 18f44k20, 18f45k20, 18f46k20 //v3
#processor 18f13k50, 18f14k50 //v4
#processor 18f13k22, 18f14k22 //v4
#parameter const, ADC_Sample_uS, 0-255, 20
#parameter const, ADC_Clk, 0-7, 3
#statement_begin ADC_Read adc_channel, adc_result
#statement_type procedure
#argument adc_channel, byte system R0L, byval 0-15
#argument adc_result, word system ADRESL, byrefout
#code_begin
//
#redim ADRESL word
bsf ADCON2,ADFM
movlw 0x80
andwf ADCON2,f
movlw calculate[ADC_Clk]
iorwf ADCON2,f
rlcf R0L,f
rlcf R0L,f
movlw 0x3c
andwf R0L,w
movwf ADCON0
bsf ADCON0,ADON
//
WaitUs calculate[ADC_Sample_uS]
//
bsf ADCON0,GO
btfsc ADCON0,GO
bra $-2
bcf ADCON0,ADON
bcf PIR1,ADIF
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
//ADCON0
//ADCAL — CHS3 CHS2 CHS1 CHS0 GO/DONE ADON
//ADCON1
//— — VCFG1 VCFG0 PCFG3 PCFG2 PCFG1 PCFG0
//TRIGSEL — VCFG1 VCFG0 PCFG3 PCFG2 PCFG1 PCFG0 //v2
//ADCON2
//ADFM — ACQT2 ACQT1 ACQT0 ADCS2 ADCS1 ADCS0
//ADRESL
//ADRESH
//PIR1.ADIF
#processor 18f66j60, 18f66j65, 18f67j60, 18f86j60, 18f86j65, 18f87j60, 18f96j60, 18f96j65, 18f97j60
#processor 18f63j11, 18f64j11, 18f65j11, 18f83j11, 18f84j11, 18f85j11
#processor 18f24j10, 18f25j10, 18f44j10, 18f45j10
#processor 18f86j72, 18f87j72 //v2
#parameter const, ADC_Sample_uS, 0-255, 20
#parameter const, ADC_Clk, 0-7, 3
#statement_begin ADC_Read adc_channel, adc_result
#statement_type procedure
#argument adc_channel, byte system R0L, byval 0-15
#argument adc_result, word system ADRESL, byrefout
#code_begin
//
#redim ADRESL word
movlw calc[calc[ADC_Clk] + 128] //128-ADFM
movwf ADCON2
rlcf R0L,f
rlcf R0L,f
movlw 0x3c
andwf R0L,w
movwf ADCON0
bsf ADCON0,ADON
//
WaitUs calculate[ADC_Sample_uS]
//
bsf ADCON0,GO
btfsc ADCON0,GO
bra $-2
bcf ADCON0,ADON
bcf PIR1,ADIF
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
//ADCON0
//— CHS4 CHS3 CHS2 CHS1 CHS0 GO/DONE ADON
//ADCON1
//TRIGSEL — — — PVCFG1 PVCFG0 NVCFG1 NVCFG0
//TRIGSEL1 TRIGSEL0 VCFG1 VCFG0 VNCFG CHSN2 CHSN1 CHSN0 //v2
//ADCON2
//ADFM — ACQT2 ACQT1 ACQT0 ADCS2 ADCS1 ADCS0
//ADRESL
//ADRESH
//PIR1.ADIF
#processor 18f23k22, 18f24k22, 18f25k22, 18f26k22, 18f43k22, 18f44k22, 18f45k22, 18f46k22
#processor 18f65k22, 18f66k22, 18f67k22, 18f85k22, 18f86k22, 18f87k22 //v2
#processor 18f65k90, 18f66k90, 18f67k90, 18f85k90, 18f86k90, 18f87k90 //v2
#processor 18f25k80, 18f26k80, 18f45k80, 18f46k80, 18f65k80, 18f66k80 //v2
#processor 18f24k50, 18f25k50, 18f45k50
#parameter const, ADC_Sample_uS, 0-255, 20
#parameter const, ADC_Clk, 0-7, 3
#statement_begin ADC_Read adc_channel, adc_result
#statement_type procedure
#argument adc_channel, byte system R0L, byval 0-31
#argument adc_result, word system ADRESL, byrefout
#code_begin
//
#redim ADRESL word
bsf ADCON2,ADFM
movlw 0x80
andwf ADCON2,f
movlw calculate[ADC_Clk]
iorwf ADCON2,f
rlcf R0L,f
rlcf R0L,f
movlw 0x7c
andwf R0L,w
movwf ADCON0
bsf ADCON0,ADON
//
WaitUs calculate[ADC_Sample_uS]
//
bsf ADCON0,GO
btfsc ADCON0,GO
bra $-2
bcf ADCON0,ADON
bcf PIR1,ADIF
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
//ADCON0
//VCFG1 VCFG0 CHS3 CHS2 CHS1 CHS0 GO/DONE ADON
//ADCON1
//ADFM ADCAL ACQT2 ACQT1 ACQT0 ADCS2 ADCS1 ADCS0
//ADCTRIG //v2
//— — — — — — TRIGSEL1 TRIGSEL0 //v2
//ADRESL
//ADRESH
//PIR1.ADIF
#processor 18f24j50, 18f25j50, 18f26j50, 18f44j50, 18f45j50, 18f46j50
#processor 18f24j11, 18f25j11, 18f26j11, 18f44j11, 18f45j11, 18f46j11
#processor 18f26j13, 18f27j13, 18f46j13, 18f47j13 //v2
#processor 18f26j53, 18f27j53, 18f46j53, 18f47j53 //v2
#processor 18f65j50, 18f66j50, 18f66j55, 18f67j50, 18f85j50, 18f86j50, 18f86j55, 18f87j50
#parameter const, ADC_Sample_uS, 0-255, 20
#parameter const, ADC_Clk, 0-7, 3
#statement_begin ADC_Read adc_channel, adc_result
#statement_type procedure
#argument adc_channel, byte system R0L, byval 0-15
#argument adc_result, word system ADRESL, byrefout
#code_begin
//
#redim ADRESL word
movlw calculate[ADC_Clk]
movwf ADCON1
bsf ADCON1,ADFM
movlw 0xc0
andwf ADCON0,f
rlcf R0L,f
rlcf R0L,f
movlw 0x3c
andwf R0L,w
iorwf ADCON0,f
bsf ADCON0,ADON
//
WaitUs calculate[ADC_Sample_uS]
//
bsf ADCON0,GO
btfsc ADCON0,GO
bra $-2
bcf ADCON0,ADON
bcf PIR1,ADIF
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
#processor 18f2331, 18f2431, 18f4331, 18f4431
#processor 18f65j94, 18f66j94, 18f66j99, 18f67j94, 18f85j94, 18f86j94, 18f86j99, 18f87j94, 18f95j94, 18f96j94, 18f96j99, 18f97j94
#parameter n/a, ADC_Sample_uS
#parameter n/a, ADC_Clk
#statement n/a, ADC_Read
#lib_item_end
#lib_group_end
#lib_group_begin //All_Digital statement
//for backward compatibility
#alias_for All_Digital, AllDigital
#lib_item_begin
#processor 18f2420, 18f2520, 18f4420, 18f4520
#processor 18f2220, 18f2320, 18f4220, 18f4320
#processor 18f2455, 18f2550, 18f4455, 18f4550
#processor 18f2525, 18f2620, 18f4525, 18f4620
#processor 18f6520, 18f6620, 18f6720, 18f8520, 18f8620, 18f8720
#processor 18f2410, 18f2510, 18f2515, 18f2610, 18f4410, 18f4510, 18f4515, 18f4610
#processor 18f2480, 18f2580, 18f4480, 18f4580
#processor 18f6527, 18f6622, 18f6627, 18f6722, 18f8527, 18f8622, 18f8627, 18f8722
#processor 18f2221, 18f2321, 18f4221, 18f4321
#processor 18f2585, 18f2680, 18f4585, 18f4680
#processor 18f2682, 18f2685, 18f4682, 18f4685
#processor 18f6525, 18f6621, 18f8525, 18f8621
#processor 18f6585, 18f8585, 18f6680, 18f8680
#processor 18f2423, 18f2523, 18f4423, 18f4523
#processor 18f2458, 18f2553, 18f4458, 18f4553
#processor 18f66j60, 18f66j65, 18f67j60, 18f86j60, 18f86j65, 18f87j60, 18f96j60, 18f96j65, 18f97j60
#processor 18f63j11, 18f64j11, 18f65j11, 18f83j11, 18f84j11, 18f85j11
#processor 18f24j10, 18f25j10, 18f44j10, 18f45j10
#processor 18f86j72, 18f87j72
#statement_begin All_Digital
#statement_type inline
#code_begin
//
#if [reg_addr[ADCON1] >= 0] ADCON1 = 0x0f
#if [reg_addr[CMCON] >= 0] CMCON = 0x07
#if [reg_addr[CVRCON] >= 0] CVRCON.CVROE = 0
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
#processor 18f242, 18f252, 18f442, 18f452
#processor 18f248, 18f258, 18f448, 18f458
#statement_begin All_Digital
#statement_type inline
#code_begin
//
#if [reg_addr[ADCON1] >= 0] ADCON1 = 0x06
#if [reg_addr[CMCON] >= 0] CMCON = 0x07
#if [reg_addr[CVRCON] >= 0] CVRCON.CVROE = 0
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
#processor 18f1220, 18f1320
#statement_begin All_Digital
#statement_type inline
#code_begin
//
#if [reg_addr[ADCON1] >= 0] ADCON1 = 0xff
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
#processor 18f1230, 18f1330
#statement_begin All_Digital
#statement_type inline
#code_begin
//
#if [reg_addr[ADCON1] >= 0] ADCON1 = 0x0f
#if [reg_addr[CMCON] >= 0] CMCON = 0x00
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
#processor 18f23k20, 18f24k20, 18f25k20, 18f26k20, 18f43k20, 18f44k20, 18f45k20, 18f46k20
#processor 18f65k22, 18f66k22, 18f67k22, 18f85k22, 18f86k22, 18f87k22
#processor 18f65k90, 18f66k90, 18f67k90, 18f85k90, 18f86k90, 18f87k90
#processor 18f25k80, 18f26k80, 18f45k80, 18f46k80, 18f65k80, 18f66k80
#statement_begin All_Digital
#statement_type inline
#code_begin
//
#if [reg_addr[ANSEL] >= 0] ANSEL = 0x00
#if [reg_addr[ANSELH] >= 0] ANSELH = 0x00
#if [reg_addr[ANCON0] >= 0] ANCON0 = 0x00
#if [reg_addr[ANCON1] >= 0] ANCON1 = 0x00
#if [reg_addr[ANCON2] >= 0] ANCON2 = 0x00
#if [reg_addr[CVRCON] >= 0] CVRCON.CVROE = 0
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
#processor 18f13k50, 18f14k50
#statement_begin All_Digital
#statement_type inline
#code_begin
//
#if [reg_addr[ANSEL] >= 0] ANSEL = 0x00
#if [reg_addr[ANSELH] >= 0] ANSELH = 0x00
#if [reg_addr[REFCON1] >= 0] REFCON1.DAC1OE = 0
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
#processor 18f13k22, 18f14k22
#statement_begin All_Digital
#statement_type inline
#code_begin
//
#if [reg_addr[ANSEL] >= 0] ANSEL = 0x00
#if [reg_addr[ANSELH] >= 0] ANSELH = 0x00
#if [reg_addr[VREFCON1] >= 0] VREFCON1.DAC1OE = 0
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
#processor 18f23k22, 18f24k22, 18f25k22, 18f26k22, 18f43k22, 18f44k22, 18f45k22, 18f46k22
#processor 18f24k50, 18f25k50, 18f45k50
#statement_begin All_Digital
#statement_type inline
#code_begin
//
#if [reg_addr[ANSELA] >= 0] ANSELA = 0x00
#if [reg_addr[ANSELB] >= 0] ANSELB = 0x00
#if [reg_addr[ANSELC] >= 0] ANSELC = 0x00
#if [reg_addr[ANSELD] >= 0] ANSELD = 0x00
#if [reg_addr[ANSELE] >= 0] ANSELE = 0x00
#if [reg_addr[VREFCON1] >= 0] VREFCON1.DACOE = 0
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
#processor 18f24j50, 18f25j50, 18f26j50, 18f44j50, 18f45j50, 18f46j50
#processor 18f24j11, 18f25j11, 18f26j11, 18f44j11, 18f45j11, 18f46j11
#processor 18f26j13, 18f27j13, 18f46j13, 18f47j13
#processor 18f26j53, 18f27j53, 18f46j53, 18f47j53
#statement_begin All_Digital
#statement_type inline
#code_begin
//
#if [reg_addr[ANCON0] >= 0] ANCON0 = 0xff
#if [reg_addr[ANCON1] >= 0] ANCON1 = 0x7f
#if [reg_addr[CVRCON] >= 0] CVRCON.CVROE = 0
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
#processor 18f65j50, 18f66j50, 18f66j55, 18f67j50, 18f85j50, 18f86j50, 18f86j55, 18f87j50
#statement_begin All_Digital
#statement_type inline
#code_begin
//
bsf WDTCON,ADSHR //alternate SFR access on
#if [reg_addr[ANCON0] >= 0] ANCON0 = 0xff
#if [reg_addr[ANCON1] >= 0] ANCON1 = 0xff
bcf WDTCON,ADSHR //alternate SFR access off
#if [reg_addr[CVRCON] >= 0] CVRCON.CVROE = 0
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
#processor 18f2331, 18f2431, 18f4331, 18f4431
#processor 18f65j94, 18f66j94, 18f66j99, 18f67j94, 18f85j94, 18f86j94, 18f86j99, 18f87j94, 18f95j94, 18f96j94, 18f96j99, 18f97j94
#statement n/a, All_Digital
#lib_item_end
#lib_group_end
oshonsoftpic18-uart.lib file:
#lib_name OshonSoft UART Library
//UART_Init, UART_Write, UART_Read, UART_Get statements
#lib_group_begin
#alias_for UART_Init, UART1_Init
#alias_for UART_Write, UART1_Write
#alias_for UART_Read, UART1_Read
#alias_for UART_Get, UART1_Get
//for backward compatibility
#alias_for UART_Init, Hseropen
#alias_for UART_Write, Hserout
#alias_for UART_Read, Hserin
#alias_for UART_Get, Hserget
#lib_item_begin
//TXREG
//TXSTA
//CSRC TX9 TXEN SYNC — BRGH TRMT TX9D
//RCREG
//RCSTA
//SPEN RX9 SREN CREN ADDEN FERR OERR RX9D
//SPBRG
//PIR1.TXIF
//PIR1.RCIF
#processor 18f242, 18f252, 18f442, 18f452
#processor 18f248, 18f258, 18f448, 18f458
#processor 18f2220, 18f2320, 18f4220, 18f4320
#statement_begin UART_Init baud_rate
#statement_type inline
#argument baud_rate, const libtemp0, byval 100-1000000
#code_begin
//
#math libtemp10 = 1 //baud rate generator mode
#math libtemp1 = calc[calc[calc[calc[Clock_Freq * 1000000] / libtemp0] / 16] - 1]
#if [libtemp1 > 250]
#math libtemp10 = 2 //baud rate generator mode
#math libtemp1 = calc[calc[calc[calc[Clock_Freq * 1000000] / libtemp0] / 64] - 1]
#endif
#math libtemp2 = calc[int_val(libtemp1)] //SPBRG value
#math libtemp3 = calc[abs_val(libtemp2 - libtemp1)]
#if [libtemp3 > 0.5] #math libtemp2 = calc[libtemp2 + 1]
//
#if [libtemp10 == 1] #math libtemp8 = calc[calc[Clock_Freq * 1000000] / calc[calc[libtemp2 + 1] * 16]] //exact baud rate achieved
#if [libtemp10 == 2] #math libtemp8 = calc[calc[Clock_Freq * 1000000] / calc[calc[libtemp2 + 1] * 64]] //exact baud rate achieved
#math libtemp7 = calc[1000000 / libtemp8] //bit period
#math libtemp6 = calc[calc[calc[abs_val(libtemp8 - libtemp0)] / libtemp0] * 100] //baud rate error
#math libtemp6 = calc[int_val(calc[libtemp6 * 100]) / 100] //round to 2 decimal places
#echo "exact baud rate achieved = libtemp8; bit period = libtemp7µs; baud rate error = libtemp6%"
//
bcf TRISC,6
bsf TRISC,7
movlw calc[libtemp2]
movwf SPBRG
#if [libtemp10 == 1] movlw 0x24 //TXEN, BRGH
#if [libtemp10 == 2] movlw 0x20 //TXEN
movwf TXSTA
movlw 0x90 //SPEN, CREN
movwf RCSTA
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
//TXREG
//TXSTA
//CSRC TX9 TXEN SYNC SENDB BRGH TRMT TX9D
//RCREG
//RCSTA
//SPEN RX9 SREN CREN ADDEN FERR OERR RX9D
//BAUDCON
//ABDOVF RCIDL RXDTP TXCKP BRG16 — WUE ABDEN
//ABDOVF RCIDL — SCKP BRG16 — WUE ABDEN //v2
//— RCIDL — SCKP BRG16 — WUE ABDEN //v3
//ABDOVF RCIDL DTRXP CKTXP BRG16 — WUE ABDEN //v4
//SPBRG
//SPBRGH
//PIR1.TXIF
//PIR1.RCIF
#processor 18f2420, 18f2520, 18f4420, 18f4520
#processor 18f2455, 18f2550, 18f4455, 18f4550
#processor 18f2525, 18f2620, 18f4525, 18f4620
#processor 18f2410, 18f2510, 18f2515, 18f2610, 18f4410, 18f4510, 18f4515, 18f4610 //v2
#processor 18f2331, 18f2431, 18f4331, 18f4431 //v3
#processor 18f2423, 18f2523, 18f4423, 18f4523
#processor 18f2458, 18f2553, 18f4458, 18f4553
#processor 18f2221, 18f2321, 18f4221, 18f4321
#processor 18f6585, 18f8585, 18f6680, 18f8680 //v3
#processor 18f23k20, 18f24k20, 18f25k20, 18f26k20, 18f43k20, 18f44k20, 18f45k20, 18f46k20 //v4
#processor 18f24j10, 18f25j10, 18f44j10, 18f45j10 //v2
#statement_begin UART_Init baud_rate
#statement_type inline
#argument baud_rate, const libtemp0, byval 100-1000000
#code_begin
//
#math libtemp10 = 1 //baud rate generator mode
#math libtemp1 = calc[calc[calc[calc[Clock_Freq * 1000000] / libtemp0] / 4] - 1]
#math libtemp2 = calc[int_val(libtemp1)] //SPBRG value
#math libtemp3 = calc[abs_val(libtemp2 - libtemp1)]
#if [libtemp3 > 0.5] #math libtemp2 = calc[libtemp2 + 1]
//
#math libtemp8 = calc[calc[Clock_Freq * 1000000] / calc[calc[libtemp2 + 1] * 4]] //exact baud rate achieved
#math libtemp7 = calc[1000000 / libtemp8] //bit period
#math libtemp6 = calc[calc[calc[abs_val(libtemp8 - libtemp0)] / libtemp0] * 100] //baud rate error
#math libtemp6 = calc[int_val(calc[libtemp6 * 100]) / 100] //round to 2 decimal places
#echo "exact baud rate achieved = libtemp8; bit period = libtemp7µs; baud rate error = libtemp6%"
//
bsf TRISC,6
bsf TRISC,7
movlw calc[libtemp2 % 256]
movwf SPBRG
movlw calc[libtemp2 \ 256]
movwf SPBRGH
clrf BAUDCON
#if [libtemp10 == 1] bsf BAUDCON,BRG16
#if [libtemp10 == 1] movlw 0x24 //TXEN, BRGH
movwf TXSTA
movlw 0x90 //SPEN, CREN
movwf RCSTA
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
//TXREG1
//TXSTA1
//CSRC TX9 TXEN SYNC SENDB BRGH TRMT TX9D
//RCREG1
//RCSTA1
//SPEN RX9 SREN CREN ADDEN FERR OERR RX9D
//BAUDCON1
//ABDOVF RCIDL RXDTP TXCKP BRG16 — WUE ABDEN
//SPBRG1
//SPBRGH1
//PIR1.TXIF
//PIR1.RCIF
#processor 18f24k50, 18f25k50, 18f45k50
#statement_begin UART_Init baud_rate
#statement_type inline
#argument baud_rate, const libtemp0, byval 100-1000000
#code_begin
//
#math libtemp10 = 1 //baud rate generator mode
#math libtemp1 = calc[calc[calc[calc[Clock_Freq * 1000000] / libtemp0] / 4] - 1]
#math libtemp2 = calc[int_val(libtemp1)] //SPBRG value
#math libtemp3 = calc[abs_val(libtemp2 - libtemp1)]
#if [libtemp3 > 0.5] #math libtemp2 = calc[libtemp2 + 1]
//
#math libtemp8 = calc[calc[Clock_Freq * 1000000] / calc[calc[libtemp2 + 1] * 4]] //exact baud rate achieved
#math libtemp7 = calc[1000000 / libtemp8] //bit period
#math libtemp6 = calc[calc[calc[abs_val(libtemp8 - libtemp0)] / libtemp0] * 100] //baud rate error
#math libtemp6 = calc[int_val(calc[libtemp6 * 100]) / 100] //round to 2 decimal places
#echo "exact baud rate achieved = libtemp8; bit period = libtemp7µs; baud rate error = libtemp6%"
//
bsf TRISC,6
bsf TRISC,7
movlw calc[libtemp2 % 256]
movwf SPBRG1
movlw calc[libtemp2 \ 256]
movwf SPBRGH1
clrf BAUDCON1
#if [libtemp10 == 1] bsf BAUDCON1,BRG16
#if [libtemp10 == 1] movlw 0x24 //TXEN, BRGH
movwf TXSTA1
movlw 0x90 //SPEN, CREN
movwf RCSTA1
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
//TXREG
//TXSTA
//CSRC TX9 TXEN SYNC SENDB BRGH TRMT TX9D
//RCREG
//RCSTA
//SPEN RX9 SREN CREN ADDEN FERR OERR RX9D
//BAUDCON
//ABDOVF RCIDL — SCKP BRG16 — WUE ABDEN
//SPBRG
//SPBRGH
//PIR1.TXIF
//PIR1.RCIF
#processor 18f2480, 18f2580, 18f4480, 18f4580
#processor 18f2585, 18f2680, 18f4585, 18f4680
#processor 18f2682, 18f2685, 18f4682, 18f4685
#statement_begin UART_Init baud_rate
#statement_type inline
#argument baud_rate, const libtemp0, byval 100-1000000
#code_begin
//
#math libtemp10 = 1 //baud rate generator mode
#math libtemp1 = calc[calc[calc[calc[Clock_Freq * 1000000] / libtemp0] / 4] - 1]
#math libtemp2 = calc[int_val(libtemp1)] //SPBRG value
#math libtemp3 = calc[abs_val(libtemp2 - libtemp1)]
#if [libtemp3 > 0.5] #math libtemp2 = calc[libtemp2 + 1]
//
#math libtemp8 = calc[calc[Clock_Freq * 1000000] / calc[calc[libtemp2 + 1] * 4]] //exact baud rate achieved
#math libtemp7 = calc[1000000 / libtemp8] //bit period
#math libtemp6 = calc[calc[calc[abs_val(libtemp8 - libtemp0)] / libtemp0] * 100] //baud rate error
#math libtemp6 = calc[int_val(calc[libtemp6 * 100]) / 100] //round to 2 decimal places
#echo "exact baud rate achieved = libtemp8; bit period = libtemp7µs; baud rate error = libtemp6%"
//
bcf TRISC,6
bsf TRISC,7
movlw calc[libtemp2 % 256]
movwf SPBRG
movlw calc[libtemp2 \ 256]
movwf SPBRGH
clrf BAUDCON
#if [libtemp10 == 1] bsf BAUDCON,BRG16
#if [libtemp10 == 1] movlw 0x24 //TXEN, BRGH
movwf TXSTA
movlw 0x90 //SPEN, CREN
movwf RCSTA
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
//TXREG
//TXSTA
//CSRC TX9 TXEN SYNC SENDB BRGH TRMT TX9D
//RCREG
//RCSTA
//SPEN RX9 SREN CREN ADDEN FERR OERR RX9D
//BAUDCTL
//— RCIDL — SCKP BRG16 — WUE ABDEN
//SPBRG
//SPBRGH
//PIR1.TXIF
//PIR1.RCIF
#processor 18f1220, 18f1320
#statement_begin UART_Init baud_rate
#statement_type inline
#argument baud_rate, const libtemp0, byval 100-1000000
#code_begin
//
#math libtemp10 = 1 //baud rate generator mode
#math libtemp1 = calc[calc[calc[calc[Clock_Freq * 1000000] / libtemp0] / 4] - 1]
#math libtemp2 = calc[int_val(libtemp1)] //SPBRG value
#math libtemp3 = calc[abs_val(libtemp2 - libtemp1)]
#if [libtemp3 > 0.5] #math libtemp2 = calc[libtemp2 + 1]
//
#math libtemp8 = calc[calc[Clock_Freq * 1000000] / calc[calc[libtemp2 + 1] * 4]] //exact baud rate achieved
#math libtemp7 = calc[1000000 / libtemp8] //bit period
#math libtemp6 = calc[calc[calc[abs_val(libtemp8 - libtemp0)] / libtemp0] * 100] //baud rate error
#math libtemp6 = calc[int_val(calc[libtemp6 * 100]) / 100] //round to 2 decimal places
#echo "exact baud rate achieved = libtemp8; bit period = libtemp7µs; baud rate error = libtemp6%"
//
bsf TRISB,1
bsf TRISB,4
bsf ADCON1,PCFG5
bsf ADCON1,PCFG6
movlw calc[libtemp2 % 256]
movwf SPBRG
movlw calc[libtemp2 \ 256]
movwf SPBRGH
clrf BAUDCTL
#if [libtemp10 == 1] bsf BAUDCTL,BRG16
#if [libtemp10 == 1] movlw 0x24 //TXEN, BRGH
movwf TXSTA
movlw 0x90 //SPEN, CREN
movwf RCSTA
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
//TXREG
//TXSTA
//CSRC TX9 TXEN SYNC SENDB BRGH TRMT TX9D
//RCREG
//RCSTA
//SPEN RX9 SREN CREN ADDEN FERR OERR RX9D
//BAUDCON
//ABDOVF RCIDL RXDTP TXCKP BRG16 — WUE ABDEN
//SPBRG
//SPBRGH
//PIR1.TXIF
//PIR1.RCIF
#processor 18f1230, 18f1330
#statement_begin UART_Init baud_rate
#statement_type inline
#argument baud_rate, const libtemp0, byval 100-1000000
#code_begin
//
#math libtemp10 = 1 //baud rate generator mode
#math libtemp1 = calc[calc[calc[calc[Clock_Freq * 1000000] / libtemp0] / 4] - 1]
#math libtemp2 = calc[int_val(libtemp1)] //SPBRG value
#math libtemp3 = calc[abs_val(libtemp2 - libtemp1)]
#if [libtemp3 > 0.5] #math libtemp2 = calc[libtemp2 + 1]
//
#math libtemp8 = calc[calc[Clock_Freq * 1000000] / calc[calc[libtemp2 + 1] * 4]] //exact baud rate achieved
#math libtemp7 = calc[1000000 / libtemp8] //bit period
#math libtemp6 = calc[calc[calc[abs_val(libtemp8 - libtemp0)] / libtemp0] * 100] //baud rate error
#math libtemp6 = calc[int_val(calc[libtemp6 * 100]) / 100] //round to 2 decimal places
#echo "exact baud rate achieved = libtemp8; bit period = libtemp7µs; baud rate error = libtemp6%"
//
bsf TRISA,2
bsf TRISA,3
movlw calc[libtemp2 % 256]
movwf SPBRG
movlw calc[libtemp2 \ 256]
movwf SPBRGH
clrf BAUDCON
#if [libtemp10 == 1] bsf BAUDCON,BRG16
#if [libtemp10 == 1] movlw 0x24 //TXEN, BRGH
movwf TXSTA
movlw 0x90 //SPEN, CREN
movwf RCSTA
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
//TXREG
//TXSTA
//CSRC TX9 TXEN SYNC SENDB BRGH TRMT TX9D
//RCREG
//RCSTA
//SPEN RX9 SREN CREN ADDEN FERR OERR RX9D
//BAUDCON
//ABDOVF RCIDL DTRXP CKTXP BRG16 — WUE ABDEN
//SPBRG
//SPBRGH
//PIR1.TXIF
//PIR1.RCIF
#processor 18f13k22, 18f14k22
#processor 18f13k50, 18f14k50
#statement_begin UART_Init baud_rate
#statement_type inline
#argument baud_rate, const libtemp0, byval 100-1000000
#code_begin
//
#math libtemp10 = 1 //baud rate generator mode
#math libtemp1 = calc[calc[calc[calc[Clock_Freq * 1000000] / libtemp0] / 4] - 1]
#math libtemp2 = calc[int_val(libtemp1)] //SPBRG value
#math libtemp3 = calc[abs_val(libtemp2 - libtemp1)]
#if [libtemp3 > 0.5] #math libtemp2 = calc[libtemp2 + 1]
//
#math libtemp8 = calc[calc[Clock_Freq * 1000000] / calc[calc[libtemp2 + 1] * 4]] //exact baud rate achieved
#math libtemp7 = calc[1000000 / libtemp8] //bit period
#math libtemp6 = calc[calc[calc[abs_val(libtemp8 - libtemp0)] / libtemp0] * 100] //baud rate error
#math libtemp6 = calc[int_val(calc[libtemp6 * 100]) / 100] //round to 2 decimal places
#echo "exact baud rate achieved = libtemp8; bit period = libtemp7µs; baud rate error = libtemp6%"
//
bsf TRISB,5
bsf TRISB,7
movlw calc[libtemp2 % 256]
movwf SPBRG
movlw calc[libtemp2 \ 256]
movwf SPBRGH
clrf BAUDCON
#if [libtemp10 == 1] bsf BAUDCON,BRG16
#if [libtemp10 == 1] movlw 0x24 //TXEN, BRGH
movwf TXSTA
movlw 0x90 //SPEN, CREN
movwf RCSTA
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
#processor 18f242, 18f252, 18f442, 18f452
#processor 18f248, 18f258, 18f448, 18f458
#processor 18f2220, 18f2320, 18f4220, 18f4320
#processor 18f2420, 18f2520, 18f4420, 18f4520
#processor 18f2455, 18f2550, 18f4455, 18f4550
#processor 18f2525, 18f2620, 18f4525, 18f4620
#processor 18f2410, 18f2510, 18f2515, 18f2610, 18f4410, 18f4510, 18f4515, 18f4610
#processor 18f2331, 18f2431, 18f4331, 18f4431
#processor 18f2423, 18f2523, 18f4423, 18f4523
#processor 18f2458, 18f2553, 18f4458, 18f4553
#processor 18f2221, 18f2321, 18f4221, 18f4321
#processor 18f6585, 18f8585, 18f6680, 18f8680
#processor 18f23k20, 18f24k20, 18f25k20, 18f26k20, 18f43k20, 18f44k20, 18f45k20, 18f46k20
#processor 18f24j10, 18f25j10, 18f44j10, 18f45j10
#processor 18f2480, 18f2580, 18f4480, 18f4580
#processor 18f2585, 18f2680, 18f4585, 18f4680
#processor 18f2682, 18f2685, 18f4682, 18f4685
#processor 18f1220, 18f1320
#processor 18f1230, 18f1330
#processor 18f13k22, 18f14k22
#processor 18f13k50, 18f14k50
#statement_begin UART_Write tx_data
#statement_type procedure
#statement_accept_multiple_arguments
#argument tx_data, byte system WREG, byval
#code_begin
//
l1:
btfsc PIR1,TXIF
bra l2
bra l1
l2:
movwf TXREG
//
#break_for_string_argument
l3:
movf POSTINC1,w
btfsc STATUS,Z
return
rcall l1
bra l3
//
#code_end
#statement_end
#statement_begin UART_Read rx_data
#statement_type procedure
#statement_accept_multiple_arguments
#argument rx_data, byte system WREG, byrefout
#code_begin
//
l1:
btfsc PIR1,RCIF
bra l2
bra l1
l2:
movf RCREG,w
//
#code_end
#statement_end
#statement_begin UART_Get rx_data
#statement_type procedure
#argument rx_data, byte system WREG, byrefout
#variable UART_Data_Ready, byte
#code_begin
//
UART_Data_Ready = 0
clrf WREG
btfss PIR1,RCIF
bra l1
UART_Data_Ready = 1
movf RCREG,w
l1:
//
#code_end
#statement_end
#lib_item_end
#lib_item_begin
#processor 18f24k50, 18f25k50, 18f45k50
#statement_begin UART_Write tx_data
#statement_type procedure
#statement_accept_multiple_arguments
#argument tx_data, byte system WREG, byval
#code_begin
//
l1:
btfsc PIR1,TXIF
bra l2
bra l1
l2:
movwf TXREG1
//
#break_for_string_argument
l3:
movf POSTINC1,w
btfsc STATUS,Z
return
rcall l1
bra l3
//
#code_end
#statement_end
#statement_begin UART_Read rx_data
#statement_type procedure
#statement_accept_multiple_arguments
#argument rx_data, byte system WREG, byrefout
#code_begin
//
l1:
btfsc PIR1,RCIF
bra l2
bra l1
l2:
movf RCREG1,w
//
#code_end
#statement_end
#statement_begin UART_Get rx_data
#statement_type procedure
#argument rx_data, byte system WREG, byrefout
#variable UART_Data_Ready, byte
#code_begin
//
UART_Data_Ready = 0
clrf WREG
btfss PIR1,RCIF
bra l1
UART_Data_Ready = 1
movf RCREG1,w
l1:
//
#code_end
#statement_end
#lib_item_end
#lib_group_end