Mikrobasic Manual Files Center)
Mikrobasic Manual Files Center)
Mikrobasic Manual Files Center)
yu
MikroElektronika
Basic Compiler for Microchip PIC microcontrollers
Users manual
mikroBASIC
making it simple...
Develop your applications quickly and easily with the world's most intuitive Basic compiler for PIC Microcontrollers (families PIC12, PIC16, and PIC18). Highly sophisticated IDE provides the power you need with the simplicity of a Windows based point-and-click environment. With useful implemented tools, many practical code examples, broad set of built-in routines, and a comprehensive Help, mikroBasic makes a fast and reliable tool, which can satisfy needs of experienced engineers and beginners alike.
Table of Contents
CHAPTER 1 CHAPTER 2 CHAPTER 3 mikroBasic IDE mikroBasic Reference Built-In and Library Routines
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
CHAPTER 1: mikroBasic IDE Quick Overview Code Editor Basic Editor Features Advanced Editor Features Code Explorer Creating First Project Projects Managing Source Files Compile and Link Source Code Debugger Error Window Assembly View Statistics Integrated Tools Keyboard Shortcuts CHAPTER 2: mikroBasic Reference Identifiers Keywords Data Types Array Strings Numerals and Character Strings Constants Array Constants Symbols Variables Comments Expressions Declaration and Statements Directives
1 1 3 3 4 6 7 13 14 16 17 19 20 21 24 26 28 29 30 31 32 34 35 36 38 40 41 45 46 48 50
page
MikroElektronika: Development tools - Books - Compilers
ii
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple... 52 57 60 62 64 67 71 75 78 81 82 86 89 89 90 92 94 95 97 98 99 100 101 103 106 107 109 110 113 115 127 136 144 145
Procedures And Functions Modules Scope (Identifier Visibility) Program Organization Type Conversion Assignment And Implicit Conversion Implicit Conversion And Legal Expressions Operators Arithmetic Operators Boolean Operators Logical (Bitwise) Operators Relation (Comparison) Operators Conditional Statements Labels and Goto Case Statement If Statement Loops For Statement Repeat Statement While Statement ASM Statement PIC MCU Specific mikroBasic Specific Compiler Error Messages CHAPTER 3: Built-In and Library Routines Built-In Routines Library Routines 1-Wire Library ADC Library CAN Library CANSPI Library Compact Flash Library EEPROM Library I2C Library
iii
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
LCD Library LCD8 Library (8-bit interface) Graphic LCD Library PWM Library RS485 Library SPI Library USART Library Software I2C Software SPI Software UART Flash Memory Manchester Code Numeric Formatting Routines Trigonometry Library Sound Library Utilities
149 154 158 163 165 171 176 179 181 183 185 188 194 196 198 200
iv
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
To readers note
DISCLAIMER: mikroBASIC compiler and this manual are owned by MikroElektronika and are protected by copyright law and international copyright treaty. Therefore, you should treat this manual like any other copyrighted material (e.g., a book). The manual and the compiler may not be copied, partially or as a whole without the written consent from the MikroEelktronika. The PDF-edition of the manual can be printed for private or local use, but not for distribution. Modifying the manual or the compiler is strictly prohibited. HIGH RISK ACTIVITIES The mikroBASIC compiler is not fault-tolerant and is not designed, manufactured or intended for use or resale as on-line control equipment in hazardous environments requiring fail-safe performance, such as in the operation of nuclear facilities, aircraft navigation or communication systems, air traffic control, direct life support machines, or weapons systems, in which the failure of the Software could lead directly to death, personal injury, or severe physical or environmental damage ("High Risk Activities"). MikroElektronika and its suppliers specifically disclaim any express or implied warranty of fitness for High Risk Activities. LICENSE AGREEMENT: By using the mikroBASIC compiler, you agree to the terms of this agreement. Only one person may use licensed version of mikroBASIC compiler at a time. Copyright MikroElektronika 2003 - 2004. This manual covers mikroBASIC 1.16 and the related topics. New versions may contain changes without prior notice. COMPILER BUG REPORTS: The compiler has been carefully tested and debugged. It is, however, not possible to guarantee a 100 % error free product. If you would like to report a bug, please contact us at the address [email protected]. Please include next information in your bug report: - Your operating system - Version of mikroBASIC - Code sample - Description of a bug CONTACT US: MikroElektronika magazine Voice: +381 11 362 04 22, + 381 11 684 919 Fax: +381 11 362 04 22 Web: www.MikroElektronika.co.yu E-mail: office@MikroElektronika .co.yu
PIC, PICmicro and MPLAB is a Registered trademark of Microchip company. Windows is a Registered trademark of Microsoft Corp. All other trade and/or services marks are the property of their respective owners.
page
CHAPTER
mikroBasic IDE
QUICK OVERVIEW
mikroBasic is a Windows-based Integrated Development Environment, and is much more than just Basic compiler for PIC MCUs. With mikroBasic, you can: 1. 2. 3. 4. 5. 6. Create Basic source code using the built-in Code Editor Compile and link your source code Inspect program flow and debug executable logic with Debugger Monitor variables in Watch Window Get error reports Get detailed statistics (how compiled code utilizes PIC MCU memory, hex map, charts and more...)
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Watch Window
Code Explorer
Code Editor
Breakpoints Dialog
Code Editor features adjustable Syntax Highlighting, Code Assistant, Parameters Assistant, Auto Correct for common typos, and Code Templates. Code browser, Keyboard shortcut browser, and Quick Help browser are at your disposal for easier project management. Error Window displays all errors detected during compiling and linking. Watch Window enables you to monitor variables, registers and PIC MCU memory. New Project Wizard is fast, reliable, and easy way to create a project. Source-level Debugger lets you debug executable logic step-by-step by watching program flow. Help files are syntax and context sensitive.
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
CODE EDITOR
Basic Editor Features
General code editing is same as working with any standard text-editor, including familiar Copy, Paste, and Undo actions, common for Windows environment. Advanced code editing includes: - Adjustable Syntax Highlighting - Code Assistant, Parameters Assistant, Code Templates - Auto Correct for common typos You can configure Syntax Highlighting, Code Assistant and Auto Correct from Editor Settings dialog. To access this window, click Tools > Options from dropdown menu, or click Tools icon in Settings toolbar.
Tools Icon.
page
MikroElektronika: Development tools - Books - Compilers
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Parameter Assistant [CTRL+SHIFT+SPACE] Parameter Assistant will be automatically invoked when you open a parenthesis "(" or press CTRL+SHIFT+SPACE. If name of valid function or procedure precedes the parenthesis, then the expected parameters will be prompted to you in a floating panel. As you type the actual parameter, next expected parameter will become bold.
Code Template [CTR+J] You can insert Code Template by typing the name of the template (for instance, proc), then press CTRL+J, and Editor will automatically generate code. Or you can click button from Code toolbar and select template from the list. You can add your own templates to the list. Just select Tools > Options from dropdown menu, or click Tools Icon from Settings Toolbar, and then select Auto Complete Tab. Here you can enter the appropriate keyword, description, and code of your template. Auto Correct Auto Correct corrects common typing mistakes. To access the list of recognized typos, select Tools > Options from drop-down menu, or click Tools Icon from Settings Toolbar, and then select Auto Correct Tab. You can also add your own preferences to the list.
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Also, Code Editor has feature to comment or uncomment selected block of code by simple click of a mouse, using icons and from Code Toolbar.
Bookmarks Bookmarks make navigation through large code easier. CTRL+<number> : Goto bookmark CTRL+SHIFT+<number> : Set bookmark Goto Line Goto Line option makes navigation through large code easier. Select Search > Goto Line from drop-down menu, or use the shortcut CTRL+G.
page
MikroElektronika: Development tools - Books - Compilers
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
CODE EXPLORER
Code Explorer is placed to the left of the main window by default, and gives clear view of every declared item in the source code. You can jump to declaration of any item by right clicking it, or by clicking the Find Declaration icon. To expand or collapse treeview in Code Explorer, use the Collapse/Expand All icon. Also, two more tab windows are available in Code Explorer: Keyboard Tab lists all keyboard shortcuts, and QHelp Tab lists all the available built-in and library functions and procedures, for a quick reference. Double-clicking a routine in QHelp Tab opens an appropriate Help chapter.
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Step 2 Fill the New Project Wizard dialog with correct values to set up your new project. - Select a device for your project from the drop-down menu - Set configuration bits (Device Flags) by clicking Default push-button. - Select Device Clock by entering appropriate value in edit box. - Enter a name for your new project - Enter project description edit box for closer information about your project - Enter project path
page
MikroElektronika: Development tools - Books - Compilers
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
After you have set up your project, select OK push button in New Project Wizard dialog box. mikroBasic will create project for you and automatically open the program file in code editor. Now we can write the source code.
Step 3 After you have successfully created an empty project with New Project Wizard, Code Editor will display an empty program file, named same as your project.
Now we can write the code for this simple example. We want to make LED diode blink once per second. Assuming we have the configuration given in the following figure, LED diodes are connected to PIC16F877 PORTB pins. (it can be any other PIC that has PORTB)
page
mikroBASIC
making it simple...
+5V
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
PIC16F877A
MCLR/Vpp/THV RB7/PGD RA0/AN0 RB6/PGC RB5 RB4 RB3/PGM RB2 RB1 RB0/INT Vdd Vss RD7/PSP7 RD6/PSP6 RD5/PSP5 RD4/PSP4 RC7/RX/DT RC6/TX/CK RC5 RC4 RD3/PSP3 RD2/PSP2
10K
330R
LB7
Reset
RE0/RD/AN5
330R
+5V
RE1/WR/AN6 RE2/CS/AN7 Vdd Vss OSC1 OSC2 RCO/T1OSO RC1/T1OSI RC2/CCP1 RC3 RD0/PSP0 RD1/PSP1
LB6 LB5
330R
330R
LB4
330R
LB3
4MHz
330R
LB2
330R
LB1
330R
LB0
In this configuration, LED will emit light when voltage on pin is high (5V), and will be off when voltage on pin is low (0V). We have to designate PORTB pins as output, and change its value every second. Listing of program is below
program My_LED main: TRISB = 0 eloop: PORTB = $FF delay_ms(1000) PORTB = 0 delay_ms(1000) goto eloop end.
' configure ' ' ' ' ' turn wait turn wait stay
page
MikroElektronika: Development tools - Books - Compilers
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Compile Icon.
Step 4 Before compiling, it is recommended to save the project (menu choice File>Save All). Now you can compile your code by selecting menu Run > Compile, or by clicking the Compile icon.
mikroBasic has generated hex file which can be used to program PIC MCU. But before that, let's check our program with the Debugger. Also mikroBasic generates list and assembly files. Step 5 After successful compiling, we can use mikroBasic Debugger to check our program behavior before we feed it to the device (PIC16F877 or other). For a simple program such as this, simulation is not really necessary, but it is a requirement for more complex programs. To start the Debugger, select Run > Debug, or click the Debug icon, or simply hit F9.
Debug Icon.
Upon starting the Debugger, Watch Window appears, and the active line in Code Editor marks the instruction to be executed next. We will set the breakpoint at line 7 by positioning the cursor to that line and toggling the breakpoint (Run > Toggle Breakpoint or F5). See the following image.
10
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
We will use the Step Over option (Run > Step Over or F8) to execute the current program line. Now, you can see the changes in variables, SFR registers, etc, in the Watch Window items that have changed are marked red, as shown in the image below.
We could have used Run/Pause (F6) option to execute all the instructions between the active line and the breakpoint (Run > Run/Pause Debugger).
11
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Step 6 Now we can use hex file and feed it to the device (PIC16F877 or other). In order to do so hex file must be loaded in programmer (PIC Flash by mikroElektronika or any other).
12
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
PROJECTS
Each application, or project, consists of a single project file and one or more unit files. You can compile source files only if they are part of the project. First and essential step is creating a project. We will use New Project Wizard to create our new project. Select Project > New Project from drop-down menu and follow the dialog:
(select PIC MCU device, device clock, setup configuration bits, set project name, location and description) Later, if you want to change some project settings, select Project > Edit from dropdown menu. To save your project , select Project > Save All from drop-down menu. To save your project under different name, select Project > Save Project As from drop-down menu. To open a project, select Project > Open, or Project > Reopen from drop-down menu. When you create new project, mikroBasic automatically creates an empty main unit file in which you'll write your source code.
13
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
14
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Select File > Open from drop-down menu, or press CTRL+O, or click the Open File icon. The Select Input File dialog opens. In the dialog, browse to the location of the file you want to open and select it. Click the Open button. The selected file is displayed in its own tab. If the selected file is already open, its current Editor tab will become active. Printing an Open File
Make sure that window containing the file you want to print is the active window. Select File > Print from drop-down menu, or press CTRL+P, or click the Print icon. In the Print Preview Window, set the desired layout of the document and click the OK button. The file will be printed on the selected printer. Saving File
Make sure that window containing the file you want to save is the active window. Select File > Save from drop-down menu, or press CTRL+S, or click the Save icon. The file will be saved under the name on its window. Saving File Under a Different Name Make sure that window containing the file you want to save is the active window. Select File > Save As from drop-down menu, or press SHIFT+CTRL+S. The New File Name dialog will be displayed. In the dialog, browse to the folder where you want to save the file. In the File Name field, modify the name of the file you want to save. Closing a File Click the Save button. Make sure that tab containing the file you want to close is the active tab. Select File > Close from drop-down menu, or right click the tab of the file you want to close in Code Editor. If the file has been changed since it was last saved, you will be prompted to save your changes.
15
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Compile Icon.
16
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
DEBUGGER
Source-level Debugger is integral component of mikroBasic development environment. It is designed to simulate operations of Microchip Technology's PIC MCUs and to assist users in debugging Basic software written for these devices. Debugger simulates program flow and execution of instruction lines, but does not fully emulate PIC device behavior: it does not update timers, interrupt flags, etc. Jump to interrupt is performed by clicking the Interrupt icon . After you have successfully compiled your project, you can run Debugger by selecting Run > Debug from drop-down menu, or by clicking Debug Icon . Starting the Debugger makes more options available: Step Into, Step Over, Run to Cursor etc. Line that is to be executed is color highlighted (blue).
Debug Icon.
Debug Icon.
Step Into [F7] Execute the current Basic instruction (single or multiple cycle instructions) and then halt. After execution, all windows are updated. If the instruction is a procedure or function call, execute it enters routine and halt at the first following instruction after the call.
Step Over [F8] Execute the current Basic instruction (single or multiple cycle instructions) then halt. If the instruction is a procedure or function call, execute the called routine and halt at the instruction following the call.
Run to cursor [F4] Executes all instructions between the current instruction and the cursor position.
17
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Run/Pause Debugger [F6] Run or pause Debugger. Run > View Breakpoints Invoke breakpoints window, with list of breakpoints. Double clicking item in window list locates breakpoint. Watch Window Watch Window allows you to monitor program items while running your program. It displays variables and special function registers of PIC MCU, their addresses and values. Values are updated as you go through the simulation. See the image below.
Double clicking one of the items opens a window in which you can assign new value to the selected variable or register.
18
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
ERROR WINDOW
In case that errors were encountered during compiling, compiler will report them and won't generate a hex file. Error Window will be prompted at the bottom of the main window. Error Window is located under message tab, and displays location and type of errors compiler has encountered. Compiler also reports warnings, but these do not affect generating hex code. Only errors can interefere with generation of hex.
Double clicking the message line in Error Window results in highlighting the line of source code where the error took place.
19
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
ASSEMBLY VIEW
After compiling your program in mikroBasic, you can click toolbar Assembly icon or select Project > View Assembly from drop-down menu to review generated assembly code in a new tab window. Assembly is human readable with symbolic names. All physical addresses and other information can be found in Statistics or in list file. If program is not compiled and there is no assembly file, starting this option will compile your code and then display assembly.
Assembly Icon.
20
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
STATISTICS
After successful compiling, you can review statistics on your code. Select Project > View Statistics from drop-down menu, or click the Statistics icon. There are five tab windows: Memory Usage Window Provides overview of RAM and ROM memory usage in form of histogram.
Statistics Icon.
Procedures (Graph) Window Displays procedures and functions in form of histogram, according to their memory allotment.
21
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Procedures (Locations) Window Displays how procedures and functions are located in microcontrollers memory.
Procedures (Details) Window Displays complete call tree, along with details for each procedure and function: size, start and end address, frequency in program, return type, etc.
22
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
RAM Window Summarizes all GPR and SFR registers and their addresses. Also displays symbolic names of variables and their addresses.
ROM Window Lists op-codes and their addresses in form of a human readable hex code.
23
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
INTEGRATED TOOLS
USART Terminal mikroBasic includes USART (Universal Synchronous Asynchronous Receiver Transmitter) communication terminal for RS232 communication. You can launch it from drop-down menu Tools > Terminal or by clicking the icon .
ASCII Chart ASCII Chart is a handy tool, particularly useful when working with LCD display. You can launch it from drop-down menu Tools > ASCII chart.
24
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
7 Segment Display Decoder 7seg Display Decoder is a convenient visual panel which returns decimal/hex value for any viable combination you would like to display on 7seg. Click on the parts of 7 segment image to the left to get the desired value in the edit boxes. You can launch it from drop-down menu Tools > 7 Segment Display.
EEPROM Editor EEPROM Editor allows you to easily manage EEPROM of PIC microcontroller.
25
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
KEYBOARD SHORTCUTS
Complete list of keyboard shortcuts is available from Code Explorer window, tab Keyboard.
IDE Shortcuts F1 CTRL+N CTRL+O CTRL+F9 CTRL+F11 CTRL+SHIFT+F5 Advanced Editor shortcuts CTRL+SPACE CTRL+SHIFT+SPACE CTRL+D CTRL+G CTRL+J CTRL+<number> CTRL+SHIFT+<number> CTRL+SHIFT+I CTRL+SHIFT+U CTRL+ALT+SELECT Debugger Shortcuts F4 F5 F6 F7 F8 F9 CTRL+F2 Run to Cursor Toggle breakpoint Run/Pause Debugger Step into Step over Debug Reset Code Assistant Parameters Assistant Find declaration Goto line Insert Code Template Goto bookmark Set bookmark Indent selection Unindent selection Select columns Help New Unit Open Compile Code Explorer on/off View breakpoints
26
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Basic Editor shortcuts F3 CTRL+A CTRL+C CTRL+F CTRL+P CTRL+R CTRL+S CTRL+SHIFT+S CTRL+V CTRL+X CTRL+Y CTRL+Z Find, Find Next Select All Copy Find Print Replace Save unit Save As Paste Cut Redo Undo
27
page
CHAPTER
mikroBasic Reference
"Why Basic?", you may wonder. Well, the answer is simple: it is legible, easy-tolearn, procedural programming language, with sufficient power and flexibility needed for programming microcontrollers. Whether you had any previous programming experience, you will find that writing programs in mikroBasic is very easy. This chapter will help you learn or recollect Basic syntax, along with the specifics of programming PIC microcontrollers.
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
IDENTIFIERS
Identifiers are names used for referencing the stored values, such as variables and constants. Every program, procedure, and function must be identified (hence the term) by an identifier.
Rules
Valid identifier: 1. must begin with a letter of English alphabet or possibly the underscore (_) 2. can be followed by alphanumeric characters and the underscore (_) 3. may not contain special characters: ~!@#$%^&*()+`-={}[]:";'<>?,./|\ mikroBasic is not case sensitive. First, FIRST, and fIrST are an equivalent identifier. Elements ignored by the compiler include spaces, new lines, and tabs. All these elements are collectively known as the white space. White space serves only to make the code more legible; it does not affect the actual compiling. Several identifiers are reserved in mikroBasic - you cannot use them as your own identifiers. Please refer to Kewords. Also, mikroBasic has several pre-defined identifiers. Pre-defined identifiers are listed in the chapter Library Functions and Procedures.
Note
Examples
begin with a numeral contain special characters match reserved word contain special characters
29
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
KEYWORDS
The following keywords (reserved words) cannot be redefined or used as identifiers. absolute and asm boolean char clear div double end for goto if int is mod next or procedure float select string then module include wend with abs array begin case chr const do else exit function gosub in interrupt loop new not print program read step switch to until dim while xor
In mikroBasic, all SFR (Special Function Registers) are defined as global variables and represent special reserved words that cannot be redefined. For example TMR0, PCL, STATUS, etc. Also, mikroBasic has a number of predefined identifiers (refer to Library Routines). These can be replaced by your own definitions, but that would impede the functionality of mikroBasic.
30
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
DATA TYPES
Type determines the allowed range of values for variable, and which operations may be performed on it. It also determines the amount of memory used for one instance of that variable.
Simple
Range of values 0 .. 255 0 .. 255 0 .. 65535 -128 .. 127 -32768 .. 32767 -2147483648 ..147483647
Structured
Array represents an indexed collection of elements of the same type, often called the base type. Base type can be any simple type. String represents a sequence of characters. It is an array that holds characters and the first element of string holds the number of characters (max number is 255).
Sign
Sign is important attribute of data types, and affects the way variable is treated by the compiler. Unsigned can hold only positive numbers: byte word 0 .. 255 0 .. 65535
Signed can hold both positive and negative numbers: short integer longint -128 .. 127 -32768 .. 32767 -2147483648 .. 214748364
31
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Array
Array is a set of data stored in consecutive memory locations. Defining an array and manipulating its elements is simple. Elements of array are always of same data type (any simple).
First declaration above generates 7 variables of byte type. These can be accessed by array name followed by number in the square brackets [] (this number is also known as index). Indexing is zero based, meaning that in our example, index spans numbers from 0 to 6. Instead of byte, you can define array of any other simple type (word, short, integer or longint). Note that:
dim something as integer[10]
occupies 20 RAM locations (bytes), not 10. You can use any kind of operator with array elements - Arithmetic Operators, Logical (Bitwise) Operators, and Relation (Comparison) Operators. Technically, array element is treated as a simple type. Also, instead of a number, index can be any expression with result type of byte. For example:
m[a + b] = 90 m[1] = m[2] + 67 m[1] = m[2] div m[3]
When you declare an array, mikroBasic allocates a certain amount of RAM for it. Elements of array consume consecutive RAM locations; in case of array of bytes, if the address of m[0] is 0x23, m[1] will be at 0x24, and so on. Accessing these elements is almost as fast as accessing any variable of simple type. Instead of byte you can define array of any other simple type (word, short, integer or longint). Don't forget that you are restricted by the amount of free space in PIC RAM memory.
32
page
mikroBASIC
making it simple... For example:
dim size as longint[10]
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
After you have declared an array, for example: dim m as byte[5] you can easily access its elements m[0],m[1],m[2]....
Example
j[0] = m[3] + 6 m[4] = m[2] mod 3 j[2] = not j[0] if m[0] > 0 then m[1] = 9 else m[1] = 90 end if end.
33
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Strings
String represents a sequence of characters. String type is similar to array, but can hold only characters.
dim M_name as string[16] dim Start_message as string[6]
For each string declaration, compiler will reserve the appropriate amount of memory locations. For example, string M_name will take 16+1 locations; additional memory location is reserved to contain the length of the string. If we assign string literal to variable M_name, M_name = "mik", then:
M_name[0] M_name[1] M_name[2] M_name[3]
will be 3 (contains length of the string) will be 'm' will be 'i' will be 'k'
Length
It returns string length as byte, and is quite useful for handling characters within string:
M = "mikroElektronika" for i = 1 to Length(M) LCD_Chr(1,i,M[i]) next i
34
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Character Strings
Character string, also called a string literal or a string constant, consists of a quoted string. Separators can be used only within quoted strings. A quoted string is a sequence of up to 255 characters from the extended ASCII character set, written in one line and enclosed by apostrophes. Quoted string with nothing between the apostrophes is a null string. Apostrophe itself cannot be used as part of the string. For example:
"mikroBasic" "" " "
Length of character string is the number of characters it consists of. Character string of length 1 is compatible with the char type. You can assign string literal to a string variable or to array of char.
35
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
CONSTANTS
Constant is data whose value cannot be changed during the runtime. Every constant is declared under unique name which must be a valid identifier. It is a good practice to write constant names in uppercase. In mikroBasic, constants have to be of simple data type (no arrays or strings are allowed). Example of constant declaration:
const MAXVALUE = 237
Constants can be used in any legal expression, but they cannot be assigned a new value. Therefore, they cannot appear on the left side of the assignment operator.
Note
If you frequently use the same value throughout the program and its value is fixed, you should declare it a constant (for example, maximum number allowed is 1000). This is a good practice since the value can be changed simply by modifying the declaration, instead of going trough the entire program and adjusting each instance manually. As simple as this:
const MAX = 1000
It is important to understand why constants should be used and how this affects the MCU. Using a constant in a program consumes no RAM memory. This is very important due to the limited RAM space (PIC16F877 has 368 locations/bytes).
36
page
mikroBASIC
making it simple...
Examples const const const const
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
ADC_Res = ADC_Read(2) if ADC_Res > Max then portb = 1 else portb = Min end if
const 7time = 123 ' Wrong constant name, it must be ' a valid identifier const Max = 1123456 ' Assigned value exceeds the allowed ' range for integer Max = A Max = 123 ' You cannot assign new value to a constant, ' compiler will report an error
37
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
ARRAY CONSTANTS
Array constant is a set of data stored in ROM memory. Elements of array are always of the same data type (any simple).
To declare an array constant holding numerals, enclose the values of the array's elements, separated by commas, in parentheses. For arrays of char type, use a string literal (text enclosed by quotes), as shown in the example above. Number of values in parentheses, i.e. a number of characters in quotes, must match the specified value in the square brackets. Accessing elements of array constant is simple, but be careful not to exceed the array range (if index is greater than array size, program won't work correctly). Indexing is zero based, so if you declare:
const width as byte[3] = (23,5,67)
Note
then width[0] is the first element and index needs to be less or equal than 2. Special case is array constant of char which holds the size of the array in the first location. Array constant of char is limited to 255 characters. You can use any kind of operator with array constant elements. Technically, array constant element is treated as a simple constant. Also, instead of a number, index can be any expression. But, you cannot assign new value to array constant element. For example:
m = CMONTHS[a + b] m = CMONTHS[2] + 67 vv = vv div CMONTHS[3]
38
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Also, it is possible for array constants of type char to copy whole array to variable of same type by simple assignment. For example:
const CTXT as char[4] = "dota" dim txt as char[4] ... txt = CTXT ' this is legitimate
Elements of array constant are located in R0M. PIC16 family restricts array constants to 255 elements of byte type, while PIC18 family is limited only by ROM size. Instead of byte, you can define array of any other simple type (word, short, integer or longint). Don't forget that you are restricted by the amount of PIC ROM memory. For example:
const foo as longint[5] = (36732, 32442, 19901, 82, 27332724)
Example
program Array_test const m dim j main: j[0] = j[4] = j[2] = as byte[3] = (0,1,2) as byte[5] m[3] + 6 m[2] mod 3 not j[0]
39
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
SYMBOLS
Symbol makes possible to replace expression with a single identifier alias. Use of symbols increases the reusability and flexibility of code. BASIC syntax restricts you to single line expressions, allowing shortcuts for constants, simple statements, function calls, etc. Scope of symbol identifier is a whole source file in which it is declared. Symbol is declared as:
symbol alias = single_line_expression
where alias must be a valid identifier which you will be using throughout the code.
Using a symbol in a program technically consumes no RAM memory - compiler simply replaces each instance of a symbol with the appropriate code from the declaration.
Example
symbol MaxAllowed = 234 symbol PORT = PORTC symbol DELAY1S = delay_ms(1000) teA > MaxAllowed then teA = teA - 100 end if PORT.1 = 0 DELAY1S ... if
' symbol as alias for numeral ' symbol as alias for SFR ' symbol as alias for proc. call
40
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
VARIABLES
Variable is data whose value can be changed during the runtime. Every variable is declared under unique name which must be a valid identifier. This name is used for accessing the memory location occupied by the variable. Variable can be seen as a container for data and because it is typed, it instructs the compiler how to interpret the data it holds. For more details refer to Data Types and Type Conversion. For more information on variables' scope refer to the chapter Scope (Variable Visibility). In mikroBasic, variable needs to be declared before it can be used. Specifying a data type for each variable is mandatory. Basic syntax for variable declaration is:
dim variable as type
where variabe is any valid identifier, and type can be any valid data type. For example:
dim A as byte dim BB as word
' declare variable tA of byte type ' declare variable tB of word type
Every declared variable consumes part of MCU RAM memory. Data type of variable determines not only the allowed range of values, but also the space variable occupies in RAM memory. Bear in mind that operations using different types of variables take different time to be completed. For example: Variable A (byte) occupies 1 byte (8 bit) of RAM memory, while variable BB (word) occupies 2 bytes (16 bit) of RAM memory. Therefore, A = A + A is faster to execute than BB = BB + BB.
41
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Note
mikroBasic recycles local variable memory space - local variables declared in different functions and procedures share same memory space, if possible.
Additional info
Variable declaration has to be properly placed to have a correct meaning. Variables can be declared in a program block or implementation section of a module. Variable declaration must be placed ahead of the keyword begin. You can also declare variables in function or procedure block. Refer to Program Organization, and see the following example. There is no need to declare PIC SFR (Special Function Registers), as they are already declared as global variables of byte type - for example: TMR0, PCL, STATUS, PORTA, TRISA, etc. These variables may be used anywhere within the code. For closer information on how to use variables and build valid expressions refer to the chapter Operators.
42
page
mikroBASIC
making it simple...
Examples program TRIAL include "other.pbas"
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
main: tA = tD and tF
' STATUS and TMR0 are PIC registers tR = STATUS and $03 TMR0 = 45 end.
... module other
sub function Sum( dim R as byte) as byte ' You can also declare variables in ' function or procedure block. dim B as char dim K as byte ... end sub
43
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
tE = pr_function(1,tA) ' pass variable to function or procedure, ' by value or address pr_procedure(1,2,tD,tE)
' use them in conditional and/or ' loop statements and more ...
select case tb case 1 tA = tD + 4 case 2 tB = tC + 6 case 3 tC = $ff tb = tc - tA case else pr_procedure(1,2,tD,tE) end select for tA = 0 to 7 tC = tB >> 1 next tA
44
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
COMMENTS
Comments are text that is added to the code for purpose of description or clarification, and are completely ignored by the compiler.
' Any text between an apostrophe and the end of the ' line constitutes a comment. May span one line only.
It is a good practice to comment your code, so that you or anybody else can later re-use it. On the other hand, it is often useful to comment out a troublesome part of the code, so it could be repaired or modified later. mikroBasic Code Editor features syntax color highlighting - it is easy to distinguish comments from the code due to different color, and comments are also italicized.
Example
main: teC = 12
if teA > 0 then teC = 9 else teA = teB end if ' you can also comment out part of the ' code you don't want to compile:
45
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
EXPRESSIONS
Expression is a construction that returns a value. The simplest expressions are variables and constants, while more complex expressions are constructed from simpler ones using operators, function calls, indexes, and typecasts. Rules for creating legal expressions are presented in chapter Implicit Conversion and Legal Expressions. These are all expressions:
X 15 Calc(X, Y) X * Y
Legal Expressions
We will present in short notice rules for building expressions here. But, we should recollect some information beforehand: Simple data types include: byte, word, short, integer and longint. Byte and word types hold only positive values so well call them unsigned. Ranges are: byte word 0 .. 255 0 .. 65535
Short, integer, and longint types can hold both positive and negative numbers so well call them signed. Ranges are: short integer longint -128 .. 127 -32768 .. 32767 -2147483648 .. 214748364
46
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
You cannot mix signed and unsigned data types in expressions with arithmetic or logical operators. You can use explicit conversion though.
dim dim dim dim dim ... A = A = Sa as short A as byte Bb as word Sbb as integer Scccc as longint A + Sa A and Sa
' compiler will report an error ' compiler will report an error
' But you can freely mix byte with word.. Bb = Bb + (A * A) ' ..and short with integer and longint Scccc = Sbb * Sa + Scccc
You can assign signed to unsigned or vice versa only using the explicit conversion.
Sa = short(A) ' this can be done; convert A to short, ' then assign to Sa Sa = A ' this can't be done, ' compiler will report an error
Relation operators can freely be used even when mixing signed and unsigned data. For example:
if Sa > B then Sa = 0 end if
Note
Comparing variable or constant to variable or constant will always produce correct results. Comparing expressions requires a little more attention. For more information refer to the chapter Implicit Conversion and Relation Operators.
47
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Declarations
Names of variables, constants, types, procedures, functions, programs and units are called identifiers (numeric constant like 321 is not an identifier). Identifiers need to be declared before you can use them. Only exceptions are few predefined types, library functions and procedures, PIC MCU SFR ( PIC Special Function Registers), and constants; these are understood by the compiler automatically. Declaration defines an identifier and, where appropriate, allocates memory for it. For example:
dim Right as word
declares a function called Each which collects two integers as arguments and returns an integer. Each declaration ends with a semicolon (separator). When declaring several variables, constants, or types at the same time, you need to write the appropriate reserved word only once :
dim Height as integer dim Description as string[10]
The syntax and placement of a declaration depends on the kind of identifier you are defining. In general, declarations take place only at the beginning of a block, or at the beginning of the implementation section of a unit (after the include clause). Specific conventions for declaring variables, constants, types, functions, and so forth can be found in the appropriate chapters.
48
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Statements
Statements define algorithmic actions within a program. Simple statements - like assignments and procedure calls - can be combined to form loops, conditional statements, and other structured statements. Refer to Implicit Conversion and Assignment.
Simple Statements Simple statement does not contain any other statements. Simple statements include assignments, and calls to procedures and functions.
Structured Statements Structured statements are constructed from other statements. Use a structured statement when you want to execute other statements sequentially, conditionally, or repeatedly. Conditional statements if and case execute at most one of their constituents, depending on a specified criteria. Loop statements repeat, while, and for execute a sequence of constituent statements repeatedly.
49
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
DIRECTIVES
Directives are words of special significance for the mikroBasic, but unlike other reserved words, appear only in contexts where user-defined identifiers cannot occur. You cannot define an identifier that looks exactly like a directive.
Overview
Directive
Meaning
Absolute Org
specify exact location of variable in RAM specify exact location of routine in ROM
Absolute directive specifies the starting address in RAM for variable (if variable is multi-byte, higher bytes are stored at consecutive locations). Org directive specifies the starting address of routine in ROM. For PIC16 family, routine must fit in one page - otherwise, compiler will report an error. Directive absolute is appended to the declaration of variable:
dim rem as byte absolute $22 ' Variable will occupy 1 byte at address $22 dim dot as word absolute $23 ' Variable will occupy 2 bytes at addresses $23 and $24
50
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
m[0] Byte variable will occupy 1 byte at address $22 Word variable will occupy 2 bytes At addresses $23 and $24
Important
We recommend careful use of absolute directive, because you may overlap two variables by mistake. For example:
dim Ndot as byte absolute $33 ' Variable will occupy 1 byte at address $33 dim Nrem as longint absolute $30 ' Variable will occupy 4 bytes at $30, $31, $32, $33, ' so changing Ndot changes Nrem highest ' byte at the same time
Runtime Behavior
mikroBasic uses internal algorithm to distribute variables within RAM. If there is a need to have variable at specific predefined address, use the directive absolute. Also if, for some reason, you want to overlap existing variables, use the directive absolute.
Example
program lite
51
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Procedures
where procedureName is any valid identifier, statements is a sequence of statements that are executed upon the calling the procedure, and (parameterList) and localDeclarations are optional declaration of variables and/or constants.
sub procedure pr1_procedure(dim par1 as byte, dim par2 as byte, dim byref vp1 as byte, dim byref vp2 as byte) dim locS as byte par1 = locS + par1 + par2 vp1 = par1 or par2 vp2 = locS xor par1 end sub
par1 and par2 are passed to the procedure by the value, but variables marked by keyword byref are passed by the address.
52
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
passes tA and tB by the value: it first creates par1 = tA and par2 = tB, then manipulates par1 and par2 so that tA and tB remain unchanged; passes tC and tD by the address: whatever changes are made upon vp1 and vp2 are also made upon tC and tD. Note that a procedure without parameters can be substituted by label which marks the beginning of procedure and keyword return that marks the end of procedure. To call such subroutine, use the keyword gosub. These subroutines must be placed between the label main: and the end of the source file.
main: if PORTC.1 = 1 then gosub TogglePortb end if ...
Functions
Function declaration is similar to procedure declaration, except it has a specified return type and a return value. Function declaration has the form:
sub function functionName(parameterList) as returnType localDeclarations statements end sub
where functionName is any valid identifier, returnType is any simple type, statements is a sequence of statements to be executed upon calling the function, and (parameterList) and localDeclarations are optional declarations of variables and/or constants.
53
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
In mikroBasic, use the keyword Result to assign the return value of a function. Example:
sub function some_function(dim par1 as byte, dim par2 as word) as word dim locS as word locS = par1 + par2 Result = locS end sub
Function Calls
As functions return a value, function calls are technically expressions. For example, if you have defined a function called Calc, which collects two integer arguments and returns an integer, then the function call Calc(24, 47) is an integer expression. If I and J are integer variables, then I + Calc(J, 8) is also an integer expression. Here are a few examples of function calls:
Sum(tA,63) Maximum(147,J) GetValue
Important
Note that cross-calling and recursive calls are not allowed in mikroBasic. Crosscalling is an instance of procedure A calling procedure B, and then procedure B calling procedure A. Recursive call is an instance of procedure or function calling itself. Compiler will report error if cross-calling or recursive calls are encountered in the code. mikroBasic has a number of built-in and predefined library routines. For example, procedure interrupt is the interrupt service routine. Nested calls are limited to 8-level depth for PIC16 series and 31-level depth for PIC18 series. Nested call represent call of another function or procedure within a function or procedure. For closer information, refer to the chapter PIC Specifics.
54
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Procedure or Function
Nested procedures or functions calls are limited to 8 for PIC16 series, and to 31 for PIC18
Procedure or Function
Number of allowed nested calls will be decremented by 1 if you use interrupt procedure and 1 more if you use *, div, mod
Procedure or Function
Compiler will report stack overflow error if you exceed the allowed number of nested calls
Example
sub function mask(dim byref ' select case num ' case 0 result = $3F ' case 1 result = $06 case 2 result = $5B ' case 3 result = $4F case 4 result = $66 case 5 result = $6D case 6 result = $7D case 7 result = $07 case 8 result = $7F case 9 result = $6f ' end select end sub
num as byte) as byte This function returns code for digit for common cathode 7 seg. display.
Note that the value of result is not initialized for values greater than 9
case end
55
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
sub program Stack_overflow sub procedure interrupt nop end sub sub procedure proc0 nop end sub sub procedure proc1 proc0 end sub sub procedure proc2 proc1 end sub sub procedure proc3 proc2 end sub sub procedure proc4 proc3 end sub sub procedure proc5 proc4 end sub sub procedure proc6 proc5 end sub sub procedure proc7 proc6 end sub main: proc7 end.
56
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
MODULES
Each project consists of a single project file, and one or more module files. To build a project, the compiler needs either a source file or a compiled file for each module.
Project file
Module files
Every project consist of single project file and one or more module files
Each module is stored in its own file and compiled separately; compiled modules are linked to create an application. Modules allow you to: Break large programs into parts that can be edited separately. Create libraries that can be used in different programs. Distribute libraries to other developers without disclosing the source code.
In mikroBasic programming, all source code including the main program is stored in .pbas files. If you perform circular unit references, compiler will give a warning. A simple instance of circular unit references would be, for example, situation in which Module1 uses Module2, but in the same time it is specified that Module2 uses Module1. Newly created blank unit contains the following :
module Module1 end.
57
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
program Project1 include "additional.pbas" dim tA as word dim tB as word main: tA = sqrt(tb) end.
Keyword include instructs the compiler which file to compile. If you want to include a module, add the keyword include followed by the quoted name of the file. The example above includes the module additional.pbas in the program file.
58
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Project file
Module files
mikroBasic
1.
Once you have written your program, mikroBasic can compile each unit file and create mcl files
Compiler
mcl files Def file
2.
mikroBasic links mcl files and creates asm, list and hex files
Linker
HEX file
LST file
ASM file
3.
Finally, you can load hex file to programmer and program the device
Programmer
PIC MCU
59
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
PIC SFR (Special Function Registers) such as TMR0, PORTA, etc, are implicitly declared as global variables of byte type. Their scope is the entire project and they are visible in any part of the program or any module.
60
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
first line of the declaration is the function heading . B and K are local variables; their declarations apply only to the Com function block and override - in this routine only - any declarations of the same identifiers that may occur in the program module or at beginning of a module.
61
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
PROGRAM ORGANIZATION
Program elements (constants, variables and routines) need to be declared in their proper place in the code. Otherwise, compiler may not be able to comprehend the program correctly. Organization of the main unit should have the following form:
program program_name include ... symbol ... const ... dim ... sub procedure procedure_name ... end sub sub function function_name ... end sub main:
' program name ' include other units ' symbols declaration ' constants declaration ' variables declaration ' procedures declaration
' program must start with label ' main ' program body ' end of program
... end.
62
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
' unit name ' include other units ' symbols declaration ' constants declaration ' variables declaration ' procedures declaration
63
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
TYPE CONVERSION
mikroBasic is capable of both implicit and explicit conversion of data types. Implicit conversion is the one automatically performed by compiler. On the other hand, explicit conversion is performed only on demand issued by user. This means that you can, obeying a few rules, combine simple data types with any operators to create legal expressions and statements. Refer to Data Types if you are not familiar with data types supported by mikroBasic. As stated in the chapter about operators, you cannot mix signed and unsigned data types in expressions that contain arithmetic or logical operators. You can assign signed to unsigned or vice versa only using the explicit conversion.
Implicit Conversion
Implicit conversion takes place between byte and word, so you can combine byte and word with any operators to form legal expressions. Implicit conversion takes place between short, integer and longint so you can combine short, integer and longint with any operators to form legal expressions. Relation operators can be used without any restraints. Smart algorithm governing relation operators allows comparing any two data types. The compiler provides automatic type conversion when an assignment is performed, but does not allow to assign signed data type to unsigned and vice versa.
You can find more information on implicit conversion in chapters Assignment and Implicit Conversion, and Implicit Conversion and Legal Expressions.
Explicit Conversion
Explicit conversion can be executed at any point by inserting type (byte, word, short, integer, or longint) ahead of the expression to be converted. The expression must be enclosed in parentheses. You can't execute explicit conversion on the operand left of the assignment operator.
64
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Special case is conversion between signed and unsigned. It is important to understand that explicit conversion between signed and unsigned data does not change binary representation of data; it merely allows copying of source to destination.
Example 1:
dim tA as byte dim tB as byte dim tC as byte if tA + tB > tC then tA = 0 end if
This could be wrong, because there is an expression on the left. Compiler evaluates it, and treats it as a variable of type that matches type of tA or tB (the larger of the two); in this case - a byte.
tA = 250 tB = 10 tC = 20 if tA + tB > tC then tA = 0 end if
In this case, since the result of the expression is treated as byte, we get that 250 + 10 is lower than 20. Actually, the result of the expression is truncated to byte: 250 + 10 is 4, and 4 is lower than 20. But if we wrote it like this:
if word(tA + tB) > tC then tA = 0 end if
.it would be correct, because we have explicitly instructed the compiler to treat tA + tB as a word. Hence, the result will equal 260 and greater than 20, returning the expected result.
65
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Example 2:
Explicit conversion can also be used when you are sure which type you want to convert expression to. Consider the following lines:
dim dim dim dim dim tA tB tC A_ B_ as as as as as byte byte byte short short
It is important to understand that explicit conversion between signed and unsigned data does not change binary representation of data; it only allows copying source to destination. Thus, if A_ was -1, its binary representation would be 11111111, and A would become 255. Even if you have ordered the explicit conversion, compiler will perform implicit if necessary.
Example 3:
You cannot execute explicit conversion on the operand left of the assignment operator:
word(b) = Bb
66
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
mikroBasic provides automatic type conversion every time an assignment is performed. But it does not allow assigning signed data to unsigned and vice versa, because there is a significant risk of losing information. Implicit conversion takes place when assignment is performed: between byte and word between short, integer, and longint
Notes
Destination will store the correct value only if it can properly represent the result of expression (that is, if the result fits in destination range). Feel free to use operands of any size under the defined rules, but keep in mind that the PIC is optimized to work with bytes. Every operation involving more complex data types (word, integer or longint) will take more run time and more memory. So for the best possible results, use as small destinations and operands as you can.
Examples
A = B
If A and B are of the same type, value of B is simply assigned to A. More interesting case is if A and B are of different types:
dim dim ... B = A = A as byte B as word $ff0f B ' A becomes $0f, higher byte $ff is lost
67
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
In hex representation, this means that the higher byte is sign extended.
C = expression
Calculated value of the expression will be assigned to the destination. Part of the information may be lost if the destination cannot properly represent the result of the expression (i.e. if result can't fit in range of destination data type). Browse through examples for more details. For example (this is correct):
C = A + B
C is byte, so its range is 0 .. 255. If (A + B) fits in this range you will get the correct value in C.
A = 123 B = 90 C = A + B
But what happens when A + B exceeds the destination range? Let's assume the following:
A = 241 B = 128 C = A + B ' C becomes 113, obviously incorrect
68
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Lets see what happens when we add two bytes and assign result to byte
byte3
First byte has value 241 and its binary representation is 11110001
byte2
byte1
Second byte has value 128 and its binary representation is 10000000
1 1 1 1 0 0 0 1
+
1 0 0 0 0 0 0 0
=
1 0 1 1 1 0 0 0 1
Result has 9 bits. Because destination byte can hold only 8 bits, the most significant bit is lost
As byte3 holds 01110001, result is 113 instead of 369. Most significant bit is lost: (1)01110001
In order to fully understand this, we should recollect the data types. Data type determines not only the range of values variable can hold, but also the amount of RAM space it consumes. This is fundamental in practical programming. Let's assume that our destination variable C is a byte, consuming 8 bits of PIC RAM, spanning values 0 to 255. Now observe what really happens inside the PIC: the result should be 369, but in binary representation it equals (1)01110001. Because C is limited to 8 bits it will store the lower 8 bits while dropping the rest of the information (the most significant bit). 01110001 equals 113 in decimal representation.
dim dim dim testA as byte testB as byte Cc as word
main: testA = 250 testB = 10 Cc = testA + testB ' this will always be correct because ' range for Cc is 0..65535 and maximum result ' of adding two bytes is only 255 + 255 = 510 end.
69
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
As already stated, destination will store the correct value only if it can properly represent the result of the expression (that is, the result fits in destination range).
dim testA as byte dim testB as byte dim Cc as word dim Sa as short dim Sb as short dim Sc as short dim Saa as integer dim Sbbbb as longint main: testA = 250 testB = 10 ' Cc becomes 2510; Cc = testA * testB + testB Sb = 120 Sc = -100 ' Sa becomes 20; Sa = Sb + Sc Sa = Sb - Sc ' Sa is short with range -127..128, ' thus, instead of 220, ' Sa becomes -36, because only ' lower 8 bits are registered Saa = (Sb * Sc) div 13 ' Saa becomes -923 Sbbbb = integer(Sb * Sc) * Sc ' Sbbbb becomes 1200000 end.
70
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
To create legal expressions, you can: 1. combine byte and word with any operators, 2. combine short, integer, and longint (note that longint does not employ *, div, mod) with any operators, 3. use Relation operators
expression1 (relation operator) expression2
Expression1 and expression2 can be any legal expressions. Be sure to understand how implicit conversion works with relation operators.
Implicit Conversion and Relation Operators
Comparing variable or constant to variable or constant always produces correct results. Comparing expressions requires a little more attention.
expression1 (relation operator) expression2
Expressions can be any legal expressions created with arithmetical or logical operators. Every expression no matter how complex, can be decomposed to a number of simple expressions. Simple expression is expression composed of just one operator and its operands. Operator is logical or arithmetical. Examine the rules presented below.
Rules for Comparing Expressions
1. Complex expression is decomposed to a number of simple expressions, with respect to operator precedence and overriding parenthesis. 2. Simple expression is now treated in the following manner: if operands are of the same type, operation is performed, assuming that the result is of the same type. 3. If operands are not of the same type, then less complex operand (speaking in terms of data range) is extended:
71
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
If one operand is byte and another is word, byte is converted in word. If one operand is short and another is integer, short is converted to integer. If one operand is short and another is longint, short is converted to longint. If one operand is integer and another is longint, integer is converted to longint.
4. After the first expression is decomposed to simpler ones, each of these simpler ones is evaluated abiding the rules presented here. Expression a + b + c is decomposed like this: First evaluate a + b and get (value of a + b) This gives us another simple expression
(value of a + b) + c
Compiler first calculates value of a + b and assumes that the result is byte: a + b gives 57. As c is of word type, result of adding a + b is casted to word and then added to c: 57 + c is 1057.
Signed and unsigned numbers cannot be combined using arithmetical and logical operators. Rules presented above are not valid when assigning expression result to variable.
72
page
mikroBASIC
making it simple...
r = expression
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Refer to chapter Assignment and Implicit Conversion for details. When adding operands of the same type and assigning value to third operand, incorrect value may be proceeded if the result exceeds range of declared data type. Similar rules apply to other arithmetical operators. For example, if a and b are bytes, and cc is word:
a = 56 b = 200 cc = 1000
Note
a + b equals 1, because result type is assumed to be same as the operands' type (byte). Added to cc, we get 1001, instead of the expected 1256. Solution is to simply instruct the compiler to evaluate expression as you explicitly define. For example, you could explicitly cast the expression, like this:
word(a + b + c).
As result fits in word range, we get 1256 as expected. For more details, refer to chapter Explicit Conversion. Comparing variables and constants always produces the correct results regardless of the operands' type.
73
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Example
if A + B > A then
First, compiler evaluates the expression on the left. During runtime, result is stored in a variable of type that matches the largest data type in the expression. In this case it is byte, as variables A and B are both bytes. This is correct if the value does not exceed range 0..255, that is, if A + B is less than 255. Let's assume Aa is of word type :
if Aa + B > A ...
First, compiler evaluates the expression on the left. The result value is treated as type that matches the largest data type in the expression. Since Aa is word and B is byte, our result will be treated as word type. This is correct if the value does not exceed range 0..65535, i.e. if Aa + B is less than 65535.
' Stay in loop while C is not equal to variable ' compare_match; increment C in every cycle
while tC <> compare_match tC = tC + 1 wend
74
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
OPERATORS
There are three types of operators in mikroPascal: Arithmetic Operators Logical (Bitwise) Operators Relation Operators (Comparison Operators)
Operator Precedence
Operator not *, div, mod, and, shl, shr +, -, or, xor =, <>, <, >, <=, >= Priority first (highest) second third fourth (lowest)
In complex expressions, operators with higher precedence are evaluated before the operators with lower precedence; operators of equal precedence are evaluated according to their position in the expression starting from the left.
Example 1: B and T + A ' (bitwise and) B and T, then add A to the result; ' and is performed first, because it has precedence over +. Example 2: A - B + D ' first subtract B from A, then add D to the result; ' - and + have the equal precedence, thus the operation on ' the left is performed first. Example 3:
' You can use parentheses to override these precedence rules. ' An expression within parentheses is evaluated first, then ' treated as a single operand. For example:
(A + B) * D ' multiply D and the sum of A and B. A + B * D ' first multiply B and D and then add A to the product.
75
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
' But you can freely mix byte and word . . Bb = Bb + (teA * teA) ' . . and short with integer and longint; Scccc = Sbb * Sa + Scccc
You can assign signed to unsigned, or unsigned to signed only using the explicit conversion. More details can be found in chapter Implicit Conversion and Assignment Operator.
Sa = short(teA) ' this can be done Sa = teA ' this can't be done, compiler will report an error
Relation operators can be used with all data types, regardless of the sign. Example:
if Sa > teA then Sa = 0 end if
76
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Comparing variable or constant to variable or constant will always produce correct results. Comparing expressions requires a little more attention - when compiler is calculating value of the expression to be compared, it first has to evaluate the expression. If the result of the expression exceeds the range of the largest data type in the expression, comparison will most likely be inaccurate. This can be avoided by using the explicit conversion. More details can be found in chapter Implicit Conversion and Relation Operators.
Runtime Behavior
PIC MCUs are optimized for working with bytes. It takes less time to add two bytes than to add two words, naturally, and similar pattern is followed by all the other operators. It is a good practice to use byte or short data type whenever appropriate. Although the improvement may seem insignificant, it could prove valuable for applications which impose execution within time boundaries. This is a recommendation which shouldn't be followed too literally - word, integer and longint are indispensable in certain situations.
77
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Arithmetic Operators
Overview
Operand Types
Result Type
byte, short, integer, byte, short, integer, word, longint word, longint byte, short, integer, byte, short, integer, word, longint word, longint byte, short, integer, integer, word, word longint byte, short, integer, byte, short, integer, word word byte, short, integer, byte, short, integer, word word
A div B is the value of A divided by B rounded down to the nearest integer. The mod operator returns the remainder obtained by dividing its operands. In other
words,
X mod Y = X (X div Y) * Y.
If 0 (zero) is used explicitly as the second operand (i.e. X div 0), compiler will report an error and will not generate code. But in case of implicit division by zero: X div Y , where Y is 0 (zero), result will be the maximum value for the appropriate type (for example, if X and Y are words, the result will be $ffff). Destination will store the correct value only if it can properly represent the result of the expression (that is, if result fits in the destination range). More details can be found in chapter Assignment and Implicit Conversion. mikroBasic is more flexible compared to standard Basic as it allows both implicit and explicit type conversion. In mikroBasic, operator can take operands of different type; refer to chapter Type Conversion for more details. You cannot combine signed and unsigned data types in expressions with arithmetic operators.
Important
78
page
mikroBASIC
making it simple...
Unsigned and Conversion
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
If number is converted from less complex to more complex data type, upper bytes are filled with zeros. If number is converted from more complex to less complex data type, data is simply truncated (upper bytes are lost). If number is converted from less complex to more complex data type, upper bytes are filled with ones if sign bit equals 1 (number is negative). Upper bytes are filled with zeros if sign bit equals 0 (number is positive). If number is converted from more complex to less complex data type, data is simply truncated (upper bytes are lost).
Example
program extr dim dim dim dim dim Sa as short A as byte Bb as word Sbb as integer Scccc as longint
A = A + Sa ' compiler will report an error, ' mixing signed with unsigned; A = A - Sa ' compiler will report an error, ' mixing signed with unsigned;
79
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Result Types short, integer, longint short, integer, longint
Runtime Behavior
PIC microcontrollers are optimized to work with bytes. Refer to PIC MCU Specific.
80
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Boolean Operators
Boolean operators are not true operators, because there is no boolean data type defined in mikroBasic. These "operators" conform to standard Boolean logic. They cannot be used with any data type, but only to build complex conditional expression.
Operator not and or Operation negation conjunction disjunction
Example
if (astr > 10) and (astr < 20) then PORTB = 0xff end if
81
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Operand Types
Result Types byte, word, short, integer, long byte, word, short, integer, long byte, word, short, integer, long byte, word, short, integer, long byte, word, short, integer, long byte, word, short, integer, long
byte, word, short, integer, long byte, word, short, bitwise conjunction integer, long byte, word, short, bitwise disjunction integer, long byte, word, short, bitwise xor integer, long byte, word, short, bit shift left integer, long byte, word, short, bit shift right integer, long
<< : shift left the operand for a number of bit places specified in the right operand (must be positive and less then 255). >> : shift right the operand for a number of bit places specified in the right operand (must be positive and less then 255). For example, if you need to extract the higher byte, you can do it like this:
dim temp as word main: TRISA = word(temp >> 8) end.
Important
Destination will hold the correct value if it can properly represent the result of the expression (that is, if result fits in destination range). More details can be found in chapters Type Conversions and Assignment and implicit Conversion.
mikroBasic is more flexible compared to standard Basic as it allows both implicit and explicit type conversion. Note that you cannot mix signed and unsigned data types in expressions with logical operators.
82
page
mikroBASIC
making it simple...
Unsigned and Conversion
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
If number is converted from less complex to more complex data type, upper byte is filled with zeros; If number is converted from more complex to less complex data type, data is simply truncated (upper bytes are lost). Example for unsigned and logical operators :
dim dim teA as byte Bb as word
In this case, teA is treated as a word with upper byte equal to 0 prior to the operation.
If number is converted from less complex data type to more complex, upper bytes are filled with ones if sign bit is 1 (number is negative); upper bytes are filled with zeros if sign bit is 0 (number is positive). If number is converted from more complex data type to less complex, data is simply truncated (upper bytes are lost).
dim dim Sa as short Sbb as integer
In this case, Sa is treated as an integer with the upper byte equal to $FF (this in fact is sign extending of short to integer) prior to the operation.
83
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
In this case, Sa is treated as an integer with the upper byte equal to $00 (this in fact is sign extending of short to integer) prior to the operation.
Example
' The logical operators perform bitwise manipulation ' on the operands. For example, if the value stored in ' teA (in binary) is 00001111 and the value stored in ' teB is 10000001, the following statements..
main: teA = $0F teB = $81
' .. assign the value 00001111 to teA. ' .. assign the value 10000001 to teB.
teC = teA or teB ' Performs bitwise or with teA, teB and the ' result is assigned to teC (value 10001111) teC = not teA ' Performs bitwise not with teA and the ' result is assigned to teC (value 11110000) teC = teA << 4 ' shift teA to the left for a number of positions ' specified in the operand on the right; ' operand on the right must be positive. ' In this example teC becomes $F0 ' All bits shifted in are zeros. teC = teA >> 4 ' shift teA to the right for a number of positions ' specified in operand on the right; ' operand on the right must be positive. ' In this example C becomes $00.
' New bits shifted in are zeros if operand type is ' byte/word sign extended for short, word, integer. end.
84
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
' You cannot mix signed and unsigned data types in ' expressions with logical operators:
dim dim dim dim dim Sa as short teA as byte Bb as word Sbb as integer Scccc as longint
' compiler will report an error ' compiler will report an error
' But you can freely mix byte with word . . Bb = Bb and ( not teA) ' . . and short with integer and longint. Scccc = Sbb xor Sa or Scccc end.
Runtime Behavior
PIC microcontrollers are optimized to work with bytes. Refer to PIC MCU Specific.
85
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Operand Types All simple types All simple types All simple types All simple types
Result Types True or False True or False True or False True or False True or False True or False
Relation operators (Comparison Operators) are commonly used in conditional and loop statements to control the program flow. In general case: Expression1 (relation operator) Expression2, expression1 and expression2 can be any legal expression. Be familiar with how implicit conversion works with relations operators. You can compare signed and unsigned values.
1. Complex expression is decomposed to a number of simple expressions, with respect to operator precedence and overriding parenthesis. 2. Simple expression is now treated in the following manner: if operands are of the same type, operation is performed, assuming that the result is of the same type. 3. If operands are not of the same type, then less complex operand (speaking in terms of data range) is extended:
86
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
If one operand is byte and another is word, byte is converted in word. If one operand is short and another is integer, short is converted to integer. If one operand is short and another is longint, short is converted to longint. If one operand is integer and another is longint, integer is converted to longint. 4. After the first expression is decomposed to simpler ones, each of these is evaluated abiding the rules presented here.
Illustration
Expression a + b + c is decomposed like this: First evaluate a + b and get (value of a + b) This gives us another simple expression (value of a + b) + c Let's assume a and b are bytes and c is word, with values:
a = 23 b = 34 c = 1000
Compiler first calculates value of a + b and assumes that the result is byte: a + b gives 57. As c is of word type, result of adding a + b is casted to word and then added to c: 57 + c is 1057. Signed and unsigned numbers cannot be combined using arithmetical and logical operators. Rules presented above are not valid when assigning expression result to variable.
r = expression
87
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Examples
Comparing variables and constants always produces the correct results regardless of the operands' type.
if A > B then ... if A > 47 then ... if A + B > A ...
First, compiler evaluates the expression on the left. During the run-time, result is stored in a variable of type that matches the largest data type in the expression. In this case it is byte, as variables A and B are both bytes. This is correct if the value does not exceed range 0..255, that is, if A + B is less then 255. Let's assume Aa is of word type :
if Aa + B > A ...
First, compiler evaluates the expression on the left. The result value is treated as type that matches the largest data type in the expression. Since Aa is word and B is byte, our result will be treated as word type. This is correct if the value does not exceed range 0..65535, that is, if A + B is less then 65535.
' Stay in loop while C is not equal to variable ' compare_match; increment C in every cycle:
while tC <> compare_match tC = tC + 1 wend
88
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
CONDITIONAL STATEMENTS
Conditional statements control which part(s) of the program will be executed, depending on a specified criteria. There are two conditional statements in mikroBasic: SELECT CASE statement, IF statement. We suggest browsing the chapters Relation Operators and Implicit Conversion and Relation Operators, if you have not done so already.
program test dim jjj as byte main: ' some instructions ... goto myLabel ' some instructions... myLabel: ' some instructions... end.
89
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
where selector is any variable of simple type or expression, and each Values is a comma-delimited sequence of expressions. Case statement can have a final else clause:
select case Selector case Values_1 Statements_1 case Values_2 Statements_2 ... case Values_N Statements_n case else Statements_else end select
As soon as the case statement is executed, at most one of the statements statements_1 .. statements_n will be executed. The Values which matches the selector determines the statements to be executed. If none of the Value items matches the selector, then the statements_else in the else clause (if there is one) are executed.
page
90
mikroBASIC
making it simple...
Examples
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
select case message_flag case 0 opmode = 0 LCD_Out(1, 1, "Test Message 0") case 1, 2, 3, 4 opmode = 1 LCD_Out(1, 1, "Test Message 1") case 5, 6, 7 opmode = 2 LCD_Out(1, 1, "Test Message 2") end select
In case there are multiple matches, the first matching block will be executed. For example, if state2 equals -1, msg will be OK, not Error:
select case state case 0, state0, state1, state2 msg = "OK" case -1, state0 or errorFlag, state1 or errorFlag msg = "Error" case else msg = "No input" end select
91
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
If Statement
There are two forms of if statement: Syntax of if..then statement is:
if expression then statements end if
where expression returns a True or False value. If expression is True, then statement is executed, otherwise it's not. Syntax of if..then..else statement is:
if expression then statements1 else statements2 end if
where expression returns a True or False value. If expression is True, then statements1 are executed; otherwise statements2 are executed. Statements1 and statements2 can be statements of any type. Nested if statements require additional attention. General rule is that the nested conditionals are parsed starting from the innermost conditional, with each else bound to the nearest available if on its left.
if expression1 then if expression2 then statements1 else statements2 end if end if
Nested IF
92
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
To force the compiler to interpret our example the other way around, we would have to write it explicitly:
if expression1 then if expression2 then statement1 end if else statement2 end if
Examples
if J <> 0 then Res = I div J end if if j <> 0 then i = i + 1 j = 0 end if ... if v = 0 then portb = por2 porta = 1 v = 1 else portb = por1 porta = 2 v = 0 end if
93
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
LOOPS
Loops are a specific way to control the program flow. By using loops, you can execute a sequence of statements repeatedly, with a control condition or variable to determine when the execution stops. You can use the standard break and continue to control the flow of a do..loop until, while, or for statement. Break terminates the statement in which it occurs, while continue begins executing the next iteration of the sequence. mikroBasic has three kinds of control loop instructions: DO..LOOP UNTIL statement WHILE statement FOR statement
Runtime Behavior
Note that certain operations may take longer time to be executed, which can lead to undesired consequences. If you add two variables of short type and assign the result to short, it will be faster than to add two longint and assign value to longint, naturally. Take a look at the following code :
dim dim dim dim Sa as Sb as Saaaa Sbbbb short short as longint as longint
for Sa = 0 to 100 Sb = Sb + 2 next Sa for Saaaa = 0 to 100 Sbbbb = Sbbbb + 2 next Saaaa end.
94
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
For Statement
For statement requires you to specify the number of iterations you want the loop to go through. Syntax of for statement is:
for counter = initialValue to finalValue [step step_value] statement_1 statement_2 ... statement_N next counter
where counter is variable; initialValue and finalValue are expressions compatible with counter; statement_X is any statement that does not change the value of counter; step_value is value that is added to the counter in each iteration. Step_value is optional, and defaults to 1 if not stated otherwise. Be careful when using large values for step_value, as overflow may occur. Every statement between for and next will be executed once for each iteration.
Endless Loop
will result in an an endless loop if finalValue is greater than, or equal to maximum value of counter data type. For example, this will be an endless loop, if counter is of byte type:
for counter = 0 to 255 nop next counter
' or
for counter = 0 to 500 nop next counter
95
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Example
Here is a simple example of a for loop used for emitting hex code on PORTB. Nine digits will be printed with one second delay, by incrementing the counter.
96
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
where expression returns a True or False value. Do..loop statement executes statement_1 ... statement_N continually, checking the expression after each iteration. Eventually, when expression returns True, do..loop statement terminates. The sequence is executed at least once because the check takes place in the end.
Example
97
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
While Statement
Syntax of while statement is:
while expression statement_0 statement_1 ... statement_N wend
Expression is tested first. If it returns True, all the following statements enclosed by while and wend will be executed. It will keep on executing statements until the expression returns False. Eventually, as expression returns False, while will be terminated without executing statements.
While is similar to do..loop until, except the check is performed at the
beginning of the loop. If expression returns False upon first test, statements will not be executed.
Example
98
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
ASM Statement
Sometimes it can be useful to write part of the program in assembly. ASM statement allows you to embed PIC assembly instructions into Basic code. Note that you cannot use numerals as absolute addresses for SFR or GPR variables in assembly instructions. You may use symbolic names instead (listing will display these names as well as addresses). Also, you cannot use Labels in assembly; instead, you can use relative jumps such as goto $-1. Declaration of asm statement is:
asm statementList end asm
where statementList is a sequence of assembly instructions. Be careful when embedding assembly code - mikroBasic will not check if assembly instruction changed memory locations already used by Basic variables. Also, you cannot write comments in assembly.
Example
' second instruction is incorrect, see above asm MOVLW 0 MOVWF $5 MOVWF PORTA end asm ' note that you cannot write comments in assembly
99
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
where i and A are variables of byte type, and ii and Aa are variables of word type. First loop will be executed considerably faster. Although memory management is completely under the compiler's control, you can explicitly assign address to variable by means of directive absolute. See Directives for more information. NOTE : Be aware that nested function and procedure calls have limited depth - 8 for PIC16 series and 31 for PIC18 series.
100
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
mikroBASIC SPECIFIC
mikroBasic compiler was designed with reliability and comfort in mind. Thus, certain modifications of standard Basic were necessary in order to make the compiler more PIC MCU compatible. PIC SFR (Special Function Registers) are implicitly declared as global variables of byte type. Their scope is the entire project - they are visible in any part of the program or any unit. Memory management is completely under compiler's control, so there is no need to worry about PIC memory banks and storing the variables. Accessing to individual bits of SFR (as accessing to bit of any variable of byte type) is very simple. Use identifier followed by dot, and a pin:
Identifier.PIN
For example:
sub procedure check ifPORTB.1 = 1 then counter = counter + 1 else INTCON.GIE = 0 end if end sub
Interrupts can be easily handled in mikroBasic by means of predefined procedure interrupt. All you need to do is include the complete procedure definition in your program. mikroBasic saves the following SFR when entering interrupt: PIC12 and PIC16 series: W, STATUS, FSR, PCLATH; PIC18 series: FSR (fast context is used to save WREG, STATUS, BSR). Upon return from interrupt routine, these registers are restored. NOTE: For PIC18 family, interrupts must be of high priority. mikroBasic does not support low priority interrupts.
101
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
For example, when handling the interrupts from TMR0 (if no other interrupts are allowed):
sub procedure interrupt counter = counter + 1 TMR0 = 96 INTCON = $20 end sub
In case of multiple interrupts enabled, you must test which of the interrupts occurred and then proceed with the appropriate code (interrupt handling):
sub procedure interrupt if INTCON.TMR0IF = 1 then counter = counter + 1 TMR0 = 96 INTCON.TMR0IF = 0 else if INTCON.RBIF = 1 then counter = counter + 1 TMR0 = 96 INTCON.RBIF = 0 end if end if end sub
See also: Built-in Functions and Procedures Library Functions and Procedures
102
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Type of Error _SYNTAX_ERROR _NOT_VALID_IDENT _INVALID_STATEMENT _STACK_OVERFLOW _INVALID_OPERATOR _IF_ELSE_ERROR _VARIABLE_EXPECTED _CONSTANT_EXPECTED _ASSIGNMENT_EXPECTED _BREAK_ERROR _UNKNOWN_TYPE _VARIABLE_REDECLARED _VARIABLE_NOT_DECLARED _MAX_LINE_NUMBER_EXCEEDED _ALREADY_DECLARED // for proc and func _TOO_MANY_PARAMS _NOT_ENOUGH_PARAMS _TYPE_MISMATCH _FILE_NOT_FOUND _NOT_ENOUGH_RAM _USES_IN_BETA_V _INTERNAL_ERROR _NOT_ENOUGH_ROM _INVALID_ARRAY_TYPE _BAUD_TOO_HIGH _DIVISION_BY_ZERO _INCOMPATIBLE_TYPES _TOO_MANY_CHARACTERS _OUT_OF_RANGE _USES_POSITION _INVALID_ASM_COMMAND _OPERATOR_NOT_APPLICABLE _EXPRESSION_BY_ADDRESS _IDENTIFIER_EXPECTED _MOVING_ARRAYS
Error No. 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 page
103
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Error No. 200 201 202 203 204
Warning Messages
Hint Messages
104
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
105
page
CHAPTER
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
BUILT-IN ROUTINES
mikroBasic compiler incorporates a set of built-in functions and procedures. They are provided to make writing programs faster and easier. You can call built-in functions and procedures in any part of the program.
Routines
sub procedure SetBit(dim byref REG as byte, dim BIT as byte) sub procedure ClearBit(dim byref REG as byte, dim BIT as byte) sub function TestBit(dim byref REG as byte, dim BIT as byte) as byte sub sub sub sub function function function function Lo(dim arg as byte..longint) Hi(dim arg as word..longint) Higher(dim arg as longint) Highest(dim arg as longint) as as as as byte byte byte byte
sub procedure Inc(byref arg as byte..longint) sub procedure Dec(byref arg as byte..longint) sub procedure Delay_us(const COUNT as word) sub procedure Delay_ms(const COUNT as word) sub procedure Delay_Cyc(dim Cycles_div_by_10 as byte) sub function Length(dim text as string) as byte
Routines SetBit, ClearBit and TestBit are used for bit manipulation. Any SFR (Special Function Register) or variable of byte type can pass as valid variable parameter, but constants should be in range [0..7]. Routines Lo, Hi, Higher and Highest extract one byte from the specified parameter. Check the examples for details. Routines Inc and Dec increment and decrement their argument respectively Routines Delay_us and Delay_ms create a software delay in duration of COUNT microseconds or milliseconds, respectively. Routine Delay_Cyc creates a delay based on MCU clock. Delay lasts for (10 times the input parameter) in MCU cycles. Input parameter needs to be in range 3 .. 255. Function Length returns string length.
107
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Examples
SetBit(PORTB,2) ' set PORTB bit RB2 to value 1 ClearBit(PORTC,7) ' clear PORTC bit RC7 TestBit(PORTA,2) ' returns 1 if PORTA bit RA2 is 1, and 0 if RA2 is 0
Lo(A) ' returns lower byte of variable A ' byte 0, assuming that word/integer comprises bytes 1 and 0, ' and longint comprises bytes 3, 2, 1, and 0 Hi(Aa) ' returns higher byte of variable Aa ' byte 1, assuming that word/integer comprises bytes 1 and 0, ' and longint comprises bytes 3, 2, 1, and 0 Higher(Aaaa) ' returns byte next to the highest byte of variable Aaaa ' byte 2, assuming that longint comprises bytes 3, 2, 1, 0 Highest(Aaaa) ' returns the highest byte of variable Aaaa ' byte 3, assuming that longint comprises bytes 3, 2, 1, 0
Inc(Aaaa) ' increments variable Aaaa by 1 Dec(Aaaa) ' decrements variable Aaaa by 1
Delay_us(100) ' creates software delay equal to 100 microseconds. Delay_ms(1000) ' creates software delay equal to 1000 milliseconds = 1s. Delay_Cyc(100) ' creates delay equal to 1000 MCU cycles. Length(Text) ' returns string length as byte
108
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
LIBRARY ROUTINES
Library procedures and functions represent a set of routines. This collection of functions and procedures is provided for simplifying the initialization and use of PIC MCU and its hardware modules (ADC, I2C, USART, SPI, PWM), driver for LCD, drivers for internal and external CAN modules, flexible 485 protocol, numeric formatting routines... Currently included libraries: 1wire ADC CAN CANSPI Compact Flash Flash Memory EEPROM I2C LCD (4-bit interface) LCD8 (8-bit interface) Graphic LCD PWM RS485 SPI USART Software I2C Software SPI Software UART Sound Manchester Code Numeric Formatting Routines Utilities
109
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
1-Wire Library
1-wire library provides routines for communicating via 1-wire bus, for example with DS1820 digital thermometer. Note that oscillator frequency Fosc needs to be at least 4MHz in order to use the routines with Dallas digital thermometers.
Routines
function OW_Reset(dim byref PORT as byte, dim PIN as byte) as byte function OW_Read(dim byref PORT as byte, dim PIN as byte) as byte procedure OW_Write(dim byref PORT as byte, dim PIN, par as byte)
function
Issues 1-wire reset signal for DS1820. Parameters PORT and pin specify the location of DS1820; return value of the function is 0 if DS1820 is present, and 1 if it is not present.
function
Example
The following code demonstrates use of 1-wire library procedures and functions. The example reads the temperature using DS1820 connected to PORTA, pin 5. Be sure to set the Fosc appropriately in your project.
110
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
program onewire_test dim dim dim dim dim dim i j1 j2 por1 por2 text as as as as as as byte byte byte byte byte char[20]
main: text = "Temperature:" PORTB = 0 PORTA = 255 TRISB = 0 TRISA = 255 LCD_Init(PORTB) LCD_Cmd(LCD_CURSOR_OFF) LCD_Out(1, 1, text) do OW_Reset(PORTA,5) OW_Write(PORTA,5,$CC) OW_Write(PORTA,5,$44) Delay_ms(120) i = OW_Reset(PORTA,5) OW_Write(PORTA,5,$CC) OW_Write(PORTA,5,$BE) Delay_ms(1000) j1 = OW_Read(PORTA,5) j2 = OW_Read(PORTA,5) j1 = j1 >> 1 ByteToStr(j1, text) LCD_Out(2, 8, text) LCD_Chr(2, 10, 223) LCD_Chr(2, 11,"C") Delay_ms(500) loop until false end.
' 1-wire reset signal ' issue command to DS1820 ' issue command to DS1820
' issue command to DS1820 ' issue command to DS1820 ' ' ' ' ' ' get result get result assuming the temp. >= 0C convert j1 to text print text degree character ()
111
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
+5V
10K
PIC16F877A
MCLR/Vpp/THV RB7/PGD RA0/AN0 RA1/AN1 RA2/AN2/VrefRA3/AN3/Vref+ RA4/TOCKI RA5/AN4 RE0/RD/AN5 RE1/WR/AN6 RE2/CS/AN7 Vdd Vss OSC1 OSC2 RCO/T1OSO RB6/PGC RB5 RB4 RB3/PGM RB2 RB1 RB0/INT Vdd Vss RD7/PSP7 RD6/PSP6 RD5/PSP5 RD4/PSP4 RC7/RX/DT RC6/TX/CK RC5 RC4 RD3/PSP3 RD2/PSP2
Reset
+5V
+125
DS1820
+5V
D7 D6 D5 D4
Vdd DQ GND
-55
4MHz
E RS
4K7
+5V
LCD contrast
1
Vss Vdd Vee RS R/W E D0 D1 D2 D3 D4 D5 D6 D7
m i k ro el E kt ron i ka
112
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
ADC Library
ADC (Analog to Digital Converter) module is available with a number of PIC MCU models. Library function ADC_read is included to provide you comfortable work with the module. The function is currently unsupported by the following PIC MCU models: P18F2331, P18F2431, P18F4331, and P18F4431.
Routines
You can use the library function to initialize internal AD converter, select channel, and get the result of conversion:
sub function ADC_Read(dim Channel as byte) as word
It initializes ADC module to work with RC clock. Clock determines the time period necessary for performing AD conversion (min 12 Tad). RC sources typically have Tad 4uS (A/D conversion time per bit). Parameter Channel determines which channel will be sampled. Refer to the device data sheet for information on device channels.
Important
Before using the function above, be sure to configure the appropriate TRISA bits to designate the pins as input. Also, configure the desired pin as analog input, and set Vref (voltage reference value).
Example
The following code demonstrates use of library function ADC_read. Example reads Channel 2 and stores value in variable temp_res.
113
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
program ADC_Test dim temp_res as word main: ' configure analog inputs and Vref ADCON1 = $80 TRISA = $FF ' PORTA is input TRISB = $3F ' pins RB7, RB6 are output TRISD = $0 ' PORTD is output while true temp_res = ADC_read(2) ' now you can use temp_res ... PORTD = temp_res ' send lower 8 bits to PORTD PORTB = word(temp_res >> 2) ' send two most significant bits to PORTB wend end.
+5V +5V
PIC16F877A
330R
MCLR/Vpp/THV RB7/PGD RA0/AN0 RA1/AN1 RA2/AN2/VrefRA3/AN3/Vref+ RA4/TOCKI RA5/AN4 RB6/PGC RB5 RB4 RB3/PGM RB2 RB1 RB0/INT Vdd Vss RD7/PSP7 RD6/PSP6 RD5/PSP5 RD4/PSP4 RC7/RX/DT RC6/TX/CK RC5 RC4 RD3/PSP3 RD2/PSP2
LB7
10K
330R
LB6
330R
LD7
Reset
RE0/RD/AN5
+5V
RE1/WR/AN6 RE2/CS/AN7 Vdd Vss OSC1 OSC2 RCO/T1OSO RC1/T1OSI RC2/CCP1 RC3 RD0/PSP0 RD1/PSP1
330R
LD6
330R
LD5
330R
LD4
330R
LD3
4MHz
330R
LD2
330R
LD1
330R
LD0
114
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
CAN Library
CAN (Controller Area Network) module is available with a number of PIC MCU models. mikroBasic includes a set of library routines to provide you comfortable work with the module. CAN routines are currently supported by PIC MCU models P18XXX8. Microcontroller must be connected to CAN tranceiver (MCP2551 or similar) which is connected to CAN bus. The Controller Area Network module is a serial interface, useful for communicating with other peripherals or microcontrollers. Details about CAN can be found in appropriate literature and on mikroElektronika Web site. Following routines can be considered a driver for CAN module on PIC MCUs.
sub procedure CANSetOperationMode(dim mode as byte, dim WAIT as byte) sub function CANGetOperationMode as byte
sub procedure CANInitialize(dim SJW as byte, dim BRP as byte, dim PHSEG1 as byte, dim PHSEG2 as byte, dim PROPSEG as byte,dim CAN_CONFIG_FLAGS as byte) sub procedure CANSetBaudRate(dim SJW as byte, dim BRP as byte, dim PHSEG1 as byte, dim PHSEG2 as byte, dim PROPSEG as byte,dim CAN_CONFIG_FLAGS as byte) sub procedure CANSetMask(dim CAN_MASK as byte, dim val as longint, dim CAN_CONFIG_FLAGS as byte) sub procedure CANSetFilter(dim CAN_FILTER as byte, dim val as longint, dim CAN_CONFIG_FLAGS as byte) sub function RegsToCANID(dim byref ptr as byte, dim CAN_CONFIG_FLAGS as byte) as longint
sub procedure CANIDToRegs(dim byref ptr as byte, dim val as longint, dim CAN_CONFIG_FLAGS as byte) sub function CANwrite(dim id as longint, dim byref Data as byte[8], dim DataLen as byte, dim CAN_TX_MSG_FLAGS as byte) as byte CANread(dim byref id as longint, dim byref Data as byte[8], dim byref DataLen as byte, dim byref CAN_RX_MSG_FLAGS as byte) as byte
sub function
115
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
CANSetOperationMode
Prototype: Parameters:
sub procedure CANSetOperationMode(dim mode as byte, dim WAIT as byte)
mode - Operation mode code can take any of predefined constant values (see the constants below) WAIT - Should have value TRUE(255) or FALSE(0) CAN is set to requested mode Given mode byte is copied to CANSTAT If WAIT is true, this is a blocking call. It won't return until requested mode is set. If WAIT is false, this is a non-blocking call. It does not verify if CAN module is switched to requested mode or not. Caller must use CANGetOperationMode() to verify correct operation mode before performing mode specific operation.
CANGetOperationMode
Prototype: Parameters: Output:
sub function CANGetOperationMode as byte
116
page
mikroBASIC
making it simple... CANInitialize
Prototype:
sub procedure CANInitialize(dim SJW as byte, dim BRP as byte, dim PHSEG1 as byte, dim PHSEG2 as byte, dim PROPSEG as byte,dim CAN_CONFIG_FLAGS as byte) mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Precondition: Parameters:
CAN must be in Configuration mode or else these values will be ignored. SJW value as defined in 18XXX8 datasheet (must be between 1 thru 4) BRP value as defined in 18XXX8 datasheet (must be between 1 thru 64) PHSEG1 value as defined in 18XXX8 datasheet (must be between 1 thru 8) PHSEG2 value as defined in 18XXX8 datasheet (must be between 1 thru 8) PROPSEG value as defined in 18XXX8 datasheet (must be between 1 thru 8) CAN_CONFIG_FLAGS value is formed from constants (see below) CAN bit rate is set. All masks registers are set to '0' to allow all messages. Filter registers are set according to flag value:
If (CAN_CONFIG_FLAGS and CAN_CONFIG_VALID_XTD_MSG) <> 0 Set all filters to XTD_MSG Else if (config and CONFIG_VALID_STD_MSG) <> 0 Set all filters to STD_MSG Else Set half of the filters to STD, and the rest to XTD_MSG.
Effects:
Side Effects:
117
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
CANSetBaudRate
Prototype:
sub procedure CANSetBaudRate(dim SJW as byte, dim BRP as byte, dim PHSEG1 as byte,dim PHSEG2 as byte,dim PROPSEG as byte,dim CAN_CONFIG_FLAGS as byte)
Precondition: Parameters:
CAN must be in Configuration mode or else these values will be ignored. SJW value as defined in 18XXX8 datasheet (must be between 1 thru 4) BRP value as defined in 18XXX8 datasheet (must be between 1 thru 64) PHSEG1 value as defined in 18XXX8 datasheet (must be between 1 thru 8) PHSEG2 value as defined in 18XXX8 datasheet (must be between 1 thru 8) PROPSEG value as defined in 18XXX8 datasheet (must be between 1 thru 8) CAN_CONFIG_FLAGS - Value formed from constants (see section below) CAN bit rate is set as per given values. Given values are bit adjusted to fit in 18XXX8. BRGCONx registers and copied.
Effects: Overview:
CANSetMask
Prototype:
sub procedure CANSetMask(dim CAN_MASK as byte, dim val as longint, dim CAN_CONFIG_FLAGS as byte)
Precondition: Parameters:
CAN must be in Configuration mode. If not, all values will be ignored. CAN_MASK - One of predefined constant value val - Actual mask register value. CAN_CONFIG_FLAGS - Type of message to filter, either CAN_CONFIG_XTD_MSG or CAN_CONFIG_STD_MSG Given value is bit adjusted to appropriate buffer mask registers.
Effects:
118
page
mikroBASIC
making it simple... CANSetFilter
Prototype:
sub procedure CANSetFilter(dim CAN_FILTER as byte, dim val as longint, dim CAN_CONFIG_FLAGS as byte) mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Precondition: Parameters:
CAN must be in Configuration mode. If not, all values will be ignored. CAN_FILTER - One of predefined constant values val - Actual filter register value. CAN_CONFIG_FLAGS - Type of message to filter, either CAN_CONFIG_XTD_MSG or CAN_CONFIG_STD_MSG Given value is bit adjusted to appropriate buffer filter registers.
Effects:
Effects:
These two routines are used by other routines (internal purpose only)
119
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
CANWrite
Prototype:
sub function CANwrite(dim id as longint, dim byref Data as byte[8], dim DataLen as byte, dim CAN_TX_MSG_FLAGS as byte) as byte
Precondition: Parameters:
CAN must be in Normal mode. id - CAN message identifier. Only 11 or 29 bits may be used depending on message type (standard or extended). Data - array of bytes up to 8 bytes in length DataLen - Data length from 1 thru 8. CAN_TX_MSG_FLAGS - Value formed from constants (see section below) If at least one empty transmit buffer is found, given message is queued for the transmission. If none found, FALSE value is returned.
Effects:
CANRead
Prototype:
sub function CANread(dim byref id as longint, dim byref Data as byte[8], dim byref DataLen as byte, dim byref CAN_RX_MSG_FLAGS as byte) as byte
Precondition: Parameters:
CAN must be in mode in which receiving is possible. id - CAN message identifier Data - array of bytes up to 8 bytes in length DataLen - Data length from 1 thru 8. CAN_TX_MSG_FLAGS - Value formed from constants (see below) If at least one full receive buffer is found, it is extracted and returned. If none found, FALSE value is returned.
Effects:
120
page
mikroBASIC
making it simple... CAN Library Constants You need to be familiar with constants that are provided for use with CAN library routines. See how to form values (from constants) that will be passed to or from routines in the example at the end of the chapter. All of the constants are predefined in CAN library.
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
CAN_OP_MODE
These constant values define CAN module operation mode. CANSetOperationMode() routine requires this code. These values must be used by itself, i.e. they cannot be ANDed to form multiple values.
const const const const const const CAN_MODE_BITS CAN_MODE_NORMAL CAN_MODE_SLEEP CAN_MODE_LOOP CAN_MODE_LISTEN CAN_MODE_CONFIG = = = = = = $E0 0 $20 $40 $60 $80
CAN_TX_MSG_FLAGS
These constant values define flags related to transmission of a CAN message. There could be more than one this flag ANDed together to form multiple flags.
const const const const const CAN_TX_PRIORITY_BITS CAN_TX_PRIORITY_0 = CAN_TX_PRIORITY_1 = CAN_TX_PRIORITY_2 = CAN_TX_PRIORITY_3 = = $03 $FC $FD $FE $FF
const CAN_TX_FRAME_BIT = $08 const CAN_TX_STD_FRAME = $FF const CAN_TX_XTD_FRAME = $F7 const CAN_TX_RTR_BIT = $40 const CAN_TX_NO_RTR_FRAME = $FF const CAN_TX_RTR_FRAME = $BF
121
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
CAN_RX_MSG_FLAGS
These constant values define flags related to reception of a CAN message. There could be more than one this flag ANDed together to form multiple flags. If a particular bit is set; corresponding meaning is TRUE or else it will be FALSE. e.g.
if (MsgFlag and CAN_RX_OVERFLOW) <> 0 then
' Receiver overflow has occurred. ' We have lost our previous message. ...
const const const const const const const const const const const const CAN_RX_FILTER_BITS = $07 CAN_RX_FILTER_1 = $00 CAN_RX_FILTER_2 = $01 CAN_RX_FILTER_3 = $02 CAN_RX_FILTER_4 = $03 CAN_RX_FILTER_5 = $04 CAN_RX_FILTER_6 = $05 CAN_RX_OVERFLOW = $08 CAN_RX_INVALID_MSG = $10 CAN_RX_XTD_FRAME = $20 CAN_RX_RTR_FRAME = $40 CAN_RX_DBL_BUFFERED = $80
Set if Overflowed else cleared Set if invalid else cleared Set if XTD message else cleared Set if RTR message else cleared Set if this message was hardware double-buffered
CAN_MASK
These constant values define mask codes. Routine CANSetMask() requires this code as one of its arguments. These enumerations must be used by itself i.e. it cannot be ANDed to form multiple values.
const CAN_MASK_B1 = 0 const CAN_MASK_B2 = 1
122
page
mikroBASIC
making it simple...
CAN_FILTER
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
These constant values define filter codes. Routine CANSetFilter() requires this code as one of its arguments. These enumerations must be used by itself i.e. it cannot be ANDed to form multiple values.
const const const const const const CAN_FILTER_B1_F1 CAN_FILTER_B1_F2 CAN_FILTER_B2_F1 CAN_FILTER_B2_F2 CAN_FILTER_B2_F3 CAN_FILTER_B2_F4 = = = = = = 0 1 2 3 4 5
CAN_CONFIG_FLAGS
These constant values define flags related to configuring CAN module. Routines CANInitialize() and CANSetBaudRate() use these codes. One or more these values may be ANDed to form multiple flags.
const CAN_CONFIG_DEFAULT = $FF const CAN_CONFIG_PHSEG2_PRG_BIT = $01 const CAN_CONFIG_PHSEG2_PRG_ON = $FF const CAN_CONFIG_PHSEG2_PRG_OFF = $FE const CAN_CONFIG_LINE_FILTER_BIT = $02 const CAN_CONFIG_LINE_FILTER_ON = $FF const CAN_CONFIG_LINE_FILTER_OFF = $FD const CAN_CONFIG_SAMPLE_BIT = $04 const CAN_CONFIG_SAMPLE_ONCE = $FF const CAN_CONFIG_SAMPLE_THRICE = $FB const CAN_CONFIG_MSG_TYPE_BIT = $08 const CAN_CONFIG_STD_MSG = $FF const CAN_CONFIG_XTD_MSG = $F7 const CAN_CONFIG_DBL_BUFFER_BIT = $10 const CAN_CONFIG_DBL_BUFFER_ON = $FF const CAN_CONFIG_DBL_BUFFER_OFF = $EF const const const const const CAN_CONFIG_MSG_BITS = $60 CAN_CONFIG_ALL_MSG = $FF CAN_CONFIG_VALID_XTD_MSG = $DF CAN_CONFIG_VALID_STD_MSG = $BF CAN_CONFIG_ALL_VALID_MSG = $9F
' 11111111
123
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Example
sub function TestTaster as byte result = true if Button(PORTB, 0, 1, 0) then oldstate = 255 end if if oldstate and Button(PORTB, 0, 1, 1) then result = false oldstate = 0 end if end sub main: TRISB.0 PORTC = TRISC = PORTD = TRISD = aa = aa1 = aa2 = aa1 =
= 1 0 0 0 0 0 0 0
CAN_TX_PRIORITY_0 and CAN_TX_XTD_FRAME and CAN_TX_NO_RTR_FRAME CAN_CONFIG_SAMPLE_THRICE and CAN_CONFIG_PHSEG2_PRG_ON and CAN_CONFIG_STD_MSG and CAN_CONFIG_DBL_BUFFER_ON and CAN_CONFIG_VALID_XTD_MSG and CAN_CONFIG_LINE_FILTER_OFF
aa =
' continues..
124
page
mikroBASIC
making it simple...
' ..continued
cont = true while cont cont = TestTaster wend
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
' upon signal change on RB0 pin ' from logical 0 to 1 ' proceed with program ' execution
CANSetMask(CAN_MASK_B1,ID,CAN_CONFIG_XTD_MSG) ' set all mask1 bits to ones CANSetMask(CAN_MASK_B2,ID,CAN_CONFIG_XTD_MSG) ' set all mask2 bits to ones CANSetFilter(CAN_FILTER_B1_F1,3,CAN_CONFIG_XTD_MSG) ' set id of filter B1_F1 to 3 CANSetOperationMode(CAN_MODE_NORMAL,TRUE) ' set NORMAL mode portd = $FF id = 12111 CANWrite(id,data,1,aa1)
while true oldstate = 0 zr = CANRead(id , Data , lenn, aa2) if (id = 3) and zr then portd = $AA ' output data at portC portc = data[0] data[0] = data[0]+1 id = 12111 ' send incremented data back CANWrite(id,data,1,aa1) if lenn = 2 then ' if msg contains two data bytes portd = data[1] ' output second byte at portd end if end if wend end.
125
page
10K
RA1/AN1 RB5/PGM RB4 RB3/CANRX RB2/CANTX/INT2 RB1/INT1 RB0/INT0 Vdd Vss RA2/AN2/VrefRA3/AN3/Vref+ RA4/TOCKI RA5/AN4/SS/LVDIN RE0/AN5/RD/ RE1/AN6/WR/C1OUT RE2/AN7/CS/C2OUT
10K
Reset
Reset
RD6/PSP6/P1C
10R
RD1/PSP1/C1INRD2/PSP2/C2IN+
10R
126
PIC18F458
+5V
MCLR/Vpp RB7/PGD RB6/PGC RA0/AN0/Cvref MCLR/Vpp RA0/AN0/Cvref RA1/AN1 RA2/AN2/VrefRA3/AN3/Vref+ RA4/TOCKI RA5/AN4/SS/LVDIN RB7/PGD RB6/PGC RB5/PGM RB4 RB3/CANRX RB2/CANTX/INT2 RB1/INT1 RE0/AN5/RD/ RB0/INT0
page
PIC18F458
+5V +5V
RE1/AN6/WR/C1OUT RE2/AN7/CS/C2OUT Vdd Vss OSC1/CLKI OSC2/CLKO/RA6 RC0/T1OSO/T1CKI Vdd Vss RD7/PSP7/P1D RD6/PSP6/P1C RD5/PSP5/P1B
RD4/PSP4/ ECCP1/P1A
+5V
+5V
Vdd RD7/PSP7/P1D
OSC2/CLKO/RA6 RC0/T1OSO/T1CKI RC1/T1OSI RC2/CCP1 RC3/SCK/SCL RD0/PSP0/C1IN+ RD3/PSP3/C2INRC4/SDI/SDA RC5/SDO RC6/TX/CK RC7/RX/DT
PCA82C250 or MCP2551
+5V
PCA82C250 or MCP2551
mikroBASIC
making it simple...
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
CANSPI Library
SPI (Serial Peripheral Interface) module is available with a number of PIC MCU models. Set of library procedures and functions is listed below to provide comfortable work with external CAN modules (such as MCP2515 or MCP2510) via SPI. CANSPI routines are supported by any PIC MCU model that has SPI interface on portc. Also, CS pin of MCP2510 or MCP2515 must be connected to RC0 pin. Example of HW connection is given at the end of the chapter. The Controller Area Network module is a serial interface, useful for communicating with other peripherals or microcontrollers. Details about CAN can be found in appropriate literature and on mikroElektronika Web site. MCP2515 or MCP2510 are modules that enable any chip with SPI interface to communicate over CAN bus. Following routines should be considered a driver for CANSPI (CAN via SPI module) on PIC MCUs.
sub procedure CANSPISetOperationMode(dim mode as byte, dim WAIT as byte) sub function CANSPIGetOperationMode as byte
sub procedure CANSPIInitialize(dim SJW as byte, dim BRP as byte, dim PHSEG1 as byte, dim PHSEG2 as byte, dim PROPSEG as byte,dim CAN_CONFIG_FLAGS as byte) sub procedure CANSPISetBaudRate(dim SJW as byte, dim BRP as byte, dim PHSEG1 as byte, dim PHSEG2 as byte, dim PROPSEG as byte,dim CAN_CONFIG_FLAGS as byte) sub procedure CANSPISetMask(dim CAN_MASK as byte, dim val as longint, dim CAN_CONFIG_FLAGS as byte) sub procedure CANSPISetFilter(dim CAN_FILTER as byte, dim val as longint, dim CAN_CONFIG_FLAGS as byte) sub function RegsToCANSPIID(dim byref ptr as byte, dim CAN_CONFIG_FLAGS as byte) as longint
sub procedure CANSPIIDToRegs(dim byref ptr as byte, dim val as longint, dim CAN_CONFIG_FLAGS as byte) sub function CANSPIwrite(dim id as longint, dim byref Data as byte[8], dim DataLen as byte, dim CAN_TX_MSG_FLAGS as byte) as byte CANSPIread(dim byref id as longint, dim byref Data as byte[8], dim byref DataLen as byte, dim byref CAN_RX_MSG_FLAGS as byte) as byte
sub function
127
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
CANSPISetOperationMode
Prototype: Parameters:
sub procedure CANSPISetOperationMode(dim mode as byte, dim WAIT as byte)
mode - Operation mode code can take any of predefined constant values (see the constants below) WAIT - Should have value TRUE(255) or FALSE(0) CAN is set to requested mode Given mode byte is copied to CANSTAT If WAIT is true, this is a blocking call. It won't return until requested mode is set. If WAIT is false, this is a non-blocking call. It does not verify if CAN module is switched to requested mode or not. Caller must use CANSPIGetOperationMode() to verify correct operation mode before performing mode specific operation.
CANSPIGetOperationMode
Prototype: Parameters: Output:
sub function CANSPIGetOperationMode as byte
128
page
mikroBASIC
making it simple... CANSPIInitialize
Prototype:
sub procedure CANSPIInitialize(dim SJW as byte, dim BRP as byte, dim PHSEG1 as byte, dim PHSEG2 as byte, dim PROPSEG as byte,dim CAN_CONFIG_FLAGS as byte) mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Precondition: Parameters:
CAN must be in Configuration mode or else these values will be ignored. SJW value as defined in 18XXX8 datasheet (must be between 1 thru 4) BRP value as defined in 18XXX8 datasheet (must be between 1 thru 64) PHSEG1 value as defined in 18XXX8 datasheet (must be between 1 thru 8) PHSEG2 value as defined in 18XXX8 datasheet (must be between 1 thru 8) PROPSEG value as defined in 18XXX8 datasheet (must be between 1 thru 8) CAN_CONFIG_FLAGS value is formed from constants (see below) CAN bit rate is set. All masks registers are set to '0' to allow all messages. Filter registers are set according to flag value:
If (CAN_CONFIG_FLAGS and CAN_CONFIG_VALID_XTD_MSG) <> 0 Set all filters to XTD_MSG Else if (config and CONFIG_VALID_STD_MSG) <> 0 Set all filters to STD_MSG Else Set half of the filters to STD, and the rest to XTD_MSG.
Effects:
Side Effects:
129
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
CANSPISetBaudRate
Prototype:
sub procedure CANSPISetBaudRate(dim SJW as byte, dim BRP as byte, dim PHSEG1 as byte, dim PHSEG2 as byte, dim PROPSEG as byte,dim AN_CONFIG_FLAGS as byte)
Precondition: Parameters:
CAN must be in Configuration mode or else these values will be ignored. SJW value as defined in 18XXX8 datasheet (must be between 1 thru 4) BRP value as defined in 18XXX8 datasheet (must be between 1 thru 64) PHSEG1 value as defined in 18XXX8 datasheet (must be between 1 thru 8) PHSEG2 value as defined in 18XXX8 datasheet (must be between 1 thru 8) PROPSEG value as defined in 18XXX8 datasheet (must be between 1 thru 8) CAN_CONFIG_FLAGS - Value formed from constants (see section below) CAN bit rate is set as per given values. Given values are bit adjusted to fit in 18XXX8. BRGCONx registers and copied.
Effects: Overview:
CANSPISetMask
Prototype:
sub procedure CANSPISetMask(dim CAN_MASK as byte, dim val as longint, dim CAN_CONFIG_FLAGS as byte)
Precondition: Parameters:
CAN must be in Configuration mode. If not, all values will be ignored. CAN_MASK - One of predefined constant value val - Actual mask register value. CAN_CONFIG_FLAGS - Type of message to filter, either CAN_CONFIG_XTD_MSG or CAN_CONFIG_STD_MSG Given value is bit adjusted to appropriate buffer mask registers.
Effects:
130
page
mikroBASIC
making it simple... CANSPISetFilter
Prototype:
sub procedure CANSPISetFilter(dim CAN_FILTER as byte, dim val as longint, dim CAN_CONFIG_FLAGS as byte) mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Precondition: Parameters:
CAN must be in Configuration mode. If not, all values will be ignored. CAN_FILTER - One of predefined constant values val - Actual filter register value. CAN_CONFIG_FLAGS - Type of message to filter, either CAN_CONFIG_XTD_MSG or CAN_CONFIG_STD_MSG Given value is bit adjusted to appropriate buffer filter registers.
Effects:
Effects:
These two routines are used by other routines (internal purpose only).
131
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
CANSPIWrite
Prototype:
sub function CANSPIwrite(dim id as longint, dim byref Data as byte[8], dim DataLen as byte, dim CAN_TX_MSG_FLAGS as byte) as byte
Precondition: Parameters:
CAN must be in Normal mode. id - CAN message identifier. Only 11 or 29 bits may be used depending on message type (standard or extended). Data - array of bytes up to 8 bytes in length DataLen - Data length from 1 thru 8. CAN_TX_MSG_FLAGS - Value formed from constants (see section below) If at least one empty transmit buffer is found, given message is queued for the transmission. If none found, FALSE value is returned.
Effects:
CANSPIRead
Prototype:
sub function CANSPIread(dim byref id as longint, dim byref Data as byte[8], dim byref DataLen as byte, dim byref CAN_RX_MSG_FLAGS as byte) as byte
Precondition: Parameters:
CAN must be in mode in which receiving is possible. id - CAN message identifier Data - array of bytes up to 8 bytes in length DataLen - Data length from 1 thru 8. CAN_TX_MSG_FLAGS - Value formed from constants (see below) If at least one full receive buffer is found, it is extracted and returned. If none found, FALSE value is returned.
Effects:
132
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Example
' continues..
133
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
' ..continued
aa1 = CAN_TX_PRIORITY_BITS and CAN_TX_FRAME_BIT and CAN_TX_RTR_BIT ' prepare flags for CANSPIwrite function CANSPIInitialize( 1,2,3,3,1,aa)
CANSPISetOperationMode(CAN_MODE_CONFIG,true) ' set configuration mode ID = -1 CANSPISetMask(CAN_MASK_B1,id,CAN_CONFIG_XTD_MSG) ' bring all mask1 bits to ones CANSPISetMask(CAN_MASK_B2,0,CAN_CONFIG_XTD_MSG) ' bring all mask2 bits to ones CANSPISetFilter(CAN_FILTER_B1_F1,12111,CAN_CONFIG_XTD_MSG) ' set filter_b1_f1 id to 12111 CANSPISetOperationMode(CAN_MODE_NORMAL,true) ' get back to Normal mode while true zr = CANSPIRead(id , Data , len, aa2) if (id = 12111) and zr then portd = $AA portB = data[0] data[0] = data[0]+1 id = 3 delay_ms(10) CANSPIWrite(id,data,1,aa1) if lenn = 2 then portd = data[1] end if end if wend end.
134
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
+5V
+5V
10K
PIC16F877A
MCLR/Vpp/THV RB7/PGD RA0/AN0 RA1/AN1 RB6/PGC RB5 RB4 RB3/PGM RB2 RB1 RB0/INT Vdd Vss RD7/PSP7 RD6/PSP6 RD5/PSP5
100K
100K
100K
Reset
+5V
TX-CAN Vdd RX-CAN RST CLKOUT TX0RTS TX1RTS TX2RTS OSC2 OSC1 Vss 8MHz CS SO SI SCK
+5V
OSC2 RD4/PSP4 RCO/T1OSO RC7/RX/DT RC1/T1OSI RC2/CCP1 RC3 RD0/PSP0 RD1/PSP1 RC6/TX/CK RC5 RC4 RD3/PSP3 RD2/PSP2
4MH z
MCP2510
+5V
PCA82C250
Example of interfacing CAN transceiver MCP2551 and MCP2510 with MCU and bus
10R
135
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
sub procedure CF_File_Write_Init(dim byref CtrlPort as byte, dim byref DataPort as byte) sub procedure CF_File_Write_Byte(dim byref CtrlPort as byte, dim byref DataPort as byte, dim Bdata as byte) sub procedure CF_File_Write_Complete(dim byref CtrlPort as byte, dim byref DataPort as byte, dim byref Filename as char[9])
136
page
mikroBASIC
making it simple... CF_INIT_PORT
Prototype:
sub procedure CF_INIT_PORT(dim byref CtrlPort as byte, dim byref DataPort as byte) mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
None. CtrlPort is control port, DataPort is data port to which CF is attached. Initializes ports appropriately.
CF_DETECT
Prototype: Precondition: Effects: Output:
sub function CF_DETECT(dim byref CtrlPort as byte) as byte
CtrlPort must be initialized (call CF_INIT_PORT first). Check for presence of CF. Returns TRUE if CF is present, otherwise returns FALSE.
CF_WRITE_INIT
Prototype:
sub procedure CF_WRITE_INIT(dim byref CtrlPort as byte, dim byref DataPort as byte, dim Adr as longint, dim SectCnt as byte)
Precondition: Parameters:
Ports must be initialized. CtrlPort - control port , DataPort - data port , Adr - specifies sector address from where data will be written, SectCnt - parameter is total number of sectors prepared for write. Initializes CF card for write operation.
Effects:
137
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
CF_WRITE_BYTE
Prototype:
sub procedure CF_WRITE_BYTE(dim byref CtrlPort as byte, dim byref DataPort as byte, dim BData as byte)
Precondition:
Ports must be initialized, CF must be initialized for write operation (see CF_WRITE_INIT). CtrlPort - control port , DataPort - data port , dat - is data byte written to CF. Write 1 byte to CF. This procedure has effect if writing is previously initialized, and all 512 bytes are transferred to a buffer.
Parameters: Effects:
CF_WRITE_WORD
Prototype:
sub procedure CF_WRITE_WORD(dim byref CtrlPort as byte, dim byref DataPort as byte, dim WData as word)
Precondition:
Ports must be initialized, CF must be initialized for write operation (see CF_WRITE_INIT). CtrlPort - control port , DataPort - data port , dat - is data word written to CF. Writes 1 word to CF. This procedure has effect if writing is previously initialized, and all 512 bytes are transferred to a buffer.
Parameters: Effects:
CF_READ_INIT
Prototype:
sub procedure CF_READ_INIT(dim byref CtrlPort as byte, dim byref DataPort as byte, dim Adr as longint, dim SectCnt as byte)
Precondition: Parameters:
Ports must be initialized. CtrlPort - control port , DataPort - data port , Adr - specifies sector address from where data will be read, SectCnt - parameter is total number of sectors prepared for read operations. This procedure initializes CF card for write operation.
Effects:
138
page
mikroBASIC
making it simple... CF_READ_BYTE
Prototype:
sub function CF_READ_BYTE(dim byref CtrlPort as byte, dim byref DataPort as byte) as byte mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Precondition:
Ports must be initialized, CF must be initialized for read operation (see CF_READ_INIT). CtrlPort - control port , DataPort - data port. Read 1 byte from CF.
Parameters: Effects:
CF_READ_WORD
Prototype:
sub function CF_READ_WORD(dim byref CtrlPort as byte, dim byref DataPort as byte) as word
Precondition:
Ports must be initialized, CF must be initialized for read operation (see CF_READ_INIT). CtrlPort - control port , DataPort - data port. Read 1 word from CF.
Parameters: Effects:
CF_SET_REG_ADR
Prototype: Effects:
sub procedure CF_SET_REG_ADR(dim byref CtrlPort as byte, dim adr as byte)
139
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
CF_FILE_WRITE_INIT
Prototype: procedure CF_File_Write_Init(dim byref CtrlPort as byte, dim byref DataPort as byte)
Precondition:
Ports must be initialized, CF must be initialized for read operation (see CF_READ_INIT). CtrlPort - control port, DataPort - data port. This procedure initializes CF card for file writing operation (FAT16 only).
Parameters: Effects:
CF_FILE_WRITE_BYTE
Prototype: procedure CF_File_Write_Byte(dim byref CtrlPort as byte, dim byref DataPort as byte, dim Bdata as byte)
Precondition:
Ports must be initialized, CF must be initialized for write operation (see CF_File_Write_Init). CtrlPort - control port, DataPort - data port, Bdata - data byte to be written. This procedure adds one byte (<Bdata>) to file.
Parameters: Effects:
CF_FILE_WRITE_BYTE
Prototype: procedure CF_File_Write_Complete(dim byref CtrlPort as byte, dim byref DataPort as byte, dim byref Filename as char[9])
Parameters:
CtrlPort - control port, DataPort - data port, Filename (must be in uppercase and must have exactly 8 characters). Upon all data has be written to file, use this procedure to close the file and make it readable by Windows.
Effects:
140
page
mikroBASIC
making it simple...
Example
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
nop loop until CF_DETECT(PORTB) = true ' wait until CF card is inserted
Delay_ms(500) CF_WRITE_INIT(PORTB, PORTD, 590, 1) ' Initialize write at sector address 590 ' of 1 sector (512 bytes) for i = 0 to 511 ' write 512 bytes to sector (590) CF_WRITE_BYTE(PORTB,PORTD,i+11) next i PORTC = $FF Delay_ms(1000) CF_READ_INIT(PORTB, PORTD, 590, 1) ' Initialize write at sector address 590 ' of 1 sector (512 bytes) for i = 0 to 511 ' read 512 bytes from sector (590) PORTC = CF_READ_BYTE(PORTB, PORTD) ' read byte and display on portc Delay_ms(1000) next i end.
141
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Example
program CompactFlash_File dim i1 as word dim index as byte dim Fname as string[9] sub procedure Init ' designate portc as output TRISC = 0 CF_Init_Port(PORTB,PORTD) ' initialize ports do nop loop until CF_DETECT(PORTB) = true ' wait until CF card is inserted Delay_ms(50) ' wait for until the card stabilizes end sub main:
' index of file to be written index = 0 while index < 5 portc = 0 Init portc = index CF_File_Write_Init(PORTB,PORTD) ' initialization for writing ' to new file i1 = 0 while i1 < 50000 CF_File_Write_Byte(PORTB,PORTD,48+index) ' writes 50000 ' bytes to file inc(i1) wend Fname = "RILEPROX" ' must be 8 character long in upper case fname[8] = 48 + index ' ensure that files have different name CF_File_Write_Complete(PORTB,PORTD, Fname) ' close the file Inc(index) wend PORTC = $FF
end.
142
page
mikroBASIC
making it simple...
+5V
PIC16F877A
MCLR/Vpp/THV RB7/PGD RA0/AN0 RA1/AN1 RB5 RB4 RB3/PGM RB2 RB1 RB0/INT Vdd Vss RD7/PSP7 RD6/PSP6 RD5/PSP5 RD4/PSP4 RC7/RX/DT RC6/TX/CK RC5 RC4 RD3/PSP3 RD2/PSP2
10K
50
+5V
RB6/PGC
10K
RA2/AN2/VrefRA3/AN3/Vref+ RA4/TOCKI RA5/AN4 RE0/RD/AN5 RE1/WR/AN6 RE2/CS/AN7 Vdd Vss OSC1 OSC2 RCO/T1OSO RC1/T1OSI RC2/CCP1 RC3 RD0/PSP0 RD1/PSP1
Reset
+5V
25 49 24 48 23 47 22 46 21 45 20 44 19 43 18 42 17 41 16 40 15 39 14 38 13 37 12 36 11 35 10 34 9 33 8 32 7 31 6 30 5 29 4 28 3 27 2 26 1
4MHz
+5V
143
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
EEPROM Library
EEPROM data memory is available with a number of PIC MCU models. Set of library procedures and functions is listed below to provide you comfortable work with EEPROM.
Routines
Basically, there are two operations that can be performed on EEPROM data memory.
function EEprom_Read(dim Address as byte) as byte procedure EEprom_Write(dim Address as byte, dim Data as byte)
Library function EEprom_Read reads data from specified Address, while the library procedure EEprom_Write writes Data to specified Address.
Note
Parameter Address is of byte type, which means it can address only 256 locations. For PIC18 MCU models with more EEPROM data locations, it is programmer's responsibility to set SFR EEADRH register appropriately.
Example
program EEPROMtest dim i as byte dim j as byte main: TRISB = 0 for i = 0 to 20 EEprom_write(i,i+6) next i for i = 0 to 20 PORTB = EEprom_read(i) for j = 0 to 200 delay_us(500) next j next i end.
144
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
I2C Library
I2C (Inter Integrated Circuit) full master MSSP (Master Synchronous Serial Port) module is available with a number of PIC MCU models. Set of library procedures and functions is listed below to support the master I2C mode.
Important
Note that these functions support module on PORTC, and won't work with modules on other ports. Examples for PIC MCUs with module on other ports can be found in your mikroBasic installation folder, subfolder 'examples'. I2C interface is serial interface used for communicating with peripheral or other microcontroller devices. All functions and procedures bellow are intended for PIC MCUs with MSSP module. By using these, you can configure and use PIC MCU as master in I2C communication.
Routines
I2C_Init(const clock as longint) I2C_Is_Idle as byte I2C_Start as byte I2C_Repeated_Start I2C_Wr(dim Data as byte) as byte I2C_Rd(dim Ack as byte) as byte I2C_Stop as byte
Parameter clock is a desired I2C clock (refer to device data sheet for correct values in respect with Fosc). Example:
I2C_init(100000)
145
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
After configuring the I2C master mode, you have the following functions and procedures at your disposal:
Determines if I2C bus is free and issues START condition; if there is no error, function returns 0.
After you have issued a start or repeated start you can send data byte via I2C bus; this function also returns 0 if there is no errors.
Receives 1 byte from the slave; and sends not acknowledge signal if parameter Ack is 0 in all other cases it sends acknowledge.
Example
The following code demonstrates use of I2C Library procedures and functions. PIC MCU is connected (SCL,SDA pins ) to 24c02 EEPROM. Program sends data to EEPROM (data is written at address 2). Then, we read data via I2C from EEPROM and send its value to PORTD, to check if the cycle was successful. See the following figure on how to interface 24c02 to PIC.
146
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
main: I2C_init(100000) TRISD = 0 PORTD = $ff I2C_Start I2C_Wr($a2) EE_adr = 2 I2C_Wr(EE_adr) EE_data = $aa I2C_Wr(EE_data) I2C_Stop for jj = 0 to 65500 nop next i I2C_Start I2C_Wr($a2) EE_adr = 2 I2C_Wr(EE_adr) I2C_Repeated_Start I2C_Wr($a3) EE_data = I2C_rd(1) I2C_Stop PORTD = EE_data noend: goto noend end.
initialize full master mode designate portd as output initialize portd issue I2C start signal send byte via I2C(command to 24cO2)
' send byte(address for EEPROM) ' send data to be written ' issue I2C stop signal ' pause while EEPROM writes data
' issue I2C start signal ' send byte via I2C ' ' ' ' ' ' send byte(address for EEPROM) issue I2Csignal repeated start send byte(request data from EEPROM) Read the data issue I2C stop signal show data on PORTD
147
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
+5V
+5V
PIC16F877A
MCLR/Vpp/THV RB7/PGD RA0/AN0 RB6/PGC RB5 RB4 RB3/PGM RB2 RB1 RB0/INT Vdd Vss RD7/PSP7 RD6/PSP6 RD5/PSP5 RD4/PSP4 RC7/RX/DT RC6/TX/CK RC5 RC4 RD3/PSP3 RD2/PSP2
10K
10K
10K
Reset
+5V
RE0/RD/AN5
+5V
RE1/WR/AN6 RE2/CS/AN7 Vdd Vss OSC1 OSC2 RCO/T1OSO RC1/T1OSI RC2/CCP1 RC3 RD0/PSP0 RD1/PSP1
1 2 3 4
A0 A1 NC GND
7 6 5
Hz 4M
24C04
148
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
LCD Library
mikroBasic provides a set of library procedures and functions for communicating with commonly used 4-bit interface LCD (with Hitachi HD44780 controller). Figure showing HW connection of PIC and LCD is given at the bottom of the page (if you need different pin settings, refer to LCD_Config routine).
Note
Be sure to designate port with LCD as output, before using any of the following library routines.
Routines
sub procedure LCD_Config(dim byref Port as byte, const RS, const EN, const WR, const D7, const D6, const D5, const D4)
Initializes LCD at <Port> with pin settings you specify: parameters <RS>, <EN>, <WR>, <D7> .. <D4> need to be a combination of values 0..7 (e.g. 3,6,0,7,2,1,4).
Initializes LCD at <Port> with default pin settings (check the figures at the end of the chapter).
sub procedure LCD_Out(dim Row as byte, dim Column as byte, dim byref Text as char[255])
Prints <Text> (string variable) at specified row and column on LCD. Both string variables and string constants can be passed.
Prints <Text> (string variable) at current cursor position. Both string variables and string constants can be passed.
149
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
sub procedure LCD_Chr(dim Row as byte, dim Column as byte, dim Character as byte)
Sends command <Command> to LCD. Refer to the following list of available commands.
LCD Commands
Command LCD_First_Row LCD_Second_Row LCD_Third_Row LCD_Fourth_Row LCD_Clear LCD_Return_Home LCD_Cursor_Off LCD_Underline_On LCD_Blink_Cursor_On LCD_Move_Cursor_Left
Purpose Moves cursor to 1st row Moves cursor to 2nd row Moves cursor to 3rd row Moves cursor to 4th row Clears display Returns cursor to home position, returns a shifted display to original position. Display data RAM is unaffected Turns off cursor Underline cursor on Blink cursor on Move cursor left without changing display data RAM
LCD_Move_Cursor_Right Move cursor right without changing display data RAM LCD_Turn_On LCD_Turn_Off LCD_Shift_Left LCD_Shift_Right page Turn LCD display on Turn LCD display off Shift display left without changing display data RAM Shift display right without changing display data RAM
150
mikroBASIC
making it simple...
Example
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
151
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Example
Use LCD_Init for default pin settings (see the figure below).
program LCD_default_test
PORTB is output Initialize LCD at PORTB Turn off cursor Print Text at LCD
PIC MCU
any port (with 8 pins) PIN0 PIN1 PIN2 PIN3 PIN4 PIN5 PIN6 PIN7
PIC
PIN7 PIN6 PIN5 PIN4 PIN3 PIN2 PIN1 PIN0
LCD
D7 D6 D5 D4 E RS
+5V
1
Vss Vdd Vee RS R/W E D0 D1 D2 D3 D4 D5 D6 D7
m i k ro el E kt ron i ka
LCD HW connection by default initialization (using LCD_Init). If you need different pin settings, refer to LCD_Config routine.
page
152
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Alternatively, you can use LCD_Config for custom pin settings. For example:
program LCD_custom_test
main: TRISD = 0
' Initialize LCD at portd with custom pin settings (figure) LCD_Config(PORTD,1,2,0,3,5,4,6) LCD_Cmd(LCD_CURSOR_OFF) ' Turn off cursor LCD_Out(1, 1, "mikroelektronika") ' Print text at LCD end.
PIC MCU
any port (with 8 pins) PIN0 PIN1 PIN2 PIN3 PIN4 PIN5 PIN6 PIN7
PIC
PIN7 PIN6 PIN5 PIN4 PIN3 PIN2 PIN1 PIN0
LCD
D7 D6 D5 D4 E RS
+5V
1
Vss Vdd Vee RS R/W E D0 D1 D2 D3 D4 D5 D6 D7
m i k ro el E kt ron i ka
153
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Note
Routines
sub procedure LCD8_Config(dim byref portCtrl as byte, dim byref portData as byte, const RS, const EN, const WR, const D7, const D6, const D5, const D4, const D3, const D2, const D1, const D0)
Initializes LCD at <portCtrl> and <portData> with pin settings you specify: parameters <RS>, <EN>, <WR> need to be in range 0..7; parameters <D7> .. <D0> need to be a combination of values 0..7 (e.g. 3,6,5,0,7,2,1,4).
sub procedure LCD8_Init(dim byref portCtrl as byte, dim byref portData as byte)
Initializes LCD at <portCtrl> and <portData> with default pin settings (check the figures at the end of the chapter).
sub procedure LCD8_Out(dim Row as byte, dim Column as byte, dim byref Text as char[255])
Prints <Text> (string variable) at specified row and column on LCD. Both string variables and string constants can be passed.
Prints <Text> (string variable) at current cursor position. Both string variables and string constants can be passed.
154
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
sub procedure LCD8_Chr(dim Row as byte, dim Column as byte, dim Character as byte)
Sends command <Command> to LCD. Refer to page 150 for the complete list of available LCD commands.
Example
155
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Example
Use LCD8_Init for default pin settings (see the figure below).
program LCD8_test dim Text as char[17] main: TRISB = 0 TRISC = 0 LCD8_Init(portb, portc) LCD8_Cmd(LCD_CURSOR_OFF) Text = "mikroElektronika" LCD8_Out(1, 1, Text) end.
' Portb is output ' Portc is output ' Initialize LCD at portb and portc ' Turn off cursor ' Print text at LCD
PIC MCU
any port (with 8 pins)
Control Port
PIN0 R/W RS PIN2 PIN3 E
Data Port
PIN0 PIN1 PIN2 PIN3 PIN4 PIN5 PIN6 PIN7
+5V
1
Vss Vdd Vee RS R/W E D0 D1 D2 D3 D4 D5 D6 D7
m i k ro el E ktron i ka
156
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Alternatively, you can use LCD8_Config to set custom pin settings. For example:
program LCD8_custom_test dim Text as char[17] main: ' TRISB = 0 TRISD = 0 ' ' Initialize LCD at portb and portd LCD8_Config(PORTB,PORTD,2,3,0,7,6,5,4,3,2,1,0) ' LCD8_Cmd(LCD_CURSOR_OFF) Text = "mikroElektronika" LCD8_Out(1, 1, Text) ' end.
PIC MCU
any port (with 8 pins)
Control Port
PIN0 R/W RS PIN2 E PIN3
Data Port
PIN0 PIN1 PIN2 PIN3 PIN4 PIN5 PIN6 PIN7
+5V
1
Vss Vdd Vee RS R/W E D0 D1 D2 D3 D4 D5 D6 D7
m i k ro el E ktron i ka
157
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Note
Routines
sub procedure GLCD_Config(dim byref Ctrl_Port as byte, dim byref Data_Port as byte, dim Reset as byte, dim Enable as byte, dim RS as byte, dim RW as byte, dim CS1 as byte, dim CS2 as byte)
Initializes LCD at <Ctrl_Port> and <Data_Port> with custom pin settings. For example: GLCD_Config(portb, portc, 1,7,4,6,0,2).
Adress base for Page 0 Adress base for Y0 Adress base for line 0 Turn display on Turn display off
158
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
sub procedure GLCD_Circle(dim CenterX as integer, dim CenterY as integer, dim Radius as integer)
sub procedure GLCD_Line(dim x1 as integer, dim y1 as integer, dim x2 as integer, dim y2 as integer)
159
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Procedure inverts display (changes dot state on/off) in the specified area, X pixels wide starting from 0 position, 8 pixels high. Parameter X spans 0..127, parameter Y spans 0..7 (8 text lines).
sub procedure GLCD_Goto_XY(dim x as byte, dim y as byte)
Sets cursor to dot (x,y). Procedure is used in combination with GLCD_Put_Data, GLCD_Put_Data2, and GLCD_Put_Char.
sub procedure GLCD_Put_Text(dim x_pos as word, dim y_pos as word, dim byref text as char[25], dim invert as byte)
sub procedure GLCD_Rectangle(dim X1 as byte, dim Y1 as byte, dim X2 as byte, dim Y2 as byte)
Draws a rectangle on the GLCD. (x1,y1) sets the upper left corner, (x2,y2) sets the lower right corner.
Sets font for GLCD. Parameter <font_index> spans from 1 to 4, and determines which font will be used: 1: 5x8 dots, 2: 5x7 dots, 3: 3x6 dots, 4: 8x8 dots.
160
page
mikroBASIC
making it simple...
Example program GLCDDemo include "GLCD_128x64.pbas" dim text as string[25] dim j as byte dim k as byte main: PORTC PORTB PORTD TRISC TRISD TRISB
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
= = = = = =
0 0 0 0 0 0
while true ' Draw Circles GLCD_Clear_Screen text = "Circle" GLCD_Put_Text(0, 7, text, NONINVERTED_TEXT) GLCD_Circle(63,31,20) Delay_Ms(4000)
' Draw rectangles GLCD_Clear_Screen text = "Rectangle" GLCD_Put_Text(0, 7, text, NONINVERTED_TEXT) GLCD_Rectangle(10, 0, 30, 35) Delay_Ms(4000) GLCD_Clear_Screen ' Draw Lines GLCD_Clear_Screen text = "Line" GLCD_Put_Text(55, 7, text, NONINVERTED_TEXT) GLCD_Line(0, 0, 127, 50) GLCD_Line(0, 63, 50, 0) Delay_Ms(5000) { continued.. }
161
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
{ ..continued } ' Fonts DEMO GLCD_Clear_Screen text = "Fonts DEMO" GLCD_Set_Font(FONT_TINY) GLCD_Put_Text(0, 4, text, GLCD_Put_Text(0, 5, text, GLCD_Set_Font(FONT_BIG) GLCD_Put_Text(0, 6, text, GLCD_Put_Text(0, 7, text, Delay_ms(5000) wend
end.
18
D7 D6 D5 D4 D3 D2 D1 D0 E R/ W RS Vee Vcc VOUT RESET CS2 CS1
1
GND
10k
10 + 5V
GND
162
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
PWM Library
CCP (Capture/ Compare/ PWM) module is available with a number of PIC MCU models. Set of library procedures and functions is listed below to provide comfortable work with PWM (Pulse Width Modulation).
Note
Note that these routines support module on PORTC pin RC2, and won't work with modules on other ports. Also, mikroBasic doesn't support enhanced PWM modules. Examples for PIC MCUs with module on other ports can be found in your mikroBasic installation folder, subfolder 'examples'.
Routines
Initializes the PWM module. It starts with (duty ratio) 0%. Parameter PWM_Freq is a desired PWM frequency (refer to device data sheet for correct values in respect with Fosc). Example: PWM_Init(5000);
Parameter New_Duty (duty ratio) takes values from 0 to 255, where 0 is 0% duty ratio, 127 is 50% duty ratio, and 255 is 100% duty ratio. Other values for specific duty ratio can be calculated as (Percent*255)/100.
sub procedure PWM_start
Starts PWM.
sub procedure PWM_stop
Stops PWM.
163
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Example
This code demonstrates use of PWM library procedures and functions. If pin RC2 is connected to LED diode, light emitted will depend of PWM duty ratio and this change can be noticed.
program PWMtest dim j as byte main: j = 0 PORTC = $FF PWM_init(5000) PWM_start while true delay_ms(100) j = j + 1 PWM_change_duty(j) wend end.
PIC16F877A
+5V
MCLR/Vpp/THV RB7/PGD
10K
RB6/PGC RB5 RB4 RB3/PGM RB2 RB1 RB0/INT Vdd Vss RD7/PSP7 RD6/PSP6 RD5/PSP5 RD4/PSP4 RC7/RX/DT RC6/TX/CK RC5 RC4 RD3/PSP3 RD2/PSP2
Reset
RE0/RD/AN5
+5V
RE1/WR/AN6 RE2/CS/AN7 Vdd Vss OSC1 OSC2 RCO/T1OSO RC1/T1OSI RC2/CCP1 RC3 RD0/PSP0 RD1/PSP1
4MHz
330R
164
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
RS485 Library
RS485 is a multipoint communication which allows multiple devices to be connected to a single signal cable. mikroBasic provides a set of library routines to provide you comfortable work with RS485 system using Master/Slave architecture. Master and Slave devices interchange packets of information, each of these packets containing synchronization bytes, CRC byte, address byte, and the data. In Master/Slave architecture, Slave can never initiate communication. Each Slave has its unique address and receives only the packets containing that particular address. It is programmer's responsibility to ensure that only one device transmits data via 485 bus at a time. Address 50 is a common address for all Slave devices: packets containing address 50 will be received by all Slaves. The only exceptions are Slaves with addresses 150 and 169, which require their particular address to be specified in the packet.
Note
RS485 routines require USART module on port C. Pins of USART need to be attached to RS485 interface transceiver, such as LTC485 or similar. Pins of transceiver (Receiver Output Enable and Driver Outputs Enable) should be connected to port C, pin 2 (see the figure at end of the chapter).
Routines
Following routines implement flexible protocol for RS485 system with Master/Slave architecture:
sub procedure RS485master_init sub procedure RS485slave_init(dim address as byte) sub procedure RS485master_read(dim byref data as byte[5]) sub procedure RS485master_write(dim byref data as byte[2], dim datalen as byte, dim address as byte) sub procedure RS485slave_read(dim byref data as byte[5]) sub procedure RS485slave_write(dim byref data as byte[2], dim datalen as byte)
165
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
RS485master_init
Prototype: Precondition: Parameters: Effects: sub procedure RS485master_init
USART needs to be initialized (USART_init) None Initializes MCU as Master in RS485 communication
RS485slave_init
Prototype: Precondition: Parameters: sub procedure RS485slave_init(dim address as byte)
USART needs to be initialized (USART_init) Slave address can take any value between 0 and 255, except 50 which is a common address for all slaves Initializes MCU as Slave in RS485 communication
Effects:
RS485master_read
Prototype: Precondition: Parameters: Effects: sub procedure RS485master_read(dim byref data as byte[5])
Master receives any message sent by Slaves. As messages are multi-byte, this procedure must be called for each byte received. Upon receiving a message, buffer is filled with the following values: data[0..2] is data; data[3] is the number of received bytes (1..3); data[4] is set to 255 (TRUE) when message is received; data[5] is set to 255 (TRUE) if an error has occurred; data[6] is the address of the Slave which sent the message Procedure automatically sets data[4] and data[5] upon every received message.These flags need to be cleared repeatedly from the program.
166
page
mikroBASIC
making it simple... RS485master_write
Prototype: sub procedure RS485master_write(dim byref data as byte[2], dim datalen as byte, dim address as byte)
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Precondition:
MCU must be initialized as Master in 485 communication. It is programmer's responsibility to ensure (by protocol) that only one device sends data via 485 bus at a time.
dim byref data as byte[2], dim datalen as byte
Parameters: Effects:
Sends number of bytes (1 < datalen <= 3) from buffer via 485.
RS485slave_read
Prototype: Precondition: Parameters: Effects: sub procedure RS485slave_read(dim byref data as byte[5])
Only messages that appropriately address Slaves will be received. As messages are multi-byte, this procedure must be called for each byte received (see the example at the end of the chapter). Upon receiving a message, buffer is filled with the following values: data[0..2] is data; data[3] is number of bytes received (1..3) ; data[4] is set to 255(TRUE) when message is received; data[5] is set to 255(TRUE) if an error has occurred; rest of the buffer is undefined Procedure automatically sets data[4] and data[5] upon every received message. These flags need to be cleared repeatedly from the program.
167
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
RS485slave_write
Prototype: sub procedure RS485slave_write(dim byref data as byte[2], dim datalen as byte)
Sends number of bytes (1 < datalen <= 3) from buffer via 485
168
page
mikroBASIC
making it simple...
Example program pr485 dim dat as byte[8] dim i as byte dim j as byte
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
sub procedure interrupt if TestBit(RCSTA,OERR) = 1 then portd = $81 end if RS485slave_receive(dat) end sub
main: trisb = 0 trisd = 0 ' initialize usart module USART_init(9600) RS485slave_init(160) ' init. MCU as Slave with address 160 SetBit(PIE1,RCIE) ' enable interrupt SetBit(INTCON,PEIE) ' on byte received ClearBit(PIE2,TXIE) ' via USART (RS485) SetBit(INTCON,GIE) portb = 0 portd = 0 ' ensure that message received flag is 0 dat[4] = 0 ' ensure that error flag is 0 dat[5] = 0 while true if dat[5] then portd = $aa ' if there is error, set portd to $aa end if if dat[4] then ' if message received dat[4] = 0 ' clear message received flag j = dat[3] ' number of data bytes received for i = 1 to j portb = dat[i-1] ' output received data bytes next i ' increment received dat[0] dat[0] = dat[0] + 1 RS485slave_send(dat,1) ' send it back to Master end if wend end.
' every byte is received by ' RS485slave_read(dat); ' upon receiving a msg with no errors ' data[4] is set to 255
169
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
PIC16F877A
+5V
MCLR/Vpp/THV RB7/PGD RA0/AN0 RB6/PGC RB5 RB4 RB3/PGM RB2 RB1 RB0/INT Vdd Vss RD7/PSP7 RD6/PSP6 RD5/PSP5 RD4/PSP4 RC7/RX/DT RC6/TX/CK RC5 RC4 RD3/PSP3 RD2/PSP2 RA1/AN1 RA2/AN2/VrefRA3/AN3/Vref+ RA4/TOCKI RA5/AN4
10K
+5V
10K
Reset
RE0/RD/AN5
+5V
+5V
RE1/WR/AN6 RE2/CS/AN7 Vdd Vss OSC1 OSC2 RCO/T1OSO RC1/T1OSI RC2/CCP1 RC3 RD0/PSP0 RD1/PSP1
R0 RE DE DI
Vcc B A GND
LTC485
4.7uF
+ +
4.7uF
4.7uF
RX TX RTS GND
LTC485
MAX232
170
page
620R
R0 RE DE DI
Vcc B A GND
620R
4MHz
4.7uF
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
SPI Library
SPI (Serial Peripheral Interface) module is available with a number of PIC MCU models. Set of library procedures and functions is listed below to provide initialization of slave mode and comfortable work with the master mode. You can easily communicate with other devices via SPI - A/D converters, D/A converters, MAX7219, LTC1290 etc. You need PIC MCU with hardware integrated SPI (for example, PIC16F877). Then, simply use the following functions and procedures.
Note
Note that these functions support module on PORTB or PORTC, and won't work with modules on other ports. Examples for PIC MCUs with module on other ports can be found in your mikroBasic installation folder, subfolder 'examples'.
Routines
procedure SPI_init procedure SPI_write(dim Data as byte) function SPI_read(dim Buffer as byte) as byte procedure SPI_Init_advanced(dim Master as byte, Data_Sample as byte, dim Clock_Idle as byte,dim Low_To_High as byte)
Initialization
You can use procedure SPI_init without parameters and get the default result: Master mode, clock Fosc/4, clock idle state low, data transmitted on low to high edge, input data sampled at the middle of interval; For advanced settings, configure and initialize SPI using the procedure:
sub procedure SPI_Init_advanced(dim Master as byte, dim Data_Sample as byte, dim Clock_Idle as byte, dim Low_To_High as byte)
171
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Example:
SPI_init(Master_OSC_div4, Data_SAMPLE_MIDDLE,LK_Idle_LOW,LOW_2_HIGH)
This will set SPI to master mode, clock = Fosc/4, data sampled at the middle of interval, clock idle state low and data transmitted at low to high edge.
Parameters
Parameter mast_slav determines the work mode for SPI; can have the following values:
Value Master_OSC_div4 Master_OSC_div16 Master_OSC_div64 Master_TMR2 Slave_SS_ENABLE Slave_SS_DIS Meaning Master clock=Fosc/4 Master clock=Fosc/16 Master clock=Fosc/64 Master clock source TMR2 Master slave select enabled Master slave select disabled
Parameter Data_sample determines when data is sampled. It can have the following values:
Value Data_SAMPLE_MIDDLE Data_SAMPLE_END Meaning Input data sampled in middle of interval Input data sampled at end of interval
Parameter clk_idl determines idle state for clock; can have the following values:
Value CLK_Idle_HIGH CLK_Idle_LOW Meaning Clock idle HIGH Clock idle LOW
172
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Parameter lth_htl determines transmit edge for data. It can have the following values:
Value LOW_2_HIGH HIGH_2_LOW Meaning Data transmit on low to high edge Data transmit on high to low edge
Note
In order to keep this working, you shouldn't override the settings made by the procedures spi_init or spi_init_ordinary as it uses some of the PIC MCU resources. Pins RC3, RC4, RC5 are configured as needed (don't change TRISC settings for these pins - procedure will set them automatically).
The following routines are provided for comfortable use of master mode :
Provide clock by sending data (byte b) and read the received data at the end of the period.
173
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Example
The folowing code demonstrates how to use SPI library procedures and functions. Same example along with m7219.pbas file is given in folder ../mikroBasic/examples. Assumed HW configuration is: max7219 (chip select pin) is connected to RC1, and SDO, SDI, SCK pins are connected to corresponding pins of max7219.
program SPI include "m7219.pbas" dim i as byte main: SPI_init TRISC = TRISC and $Fd max7219_init PORTC.1 = 0 SPI_write(1) SPI_write(7) PORTC.1 = 0 end.
' standard configuration ' ' ' ' ' initialize max7219 select max7219 send address (1) to max7219 send data (7) to max7219 deselect max7219s
174
page
MAX7219
DIN DIG0 DIG4 GND DIG6 DIG2 DIG3 DIG7 GND DOUT SEGD SEGDP SEGE SEGC V+ ISET SEGG SEGB SEGF
10K
+5V
10K
8. 8. 8. 8. 8. 8. 8. 8.
PIC16F877A
MCLR/Vpp/THV RB7/PGD RA0/AN0 RB6/PGC RA1/AN1 RA2/AN2/VrefRA3/AN3/Vref+ RA4/TOCKI RA5/AN4 RE0/RD/AN5 RE1/WR/AN6 RB5 RB4 RB3/PGM RB2 RB1 RB0/INT
Reset
g
Vdd Vss
+5V
8
f K a
g
4MHz
b e c d dp
e d K c dp
making it simple...
mikroBASIC
175
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
USART Library
USART (Universal Synchronous Asynchronous Receiver Transmitter) hardware module is available with a number of PIC MCU models. Set of library procedures and functions is listed below to provide comfortable work with the Asynchronous (full duplex) mode. You can easily communicate with other devices via RS232 protocol (for example with PC, see the figure at the end of this chapter - RS232 HW connection). You need a PIC MCU with hardware integrated USART (for example, PIC16F877). Then, simply use the functions and procedures described below.
Note
Note that these functions and procedures support module on PORTB, PORTC or PORTG, and won't work with modules on other ports. Examples for PIC MCUs with module on other ports can be found in your mikroBasic installation folder, subfolder 'examples'.
Routines
Certain PIC MCU models with two USART modules, such as P18F8520, require you to specify the module you want to use. Simply append the number 1 or 2 to procedure or function name - for example, USART_Write2(dim Data as byte).
176
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
This will initialize PIC MCU USART hardware and establish the communication at baud rate of 2400. Refer to the device data sheet for baud rates allowed for specific Fosc. If you specify the unsupported baud rate, compiler will report an error. In order to keep this working, you should not override settings made by the procedure USART_init as it uses some of the PIC MCU resources. (For example: pins RC7, RC6 configured as input, output respectively; do not change TRISC settings for this pins - procedure will set them automatically). Check the figure on the following page. Following routines can be used after the communication has been established:
sub function USART_Data_Ready as byte
Transmit a byte.
Example
The following code demonstrates how to use USART library procedures and functions. When PIC MCU receives data via rs232 it immediately sends the same data back. If PIC MCU is connected to the PC (see figure below), you can test it using mikroBasic terminal for RS232 communication, menu choice Tools > Terminal.
177
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Example
main: USART_init(2400) while true if USART_data_ready = 1 then Received_byte = USART_read USART_write(Received_byte) end if wend end.
' initialize USART module ' if data is received ' read received data, ' send data via USART
PIC16F877A
4.7uF
+5V
+5V
MCLR/Vpp/THV RB7/PGD
10K
RB6/PGC RB5 RB4 RB3/PGM RB2 RB1 RB0/INT Vdd Vss RD7/PSP7 RD6/PSP6 RD5/PSP5 RD4/PSP4 RC7/RX/DT RC6/TX/CK RC5 RC4 RD3/PSP3 RD2/PSP2
4.7uF
+ +
Reset
4.7uF
RE0/RD/AN5
+5V
RE1/WR/AN6 RE2/CS/AN7 Vdd Vss OSC1 OSC2 RCO/T1OSO RC1/T1OSI RC2/CCP1 RC3 RD0/PSP0 RD1/PSP1
4.7uF
serial cable (1 to 1)
1 6 2 7 3 8 4 9 5
178
MAX232
4MHz
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Software I2C
mikroBasic provides routines which implement software I2C. These routines are hardware independent and can be used with any MCU. Software I2C enables you to use MCU as Master in I2C communication. Multi-master mode is not supported. Note that these functions and procedures implement time-based activities, so the interrupts must be disabled when using them. I2C interface is serial interface used for communicating with peripheral or other microcontroller devices. Routines below are intended for PIC MCUs with MSSP module. By using these, you can configure and use PIC MCU as master in I2C communication.
Routines
sub procedure Soft_I2C_Config(dim byref Port as byte, const SDA, const SCL, const clock)
Parameter <Port> specifies port of MCU on which SDA and SCL pins will be located; parameters <SCL> and <SDA> need to be in range 0..7 and cannot point at the same pin.
sub procedure Soft_I2C_Start
After you have issued a start or repeated start you can send data byte via I2C bus; this function also returns 0 if there are no errors.
sub function Soft_I2C_Read(dim Ack as byte) as byte
Receive 1 byte from the slave; and sends not acknowledge signal if parameter Ack is 0 in all other cases it sends acknowledge.
sub procedure Soft_I2C_Stop
179
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Example
This code demonstrates use of software I2C routines. PIC MCU is connected (SCL,SDA pins ) to 24c02 EEPROM. Program sends data to EEPROM (data is written at address 2). Then, we read data via I2C from EEPROM and send its value to PORTC, to check if the cycle was successful.
program soft_I2C_test dim EE_adr as byte dim EE_data as byte dim jj as word main: Soft_I2C_config(PORTD,3,4) TRISC = 0 PORTC = $ff Soft_I2C_Start Soft_I2C_Write($a2) EE_adr = 2 Soft_I2C_Write(EE_adr) EE_data = $aa Soft_I2C_Write(EE_data) Soft_I2C_Stop for jj = 0 to 65500 nop next jj Soft_I2C_Start Soft_I2C_Write($a2) EE_adr = 2 Soft_I2C_Write(EE_adr) Soft_I2C_Start Soft_I2C_Write($a3) EE_data = Soft_I2C_Read(0) Soft_I2C_Stop PORTC = EE_data noend: goto noend end.
initialize full master mode portc is output initialize portc I2C start signal send byte via I2C
' send byte(address for EEPROM) ' send data (data to be written) ' I2C stop signal ' pause while EEPROM writes data
' issue I2C start signal ' send byte via I2C ' ' ' ' ' ' ' send byte (address for EEPROM) I2C signal repeated start send byte (request data) read the data I2C_stop signal show data on PORTD endless loop
180
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Software SPI
mikroBasic provides routines which implement software SPI. These routines are hardware independent and can be used with any MCU.
Note
Note that these functions and procedures implement time-based activities, so the interrupts need to be disabled when using them.
Routines
sub procedure Soft_SPI_Config(dim byref Port as byte, const SDI, const SD0, const SCK) sub procedure Soft_SPI_Init(dim byref Port as byte) sub procedure Soft_SPI_Write(dim Data as byte) sub function Soft_SPI_Read(dim Buffer as byte) as byte
This will set SPI to master mode, clock = 50kHz, data sampled at the middle of interval, clock idle state low and data transmitted at low to high edge. SDI pin is RB1, SDO pin is RB2 and SCK pin is RB3. Parameter <Port> specifies port of MCU on which SDI,SDO and SCK pins will be located; parameters <SDI>, <SDO> and <SCK> need to be in range 0..7 and cannot point at the same pin; In order to keep this working, you shouldn't override the settings made by the procedures soft_spi_config as it uses some of the PIC MCU resources. Specified pins SDI,SDO and SCK are configured as needed (don't change TRISX settings for these pins - procedure will set them automatically).
181
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
The following functions are provided for comfortable use of master mode:
sub procedure Soft_SPI_Write(dim Data as byte)
Provide clock by sending data (byte Buffer) and return the received data.
Example
This code demonstrates how to use Software SPI procedures and functions. Assumed HW configuration is: max7219 (chip select pin) is connected to RD1, and SDO, SDI, SCK pins are connected to corresponding pins of max7219.
program Soft_SPI_test include "m7219.pbas" dim i as byte main: Soft_SPI_Config(portd,4,5,3) TRISC = TRISC and $Fd max7219_init PORTD.1 = 0 Soft_SPI_Write(1) Soft_SPI_Write(7) PORTD.1 = 0 end.
' standard configuration ' ' ' ' ' initialize max7219 select max7219 send address to max7219 send data to max7219 deselect max7219
182
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Software UART
mikroBasic provides routines which implement software UART. These routines are hardware independent and can be used with any MCU. You can easily communicate with other devices via RS232 protocol. Simply use the functions and procedures described below.
Note
Note that these functions and procedures implement time-based activities, so the interrupts need to be disabled when using them.
Routines
sub procedure Soft_UART_Init(dim byref Port as byte, const RX, const TX, const Baud_Rate) sub function Soft_UART_Read(dim byref Msg_received as byte) as byte sub procedure Soft_UART_Write(dim Data as byte)
Parameter <Port> specifies port of MCU on which RX and TX pins are located (RX and TX have to be on the same port, obviously); parameters <RX> and <TX> need to be in range 0..7 and cannot point the same pin; <Baud_Rate> is the desired baud rate. Example:
Soft_UART_Init(portb, 1, 2, 9600)
This will initialize software UART and establish the communication at baud rate of 9600. Maximum baud rate depends on PIC MCU clock and working conditions. In order to keep this working, you should not override settings made by the procedure Soft_UART_Init as it uses some of PIC resources. (the example above configures pins RB1 and as input; do not change TRISB settings for these pins - procedure will set them automatically).
183
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Following functions can be used after the communication has been established:
sub function Soft_UART_Read(dim byref Msg_received as byte) as byte
Function returns a received byte; parameter <Msg_received> will take true if transfer was succesful. Soft_UART_Read is a non-blocking function call, so you should test <Msg_received> manually (check the example below).
Example
This code demonstrates how to use software UART procedures and functions. When PIC MCU receives data via RS232 it immediately sends the same data back. If PIC MCU is connected to the PC, you can test it using the mikroBasic terminal for RS232 communication, menu choice Tools > Terminal. Be aware that during transmission, software UART is incapable of receiving data data transfer protocol must be set in such a way to prevent loss of information.
program soft_UART_test dim Received_byte as byte dim Rec_ok as byte main: ' initialize software UART Soft_UART_init(PORTB,1,2,2400) while true do ' read received data, loop until Rec_ok Received_byte = Soft_UART_read(Rec_ok)
184
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Routines
For PIC18:
procedure Flash_Write(dim Address as longint, dim byref Data as byte[64]) function Flash_Read(dim Address as longint) as byte
For PIC16:
procedure Flash_Write(dim Address as word, dim Data as word) function Flash_Read(dim Address as word) as word
Procedure FlashWrite writes chunk of data to Flash memory (for PIC18, data needs to exactly 64 bytes in size). Procedure FlashRead reads data from the specified <Address>.
Important
Keep in mind that this function erases target memory before writing <Data> to it. This means that if write was unsuccessful, your previous data will be lost.
185
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Example
dim toRead as byte dim i as byte dim toWrite as byte[64] main: TRISB = 0 for i = 0 to 63 toWrite[i] = i next i
' write contents of the array to the address 0x0D00 Flash_Write($0D00, toWrite) ' verify write PORTB = 0 toRead = FLASH_ERROR
for i = 0 to 63
186
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
' write the value of i starting from the address 0x0A00 Flash_Write(i + $0A00, i)
next i
' i contains the address of the erroneous location i = i + $0A00 ' indicate error PORTB = FLASH_ERROR Delay_ms(500)
else PORTB = FLASH_OK end if next i end.
187
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
1
2.4ms
0
Example of transmission
1 1 0 0 01 0 0 01 1
Note
Manchester receive routines are blocking calls (Man_Receive_Config, Man_Receive_Init, Man_Receive). This means that PIC will wait until the task is performed (e.g. byte is received, synchronization achieved, etc.) Routines for receiving are limited to a baud rate scope from 340 ~ 560 bps.
188
page
mikroBASIC
making it simple...
Routines
sub sub sub sub sub sub procedure procedure function procedure procedure procedure mikroBASIC - Basic Compiler for Microchip PIC microcontrollers Man_Receive_Config(dim byref port as byte, dim rxpin as byte) Man_Receive_Init(dim byref port as byte) Man_Receive(dim byref error as byte) as byte Man_Send_Config(dim byref port as byte, dim txpin as byte) Man_Send_Init(dim byref port as byte) Man_Send(dim data as byte)
This procedure needs to be called in order to receive signal by procedure Man_Receive. You need to specify the port and rxpin of input signal. In case of multiple errors on reception, you should call Man_Receive_Init once again to enable synchronization.
Procedure works same as Man_Receive_Config, with default pin setting (pin 6).
sub function
Function extracts one byte from signal. If format does not match the expected, <error> flag will be set True.
Procedure needs to be called in order to send signals via procedure Man_Send. Procedure specifies <port> and <txpin> for outgoing signal (const baud rate).
Procedure works same as Man_Send_Config, but with default pin setting (pin 0).
189
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Example
' errorFlag indicator ' Synchronize receiver ' Initialize LCD on PORTB
while true ' endless loop do IdleCount = 0 ' Reset idle counter temp = Man_Receive(ErrorFlag) ' Attempt byte receive if errorFlag then inc(errorCount) else PORTC = 0 end if ' If too many errorFlags if errorCount > 20 then ' try to synchronize the receiver again errorCount = 0 PORTC = $AA ' Indicate errorFlag Man_Receive_Init(PORTD) ' Synchronize receiver end if inc(IdleCount) if IdleCount > 18 then
' If nothing is received after some time ' try to synchronize again
IdleCount = 0 Man_Receive_Init(PORTD) end if loop until temp = $0B
' continues..
190
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
191
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
' Initialize port ' Disable interrupts ' Initialize manchester sender ' Send start marker ' Wait for a while
192
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
+5V
PIC16F877A
MCLR/Vpp/THV RB7/PGD RA0/AN0 RB6/PGC RB5 RB4 RB3/PGM RB2 RB1 RB0/INT Vdd Vss RD7/PSP7 RD6/PSP6 RD5/PSP5 RD4/PSP4 RC7/RX/DT RC6/TX/CK RC5 RC4 RD3/PSP3 RD2/PSP2
Transmitter RF Module
+5V
Ant en na
10K
Vcc In
Reset
RE0/RD/AN5
+5V
RE1/WR/AN6 RE2/CS/AN7 Vdd Vss OSC1 OSC2 RCO/T1OSO RC1/T1OSI RC2/CCP1 RC3 RD0/PSP0 RD1/PSP1
RT4
GND
4MHz
+5V
PIC16F877A
MCLR/Vpp/THV RB7/PGD RA0/AN0 RB6/PGC RB5 RB4 RB3/PGM RB2 RB1 RB0/INT Vdd Vss RD7/PSP7 RD6/PSP6 RD5/PSP5 RD4/PSP4 RC7/RX/DT RC6/TX/CK RC5 RC4 RD3/PSP3 RD2/PSP2
10K
Ant en na
Reset
RR3
Receiver RF Module
+5V
RE0/RD/AN5
+5V
RE1/WR/AN6 RE2/CS/AN7 Vdd Vss OSC1 OSC2 RCO/T1OSO RC1/T1OSI RC2/CCP1 RC3 RD0/PSP0 RD1/PSP1
4MHz
193
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Routines
You can get text representation of numerical value by passing it to one of the routines listed below:
sub sub sub sub procedure procedure procedure procedure ByteToStr(dim input as byte, dim byref txt as char[6]) WordToStr(dim input as word, dim byref txt as char[6]) ShortToStr(dim input as short, dim byref txt as char[6]) IntToStr(dim input as integer, dim byref txt as char[6])
Parameter input represents numerical value of that should be converted to string; parameter txt is passed by address and it contains the result of conversion. All four procedures behave in similar fashion for appropriate input data type. (Parameter txt has to be of sufficient size to fit the converted string.) Following routines convert decimal values to BCD (Binary Coded Decimal) and vice versa:
sub sub sub sub function function function function Bcd2Dec(dim bcd_num as byte) as byte Dec2Bcd(dim dec_num as byte) as byte Bcd2Dec16(dim bcd_num as word) as word Dec2Bcd16(dim dec_num as word) as word
For instance, function Bcd2Dec converts 8-bit BCD numeral bcd_num to its decimal equivalent and returns the result as byte. Simple example:
.. dim a as byte dim b as byte begin a = 140 ' b equals 224 now b = Bcd2Dec(a) end.The following code demonstrates use of library
procedure ShortToStr.
194
page
mikroBASIC
making it simple...
Example
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
This code demonstrates use of library procedure ShortToStr. Example prints the converted value to LCD display.
program num_format_test dim txt as char[20] dim i as short main: PORTB = 0 TRISB = 0 LCD_Init(PORTB) LCD_Cmd(LCD_CLEAR) LCD_Cmd(LCD_CURSOR_OFF) txt = "mikroElektronika" LCD_Out(1,1,txt) Delay_ms(1000) txt = "testing.." LCD_Out(2,1,txt) Delay_ms(1000) LCD_Cmd(LCD_CLEAR) for i = 127 to -111 step -1 ShortToStr(i,txt) LCD_Out(2,1,txt) Delay_ms(100) LCD_Cmd(LCD_CLEAR) next i LCD_Out(1,1,"The End") end.
initial value for portb designate portb as output initialize LCD on portb send command 'clear display' send command 'cursor off' assign text
195
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Trigonometry Library
Trigonometric functions take an angle (in degrees) as parameter of type word and return sine and cosine multiplied by 1000 and rounded up (as integer). Functions implemented in the library are:
sub function sinE3(dim Angle as word) as integer sub function cosE3(dim Angle as word) as integer
Routines
Functions take a word-type number which represents angle in degrees and return the sine of <Angle> as integer, multiplied by 1000 (1E3) and rounded up to nearest integer: result = round_up(sin(Angle)*1000) Thus, the range of the return values for these functions is from -1000 to 1000. For example:
dim angle as word dim result as integer angle = 45; result = sinE3(angle)
Note
Parameter <Angle> cannot be negative. These functions are implemented as lookup tables. The maximum error obtained is 1.
196
page
mikroBASIC
making it simple...
Example
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
The example demonstrates use of library functions sinE3 and cosE3. Example prints the deg, sine and cosine angle values on LCD display. The angle parameter can be altered by pushbuttons on PORTC.0 and PORTC.1.
program TestTrigon dim angle as word dim txtNum as char[6] dim res as integer main: TRISB = 0 TRISC = $FF LCD_Init(PORTB) LCD_Cmd(LCD_CURSOR_OFF) angle = 45 LCD_Out(1,1,"deg") LCD_Out(1,6,"sin") LCD_Out(1,12,"cos") while True LCD_Out(2,1," ") if (Button(PORTC, 0, 1, 1)=True) and (angle < 1000) then inc(angle) end if if (Button(PORTC, 1, 1, 1)=True) and (angle > 0) then dec(angle) end if WordToStr(angle,txtNum) ' convert angle to text LCD_Out(2,1,txtNum) res = sinE3(angle) ' convert 1000*sin(angle) to text IntToStr(res, txtNum) LCD_Out(2,6,txtNum) res = cosE3(angle) IntToStr(res, txtNum) LCD_Out(2,12,txtNum) Delay_ms(100) wend end.
197
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Sound Library
mikroBasic provides a sound library which allows you to use sound signalization in your applications.
Routines
sub procedure Sound_Init(dim byref Port as byte, Pin as byte) sub procedure Sound_Play(dim Period as byte, dim Num_Of_Periods as word)
Procedure Sound_Init initializes sound engine at specified <Port> and <Pin>. Parameter <Pin> needs to be within range 0..7. Procedure Sound_Play plays the sound at the specified port pin. <Period_div_10> is a sound period given in MCU cycles divided by ten, and generated sound lasts for a specified number of periods (<Num_of_Periods>). For example, if you want to play sound of 1KHz: T = 1/f = 1ms = 1000 cycles @ 4MHz. This gives us our first parameter: 1000/10 = 100. We'll play 150 periods like this:
Sound_Play(100, 150)
198
page
mikroBASIC
making it simple...
Example
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
This is a simple demonstration of how to use sound library for playing tones on a piezo speaker. The code can be used with any MCU that has PORTB and ADC on PORTA. Sound frequencies in this example are generated by reading the value from ADC and using the lower byte of the result as base for T (f = 1/T).
program SoundADC dim adcValue as byte begin PORTB TRISB INTCON ADCON1 TRISA
= = = =
0 0 0 $82
= $FF
Clear PORTB PORTB is output Disable all interrupts Configure VDD as Vref, and analog channels PORTA is input
' Initialize sound on PORTB.RB2 ' Get lower byte from ADC ' Play the sound
199
page
mikroBASIC
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
making it simple...
Utilities
mikroBasic provides a set of procedures and functions for faster development of your applications.
Routines
sub function Button(dim byref PORT as byte, dim PIN as byte, dim Time as byte, dim Astate as byte) as byte
The Button function eliminates the influence of contact flickering due to the pressing of a button (debouncing). Parameters PORT and PIN specify the location of the button; parameter Time represents the minimum time interval that pin must be in active state in order to return one; parameter Astate can be only zero or one, and it specifies if button is active on logical zero or logical one. This code demonstrates use of library function Button. Example reads the state on PORTB, pin 0, to which the button is connected. On transition from logical 1 to logical 0 which corresponds to release of a button, value on PORTD is inverted.
Example
program test dim byref oldstate as byte main: PORTD = 255 TRISD = 0 TRISB = 255 while true if Button(PORTB, 0, 1, 1) then oldstate = 255 end if oldstate and Button(PORTB, 0, 1, 0) then portD = 0 oldstate = 0 end if wend if end.
200
page
mikroBASIC
making it simple...
mikroBASIC - Basic Compiler for Microchip PIC microcontrollers
Contact us: If you are experiencing problems with any of our products or you just want additional information, please let us know. Technical Support for compiler If you are experiencing any trouble with mikroBasic, please do not hesitate to contact us - it is in our mutual interest to solve these issues. Discount for schools and universities MikroElektronika offers a special discount for educational institutions. If you would like to purchase mikroBasic for purely educational purposes, please contact us. Problems with transport or delivery If you want to report a delay in delivery or any other problem concerning distribution of our products, please use the link given below. Would you like to become mikroElektronika's distributor? We in mikroElektronika are looking forward to new partnerships. If you would like to help us by becoming distributor of our products, please let us know. Other If you have any other question, comment or a business proposal, please contact us: MikroElektronika magazine Admirala Geprata 1B 11000 Belgrade EUROPE Phone: + 381 (11) 30 66 377, + 381 (11) 30 66 378 Fax: + 381 (11) 30 66 379 E-mail: [email protected] Web: www.mikroelektronika.co.yu
201
page