PicBasic Pro Compiler Ver. 2.40 NEW.TXT Copyright 2001 microEngineering Labs, Inc. This software and accompanying documentation is copyright (c) microEngineering Labs, Inc. and may only be used by owners of the microEngineering Labs, Inc. PicBasic Pro Compiler. Please contact microEngineering Labs, Inc. to license this software. Contact information is listed at the end of this file. Version 2.4 of the PicBasic Pro Compiler adds several new commands and limited support for the 12-bit code PICmicro microcontrollers. The new commands include support for Dallas one-wire devices, low-speed USB, a special purpose 31-bit x 15-bit divide function, hardware PWM and Select Case statements. New Defines The compiler normally inserts clrwdt instructions throughout the program to keep the Watchdog Timer from timing out, if enabled. A new Define tells the compiler not to insert these clrwdt instructions: Define NO_CLRWDT 1 Adding support for the PIC16C745 and 765 low-speed USB devices meant raising the maximum oscillator speed to 24MHz. Therefore, a new oscillator Define is available for these devices: Define OSC 24 A new Define has been added to set a maximum count for Pulsin and Rctime before it stops waiting for a pulse or the end of a pulse: Define PULSIN_MAX 1000 The new HPWM instruction has a few new Defines to go along with it. The first specifies which pin is the CCP pin for devices that have alternate places for the pin, such as the 18C452: Define CCP1_REG PORTC Define CCP1_BIT 2 Define CCP2_REG PORTC Define CCP2_BIT 1 The following specify which timer, 1 or 2, to use with PWM2 and PWM3 for the 17C7xx devices. The default is timer 1 if no Define is specified. Define HPWM2_TMR 1 Define HPWM3_TMR 1 New Div32 Function PBPs multiply (*) function operates as a 16-bit x 16-bit multiply yielding a 32-bit result. However, since the compiler only supports a maximum variable size of 16 bits, access to the result had to happen in 2 steps: c = b * a returns the lower 16 bits of the multiply while d = b ** a returns the upper 16 bits. There was no way to access the 32-bit result as a unit. In many cases it is desirable to be able to divide the entire 32-bit result of the multiply by a 16-bit number for averaging or scaling. A new function has been added for this purpose: Div32. Div32 is actually limited to dividing a 31-bit unsigned integer (max 2147483647) by a 15-bit unsigned integer (max 32767). This should suffice in most circumstances. As the compiler only allows a maximum variable size of 16 bits, Div32 relies that a multiply was just performed and that the internal compiler variables still contain the 32-bit result of the multiply. No other operation may occur between the multiply and the Div32 or the internal variables may be altered, destroying the 32-bit multiplication result. This means, among other things, that On Interrupt must be Disabled from before the multiply until after the Div32. If On Interrupt is not used, there is no need to add Disable to the program. Interrupts in assembler should have no effect on the internal variables so they may be used without regard to Div32. The following code fragment shows the operation of Div32: a var word b var word c var word dummy var word b = 500 c = 1000 Disable ' Necessary if On Interrupt used dummy = b * c ' Could also use ** or */ a = Div32 100 Enable ' Necessary if On Interrupt used This program assigns b the value 500 and c the value 1000. When multiplied together, the result would be 500000. This number exceeds the 16-bit word size of a variable (65535). So the dummy variable contains only the lower 16 bits of the result. In any case, it is not used by the Div32 function. Div32 uses variables internal to the compiler as the operands. In this example, Div32 divides the 32-bit result of the multiplication b * c by 100 and stores the result of this division, 5000, in the word-sized variable a. New Hardware PWM Command A new hardware PWM command sets up the PWM hardware available on some PICmicro MCUs. It can run continuously in the background while the program is doing other things. Hpwm Channel, Dutycycle, Frequency Channel specifies which hardware PWM channel to use. Some devices have 1, 2 or 3 PWM channels. On devices with 2 channels, the Frequency must be the same on both channels. Dutycycle specifies the on/off (high/low) ratio of the signal. It ranges from 0 to 255, where 0 is off (low all the time) and 255 is on (high) all the time. A value of 127 gives a 50% duty cycle (square wave). Frequency is the desired frequency of the PWM signal. Not all frequencies are available at all oscillator settings. The lowest frequency at 4MHz is 245Hz. The highest frequency at any oscillator speed is 32767Hz. See the Microchip data sheet for the device for more information on the PWM hardware. HPWM 1,127,1000 ' Send a 50% duty cycle PWM signal at 1kHz HPWM 1,64,200 ' Send a 25% duty cycle PWM signal at 2kHz New One-Wire Commands Two new commands have been added to simplify access to Dallas Semiconductor one-wire devices: OWin and OWOut. Each command is discussed below. OWIn Pin, Mode, [Item{, Item...}] OWIn optionally sends a reset pulse to the one-wire device and then reads one or more bits or bytes of data from it, optionally ending with another reset pulse. Pin is a constant or variable that specifies which I/O pin the one-wire device is connected to. Mode specifies whether a reset is sent before and/or after the operation and the size of the data items, either bit or byte. Mode bit number Effect 0 1 = send reset pulse before data 1 1 = send reset pulse after data 2 0 = byte-sized data, 1 = bit-sized data Some Mode examples would be: Mode of 0 means no reset and byte-sized data, Mode of 1 means reset before data and byte-sized data, Mode of 4 means no reset and bit-sized data. Item is one or more variables or modifiers separated by commas. The allowable modifiers are Str for reading data into a byte array variable and Skip for skipping a number of input values. OWIn PORTC.0, 0, [temperature\2, Skip 4, count_remain, count_per_c] This statement would receive bytes from a one-wire device on PORTC pin 0 with no reset pulse being sent. It would receive 2 bytes and put them into the byte array temperature, skip the next 4 bytes and then read the final 2 bytes into separate variables. OWOut Pin, Mode, [Item{, Item...}] OWOut optionally sends a reset pulse to the one-wire device and then writes one or more bits or bytes of data to it, optionally ending with another reset pulse. Pin is a constant or variable that specifies which I/O pin the one-wire device is connected to. Mode specifies whether a reset is sent before and/or after the operation and the size of the data items, either bit or byte. Mode bit number Effect 0 1 = send reset pulse before data 1 1 = send reset pulse after data 2 0 = byte-sized data, 1 = bit-sized data Some Mode examples would be: Mode of 0 means no reset and byte-sized data, Mode of 1 means reset before data and byte-sized data, Mode of 4 means no reset and bit-sized data. Item is one or more constants, variables or modifiers separated by commas. The allowable modifiers are Str for sending data from a byte array variable and Rep for sending a number of repeated values. OWOut PORTC.0, 1, [$cc, $be] This statement would send a reset pulse to a one-wire device on PORTC pin 0 followed by the bytes $cc and $be. Peek and Poke Command Changes Peek and Poke have been changed to work more like Peek and Poke in the standard PicBasic compiler. For example, Peek PORTB, B0 will now store the value of the PORTB pins to B0. It is still recommended that Peek and Poke not be used. It is much better to simply say B0 = PORTB, for example. New Select Case Statements Case statements have been added that, in some cases, are easier to use than multiple If..Thens. These statements are used to compare a variable with different values or ranges of values, and take action based on the value. Select Case var Case expr1 {, expr...} statements Case expr2 {, expr...} statements {Case Else statements} End Select The variable used in all of the comparisons is specified in the Select Case statement. Each Case is followed by the statements to be executed if the Case is true. If none of the Cases are true, the statements under the optional Case Else statement are executed. An End Select closes the Select Case. See the sample program CASE.BAS for an example. New USB Commands Support has been added for the PIC16C745 and 765 low-speed USB devices. This support takes the form of three new PBP commands as well as some modifications to the Microchip USB libraries. The new commands are shown below: USBInit USBInit needs to be one of the first statements in the program. It will initialize the USB portion of the PICmicro MCU and wait until the USB bus is configured and enabled. USBIn enpoint, buffer, countvar, label USBIn gets any available USB data for the endpoint and places it in the buffer. Buffer must be a byte array of suitable length to contain the data. Countvar will contain the number of bytes transferred to the buffer. Label will be jumped to if no data is available. USBOut endpoint, buffer, count, label USBOut takes count number of bytes from the buffer and sends them to the USB endpoint. If the USB buffer does not have room for the data because of a pending transmission, no data will be transferred and program execution will continue at label. The USB subdirectory contains the modified Microchip USB libraries as well as example programs. USB programs require several addtional files to operate (which are in the USB subdirectory), some of which will require modification for your particular application. See the text file in the USB subdirectory for more information on the USB commands. USB communications is much more complicated than synchronous (Shiftin and Shiftout) and asynchronous (Serin, Serout and so forth) communications. There is much more to know about USB operation that can possibly be described here. The USB information on the Microchip web site needs to be studied. Also, the book "USB Complete" by Jan Axelson may be helpful. New Limited 12-bit Core Support PicBasic Pro version 2.4 adds limited support for all the 12-bit core PICmicro microcontrollers. The reason the support is limited is that the resources on the 12-bit core devices are very limited. Some of these limits include only a two-level hardware stack and very small amounts of general purpose RAM memory. The code page size is also small at 512 bytes. There is also a limitation that calls and computed jumps can only be made to the first half (256 words) of any code page. These limitations have made it necessary to eliminate some compiler commands and modify the operation of some others. While many useful programs can be written for the 12-bit core PICmicros using the PicBasic Pro Compiler, some applications will not be suited for these devices. Choosing a 14- or 16-bit core device with more resources will, in many cases, be the best solution. Commands that are not supported for the 12-bit core PICmicros: Command Reason Adcin No internal ADCs Data No on-chip EEPROM Dtmfout Not enough RAM or stack Eeprom No on-chip EEPROM Freqout Not enough RAM or stack Hpwm No hardware PWM Hserin No hardware serial port Hserout No hardware serial port On Interrupt No Interrupts Read No on-chip EEPROM Readcode No flash devices Resume No Interrupts Serin2 Not enough RAM or stack Serout2 Not enough RAM or stack USBIn No USB devices USBInit No USB devices USBOut No USB devices Write No on-chip EEPROM Writecode No flash devices Xin Not enough RAM or stack Xout Not enough RAM or stack Trying to use these commands with 12-bit core devices will result in numerous errors. If you must use one of these commands, choose a 14- or 16-bit core device with more resources. Commands that have had their operation modified are: Button The Define for debounce, BUTTON_PAUSE is limited to 65 milliseconds. Debug, Debugin The Serin2 and Serout2 modifiers are not supported for these commands because of memory and stack size limits. I2CRead, I2CWrite The I2C clock and data pins are fixed at compile time by Defines. They still must be specified in the I2CRead and I2CWrite statements, though this information is ignored by the compiler. Define I2C_SDA PORTA,0 Define I2C_SCL PORTA,1 Because of memory and stack constraints, the Define for I2C_SLOW does not do anything. Low-speed (100 kHz) I2C devices may be used up to 4MHz. Above 4MHz, high-speed (400kHz) devices should be used. The Define for I2C_HOLD has no effect. Lcdout The Serout2 modifiers are not supported for this command because of memory and stack size limits. OWIn, OWOut The Rep, Skip and Str modifiers are not supported for these commands because of memory and stack size limits. Serout The open drain modes are not available due to TRIS register constraints. Shiftin, Shiftout The Define for SHIFT_PAUSEUS is not available because of stack size limitations. General Considerations Because of the architecture of the 12-bit core PICmicro MCUs, programs compiled for them by PBP will, in general, be larger and slower that programs compiled for the other PICmicro families. In many cases, choosing a device from one of these other families will be more appropriate. However, many useful programs can be written and compiled for the 12-bit core devices. The two main programming limitations that will most likely occur are running out of RAM memory for variables and running past the first 256 word limit for the library routines. The compiler uses between 20 and 22 bytes of RAM for its internal variables, with additional RAM used for any necessary temporary variables. This RAM allocation includes a 4 level software stack so that the BASIC program can still nest Gosubs up to 4 levels deep. Some PICmicro devices only have 24 or 25 bytes of RAM so there is very little space for user variables on those devices. If the Unable to Fit Variable error message occurs during compilation, choose another PICmicro MCU with more general purpose RAM. 12-bit core PICmicro MCUs can call only into the first half (256 words) of a code page. Since the compiler's library routines are all accessed by calls, they must reside entirely in the first 256 words of the PICmicro code space. Many library routines, such as I2CRead, are fairly large. It may only take a few routines to overrun the first 256 words of code space. If it is necessary to use more library routines that will fit into the first half of the first code page, it will be necessary to move to a 14- or 16-bit core PICmicro MCU instead of the 12-bit core device.