Professional Documents
Culture Documents
Users manual
mikroBasic
Develop your applications quickly and easily with the world's most advanced BASIC compiler for dsPIC30/33 and PIC24 Microcontrollers (all families). 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 fast and reliable tool, which can satisfy the needs of experienced engineers and beginners alike.
making it simple...
Readers note
DISCLAIMER: mikroBasic 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 mikroElektronika. 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 - 2007. This manual covers mikroBasic for dsPIC30/33 and PIC24 version 4.0 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 support@mikroe.com. Please include the following information in your bug report: - Your operating system - Version of mikroBasic - Code sample - Description of a bug CONTACT US: mikroElektronika Voice: + 381 (11) 30 66 377, + 381 (11) 30 66 378 Fax: + 381 (11) 30 66 379 Web: www.mikroe.com E-mail: office@mikroe.com Support: support@mikroe.com dsPIC30/33 and PIC24, 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 the respective owners.
page
ii
Table of Contents
CHAPTER 1 CHAPTER 2 CHAPTER 3 CHAPTER 4 mikroBasic IDE Building Applications mikroBasic Language Reference mikroBasic Libraries
making it simple...
CHAPTER 1: mikroBasic IDE Quick Overview Code Editor Code Explorer Debugger Error Window Statistics Integrated Tools Keyboard Shortcuts
1 1 3 6 7 10 11 14 16
CHAPTER 2: Building Applications Projects Source Files Search Paths Managing Source Files Compilation Output Files Assembly View Error Messages
19 20 21 21 21 23 23 23 24
CHAPTER 3: mikroBasic Language Reference mikroBasic Specifics Predefined Globals and Constants Accessing Individual Bits Interrupts Linker Directives Code Explorer Code Optimization Lexical Elements Whitespace Comments Tokens Literals Integer Literals Floating Point Literals Character Literals String Literals Keywords Identifiers page
27 28 28 28 29 30 30 31 32 32 33 34 35 35 35 36 36 37 38
iv
Punctuators Program Organization Scope and Visibility Modules Include Clause Main Module Other Modules Variables Constants Labels Symbols Functions and Procedures Functions Procedures Types Simple Types Arrays Strings Pointers Records Types Conversions Implicit Conversion Explicit Conversion Operators Precedence and Associativity Arithmetic Operators Relational Operators Bitwise Operators Boolean Operators Expressions Statements asm Statement Assignment Statements Conditional Statements Iteration Statements Jump Statements Compiler Directives
39 41 44 45 45 46 47 48 49 50 51 52 52 53 55 56 57 58 60 61 63 63 64 65 65 66 67 68 71 72 73 73 74 74 76 78 81
page
mikroElektronika: Development tools - Books - Compilers
making it simple...
84 84 89 90 95 111 128 141 145 189 196 208 218 222 228 233 243 259 268 274 278 281 285 289 296 300 303 306 320 335 336 341 347 349 356 369 380 382 390 395 400 415 417 421
CHAPTER 4: mikroBasic Libraries Built-in Routines Library Routines ADC Library CAN Library CANSPI Library Compact Flash Library EEPROM Library Advanced SPI Ethernet Library SPI Ethernet Library Flash Memory Library I2C Library Keypad Library LCD Library (4-bit interface) LCD Library (8-bit interface) Graphic LCD Library T6963C Graphic LCD Library Multi Media Card Library Manchester Code Library OneWire Library PS/2 Library PWM Library PWM Motor Library RS-485 Software I2C Library Software SPI Library Software UART Library SPI Library UART Library Util Library Conversions Library Math Library Delays Library String Library DSP Library SPI Graphic LCD Library Sound Library Port Expander Library SPI LCD Library (4-bit interface) Library SPI LCD Library (8-bit interface) Library Spi T6963C Graphic LCD Library Setjmp Library Time Library Contact Us page
vi
CHAPTER
mikroBasic IDE
QUICK OVERVIEW
mikroBasic is a powerful, feature rich development tool for dsPIC30/33 and PIC24 micros. It has been designed to provide the customer with the easiest possible solution for developing applications for embedded systems, without compromising performance or control. Highly advanced IDE, broad set of hardware libraries, comprehensive documentation and plenty of ready to run examples should be more than enough to get you started in programming dsPIC30/33 and PIC24 microcontrollers.
making it simple...
Code Explorer
Watch Window
Code Editor
mikroBasic allows you to quickly develop and deploy complex applications: - Write your BASIC source code using the highly advanced Code Editor - Use the included mikroBasic libraries to dramatically speed up development: data acquisition, memory, displays, conversions, communications - Generate commented, human-readable assembly, and standard HEX compatible with all programmers. - Inspect program flow and debug executable logic with the integrated Debugger. Get detailed reports and graphs on code statistics, assembly listing, calling tree - We have provided plenty of examples for you to expand, develop, and use as building bricks in your projects.
page
CODE EDITOR
The Code Editor is advanced text editor fashioned to satisfy the needs of professionals. General code editing is same as working with any standard text-editor, including familiar Copy, Paste, and Undo actions, common for Windows environment. Advanced Editor features include: - Adjustable Syntax Highlighting - Code Assistant - Parameter Assistant - Code Templates - Code Folding - Auto Correct for common typos - Bookmarks and Goto Line You can customize these options from te Editor Settings dialog. To access the settings, click Tools > Options from the drop-down menu, or click the Tools icon.
Tools Icon.
page
mikroElektronika: Development tools - Books - Compilers
making it simple...
Code Assistant [CTRL+SPACE] If you type first few letter of a word and then press CTRL+SPACE, all valid identifiers matching the letters you typed will be prompted to you in a floating panel (see the image). Now you can keep typing to narrow the choice, or you can select one from the list using keyboard arrows and Enter.
Parameter Assistant [CTRL+SHIFT+SPACE] The 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 the Code Template by typing the name of the template (for instance, whileb), 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 the drop-down menu, or click the Tools Icon from the Settings Toolbar, and then select the Auto Complete Tab. Here you can enter the appropriate keyword, description, and code of your template.
page
Auto Correct The Auto Correct feature corrects common typing mistakes. To access the list of recognized typos, select Tools > Options from the drop-down menu, or click the Tools Icon from the Settings Toolbar, and then select the Auto Correct Tab. You can also add your own preferences to the list.
Comment/Uncomment
Comment / Uncomment Icon.
The Code Editor allows you to comment or uncomment selected block of code by a simple click of a mouse, using the Comment/Uncomment icons from the 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 the drop-down menu, or use the shortcut CTRL+G.
page
mikroElektronika: Development tools - Books - Compilers
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 the Code Explorer, use the Collapse/Expand All icon. Also, two more tab windows are available in the Code Explorer. QHelp Tab lists all the available built-in and library functions, for a quick reference. Double-clicking a routine in QHelp Tab opens the relevant Help topic. Keyboard Tab lists all available keyboard shortcuts in mikroBasic.
page
DEBUGGER
Source-level Debugger is an integral component of mikroBasic development environment. It is designed to simulate operations of Microchip Technology's dsPIC30/33 and PIC24micros and to assist users in debugging software written for these devices. Debugger simulates program flow and execution of instruction lines, but does not fully emulate dsPIC30/33 and PIC24 device behavior: it does not update timers, interrupt flags, etc. After you have successfully compiled your project, you can run Debugger by selecting Run > Debug from the 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. Debug [F9] Start the Debugger.
Pause Debugger.
Start Debugger.
Run/Pause Debugger [F6] Run or pause the Debugger. Step Into [F7] Execute the current BASIC (single or multicycle) instruction, then halt. If the instruction is a routine call, enter the routine and halt at the first instruction following the call. Step Over [F8] Execute the current BASIC (single or multicycle) instruction, then halt. If the instruction is a routine call, skip it and halt at the first instruction following the call. Stops at the first breakpoint. Step Out [Ctrl+F8] Execute the current BASIC (single or multicycle) instruction, then halt. If the instruction is within a routine, execute the instruction and halt at the first instruction following the call. Stops at the first breakpoint. Run to cursor [F4] Executes all instructions between the current instruction and the cursor position. Stops at the first breakpoint.
Step Into.
Step Over.
Step Out.
Run to Cursor.
page
mikroElektronika: Development tools - Books - Compilers
making it simple...
Toggle Breakpoint.
Toggle Breakpoint [F5] Toggle breakpoint at the current cursor position. To view all the breakpoints, select Run > View Breakpoints from the drop-down menu. Double clicking an item in window list locates the breakpoint.
Watch Window
Debugger Watch Window is the main Debugger window which allows you to monitor program items while running your program. To show the Watch Window, select View > Debug Windows > Watch Window from the drop-down menu.
The Watch Window displays variables and registers of dsPIC30/33 and PIC24, with their addresses and values. Values are updated as you go through the simulation. Use the drop-down menu to add and remove the items that you want to monitor. Recently changed items are colored red. Double clicking an item opens the Edit Value window in which you can assign a new value to the selected variable/register. Also, you can change view to binary, hex, char, or decimal for the selected item.
page
Stopwatch Window
Debugger Stopwatch Window is available from the drop-down menu, View > Debug Windows > Stopwatch. The Stopwatch Window displays the current count of cycles/time since the last Debugger action. Stopwatch measures the execution time (number of cycles) from the moment Debugger is started, and can be reset at any time. Delta represents the number of cycles between the previous instruction line (line where Debugger action was performed) and the active instruction line (where the Debugger action landed).
Note: You can change the clock in the Stopwatch Window; this will recalculate values for the newly specified frequency. Changing the clock in the Stopwatch Window does not affect the actual project settings it only provides a simulation.
page
mikroElektronika: Development tools - Books - Compilers
making it simple...
ERROR WINDOW
In case that errors were encountered during compiling, compiler will report them and won't generate a hex file. The Error Window will be prompted at the bottom of the main window. The Error Window is located under message tab, and displays location and type of errors compiler has encountered. The compiler also reports warnings, but these do not affect generating hex code. Only errors can interefere with generation of hex.
Double click the message line in the Error Window to highlight the line where the error was encountered. Consult the Error Messages for more information about errors recognized by the compiler.
page
10
STATISTICS
After successful compilation, you can review statistics of your code. Select Project > View Statistics from the drop-down menu, or click the Statistics icon. There are six tab windows: Memory Usage Window Provides overview of RAM and ROM memory usage in form of histogram.
Statistics Icon.
Procedures (Graph) Window Displays functions in form of histogram, according to their memory allotment.
page
mikroElektronika: Development tools - Books - Compilers
11
making it simple...
Procedures (Locations) Window Displays how functions are distributed in the microcontrollers memory.
Procedures (Details) Window Displays the complete call tree, along with details for each routine: size, start and end address, calling frequency, return type, etc.
page
12
RAM Window Summarizes all GPR and SFR registers and their addresses. It 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.
page
mikroElektronika: Development tools - Books - Compilers
13
making it simple...
INTEGRATED TOOLS
USART Terminal mikroBasic includes the USART (Universal Synchronous Asynchronous Receiver Transmitter) communication terminal for RS232 communication. You can launch it from the drop-down menu Tools > Terminal or by clicking the Terminal icon.
ASCII Chart The ASCII Chart is a handy tool, particularly useful when working with LCD display. You can launch it from the drop-down menu Tools > ASCII chart.
page
14
7 Segment Display Decoder The 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 the drop-down menu Tools > 7 Segment Display.
page
mikroElektronika: Development tools - Books - Compilers
15
making it simple...
KEYBOARD SHORTCUTS
Below is the complete list of keyboard shortcuts available in mikroBasic IDE. You can also view keyboard shortcuts in the Code Explorer, tab Keyboard. IDE Shortcuts F1 CTRL+N CTRL+O CTRL+F9 CTRL+F11 CTRL+SHIFT+F5 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 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
page
Help New Module Open Compile Code Explorer on/off View breakpoints
Find, Find Next Select All Copy Find Print Replace Save unit Save As Paste Cut Redo Undo
Code Assistant Parameters Assistant Find declaration Goto line Insert Code Template Goto bookmark Set bookmark Indent selection Unindent selection Select columns
16
Debugger Shortcuts F4 F5 F6 F7 F8 F9 CTRL+F2 Run to Cursor Toggle breakpoint Run/Pause Debugger Step into Step over Debug Reset
page
mikroElektronika: Development tools - Books - Compilers
17
making it simple...
page
18
CHAPTER
Building Applications
Creating applications in mikroBasic is easy and intuitive. Project Wizard allows you to set up your project in just few clicks: name your application, select chip, set flags, and get going. mikroBasic allows you to distribute your projects in as many units as you find appropriate. You can then share your mikroCompiled Libraries (.mcl files) with other developers without disclosing the source code.
making it simple...
PROJECTS
mikroBasic organizes applications into projects, consisting of a single project file (extension .dbp) and one or more source files (extension .dbas). You can compile source files only if they are a part of the project. Project file carries the following information: - project name and optional description - target device - device flags (config word) and device clock - list of project source files with paths
New Project
New Project.
The easiest way to create project is by means of the New Project Wizard, dropdown menu Project > New Project. Just fill the dialog with desired values (project name and description, location, device, clock, config word) and mikroBasic will create the appropriate project file. Also, an empty source file named after the project will be created by default. mikroBasic does not require you to have a source file named same as the project, its just a matter of convenience.
Editing Project
Edit Project.
Later, you can change project settings from the drop-down menu Project > Edit. You can add or remove source files from project, rename the project, modify its description, change chip, clock, config word, etc. To delete a project, simply delete the folder in which the project file is stored.
page
20
SOURCE FILES
Source files containing BASIC code should have the extension .dbas. List of source files relevant for the application is stored in the project file with extension .dbp, along with other project information. You can compile source files only if they are part of a project.
Search Paths You can specify your own custom search paths. This can be configured by selecting Tools > Options from the drop-down menu and Compiler > Search Paths. When including source files with the include clause, mikroBasic will look for the file in following locations, in this particular order: 1. mikroBasic installation folder > defs folder 2. mikroBasic installation folder > uses folder 3. your custom search paths 4. the project folder (folder which contains the project file .dbp)
To create a new source file, do the following: Select File > New from the drop-down menu, or press CTRL+N, or click the New File icon. A new tab will open, named Untitled1. This is your new source file. Select File > Save As from the drop-down menu to name it the way you want. If you have used the New Project Wizard, an empty source file, named after the project with extension .dbas, is created automatically. mikroBasic does not require you to have a source file named same as the project, its just a matter of convenience.
page
mikroElektronika: Development tools - Books - Compilers
21
making it simple...
Select File > Open from the 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 that 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
Print File.
Make sure that the window containing the file that you want to print is the active window. Select File > Print from the 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
Save File.
Make sure that the window containing the file you that want to save is the active window. Select File > Save from the 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 the window containing the file that you want to save is the active window. Select File > Save As from the 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. Click the Save button. Closing a File
Close File.
Make sure that the tab containing the file that you want to close is the active tab. Select File > Close from the drop-down menu, or right click the tab of the file that 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.
page
22
COMPILATION
When you have created the project and written the source code, you will want to compile it. Select Project > Build from the drop-down menu, or click the Build Icon, or simply hit CTRL+F9. Progress bar will appear to inform you about the status of compiling. If there are errors, you will be notified in the Error Window. If no errors are encountered, mikroBasic will generate the output files.
Build Icon.
Output Files Upon successful compilation, mikroBasic will generate output files in the project folder (folder which contains the project file .dbp). Output files are summarized below: Intel HEX file (.hex) Intel style hex records. Use this file to program the chip. Binary mikro Compiled Library (.mcl) Binary distribution of application that can be included in other projects. List File (.lst) Overview of dsPIC30/33 and PIC24 memory allotment: addresses, registers, routines, etc. Assembler File (.asm) Human readable assembly with symbolic names, extracted from the List File. Assembly View
View Assembly Icon.
After compiling your program in mikroBasic, you can click the View Assembly Icon or select Project > View Assembly from the drop-down menu to review generated assembly code (.asm file) in a new tab window. The assembler is human readable with symbolic names. All physical addresses and other information can be found in Statistics or in list file (.lst). If the program is not compiled and there is no assembly file, starting this option will compile your code and then display assembly.
page
mikroElektronika: Development tools - Books - Compilers
23
making it simple...
ERROR MESSAGES
Error Messages
Message
Error: "%s" is not a valid identifier Error: Unknown type "%s" Error: Identifier "%s" was not declared Error: Expected "%s" but "%s" found Error: Argument is out of range Error: Syntax error in additive expression Error: File "%s" not found Error: Invalid command "%s" Error: Not enough parameters Error: Too many parameters Error: Too many characters Error: Actual and formal parameters must be identical Error: Invalid ASM instruction: "%s" Error: Identifier "%s" has been already declared Error: Syntax error in multiplicative expression Error: Definition file for "%s" is corrupted page
Message Number
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
24
Message Number
1 2 3 4 5
page
mikroElektronika: Development tools - Books - Compilers
25
making it simple...
page
26
CHAPTER
making it simple...
mikroBasic SPECIFICS
Predefined Globals and Constants
To facilitate programming, mikroBasic implements a number of predefined globals and constants. All dsPIC30/33 and PIC24 SFR registers are implicitly declared as global variables of word type. These identifiers have external linkage, and are visible in the entire project. When creating a project, mikroBasic will include an appropriate .def file, containing declarations of available SFR and constants (such as W0, TMR1, etc). Identifiers are all in uppercase, identical to the nomenclature in Microchip datasheets. For the complete set of predefined globals and constants, look for Defs in your mikroBasic installation folder, or probe the Code Assistant for specific letters (Ctrl+Space in the Code Editor).
There is no need for any special declarations; this kind of selective access is an intrinsic feature of mikroBasic and can be used anywhere in the code.
page
28
Interrupts
You can create a specific interrupt handler by placing your procedure at the address from interrupt vector table. Use the linker directive org to push routine to specific memory address (see Linker Directives). Consult the datasheet for interrupt vector details. For example, to create a handler for Timer1 interrupt, well use the value $A1 (as stated in datasheet, interupt vector table):
sub procedure Timer1Int org 0x1A IFS0 = IFS0 and 0xFFF7 ' clear TMR1IF ' code for interrupt handling goes here end sub
You dont need to save the context manually. mikroBasic will automatically save registers W0 W13 upon entering the interrupt routine, and restore them upon exit. Example Here is a simple procedure which inverts state of PORTB upon each interrupt from Timer1:
sub procedure Timer1Int org 0x1A IFS0 = IFS0 and 0xFFF7 ' clear TMR1IF LATB = not PORTB ' invert PORTB sub end
page
mikroElektronika: Development tools - Books - Compilers
29
making it simple...
Linker Directives
mikroBasic uses internal algorithm to distribute objects within memory. If you need to have a variable or a routine at the specific predefined address, use the linker directives absolute and org. Note: You must specify an even address when using the linker directives.
Directive absolute Directive absolute specifies the starting address in RAM for a variable. If the variable spans more than 1 word (16-bit), higher words will be stored at the consecutive locations. Directive absolute is appended to the declaration of a variable:
dim x as word absolute $32 ' Variable x will occupy 1 word (16 bits) at address $32 y as longint absolute $34 ' Variable y will occupy 2 words at addresses $34 and $36
Be careful when using the absolute directive, as you may overlap variables by accident. For example:
dim i as word absolute $42 ' Variable i will occupy 1 word at address $42; jj as longint absolute $40 ' Variable will occupy 2 words at $40 and $42; thus, ' changing i changes jj at the same time and vice versa
Directive org Directive org specifies the starting address of a routine in ROM. It is appended to the declaration of a routine. For example:
sub procedure proc(dim par as word) org $200 ' Procedure will start at the address $200; ... end sub
page
30
Code Optimization
Optimizer has been added to extend the compiler usability, cuts down the amount of code generated and speed-up its execution. Main features are: Constant folding All expressions that can be evaluated in the compile time (i.e. are constant) are being replaced by their result. (3 + 5 -> 8); Constant propagation When a constant value is being assigned to certain variable, the compiler recognizes this and replaces the use of the variable in the code that follows by constant, as long as variable's value remains unchanged. Copy propagation The compiler recognizes that two variables have same value and eliminates one of them in the further code. Value numbering The compiler "recognize" if the two expressions yield the same result, and can therefore eliminate the entire computation for one of them. "Dead code" ellimination The code snippets that are not being used elsewhere in the programme do not affect the final result of the application. They are automatically being removed. Stack allocation Temporary registers ("Stacks") are being used more rationally, allowing for VERY complex expressions to be evaluated with minimum stack consumption. Local vars optimization No local variables are being used if their result does not affect some of the global or volatile variables. Better code generation and local optimization Code generation is more consistent, and much attention has been made to implement specific solutions for the code "building bricks" that further reduce output code size.
page
mikroElektronika: Development tools - Books - Compilers
31
making it simple...
LEXICAL ELEMENTS
These topics provide a formal definition of the mikroBasic lexical elements. They describe the different categories of word-like units (tokens) recognized by a language. In the tokenizing phase of compilation, the source code file is parsed (that is, broken down) into tokens and whitespace. The tokens in mikroBasic are derived from a series of operations performed on your programs by the compiler. A mikroBasic program starts as a sequence of ASCII characters representing the source code, created by keystrokes using a suitable text editor (such as the mikroBasic Code Editor). The basic program unit in mikroBasic is the file. This usually corresponds to a named file located in RAM or on disk and having the extension .dbas.
Whitespace
Whitespace is the collective name given to spaces (blanks), horizontal and vertical tabs, newline characters, and comments. Whitespace serves to indicate where tokens start and end, but beyond this function, any surplus whitespace is discarded. Newline Character Newline character (CR/LF) is not a whitespace in BASIC, and serves as a statement terminator/separator. In mikroBasic, however, you may use newline to break long statements into several lines. Parser will first try to get the longest possible expression (across lines if necessary), and then check for statement terminators.
page
32
Whitespace in Strings The ASCII characters representing whitespace can occur within string literals, in which case they are protected from the normal parsing process (they remain as part of the string). For example, statement
some_string = "mikro foo"
Comments
Comments are pieces of text used to annotate a program, and are technically another form of whitespace. Comments are for the programmers use only; they are stripped from the source text before parsing. Use the apostrophe to create a comment:
' Any text between an apostrophe and the end of the ' line constitutes a comment. May span one line only.
page
mikroElektronika: Development tools - Books - Compilers
33
making it simple...
TOKENS
Token is the smallest element of a BASIC program that is meaningful to the compiler. The parser separates tokens from the input stream by creating the longest token possible using the input characters in a lefttoright scan. mikroBasic recognizes these kinds of tokens: - keywords - identifiers - constants - operators - punctuators (also known as separators)
Token Extraction Example Here is an example of token extraction. Lets have the following code sequence:
end_flag = 0
Note that end_flag would be parsed as a single identifier, rather than as the keyword end followed by the identifier _flag.
page
34
LITERALS
Literals are tokens representing fixed numeric or character values. The data type of a constant is deduced by the compiler using such clues as numeric value and the format used in the source code.
Integer Literals
Integral values can be represented in decimal, hexadecimal, or binary notation. In decimal notation, numerals are represented as a sequence of digits (without commas, spaces, or dots), with optional prefix + or - operator to indicate the sign. Values default to positive (6258 is equivalent to +6258). The dollar-sign prefix ($) or the prefix 0x indicates a hexadecimal numeral (for example, $8F or 0x8F). The percent-sign prefix (%) indicates a binary numeral (for example, %0101). The allowed range of values is imposed by the largest data type in mikroBasic
longint. Compiler will report an error if the literal exceeds 2147483647 ($7FFFFFFF).
page
mikroElektronika: Development tools - Books - Compilers
35
making it simple...
Character Literals
Character literal is one character from the extended ASCII character set, enclosed by quotes (for example, "A"). Character literal can be assigned to variables of byte and char type (variable of byte will be assigned the ASCII value of the character). Also, you can assign character literal to a string variable.
String Literals
String literal is a sequence of up to 255 characters from the extended ASCII character set, enclosed by quotes. Whitespace is preserved in string literals, i.e. parser does not go into strings but treats them as single tokens. Length of string literal is the number of characters it consists of. String is stored internally as the given sequence of characters plus a final null character (ASCII zero). This appended stamp does not count against strings total length. String literal with nothing in between the quotes (null string) is stored as a single null character. You can assign string literal to a string variable or to an array of char. Here are several string literals:
"Hello world!" " " "C" "" ' ' ' ' message, 12 chars long two spaces, 2 chars long letter, 1 char long null string, 0 chars long
Quote itself cannot be a part of the string literal, i.e. there is no escape sequence. See String Splicing under Strings (Types) for more inforation.
page
36
KEYWORDS
Keywords are words reserved for special purposes and must not be used as normal identifier names. Beside standard BASIC keywords, all relevant SFR are defined as global variables and represent reserved words that cannot be redefined (for example: W0, TMR1, T1CON, etc). Probe the Code Assistant for specific letters (CTRL+SPACE in Editor) or refer to Predefined Globals and Constants. Here is the alphabetical listing of keywords in mikroBasic:
absolute abs and array asm begin boolean case char chr clear const dim div do double else end exit
float for function goto gosub if include in int integer interrupt is loop label mod module new next not
or org print procedure program read select sub step string switch then to until wend while with xor
Also, mikroBasic includes a number of predefined identifiers used in libraries. You could replace these by your own definitions, if you plan to develop your own libraries. For more information, see mikroBasic Libraries.
page
mikroElektronika: Development tools - Books - Compilers
37
making it simple...
IDENTIFIERS
Identifiers are arbitrary names of any length given to functions, variables, symbolic constants, user-defined data types, and labels. All these program elements will be referred to as objects throughout the help (not to be confused with the meaning of object in object-oriented programming). Identifiers can contain letters a to z and A to Z, the underscore character _, and digits 0 to 9. First character must be a letter or an underscore, i.e. identifier cannot begin with a numeral.
Case Sensitivity
BASIC is not case sensitive, so Sum, sum, and suM represent an equivalent identifier.
Identifier Examples
Here are some valid identifiers:
temperature_V1 Pressure no_hit dat2string SUM3 _vtext
page
38
PUNCTUATORS
The mikroBasic punctuators (also known as separators) include brackets, parentheses, comma, semicolon, colon, and dot.
Brackets
Brackets [ ] indicate single and multidimensional array subscripts:
dim alphabet as byte[30] ' ... alphabet[2] = "c"
Parentheses
Parentheses ( ) are used to group expressions, isolate conditional expressions, and indicate function calls and function declarations:
d = c * (a + b) if (d = z) then ... func() ' Override normal precedence ' Useful with conditional statements ' Function call, no args
For more information, refer to Operators Precedence and Associativity, Expressions, or Functions and Procedures.
Comma
The comma (,) separates the arguments in routine calls:
Lcd_Out(1, 1, txt)
page
mikroElektronika: Development tools - Books - Compilers
39
making it simple...
Colon
Colon (:) is used to indicate a labeled statement:
start: nop '... goto start
Dot
Dot (.) indicates access to a field of a record. For example:
person.surname = "Smith"
For more information, refer to Structures. Dot is also a necessary part of floating point literals. Also, dot can be used for accessing individual bits of registers in mikroBasic.
page
40
PROGRAM ORGANIZATION
mikroBasic imposes strict program organization. Below you can find models for writing legible and organized source files. For more information on file inclusion and scope, refer to Units and to Scope and Visibility.
page
mikroElektronika: Development tools - Books - Compilers
41
making it simple...
page
42
page
mikroElektronika: Development tools - Books - Compilers
43
making it simple...
Visibility
The visibility of an identifier is that region of the program source code from which legal access can be made to the identifiers associated object. Scope and visibility usually coincide, though there are circumstances under which an object becomes temporarily hidden by the appearance of a duplicate identifier: the object still exists but the original identifier cannot be used to access it until the scope of the duplicate identifier is ended. Technically, visibility cannot exceed scope, but scope can exceed visibility.
page
44
MODULES
In mikroBasic, each project consists of a single project file, and one or more unit files. Project file, with extension .dbp contains information about the project, while modules, with extension .dbas, contain the actual source code. Modules allow you to: - break large programs into encapsulated modules that can be edited separately, - create libraries that can be used in different projects, - distribute libraries to other developers without disclosing the source code. Each module is stored in its own file and compiled separately; compiled modules are linked to create an application. To build a project, the compiler needs either a source file or a compiled module file for each module.
Include Clause
mikroBasic includes modules by means of include clause. It consists of the reserved word include, followed by a quoted module name. Extension of the file should not be included. You can include one file per include clause. There can be any number of include clauses in each source file, but they all must be stated immediately after the program (or module) name. Heres an example:
program MyProgram include "utils" include "strings" include "MyUnit" ...
page
mikroElektronika: Development tools - Books - Compilers
45
making it simple...
Given a unit name, compiler will check for the presence of .mcl and .dbas files, in order specified by the search paths. - If both .dbas and .mcl files are found, compiler will check their dates and include the newer one in the project. If the .dbas file is newer than the .mcl, new library will be written over the old one; - If only .dbas file is found, compiler will create the .mcl file and include it in the project; - If only .mcl file is present, i.e. no source code is available, compiler will include it as found; - If none found, compiler will issue a File not found warning.
Main Module
Every project in mikroBasic requires a single main module file. Main unit is identified by the keyword program at the beginning; it instructs the compiler where to start. After you have successfully created an empty project with Project Wizard, Code Editor will display a new main unit. It contains the bare-bones of a program:
program MyProject ' main procedure main: ' Place program code here end.
Other than comments, nothing should precede the keyword program. After the program name, you can optionally place the include clauses. Place all global declarations (constants, variables, labels, routines) before the label main.
page
46
Other Modules
Modules other than main start with the keyword module. Newly created blank unit contains the bare-bones:
module MyModule implements end.
Other than comments, nothing should precede the keyword module. After the module name, you can optionally place the include clauses. Interface Section Part of the unit above the keyword implements is referred to as interface section. Here, you can place global declarations (constants, variables, and labels) for the project. You do not define routines in the interface section. Instead, state the prototypes of routines (from implementation section) that you want to be visible outside the unit. Prototypes must match the declarations exactly. Implementation Section Implementation section hides all the irrelevant innards from other units, thus encapsulating the code. Everything declared below the keyword implements is private, i.e. has its scope limited to the file. When you declare an identifier in the implementation section of a unit, you cannot use it outside the unit, but you can use it in any block or routine defined within the unit. By placing the prototype in the interface section of the unit (above the word implements) you can make the routine public, i.e. visible outside of unit. Prototypes must match the declarations exactly.
page
mikroElektronika: Development tools - Books - Compilers
47
making it simple...
VARIABLES
Variable is object 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. Variables are declared in the declaration part of the file or routine each variable needs to be declared before it can be used. Global variables (those that do not belong to any enclosing block) are declared below the include statements, above the label main. Specifying a data type for each variable is mandatory. Basic syntax for variable declaration is:
dim identifier_list as type
The identifier_list is a comma-delimited list of valid identifiers and type can be any data type. For more details refer to Types and Types Conversions. For more information on variables scope refer to the chapter Scope and Visibility. Here are a few examples:
dim i, j, k as byte dim counter, temp as word dim samples as longint[100]
page
48
CONSTANTS
Constant is data whose value cannot be changed during the runtime. Using a constant in a program consumes no RAM memory. Constants can be used in any expression, but cannot be assigned a new value. Constants are declared in the declaration part of program or routine, with the following syntax:
const constant_name [as type] = value
Every constant is declared under unique constant_name which must be a valid identifier. It is a tradition to write constant names in uppercase. Constant requires you to specify value, which is a literal appropriate for the given type. The type is optional; in the absence of type, compiler assumes the smallest type that can accommodate value. Note: You cannot omit type if declaring a constant array. BASIC allows shorthand syntax with only one keyword const followed by multiple constant declarations. Heres an example:
const const const const const MAX as longint = 10000 MIN = 1000 ' compiler will assume word type SWITCH = "n" ' compiler will assume char type MSG = "Hello" ' compiler will assume string type MONTHS as byte[12] = (31,28,31,30,31,30,31,31,30,31,30,31)
page
mikroElektronika: Development tools - Books - Compilers
49
making it simple...
LABELS
Labels serve as targets for goto statements. Mark the desired statement with label and a colon like this:
label_identifier : statement
No special declaration of label is necessary in mikroBasic. Name of the label needs to be a valid identifier. The labeled statement, and goto/gosub statement must belong to the same block. Hence it is not possible to jump into or out of routine. Do not mark more than one statement in a block with the same label. Note: Label main marks the entry point of a program and must be present in the main module of every project. See Program Organization for more information. Here is an example of an infinite loop that calls the procedure Beep repeatedly:
loop: Beep goto loop
page
50
SYMBOLS
BASIC symbols allow you to create simple macros without parameters. You can replace any one line of code with a single identifier alias. Symbols, when properly used, can increase code legibility and reusability. Symbols need to be declared at the very beginning of the module, right after the module name and the (optional) include clauses. Check Program Organization for more details. Scope of a symbol is always limited to the file in which it has been declared. Symbol is declared as:
symbol alias = code
Here, alias must be a valid identifier which you will be using throughout the code. This identifier has file scope. The code can be any one line of code (literals, assignments, function calls, etc). Using a symbol in program consumes no RAM memory compiler simply replaces each instance of a symbol with the appropriate line of code from the declaration. Here is an example:
symbol MAXALLOWED = 216 symbol PORT = PORTC symbol MYDELAY = Delay_ms(1000) dim cnt as byte '... main: if cnt > MAXALLOWED then cnt = 0 PORT.1 = 0 MYDELAY end if ' Some variable ' Alias for numeric value ' Alias for SFR ' Alias for procedure call
Note: Symbols do not support macro expansion in the way C preprocessor does.
page
mikroElektronika: Development tools - Books - Compilers
51
making it simple...
Functions
Function is declared like this:
sub function function_name(parameter_list) as return_type [ local declarations ] function body end sub
The function_name represents a functions name and can be any valid identifier. The return_type is the type of return value and can be any simple type. Within parentheses, parameter_list is a formal parameter list similar to variable declaration. In mikroBasic, parameters are always passed to function by value; to pass argument by the address, add the keyword var ahead of identifier.
Local declarations are optional declarations of variables and/or constants, local for the given function. Function body is a sequence of statements to be
executed upon calling the function. A function is called by its name, with actual arguments placed in the same sequence as their matching formal parameters. The compiler is able to coerce mismatching arguments to the proper type according to implicit conversion rules. Upon function call, all formal parameters are created as local objects initialized by values of actual arguments. Upon return from a function, temporary object is created in the place of the call, and it is initialized by the expression of return statement. This means that function call as an operand in complex expression is treated as the function result. Use the variable result (automatically created local) to assign the return value of a function.
page
52
Function calls are considered to be primary expressions, and can be used in situations where expression is expected. Function call can also be a self-contained statement, in which case the return value is discarded. Heres a simple function which calculates xn based on input parameters x and n (n > 0):
sub function power(dim x, n as byte) as longint dim i as byte i = 0 result = 1 if n > 0 then for i = 1 to n result = result*x next i end if end sub
Procedures
Procedure is declared like this:
sub procedure procedure_name(parameter_list) [ local declarations ] procedure body end sub
The procedure_name represents a procedures name and can be any valid identifier. Within parentheses, parameter_list is a formal parameter list similar to variable declaration. In mikroBasic, parameters are always passed to procedure by value; to pass argument by the address, add the keyword var ahead of identifier.
Local declarations are optional declaration of variables and/or constants, local for the given procedure. Procedure body is a sequence of statements to be
page
mikroElektronika: Development tools - Books - Compilers
53
making it simple...
A procedure is called by its name, with actual arguments placed in the same sequence as their matching formal parameters. The compiler is able to coerce mismatching arguments to the proper type according to implicit conversion rules. Upon procedure call, all formal parameters are created as local objects initialized by values of actual arguments. Procedure call is a self-contained statement. Heres an example procedure which transforms its input time parameters, preparing them for output on LCD:
sub procedure time_prep(dim byref sec, min, hr as byte) sec = ((sec and $F0) >> 4)*10 + (sec and $0F) min = ((min and $F0) >> 4)*10 + (min and $0F) hr = ((hr and $F0) >> 4)*10 + (hr and $0F) end sub
page
54
TYPES
BASIC is a strictly typed language, which means that every variable and constant needs to have a strictly defined type, known at the time of compilation. The type serves: - to determine the correct memory allocation required, - to interpret the bit patterns found in the object during subsequent accesses, - in many type-checking situations, to ensure that illegal assignments are trapped. mikroBasic supports many standard (predefined) and user-defined data types, including signed and unsigned integers of various sizes, arrays, strings, pointers, and records.
Type Categories
Types can be divided into: - simple types - arrays - strings - pointers - structures (user defined types)
page
mikroElektronika: Development tools - Books - Compilers
55
making it simple...
SIMPLE TYPES
Simple types represent types that cannot be divided into more basic elements, and are the model for representing elementary data on machine level. Here is an overview of simple types in mikroBasic:
Type
word, byte, char integer, short longint float
Range 0 .. 65535 -32768 .. 32767 -2147483648 .. 2147483647 1.17549435082 * 10-38 .. 6.80564774407 * 1038
Note: Italicized types (char, byte, and short) are kept in mikroBasic for dsPIC for the sake of backward compatibility. Types char and byte behave exactly as the 16-bit word, while short is a synonym for integer. You cannot mix signed and unsigned objects in expressions with arithmetic or logical operators. You can assign signed to unsigned or vice versa only using the explicit conversion. Refer to Types Conversions for more information. Bit Type mikroBasic for dsPIC includes a special bit type. Variables of this type behave as 16-bit words, so they are not 0/1 flags. The bit type has its use for passing parameters to routines, and is commonly served in format REGISTER.PIN (see Accessing Individual Bits for more information). If bit type parameter is passed by the address, two words are pushed on stack: the address of the origin register, and bit position in register (15 being the most significant bit). If bit type parameter is passed by the value, then 0 or 1 is pushed on stack and can be accessed as any other variable of word type.
page
56
ARRAYS
An array represents an indexed collection of elements of the same type (called the base type). Because each element has a unique index, arrays, unlike sets, can meaningfully contain the same value more than once. Array types are denoted by constructions of the form:
type[array_length]
Each of the elements of an array is numbered from 0 through the array_length - 1. Every element of an array is of type and can be accessed by specifying array name followed by elements index within brackets. Here are a few examples of array declaration:
dim weekdays as byte[7] dim samples as word[50] main: ' Now we can access elements of array variables, for example: samples[0] = 1 if samples[37] = 0 then ' ...
Constant Arrays Constant array is initialized by assigning it a comma-delimited sequence of values within parentheses. For example:
' Declare a constant array which holds no. of days in each month: const MONTHS as byte[12] = (31,28,31,30,31,30,31,31,30,31,30,31)
Note that indexing is zero based; in the previous example, number of days in January is MONTHS[0], and number of days in December is MONTHS[11]. The number of assigned values must not exceed the specified length. Vice versa is possible, when the trailing excess elements will be assigned zeroes. For more information on arrays of char, refer to Strings.
page
mikroElektronika: Development tools - Books - Compilers
57
making it simple...
STRINGS
A string represents a sequence of characters, and is an equivalent to an array of char. It is declared like:
string[string_length]
Specifier string_length is the number of characters string consists of. String is stored internally as the given sequence of characters plus a final null character (zero). This appended stamp does not count against strings total length. A null string ("") is stored as a single null character. You can assign string literals or other strings to string variables. String on the right side of an assignment operator has to be the shorter of the two, or of equal length. For example:
dim msg1 as string[20] dim msg2 as string[19] main: msg1 = "This is some message" msg2 = "Yet another message" msg1 = msg2 ' this is ok, but vice versa would be illegal
Be careful when handling strings in this way, since overwriting the end of a string can cause access violations.
page
58
String Splicing
mikroBasic allows you to splice strings by means of plus character (+). This kind of concatenation is applicable to string variables/literals and character variables/literals. For control characters, use the mikroBasics built-in function Chr (e.g. Chr(13) for CR). The result of splicing is of string type. See also Concat function. Here is an example:
dim msg as string[100] dim res_txt as string[5] dim res, channel as word main: res = Adc_Read(channel) WordToStr(res, res_txt) ' Get result of ADC ' Create string out of numeric result
' Prepare message for output msg = "Result is" + ' Text "Result is" Chr(13) + ' Append CR (carriage return) Chr(10) + ' Append LF (linefeed) res_txt + ' Result of ADC "." ' Append a dot '...
Note: mikroBasic includes a String Library which automatizes string related tasks.
page
mikroElektronika: Development tools - Books - Compilers
59
making it simple...
POINTERS
A pointer is a data type which holds a memory address. While a variable accesses that memory address directly, a pointer can be thought of as a reference to that memory address. To declare a pointer data type, add a carat prefix (^) before the type. For example, if you are creating a pointer to an integer, you would write:
^integer;
To access data at the pointers memory location, add a carat after the variable name. For example, lets declare variable p which points to a word, and then assign the pointed memory location value 5:
dim p as ^word '... p^ = 5
A pointer can be assigned to another pointer. However, note that only the address, not the value, is copied. Once you modify the data located at one pointer, the other pointer, when dereferenced, also yields modified data. @ Operator The @ operator returns the address of a variable or routine; that is, @ constructs a pointer to its operand. The following rules apply to @: - If X is a variable, @X returns the address of X. - If F is a routine (a function or procedure), @F returns Fs entry point (result is of longint).
page
60
STRUCTURES
A structure represents a heterogeneous set of elements. Each element is called a member; the declaration of a structure type specifies a name and type for each member. The syntax of a structure type declaration is
structure structname dim member1 as type1 '... dim membern as typen end structure
where structname is a valid identifier, each type denotes a type, and each member is a valid identifier. The scope of a member identifier is limited to the structure in which it occurs, so you dont have to worry about naming conflicts between member identifiers and other variables. For example, the following declaration creates a structure type called Dot:
structure Dot dim x as float dim y as float end structure
Each Dot contains two members: x and y coordinates; memory is allocated when you instantiate the structure, like this:
dim m, n as Dot
This variable declaration creates two instances of Dot, called m and n. A member can be of a previously defined structure type. For example:
' Structure defining a circle: structure Circle dim radius as float dim center as Dot end structure
page
mikroElektronika: Development tools - Books - Compilers
61
making it simple...
You can also commit assignments between complex variables, if they are of the same type:
circle2 = circle1 ' This will copy values of all members
page
62
TYPES CONVERSIONS
Conversion of object of one type is changing it to the same object of another type (i.e. applying another type to a given object). mikroBasic supports both implicit and explicit conversions for built-in types.
Implicit Conversion
You cannot mix signed and unsigned objects in expressions with arithmetic or logical operators. You can assign signed to unsigned or vice versa only using the explicit conversion. Compiler will provide an automatic implicit conversion in the following situations: - statement requires an expression of particular type (according to language definition), and we use an expression of different type, - operator requires an operand of particular type, and we use an operand of different type, - function requires a formal parameter of particular type, and we pass it an object of different type, - result does not match the declared function return type.
Promotion When operands are of different types, implicit conversion promotes the less complex to more complex type taking the following steps:
byte/char short short integer integral -> -> -> -> -> word integer longint longint float
Higher bytes of extended unsigned operand are filled with zeroes. Higher bytes of extended signed operand are filled with bit sign (if number is negative, fill higher bytes with one, otherwise with zeroes).
page
mikroElektronika: Development tools - Books - Compilers
63
making it simple...
Clipping In assignments, and statements that require an expression of particular type, 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). If expression evaluates to a more complex type than expected, excess data will be simply clipped (higher bytes are lost).
dim i as byte dim j as word '... j = $FF0F i = j ' i becomes $0F, higher byte $FF is lost
Explicit Conversion
Explicit conversion can be executed at any point by inserting type keyword (byte, word, short, integer or longint) ahead of the expression to be converted. The expression must be enclosed in parentheses. Explicit conversion can be performed only on the operand left of the assignment operator. Special case is the conversion between signed and unsigned types. Explicit conversion between signed and unsigned data does not change binary representation of data; it merely allows copying of source to destination. For example:
dim a as byte dim b as short '... b = -1 a = byte(b) ' a is 255, not 1 ' This is because binary representation remains ' 11111111; it's just interpreted differently now
You cannot execute explicit conversion on the operand left of the assignment operator.
page
64
OPERATORS
Operators are tokens that trigger some computation when applied to variables and other objects in an expression. There are four types of operators in mikroBasic: - Arithmetic Operators - Bitwise Operators - Boolean Operators - Relational Operators
Precedence 4 3 2 1 1 2 2 2
Operands
Operators
@ not + -
<<
>>
left-to-right
page
mikroElektronika: Development tools - Books - Compilers
65
making it simple...
Arithmetic Operators
Arithmetic operators are used to perform mathematical computations. They have numerical operands and return numerical results. As char operators are technically bytes, they can be also used as unsigned operands in arithmetic operations. Operands need to be either both signed or both unsigned. All arithmetic operators associate from left to right.
Operation
Precedence 2 2 3 3 3 3
division, rounds down to nearest integer returns the remainder of integer division (cannot be used with floating points)
Operator - can be used as a prefix unary operator to change sign of a signed value. Unary prefix operator + can be used, but it doesnt affect the data. For example: b = -a Division by Zero 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).
page
66
Relational Operators
Use relational operators to test equality or inequality of expressions. All relational operators return TRUE or FALSE. All relational operators associate from left to right.
Operation equal not equal greater than less than greater than or equal less than or equal
Precedence 1 1 1 1 1 1
Relational Operators in Expressions Precedence of arithmetic and relational operators was designated in such a way to allow complex expressions without parentheses to have expected meaning:
a + 5 >= c - 1.0 / e ' i.e. (a + 5) >= (c - (1.0 / e))
page
mikroElektronika: Development tools - Books - Compilers
67
making it simple...
Bitwise Operators
Use the bitwise operators to modify the individual bits of numerical operands. Operands need to be either both signed or both unsigned. Bitwise operators associate from left to right. The only exception is the bitwise complement operator not which associates from right to left.
Operator
and or xor not << >>
Operation bitwise AND; returns 1 if both bits are 1, otherwise returns 0 bitwise (inclusive) OR; returns 1 if either or both bits are 1, otherwise returns 0 bitwise exclusive OR (XOR); returns 1 if the bits are complementary, otherwise 0 bitwise complement (unary); inverts each bit bitwise shift left; moves the bits to the left, see below bitwise shift right; moves the bits to the right, see below
Precedence 3 2 2 4 3 3
Bitwise operators and, or, and xor perform logical operations on appropriate pairs of bits of their operands. Operator not complements each bit of its operand. For example:
$1234 and $5678 ' because .. ' $1234 : 0001 0010 0011 0100 ' $5678 : 0101 0110 0111 1000 ' ---------------------------' and : 0001 0010 0011 0000 ' .. that is, $1230 ' equals $1230
page
68
Unsigned and Conversions If number is converted from less complex to more complex data type, upper bytes are filled with zeroes. If number is converted from more complex to less complex data type, data is simply truncated (upper bytes are lost). For example:
dim a dim b ' ... a = b = b = ' a as byte as word $AA $F0F0 b and a is extended with zeroes; b becomes $00A0
Signed and Conversions 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 zeroes 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). For example:
dim a dim b ' ... a = b = b = as byte as word -12 $70FF b and a
page
mikroElektronika: Development tools - Books - Compilers
69
making it simple...
Bitwise Shift Operators Binary operators << and >> move the bits of the left operand for a number of positions specified by the right operand, to the left or right, respectively. Right operand has to be positive and less than 255. With shift left (<<), left most bits are discarded, and new bits on the right are assigned zeroes. Thus, shifting unsigned operand to the left by n positions is equivalent to multiplying it by 2n if all the discarded bits are zero. This is also true for signed operands if all the discarded bits are equal to the sign bit. With shift right ( >>), right most bits are discarded, and the freed bits on the left are assigned zeroes (in case of unsigned operand) or the value of the sign bit (in case of signed operand). Shifting operand to the right by n positions is equivalent to dividing it by 2n.
page
70
Boolean Operators
Although mikroBasic does not support boolean type, you have Boolean operators at your disposal for building complex conditional expressions. These operators conform to standard Boolean logic, and return either TRUE (all ones) or FALSE (zero):
Operator
and or xor not
Boolean operators associate from left to right. Negation operator not associates from right to left.
page
mikroElektronika: Development tools - Books - Compilers
71
making it simple...
EXPRESSIONS
An expression is a sequence of operators, operands, and punctuators that returns a value. The primary expressions include: literals, variables, and function calls. From these, using operators, more complex expressions can be created. Formally, expressions are defined recursively: subexpressions can be nested up to the limits of memory. Expressions are evaluated according to certain conversion, grouping, associativity and precedence rules that depend on the operators used, the presence of parentheses and the data types of the operands. Precedence and associativity of the operators are summarized in Operator Precedence and Associativity. The way operands and subexpressions are grouped does not necessarily specify the actual order in which they are evaluated by mikroBasic. You cannot mix signed and unsigned data types in assignment expressions or in expressions with arithmetic or logical operators. You can use explicit conversion though.
page
72
STATEMENTS
Statements define algorithmic actions within a program. Each statement needs to be terminated by a newline character (CR/LF). The simplest statements include assignments, routine calls and jump statements. These can be combined to form loops, branches, and other structured statements. In the absence of specific jump and selection statements, statements are executed sequentially in order of appearance in the source code. Statements can be roughly divided into: - asm Statement - Assignment Statements - Conditional Statements - Iteration Statements (Loops) - Jump Statements
asm Statement
mikroBasic allows embedding assembly in the source code by means of asm statement. Note that you cannot use numerals as absolute addresses for register variables in assembly instructions. You may use symbolic names instead (listing will display these names as well as addresses). Denote a group of assembly instructions with the keyword asm:
asm block of assembly instructions end asm
BASIC comments are not allowed in embedded assembly code. Instead, you may use one-line assembly comments starting with semicolon. If you plan to use a certain BASIC variable only in the embedded assembler, be sure to at least initialize it (assign it initial value) in BASIC code; otherwise, linker will issue an error. This does not apply to predefined globals such as PORTB.
page
mikroElektronika: Development tools - Books - Compilers
73
making it simple...
Assignment Statements
Assignment statements have the form:
variable = expression
The statement evaluates the expression and assigns its value to the variable. All rules of the implicit conversion apply. Variable can be any declared variable or array element, and expression can be any expression. Do not confuse the assignment with the relational operator = which tests for equality. mikroBasic will interpret the meaning of the character = from the context.
Conditional Statements
Conditional or selection statements select from alternative courses of action by testing certain values. There are two types of selection statements in mikroBasic: if and select case. If Statement Use the keyword if to implement a conditional statement. Syntax of the if statement has the form:
if expression then statements [else other statements] end if
When expression evaluates to true, statements execute. If the expression is false, other statements execute. The expression must convert to a boolean type; otherwise, the condition is ill-formed. The else keyword with an alternate block of statements (other statements) is optional. 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.
page
74
Select Case Statement Use the select case statement to pass control to a specific program branch, based on a certain condition. The select case statement consists of a selector expression (a condition) and a list of possible values. Syntax of select case statement is:
select case selector case value_1 statements_1 ... case value_n statements_n [case else default_statements] end select
The selector is an expression which should evaluate as integral value. The values can be literals, constants, or expressions, and statements can be any statements. The case else clause is optional. First, the selector expression (condition) is evaluated. The select case statement then compares it against all the available values. If the match is found, the statements following the match evaluate, and select case statement terminates. In case that there are multiple matches, the first matching statement will be executed. If none of the values matches the selector, then the default_statements in the case else clause (if there is one) are executed. Here is a simple example of select case statement:
select case operator case "+" res = n1 + n2 case "-" res = n1 - n2 case else res = 0 cnt = cnt + 1 end select
Also, you can group values together for a match. Simply separate the values by commas. Note that select case statements can be nested values are then assigned to the innermost enclosing select case statement.
page
mikroElektronika: Development tools - Books - Compilers
75
making it simple...
For Statement The for statement implements an iterative loop and requires you to specify the number of iterations. Syntax of for statement is:
for counter = initial_value to final_value [step step_value] statements next counter
The counter is a variable which increases by step_value with each iteration of the loop. Parameter step_value is an optional integral value, and defaults to 1 if omitted. Before the first iteration, counter is set to the initial_value and will increment until it reaches (or exceeds) the final_value. With each iteration, statements will be executed. The initial_value and final_value should be expressions compatible with the counter; statements can be any statements that do not change the value of counter. Note that parameter step_value may be negative, allowing you to create a countdown. Here is an example of calculating scalar product of two vectors, a and b, of length n, using for statement:
s = 0 for i = 0 to n s = s + a[i] * b[i] next i
The for statement results in an endless loop if the final_value equals or exceeds the range of counters type.
page
76
While Statement Use the while keyword to conditionally iterate a statement. Syntax of while statement is:
while expression statements wend
The statements are executed repeatedly as long as the expression evaluates true. The test takes place before the statements are executed. Thus, if expression evaluates false on the first pass, the loop does not execute. Here is an example of calculating scalar product of two vectors, using the while statement:
s = 0 i = 0 while i < n s = s + a[i] * b[i] i = i + 1 wend
Do Statement The do statement executes until the condition becomes true. Syntax of do statement is:
do statements loop until expression
The statements are executed repeatedly until the expression evaluates true. The expression is evaluated after each iteration, so the loop will execute statements at least once. Here is an example of calculating scalar product of two vectors, using the do statement:
s = 0 i = 0 do s = s + a[i] * b[i] i = i + 1 loop until i = n
page
mikroElektronika: Development tools - Books - Compilers
77
making it simple...
Jump Statements
A jump statement, when executed, transfers control unconditionally. There are five such statements in mikroBasic: break, continue, exit, goto and gosub.
Break Statement Sometimes, you might need to stop the loop from within its body. Use break within loops to pass control to the first statement following the innermost loop (for, while or do). For example:
' Wait for CF card to be plugged; refresh every second while true Lcd_Out(1, 1, "No card inserted") if Cf_Detect() = 1 then break end if Delay_ms(1000) wend ' Now we can work with CF card ... Lcd_Out(1, 1, "Card detected ")
Continue Statement You can use the continue statement within loops to skip the cycle: - continue statement in for loop moves program counter to the line with keyword for; it does not change the loop counter, - continue statement in while loop moves program counter to the line with loop condition (top of the loop), - continue statement in do loop moves program counter to the line with loop condition (bottom of the loop).
page
78
Exit Statement The exit statement allows you to break out of a routine (function or procedure). It passes the control to the first statement following the routine call. Here is a simple example:
sub procedure Proc1() dim error as byte ... ' we're doing something here if error = TRUE then exit end if ... ' some code, which won't be executed if error is true end sub
Note: If breaking out of a function, return value will be the value of the local variable result at the moment of exit.
Goto Statement Use the goto statement to unconditionally jump to a local label for more information, refer to Labels. Syntax of goto statement is:
goto label_name
This will transfer control to the location of a local label specified by label_name. The goto line can come before or after the label. It is not possible to jump into or out of routine. You can use goto to break out from any level of nested control structures. Never jump into a loop or other structured statement, since this can have unpredictable effects. Use of goto statement is generally discouraged as practically every algorithm can be realized without it, resulting in legible structured programs. One possible application of goto statement is breaking out from deeply nested control structures.
page
mikroElektronika: Development tools - Books - Compilers
79
making it simple...
Gosub Statement Use the gosub statement to unconditionally jump to a local label for more information, refer to Labels. Syntax of gosub statement is:
gosub label_name ... label_name: ... return
This will transfer control to the location of a local label specified by label_name. Also, the calling point is remembered. Upon encountering a return statement, program execution will continue with the next statement (line) after the gosub. The gosub line can come before or after the label. It is not possible to jump into or out of routine by means of gosub. Never jump into a loop or other structured statement, since this can have unpredictable effects. Note: Like with goto, use of gosub statement is generally discouraged. mikroBasic supports gosub only for the sake of backward compatibility. It is better to rely on functions and procedures, creating legible structured programs.
page
80
COMPILER DIRECTIVES
Any line in source code with a leading # is taken as a compiler directive. The initial # can be preceded or followed by whitespace (excluding new lines). Compiler directives are not case sensitive. You can use conditional compilation to select particular sections of code to compile while excluding other sections. All compiler directives must be completed in the source file in which they begun.
Directives #DEFINE and #UNDEFINE Use directive #DEFINE to define a conditional compiler constant (flag). You can use any identifier for a flag, with no limitations. No conflicts with program identifiers are possible, as flags have a separate name space. Only one flag can be set per directive. For example: #DEFINE extended_format Use #UNDEFINE to undefine (clear) previously defined flag.
Directive #IFDEF Conditional compilation is carried out by the #IFDEF directive. The #IFDEF tests whether a flag is currently defined or not; that is, whether a previous #DEFINE directive has been processed for that flag and is still in force. Directive #IFDEF is terminated by the #ENDIF directive, and can have any number of #ELSEIF clauses and an optional #ELSE clause:
#IFDEF flag THEN block of code [ #ELSEIF flag_1 THEN block of code 1 ... #ELSEIF flag_n THEN block of code n ] [ #ELSE alternate block of code ] #ENDIF
page
mikroElektronika: Development tools - Books - Compilers
81
making it simple...
First, #IFDEF checks if the flag is set by means of #DEFINE. If so, only block of code will be compiled. Otherwise, compiler will check flags flag_1 .. flag_n and execute the appropriate block of code i. Eventually, if none of the flags is set, alternate block of code in the #ELSE (if any) will be compiled. The #ENDIF ends the conditional sequence. The result of the preceding scenario is that only one section of code (possibly empty) is passed on for further processing. The processed section can contain further conditional clauses, nested to any depth; each #IFDEF must be matched with a closing #ENDIF. Here is an example:
' Uncomment the appropriate flag for your application: '#DEFINE resolution8 '#DEFINE resolution10 '#DEFINE resolution12 #IFDEF resolution8 THEN ... ' code specific to 8-bit resolution #ELSEIF resolution10 THEN ... ' code specific to 10-bit resolution #ELSEIF resolution12 THEN ... ' code specific to 12-bit resolution #ELSE ... ' default code #ENDIF
Predefined Flags mikroBasic has several predefined flags for configuring hardware. These can be found in definition files (defs folder), specifying hardware settings for individual chips. SFR are sorted under categories: ___SFR (umbrella for all registers), ___CONFIG_OSC (oscillator), ___CONFIG_WDT (Watchdog timer), and ___CONFIG_BORPOR (brownout reset and powerontimer).
page
82
CHAPTER
mikroBasic Libraries
mikroBasic provides a number of built-in and library routines which can help you develop your applications faster and easier. Libraries for ADC, UART, SPI, I2C, LCD, GLCD, PWM, MMC/SD, SPI Ethernet, T6963C, Port Expander, numeric formatting, and many other are included along with practical, ready-to-use code examples.
making it simple...
BUILT-IN ROUTINES
mikroBasic compiler provides a set of useful built-in utility functions. Built-in routines can be used in any part of the project. Currently, mikroBasic includes following built-in functions:
LoWord HiWord Lo Hi Higher Highest SizeOf Chr Ord SetBit ClearBit TestBit Inc Dec Clock_Khz Clock_Mhz
LoWord
Prototype Returns Description
sub function LoWord(number as longint) as word
Lower 16 bits (word) of number. Function returns lower word of number. Function does not interpret bit patterns of number it merely returns lower 16 bits as found in register.
a = LoWord($AC10F4) ' Equals $10F4
Example
page
84
HiWord
Prototype Returns Description Example
sub function HiWord(number as longint) as word
Higher 16 bits (word) of number. Function returns higher word of number. Function does not interpret bit patterns of number it merely returns higher 16 bits as found in register.
a = HiWord($AC10F4) ' Equals $00AC
Lo
Prototype Returns Description Example
sub function Lo(val as longint) as byte
Returns the lowest 8 bits (byte) of val. Function returns the lowest byte of val. Function does not interpret bit patterns of number it merely returns lowest 8 bits as found in register.
d = 0x1AC30F4 tmp = Lo(d) ' Equals 0xF4
Hi
Prototype Returns Description Example
sub function Hi(val as longint) as byte
Returns next to the lowest 8 bits (byte) of val. Function returns next to the lowest byte of val. Function does not interpret bit patterns of number it merely returns next to the lowest 8 bits as found in register.
d = 0x1AC30F4 tmp = Hib(d) ' Equals 0x30
Higher
Prototype Returns Description Example
sub function Higher(val as longint) as byte
Returns next to the high byte of (byte) of val bits 16..23. Function returns next to the high byte of val. Function does not interpret bit patterns of number it merely returns next to the high 8 bits as found in register.
d = 0x1AC30F4 tmp = Higherb(d) ' Equals 0xAC
page
mikroElektronika: Development tools - Books - Compilers
85
making it simple...
Highest
Prototype Returns Description Example
sub function Highest(val as longint) as byte
Returns the highest (byte) of val. Function returns the highest byte of val. Function does not interpret bit patterns of number it merely returns the highest 8 bits as found in register.
d = 0x1AC30F4 tmp = Highestb(d) ' Equals 0x01
SizeOf
Returns size in bytes of a variable. This function gives the size in bytes of how much memory space is used by its operand.
structure TStruct dim FieldA as byte ' 1 byte dim FieldB as word ' 2 bytes end structure ' total 3 bytes dim SomeVar as TStruct dim SomeOtherVar as word main: someOtherVar = SizeOf(SomeVar) ' SomeOtherVar = 3 end.
Chr
Prototype Returns Description Example
sub function Chr(dim code as byte) as char
Returns a character associated with the specified character code. Function returns a character associated with the specified character code. Numbers from 0 to 31 are the standard non-printable ASCII codes.
c = Chr(10) ' returns a linefeed character
page
86
Ord
Prototype Returns Description Example
sub function Ord(dim character as char) as byte
ASCII code of the character. Function returns ASCII code of the character.
c = Ord("A") ' returns 65
SetBit
Prototype Description
sub procedure SetBit(dim byref register as word, dim rbit as word)
Function sets the bit rbit of register. Parameter rbit needs to be a variable or literal with value 0..15. See Predefined Globals and Constants for more information.
tBit(PORTB, 2) ' Set RB2
Example
ClearBit
Prototype Description
sub procedure ClearBit(dim byref register as word, dim rbit as word)
Function clears the bit rbit of register. Parameter rbit needs to be a variable or literal with value 0..15. See Predefined Globals and Constants for more information.
ClearBit(PORTC, 7) ' Clear RC7
Example
TestBit
Prototype Returns Description
sub function TestBit(dim register, rbit as word) as word
If the bit is set, returns 1, otherwise returns 0. Function tests if the bit rbit of register is set. If set, function returns 1, otherwise returns 0. Parameter rbit needs to be a variable or literal with value 0..15. See Predefined Globals and Constants for more information on register identifiers.
flag = TestBit(PORTE, 2) ' 1 if RE2 is set, otherwise 0
Example
page
mikroElektronika: Development tools - Books - Compilers
87
making it simple...
Inc
Prototype Description Example
sub procedure Inc(dim byref par as longint)
' p is now 5
Dec
Prototype Description Example
sub procedure Dec(dim byref par as longint)
' p is now 3
Clock_Khz
Prototype Returns Description Example
sub function Clock_Khz as longint
Device clock in KHz. Returns device clock in KHz, rounded to the nearest integer.
clk = Clock_Khz()
Clock_Mhz
Prototype Returns Description Example
sub function Clock_Mhz as word
Device clock in MHz. Returns device clock in MHz, rounded to the nearest integer.
clk = Clock_Mhz()
page
88
LIBRARY ROUTINES
mikroBasic provides a set of libraries which simplify the initialization and use of dsPIC and its modules: Library functions do not require any header files to be included; you can use them anywhere in your projects. Currently available libraries are: - ADC Library - CAN Library - CANSPI Library - Compact Flash Library - Advanced SPI Ethernet Library - SPI Ethernet Library - EEPROM Library - Flash Memory Library - Graphic LCD Library - Toshiba T6963C Graphic LCD Library - IC Library - Keypad Library - LCD Library - LCD8 Library - Manchester Code Library - Multi Media Card Library - OneWire Library - PS/2 Library - PWM Library - PWM Motor Library - RS-485 Library - Software IC Library - Software SPI Library - Software UART Library - SPI Library - Sound Library - UART Library - Util Library - Conversions Library - Math Library - Delays Library - String Library - DSP Library - SPI Graphic LCD Library - Port Expander Library - SPI LCD Library - SPI LCD8 Library - Spi T6963C Graphic LCD Library - Setjmp Library - Time Library
page
mikroElektronika: Development tools - Books - Compilers
89
making it simple...
ADC Library
ADC (Analog to Digital Converter) module is available with a number of dsPIC30/33 and PIC24 MCU models. Library function Adc_Read is included to provide you comfortable work with the module.
Library Routines
dsPIC30 and PIC24FJ Functions ADC_Read dsPIC33F and PIC24HJ Functions Adc1_Read Adc2_Read dsPIC30 and PIC24FJ Functions
Adc_Read
Prototype Returns Description
sub function Adc_Read(dim channel as word) as word
Depending on chip, function reads 10-bit unsigned value from the specified channel. Initializes dsPIC30/33 and PIC24s internal ADC module to: - Work with instruction cycle clock; - Conversion clock is 32*Tcy; - Sampling is auto-sample, auto-sample time is 31TAD; Parameter channel represents the channel from which the analog value is to be acquired. Refer to the appropriate datasheet for channel-to-pin mapping.
Requires
dsPIC30/33 and PIC24 MCU with built-in ADC module. You should consult the Datasheet documentation for specific device. Before using the function, be sure to configure the appropriate TRISx bits to designate the pins as input. Also, configure the desired pin as analog (register ADPCFG), and set Vref (voltage reference value).
Example
page
90
Adc1_Read
Prototype Returns Description
sub function Adc1_Read(dim channel, AdcMode as word) as word
Depending on AdcMode, function reads 10-bit or 12-bit unsigned value from the specified channel. Initializes dsPIC30/33 and PIC24s internal ADC module to: - Work with instruction cycle clock; - Conversion clock is 32*Tcy; - Sampling is auto-sample, auto-sample time is 31TAD;
AdcMode represents ADC resolution (Valid values are: 0 (ADC_10bit constant) and 1 (ADC_12bit constant)).Parameter channel represents the channel from which the ana-
log value is to be acquired. Refer to the appropriate datasheet for channel-to-pin mapping. This library is using ADC 1 module. Requires dsPIC30/33 and PIC24 MCU with built-in ADC module. You should consult the Datasheet documentation for specific device. Before using the function, be sure to configure the appropriate TRISx bits to designate the pins as input. Also, configure the desired pin as analog (register ADPCFG), and set Vref (voltage reference value). Example
dim k as word k = Adc1_Read(1, ADC_10bit) ' read analog value from channel 1
page
mikroElektronika: Development tools - Books - Compilers
91
making it simple...
Adc2_Read
Prototype Returns Description
sub function Adc2_Read(dim channel, AdcMode as word) as word
Depending on AdcMode, function reads 10-bit or 12-bit unsigned value from the specified channel. Initializes dsPIC30/33 and PIC24s internal ADC module to: - Work with instruction cycle clock; - Conversion clock is 32*Tcy; - Sampling is auto-sample, auto-sample time is 31TAD;
AdcMode represents ADC resolution (Valid values are: 0 (ADC_10bit constant) and 1 (ADC_12bit constant)).Parameter channel represents the channel from which the ana-
log value is to be acquired. Refer to the appropriate datasheet for channel-to-pin mapping. This library is using ADC 2 module. Requires dsPIC30/33 and PIC24 MCU with built-in ADC module. You should consult the Datasheet documentation for specific device. Before using the function, be sure to configure the appropriate TRISx bits to designate the pins as input. Also, configure the desired pin as analog (register ADPCFG), and set Vref (voltage reference value). Example
dim k as word k = Adc2_Read(1, ADC_10bit) ' read analog value from channel 1
page
92
Library Example
dsPIC30 and PIC24FJ Functions
This code snippet reads analog value from channel 10 and sends its lower byte over UART1.
program ADC_test dim k main: Uart1_Init(9600) while TRUE k = Adc_Read(10) Uart1_Write_Char(k) Delay_ms(50) wend end. as word
This simple example reads analog value from channel 1 and sends its lower byte over UART1.
program ADC_test main: PORTB = 0x0000 TRISB = 0xFFFF PORTD = 0 TRISD = 0 Uart1_Init(9600) while TRUE PORTD = Adc_Read(1, ADC_12bit) Uart1_Write_Char(PORTD) Delay_ms(50) wend end.
page
mikroElektronika: Development tools - Books - Compilers
93
making it simple...
Hardware Connection
RG12 RG14 RA7 RA6 RG0 RG1 RF1 RF0 Vdd Vss RD7 RD6 RD5 RD4 RD13 RD12 RD3 RD2 RD1
RG13
330 330 330 330 330 330 330 330 330 330 330 330
LD11 LD10 LD9 LD8 LD7 LD6 LD5 LD4 LD3 LD2 LD1 LD0
10K
VCC
RB6 RB7 RA9 RA10 AVdd AVss RB8 RB9 RB10 RB11 Vss Vdd RB12 RB13 RB14 RB15 RD14 RD15 RF4 RF5
VCC
RG15 RC1 RC2 RC3 RC4 RG6 RG7 RG8 MCLR RG9 Vss Vdd RA12 RA13 RB5 RB4 RB3 RB2 RB1 RB0
dsPIC30F6014
RC14 RC13 RD0 RD11 RD10 RD9 RD8 RA15 RA14 Vss OSC2 OSC1 Vdd RG2 RG3 RF6 RF7 RF8 RF2 RF3
Reset
10MHz
page
94
CAN Library
mikroBasic for dsPIC30/33 and PIC24 provides a library (driver) for working with the CAN module. CAN is a very robust protocol that has error detection and signalling, selfchecking and fault confinement. Faulty CAN data and remote frames are re-transmitted automatically, similar to the Ethernet. Data transfer rates vary from up to 1 Mbit/s at network lengths below 40m to 250 Kbit/s at 250m cables, and can go even lower at greater network distances, down to 200Kbit/s, which is the minimum bitrate defined by the standard. Cables used are shielded twisted pairs, and maximum cable length is 1000m. CAN supports two message formats: Standard format, with 11 identifier bits, and Extended format, with 29 identifier bits Note: CAN routines are currently supported only by dsPIC30 with CAN. Microcontroller must be connected to CAN transceiver (MCP2551 or similar) which is connected to CAN bus.
Library Routines
CAN1SetOperationMode CAN1GetOperationMode CAN1Initialize CAN1SetBaudRate CAN1SetMask CAN1SetFilter CAN1Read CAN1Write CAN2SetOperationMode CAN2GetOperationMode CAN2Initialize CAN2SetBaudRate CAN2SetMask CAN2SetFilter CAN2Read CAN2Write
page
mikroElektronika: Development tools - Books - Compilers
95
making it simple...
Be sure to check CAN constants necessary for using some of the functions.
CAN1SetOperationMode
Prototype Description
sub procedure CAN1SetOperationMode(dim mode, wait_flag as byte)
Sets CAN1 to requested mode, i.e. copies mode to CAN1STAT. Parameter mode needs to be one of CAN1_OP_MODE constants (see CAN constants). Parameter wait_flag needs to be either 0 or 0xFF: If set to 0xFF, this is a blocking call the function wont return until the requested mode is set. If 0, this is a non-blocking call. It does not verify if CAN1 module is switched to requested mode or not. Caller must use CAN1GetOperationMode to verify correct operation mode before performing mode specific operation. CAN routines are currently supported only by dsPICmicros with CAN modules. Microcontroller must be connected to CAN transceiver (MCP2551 or similar) which is connected to CAN bus.
CAN1SetOperationMode(CAN_MODE_CONFIG, $FF)
Requires
Example
CAN1GetOperationMode
Prototype Returns Description Requires
sub function CAN1GetOperationMode as byte
Current opmode. Function returns current operational mode of CAN module. CAN routines are currently supported only by dsPICmicros with CAN modules. Microcontroller must be connected to CAN transceiver (MCP2551 or similar) which is connected to CAN bus.
if CAN1GetOperationMode = CAN_MODE_NORMAL then ...
Example
page
96
CAN1Initialize
Prototype Description
sub procedure CAN1Initialize(dim SJW, BRP, PHSEG1, PHSEG2, PROPSEG, CAN_CONFIG_FLAGS as byte)
Initializes CAN1. All pending transmissions are aborted. Sets all mask registers to 0 to allow all messages. The Config mode is internaly set by this function. Upon a execution of this function Normal mode is set. Filter registers are set according to flag value:
if ((CAN_CONFIG_FLAGS and CAN_CONFIG_VALID_XTD_MSG) <> 0) then // Set all filters to XTD_MSG else if ((config and CONFIG_VALID_STD_MSG) <> 0) then // Set all filters to STD_MSG else // Set half the filters to STD, and the rest to XTD_MSG
Parameters:
SJW as defined in dsPIC datasheet (CAN1 Module) BRP as defined in dsPIC datasheet (CAN1 Module) PHSEG1 as defined in dsPIC datasheet (CAN1 Module) PHSEG2 as defined in dsPIC datasheet (CAN1 Module) PROPSEG as defined in dsPIC datasheet (CAN1 Module) CAN_CONFIG_FLAGS is formed from predefined constants (see CAN constants)
Requires
CAN routines are currently supported only by dsPICmicros with CAN modules. Microcontroller must be connected to CAN transceiver (MCP2551 or similar) which is connected to CAN bus.
init = 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 ' Initialize CAN1
Example
page
mikroElektronika: Development tools - Books - Compilers
97
making it simple...
CAN1SetBaudRate
Prototype Description
sub procedure CAN1SetBaudRate(dim SJW, BRP, PHSEG1, PHSEG2, PROPSEG, CAN_CONFIG_FLAGS as byte)
Sets CAN1 baud rate. Due to complexity of CAN1 protocol, you can1not simply force a bps value. Instead, use this function when CAN1 is in Config mode. Refer to datasheet for details. Parameters:
SJW as defined in dsPIC datasheet (CAN1 Module) BRP as defined in dsPIC datasheet (CAN1 Module) PHSEG1 as defined in dsPIC datasheet (CAN1 Module) PHSEG2 as defined in dsPIC datasheet (CAN1 Module) PROPSEG as defined in dsPIC datasheet (CAN1 Module) CAN_CONFIG_FLAGS is formed from predefined constants (see CAN constants)
Requires
CAN1 must be in Config mode; otherwise the function will be ignored. CAN routines are currently supported only by dsPICmicros with CAN modules. Microcontroller must be connected to CAN transceiver (MCP2551 or similar) which is connected to CAN bus.
Example
init =
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
page
98
CAN1SetMask
Prototype Description
sub procedure CAN1SetMask(dim CAN_MASK as byte, dim value as longint, dim CAN_CONFIG_FLAGS as byte)
Function sets mask for advanced filtering of messages. Given value is bit adjusted to appropriate buffer mask registers. Parameters: CAN_MASK is one of predefined constant values (see CAN constants); value is the mask register value; CAN_CONFIG_FLAGS selects type of message to filter, either CAN_CONFIG_XTD_MSG or CAN_CONFIG_STD_MSG.
Requires
CAN must be in Config mode; otherwise the function will be ignored. CAN routines are currently supported only by dsPICmicros with CAN modules. Microcontroller must be connected to CAN transceiver (MCP2551 or similar) which is connected to CAN bus.
' Set all mask bits to 1, i.e. all filtered bits are relevant: CAN1SetMask(CAN_MASK_B1, -1, CAN_CONFIG_XTD_MSG) ' Note that -1 is just a cheaper way to write $FFFFFFFF. ' Complement will do the trick and fill it up with ones.
Example
CAN1SetFilter
Prototype Description
sub procedure CAN1SetFilter(dim CAN_FILTER as byte, dim value as longint, dim CAN_CONFIG_FLAGS as byte)
Function sets message filter. Given value is bit adjusted to appropriate buffer mask registers. Parameters: - CAN_FILTER is one of predefined constant values (see CAN constants) - value is the filter register value - CAN_CONFIG_FLAGS selects type of message to filter, either CAN_CONFIG_XTD_MSG or CAN_CONFIG_STD_MSG
Requires
CAN must be in Config mode; otherwise the function will be ignored. CAN routines are currently supported only by dsPICmicros with CAN modules. Microcontroller must be connected to CAN transceiver (MCP2551 or similar) which is connected to CAN bus.
' Set id of filter B1_F1 to 3: CAN1SetFilter(CAN_FILTER_B1_F1, 3, CAN_CONFIG_XTD_MSG)
Example
page
mikroElektronika: Development tools - Books - Compilers
99
making it simple...
CAN1Read
Prototype Returns Description
sub function CAN1Read(dim byref id as longint, dim byref data as byte[8], dim byref datalen, CAN_RX_MSG_FLAGS as byte) as byte
Message from receive buffer or zero if no message found. Function reads message from receive buffer. If at least one full receive buffer is found, it is extracted and returned. If none found, function returns zero. Parameters: id is message identifier; data is an array of bytes up to 8 bytes in length; datalen is data length, from 18; CAN_RX_MSG_FLAGS is value formed from constants (see CAN constants).
Requires Example
CAN1Write
Prototype Returns Description
sub function CAN1Write(dim id as longint, dim byref data as byte[8], dim datalen, CAN_TX_MSG_FLAGS as byte) as byte
Returns zero if message cannot be queued (buffer full). If at least one empty transmit buffer is found, function sends message on queue for transmission. If buffer is full, function returns 0. Parameters: id is CAN message identifier. Only 11 or 29 bits may be used depending on message type (standard or extended); data is array of bytes up to 8 bytes in length; datalen is data length from 18; CAN_TX_MSG_FLAGS is value formed from constants (see CAN constants). CAN must be in Normal mode.
dim id as longint dim tx, data as byte ' ... tx = CAN_TX_PRIORITY_0 and CAN_TX_XTD_FRAME ' ... CAN1Write(id, data, 2, tx)
Requires Example
page
100
CAN2SetOperationMode
Prototype Description
sub procedure CAN2SetOperationMode(dim mode, wait_flag as byte)
Sets CAN2 to requested mode, i.e. copies mode to CAN2STAT. Parameter mode needs to be one of CAN_OP_MODE constants (see CAN constants). Parameter wait_flag needs to be either 0 or 0xFF: If set to 0xFF, this is a blocking call the function wont return until the requested mode is set. If 0, this is a non-blocking call. It does not verify if CAN2 module is switched to requested mode or not. Caller must use CAN2GetOperationMode to verify correct operation mode before performing mode specific operation. CAN routines are currently supported only by dsPICmicros with CAN modules. Microcontroller must be connected to CAN transceiver (MCP2551 or similar) which is connected to CAN bus.
CAN2SetOperationMode(CAN_MODE_CONFIG, $FF)
Requires
Example
CAN2GetOperationMode
Prototype
sub function CAN2GetOperationMode as byte
Current opmode. Function returns current operational mode of CAN module. CAN routines are currently supported only by dsPICmicros with CAN modules. Microcontroller must be connected to CAN transceiver (MCP2551 or similar) which is connected to CAN bus.
if CAN2GetOperationMode = CAN_MODE_NORMAL then ...
Example
page
mikroElektronika: Development tools - Books - Compilers
101
making it simple...
CAN2Initialize
Prototype Description
sub procedure CAN2Initialize(dim SJW, BRP, PHSEG1, PHSEG2, PROPSEG, CAN_CONFIG_FLAGS as byte)
Initializes CAN2. All pending transmissions are aborted. Sets all mask registers to 0 to allow all messages. The Config mode is internaly set by this function. Upon a execution of this function Normal mode is set. Filter registers are set according to flag value:
if ((CAN_CONFIG_FLAGS and CAN_CONFIG_VALID_XTD_MSG) <> 0) then // Set all filters to XTD_MSG else if ((config and CONFIG_VALID_STD_MSG) <> 0) then // Set all filters to STD_MSG else // Set half the filters to STD, and the rest to XTD_MSG
Parameters:
SJW as defined in dsPIC datasheet (CAN2 Module) BRP as defined in dsPIC datasheet (CAN2 Module) PHSEG1 as defined in dsPIC datasheet (CAN2 Module) PHSEG2 as defined in dsPIC datasheet (CAN2 Module) PROPSEG as defined in dsPIC datasheet (CAN2 Module) CAN_CONFIG_FLAGS is formed from predefined constants (see CAN constants)
Requires
CAN routines are currently supported only by dsPICmicros with CAN modules. Microcontroller must be connected to CAN transceiver (MCP2551 or similar) which is connected to CAN bus.
init = 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 ' Initialize CAN2
Example
page
102
CAN2SetBaudRate
Prototype Description
sub procedure CAN2SetBaudRate(dim SJW, BRP, PHSEG1, PHSEG2, PROPSEG, CAN_CONFIG_FLAGS as byte)
Sets CAN2 baud rate. Due to complexity of CAN2 protocol, you can1not simply force a bps value. Instead, use this function when CAN2 is in Config mode. Refer to datasheet for details. Parameters:
SJW as defined in dsPIC datasheet (CAN2 Module) BRP as defined in dsPIC datasheet (CAN2 Module) PHSEG1 as defined in dsPIC datasheet (CAN2 Module) PHSEG2 as defined in dsPIC datasheet (CAN2 Module) PROPSEG as defined in dsPIC datasheet (CAN2 Module) CAN_CONFIG_FLAGS is formed from predefined constants (see CAN constants)
Requires
CAN2 must be in Config mode; otherwise the function will be ignored. CAN routines are currently supported only by dsPICmicros with CAN modules. Microcontroller must be connected to CAN transceiver (MCP2551 or similar) which is connected to CAN bus.
Example
init =
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
page
mikroElektronika: Development tools - Books - Compilers
103
making it simple...
CAN2SetMask
Prototype Description
sub procedure CAN2SetMask(dim CAN_MASK as byte, dim value as longint, dim CAN_CONFIG_FLAGS as byte)
Function sets mask for advanced filtering of messages. Given value is bit adjusted to appropriate buffer mask registers. Parameters: CAN_MASK is one of predefined constant values (see CAN constants); value is the mask register value; CAN_CONFIG_FLAGS selects type of message to filter, either CAN_CONFIG_XTD_MSG or CAN_CONFIG_STD_MSG.
Requires
CAN must be in Config mode; otherwise the function will be ignored. CAN routines are currently supported only by dsPICmicros with CAN modules. Microcontroller must be connected to CAN transceiver (MCP2551 or similar) which is connected to CAN bus.
' Set all mask bits to 1, i.e. all filtered bits are relevant: CAN2SetMask(CAN_MASK_B1, -1, CAN_CONFIG_XTD_MSG) ' Note that -1 is just a cheaper way to write $FFFFFFFF. ' Complement will do the trick and fill it up with ones.
Example
CAN2SetFilter
Prototype Description
sub procedure CAN2SetFilter(dim CAN_FILTER as byte, dim value as longint, dim CAN_CONFIG_FLAGS as byte)
Function sets message filter. Given value is bit adjusted to appropriate buffer mask registers. Parameters: - CAN_FILTER is one of predefined constant values (see CAN constants) - value is the filter register value - CAN_CONFIG_FLAGS selects type of message to filter, either CAN_CONFIG_XTD_MSG or CAN_CONFIG_STD_MSG
Requires
CAN must be in Config mode; otherwise the function will be ignored. CAN routines are currently supported only by dsPICmicros with CAN modules. Microcontroller must be connected to CAN transceiver (MCP2551 or similar) which is connected to CAN bus.
' Set id of filter B1_F1 to 3: CAN2SetFilter(CAN_FILTER_B1_F1, 3, CAN_CONFIG_XTD_MSG)
Example
page
104
CAN2Read
Prototype Returns Description
sub function CAN2Read(dim byref id as longint, dim byref data as byte[8], dim byref datalen, CAN_RX_MSG_FLAGS as byte) as byte
Message from receive buffer or zero if no message found. Function reads message from receive buffer. If at least one full receive buffer is found, it is extracted and returned. If none found, function returns zero. Parameters: id is message identifier; data is an array of bytes up to 8 bytes in length; datalen is data length, from 18; CAN_RX_MSG_FLAGS is value formed from constants (see CAN constants).
Requires Example
CAN2Write
Prototype Returns Description
sub function CAN2Write(dim id as longint, dim byref data as byte[8], dim datalen, CAN_TX_MSG_FLAGS as byte) as byte
Returns zero if message cannot be queued (buffer full). If at least one empty transmit buffer is found, function sends message on queue for transmission. If buffer is full, function returns 0. Parameters: id is CAN message identifier. Only 11 or 29 bits may be used depending on message type (standard or extended); data is array of bytes up to 8 bytes in length; datalen is data length from 18; CAN_TX_MSG_FLAGS is value formed from constants (see CAN constants).
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
105
making it simple...
CAN Constants
There is a number of constants predefined in CAN library. To be able to use the library effectively, you need to be familiar with these. You might want to check the example at the end of the chapter. CAN_OP_MODE
CAN_OP_MODE constants define CAN operation mode. Function CANSetOperationMode expects one of these as its argument: 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 ' Use it to access mode bits
CAN_CONFIG_FLAGS
CAN_CONFIG_FLAGS constants define flags related to CAN module configuration. Functions CANInitialize and CANSetBaudRate expect one of these (or a bitwise
page
106
' ..continued const CAN_CONFIG_DBL_BUFFER_BIT const CAN_CONFIG_DBL_BUFFER_ON const CAN_CONFIG_DBL_BUFFER_OFF const const const const const CAN_CONFIG_MSG_BITS CAN_CONFIG_ALL_MSG CAN_CONFIG_VALID_XTD_MSG CAN_CONFIG_VALID_STD_MSG CAN_CONFIG_ALL_VALID_MSG = $10 = $FF = $EF = = = = = $60 $FF $DF $BF $9F
You may use bitwise AND to form config byte out of these values. For example:
init = CAN_CONFIG_SAMPLE_THRICE and CAN_CONFIG_STD_MSG and CAN_CONFIG_VALID_XTD_MSG and '... CANInitialize(1, 1, 3, 3, 1, init) CAN_CONFIG_PHSEG2_PRG_ON and CAN_CONFIG_DBL_BUFFER_ON and CAN_CONFIG_LINE_FILTER_OFF ' initialize CAN
CAN_TX_MSG_FLAGS
CAN_TX_MSG_FLAGS const const const const const
const CAN_TX_FRAME_BIT const CAN_TX_STD_FRAME const CAN_TX_XTD_FRAME const CAN_TX_RTR_BIT const CAN_TX_NO_RTR_FRAME const CAN_TX_RTR_FRAME
You may use bitwise AND to adjust the appropriate flags. For example:
' form value to be used with CANSendMessage: send_config = CAN_TX_PRIORITY_0 and CAN_TX_XTD_FRAME and CAN_TX_NO_RTR_FRAME '... CANSendMessage(id, data, 1, send_config)
page
mikroElektronika: Development tools - Books - Compilers
107
making it simple...
CAN_RX_MSG_FLAGS
CAN_RX_MSG_FLAGS
are flags related to reception of CAN message. If a particular bit is set; corresponding meaning is TRUE or else it will be FALSE.
CAN_RX_FILTER_BITS CAN_RX_FILTER_1 CAN_RX_FILTER_2 CAN_RX_FILTER_3 CAN_RX_FILTER_4 CAN_RX_FILTER_5 CAN_RX_FILTER_6 CAN_RX_OVERFLOW CAN_RX_INVALID_MSG CAN_RX_XTD_FRAME CAN_RX_RTR_FRAME CAN_RX_DBL_BUFFERED = = = = = = = = = = = = $07 ' $00 $01 $02 $03 $04 $05 $08 ' $10 ' $20 ' $40 ' $80 ' ' Use it to access filter bits
const const const const const const const const const const const const
Set if Overflowed; else clear Set if invalid; else clear Set if XTD msg; else clear Set if RTR msg; else clear Set if msg was hardware double-buffered
You may use bitwise AND to adjust the appropriate flags. For example:
if MsgFlag and CAN_RX_OVERFLOW = 0 then ... ' Receiver overflow has occurred; previous message is lost.
CAN_MASK constants define mask codes. Function CANSetMask expects one of these as its argument:
CAN_MASK const CAN_MASK_B1 const CAN_MASK_B2 = 0 = 1
CAN_FILTER
CAN_FILTER constants define filter codes. Function CANSetFilter expects one of these as its argument: 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
page
108
Library Example
program Can1st dim aa, aa1, Llen, aa2 as word data as byte[8] id as longint zr, cont, oldstate as word main: ADPCFG PORTB TRISB PORTF TRISF aa aa1 aa2 PORTD= TRISD= aa1 =
= = = = = = = = 0 0
0xFFFF 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_MATCH_MSG_TYPE and CAN_CONFIG_LINE_FILTER_OFF
aa
data[0] = 9 CAN1Initialize(1,3,3,3,1,aa) ' initialize CAN CAN1SetOperationMode(CAN_MODE_CONFIG,0xFF) ' set CONFIGURATION mode id = -1 CAN1SetMask(CAN_MASK_B1,id,CAN_CONFIG_MATCH_MSG_TYPE and CAN_CONFIG_XTD_MSG) ' set all mask1 bits to ones CAN1SetMask(CAN_MASK_B2,id,CAN_CONFIG_MATCH_MSG_TYPE and CAN_CONFIG_XTD_MSG) ' set all mask2 bits to ones CAN1SetFilter(CAN_FILTER_B2_F3,3,CAN_CONFIG_XTD_MSG) ' set id of filter B1_F1 to 3 CAN1SetOperationMode(CAN_MODE_NORMAL,0xFF) ' set NORMAL mode id = 12111 data[1] = 0xF1 CAN1Write(id,data,1,aa1)
page
mikroElektronika: Development tools - Books - Compilers
109
making it simple...
while true zr = CAN1Read(id , data , Llen, aa2) if ((id = 3) and (zr <> 0)) <> 0 then PORTB = data[0] data[0] = data[0] + 1 Delay_ms(10) id = 12111 CAN1Write(id, data, 1,aa1) end if wend end.
Hardware Connection
10
1 2 8 7 6 5
VCC
3 4
RXD
Vref
MCP2551
page
110
CANSPI Library
SPI module is available with a number of dsPIC30/33 and PIC24micros. mikroBasic for dsPIC30/33 and PIC24 provides a library (driver) for working with the external CAN modules (such as MCP2515 or MCP2510) via SPI. In mikroBasic for dsPIC30/33 and PIC24, each routine of CAN library has its CANSPI counterpart with identical syntax. For more information on the Controller Area Network, consult the CAN Library. Note that the effective communication speed depends on the SPI, and is certainly slower than the real CAN. Note: CANSPI routines are currently supported only by dsPIC30 that has SPI module. Example of HW connection is given at the end of the chapter.
Library Routines
CANSPI1SetOperationMode CANSPI1GetOperationMode CANSPI1Initialize CANSPI1SetBaudRate CANSPI1SetMask CANSPI1SetFilter CANSPI1Read CANSPI1Write CANSPI2SetOperationMode CANSPI2GetOperationMode CANSPI2Initialize CANSPI2SetBaudRate CANSPI2SetMask CANSPI2SetFilter CANSPI2Read CANSPI2Write
page
mikroElektronika: Development tools - Books - Compilers
111
making it simple...
CANSPI1SetOperationMode
Prototype Description
sub procedure CANSPI1SetOperationMode(dim mode, wait_flag as byte)
Sets CAN to requested mode, i.e. copies mode to CANSTAT. Parameter mode needs to be one of CAN_OP_MODE constants (see CAN constants, page 141). Parameter wait_flag needs to be either 0 or 0xFF: If set to 0xFF, this is a blocking call the function wont return until the requested mode is set. If 0, this is a nonblocking call. It does not verify if CAN module is switched to requested mode or not. Caller must use function CANSPIGetOperationMode to verify correct operation mode before performing mode specific operation.
Requires Example
CANSPI functions are supported by any dsPIC30 MCU that has SPI interface
CANSPI1SetOperationMode(CAN_MODE_CONFIG, $FF)
CANSPI1GetOperationMode
Prototype Returns Description Example
sub function CANSPI1GetOperationMode as byte
page
112
CANSPI1Init
Prototype
sub procedure CANSPI1Init(dim SJW, BRP, PHSEG1, PHSEG2, PROPSEG, CAN_CONFIG_FLAGS as byte, dim byref RstPort as word, dim RstPin as word, dim byref CSPort as word, dim CSPin as word)
Description
Initializes CANSPI. All pending transmissions are aborted. Sets all mask registers 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) then ' Set all filters to XTD_MSG else if ((config and CONFIG_VALID_STD_MSG) = 0) then ' Set all filters to STD_MSG else ' Set half the filters to STD, and the rest to XTD_MSG
Parameters:
SJW as defined in dsPIC datasheet (CAN Module) BRP as defined in dsPIC datasheet (CAN Module) PHSEG1 as defined in dsPIC datasheet (CAN Module) PHSEG2 as defined in dsPIC datasheet (CAN Module) PROPSEG as defined in dsPIC datasheet (CAN Module) CAN_CONFIG_FLAGS is formed from predefined constants (see CAN constants)
Requires
Spi1_Init(); must be called before initializing CANSPI. CANSPI1 must be in Config mode; otherwise the function will be ignored. CANSPI1 functions are supported by any dsPIC30 MCU that has SPI interface.
init = CAN_CONFIG_SAMPLE_THRICE CAN_CONFIG_PHSEG2_PRG_ON CAN_CONFIG_STD_MSG CAN_CONFIG_DBL_BUFFER_ON CAN_CONFIG_VALID_XTD_MSG CAN_CONFIG_LINE_FILTER_OFF ... CANSPI1Init(1,3,3,3,1,aa, portf, and and and and and
Example
page
mikroElektronika: Development tools - Books - Compilers
113
making it simple...
CANSPI1SetBaudRate
Prototype Description
sub procedure CANSPI1SetBaudRate(dim SJW, BRP, PHSEG1, PHSEG2, PROPSEG, CAN_CONFIG_FLAGS as byte)
Sets CANSPI baud rate. Due to complexity of CANSPI protocol, you cannot simply force a bps value. Instead, use this function when CANSPI is in Config mode. Refer to datasheet for details. Parameters:
SJW as defined in datasheet (14) BRP as defined in datasheet (164) PHSEG1 as defined in datasheet (18) PHSEG2 as defined in datasheet (18) PROPSEG as defined in datasheet (18) CAN_CONFIG_FLAGS is formed from predefined constants (see CAN constants)
Requires Example
page
114
CANSPI1SetMask
Prototype Description
sub procedure CANSPI1SetMask(dim CAN_MASK as byte, dim value as longint, dim CAN_CONFIG_FLAGS as byte)
Function sets mask for advanced filtering of messages. Given value is bit adjusted to appropriate buffer mask registers. Parameters: CAN_MASK is one of predefined constant values (see CAN constants); value is the mask register value; CAN_CONFIG_FLAGS selects type of message to filter, either CAN_CONFIG_XTD_MSG or CAN_CONFIG_STD_MSG.
Requires Example
CANSPI1SetFilter
Prototype Description
sub procedure CANSPI1SetFilter(dim CAN_FILTER as byte, dim val as longint, dim CAN_CONFIG_FLAGS as byte)
Function sets mask for advanced filtering of messages. Given value is bit adjusted to appropriate buffer mask registers. Parameters: CAN_MASK is one of predefined constant values (see CAN constants); value is the filter register value; CAN_CONFIG_FLAGS selects type of message to filter, either CAN_CONFIG_XTD_MSG or CAN_CONFIG_STD_MSG.
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
115
making it simple...
CANSPI1Read
Prototype Returns Description
sub function CANSPI1Read(dim byref id as longint, dim byref data as byte[8], dim byref DataLen, CAN_RX_MSG_FLAGS as byte) as byte
Message from receive buffer or zero if no message found. Function reads message from receive buffer. If at least one full receive buffer is found, it is extracted and returned. If none found, function returns zero. Parameters: id is message identifier; data is an array of bytes up to 8 bytes in length; datalen is data length, from 18; CAN_RX_MSG_FLAGS is value formed from constants (see CAN constants).
Requires Example
CANSPI1Write
Prototype Returns Description
sub function CANSPI1Write(dim id as longint, dim byref data as byte[8], dim datalen, CAN_TX_MSG_FLAGS as byte) as byte
Returns zero if message cannot be queued (buffer full). If at least one empty transmit buffer is found, function sends message on queue for transmission. If buffer is full, function returns 0. Parameters: id is CANSPI message identifier. Only 11 or 29 bits may be used depending on message type (standard or extended); data is array of bytes up to 8 bytes in length; datalen is data length from 18; CAN_TX_MSG_FLAGS is value formed from constants (see CAN constants).
Requires Example
page
116
CANSPI2SetOperationMode
Prototype Description
sub procedure CANSPI2SetOperationMode(dim mode, wait_flag as byte)
Sets CAN to requested mode, i.e. copies mode to CANSTAT. Parameter mode needs to be one of CAN_OP_MODE constants (see CAN constants, page 141). Parameter wait_flag needs to be either 0 or 0xFF: If set to 0xFF, this is a blocking call the function wont return until the requested mode is set. If 0, this is a nonblocking call. It does not verify if CAN module is switched to requested mode or not. Caller must use function CANSPIGetOperationMode to verify correct operation mode before performing mode specific operation.
Requires Example
CANSPI2 functions are supported by any dsPIC30 MCU that has SPI interface.
CANSPI2SetOperationMode(CAN_MODE_CONFIG, $FF)
CANSPI2GetOperationMode
Prototype Returns Description Example
sub function CANSPI2GetOperationMode as byte
page
mikroElektronika: Development tools - Books - Compilers
117
making it simple...
CANSPI2Init
Prototype
sub procedure CANSPI2Init(dim SJW, BRP, PHSEG1, PHSEG2, PROPSEG, CAN_CONFIG_FLAGS as byte, dim byref RstPort as word, dim RstPin as word, dim byref CSPort as word, dim CSPin as word)
Description
Initializes CANSPI. All pending transmissions are aborted. Sets all mask registers 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) then ' Set all filters to XTD_MSG else if ((config and CONFIG_VALID_STD_MSG) = 0) then ' Set all filters to STD_MSG else ' Set half the filters to STD, and the rest to XTD_MSG
Parameters:
SJW as defined in datasheet (14) BRP as defined in datasheet (164) PHSEG1 as defined in datasheet (18) PHSEG2 as defined in datasheet (18) PROPSEG as defined in datasheet (18) CAN_CONFIG_FLAGS is formed from predefined constants (see CAN constants)
Requires Example
Spi2_Init(); must be called before initializing CANSPI. CANSPI2 must be in Config mode; otherwise the function will be ignored.
init = CAN_CONFIG_SAMPLE_THRICE CAN_CONFIG_PHSEG2_PRG_ON CAN_CONFIG_STD_MSG CAN_CONFIG_DBL_BUFFER_ON CAN_CONFIG_VALID_XTD_MSG CAN_CONFIG_LINE_FILTER_OFF ... CANSPI2Init(1,3,3,3,1,aa, portf, and and and and and
page
118
CANSPI2SetBaudRate
Prototype Description
sub procedure CANSPI2SetBaudRate(dim SJW, BRP, PHSEG1, PHSEG2, PROPSEG, CAN_CONFIG_FLAGS as byte)
Sets CANSPI baud rate. Due to complexity of CANSPI protocol, you cannot simply force a bps value. Instead, use this function when CANSPI is in Config mode. Refer to datasheet for details. Parameters:
SJW as defined in datasheet (14) BRP as defined in datasheet (164) PHSEG1 as defined in datasheet (18) PHSEG2 as defined in datasheet (18) PROPSEG as defined in datasheet (18) CAN_CONFIG_FLAGS is formed from predefined constants (see CAN constants)
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
119
making it simple...
CANSPI2SetMask
Prototype Description
sub procedure CANSPI2SetMask(dim CAN_MASK as byte, dim value as longint, dim CAN_CONFIG_FLAGS as byte)
Function sets mask for advanced filtering of messages. Given value is bit adjusted to appropriate buffer mask registers. Parameters: CAN_MASK is one of predefined constant values (see CAN constants); value is the mask register value; CAN_CONFIG_FLAGS selects type of message to filter, either CAN_CONFIG_XTD_MSG or CAN_CONFIG_STD_MSG.
Requires Example
CANSPI2SetFilter
Prototype Description
sub procedure CANSPI2SetFilter(dim CAN_FILTER as byte, dim val as longint, dim CAN_CONFIG_FLAGS as byte)
Function sets mask for advanced filtering of messages. Given value is bit adjusted to appropriate buffer mask registers. Parameters: CAN_MASK is one of predefined constant values (see CAN constants); value is the filter register value; CAN_CONFIG_FLAGS selects type of message to filter, either CAN_CONFIG_XTD_MSG or CAN_CONFIG_STD_MSG.
Requires Example
page
120
CANSPI2Read
Prototype Returns Description
sub function CANSPI2Read(dim byref id as longint, dim byref data as byte[8], dim byref DataLen, CAN_RX_MSG_FLAGS as byte) as byte
Message from receive buffer or zero if no message found. Function reads message from receive buffer. If at least one full receive buffer is found, it is extracted and returned. If none found, function returns zero. Parameters: id is message identifier; data is an array of bytes up to 8 bytes in length; datalen is data length, from 18; CAN_RX_MSG_FLAGS is value formed from constants (see CAN constants).
Requires Example
CANSPI2Write
Prototype Returns Description
sub function CANSPI2Write(dim id as longint, dim byref data as byte[8], dim datalen, CAN_TX_MSG_FLAGS as byte) as byte
Returns zero if message cannot be queued (buffer full). If at least one empty transmit buffer is found, function sends message on queue for transmission. If buffer is full, function returns 0. Parameters: id is CANSPI message identifier. Only 11 or 29 bits may be used depending on message type (standard or extended); data is array of bytes up to 8 bytes in length; datalen is data length from 18; CAN_TX_MSG_FLAGS is value formed from constants (see CAN constants).
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
121
making it simple...
CAN Constants
There is a number of constants predefined in CAN library. To be able to use the library effectively, you need to be familiar with these. You might want to check the example at the end of the chapter. CAN_OP_MODE
CAN_OP_MODE constants define CAN operation mode. Function CANSetOperationMode expects one of these as its argument: 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 ' Use it to access mode bits
CAN_CONFIG_FLAGS
CAN_CONFIG_FLAGS constants define flags related to CAN module configuration. Functions CANInit and CANSetBaudRate expect one of these (or a bitwise combi-
page
122
' ..continued const CAN_CONFIG_DBL_BUFFER_BIT const CAN_CONFIG_DBL_BUFFER_ON const CAN_CONFIG_DBL_BUFFER_OFF const const const const const CAN_CONFIG_MSG_BITS CAN_CONFIG_ALL_MSG CAN_CONFIG_VALID_XTD_MSG CAN_CONFIG_VALID_STD_MSG CAN_CONFIG_ALL_VALID_MSG = $10 = $FF = $EF = = = = = $60 $FF $DF $BF $9F
You may use bitwise AND to form config byte out of these values. For example:
init = CAN_CONFIG_SAMPLE_THRICE CAN_CONFIG_STD_MSG CAN_CONFIG_VALID_XTD_MSG '... CANSPI1Init(1,3,3,3,1,aa, portf, and CAN_CONFIG_PHSEG2_PRG_ON and and CAN_CONFIG_DBL_BUFFER_ON and and CAN_CONFIG_LINE_FILTER_OFF 1, portf, 0) 'Initialize CANSPI1
CAN_TX_MSG_FLAGS
CAN_TX_MSG_FLAGS const const const const const
const CAN_TX_FRAME_BIT const CAN_TX_STD_FRAME const CAN_TX_XTD_FRAME const CAN_TX_RTR_BIT const CAN_TX_NO_RTR_FRAME const CAN_TX_RTR_FRAME
You may use bitwise AND to adjust the appropriate flags. For example:
' form value to be used with CANSendMessage: send_config = CAN_TX_PRIORITY_0 and CAN_TX_XTD_FRAME and CAN_TX_NO_RTR_FRAME '... CANSendMessage(id, data, 1, send_config)
page
mikroElektronika: Development tools - Books - Compilers
123
making it simple...
CAN_RX_MSG_FLAGS
CAN_RX_MSG_FLAGS
are flags related to reception of CAN message. If a particular bit is set; corresponding meaning is TRUE or else it will be FALSE.
CAN_RX_FILTER_BITS CAN_RX_FILTER_1 CAN_RX_FILTER_2 CAN_RX_FILTER_3 CAN_RX_FILTER_4 CAN_RX_FILTER_5 CAN_RX_FILTER_6 CAN_RX_OVERFLOW CAN_RX_INVALID_MSG CAN_RX_XTD_FRAME CAN_RX_RTR_FRAME CAN_RX_DBL_BUFFERED = = = = = = = = = = = = $07 ' $00 $01 $02 $03 $04 $05 $08 ' $10 ' $20 ' $40 ' $80 ' ' Use it to access filter bits
const const const const const const const const const const const const
Set if Overflowed; else clear Set if invalid; else clear Set if XTD msg; else clear Set if RTR msg; else clear Set if msg was hardware double-buffered
You may use bitwise AND to adjust the appropriate flags. For example:
if MsgFlag and CAN_RX_OVERFLOW = 0 then ... ' Receiver overflow has occurred; previous message is lost.
CAN_MASK constants define mask codes. Function CANSetMask expects one of these as its argument:
CAN_MASK const CAN_MASK_B1 const CAN_MASK_B2 = 0 = 1
CAN_FILTER
CAN_FILTER constants define filter codes. Function CANSetFilter expects one of these as its argument: 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
page
124
Library Example
This project is a simple demonstration of CANSPI on dsPIC30F6014A with minor adjustments, it should work with any other dsPIC MCU that has a SPI module. This code demonstrates how to use CANSPI library functions and procedures. It is used together with the CAN_2nd example (on second dsPIC), and it can be used to test the connection of dsPIC to the CAN network. This node initiates the communication with the Can_2nd node by sending some data to its address. The 2nd node responds by sending back the data incre- mented by 1. This (1st) node then does the same and sends incremented data back to 2nd node, etc.
program CanSPI1st dim aa, aa1, Llen, aa2 as byte data as string[8] id as longint zr as byte main: ADPCFG = 0xFFFF PORTB = 0 TRISB =0 = 0 = 0 0 0 0 CANSPI_CONFIG_SAMPLE_THRICE and CANSPI_CONFIG_PHSEG2_PRG_ON and CANSPI_CONFIG_XTD_MSG and CANSPI_CONFIG_DBL_BUFFER_ON and CANSPI_CONFIG_VALID_XTD_MSG aa1 = CANSPI_TX_PRIORITY_0 and CANSPI_TX_XTD_FRAME and CANSPI_TX_NO_RTR_FRAME PORTD TRISD aa = aa1 = aa2 = aa =
Spi1_Init() CANSPI1Init(1,3,3,3,1,aa, PORTF, 1, PORTF, 0) ' initialize external CAN module CANSPI1SetOperationMode(CANSPI_MODE_CONFIG,0xFF) ' set CONFIGURATION mode ' continues ..
page
mikroElektronika: Development tools - Books - Compilers
125
making it simple...
' continues .. ID = -1 CANSPI1SetMask(CANSPI_MASK_B1, id, CANSPI_CONFIG_XTD_MSG) ' set all mask1 bits to ones CANSPI1SetMask(CANSPI_MASK_B2, id, CANSPI_CONFIG_XTD_MSG) ' set all mask2 bits to ones CANSPI1SetFilter(CANSPI_FILTER_B2_F4, 3, CANSPI_CONFIG_XTD_MSG) ' set id of filter B1_F1 to 12111 CANSPI1SetOperationMode(CANSPI_MODE_NORMAL, 0xFF) ' set NORMAL mode data[0] = 7 id = 12111 CANSPI1Write(id,data,1,aa1) while true zr = CANSPI1Read(id, data , Llen, aa2) ' receive data, if any if(((id = 3) and (zr <> 0)) <> 0) then PORTB = data[0] data[0] = data[0] + 1 ' output data at portB id = 12111 Delay_ms(5) CANSPI1Write(id, data, 1, aa1) if(Llen = 2) then PORTD = data[1] ' if message contains two data bytes end if ' output second byte at portd end if wend end.
page
126
Hardware Connection
VCC
100K
VCC
1 2 3 4 5 6 7 8 9 8 MhZ 18 17 16
TX RX CLKO
Vdd RST CS
SO
dsPIC4013
TX0
TX1 TX2 OSC2
15 14 13 12 11 10
13 14 VCC GND OSC1 OSC2
SI SCK INT
VCC
RF0
30
MCP2510
26 25 24
10 MhZ
10
1 2 8 7 6 5
VCC
3 4
RXD
Vref
MCP2551
page
mikroElektronika: Development tools - Books - Compilers
127
making it simple...
Library Routines
Cf_Init Cf_Detect Cf_Read_Init Cf_Read_Byte Cf_Read_Word Cf_Write_Init Cf_Write_Byte Cf_Write_Word Cf_Read_Sector Cf_Write_Sector Cf_Fat_Init Cf_Fat_Assign Cf_Fat_Reset Cf_Fat_Read Cf_Fat_Rewrite Cf_Fat_Append Cf_Fat_Delete Cf_Fat_Write Cf_Fat_Set_File_Date Cf_Fat_Get_File_Date Cf_Fat_Get_File_Size Cf_Fat_Get_Swap_File
page
128
Cf_Init
Prototype
procedure CF_Init(dim byref wr_port as word, dim wr_pin as word, dim byref oe_port as word, dim oe_pin as word, dim byref a2_port as word, dim a2_pin as word, dim byref a1_port as word, dim a1_pin as word, dim byref a0_port as word, dim a0_pin as word, dim byref ry_port as word, dim ry_pin as word, dim byref ce_port as word, dim ce_pin as word, dim byref cd_port as word, dim cd_pin as word, dim byref Data_Port as word)
Description Example
Initializes microcontroller ports appropriately for communication with CF card. Specify the dataport; parameters WR, RD, A2, A1, A0, RY, CE, CD can be any available pins.
'** dsPIC30F601x, dsPICPro Board 2 Cf_Init(PORTG, 12, ' write enable PORTD, 11, ' output enable PORTD, 10, ' a2 PORTD, 9, ' a1 PORTD, 8, ' a0 PORTG, 14, ' ready PORTG, 13, ' card enable PORTG, 15, ' card detect PORTD) ' data port
Cf_Detect
Prototype Returns Description Requires Example
sub function Cf_Detect as byte
Returns 1 if CF is present, otherwise returns 0. Checks for presence of CF card on ctrlport. Ports must be initialized. See Cf_Init.
' Wait until CF card is inserted: do nop loop until Cf_Detect() = 1
page
mikroElektronika: Development tools - Books - Compilers
129
making it simple...
Cf_Read_Init
Prototype Description
sub procedure Cf_Read_Init(dim address as longint, dim sectcnt as byte)
Initializes CF card for reading. Parameter address specifies sector address from where data will be read, and sectcnt is total number of sectors prepared for read operation. Ports must be initialized. See Cf_Init.
Cf_Read_Init(590, 1)
Requires Example
Cf_Read_Byte
Prototype Returns Description Requires Example
sub function Cf_Read_Byte as byte
Returns byte from CF. Reads one byte from CF. CF must be initialized for read operation. See Cf_Read_Init.
PORTC = Cf_Read_Byte
Cf_Read_Word
Prototype Returns Description Requires Example
sub function Cf_Read_Word as word
Returns word (16-bit) from CF. Reads one word from CF. CF must be initialized for read operation. See Cf_Read_Init.
PORTC = Cf_Read_Word
page
130
Cf_Write_Init
Prototype Description
sub procedure Cf_Write_Init(dim address as longint, dim sectcnt as byte)
Initializes CF card for writing. Parameter address specifies sector address where data will be stored, and sectcnt is total number of sectors prepared for write operation. Ports must be initialized. See Cf_Init.
Cf_Write_Init(590, 1)
Requires Example
Cf_Write_Byte
Prototype Description Requires Example
sub procedure Cf_Write_Byte(dim data as byte)
Writes one byte (data) to CF. All 512 bytes are transferred to a buffer. CF must be initialized for write operation. See Cf_Write_Init.
Cf_Write_Byte(100)
Cf_Write_Word
Prototype Description Requires Example
sub procedure Cf_Write_Word(dim data as word)
Writes one word (data) to CF. All 512 bytes are transferred to a buffer. CF must be initialized for write operation. See Cf_Write_Init.
Cf_Write_Word(100)
page
mikroElektronika: Development tools - Books - Compilers
131
making it simple...
Cf_Read_Sector
Prototype Description Requires Example
sub procedure CF_Read_Sector(dim sector_number as longint, dim byref buffer1 as byte[512])
Reads one sector (sector_number) into buffer. Ports must be initialized. See Cf_Init.
Cf_Read_Sector(22, data)
Cf_Write_Sector
Prototype Returns Description Requires Example
sub procedure CF_Write_Sector(dim sector_number as longint, dim byref buffer as byte[512])
Nothing. Writes value from buffer to CF sector at sector_number. Ports must be initialized. See Cf_Init.
Cf_Write_Sector(22, data)
page
132
Cf_Fat_Init
Prototype
sub function Cf_Fat_Init(dim byref wr_port as word, dim wr_pin as word, dim byref rd_port as word, dim rd_pin as word, dim byref a2_port as word, dim a2_pin as word, dim byref a1_port as word, dim a1_pin as word, dim byref a0_port as word, dim a0_pin as word, dim byref ry_port as word, dim ry_pin as word, dim byref ce_port as word, dim ce_pin as word, dim byref cd_port as word, dim cd_pin as word, dim byref Data_Port as word) as word
Returns 0 if initialization is successful, 1 if boot sector was not found and 255 if card was not detected. Initializes ports appropriately for FAT operations with CF card. Specify two different ports: ctrlport and dataport. Nothing.
Cf_Init(PORTD,0,1,2, PORTG,14, PORTD,4, PORTD,3, PORTG,15, PORTG,13, PORTB)
Cf_Fat_Assign
Prototype Returns Description
sub function Cf_Fat_Assign(dim byref filename as string[12], dim create_file as byte) as byte
"1" is file is present(or file isn't present but new file is created), or "0" if file isn't present and no new file is created. Assigns file for FAT operations. If file isn't present, function creates new file with given filename. filename parameter is name of file (filename must be in format 8.3 UPPERCASE). create_file is a parameter for creating new files. if create_file if different from 0 then new file is created (if there is no file with given filename). Ports must be initialized for FAT operations with CF. See Cf_Fat_Init.
Cf_Fat_Assign('MIKROELE.TXT',1)
Requires Example
Cf_Fat_Reset
Prototype Returns Description Requires Example
sub procedure Cf_Fat_Reset(dim byref size as longint)
Size of file in bytes. Size is stored on address of input variable. Opens assigned file for reading. Ports must be initialized for FAT operations with CF. See Cf_Fat_Init. File must be assigned. See Cf_Fat_Assign.
Cf_Fat_Reset(size)
page
mikroElektronika: Development tools - Books - Compilers
133
making it simple...
Cf_Fat_Read
Prototype Description Requires
sub procedure Cf_Fat_Read(dim byref bdata as byte)
Reads data from file. bdata is data read from file. Ports must be initialized for FAT operations with CF. See Cf_Fat_Init. File must be assigned. See Cf_Fat_Assign. File must be open for reading. See Cf_Fat_Reset.
Cf_Fat_Read(character)
Example
Cf_Fat_Rewrite
Prototype Returns Description Requires Example
sub procedure Cf_Fat_Rewrite
Nothing. Rewrites assigned file. Ports must be initialized for FAT operations with CF. See Cf_Fat_Init. File must be assigned. See Cf_Fat_Assign.
Cf_Fat_Rewrite
Cf_Fat_Append
Prototype Returns Description Requires Example
sub procedure Cf_Fat_Append
Nothing. Opens file for writing. This procedure continues writing from the last byte in file. Ports must be initialized for FAT operations with CF. See Cf_Fat_Init. File must be assigned. See Cf_Fat_Assign.
Cf_Fat_Append
page
134
Cf_Fat_Delete
Prototype Description Requires Example
sub procedure Cf_Fat_Delete
Deletes file from CF. Ports must be initialized for FAT operations with CF. See Cf_Fat_Init. File must be assigned. See Cf_Fat_Assign.
Cf_Fat_Delete
Cf_Fat_Write
Prototype Returns Description Requires
sub procedure Cf_Fat_Write(dim byref fdata as byte[512], dim data_len as word)
Nothing. Writes data to CF. fdata parameter is data written to CF. data_len number of bytes that is written to CF. Ports must be initialized for FAT operations with CF. See Cf_Fat_Init. File must be assigned. See Cf_Fat_Assign. File must be open for writing. See Cf_Fat_Rewrite or Cf_Fat_Append.
Cf_Fat_Write(file_contents, 42) write data to the assigned file
Example
Cf_Fat_Set_File_Date
Prototype Returns Description Requires
sub procedure Cf_Fat_Set_File_Date(dim year as word, dim month, day, hours, mins, seconds as byte)
Nothing. Sets time attributes of file.You can set file year, month, day. hours, mins, seconds. Ports must be initialized for FAT operations with CF. See Cf_Fat_Init. File must be assigned. See Cf_Fat_Assign. File must be open for writing. See Cf_Fat_Rewrite or Cf_Fat_Append.
Cf_Fat_Set_File_Date(2006,6,30,17,41,0)
Example
page
mikroElektronika: Development tools - Books - Compilers
135
making it simple...
Cf_Fat_Get_File_Date
Prototype
sub procedure Cf_Fat_Get_File_Date(dim byref year as word, dim byref month as word, dim byref day as word, dim byref hours as word, dim byref mins as word)
Reads time attributes of file.You can read file year, month, day. hours, mins. Ports must be initialized for FAT operations with CF. See Cf_Fat_Init. File must be assigned. See Cf_Fat_Assign.
Cf_Fat_Get_File_Date(year, month, day, hours, mins)
Cf_Fat_Get_File_Size
Prototype Returns Description Requires Example
sub function Cf_Fat_Get_File_Size as longint
Size of file in bytes. This function returns size of file in bytes. Ports must be initialized for FAT operations with CF. See Cf_Fat_Init. File must be assigned. See Cf_Fat_Assign.
Cf_Fat_Get_File_Size
page
136
Cf_Fat_Get_Swap_File
Prototype Returns
sub function Cf_Fat_Get_Swap_File(sectors_cnt as longint) as longint
No. of start sector for the newly created swap file, if swap file was created; otherwise, the function returns zero. This function is used to create a swap file on the Compact Flash media. It accepts as sectors_cnt argument the number of consecutive sectors that user wants the swap file to have. During its execution, the function searches for the available consecutive sectors, their number being specified by the sectors_cnt argument. If there is such space on the media, the swap file named MIKROSWP.SYS is created, and that space is designated (in FAT tables) to it. The attributes of this file are: system, archive and hidden, in order to distinct it from other files. If a file named MIKROSWP.SYS already exists on the media, this function deletes it upon creating the new one. The purpose of the swap file is to make reading and writing to the card as fast as possible, by using the Cf_Read_Sector and Cf_Write_Sector functions directly, without potentially damaging the FAT system. Swap file can be considered as a "window" on the media where user can freely write/read the data, in any way (s)he wants to. Its main purpose in mikroBasic's library is to be used for fast data acquisition; when the time-critical acquisition has finished, the data can be re-written into a "normal" file, and formatted in the most suitable way.
Description
Requires Example
Ports must be initialized for FAT operations with CF. See Cf_Fat_Init.
'Tries to create a swap file, whose size will be at least 100 'sectors. 'If it succeeds, it sends the No. of start sector over USART sub procedure C_Create_Swap_File size = Cf_Fat_Get_Swap_File(100) if (size) then Usart_Write($AA) Usart_Write(Lo(size)) Usart_Write(Hi(size)) Usart_Write(Higher(size)) Usart_Write(Highest(size)) Usart_Write($AA) end if end sub
page
mikroElektronika: Development tools - Books - Compilers
137
making it simple...
Library Example
The following example writes 512 bytes at sector no.620, and then reads the data and sends it over UART1 for a visual check.
program compact_flash_test dim i as word
'** It is adviceable to initialize dsPIC in one routine. In this way '** the code is easier to read and well organized. sub procedure Init TRISF = 0 '** make portf to be output PORTF = 0 '** initilize portf '** Initialize CF card. Note that when writing to a port '** we need to use async register LATx, while reading a '** port we need to access PORTx. Cf_Init(PORTG, 12, PORTD, 11, PORTD, 10, PORTD, 9, PORTD, 8, PORTG, 14, PORTG, 13, PORTG, 15, PORTD) '** Since PORTB can be analog as well, we need to make sure it"s digital ADPCFG = $FFFF while Cf_Detect() = 0 '** When CF is inserted Cf_Detect will return 0. nop wend Delay_ms(200) '** Some time is needed for the card to make good contacts end sub sub procedure WriteByte Cf_Write_Init(590,1) Delay_ms(50) i = 0 while i < 512 Delay_ms(10) Cf_Write_Byte(i) Inc(i) wend end sub
'** We will write 512 bytes to CF card '** Write one byte
' .. continues
page
138
'** We will read 512 bytes from CF card '** Read one byte '** Write readings to PORTF
page
mikroElektronika: Development tools - Books - Compilers
139
making it simple...
HW Connection
RB6 RB7 RA9 RA10 AVdd AVss RB8 RB9 RB10 RB11 Vss Vdd RB12 RB13 RB14 RB15 RD14 RD15 RF4 RF5
RG15 RC1 RC2 RC3 RC4 RG6 RG7 RG8 MCLR RG9 Vss Vdd RA12 RA13 RB5 RB4 RB3 RB2 RB1 RB0
RG13 RG12 RG14 RA7 RA6 RG0 RG1 RF1 RF0 Vdd Vss RD7 RD6 RD5 RD4 RD13 RD12 RD3 RD2 RD1
RC14 RC13 RD0 RD11 RD10 RD9 RD8 RA15 RA14 Vss OSC2 OSC1/CLKI Vdd RG2 RG3 RF6 RF7 RF8 RF2 RF3
dsPIC30FXXXX
VCC
VCC
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
R25 10K
VCC
page
140
EEPROM Library
EEPROM data memory is available with a number of dsPIC. mikroBasic for dsPIC30/33 and PIC24micros includes library for comfortable work with internal EEPROM.
Library Routines
Eeprom_Erase Eeprom_Erase_Block Eeprom_Read Eeprom_Write Eeprom_Write_Block
Eeprom_Erase
Prototype Returns Description Requires
sub procedure Eeprom_Erase(address : longint);
Nothing. Erases a single (16-bit) location in EEPROM memory. Requires internal EEPROM module. Erase cycle will complete in 2mS. CPU is not stalled for the Data Erase cycle. User can poll WR bit, use NVMIF or Timer IRQ to determine completion of erase sequence.
Example
page
mikroElektronika: Development tools - Books - Compilers
141
making it simple...
Eeprom_Erase_Block
Prototype Returns Description Requires
sub procedure Eeprom_Erase_Block(dim address as longint)
Nothing. Erases a 16-word (32-byte) block of EEPROM memory. Requires internal EEPROM module. Erase cycle will complete in 2mS. CPU is not stalled for the Data Erase cycle. User can poll WR bit, use NVMIF or Timer IRQ to determine completion of erase sequence.
Example
Eeprom_Erase_Block($7FFC20)
Eeprom_Read
Prototype Returns Description Requires Example
sub function Eeprom_Read(dim address as longint) as word
Returns word from the specified address. Reads data from specified address. It is programmers responsibility to obtain proper address parity (in this case, even). Requires internal EEPROM module.
take = Eeprom_Read($7FFC30)
Eeprom_Write
Prototype Returns Description
sub procedure Eeprom_Write(dim address as longint, dim data as word)
Nothing. Writes data to specified address. Be aware that all interrupts will be disabled during execution of Eeprom_Write routine (GIE bit of INTCON register will be cleared). Routine will set this bit on exit.
Requires
Requires internal EEPROM module. Write cycle will complete in 2mS. CPU is not stalled for the Data Write Cycle. User can poll WR bit, use NVMIF or Timer IRQ to determine write complete.
Example
page
142
Eeprom_Write_Block
Prototype Description
sub procedure Eeprom_Write_Block(dim address as longint, dim byref data as word[100])
Writes a block (16 words) of data from an array or structure to specified address. It is user's responsibility to maintain proper address allignment. In this case, address has to be a multiply of 32, which is the size (in bytes) of one row of dsPIC's EEPROM memory.
Requires
Requires internal EEPROM module. Write cycle will last at least for 2mS. CPU is not stalled for the Data Write Cycle. User can poll WR bit, use NVMIF or Timer IRQ to determine write complete.
Example
Library Example
program EEPROM const iArr as word[10] = ("m", "i", "k", "r", "o", "E", "l", "e", "k", 0) dim iArr1 as word[15] dim eeRead as word eeAddr as longint dArr as byte[16] i as word main: iArr1 = iArr '--- disable analog inputs ADPCFG = 0xFFFF TRISB LATB eeRead eeAddr = = = = 0 0xFFFF 0xAAAA 0x7FFC80
page
mikroElektronika: Development tools - Books - Compilers
143
making it simple...
'continued... while(eeRead < 0xAABA) Eeprom_Write(eeAddr, eeRead) eeRead = eeRead + 1 while(NVMCON.15 <> 0) nop ' wait for write to finish, wend LATB = Eeprom_Read(eeAddr) ' then, read the just-written ' data. eeAddr = eeAddr + 2 Delay_ms(500) wend '--- write entire row of EEPROM data,... Eeprom_Write_Block(0x7FFC20, iArr1) while(NVMCON.15 <> 0) nop wend '--- ...read the data back... eeRead = 1 eeAddr = 0x7FFC20 i = 0 while(eeRead <> 0) eeRead = Eeprom_Read(eeAddr) dArr[i] = Lo(eeRead) i = i + 1 eeAddr = eeAddr + 2 wend '--- ...and display it on LCD. Lcd_Init(PORTB, 7,6,5,4, PORTD, 0,1,2) Lcd_Out(2,1, dArr) end.
page
144
Library Routines
Ethernet Initialization
EthSetMACAddr EthSetIPAddr EthSetIPMask EthSetGateWayAddr EthInit Eth_Set_Udp_Port Eth_Send_Udp Eth_Load_Tcp_Header Eth_Get_Tcp_Hdr_Offset Eth_Get_Tcp_Flags Eth_Set_Tcp_Data Eth_Tcp_Response
page
mikroElektronika: Development tools - Books - Compilers
145
making it simple...
page
146
Other
StackInit StackTask HTTPInit HTTPServer
page
mikroElektronika: Development tools - Books - Compilers
147
making it simple...
EthSetMACAddr
Prototype Returns Description Requires Example
sub procedure EthSetMACAddr(dim MACByte1, MACByte2, MACByte3, MACByte4, MACByte5, MACByte6 as byte)
EthSetIPAddr
Prototype Description Requires Example
sub procedure EthSetIPAddr(dim IpByte1, IpByte2, IpByte3, IpByte4 as byte)
EthSetIPMask
Prototype Description Requires Example
sub procedure EthSetIPMask(dim IPMaskByte1, IPMaskByte2, IPMaskByte3, IPMaskByte4 as byte)
EthSetGateWayAddr
Prototype Description Requires Example
sub procedure EthSetGateWayAddr(dim GateWayByte1, GateWayByte2, GateWayByte3, GateWayByte4 as byte)
page
148
EthInit
Prototype Description Requires Example
sub procedure EthInit(dim byref RstPort as word, dim RstPin as word, dim byref CSPort as word, dim CSPin as word)
This routine initializes NIC and global variables needed for Ethernet connection. EthSetMACAddr, EthSetIPAddr, EthSetIPMask needs to be set before calling this routine. Calling EthSetGateWayAddr before this routine is optional.
' Initializes Ethernet connection EthInit(PORTF,0,PORTF,1)
MACInit
Prototype Description Requires Example
sub procedure MACInit(dim byref RstPort as word, RstPin as word, dim byref CSPort as word, dim CSPin as word)
This function initializes MAC layer. It initializes internal buffers and resets the NIC to a known state. All pending transmission and receptions are discarded. As specified for the entire library (MAC).
' Initialize MAC Module MACInit(PORTF,0,PORTF,1)
MACIsTxReady
Prototype Returns Description Requires Example
sub function MACIsTxReady as byte
(<>0) - If at least one MAC transmit buffer is empty. (=0) - If all MAC transmit buffers are full. This function indicates whether at least one MAC transmit buffer is empty or not. As specified for the entire library (MAC).
' Check MAC transmit readiness... if (MACIsTxReady<>0) then ' Transmit buffer is empty, transmit a message. ...
page
mikroElektronika: Development tools - Books - Compilers
149
making it simple...
MACGetHeader
Prototype Returns Description
sub function MACGetHeader(dim byref remote as MAC_ADDR, dim byref type as byte) as byte
(<>0) : If a data packet is received and found to be valid. All parameters are populated. (=0) : If no data packet is received or found to be invalid. This function checks the MAC receive buffer; if any packet is found, it returns the remote host and data packet information. Remote specifies Remote MAC address and type represents Data packet type. Possible values for type parameter are: MAC_IP (An IP data packet is received), MAC_ARP (An ARP data packet is received) MAC_UNKNOWN (An unknown or unsupported data packet is received). As specified for the entire library (MAC).
' Get possible data packet info. if(MACGetHeader(RemoteNodeMAC, PacketType)<>0) then ' A packet is received, process it. ... ' Once done, discard it. MACDiscardRx ...
Requires Example
MACGet
Prototype Returns Description Requires Example
sub function MACGet as byte
Data byte. This function returns the next byte from an active transmit or receive buffer. MACGetHeader, MACPutHeader, MACSetRxBuffer or MACSetTxBuffer must have been called.
' Get possible data packet info. if (MACGetHeader(RemoteNode, PacketType)<>0) then ' A packet is received, process it. data = MACGet ... ' When done, discard it. MACDiscardRx ...
page
150
MACGetArray
Prototype Returns Description Requires
sub function MACGetArray(dim byref val as byte, dim len as word) as word
Total number of bytes fetched. This function fetches an array of bytes from the active transmit or receive buffer. val represents pointer to a byte array and len represents number of bytes to fetch. MACGetHeader, MACPutHeader,MACSetRxBuffer or MACSetTxBuffer must have been called.
' Get possible data packet info. if (MACGetHeader(RemoteNode, PacketType)<>0) then ' A packet is received, process it. actualCount = MACGetArray(data, count) ...
Example
MACDiscardRx
Prototype Returns Description Requires Example
sub procedure MACDiscardRx
Nothing. This function discards the active receive buffer data and marks that buffer as free. Nothing.
' Get possible data packet info. if (MACGetHeader(RemoteNode, PacketType)<>0) then ' A packet is received, process it. actualCount = MACGetArray(data, count) ... ' Done processing it. Discard it. MACDiscardRx ...
page
mikroElektronika: Development tools - Books - Compilers
151
making it simple...
MACPutHeader
Prototype Returns Description
sub procedure MACPutHeader(dim byref remote as MAC_ADDR, dim type as byte, dim dataLen as word)
Nothing. This function assembles the MAC header and loads it to an active transmit buffer. remote - Remote node MAC address, type - Type of data packet being sent. Possible values for this parameter are: MAC_IP(An IP data packet is to be transmitted) and MAC_ARP(An ARP data packet is to be transmitted), data - Number of bytes for this packet, including IP header. Nothing.
' Check to see if at least one transmit buffer is empty if (MACIsTxReady<>0) then ' Assemble IP packet with total IP packet size of 100 bytes ' including IP header. MACPutHeader(RemoteNodeMAC, MAC_IP, 100) ...
Requires Example
MACPut
Prototype Returns Description Requires Example
sub procedure MACPut(dim val as byte)
Nothing. This function loads the given data byte into an active transmit or receive buffer. val Data byte to be written. MACGetHeader, MACPutHeader, MACSetRxBuffer or MACSetTxBuffer must have been called.
' Check to see if at least one transmit buffer is empty if (MACIsTxReady<>0) then ' Assemble IP packet with total IP packet size of 100 bytes ' including IP header. MACPutHeader(RemoteNodeMAC, MAC_IP, 100) ' Now put the actual IP data bytes MACPut($55) ...
page
152
MACPutArray
Prototype Returns Description
sub procedure MACPutArray(dim byref val as byte, dim len as word)
Nothing. This function writes an array of data bytes into an active transmit or receive buffer. val - Data bytes to be written. len - Total number of bytes to write. MACGetHeader, MACPutHeader, MACSetTxBuffer or MACSetRxBuffer must have been called.
' Check to see if at least one transmit buffer is empty if (MACIsTxReady<>0) then ' Assemble IP packet with total IP packet size of 100 bytes ' including IP header. MACPutHeader(RemoteNodeMAC, MAC_IP, 100) ' Now put the actual IP data bytes MACPut($55) MACPutArray(data, count) ...
Requires Example
MACFlush
Prototype Description Requires Example
sub procedure MACFlush
This function marks active transmit buffer as ready for transmission. MACPutHeader or MACSetTxBuffer must have been called.
' Check to see if at least one transmit buffer is empty if (MACIsTxReady<>0) then ' Assemble IP packet with total IP packet size of 100 bytes ' including IP header. MACPutHeader(RemoteNodeMAC, MAC_IP, 100) ' Put the actual IP data bytes MACPut($55) MACPutArray(data, count) ... ' Now transmit it. MACFlush ...
page
mikroElektronika: Development tools - Books - Compilers
153
making it simple...
MACDiscardTx
Prototype Description Requires Example
sub procedure MACDiscardTx(buffer as BUFFER)
This function discards given transmit buffer content and marks it as free. Nothing.
' Check to see if at least one transmit buffer is empty if (MACIsTxReady<>0) then ' Assemble IP packet with total IP packet size of 100 bytes ' including IP header. MACPutHeader(RemoteNodeMAC, MAC_IP, 100) ' Get current transmit buffer buffer = MACGetTxBuffer ' Reserve it. MACReserveTxBuffer (Buffer) ' Put the actual IP data bytes ... ' Now transmit it. MACFlush ' No longer need this buffer MACDiscardTx(buffer) ...
MACSetRxBuffer
Prototype Description
sub procedure MACSetRxBuffer(offset as word)
This function sets the access location for the active receive buffer. offset - Location (with respect to beginning of buffer) where next access is to occur. Nothing.
' Get possible data packet info. if (MACGetHeader(RemoteNode, PacketType)<>0) then ' A packet is received, process it. actualCount = MACGetArray(data, count) ... ' Fetch data beginning at offset 20 MACSetRxBuffer(20) data = MACGet ...
Requires Example
page
154
MACSetTxBuffer
Prototype Description
sub procedure MACSetTxBuffer(dim buffer as BUFFER, dim offset as word)
This function sets the access location for a given transmit buffer, and makes that transmit buffer active. buffer - A transmit buffer where this access offset be applied. offset - Location (with respect to beginning of buffer) where next access is to occur. Nothing.
' Check to see if at least one transmit buffer is empty if (MACIsTxReady<>0) then ' Assemble IP packet with total IP packet size of 100 bytes ' including IP header. MACPutHeader(RemoteNodeMAC, MAC_IP, 100); ' Get current transmit buffer buffer = MACGetTxBuffer ' Put the actual IP data bytes ... ' Calculate the checksum of data packet that is being transmitted ... ' Now update the checksum in this packet. ' To update the checksum, set transmit buffer access to checksum MACSetTxBuffer(buffer, checksumLocation) ... ' Now transmit it. MACFlush ...
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
155
making it simple...
MACReserveTxBuffer
Prototype Description
sub procedure MACReserveTxBuffer(buffer as BUFFER)
This function reserves a given transmit buffer and marks it as unavailable. This function is useful for TCP layer where a message would be queued until it is correctly acknowledged by remote host. buffer - A transmit buffer to reserve. This value must be a valid transmit buffer identifier as returned by MACGetTxBuffer function. Nothing.
' Check to see if at least one transmit buffer is empty if (MACIsTxReady<>0) then ' Transmit IP packet with total IP packet size of 100 bytes ' including IP header. MACPutHeader(RemoteNodeMAC, MAC_IP, 100) ' Get current transmit buffer buffer = MACGetTxBuffer ' Reserve it, to be discarded when ACK is received. MACReserveTxBuffer(buffer) ' Put the actual IP data bytes ... ' Calculate the checksum of data packet that is being transmitted ... ' Now update the checksum in this packet. ' To update the checksum, set transmit buffer access to checksum MACSetTxBuffer(buffer, checksumLocation) ... ' Now transmit it. MACFlush ...
Requires Example
page
156
MACGetFreeRxSize
Prototype Returns Description Requires Example
sub function MACGetFreeRxSize as word
Total number of bytes available for future data packets. This function returns total receive buffer size available for future data packets. Nothing.
' Get available receive buffer size freeRxBuffer = MACGetFreeRxSize
MACSetDuplex
Prototype Returns Description
sub procedure MACSetDuplex(DuplexState as DUPLEX)
Nothing. This routine sets FULL-DUPLEX or HALF-DUPLEX communication mode. Input value can be 1 for FULL-DUPLEX, 0 for HALF-DUPLEX and 2 for NIC defined communication mode. Nothing.
'FULL-DUPLEX communication is set MACSetDuplex(1)
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
157
making it simple...
ARPGet
Prototype Returns
sub function ARPGet(dim byref remote as NODE_INFO, dim byref opCode as byte) as byte (<>0) - If a valid ARP packet that was addressed to local host was fetched; remote and
host. Description This function fetches complete ARP packet and returns necessary information. remote Remote node information such as MAC and IP addresses. opCode - ARP code. Possible values for this parameter are: ARP_REPLY ("ARP Reply" packet is received), ARP_REQUEST (ARP Request packet is received), ARP_UNKNOWN (An unknown ARP packet is received). MACGetHeader is already called AND Received MAC packet type = MAC_ARP
' If MAC packet is received... if (MACGetHeader(RemoteNode, PacketType)<>0) then ' If this is an ARP packet, fetch it. If (PacketType = MAC_ARP) then ' This is ARP packet. ARPGet(RemoteNode, ARPCode) ...
Requires Example
ARPPut
Prototype Description
sub procedure ARPPut(dim byref remote as NODE_INFO, dim opCode as byte)
This function loads MAC buffer with valid ARP packet. remote - Remote node information such as MAC and IP addresses. opCode - ARP code. Possible values for this parameter are: ARP_REPLY (Transmit this packet as "ARP Reply"), ARP_REQUEST (Transmit this packet as "ARP Request"). ARPIsTxReady == TRUE
' Check to see if transmit buffer is available if (ARPIsTxReady<>0) then ' Transmit it ARPPut(RemoteNode, ARP_REQUEST); ...
Requires Example
page
158
ARPInit
Prototype Description
sub procedure ARPInit
This function initializes the ARPTask state machine and prepares it to handle ARP requests and replies. Nothing.
' Initialize ARPTask ARPInit ...
Requires Example
IPIsTxReady
Prototype Returns
sub function IPIsTxReady as byte (<>0)- If there is at least one transmit buffer empty. (=0) - If there is no empty transmit buffer.
page
mikroElektronika: Development tools - Books - Compilers
159
making it simple...
IPSetTxBuffer
Prototype Returns Description
sub procedure IPSetTxBuffer(dim buffer as BUFFER, dim offset as word)
Nothing. This is a macro to allow higher level layer set transmit buffer access pointer. This macro takes IP header into account before calling MACSetTxBuffer. buffer - Transmit buffer identifier whose access pointer is to be set. offset - An offset with respect to IP Data. Nothing.
' If IP transmit buffer is ready, transmit IP packet if (IPIsTxReady<>0) then ' Assemble IP packet. IPPutHeader(Remote, MAC_TCP, IPPacketLen) ' Get current transmit buffer id. buffer = MACGetTxBuffer ' Load transmit data ... ' Calculate checksum checkHi:checkLo ... ' Update the checksum. IPSetTxBuffer(buffer, checkLocation) MACPut (checkHi) MACPut (checkLo) ...
Requires Example
page
160
IPPutHeader
Prototype Returns Description
sub function IPPutHeader(dim byref remote as NODE_INFO, dim protocol as byte, dim len as word) as word
Nothing. This function assembles a valid IP header and loads it into active transmit buffer. remote - Remote node information such as MAC and IP addresses. protocol Protocol to use for this data packet. Possible values for this parameter are: IP_PROT_ICMP (Assemble this packet as ICMP), IP_PROT_TCP (Assemble this packet as TCP segment), IP_PROT_UDP (Assemble this packet as UDP segment). len - Total length of IP data bytes, excluding IP header. IPIsTxReady = TRUE
' Check to see if transmit buffer is available if (IPIsTxReady<>0) then ' Load the header IPPutHeader(RemoteNode, IP_PROT_ICMP, ICMP_HEADER_SIZE+dataLen) ' Load ICMP data IPPutArray(ICMPData, dataLen) ' Mark it as ready to be transmitted MACFlush ...
Requires Example
IPPutArray
Prototype Returns Description
sub procedure IPPutArray(dim byref buffer as byte, dim len as word)
Nothing. This macro loads an array of bytes into the active transmit buffer. buffer - Data array that is to loaded. len - Total number of items in data array. IPIsTxReady = TRUE
' Check to see if transmit buffer is available if (IPIsTxReady<>0) then ' Load the header IPPutHeader(RemoteNode, IP_PROT_ICMP, ICMP_HEADER_SIZE+dataLen) ' Load ICMP data IPPutArray(ICMPData, dataLen) ' Mark it as ready to be transmitted MACFlush ...
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
161
making it simple...
IPGetHeader
Prototype
sub function IPGetHeader(dim byref localIP as IP_ADDR, dim byref remote as NODE_INFO, dim byref protocol as byte, dim byref len as word) as byte (<>0) - A valid IP packet was received. Remote IP address, packet protocol and packet
Returns
Description
This function fetches the IP header from the active transmit buffer and validates it. localIP - Local node information such as MAC and IP addresses, remote - Remote node information such as MAC and IP addresses, protocol - Protocol associated with this IP packet. Possible values for this parameter are: IP_PROT_ICMP (This is an ICMP packet), IP_PROT_TCP (This is a TCP packet), IP_PROT_UDP (This is a UDP packet), all others Unknown protocol. len - Total length of IP data in this packet. MACGetHeader = TRUE
' Check to see if any packet is ready if (MACGetHeader(RemoteMACAddr, PacketType)<>0) then ' Check what kind of protocol it is if (PacketType = MAC_IP) then ' This is IP packet. Fetch it. IPGetHeader(Local, Remote, IPProtocol, IPLen) ' Process this IP packet. ... ' When done processing this packet, discard it MACDiscardRx else ' This is not an IP packet. Handle it ...
Requires Example
page
162
IPGetArray
Prototype Returns Description Requires Example
sub function IPGetArray(dim byref val as byte, dim len as word) as word
Total number of bytes fetched. This macro fetches an array of bytes from an active transmit or receive buffer. val Pointer to a buffer to byte array. len - Number of bytes to fetch. IPGetHeader, IPPutHeader, IPSetRxBuffer or IPSetTxBuffer must have been called.
' Check to see if any packet is ready if (MACGetHeader(RemoteMACAddr, PacketType)<>0) then ' Check what kind of protocol it is if (PacketType = MAC_IP) then ' This is IP packet. Fetch it. IPGetHeader(Remote, IPProtocol, IPLen) ' Get 20 bytes of data IPGetArray(IPData, 20) ... ' When done processing this packet, discard it MACDiscardRx else ' This is not an IP packet. Handle it ...
page
mikroElektronika: Development tools - Books - Compilers
163
making it simple...
IPSetRxBuffer
Prototype Returns Description
sub procedure IPSetRxBuffer(dim offset as word)
Nothing. This macro allows a higher level layer to set the receive buffer access pointer. It takes the IP header into account before calling MACSetRxBuffer. offset - An offset with respect to IP Data. Nothing.
' Check to see if any packet is ready if (MACGetHeader(RemoteMACAddr, PacketType)<>0) then ' Check what kind of protocol it is if (PacketType = MAC_IP) then ' This is IP packet. Fetch it. IPGetHeader(Remote, IPProtocol, IPLen) ' Fetch 20th byte within IP data. IPSetRxBuffer(20) data = MACGet ... ' When done processing this packet, discard it MACDiscardRx else ' This is not an IP packet. Handle it ...
Requires Example
page
164
ICMPIsTxReady
Prototype Returns Description Requires Example
sub function ICMPIsTxReady as byte (<>0) - If there is at least one transmit buffer empty. (=0) - If there is no empty transmit buffer.
ICMPPut
Prototype
sub procedure ICMPPut(dim byref remote as NODE_INFO, dim code as ICMP_CODE, dim byref data, len as byte, dim id, seq as word)
Returns Description
Nothing. This function assembles a valid ICMP packet and transmits it. remote - Remote node information such as MAC and IP addresses, code - ICMP code to be used for this ICMP packet. Possible values for this parameter are: ICMP_ECHO_REPLY (This is an ICMP Echo reply packet), ICMP_ECHO_REQUEST (This is an ICMP Echo request packet). data - ICMP data. len - ICMP data length. id - ICMP packet identifier. seq - ICMP packet sequence number. IPIsTxReady = TRUE
' Check to see if transmit buffer is available if (ICMPIsTxReady<>0) then ' Transmit ICMP packet. ICMPPut(RemoteNode, ICMP_ECHO_REPLY, data, datalen, id, seq) ' Done. ICMP is put into transmit queue. ...
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
165
making it simple...
ICMPGet
Prototype
sub procedure ICMPGet(dim byref remote as NODE_INFO, dim byref code as ICMP_CODE, dim byref data, len as byte, dim byref id, seq as word) (<>0) - A valid ICMP packet was received. All parameters are populated. (==0) - An invalid ICMP packet was received. Parameters are not populated.
Returns Description
This function fetches the ICMP header from the active transmit buffer and validates it. remote - Remote node information such as MAC and IP addresses. code - ICMP code for received ICMP packet. Possible values for this parameter are: ICMP_ECHO_REPLY (An ICMP Echo reply packet is received), ICMP_ECHO_REQUEST (An ICMP Echo request packet is received), for all others (An unknown/unsupported packet is received). data - ICMP data. len - ICMP data length. id - ICMP packet identifier. seq - ICMP packet sequence number. IPGetHeader = TRUE PacketType = IP_PROT_ICMP
' Check to see if any packet is ready if (IPGetHeader(Remote, IPProtocol, IPLen)<>0) then ' Check what kind of protocol it is if (IPProtocol = IP_PROT_ICMP) then ' This is ICMPP packet. Fetch it. ICMPGet(ICMPCode, data, dataLen, id, seq); ' Process this ICMP packet. ... ' When done processing this packet, discard it MACDiscardRx else ' This is not an ICMP packet. Handle it ...
Requires
Example
page
166
TCPInit
Prototype Description Requires Example
sub procedure TCPInit
This function initializes the TCP state machine and prepares it for multiple TCP connections. Nothing.
' Initialize TCP TCPInit
TCPListen
Prototype Returns Description Requires Example
sub function TCPListen(dim port as TCP_PORT) as TCP_SOCKET
A valid socket identifier if there was at least one free socket. INVALID_SOCKET if there is no socket available. This function assigns one of the available sockets to listen on given TCP port. port TCP Port number on which to listen. Nothing.
... httpSocket = TCPListen(80) If (httpSocket = INVALID_SOCKET) then ' Socket is not available ' Return error. ...
page
mikroElektronika: Development tools - Books - Compilers
167
making it simple...
TCPConnect
Prototype Returns Description
sub function TCPConnect(dim byref remote as NODE_INFO, dim port as TCP_PORT) as TCP_SOCKET
A valid socket identifier if there was at least one free socket. INVALID_SOCKET if there is no socket available. This function initiates a connection request to a remote host on a given remote port. remote - Remote host that needs to be connected. port - TCP Port number on remote host to connect to. Nothing.
... ftpSocket = TCPConnect(RemoteNode, 21) If (ftpSocket = INVALID_SOCKET) then ' Socket is not available ' Return error. ...
Requires Example
page
168
TCPIsConnected
Prototype Returns
sub function TCPIsConnected(dim socket as TCP_SOCKET) as byte (<>0) If given socket is connected to remote host. (=0) If given socket is not connected to remote host.
Description
This function determines whether a given socket is connected to remote host or not. socket - Socket identifier for which the connection is to be checked. Nothing.
ftpSocket = TCPConnect(RemoteNode, 21) If (ftpSocket = INVALID_SOCKET) then ' Socket is not available ' Return error. else smState = SM_CONNECT_WAIT end if ' Wait for connection... if (TCPIsConnected(ftpSocket)<>0) then smState = SM_CONNECTED ...
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
169
making it simple...
TCPPut
Prototype Returns
sub procedure TCPDisconnect(dim socket as TCP_SOCKET) (<>0) - If a given data byte was successfully loaded into the transmit buffer and there is
Description
This function loads a data byte into the transmit buffer for a given socket. socket Socket identifier that needs to be checked. byte - Data byte to be loaded. TCPIsPutReady = TRUE
... if (TCPIsPutReady(ftpSocket)<>0) then ' Send data TCPPut(ftpSocket, dataByte) ...
Requires Example
page
170
TCPFlush
Prototype Returns Description
sub procedure TCPFlush(dim socket as TCP_SOCKET)
Nothing. This function marks given socket transmit buffer as ready to be transmitted. socket Socket identifier that needs to transmitted. TCPIsPutReady = TRUE
... if (TCPIsPutReady(ftpSocket)<>0) then ' Send data TCPPut(ftpSocket, dataByte) ... ' Now transmit it. TCPFlush(ftpSocket) ...
Requires Example
TCPIsGetReady
Prototype Returns Description Requires
sub function TCPIsGetReady(dim socket as TCP_SOCKET) as byte
Nothing.
(<>0) - If given socket contains receive data. (=0) - If given socket does not contain any data.
This function determines if the given socket contains receive data. socket - Socket identifier that needs to transmitted.
... if (TCPIsGetReady(httpSocket)<>0) then ' Fetch data ...
Example
page
mikroElektronika: Development tools - Books - Compilers
171
making it simple...
TCPGet
Prototype Returns
sub function TCPGet(dim socket as TCP_SOCKET, dim byref data as byte) as byte (<>0) - If a byte was read. (=0) - If no byte was read.
Description
This function fetches one data byte from a given socket receive buffer. socket - Socket identifier that needs to be fetched. byte - Data byte that was read. TCPIsGetReady = TRUE
... if (TCPIsGetReady(httpSocket)<>0) then ' Fetch data TCPGet(httpSocket, dataByte) ...
Requires Example
TCPGetArray
Prototype Returns Description
sub function TCPGetArray(dim socket as TCP_SOCKET, dim byref data as byte[1024], dim count as word) as word
Total number of data bytes read. This function fetches a data array from a given socket receive buffer. socket - Socket identifier that needs to be fetched. byte - Data array that was read. count - Total number of bytes to read. TCPIsGetReady = TRUE
... ' Fetch data if (TCPIsGetReady(httpSocket)<>0) then ' Fetch 20 bytes of data TCPGetArray(httpSocket, buffer, 20) ...
Requires Example
page
172
TCPDiscard
Prototype Returns
sub function TCPDiscard(dim socket as TCP_SOCKET) as byte (<>0) - If receive buffer for given was successfully discarded. (=0) - If receive buffer for given buffer was already discarded.
This function releases the receive buffer associated with a given socket. socket - Socket identifier that needs to transmitted. Nothing.
... ' Fetch 20 bytes of data TCPGetArray(httpSocket, buffer, 20) ' Process data. ... ' Release the buffer. TCPDiscard(httpSocket) ...
TCPDisconnect
Prototype Returns Description Requires Example
sub procedure TCPDisconnect(dim socket as TCP_SOCKET)
page
mikroElektronika: Development tools - Books - Compilers
173
making it simple...
TCPIsPutReady
Prototype Returns Description
sub function TCPIsPutReady(dim socket as TCP_SOCKET) as byte (<>0) - If given socket is ready to transmit. (=0) - If given socket is not connected or there is no transmit buffer ready.
This function determines if a socket is ready to transmit. A socket is ready to transmit when it is connected to a remote host and its transmit buffer is empty. socket - Socket identifier that needs to be checked. Nothing.
if (TCPIsPutReady(ftpSocket)<>0) then ' Send data ...
Requires Example
TCPProcess
Prototype
sub function TCPProcess(dim byref remote as NODE_INFO, dim len as word) as byte (<>0) - If this function (task) has completely processed current packet. (==0) - If this function (task) has partially processed current packet.
Returns Description
This function acts as "TCPTask". It fetches an already received TCP packet and executes the TCP State machine for matching sockets. This function must be called only when a TCP packet is received. IPGetHeader = TRUE IPProtocol = IP_PRO_TCP
... if (TCPProcess(RemoteNode, IPDataCount)<>0) then smState = SM_STACK_IDLE ...
Requires
Example
page
174
TCPTick
Prototype Description Requires
sub procedure TCPTick
This function acts as another "TCPTask" in addition to TCPProcess. This function checks for time-out conditions for all sockets and attempts to recover from them. IPGetHeader = TRUE IPProtocol = IP_PRO_TCP
TCPTick
Example
UDPInit
Prototype Description Requires Example
sub procedure UDPInit
This function initializes the UDP module and prepares it for multiple UDP connections. Nothing.
' Initialize UDP UDPInit
page
mikroElektronika: Development tools - Books - Compilers
175
making it simple...
UDPOpen
Prototype
sub function UDPOpen(dim localPort as UDP_PORT, dim byref remoteNode as NODE_INFO, dim remotePort as TCP_PORT) as UDP_SOCKET
Returns Description
A valid socket identifier if there was at least one free socket. INVALID_UDP_SOCKET if there is no socket available. This function prepares the next available UDP socket on a given port for possible data transfer. Either the local or remote node may initiate the data transfer. localPort Local UDP port number on which data transfer will occur. remoteNode - Remote host that contains remotePort. remotePort - UDP Port number on remote host to transfer the data to and from. Nothing.
... ' Talk to a remote DHCP server. DHCPSocket = UDPOpen(68, DHCPServerNode, 67) If (DHCPSocket = INVALID_UDP_SOCKET) then ' Socket is not available ' Return error. else ' Broadcast DHCP Broadcast message. ...
Requires Example
UDPClose
Prototype Description
sub procedure UDPClose(dim socket as UDP_SOCKET)
This function closes a given UDP socket and declares it as a free socket. socket Identifier of socket that needs to be closed. Nothing.
' Close the socket UDPClose(DHCPSocket)
Requires Example
page
176
UDPIsPutReady
Prototype Returns
sub function UDPIsPutReady(dim socket as UDP_SOCKET) as byte (<>0) - If a given socket is ready to transmit. (=0) - If there is no transmit buffer ready.
Description
This macro determines if a given socket is ready to transmit. A socket is ready to transmit when at least one of the MAC transmit buffers is empty. It also sets the given socket as an active UDP socket. socket - Identifier of the socket that needs to be checked and set active. Nothing.
' Talk to a remote DHCP server. DHCPSocket = UDPOpen(68, DHCPServerNode, 67) If (DHCPSocket = INVALID_UDP_SOCKET) then ' Socket is not available ' Return error. else ' Broadcast DHCP Broadcast message. smState = SM_BROADCAST if (UDPIsPutReady(DHCPSocket)<>0) then ' Socket is ready to transmit. Transmit the data... ... end if ...
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
177
making it simple...
UDPPut
Prototype Returns
sub function UDPPut(dim data as byte) as byte (<>0) - If a given data byte was successfully loaded into the transmit buffer and there is
no room for more data. Description This function loads a data byte into the transmit buffer for an active socket. byte - Data byte to be loaded. UDPIsPutReady = TRUE
... if (UDPIsPutReady(DHCPSocket)) then ' Socket is ready to transmit. Transmit the data... ' Note that there is DHCPSocket parameter in UDPPut. ' This UDPPut call will use active socket ' as set by UDPIsPutReady - that is DHCPSocket. UDPPut($55) ... end if
Requires Example
UDPFlush
Prototype Returns Description Requires Example
sub procedure UDPFlush
Nothing. This function marks the active socket transmit buffer as ready to be transmitted. UDPPut() is already called, and the desired UDP socket is set as the active socket by calling UDPIsPutReady.
... if (UDPIsPutReady(DHCPSocket)<>0) then ' Socket is ready to transmit. Transmit the data... ' Note that there is DHCPSocket parameter in UDPPut. ' This UDPPut call will use active socket ' as set by UDPIsPutReady - that is DHCPSocket. UDPPut($55) ... ' Now transmit it. UDPFlush end if ...
page
178
UDPIsGetReady
Prototype Returns
sub function UDPIsGetReady(socket as UDP_SOCKET) as byte (<>0) - If a given socket contains receive data. (=0) - If a given socket does not contain any data.
Description
This function determines if the given socket contains receive data. It also sets a given socket as an active socket. socket - Identifier for the socket that needs to transmitted and set active. UDPOpen is already called. The value of socket must be that returned by UDPOpen call.
if (UDPIsGetReady(DHCPSocket)<>0) then ' Socket does contain some data. Fetch it and process it. ... end if ...
Requires
Example
UDPGet
Prototype Returns Description Requires Example
sub function UDPGet(dim data as ^byte) as byte (<>0) If a byte was read. (=0) If no byte was read.
This function fetches one data byte from an active socket receive buffer. byte - Data byte that was read. UDPIsGetReady = TRUE
... if (UDPIsGetReady(DHCPSocket)) then ' Socket does contain some data. Fetch it all. ' buffer is a pointer to BYTE. while(UDPGet(Buffer)<>0) inc(buffer) wend ' Process it. ' Discard the socket buffer. end if ...
page
mikroElektronika: Development tools - Books - Compilers
179
making it simple...
UDPDiscard
Prototype Returns Description Requires Example
sub function UDPDiscard as byte
Nothing. This function releases the receive buffer associated with an active socket. Nothing.
... if (UDPIsGetReady(DHCPSocket)<>0) then ' Socket does contain some data. Fetch it all. ' buffer is a pointer to BYTE. while(UDPGet(Buffer)<>0) inc(buffer) wend ' Process it. ... ' Discard the socket buffer. UDPDiscard end if
UDPProcess
Prototype Returns
sub function UDPProcess(dim byref remote as NODE_INFO, dim len as word) as byte (<>0) - If this function (task) has completely processed the current packet. (=0) - If this function (task) has partially processed the current packet.
Description
This function acts as UDPTask. It fetches an already received UDP packet and assigns it to a matching UDP socket. This function must be called only when a UDP packet is received. remote - Remote node from which the current UDP packet was received. len - Total length of UDP packet length, including UDP header. IPGetHeader = TRUE IPProtocol = IP_PRO_UDP
... if (UDPProcess(RemoteNode, IPDataCount)<>0) then smState = SM_STACK_IDLE ...
Requires Example
page
180
UDPWrite
Prototype Returns Description Requires Example
sub function UDPWrite(dim UDPSocket as word, dim byref UDPBuffer as byte, dim NoBytes as byte) as byte
Number of written bytes. Sends data over UDP protocol. UDPSocket - Writes data to this socket. UDPBuffer Data to be sent. NoBytes. Requires UDPInit and UDPOpenSocket.
socket = UDPOpenSocket(10001, 192,168,20,1, 10001) 'assign socket for UDP protocol numofbytes = UDPWrite(socket, mydata)
UDPRead
Prototype Returns Description Requires Example
sub function UDPRead(dim UDPSocket as word, dim byref UDPBuffer as byte) as byte
Number of read bytes. Reads data over UDP protocol. UDPSocket - Reads data from this socket. UDPBuffer Data to be read. Requires UDPInit and UDPOpenSocket.
socket = UDPOpenSocket(10001, 192,168,20,1, 10001) ' assign socket for UDP protocol numofbytes = UDPRead(socket, mydata)
UDPOpenSocket
Prototype
sub function UDPOpenSocket(dim LocUDPPort as word, dim RemoteIPByte1, RemoteIPByte2, RemoteIPByte3, RemoteIPByte4 as byte, dim RemUDPPort as word) as word
Returns Description
Number of initialized UDP socket. Opens socket for UDP communication with remote node. LocUDPPort - NIC Udp port, RemoteIPByte1 ... RemoteIPByte4 - Remote host IP address, RemUDPPort Remote host UDP port. Requires UDPInit.
socket = UDPOpenSocket(10001, 192,168,20,1, 10001) ' assign socket for UDP protocol
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
181
making it simple...
StackInit
Prototype Returns Description Requires Example
sub procedure StackInit(dim byref RstPort as word, dim RstPin as word, dim byref CSPort as word, dim CSPin as word)
StackTask
Prototype Returns Description Requires Example
sub procedure StackTask
Nothing. This routine executes Stack FSM. StackInit() must be called before calling this routine.
StackTask
HTTPInit
Prototype Returns Description Requires Example
sub procedure HTTPInit
HTTPServer
Prototype Returns Description Requires Example
sub procedure HTTPServer
Nothing. This routine starts HTTP server. HTTPInit(); must be called before using this routine.
HTTPServer
page
182
Library Example
The following example is a simple demonstration of the SPI Ethernet Library. dsPIC is assigned an IP address of 192.168.20.60, and will respond to ping if connected to a local area network.
program SerialEthernet include "MikroEDemoPage" include "__Lib_spi1" include "__Lib_strings" const TICKS_PER_SECOND = 100 const TICK_SECOND as longint = TICKS_PER_SECOND const DISPLAY = 0 LED_D2 = 0x00 LED_D3 = 0x01 ANALOGINPUT_0 = 0x02 ANALOGINPUT_1 = 0x03 SETLED_D2 = 0x04 SETLED_D3 = 0x05 const HTTP_DEFAULT_PAGE as string[19] = "CENTER.HTM" const EXECUTE_PAGE as string[19] = "EXECUTE.CGI" const UNKNOWN_PAGE as string[20] = "UNKNOWN.HTM" const BaudRate = 9600 DefaultUDPPort = 10001 structure xxx dim ss as ^byte end structure dim main_socket as word Buffer0 as byte[10] Buffer1 as byte[10] Bbuffer as byte[20] i as word t as longint IFS0bits as word absolute $084 volatile register IEC0bits as word absolute $08C volatile register T1CONbits as word absolute $104 volatile register sub function TickGetDiff(dim a, b as longint) as longint if( a < b ) then result = longint(0xFFFFFFFF - b) + a else result = longint( a - b ) end if end sub // continues...
page
mikroElektronika: Development tools - Books - Compilers
183
making it simple...
// continued... sub procedure Interrupt_T1() org 0x001A TimeOutUpdate() end sub sub procedure ReadAnalogInputs() dim ADCResult as word ADCFVal as longint ADCResult = Adc_Read(0) ADCFVal = (ADCResult * 5000) >> 12 WordToStrWithZeros(adcfval, Buffer0) Buffer0[5] = Buffer0[4] Buffer0[4] = Buffer0[3] Buffer0[3] = Buffer0[2] Buffer0[0] = " " Buffer0[2] = "." Buffer0[6] = " " Buffer0[7] = "V" Buffer0[8] = 0 'IntToStr(ADCResult, Buffer0); ADCResult = Adc_Read(1) ADCFVal = (ADCResult * 5000) >> 12 WordToStrWithZeros(adcfval, Buffer1) Buffer1[5] = Buffer1[4] Buffer1[4] = Buffer1[3] Buffer1[3] = Buffer1[2] Buffer1[0] = " " Buffer1[2] = "." Buffer1[6] = " " Buffer1[7] = "V" Buffer1[8] = 0 end sub
// continues...
page
184
// continued... sub procedure HTTPExecCmd(dim byref argv as xxx[20], dim argc as byte) dim comm as byte i, Vvar as byte chptr as ^byte i = 0 comm = argv[i].ss^ - "0" select case comm case DISPLAY Vvar = argv[1].ss^ - "0" select case Vvar case LED_D2 LATD.2 = LATD.2 xor 1 case LED_D3 LATD.3 = LATD.3 xor 1 end select chptr = argv[0].ss for i = 0 to 12 chptr^ = EXECUTE_PAGE[i] chptr = chptr + 1 next i case else chptr = argv[0].ss for i = 0 to strlen(EXECUTE_PAGE) chptr^ = EXECUTE_PAGE[i] chptr = chptr + 1 next i end select end sub sub function HTTPGetVar(dim Vvar as byte, dim ref as word, dim Vval as ^byte) as word select case Vvar case LED_D2 if( LATD and 0x04) <> 0 then Vval^ = "1" else Vval^ = "0" end if // continues...
page
mikroElektronika: Development tools - Books - Compilers
185
making it simple...
// continued... case LED_D3 if( LATD and 0x08) <> 0 then Vval^ = "1" else Vval^ = "0" end if case ANALOGINPUT_0 Vval^ = Buffer0[byte(ref)] if( Buffer0[byte(ref)] = 0 ) then result = 0xFFFF exit end if ref = ref + 1 result = ref exit case ANALOGINPUT_1 Vval^ = Buffer1[byte(ref)] if( Buffer1[byte(ref)] = 0) then result = 0xFFFF exit end if ref = ref + 1 result = ref exit case SETLED_D2 if( LATD and 0x04 ) <> 0 then Vval^ = "0" else Vval^ = "1" end if case SETLED_D3 if( LATD and 0x08 ) <> 0 then Vval^ = "0" else Vval^ = "1" end if end select result = 0xFFFF end sub // continues...
page
186
// continues... main: i = 0 t = 0 ADPCFG = 0xFFFF PORTD = 0 TRISD = 0 PORTB = 0 TRISB = 0 ' Set up analog inputs TRISB = TRISB or 0x03 ' Set up the LED's. LATD = 0x00 LATD = LATD or 0x0C TRISD = 0x00 EthSetIPAddr(192, 168, 20, 60) EthSetMACAddr(0x00, 0x02, 0x04, 0x06, 0x08, 0x0A) EthSetIPMask(0xFF, 0xFF, 0xFF, 0x00) EthSetGateWayAddr(192, 168, 20, 60) EthInit( @PORTF, 0, @PORTF, 1 ) ' Open UDP communication sockets needed main_socket = UDPOpenSocket(DefaultUDPPort, 192, 168, 20, 1, DefaultUDPPort) ' main loop while true if( TickGetDiff(TickGet(), t) >= TICK_SECOND/2 ) then t = TickGet() LATD = LATD xor 1 end if StackTask() '* '* '* '* i = if(
Process incoming UDP packets and send a reply if needed. User specific code.
UDPRead(main_socket, @Bbuffer) i <> 0 ) then Bbuffer[i] = 0 UDPWrite(main_socket, @Bbuffer, strlen(Bbuffer)) end if HTTPServer() ReadAnalogInputs() wend end.
page
mikroElektronika: Development tools - Books - Compilers
187
making it simple...
HW Connection
dsPIC4013
VCC 11 12 13 14
10 Mhz
VCC
VCC3
LD2 LED
LD3 LED
E3 10uF
ENC28J60
1 2 VCAP GND CLKOUT INT WOL SO SI SCK CS RESET VCC LEDA LEDB 28 27 26 25 24 23 22 OSCGND PLL-GND PLL-VCC 19 RX-VCC 18 17 16 TPOUT15 TX-VCC 21 20
R2 500
R3 500
1 2
RF4
1A 1B 1Y 2A 2B 2Y
VCC 4B 4A 4Y 3B 3A 3Y
14 13 12 11 10 9 8
RF2 1B 2B 3B RF3 RF6 RF1 RF0
3 4 5 6 7 8 9 10 11 12 13 14
74HCT08N
9
3 4 5
RF5
6 7
25 MHz
GND
R4 51 R5 51
VCC3
L1 FERRITE BEAD 12 11 K2 A2
R6 51 R7 51
RJ45
TD+ CT TDRD+ CT RD1 3 2 7 6 8 C4 100nF C3 10nF
K1 A1 10
page
188
Library Routines
SPI_Ethernet_Init SPI_Ethernet_doPacket SPI_Ethernet_putByte SPI_Ethernet_getByte SPI_Ethernet_UserTCP SPI_Ethernet_UserUDP
page
mikroElektronika: Development tools - Books - Compilers
189
making it simple...
SPI_Ethernet_Init
Prototype
sub procedure SPI_Ethernet_Init(dim byref resetPort as word, dim resetBit as byte, dim byref CSportPtr as word, dim CSbit as byte, dim byref mac as byte[6], dim byref ip as byte[4], dim fullDuplex as byte)
Returns Description
Nothing. Initialize ENC controller. This function is splited into 2 parts to help linker when coming short of memory.
resetPort - pointer to reset pin port resetBit - reset bit number on resetPort CSport - pointer to CS pin port CSbit - CS bit number on CSport mac - pointer to array of 6 char with MAC address ip - pointer to array of 4 char with IP address fullDuplex - either SPI_Ethernet_HALFDUPLEX for half duplex or SPI_Ethernet_FULLDUPLEX for full duplex
Requires Example
SpiX_Init(); must be called before initializing SPI Ethernet. SPI_Ethernet_Init(PORTF, 0, PORTF, 1, myMacAddr, myIpAddr, SPI_Ethernet_FULLDUPLEX)
SPI_Ethernet_doPacket
Prototype Returns Description Requires
sub procedure SPI_Ethernet_doPacket
Nothing. Process one incoming packet if available. SPI_Ethernet_init must have been called before using this function. This function must be called as often as possible by user.
SPI_Ethernet_doPacket
Example
page
190
SPI_Ethernet_putByte
Prototype Returns Description
sub procedure ENC28J60_putByte(dim v as byte)
Nothing.
v - value to store
Store one byte to current EWRPT ENC location. Requires Example SPI_Ethernet_init must have been called before calling this function.
SPI_Ethernet_putByte(0xa0)
SPI_Ethernet_getByte
Prototype Returns Description Requires Example
dim function SPI_Ethernet_getByte as byte
Value of byte @ addr. Get next byte from current ERDPT ENC location. SPI_Ethernet_init must have been called before calling this function.
b = SPI_Ethernet_getByte
page
mikroElektronika: Development tools - Books - Compilers
191
making it simple...
SPI_Ethernet_UserTCP
Prototype Returns Description
sub function SPI_Ethernet_UserTCP(dim byref remoteHost as byte[4], dim remotePort, localPort, reqLength as word) as word
Returns the length in bytes of the HTTP reply, or 0 if nothing to transmit. This function is called by the library. The user accesses to the HTTP request by successive calls to SPI_Ethernet_getByte the user puts data in the transmit buffer by successive calls to SPI_Ethernet_putByte the function must return the length in bytes of the HTTP reply, or 0 if nothing to transmit. If you don't need to reply to HTTP requests, just define this function with a return(0) as single statement. SPI_Ethernet_init must have been called before calling this function.
Requires Example
SPI_Ethernet_UserUDP
Prototype Returns Description
sub function SPI_Ethernet_UserUDP(dim byref remoteHost as byte[4], remotePort, destPort, reqLength as word) as word
Returns the length in bytes of the UDP reply, or 0 if nothing to transmit. This function is called by the library. The user accesses to the UDP request by successive calls to SPI_Ethernet_getByte. The user puts data in the transmit buffer by successive calls to SPI_Ethernet_putByte. The function must return the length in bytes of the UDP reply, or 0 if nothing to transmit. If you don't need to reply to UDP requests,just define this function with a return(0) as single statement. SPI_Ethernet_init must have been called before calling this function.
Requires Example
page
192
Library Example
The following example is a simple demonstration of the SPI Ethernet Library. dsPIC30/33 and PIC24 is assigned an IP address of 192.168.20.60, and will respond to ping if connected to a local area network.
program enc_ethernet include enc_utils ' this is where you should write implementation for UDP and HTTP
'*********************************** '* RAM variables '* dim myMacAddr myIpAddr as byte[6] as byte[4] ' my MAC address ' my IP address
main: ADPCFG = 0xFBFF PORTB = 0 TRISB = 0xFFFF PORTD = 0x00 TRISD = 0 httpCounter = 0 myMacAddr[0] myMacAddr[1] myMacAddr[2] myMacAddr[3] myMacAddr[4] myMacAddr[5] myIpAddr[0] myIpAddr[1] myIpAddr[2] myIpAddr[3] = = = = = = = = = = 0x00 0x14 0xA5 0x76 0x19 0x3F 192 168 20 60
continues...
page
mikroElektronika: Development tools - Books - Compilers
193
making it simple...
continued...
starts ENC28J60 with : reset bit on RF0 CS bit on RF1 my MAC & IP address full duplex
SpiX_Init(1) Spi_Ethernet_Init(PORTF, 0, PORTF, 1, myMacAddr, myIpAddr, SPI_Ethernet_FULLDUPLEX) while true ' do forever Spi_Ethernet_doPacket() ' process incoming Ethernet packets '* '* add your stuff here if needed '* ENC28J60_doPacket() must be called as often as possible '* otherwise packets could be lost '* wend end.
page
194
HW Connection
dsPIC4013
VCC 11 12 13 14
10 Mhz
VCC
VCC3
LD2 LED
LD3 LED
E3 10uF
ENC28J60
1 2 VCAP GND CLKOUT INT WOL SO SI SCK CS RESET VCC LEDA LEDB 28 27 26 25 24 23 22 OSCGND PLL-GND PLL-VCC 19 RX-VCC 18 17 16 TPOUT15 TX-VCC 21 20
R2 500
R3 500
1 2
RF4
1A 1B 1Y 2A 2B 2Y
VCC 4B 4A 4Y 3B 3A 3Y
14 13 12 11 10 9 8
RF2 1B 2B 3B RF3 RF6 RF1 RF0
3 4 5 6 7 8 9 10 11 12 13 14
74HCT08N
9
3 4 5
RF5
6 7
25 MHz
GND
R4 51 R5 51
VCC3
L1 FERRITE BEAD 12 11 K2 A2
R6 51 R7 51
RJ45
TD+ CT TDRD+ CT RD1 3 2 7 6 8 C4 100nF C3 10nF
K1 A1 10
page
mikroElektronika: Development tools - Books - Compilers
195
making it simple...
- Erase can be done only in 32-instructions (64 addresses, 96 bytes) memory blocks. This means that the block start address should be a multiply of 64 (i.e. have 6 lower bits set to zero). - Data is read and written in 4-instructions (8 address, 12 bytes) blocks.This means that the block start address should be a multiply of 8 (i.e. have 3 lower bits set to zero). - On dsPIC30s, 2 address locations are assigned on every 3 bytes of (flash) program memory. Due to this specific and non-one-to-one address mapping, mikroC offers two sets of Flash handling functions: "regular" and "compact". Using the "regular" set, user can write one byte of data to a single address; this means that each byte of data written has its own address, but on every 2 bytes written one byte of Flash memory remains empty. Using the "compact" set, every byte of Flash memory, including those nonaddressable, is filled with data; this method can only be used for data organized in bytes. The "compact" functions have _Compact as name suffix.
page
196
- For the run-time FLASH read/write, dsPIC30's RTSP (Run Time Self Programming) module is being used. It organizes the data into rows and panels. Each row contains write latches that can hold 4 instructions (12 bytes). The number of panels varies between the dsPIC30 MCU models. Because of this, the flash write sequence has been split into multiple operations (_Write_Init(), _Write_LoadLatch4(), _Write_DoWrite()), in order to be usable on all dsPICs.
PIC24 and dsPIC33:
- Erase can be done only in 512-instructions (1024 addresses, 1536 bytes) memory blocks. This means that the block start address should be a multiply of 512 (i.e. have 9 lower bits set to zero). - Data is read and written in 64-instructions (128 address, 192 bytes) blocks.This means that the block start address should be a multiply of 64 (i.e. have 6 lower bits set to zero). - On dsPIC33 and PIC24s, 2 address locations are assigned on every 3 bytes of (flash) program memory. Due to this specific and non-one-to-one address mapping, mikroC offers two sets of Flash handling functions: "regular" and "compact". Using the "regular" set, user can write one byte of data to a single address; this means that each byte of data written has its own address, but on every 2 bytes written one byte of Flash memory remains empty. Using the "compact" set, every byte of Flash memory, including those nonaddressable, is filled with data; this method can only be used for data organized in bytes. The "compact" functions have _Compact as name suffix.
Library Routines
dsPIC30: Flash_Erase32 Flash_Write_Block Flash_Write_Compact Flash_Write_Init Flash_Write_Loadlatch4 Flash_Write_Loadlatch4_Compact Flash_Write_DoWrite Flash_Read4 Flash_Read4_Compact
page
mikroElektronika: Development tools - Books - Compilers
197
making it simple...
PIC24 and dsPIC33: Flash_Erase Flash_Write Flash_Write_Compact Flash_Write_DoWrite Flash_Read Flash_Read_Compact dsPIC30:
Flash_Erase32
Prototype Description Requires Example
sub procedure Flash_Erase32(dim address as longint)
Erases one block (32 instructions, 64 addresses, 96 bytes) of program FLASH memory. Nothing.
' --- erase the 32-instruction block, starting from address ' 0x006000 Flash_Erase32(0x006000)
Flash_Write_Block
Prototype Description
sub procedure Flash_Write_Block(dim address as longint, dim byref data as word)
Fills one writeable block of Flash memory (4 instructions, 8 addresses, 12 bytes) in "common" mode, with data starting from the *data location, on FLASH address address. This means that addresses and data are being mapped 1-on-1. This also means that 3rd byte of each program instruction remains unused. The block that is being written to must be erased first, either from the user code (through the RTSP), or during the programming of the MCU (through the ICSP). Please note that block size that is being erased is different than the one that can be written with this function!
Flash_Write_Block($006000,$FFFF);
Requires
Example
page
198
Flash_Write_Compact
Prototype Description
sub procedure Flash_Write_Compact(dim address as longint, dim data as word, dim bytes as word)
Fills a portion of Flash memory starting from address address, with data pointed to by the *data, the amount of data being written is bytes. This is being done through the usage of dsPICs RTSP (Run Time Self Programming) module, in "compact" manner. This way, multiple blocks of RTSP's latch can be written in one pass. One latch block contains 4 instructions (8 addresses, 12 bytes). Up to (but not necesserily) 8 latch blocks can be written in one round, resulting of total of 8*12 = 96 bytes. This method uses all the available bytes of the program FLASH memory, including those that are not mapped to address space (every 3rd byte). The block that is being written to must be erased first, either from the user code (Flash_Erase32), or during the programming of the MCU. Please note that block size that is being erased is different than the one that can be written with this function! FLASH write start address must be a multiply of 32, meaning that first 5 bytes of it are zeroes. The amount of bytes to be written must be a multiply of 12, since this is the size of the RTSP's write latch(es).
Requires
Example
Flash_Write_Init
Prototype Description Requires
sub procedure Flash_Write_Init(dim address as longint, dim data as word)
Initializes the RTSP for write-to-FLASH operation, starting from address address, with data at location data. The block that is being written to must be erased first, either from the user code (Flash_Erase32), or during the programming of the MCU. Please note that block size that is being erased is different than the one that can be written with this function! FLASH write start address must be a multiply of 32, meaning that first 5 bytes of it are zeroes.
Example
Flash_Write_Init($006100, pv1)
page
mikroElektronika: Development tools - Books - Compilers
199
making it simple...
Flash_Write_Loadlatch4
Prototype Description Requires
sub procedure Flash_Write_Loadlatch4
Loads the current RTSP write latch with data (4 instructions, 8 addresses, 12 bytes). The data is filled in "classic" manner, i.e. only addressable bytes are used. The block that is being written to must be erased first, either from the user code (Flash_Erase32), or during the programming of the MCU. Please note that block size that is being erased is different than the one that can be written with this function! This function is used as a part of the Flash write sequence, therefore Flash_Write_Init function must be called before this one. This function can be called multiple times before comminting actual write-to-Flash operation (Flash_Write_DoWrite). This depends on the organisation of the RTSP module for certain dsPIC. Please consult the Datasheet for particular dsPIC on this subject.
Example
Flash_Write_Loadlatch4()
Flash_Write_Loadlatch4_Compact
Prototype Description
sub procedure Flash_Write_Loadlatch4_Compact
Loads the current RTSP write latch with data (4 instructions, 8 addresses, 12 bytes). The data is filled in "compact" manner, i.e. all bytes in Flash are used. This function, however, can be used only for the single-byte data. The block that is being written to must be erased first, either from the user code (Flash_Erase32), or during the programming of the MCU. Please note that block size that is being erased is different than the one that can be written with this function! This function is used as a part of the Flash write sequence, therefore Flash_Write_Init function must be called before this one. This function can be called multiple times before comminting actual write-to-Flash operation (Flash_Write_DoWrite). This depends on the organisation of the RTSP module for certain dsPIC. Please consult the Datasheet for particular dsPIC on this subject. This function can be used only on the single-byte type of data.
Requires
Example
Flash_Write_Loadlatch4_Compact()
page
200
Flash_Write_DoWrite
Prototype Description Requires
sub procedure Flash_Write_DoWrite
Commits the FLASH write operation. The block that is being written to must be erased first, either from the user code (Flash_Erase32), or during the programming of the MCU. Please note that block size that is being erased is different than the one that can be written with this function! This function is used as a part of the Flash write sequence, therefore Flash_Write_Init() and certain number of Flash_Write_Loadlatch4() or Flash_Write_Loadlatch4_Compact() function calls must be made before this one. This function is to be called once, at the and of the FLASH write sequence.
Example
Flash_Write_Loadlatch4 Flash_Write_DoWrite
Flash_Read4
Prototype Returns Description Requires Example
sub procedure Flash_Read4(dim address as longint, dim write_to as word)
Pointer to data that has just been read. Reads one latch row (4 instructions, 8 addresses) from the memory location specified by address, and stores it at RAM location starting at *write_to. Starting read address must be 8-byte alligned.
Flash_Read4($006000, pv1)
page
mikroElektronika: Development tools - Books - Compilers
201
making it simple...
Flash_Read4_Compact
Prototype Returns Description Requires
sub procedure Flash_Read4_Compact(dim address as longint, dim write_to as word)
Pointer to data that has just been read. Reads one latch row (4 instructions, 8 addresses, 12 bytes) from the memory location specified by address, and stores it at RAM location starting at *write_to. Starting read address must be 8-byte alligned. FLASH contents are being read byte-by-byte.
Example
' --- reads 12 bytes (4 words) from location 0x006000 and stores ' it to ^pv1 ' ... Flash_Read4_Compact(0x006000, pv1)
Flash_Erase
Prototype Returns Description Requires
sub procedure Flash_Erase(dim address as longint)
Nothing. Erases one block (512 instructions, 1024 addresses, 1536 bytes) of program FLASH memory. Note: Due to the nature of dsPIC33 and PIC24 Flash memory organisation,9 LSBs of address have no effect to the location(s) being erased (it is only the 'row' value of the RTSP unit that is being taken into account).
Flash_Erase($006400)
Example
page
202
Flash_Write
Prototype Returns Description
sub procedure Flash_Write(dim address as longint, dim byref data as word[64])
Nothing. Writes one writeable block of Flash memory (64 instructions, 128 addresses, 192 bytes) in "regular" mode. This means that addresses and data are being mapped 1-on-1. This also means that 3rd byte of each program instruction remains uneffected. The block that is being written to must be erased first, either from the user code (through the RTSP), or during the programming of the MCU (through the ICSP). Please note that block size that is being erased is different than the one that can be written with this function!
const niz as word[64] = ("m","i","k","r","o","E") main: Flash_Write(0x6500, niz) ... end.
Requires
Example
Flash_Write_Compact
Prototype Returns Description
sub procedure Flash_Write_Compact(dim address as longint, dim byref data as byte[192])
Nothing. Fills a portion of Flash memory starting from address address, with data pointed to by the *data, the amount of data being written is bytes. This is being done through the usage of dsPIC33 and PIC24s RTSP (Run Time Self Programming) module, in "compact" manner. This way, multiple blocks of RTSP's latch can be written in one pass. One latch block contains 64 instructions (128 addresses, 192 bytes). This method uses all the available bytes of the program FLASH memory, including those that are not mapped to address space (every 3rd byte). The block that is being written to must be erased first, either from the user code (Flash_Erase), or during the programming of the MCU. Please note that block size that is being erased is different than the one that can be written with this function! FLASH write start address must be a multiply of 64, meaning that first 6 bytes of it are zeroes.
Requires
Example
page
mikroElektronika: Development tools - Books - Compilers
203
making it simple...
Flash_Write_DoWrite
Prototype Returns Description Requires
sub procedure Flash_Write_DoWrite
Nothing. Commits the FLASH write operation. The block that is being written to must be erased first, either from the user code (Flash_Erase), or during the programming of the MCU. Please note that block size that is being erased is different than the one that can be written with this function!
Example
Flash_Read
Prototype Returns Description Requires Example
sub procedure Flash_Read(dim address as longint, dim byref write_to as word[100], dim NoWords as word)
Pointer to RAM location where data has been stored. Reads a NoWords words from the memory location specified by address parameter. Nothing.
dim byref niz as byte[64] main: Flash_Read(0x6500, niz, 10) ... end
Flash_Read_Compact
Prototype Returns Description
sub procedure Flash_Read_Compact(dim address as longint, dim byref write_to as byte[100], dim NoBytes as word)
Pointer to RAM location where data has been stored. Reads a NoBytes bytes out of Flash memory that has been written in "compact" mode and stores it starting from the RAM location specified. Nothing.
dim byref niz as byte[64] main: Flash_Read_Compact(0x6500, niz, 10) ... end.
Requires Example
page
204
Library Example
dsPIC30:
In this example, various read/write tecniques to/from the on-chip FLASH memory are shown.
program FLASH_Test const dim cArr cArr2 jhh pv1 bb i as as as as as as string[35] byte[40] word[16] word word word iArr as word[8] = ("m", "i", "k", "r", "o", "E", "l", "e")
main: ADPCFG = 0xFFFF cArr = "mikroElektronikaYmikroElektronikaXX" pv1 = @cArr '--- erase the block first Flash_Erase32(0x006000) '--- write compact format to flash Flash_Write_Compact(0x006000, pv1, 36) '--- read compact format pv1 = @cArr2 Flash_Read4_Compact(0x006000, pv1) pv1 = pv1 + 12 Flash_Read4_Compact(0x006008, pv1) pv1 = pv1 + 12 Flash_Read4_Compact(0x006010, pv1) pv1 = pv1 + 12 '--- show what has been written i = 0 Uart1_Init(9600) Delay_ms(100) Uart1_Write_Char("s") Uart1_Write_Char("t") Uart1_Write_Char("a") Uart1_Write_Char("r") Uart1_Write_Char("t") Uart1_Write_Char(10)
' continues...
page
mikroElektronika: Development tools - Books - Compilers
205
making it simple...
' continued... while i <> 35 bb = cArr2[i] i = i + 1 Uart1_Write_Char(bb) wend '--- now for some non-compact flash-write jhh = iArr pv1 = @jhh Flash_Write_Init(0x006100, pv1) Flash_Write_Loadlatch4() Flash_Write_Loadlatch4() Flash_Write_DoWrite() end.
In this example, various read/write tecniques to/from the on-chip FLASH memory are shown.
program FLASH_Test const iArr as word[64] = ("m", "i", "k", "r", "o", "E", "l", "e", "k", "t", "r", "o", "n", "i", "k", "a") dim cArr as string[192] cArr2 as word[65] i, k as word main: AD1PCFG = 0xFFFF PORTB = 0x0004 TRISB = 1 cArr = "supercalifragillisticexpialidotiousABCDEFGHIJKLMNOPRSTUVWXYZ1234"
' press RB0 to continue while (PORTB.0 = 0) asm nop end asm wend '--- erase the block first Flash_Erase(0x006400) 'continues...
page
206
page
mikroElektronika: Development tools - Books - Compilers
207
making it simple...
I2C Library
IC full master MSSP module is available with a number of dsPIC30/33 and PIC24 MCU models. mikroBasic for dsPIC30/33 and PIC24 provides library which supports the master IC mode. Note: This library works solely with the I2C module and its registers. The I2C module takes full control over the SDA and SCL lines at init, so user doesn't need to take care of PORT/TRIS settings for those pins. Note: For dsPIC33 and PIC24 MCU's with multiple IC modules there are I2C1 (supports I2C1 module), I2C2 (supports I2C2 module) and I2C (supports I2C1 module same as I2C1 library) libraries. I2C and I2C1 libraries are equal due to compatibility reasons.
Library Routines
dsPIC30: I2C_Init I2C_Start I2C_Restart I2C_Wait_For_Idle I2C_Read I2C_Write I2C_Stop PIC24 and dsPIC33: I2C1_Init I2C1_Start I2C1_Restart I2C1_Wait_For_Idle I2C1_Read I2C1_Write I2C1_Stop I2C2_Init I2C2_Start I2C2_Restart I2C2_Wait_For_Idle I2C2_Read I2C2_Write I2C2_Stop I2C_Init I2C_Start I2C_Restart I2C_Wait_For_Idle I2C_Read I2C_Write I2C_Stop
page
208
I2C1_Init
Prototype Description Requires Example
sub procedure I2c_Init(dim scl as longint)
Initializes IC with desired clock (refer to device data sheet for correct values in respect with Fosc). Needs to be called before using other functions of IC Library. Library requires I2C1 module. Supported by dsPIC33 and PIC24 MCU's only.
I2C1_Init(100000)
I2C1_Start
Prototype Returns Description Requires
sub procedure I2c1_Start
If there is no error, function returns 0. Determines if IC bus is free and issues START signal. Library requires I2C1 module. IC must be configured before using this function. See I2C1_Init. Supported by dsPIC33 and PIC24 MCU's only.
I2C1_Start()
Example
I2C1_Restart
Prototype Description Requires
sub procedure I2C1_Restart
Issues repeated START signal. Library requires I2C1 module. IC must be configured before using this function. See I2C1_Init. Supported by dsPIC33 and PIC24 MCU's only.
I2C1_Restart()
Example
page
mikroElektronika: Development tools - Books - Compilers
209
making it simple...
I2C1_Wait_For_Idle
Prototype Returns Description Requires Example
sub procedure I2C1_Wait_For_Idle()
The function waits until IC bus gets free. This is a blocking function. Waits for IC bus to become free. IC must be configured before using this function. See I2C1_Init. Supported by dsPIC33 and PIC24 MCU's only.
I2C1_Wait_For_Idle()
I2C1_Read
Prototype Returns Description Requires
sub function I2c_Read(dim ack as word) as byte
Returns one byte from the slave. Reads one byte from the slave, and sends not acknowledge signal if parameter ack is 0, otherwise it sends acknowledge. Library requires MSSP module on dsPIC30/33 and PIC24 MCU. IC must be configured before using this function. See I2C1_Init. Also, START signal needs to be issued in order to use this function. See I2C1_Start. Supported by dsPIC33 and PIC24 MCU's only.
take = I2C1_Read(0) ' Read data and send not acknowledge signal
Example
I2C1_Write
Prototype Returns Description Requires
sub function I2c_Write(dim data as byte) as word
Returns 0 if there were no errors. Sends data byte (parameter data) via IC bus. Library requires MSSP module on dsPIC30/33 and PIC24 MCU. IC must be configured before using this function. See I2C1_Init. Also, START signal needs to be issued in order to use this function. See I2C1_Start. Supported by dsPIC33 and PIC24 MCU's only.
I2C_Write(0xA3)
Example
page
210
I2C1_Stop
Prototype Description Requires
sub procedure I2C1_Stop
Issues STOP signal. Library requires MSSP module on dsPIC30/33 and PIC24 MCU. IC must be configured before using this function. See I2C1_Init. Supported by dsPIC33 and PIC24 MCU's only.
I2C1_Stop
Example
I2C2_Init
Prototype Description Requires Example
sub procedure I2c2_Init(dim scl as longint)
Initializes IC with desired clock (refer to device data sheet for correct values in respect with Fosc). Needs to be called before using other functions of IC Library. Library requires I2C2 module. Supported by dsPIC33 and PIC24 MCU's only.
I2C2_Init(100000)
I2C2_Start
Prototype Returns Description Requires Example
sub procedure I2c2_Start
If there is no error, function returns 0. Determines if IC bus is free and issues START signal. Library requires I2C2 module. IC must be configured before using this function. See I2C2_Init. Supported by dsPIC33 and PIC24 MCU's only.
I2C2_Start
page
mikroElektronika: Development tools - Books - Compilers
211
making it simple...
I2C2_Restart
Prototype Description Requires Example
sub procedure I2C2_Restart
Issues repeated START signal. Library requires I2C2 module. IC must be configured before using this function. See I2C2_Init. Supported by dsPIC33 and PIC24 MCU's only.
I2C2_Restart
I2C2_Wait_For_Idle
Prototype Returns Description Requires Example
sub procedure I2C2_Wait_For_Idle
The function waits until IC bus gets free. This is a blocking function. Waits for IC bus to become free. IC must be configured before using this function. See I2C2_Init. Supported by dsPIC33 and PIC24 MCU's only.
I2C2_Wait_For_Idle
I2C2_Read
Prototype Returns Description
sub function I2c2_Read(dim ack as word) as byte
Returns one byte from the slave. Reads one byte from the slave, and sends not acknowledge signal if parameter ack is 0, otherwise it sends acknowledge. Library requires MSSP module on dsPIC30/33 and PIC24 MCU. IC must be configured before using this function. See I2C2_Init. Also, START signal needs to be issued in order to use this function. See I2C2_Start. Supported by dsPIC33 and PIC24 MCU's only.
take = I2C2_Read(0) ' Read data and send not acknowledge signal
Requires
Example
page
212
I2C2_Write
Prototype Returns Description Requires Example
sub function I2c2_Write(dim data as byte) as word
Returns 0 if there were no errors. Sends data byte (parameter data) via IC bus. START signal needs to be issued in order to use this function. See I2C2_Start.
I2C2_Write($A3)
I2C2_Stop
Prototype Description Requires
sub procedure I2C2_Stop
Issues STOP signal. Library requires MSSP module on dsPIC30/33 and PIC24 MCU. IC must be configured before using this function. See I2C2_Init. Supported by dsPIC33 and PIC24 MCU's only.
I2C2_Stop
Example
I2C_Init
Prototype Description
sub procedure I2c_Init(dim scl as longint)
Initializes IC with desired clock (refer to device data sheet for correct values in respect with Fosc). Needs to be called before using other functions of IC Library. For dsPIC33 and PIC24 MCU's this function initializes I2C1 module by default. Library requires I2C module.
I2C_Init(100000)
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
213
making it simple...
I2C_Start
Prototype Returns Description Requires Example
sub procedure I2C_Start
If there is no error, function returns 0. Determines if IC bus is free and issues START signal. IC must be configured before using this function. See I2C_Init.
I2C_Start
I2C_Restart
Prototype Description Requires Example
sub procedure I2C_Restart
Issues repeated START signal. IC must be configured before using this function. See I2C_Init.
I2C_Restart
I2C_Wait_For_Idle
Prototype Returns Description Requires Example
sub procedure I2C_Wait_For_Idle
The function waits until IC bus gets free. This is a blocking function. Waits for IC bus to become free. IC must be configured before using this function. See I2C_Init.
I2C_Wait_For_Idle
page
214
I2C_Read
Prototype Returns Description
sub function I2c_Read(dim ack as word) as byte
Returns one byte from the slave. Reads one byte from the slave, and sends not acknowledge signal if parameter ack is 0, otherwise it sends acknowledge. Library requires MSSP module on dsPIC30/33 and PIC24 MCU. IC must be configured before using this function. See I2C_Init. Also, START signal needs to be issued in order to use this function. See I2C_Start.
Requires
Example
take = I2C_Read(0) ' Read data and send not acknowledge signal
I2C_Write
Prototype Returns Description Requires
sub function I2c_Write(dim data as byte) as word
Returns 0 if there were no errors. Sends data byte (parameter data) via IC bus. Library requires MSSP module on dsPIC30/33 and PIC24 MCU. IC must be configured before using this function. See I2C_Init. Also, START signal needs to be issued in order to use this function. See I2C_Start.
Example
I2C_Write($A3)
I2C_Stop
Prototype Description Requires
sub procedure I2C_Stop
Issues STOP signal. Library requires MSSP module on dsPIC30/33 and PIC24 MCU. IC must be configured before using this function. See I2C_Init.
page
mikroElektronika: Development tools - Books - Compilers
215
making it simple...
Library Example
This code demonstrates use of IC library. dsPIC30/33 and PIC24 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 PORTB, to check if the cycle was successful (see the figure below how to interface 24c02 to dsPIC30/33 and PIC24).
program I2CEEPROM dim dAddr as word main: ADPCFG = 0xFFFF PORTB = 0 TRISB = 0 dAddr = 0x02
I2c_Init(0x000186A0) I2c_Start() I2c_Write(0xA2) I2c_Write(dAddr) I2c_Write(0xF5) I2c_Stop() Delay_ms(100) I2c_Start() I2c_Write(0xA2) I2c_Write(0x02) I2c_Restart() I2c_Write(0xA3) PORTB = I2c_Read(1) I2c_Stop() end.
I2C start signal byte via I2C (command to 24cO2) byte (address of EEPROM location) data (data to be written)
' issue I2C start signal ' send byte via I2C (device address + W) ' send byte (data address) ' issue I2C signal repeated start ' send byte (device address + R) ' Read the data (acknowledge)
page
216
HW Connection
VCC
VCC
1 2 3 4
A0 A1 NC GND
8 7 6 5
dsPIC4013
VCC
10K
11 12 13 14
34 RF2 RF3 33
10 Mhz
10K
24C02
page
mikroElektronika: Development tools - Books - Compilers
217
making it simple...
Keypad Library
mikroBasic for dsPIC30/33 and PIC24 provides library for working with 4x4 keypad; routines can also be used with 4x1, 4x2, or 4x3 keypad. Check the connection scheme at the end of the topic.
Library Routines
Keypad_Init Keypad_Key_Press Keypad_Key_Click
Keypad_Init
Prototype Description
sub procedure Keypad_Init(dim byref port as word)
Initializes key_port to work with keypad. All The function needs to be called before using other routines from Keypad library. On dsPIC30/33 and PIC24 platform, keypad library uses lower 8 bits <0:7> of the key_port.
Example
Keypad_Init(PORTB)
Keypad_Key_Press
Prototype Returns Description
sub function Keypad_Key_Press as word
1..16, depending on the key pressed, or 0 if no key is pressed. Checks if any key is pressed. Function returns 1 to 16, depending on the key pressed, or 0 if no key is pressed. Port needs to be appropriately initialized; see Keypad_Init.
kp = Keypad_Key_Press
Requires Example
page
218
Keypad_Key_Click
Prototype Returns Description Requires Example
sub function Keypad_Key_Click as word
1..16, depending on the key. Call to Keypad_Key_Click is a blocking call: function waits until any key is pressed and released. When released, function returns 1 to 16, depending on the key. Port needs to be appropriately initialized; see Keypad_Init.
kp = Keypad_Key_Click
Library Example
This program demonstrates how to use keypad and read keypad to GLCD.
program Keypad_4x4_test dim kp, oldkp as byte cnt as word txt as string[6] main: cnt = 0 Keypad_Init(PORTF) ADPCFG = $FFFF Glcd_Init_DsPicPro2() Glcd_Fill(0x00) Glcd_Set_Font(@FontSystem5x8, 5, 8, 32) Glcd_Write_Text("Keypad 4x4 example", 10, 0, 1) Glcd_Write_Text("Key pressed :", 10, 3, 1) Glcd_Write_Text("Times :" , 10, 6, 1) oldkp = 1 while TRUE nop kp = 0 ' Wait for key to be pressed while kp = 0 kp = Keypad_Key_Click() wend // continues ..
page
mikroElektronika: Development tools - Books - Compilers
219
making it simple...
' .. continued if oldkp = kp then Inc(cnt) else cnt = 1 end if oldkp = kp ' Prepare value for select case kp case 1 kp = 49 case 2 kp = 50 case 3 kp = 51 case 4 kp = 65 case 5 kp = 52 case 6 kp = 53 case 7 kp = 54 case 8 kp = 66 case 9 kp = 55 case 10 kp = 56 case 11 kp = 57 case 12 kp = 67 case 13 kp = 42 case 14 kp = 48 case 15 kp = 35 case 16 kp = 68 end select output ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' 1 2 3 A 4 5 6 B 7 8 9 C * 0 # D
Glcd_Write_Char(kp, 30, 4, 1) if cnt = 65535 then cnt = 0 end if ' Print on LCD WordToStr(cnt, txt) Glcd_Write_Text(txt, 10, 7, 1) wend 'while end.
page
220
HW Connection
4 5 6
dsPIC4013
RD0 RD1
34 33
VCC
11 12 VCC GND OSC1 OSC2
13 14
KEYPAD 4X4
10 Mhz
VCC
P2 10K
VCC
GND VCC GND GND GND GND GND RD0 RD1 RF0 RF1 RF4 RF5 Vee
E13 10uF
Key:5 Times:10
LCD 2X16
page
mikroElektronika: Development tools - Books - Compilers
221
making it simple...
Library Routines
Lcd_Init
Prototype
sub procedure Lcd_Init(dim byref data_port as word, dim db3, db2, db1, db0 as word, dim byref ctrl_port as word, dim rs, ctrl_rw, enable as word)
Description
Initializes LCD at dataport with the following pin settings: D3 -> dataport.7, D2 -> dataport.6, D1 -> dataport.5, D0 -> dataport.4 Parameters en and rs can be any available pin on any port. Use LAT exclusively for parameters. Check the connection scheme at the end of the chapter.
Example
Lcd_Init(PORTB, 7, 6, 5, 4, PORTD, 0, 1, 2)
page
222
Lcd_Out
Prototype Description
sub procedure Lcd_Out(dim row, col as word, dim text as string[20])
Prints text on LCD at the specified row and column (parameters row and col). Both string variables and literals can be passed as text. Port with LCD must be initialized. See Lcd_Init.
Lcd_Out(1, 3, "Hello!") ' Print "Hello!" at line 1, char 3
Requires Example
Lcd_Out_Cp
Prototype Description
sub procedure Lcd_Out_Cp(dim text as string[20])
Prints text on LCD at the current cursor position. Both string variables and literals can be passed as text. Port with LCD must be initialized. See Lcd_Init.
Lcd_Out_Cp("Here!") ' Print "Here!" at current cursor position
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
223
making it simple...
Lcd_Chr
Prototype Description
sub procedure Lcd_Chr(dim row, col, character as word)
Prints character on LCD at the specified row and column (parameters row and col). Both variables and literals can be passed as character. Port with LCD must be initialized. See Lcd_Init.
Lcd_Out(2, 3, "i") ' Print "i" at line 2, char 3
Requires Example
Lcd_Chr_Cp
Prototype Description
sub procedure Lcd_Chr_Cp(dim character as byte)
Prints character on LCD at current cursor position. Both variables and literals can be passed as character. Port with LCD must be initialized. See Lcd_Init.
Lcd_Chr_Cp("e") ' Print "e" at the current cursor position
Requires Example
Lcd_Cmd
Prototype Description
sub procedure Lcd_Cmd(dim command as word)
Sends command to LCD. You can pass one of the predefined constants to the function. The complete list of available commands is shown on the following page. Port with LCD must be initialized. See Lcd_Config or Lcd_Init.
Lcd_Cmd(LCD_Clear) ' Clear LCD display
Requires Example
page
224
LCD Commands
LCD Command
LCD_FIRST_ROW LCD_SECOND_ROW LCD_THIRD_ROW LCD_FOURTH_ROW LCD_CLEAR
Purpose Move cursor to 1st row Move cursor to 2nd row Move cursor to 3rd row Move cursor to 4th row Clear display Return cursor to home position, returns a shifted display to original position. Display data RAM is unaffected. Turn off cursor Underline cursor on Blink cursor on Move cursor left without changing display data RAM Move cursor right without changing display data RAM Turn LCD display on Turn LCD display off Shift display left without changing display data RAM Shift display right without changing display data RAM
LCD_RETURN_HOME
page
mikroElektronika: Development tools - Books - Compilers
225
making it simple...
Library Example
program LCD4bitTest dim txt as string[10] main: ADPCFG = $FFFF 'PORTB as digital Lcd_Init(PORTB, 7, 6, 5, 4, PORTD, 0, 1, 2) Lcd_Cmd(LCD_CURSOR_OFF) Lcd_Cmd(LCD_FIRST_ROW) Lcd_Chr_CP("m") Lcd_Chr_CP(105) Lcd_Chr_CP(107) Lcd_Chr_CP("r") Lcd_Chr_CP(111) ' ' ' ' ' m i k r o
page
226
Hardware Connection
dsPIC4013
RD0 RD1
34 33
VCC
11 12 13 14 VCC GND OSC1 OSC2
10 Mhz
VCC
P2 10K
VCC
GND VCC GND GND GND GND GND RD0 RD1 RF0 RF1 RF4 RF5 Vee
E13 10uF
CN16
page
mikroElektronika: Development tools - Books - Compilers
227
making it simple...
Library Routines
Lcd8_Init Lcd8_Config Lcd8_Out Lcd8_Out_Cp Lcd8_Chr Lcd8_Chr_Cp Lcd8_Cmd
Lcd8_Init
Prototype
procedure Lcd8_Init(dim byref data_port as word, dim db7, db6, db5, db4, db3, db2, db1, db0 as word, dim byref ctrl_port as word, dim rs, ctrl_rw, enable as word)
Description
Initializes LCD at dataport with following pin settings: D7 -> dataport.7 D6 -> dataport.6 D5 -> dataport.5 D4 -> dataport.4 D3 -> dataport.3 D2 -> dataport.2 D1 -> dataport.1 D0 -> dataport.0 Parameters en and rs can be any available pin on any port. Use LAT exclusively for parameters. Check the connection scheme at the end of the chapter.
Example
Lcd8_Init(PORTB, 7, 6, 5, 4, 3, 2, 1, 0, portd, 0, 1, 2)
page
228
Lcd8_Config
Prototype
sub procedure Lcd8_Config(dim byref data_port_Hi as word, dim db7, db6, db5, db4 as word, dim byref data_port_Lo as word, dim db3, db2, db1, db0 as word, dim byref ctrl_port as word, dim rs, ctrl_rw, enable as word)
Description
Initializes LCD at Control port (ctrlport) and Data ports (data_portLo and data_portHi) with pin settings you specify. Parameters RS, EN, WR need to be in range 07; Parameters data_portLo is port connected to LCD8.DATA.LowNibble with pins(db3..db0). data_portHi is port connected to LCD8.DATA.HiNibble with pins(db7..db4).
Example
Lcd8_Out
Prototype Description
sub procedure Lcd8_Out(dim row, col as word, dim text as string[20])
Prints text on LCD at the specified row and column (parameters row and col). Both string variables and literals can be passed as text. Ports with LCD must be initialized. See Lcd8_Init.
Lcd8_Out(1, 3, 'Hello!'); ' Print "Hello!" at line 1, char 3
Requires Example
Lcd8_Out_Cp
Prototype Description
sub procedure Lcd8_Out_Cp(dim text as string[20])
Prints text on LCD at the current cursor position. Both string variables and literals can be passed as text. Ports with LCD must be initialized. See Lcd8_Init.
Lcd8_Out_Cp("Here!") ' Print "Here!" at current cursor position
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
229
making it simple...
Lcd8_Chr
Prototype Description
sub procedure Lcd8_Chr(dim row, col, character as word)
Prints character on LCD at the specified row and column (parameters row and col). Both variables and literals can be passed as character. Ports with LCD must be initialized. See Lcd8_Init.
Lcd8_Out(2, 3, "i") ' Print "i" at line 2, char 3
Requires Example
Lcd8_Chr_Cp
Prototype Description
sub procedure Lcd8_Chr_Cp(dim character as byte)
Prints character on LCD at the current cursor position. Both variables and literals can be passed as character. Ports with LCD must be initialized. See Lcd8_Init.
Lcd8_Chr_Cp("e") ' Print "e" at current cursor position
Requires Example
Lcd8_Cmd
Prototype Description
sub procedure Lcd8_Cmd(dim command as word)
Sends command to LCD. You can pass one of the predefined constants to the function. The complete list of available commands is on the page 113. Ports with LCD must be initialized. See Lcd8_Init.
Lcd8_Cmd(LCD_Clear) ' Clear LCD display
Requires Example
page
230
Library Example
program LCD8bitTest dim txt as string[10] main: ADPCFG = $FFFF ' PORTB to be digital Lcd8_Init(PORTB, 7, 6, 5, 4, 3, 2, 1, 0, portd, 0, 1, 2) Lcd8_Cmd(LCD_CURSOR_OFF) Lcd8_Cmd(LCD_FIRST_ROW) LCD8_Chr_Cp("m") LCD8_Chr_Cp(105) LCD8_Chr_Cp(107) LCD8_Chr_Cp("r") LCD8_Chr_Cp(111) ' ' ' ' ' m i k r o
page
mikroElektronika: Development tools - Books - Compilers
231
making it simple...
Hardware Connection
dsPIC4013
RD0 RD1
34 33
VCC
11 12 13 14
RB7
RD2
22
10 Mhz
VCC
VCC
GND VCC RD0 RD2 RD1 RB0 RB1 RB2 RB3 RB4 RB5 RB6 RB7 Vee
P2 10K
E13 10uF
page
232
GLCD Library
mikroBasic for dsPIC30/33 and PIC24 provides a library for drawing and writing on commonly used Samsung (KS108/KS107) Graphic LCD 128x64. Note: mikroElektronika's development system based initialization routines can be found in setup library files located in Uses folder.
Library Routines
Basic routines:
Glcd_Init Glcd_Config Glcd_Set_Side Glcd_Set_Page Glcd_Set_X Glcd_Read_Data Glcd_Write_Data
Advanced routines:
Glcd_Fill Glcd_Dot Glcd_Line Glcd_V_Line Glcd_H_Line Glcd_Rectangle Glcd_Box Glcd_Circle Glcd_Set_Font Glcd_Write_Char Glcd_Write_Text Glcd_Image
page
mikroElektronika: Development tools - Books - Compilers
233
making it simple...
Glcd_Init
Prototype
sub procedure Glcd_Init(dim byref cs_lat as word, dim cs1, cs2 as word, dim byref ctrl_lat as word, dim rs, rw, rst, en as word, dim byref data_lat as word)
Description
Initializes GLCD at Data port (parameter dataport) with the pin settings you specify. Parameters cs1, cs2, rs, rw, rst, and en should all point to different pins. This procedure needs to be called before using other routines of GLCD library.
Glcd_Init(PORTF, 0, 1, PORTD, 0, 1, 3, 2, PORTB)
Example
Glcd_Config
Prototype
sub procedure Glcd_Config(dim byref cs_port as word, dim cs1, cs2 as word, dim byref ctrl_port as word, dim rs, rw, rst, en as word, dim byref data_port_Lo as word, dim byref data_port_Hi as word, dim ports_config as byte)
Description
Initializes GLCD module. Each of the control lines has both port and pin configurable, while data lines can be on two ports. Parameter data_port_Lo is PORT#1 connected to GLCD.DATA.LowNibble (D3..D0). data_port_Hi is PORT#2 connected to GLCD.DATA.HighNibble (D7..D4). ports_config is parameter that defines which nibble of the PORT#1 and PORT#2 is used: 0 = PORT#1.low nibble and PORT#2.low nibble, 1 = PORT#1.low nibble and PORT#2.high nibble, 2 = PORT#1.high nibble and PORT#2.low nibble, 3 = PORT#1.high nibble and PORT#2.high nibble. This function needs to be called before using other routines of GLCD library.
'--- Glcd init for EASYdsPIC3 Glcd_Config(PORTB, 4, 5, PORTF, 0, 1, 5, 4, PORTB, PORTD, 0)
Example
Glcd_Set_Side
Prototype Description
sub procedure Glcd_Set_Side(dim x as byte)
Selects side of GLCD, left or right. Parameter x specifies the side: values from 0 to 63 specify the left side, and values higher than 64 specify the right side. Use the functions Glcd_Set_Side, Glcd_Set_X, and Glcd_Set_Page to specify an exact position on GLCD. Then, you can use Glcd_Write_Data or Glcd_Read_Data on that location. GLCD needs to be initialized. See Glcd_Init.
Glcd_Set_Side(0); ' Select the left side of GLCD
Requires Example
page
234
Glcd_Set_Page
Prototype Description Requires Example
sub procedure Glcd_Set_Page(dim page as byte)
Selects page of GLCD, technically a line on display; parameter page can be 0..7. GLCD needs to be initialized. See Glcd_Init.
Glcd_Set_Page(5)
Glcd_Set_X
Prototype Description Requires Example
sub procedure Glcd_Set_X(dim x as byte)
Positions to x dots from the left border of GLCD within the given page. GLCD needs to be initialized. See Glcd_Init.
Glcd_Set_X(25)
Glcd_Read_Data
Prototype Returns Description
sub function Glcd_Read_Data as byte
One word from the GLCD memory. Reads data from from the current location of GLCD memory. Use the functions Glcd_Set_Side, Glcd_Set_X, and Glcd_Set_Page to specify an exact position on GLCD. Then, you can use Glcd_Write_Data or Glcd_Read_Data on that location. Reads data from from the current location of GLCD memory.
tmp = Glcd_Read_Data()
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
235
making it simple...
Glcd_Write_Data
Prototype Description Requires Example
sub procedure Glcd_Write_Data(dim data as byte)
Writes data to the current location in GLCD memory and moves to the next location. GLCD needs to be initialized. See Glcd_Init.
Glcd_Write_Data(data)
Glcd_Fill
Prototype Description
sub procedure Glcd_Fill(dim pattern as byte)
Fills the GLCD memory with byte pattern. To clear the GLCD screen, use Glcd_Fill(0); to fill the screen completely, use Glcd_Fill($FF). GLCD needs to be initialized. See Glcd_Init.
Glcd_Fill(0) ' Clear screen
Requires Example
Glcd_Dot
Prototype Description
sub procedure Glcd_Dot(dim x, y, color as byte)
Draws a dot on the GLCD at coordinates (x, y). Parameter color determines the dot state: 0 clears dot, 1 puts a dot, and 2 inverts dot state. GLCD needs to be initialized. See Glcd_Init.
Glcd_Dot(0, 0, 2) ' Invert the dot in the upper left corner
Requires Example
page
236
Glcd_Line
Prototype Description
sub procedure Glcd_Line(dim x1, y1, x2, y2, color as byte)
Draws a line on the GLCD from (x1, y1) to (x2, y2). Parameter color determines the dot state: 0 draws an empty line (clear dots), 1 draws a full line (put dots), and 2 draws a smart line (invert each dot). GLCD needs to be initialized. See Glcd_Init.
Glcd_Line(0, 63, 50, 0, 2)
Requires Example
Glcd_V_Line
Prototype Description
sub procedure Glcd_V_Line(dim y1, y2, x, color as byte)
Similar to GLcd_Line, draws a vertical line on the GLCD from (x, y1) to (x, y2). GLCD needs to be initialized. See Glcd_Init.
Glcd_V_Line(0, 63, 0, 1)
Requires Example
Glcd_H_Line
Prototype Description
sub procedure Glcd_H_Line(dim x1, x2, y, color as byte)
Similar to GLcd_Line, draws a horizontal line on the GLCD from (x1, y) to (x2, y). GLCD needs to be initialized. See Glcd_Init.
Glcd_H_Line(0, 127, 0, 1)
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
237
making it simple...
Glcd_Rectangle
Prototype Description
sub procedure Glcd_Rectangle(dim x1, y1, x2, y2, color as byte)
Draws a rectangle on the GLCD. Parameters (x1, y1) set the upper left corner, (x2, y2) set the bottom right corner. Parameter color defines the border: 0 draws an empty border (clear dots), 1 draws a solid border (put dots), and 2 draws a smart border (invert each dot). GLCD needs to be initialized. See Glcd_Init.
Glcd_Rectangle(10, 0, 30, 35, 1)
Requires Example
Glcd_Box
Prototype Description
sub procedure Glcd_Box(dim x1, y1, x2, y2, color as byte)
Draws a box on the GLCD. Parameters (x1, y1) set the upper left corner, (x2, y2) set the bottom right corner. Parameter color defines the fill: 0 draws a white box (clear dots), 1 draws a full box (put dots), and 2 draws an inverted box (invert each dot). GLCD needs to be initialized. See Glcd_Init.
Glcd_Box(10, 0, 30, 35, 1)
Requires Example
Glcd_Circle
Prototype Description
sub procedure Glcd_Circle(dim x, y, radius, color as integer)
Draws a circle on the GLCD, centered at (x, y) with radius. Parameter color defines the circle line: 0 draws an empty line (clear dots), 1 draws a solid line (put dots), and 2 draws a smart line (invert each dot). GLCD needs to be initialized. See Glcd_Init.
Glcd_Circle(63, 31, 25, 1)
Requires Example
page
238
Glcd_Set_Font
Prototype Description
sub procedure Glcd_Set_Font(dim font_address as longint, dim font_width, font_height as byte, dim font_offset as word)
Sets the font for text display routines, Glcd_Write_Char and Glcd_Write_Text. Font needs to be formatted as an array of byte. Parameter font_address specifies the address of the font; you can pass a font name with the @ operator. Parameters font_width and font_height specify the width and height of characters in dots. Font width should not exceed 128 dots, and font height should not exceed 8 dots. Parameter font_offset determines the ASCII character from which the supplied font starts. Demo fonts supplied with the library have an offset of 32, which means that they start with space. If no font is specified, Glcd_Write_Char and Glcd_Write_Text will use the default 5x8 font supplied with the library. You can create your own fonts by following the guidelines given in the file GLCD_Fonts.dbas. This file contains the default fonts for GLCD, and is located in your installation folder, Extra Examples > GLCD.
Requires Example
Glcd_Write_Char
Prototype Description
sub procedure Glcd_Write_Char(dim character, x, page, color as byte)
Prints character at page (one of 8 GLCD lines, 0..7), x dots away from the left border of display. Parameter color defines the fill: 0 writes a white letter (clear dots), 1 writes a solid letter (put dots), and 2 writes a smart letter (invert each dot). Use routine Glcd_Set_Font to specify font, or the default 5x7 font (included with the library) will be used.
Requires
GLCD needs to be initialized, see Glcd_Init. Use the Glcd_Set_Font to specify the font for display; if no font is specified, the default 5x8 font supplied with the library will be used.
Glcd_Write_Char("C", 0, 0, 1)
Example
page
mikroElektronika: Development tools - Books - Compilers
239
making it simple...
Glcd_Write_Text
Prototype Description
sub procedure Glcd_Write_Text(dim text as char[20], dim x, page, color as byte)
Prints text at page (one of 8 GLCD lines, 0..7), x dots away from the left border of display. Parameter color defines the fill: 0 prints a white letters (clear dots), 1 prints solid letters (put dots), and 2 prints smart letters (invert each dot). Use routine Glcd_Set_Font to specify font, or the default 5x7 font (included with the library) will be used.
Requires
GLCD needs to be initialized, see Glcd_Init. Use the Glcd_Set_Font to specify the font for display; if no font is specified, the default 5x8 font supplied with the library will be used.
Glcd_Write_Text("Hello world!", 0, 0, 1)
Example
Glcd_Image
Prototype Description
sub procedure Glcd_Image(dim image as byte[1024])
Displays bitmap image on the GLCD. Parameter image should be formatted as an array of 1024 bytes. Use the mikroBasics integrated Bitmap-to-LCD editor (menu option Tools > Graphic LCD Editor) to convert image to a constant array suitable for display on GLCD. GLCD needs to be initialized. See Glcd_Init.
Glcd_Image(my_image)
Requires Example
page
240
Library Example
The following example is a simple demonstration of GLCD Library:
program GlcdDemo include "__Lib_images" dim ii as byte jj as word someText as string[20] sub procedure delay2S delay_ms(2000) end sub main: ADPCFG = $FFFF TBLPAG = 0 Glcd_Init_DsPicPro2 Glcd_Fill(0xAA) delay2S while TRUE Glcd_Fill(0x00) Glcd_Image( truck_bmp ) delay2S for jj = 0 to 40 Glcd_Dot(jj,jj,1) next jj delay2S Glcd_Fill(0x00) Glcd_Line(120, 1, 5, 60, 1) delay2S Glcd_Line(12, 42, 5, 60, 1) delay2S Glcd_H_Line(5, 15, 6, 1) Glcd_V_Line(6, 15, 15, 1) Glcd_Rectangle(12, 20, 93,57, 1) delay2S for ii = 1 to 10 Glcd_Circle(63, 31, 3*ii, 1) next ii delay2S Glcd_Fill(0x00) Glcd_Set_Font(@FontSystem5x8, 5, 8, 32) someText = "Large Font 5x8" Glcd_Write_Text(someText, 3, 4, 1) delay2S wend end.
page
mikroElektronika: Development tools - Books - Compilers
241
making it simple...
Hardware Connection
VCC
D7 D6 D5 D4
RG15 RC1 RC2 RC3 RC4 RG6 RG7 RG8 MCLR RG9 Vss Vdd RA12 RA13 RB5 RB4 RB3 RB2 RB1 RB0
RG13 RG12 RG14 RA7 RA6 RG0 RG1 RF1 RF0 Vdd Vss RD7 RD6 RD5 RD4 RD13 RD12 RD3 RD2 RD1
RB6 RB7 RA9 RA10 AVdd AVss RB8 RB9 RB10 RB11 Vss Vdd RB12 RB13 RB14 RB15 RD14 RD15 RF4 RF5
RC14 RC13 RD0 RD11 RD10 RD9 RD8 RA15 RA14 Vss dsPIC30FXXXX OSC2 OSC1/CLKI Vdd RG2 RG3 RF6 RF7 RF8 RF2 RF3
D3 D2 D1
D0
10MHz
Vee
VCC
RST
Contrast Adjustment
P1 5K Vo
VCC
VCC
mikroElektronika dsPICPRO
Development system
page
242
20
Library Routines
T6963C_Init T6963C_writeData T6963C_writeCommand T6963C_setPtr T6963C_waitReady T6963C_fill T6963C_dot T6963C_write_char T6963C_write_text T6963C_line T6963C_rectangle T6963C_box T6963C_circle T6963C_image T6963C_sprite T6963C_set_cursor T6963C_clearBit T6963C_setBit T6963C_negBit T6963C_displayGrPanel T6963C_displayTxtPanel T6963C_setGrPanel T6963C_setTxtPanel T6963C_panelFill T6963C_grFill T6963C_txtFill T6963C_cursor_height T6963C_graphics T6963C_text T6963C_cursor T6963C_cursor_blink T6963C_Init_240x128 T6963C_Init_240x64
page
mikroElektronika: Development tools - Books - Compilers
243
making it simple...
T6963C_init
Prototype
sub procedure T6963C_init(dim width, height, fntW as word, dim byref data as word, dim byref cntrl as word, dim wr, rd, cd, rst as word)
Description
Initalizes the Graphic Lcd controller. This function must be called before all T6963C Library Routines. width - Number of horizontal (x) pixels in the display. height - Number of vertical (y) pixels in the display. fntW - Font width, number of pixels in a text character, must be set accordingly to the hardware. data - Address of the port on which the Data Bus is connected. cntrl - Address of the port on which the Control Bus is connected. wr - !WR line bit number in the *cntrl port. rd - !RD line bit number in the *cntrl port. cd - !CD line bit number in the *cntrl port. rst - !RST line bit number in the *cntrl port. Display RAM : The library doesn't know the amount of available RAM. The library cuts the RAM into panels : a complete panel is one graphics panel followed by a text panel, The programer has to know his hardware to know how much panel he has.
Requires Example
Nothing.
T6963C_init(240, 128, 8, PORTF, PORTD, 2, 1, 0, 4) ' ' ' ' ' ' ' ' init display for 240 pixel width and 128 pixel height 8 bits character width data bus on PORTF control bus on PORTD bit 2 is !WR bit 1 is !RD bit 0 is !CD bit 4 is RST
page
244
T6963C_writeData
Prototype Description Requires Example
sub procedure T6963C_writeData(dim data as byte)
Routine that writes data to T6963C controller. Ports must be initialized. See T6963C_init.
T6963C_writeData(AddrL)
T6963C_writeCommand
Prototype Description Requires Example
sub procedure T6963C_writeCommand(dim data as byte)
Routine that writes command to T6963C controller. Ports must be initialized. See T6963C_init.
T6963C_writeCommand(T6963C_CURSOR_POINTER_SET)
T6963C_setPtr
Prototype Description Requires Example
sub procedure T6963C_setPtr(dim p as word, dim c as byte)
This routine sets the memory pointer p for command c. Ports must be initialized. See T6963C_init.
T6963C_setPtr(T6963C_grHomeAddr + start, T6963C_ADDRESS_POINTER_SET)
T6963C_waitReady
Prototype Description Requires Example
sub procedure T6963C_waitReady
This routine pools the status byte, and loops until ready. Ports must be initialized. See T6963C_init.
T6963C_waitReady
page
mikroElektronika: Development tools - Books - Compilers
245
making it simple...
T6963C_fill
Prototype Description Requires Example
sub procedure T6963C_fill(dim v as byte, dim start, len as word)
This routine fills length with bytes to controller memory from start address. Ports must be initialized. See T6963C_init.
T6963C_fill(0x33,0x00FF,0x000F)
T6963C_dot
Prototype Description Requires Example
sub procedure T6963C_dot(dim x, y as integer, dim color as byte)
This sets current text work panel. It writes string str row x line y. mode = T6963C_ROM_MODE_[OR|EXOR|AND]. Ports must be initialized. See T6963C_init.
T6963C_dot(x0, y0, pcolor)
T6963C_write_char
Prototype Description
sub procedure T6963C_write_char(dim c, x, y, mode as byte)
This routine sets current text work panel. It writes char c row x line y. mode = T6963C_ROM_MODE_[OR|EXOR|AND] Ports must be initialized. See T6963C_init.
T6963C_write_char('A',22,23,AND)
Requires Example
T6963C_write_text
Prototype Description
sub procedure T6963C_write_text(dim byref str as byte[10], dim x, y, mode as byte)
This sets current text work panel. It writes string str row x line y. mode = T6963C_ROM_MODE_[OR|EXOR|AND] Ports must be initialized. See T6963C_init.
T6963C_write_text("GLCD LIBRARY DEMO, WELCOME !", 0, 0, T6963C_ROM_MODE_XOR)
Requires Example
page
246
T6963C_line
Prototype Description
sub procedure T6963C_line(dim x0, y0, x1, y1 as integer, dim pcolor as byte)
This routine current graphic work panel. It's draw a line from (x0, y0) to (x1, y1). pcolor = T6963C_[WHITE[BLACK] Ports must be initialized. See T6963C_init.
T6963C_line(0, 0, 239, 127, T6963C_WHITE)
Requires Example
T6963C_rectangle
Prototype Description
sub procedure T6963C_rectangle(dim x0, y0, x1, y1 as integer, dim pcolor as byte)
It sets current graphic work panel. It draws the border of the rectangle (x0, y0)-(x1, y1). pcolor = T6963C_[WHITE[BLACK]. Ports must be initialized. See T6963C_init.
T6963C_rectangle(20, 20, 219, 107, T6963C_WHITE)
Requires Example
T6963C_box
Prototype Description
sub procedure T6963C_box(dim x0, y0, x1, y1 as integer, dim pcolor as byte)
This routine sets current graphic work panel. It draws a solid box in the rectangle (x0, y0)-(x1, y1). pcolor = T6963C_[WHITE[BLACK]. Ports must be initialized. See T6963C_init.
T6963C_box(0, 119, 239, 127, T6963C_WHITE)
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
247
making it simple...
T6963C_circle
Prototype Description
sub procedure T6963C_circle(dim x, y as integer, dim r as longint, dim pcolor as word)
This routine sets current graphic work panel. It draws a circle, center is (x, y), diameter is r. pcolor = T6963C_[WHITE[BLACK] Ports must be initialized. See T6963C_init.
T6963C_circle(120, 64, 110, T6963C_WHITE)
Requires Example
T6963C_image
Prototype Description
sub procedure T6963C_image(const pic as ^byte)
This routine sets current graphic work panel : It fills graphic area with picture pointer by MCU. MCU must fit the display geometry. For example : for a 240x128 display, MCU must be an array of (240/8)*128 = 3840 bytes . Ports must be initialized. See T6963C_init.
T6963C_image(my_image)
Requires Example
T6963C_sprite
Prototype Description
sub procedure T6963C_sprite(dim px, py as byte, const pic as ^byte, dim sx, sy as byte)
This routine sets current graphic work panel. It fills graphic rectangle area (px, py)-(px + sx, py + sy) witch picture pointed by MCU. Sx and sy must be the size of the picture. MCU must be an array of sx*sy bytes. Ports must be initialized. See T6963C_init.
T6963C_sprite(76, 4, einstein, 88, 119) ' draw a sprite
Requires Example
page
248
T6963C_set_cursor
Prototype Description Requires Example
sub procedure T6963C_set_cursor(dim x, y as byte)
This routine sets cursor row x line y. Ports must be initialized. See T6963C_init.
T6963C_set_cursor(cposx, cposy)
T6963C_clearBit
Prototype Description Requires Example
sub procedure T6963C_clearBit(dim b as byte)
T6963C_setBit
Prototype Description Requires Example
sub procedure T6963C_setBit(dim b as byte)
T6963C_negBit
Prototype Description Requires Example
sub procedure T6963C_negBit(b as byte)
page
mikroElektronika: Development tools - Books - Compilers
249
making it simple...
T6963C_displayGrPanel
Prototype Description Requires Example
sub procedure T6963C_displayGrPanel(dim n as word)
T6963C_displayTxtPanel
Prototype Description Requires Example
sub procedure T6963C_displayTxtPanel(dim n as word)
T6963C_setGrPanel
Prototype Description Requires Example
sub procedure T6963C_setGrPanel(dim n as word)
Compute graphic start address for panel number n. Ports must be initialized. See T6963C_init.
T6963C_setGrPanel(n)
T6963C_setTxtPanel
Prototype Description Requires Example
sub procedure T6963C_setTxtPanel(dim n as word)
Compute text start address for panel number n. Ports must be initialized. See T6963C_init.
T6963C_setTxtPanel(n)
page
250
T6963C_panelFill
Prototype Description Requires Example
sub procedure T6963C_panelFill(dim v as word)
Fill full #n panel with v bitmap (0 to clear). Ports must be initialized. See T6963C_init.
T6963C_panelFill(v)
T6963C_grFill
Prototype Description Requires Example
sub procedure T6963C_grFill(dim v as word)
Fill graphic #n panel with v bitmap (0 to clear). Ports must be initialized. See T6963C_init.
T6963C_grFill(v)
T6963C_txtFill
Prototype Description Requires Example
sub procedure T6963C_txtFill(dim v as word)
Fill text #n panel with char v + 32 (0 to clear). Ports must be initialized. See T6963C_init.
T6963C_txtFill(v)
T6963C_cursor_height
Prototype Description Requires Example
sub procedure T6963C_cursor_height(dim n as word)
page
mikroElektronika: Development tools - Books - Compilers
251
making it simple...
T6963C_graphics
Prototype Description Requires Example
sub procedure T6963C_graphics(dim n as word)
T6963C_text
Prototype Description Requires Example
sub procedure T6963C_text(dim n as word)
T6963C_cursor
Prototype Description Requires Example
sub procedure T6963C_cursor(dim n as word)
T6963C_cursor_blink
Prototype Description Requires Example
sub procedure T6963C_cursor_blink(dim n as word)
page
252
T6963C_Init_240x128
Prototype Description Example
sub procedure T6963C_Init_240x128
Initialize T6963C based GLCD (240x128 pixels) with default settings for mE GLCD's.
T6963C_Init_240x128
T6963C_Init_240x64
Prototype Description Example
sub procedure T6963C_Init_240x64
Initialize T6963C based GLCD (240x64 pixels) with default settings for mE GLCD's.
T6963C_Init_240x64
Library Example
The following drawing demo tests advanced routines of T6963C GLCD library.
program T6963C include T6963c_consts include bitmap include bitmap2 dim panel as byte i as word curs as byte cposx, cposy as word ' current panel ' general purpose register ' cursor visibility ' cursor x-y position
= = = =
' port D is output only ' chip enable, reverse on, 8x8 font
' continues...
page
mikroElektronika: Development tools - Books - Compilers
253
making it simple...
' continued... '* enable both graphics and text display at the same time T6963C_graphics(1) T6963C_text(1) panel = 0 i = 0 curs = 0 cposy = 0 cposx = 0 '* text messages T6963C_write_text(" GLCD LIBRARY DEMO, WELCOME !", 0, 0, T6963C_ROM_MODE_XOR) T6963C_write_text(" EINSTEIN WOULD HAVE LIKED mE", 0, 15, T6963C_ROM_MODE_XOR) '* '* cursor '* T6963C_cursor_height(8) T6963C_set_cursor(0, 0) T6963C_cursor(0)
' 8 pixel height ' move cursor to top left ' cursor off
'* '* draw rectangles '* T6963C_rectangle(0, 0, 239, 127, T6963C_WHITE) T6963C_rectangle(20, 20, 219, 107, T6963C_WHITE) T6963C_rectangle(40, 40, 199, 87, T6963C_WHITE) T6963C_rectangle(60, 60, 179, 67, T6963C_WHITE) '* '* draw a cross '* T6963C_line(0, 0, 239, 127, T6963C_WHITE) T6963C_line(0, 127, 239, 0, T6963C_WHITE) '* '* draw solid boxes '* T6963C_box(0, 0, 239, 8, T6963C_WHITE) T6963C_box(0, 119, 239, 127, T6963C_WHITE)
' continues...
page
254
' continued... '* '* draw circles '* T6963C_circle(120, T6963C_circle(120, T6963C_circle(120, T6963C_circle(120, T6963C_circle(120, T6963C_circle(120, T6963C_circle(120, 64, 64, 64, 64, 64, 64, 64, 10, T6963C_WHITE) 30, T6963C_WHITE) 50, T6963C_WHITE) 70, T6963C_WHITE) 90, T6963C_WHITE) 110, T6963C_WHITE) 130, T6963C_WHITE)
T6963C_sprite(76, 4, einstein, 88, 119) ' draw a sprite T6963C_setGrPanel(1) ' select other graphic panel
T6963C_image(mikroPascal_logo_glcd_bmp) ' fill the graphic screen with a picture while true '* '* if RB1 is pressed, toggle the display between graphic panel '* 0 and graphic 1 '* if(PORTB.1 <> 0) then panel = panel + 1 panel = panel and 1 T6963C_displayGrPanel(panel) Delay_ms(300) '* '* if RB2 is pressed, display only graphic panel '* else if(PORTB.2 <> 0) then T6963C_graphics(1) T6963C_text(0) Delay_ms(300)
' continues...
page
mikroElektronika: Development tools - Books - Compilers
255
making it simple...
' continued... '* '* if RB3 is pressed, display only text panel '* else if(PORTB.3 <> 0) then T6963C_graphics(0) T6963C_text(1) Delay_ms(300) '* '* if RB4 is pressed, display text and graphic panels '* else if(PORTB.4 <> 0) then T6963C_graphics(1) T6963C_text(1) Delay_ms(300) '* '* if RB5 is pressed, change cursor '* else if(PORTB.5 <> 0) then curs = curs + 1 if(curs = 3) then curs = 0 end if select case curs case 0 T6963C_cursor(0) case 1 T6963C_cursor(1) T6963C_cursor_blink(1) case 2 T6963C_cursor(1) T6963C_cursor_blink(0) end select Delay_ms(300) end if end if end if end if end if
' continues...
page
256
page
mikroElektronika: Development tools - Books - Compilers
257
making it simple...
Hardware Connection
VCC
D1 D0 RD1 R/W RS E RST
D4
Contrast Adjustment
P1 10K
VCC VCC
R1 50
page
258
20
D5
RB6 RB7 RA9 RA10 AVdd AVss RB8 RB9 RB10 RB11 Vss Vdd RB12 RB13 RB14 RB15 RD14 RD15 RF4 RF5
RG15 RC1 RC2 RC3 RC4 RG6 RG7 RG8 MCLR RG9 Vss Vdd RA12 RA13 RB5 RB4 RB3 RB2 RB1 RB0
RG13 RG12 RG14 RA7 RA6 RG0 RG1 RF1 RF0 Vdd Vss RD7 RD6 RD5 RD4 RD13 RD12 RD3 RD2 RD1
RC14 RC13 RD0 RD11 RD10 RD9 RD8 RA15 RA14 Vss dsPIC30FXXXX OSC2 OSC1/CLKI Vdd RG2 RG3 RF6 RF7 RF8 RF2 RF3
MD0
10MHz
D6 D7 D2 D3
Library Routines
Mmc_Init Mmc_Read_Sector Mmc_Write_Sector Mmc_Read_Cid Mmc_Read_Csd Mmc_Fat_Init Mmc_Fat_Assign Mmc_Fat_Reset Mmc_Fat_Rewrite Mmc_Fat_Append Mmc_Fat_Read Mmc_Fat_Write Mmc_Set_File_Date Mmc_Fat_Delete Mmc_Fat_Get_File_Date Mmc_Fat_Get_File_Size Mmc_Fat_Get_Swap_File page
mikroElektronika: Development tools - Books - Compilers
259
making it simple...
Mmc_Init
Prototype Returns Description
sub function Mmc_Init(dim byref port as word, dim cspin as word) as word
Returns 0 if MMC card is present and successfully initialized, otherwise returns 1. Initializes MMC through hardware SPI communication, with chip select pin being given by the parameters port, cspin; communication port and pins are designated by the hardware SPI settings for the respective MCU. Function returns 0 if MMC card is present and successfully initialized, otherwise returns 1. Mmc_Init needs to be called before using other functions of this library.
i = Mmc_Init(PORTG, 9)
Example
Mmc_Read_Sector
Prototype Returns Description
sub function Mmc_Read_Sector(dim sector as longint, dim byref data as byte[512]) as byte
Returns 0 if read was successful, or 1 if an error occurred. Function reads one sector (512 bytes) from MMC card at sector address sector. Read data is stored in the array data. Function returns 0 if read was successful, or 1 if an error occurred. Library needs to be initialized, see Mmc_Init.
error = Mmc_Read_Sector(sector, data)
Requires Example
Mmc_Write_Sector
Prototype Returns Description
sub function Mmc_Write_Sector(dim sector as longint, dim byref data as byte[512]) as byte
Returns 0 if write was successful; returns 1 if there was an error in sending write command; returns 2 if there was an error in writing. Function writes 512 bytes of data to MMC card at sector address sector. Function returns 0 if write was successful, or 1 if there was an error in sending write command, or 2 if there was an error in writing. Library needs to be initialized, see Mmc_Init.
error = Mmc_Write_Sector(sector, data)
260
Mmc_Read_Cid
Prototype Returns Description Requires Example
sub function Mmc_Read_Cid(dim byref data_for_registers as byte[512]) as byte
Returns 0 if read was successful, or 1 if an error occurred. Function reads CID register and returns 16 bytes of content into data_for_registers. Library needs to be initialized, see Mmc_Init.
error = Mmc_Read_Cid(data)
Mmc_Read_Csd
Prototype Returns Description Requires Example
sub function Mmc_Read_Csd(dim byref data_for_registers as byte[512]) as byte
Returns 0 if read was successful, or 1 if an error occurred. Function reads CSD register and returns 16 bytes of content into data_for_registers. Library needs to be initialized, see Mmc_Init.
error = Mmc_Read_Csd(data)
Mmc_Fat_Init
Prototype Returns Description
sub function Mmc_Fat_Init(dim byref port as word, dim pin, spiselect as word) as word
Returns 0 if initialization is successful, 1 if boot sector was not found and 255 if card was not detected. Initializes hardware SPI communication; designated CS line for communication is RC2. The function returns 0 if MMC card is present and successfully initialized, otherwise returns 1. This function needs to be called before using other functions of MMC FAT library.
Example
Mmc_Fat_Init(PORTG, 9, 2)
page
mikroElektronika: Development tools - Books - Compilers
261
making it simple...
Mmc_Fat_Assign
Prototype Description
sub function Mmc_Fat_Assign(dim byref filename as char[11], dim create_file as byte) as byte
Assigns file for FAT operations. If file isn't present, function creates new file with given filename. filename parameter is filename of file. create_file is a parameter for creating new files. if create_file if different from 0 then new file is created (if there is no file with given filename). Library needs to be initialized; see Mmc_Fat_Init.
Mmc_Fat_Assign('MIKROELE.TXT',1)
Requires Example
Mmc_Fat_Reset
Prototype Description Requires
sub procedure Mmc_Fat_Reset(dim byref size as longint)
Opens file for reading. size is size of file in bytes. Ports must be initialized for FAT operations with MMC. See Mmc_Fat_Init. File must be assigned. See Mmc_Fat_Assign.
Example
Mmc_Fat_Reset(size)
Mmc_Fat_Rewrite
Prototype Description
sub procedure Mmc_Fat_Rewrite
Function resets the file pointer and clears the assigned file, so that new data can be written into the file. Library needs to be initialized; see Mmc_Fat_Init.
Mmc_Fat_Rewrite
Requires Example
page
262
Mmc_Fat_Append
Prototype Description
sub procedure Mmc_Fat_Append
The function moves the file pointer to the end of the assigned file, so that data can be appended to the file. Library needs to be initialized; see Mmc_Fat_Init.
Mmc_Fat_Append
Requires Example
Mmc_Fat_Read
Prototype Description Requires
sub procedure Mmc_Fat_Read(dim byref data as byte)
Reads data from file. bdata is data read from file. Ports must be initialized for FAT operations with MMC. See Mmc_Fat_Init. File must be assigned. See Mmc_Fat_Assign. File must be open for reading. See Mmc_Fat_Reset.
Example
Mmc_Fat_Read(character)
Mmc_Fat_Write
Prototype Description Requires
sub procedure Mmc_Fat_Write(dim byref fdata as char[512], dim datalen as word)
Writes data to MMC. fdata parameter is data written to MMC. data_len number of bytes that is written to MMC. Ports must be initialized for FAT operations with MMC. See Mmc_Fat_Init. File must be assigned. See Mmc_Fat_Assign. File must be open for writing. See Mmc_Fat_Rewrite or Mmc_Fat_Append.
Mmc_Fat_Write(file_contents, 42)
Example
page
mikroElektronika: Development tools - Books - Compilers
263
making it simple...
Mmc_Set_File_Date
Prototype Description Requires
sub procedure Mmc_Fat_Set_File_Date(dim year as word, dim month, day, hours, min, sec as byte)
Writes system timestamp to a file. Use this routine before each writing to the file; otherwise, file will be appended a random timestamp. Ports must be initialized for FAT operations with MMC. See Mmc_Fat_Init. File must be assigned. See Mmc_Fat_Assign. File must be open for writing. See Mmc_Fat_Rewrite or Mmc_Fat_Append.
' April 1st 2005, 18:07:00 Mmc_Fat_Set_File_Date(2005, 4, 1, 18, 7, 0)
Example
Mmc_Fat_Delete
Prototype Description Requires Example
sub procedure Mmc_Fat_Delete
Deletes file from MMC. Ports must be initialized for FAT operations with MMC. See Mmc_Fat_Init. File must be assigned. See Mmc_Fat_Assign.
Mmc_Fat_Delete
Mmc_Fat_Get_File_Date
Prototype Description Requires Example
sub procedure Mmc_Fat_Get_File_Date(dim byref year as word, dim byref month, day, hours, min, sec as byte)
Reads time attributes of file.You can read file year, month, day. hours, mins, seconds. Ports must be initialized for FAT operations with MMC. See Mmc_Fat_Init. File must be assigned. See Mmc_Fat_Assign.
Mmc_Fat_Get_File_Date(year, month, day, hours, mins)
Mmc_Fat_Get_File_Size
Prototype Description Requires
sub function Mmc_Fat_Get_File_Size as longint
This function returns size of file in bytes. Ports must be initialized for FAT operations with MMC. See Mmc_Fat_Init. File must be assigned. See Mmc_Fat_Assign.
my_file_size = Mmc_Fat_Get_File_Size
Example page
264
Mmc_Fat_Get_Swap_File
Prototype Returns
sub function Cf_Fat_Get_Swap_File(dim sectors_cnt as longint)as longint
No. of start sector for the newly created swap file, if swap file was created; otherwise, the function returns zero. This function is used to create a swap file on the MMC/SD media. It accepts as sectors_cnt argument the number of consecutive sectors that user wants the swap file to have. During its execution, the function searches for the available consecutive sectors, their number being specified by the sectors_cnt argument. If there is such space on the media, the swap file named MIKROSWP.SYS is created, and that space is designated (in FAT tables) to it. The attributes of this file are: system, archive and hidden, in order to distinct it from other files. If a file named MIKROSWP.SYS already exists on the media, this function deletes it upon creating the new one. The purpose of the swap file is to make reading and writing to MMC/SD media as fast as possible, by using the Mmc_Read_Sector() and Mmc_Write_Sector() functions directly, without potentially damaging the FAT system. Swap file can be considered as a "window" on the media where user can freely write/read the data, in any way (s)he wants to. Its main purpose in mikroBasic's library is to be used for fast data acquisition; when the time-critical acquisition has finished, the data can be re-written into a "normal" file, and formatted in the most suitable way.
Description
Requires Example
Ports must be initialized for FAT operations with MMC .See Mmc_Fat_Init.
' Tries to create a swap file, whose size will be at least 100 ' sectors. ' If it succeeds, it sends the No. of start sector over USART sub procedure M_Create_Swap_File size = Mmc_Fat_Get_Swap_File(100) if (size) then Usart_Write($AA) Usart_Write(Lo(size)) Usart_Write(Hi(size)) Usart_Write(Higher(size)) Usart_Write(Highest(size)) Usart_Write($AA) end if end sub
page
mikroElektronika: Development tools - Books - Compilers
265
making it simple...
Library Example
The following code tests MMC library routines. First, we fill the buffer with 512 M characters and write it to sector 56; then we repeat the sequence with character E at sector 56. Finally, we read the sectors 55 and 56 to check if the write was successful.
program mmc_test dim tmp as byte dim i as word dim data as byte[512] main: Uart1_Init(9600) SpiX_Init_Advanced(2, _SPI_MASTER, _SPI_8_BIT, _SPI_PRESCALE_SEC_1, _SPI_PRESCALE_PRI_64, _SPI_SS_DISABLE, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_HIGH, _SPI_ACTIVE_2_IDLE) i = MMC_Init(PORTG, 9) for i = 0 to 512 data[i] = "M" next i tmp = Mmc_Write_Sector(55, data) for i = 0 to 512 data[i] = "E" next i tmp = Mmc_Write_Sector(56, data) '** Verify: ** tmp = Mmc_Read_Sector(55, data) if tmp = 0 then for i = 0 to 512 Uart1_Write_Char(data[i]) next i end if tmp = Mmc_Read_Sector(56, data) if tmp = 0 then for i = 0 to 512 Uart1_Write_Char(data[i]) next i end if end. ' dsPICPro2 board ' Fill the buffer with the "M" character
' Write it to MMC card, sector 55 ' Fill the buffer with the "E" character
' Read from sector 55 ' Send 512 bytes from buffer to UART
' Read from sector 56 ' Send 512 bytes from buffer to UART
page
266
Hardware Connection
SPI-MISO MMC-CS# SPI-MOSI SPI-SCK R13 2K2 R15 2K2 R17 2K2
VCC3
1 2 3 4 5 6 7
R14 3K3
R16 3K3
R18 3K3
MMC/SD CARD
dsPIC4013
SPI-MOSI SPI-MISO
SPI-SCK
MMC-CS#
10
VCC
11 12
VCC3
VCC
13 14
C20 100nF
C19 100nF 1
VCC3
10 Mhz
1 2 3 4 5 6 7
MMC
Back view
page
mikroElektronika: Development tools - Books - Compilers
267
making it simple...
1
2.4ms
0
Example of transmission
1 1 0 0 01 0 0 01 1
Notes: Manchester receive routines are blocking calls (Man_Receive_Config, Man_Receive_Init, Man_Receive). This means that dsPIC 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.
Library Routines
Man_Receive_Config Man_Receive_Init Man_Receive Man_Send_Config Man_Send_Init Man_Send Man_Synchro page
268
Man_Receive_Config
Prototype Description
sub procedure Man_Receive_Config(dim byref port as word, dim rxpin as word)
The function prepares dsPIC for receiving signal. You need to specify the port and rxpin (07) of input signal. In case of multiple errors on reception, you should call Man_Receive_Init once again to enable synchronization.
Man_Receive_Config(PORTD, 6)
Example
Man_Receive_Init
Prototype Description
sub procedure Man_Receive_Init(dim byref port as word)
The function prepares PIC for receiving signal. You need to specify the port; rxpin is pin 6 by default. In case of multiple errors on reception, you should call Man_Receive_Init once again to enable synchronization.
Man_Receive_Init(PORTD)
Example
Man_Receive
Prototype Returns Description Requires Example
sub function Man_Receive(dim byref error as word) as word
Returns one byte from signal. Function extracts one byte from signal. If signal format does not match the expected, error flag will be set to 255. To use this function, you must first prepare the PIC for receiving. See Man_Receive_Config or Man_Receive_Init.
temp = Man_Receive(error) if error = true then ... ' error handling
page
mikroElektronika: Development tools - Books - Compilers
269
making it simple...
Man_Send_Config
Prototype Description Example
sub procedure Man_Send_Config(dim byref port as word, dim txpin as word)
The function prepares dsPIC for sending signal. You need to specify port and txpin (07) for outgoing signal. Baud rate is const 500 bps.
Man_Send_Config(PORTD, 0)
Man_Send_Init
Prototype Description Example
sub procedure Man_Send_Init(dim byref port as word)
The function prepares dsPIC for sending signal. You need to specify port for outgoing signal; txpin is pin 0 by default. Baud rate is const 500 bps.
Man_Send_Init(PORTD)
Man_Send
Prototype Description Requires Example
sub procedure Man_Send(dim data as word)
Sends one byte (data). To use this function, you must first prepare the dsPIC for sending. See Man_Send_Config or Man_Send_Init.
Man_Send(msg)
Man_Synchro
Prototype Returns Description Requires Example
sub function Man_Synchro as word
Half of the manchester bit length, given in multiples of 10us. This function returns half of the manchester bit length. The length is given in multiples of 10us. It is assumed that one bit lasts no more than 255*10us = 2550 us. To use this function, you must first prepare the dsPIC for receiving. See Man_Receive_Config or Man_Receive_Init.
man_len = Man_Synchro
page
270
Library Example
The following example transmits message in Manchester code. Message is delimited by markers $0B and $0E.
program ManchesterTx dim i, ch as byte s1 as string[20] main: s1 = "mikroElektronika" ADPCFG = 0xFFFF Man_Send_Config(PORTF, 1) while true Man_Send(0x0B) Delay_ms(100) ch = s1[0] i = 0 while(ch <> 0) 'Uart1_Write_Char(ch) Man_Send(ch) Delay_ms(90) i = i + 1 ch = s1[i] wend Man_Send(0x0E) Delay_ms(1000) wend end.
' Initialize manchester sender ' Send start marker ' Wait for a while
page
mikroElektronika: Development tools - Books - Compilers
271
making it simple...
The following code receives messages sent by the previous example, and prints it on LCD. Each error in the received string will be indicated by a quotation mark.
program ManchesterRx dim ERRr, errorR, ErrorCount, temp as word main: ADPCFG = 0xFFFF errorR = 0 ErrorCount = 0 Lcd8_Init(PORTB, 7, 6, 5, 4, 3, 2, 1, 0, PORTD, 0, 1, 2) ' Initialize LCD on PORTB Lcd8_Out(1,1,"mikroManchester") Man_Receive_Config(PORTF, 1) while true Lcd8_Cmd(LCD_FIRST_ROW) while true temp = Man_Receive(errorR) if (temp = 0x0B) then break end if if(errorR <> 0) then break end if wend while(temp <> 0x0E) temp = Man_Receive(errorR) ' if (errorR <> 0) then Lcd8_Chr_CP("?") ErrorCount = ErrorCount + 1 if(ErrorCount > 20) then 'Man_Receive_Init(PORTD) ' alternative: temp = Man_Synchro() ErrorCount = 0 end if else if (temp <> 0x0E) then Lcd8_Chr_CP(temp) end if end if Delay_ms(25) wend wend end. ' Configure and synchronize receiver
' We got the starting sequence ' Exit so we do not loop forever
page
272
Hardware Connection
Transmitter RF module
dsPIC4013
VCC
Antenna
VCC
11 12 13 14
10 Mhz
VCC A
RT4
GND
In
19 RD3
dsPIC4013
VCC
11
RR4
Receiver RF module
12 13 14
10 Mhz
19 RD3
VCC
page
mikroElektronika: Development tools - Books - Compilers
273
making it simple...
OneWire Library
OneWire library provides routines for communication via OneWire bus, for example with DS1820 digital thermometer. This is a Master/Slave protocol, and all the cabling required is a single wire. Because of the hardware configuration it uses (single pullup and open collector drivers), it allows for the slaves even to get their power supply from that line. Some basic characteristics of this protocol are: - single master system, - low cost, - low transfer rates (up to 16 kbps), - fairly long distances (up to 300 meters), - small data transfer packages. Each OneWire device also has a unique 64-bit registration number (8-bit device type, 48-bit serial number and 8-bit CRC), so multiple slaves can co-exist on the same bus. Note that oscillator frequency Fosc needs to be at least 4MHz in order to use the routines with Dallas digital thermometers.
Library Routines
Ow_Reset Ow_Read Ow_Write
page
274
Ow_Reset
Prototype Returns Description
sub function Ow_Reset(dim byref port as word, dim pin as word) as word
Returns 0 if DS1820 is present, 1 if not present. Issues OneWire reset signal for DS1820. Parameters port and pin specify the location of DS1820. Works with Dallas DS1820 temperature sensor only.
Ow_Reset(PORTA, 5)
Requires Example
Ow_Read
Prototype Returns Description Example
sub function Ow_Read(dim byref port as word, dim pin as word) as word
Data read from an external device over the OneWire bus. Reads one byte of data via the OneWire bus.
dim tmp as word ... tmp = Ow_Read(PORTD, 5)
Ow_Write
Prototype Description Example
sub procedure Ow_Write(dim byref port as word, dim pin as word, dim par as word)
page
mikroElektronika: Development tools - Books - Compilers
275
making it simple...
Library Example
This example reads the temperature using DS1820 connected to pin RF6. After reset, dsPIC obtaines temperature from sensor and prints it on LCD. Be sure to set the Fosc appropriately in your project.
program OneWire dim i, j1, j2 as byte text as char[10] tmp_sign as byte main: delay_ms(300) text = "Temperature:" ADPCFG = 0xFFFF Lcd_Init_EasyDsPIC2 Lcd_Cmd(LCD_CURSOR_OFF) Lcd_Out(1, 1, text) Lcd_Chr(2, 12, 223) Lcd_Chr(2, 13, "C") do Ow_Reset(PORTF, 6) Ow_Write(PORTF, 6, $CC) Ow_Write(PORTF, 6, $44) Delay_us(120) i = Ow_Reset(PORTF, 6) Ow_Write(PORTF, 6, $CC) Ow_Write(PORTF, 6, $BE) j1 = Ow_Read(PORTF, 6) j2 = Ow_Read(PORTF, 6) if j2 = $FF then tmp_sign = "-" else tmp_sign = "+" end if j2 = (j1 and $01) * 5 j1 = j1 >> 1 WordToStr(j1, text) Lcd_Chr(2, 7, tmp_sign) Lcd_Chr(2, 8, text[3]) Lcd_Chr(2, 9, text[4]) Lcd_Chr(2, 10, ".") // continues... ' onewire reset signal ' issue SKIP ROM command to DS1820 ' issue CONVERT T command to DS1820
issue SKIP ROM command to DS1820 issue READ SCRATCHPAD command to DS1820 get result get result
' get decimal value ' get temp value ' whole number
page
276
WordToStr(j2, text) Lcd_Chr(2, 11, text[4]) Delay_ms(500) loop until false end.
' decimal
Hardware Connection
125 C
DS1820
-50 C
VCC
dsPIC4013
VCC
VCC
11 12 13 14
10 Mhz
GND DQ
VCC
R10 10K
RF2
26
page
mikroElektronika: Development tools - Books - Compilers
277
making it simple...
PS/2 Library
mikroBasic provides a library for communicating with common PS/2 keyboard. The library does not utilize interrupts for data retrieval, and requires oscillator clock to be 6MHz and above. Please note that: - The pins to which a PS/2 keyboard is attached should be connected to pull-up resistors. - Although PS/2 is a two-way communication bus, this library does not provide dsPIC-to-keyboard communication; e.g. the Caps Lock LED will not turn on if you press the Caps Lock key.
Library Routines
Ps2_Init Ps2_Config Ps2_Key_Read
Ps2_Init
Prototype Description
sub procedure Ps2_Init(dim byref port as word)
Initializes port for work with PS/2 keyboard, with default pin settings. Port pin 0 is Data line, and port pin 1 is Clock line. You need to call either Ps2_Init or Ps2_Config before using other routines of PS/2 library. Both Data and Clock lines need to be in pull-up mode.
Ps2_Init(PORTB)
Requires Example
page
278
Ps2_Config
Prototype Description
sub procedure Ps2_Config(dim byref port as word, dim clkpin as word, dim datapin as word)
Initializes port for work with PS/2 keyboard, with custom pin settings. Parameters clock and data specify pins of port for Clock line and Data line, respectively. Clock and Data need to be in range 0..7 and cannot point to the same pin. You need to call either Ps2_Init or Ps2_Config before using other routines of PS/2 library.
Requires Example
Ps2_Key_Read
Prototype Returns Description
sub function Ps2_Key_Read(dim byref value as word, dim byref special as word, dim byref pressed as word) as word
Returns 1 if reading of a key from the keyboard was successful, otherwise 0. The procedure retrieves information about key pressed. Parameter value holds the value of the key pressed. For characters, numerals, punctuation marks, and space, value will store the appropriate ASCII value. Procedure recognizes the function of Shift and Caps Lock, and behaves appropriately. Parameter special is a flag for special function keys (F1, Enter, Esc, etc). If key pressed is one of these, special will be set to 1, otherwise 0. Parameter pressed is set to 1 if the key is pressed, and 0 if released.
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
279
making it simple...
Library Example
This simple example reads values of keys pressed on PS/2 keyboard and sends them via USART.
program ps2_test dim keydata, special, down as byte sub procedure AddressTrap org 0x08 PORTB = 0 TRISB = 0 LATB = 0xAAAA asm MOV [w15-32], w13 ;LSR w13, #8, w13 MOV w13, LATB ;LSR w15, #8, w13 ;MOV w13, LATB end asm while true wend end sub main: ADPCFG=$FFFF ' PORTB to be digital on 30F6014 keydata = 0 special = 0 down = 0 Ps2_Config(PORTC,14,13) Uart1_Init(9600) Delay_ms(100) ' Wait for keyboard to finish Uart1_Write_Text("You can type now!") ' Ready while true if Ps2_Key_Read(keydata, special, down) <> 0 then if ((down<>0) and (keydata = 16)) <> 0 then 'Uart1_Write_Char(keydata) else if ((down<>0) and (keydata = 13)) <> 0 then ' Enter Uart1_Write_Char(13) Uart1_Write_Char(10) else if ((down<>0) and (special=0) and (keydata<>0)) <> 0 then Uart1_Write_Char(keydata) end if end if end if Delay_ms(10) ' debounce end if wend end.
page
280
PWM Library
OC module is available with a number of dsPIC30/33 and PIC24micros. mikroBasic for dsPIC30/33 and PIC24 provides library which simplifies using PWM HW Module.
Library Routines
Pwm_Init Pwm_Set_Duty Pwm_Start Pwm_Stop
Pwm_Init
Prototype Returns Description
sub function Pwm_Init(dim freq_hz as longint, dim enable_channel_x, timer_prescale, use_timer_x as word) as word
Pwm period calculated. This function configures PWM module for the following parameters: freq_hz: desired pwm freq in Hz, enable_channel_x : pwm channel to initialize, timer_prescale: 1, 8, 64, 256, use_timer_x: 2 (timer 2), 3 (timer 3). Initializes PWM module at 5KHz, channel 1, no clock prescale and using timer 2:
dim period as word ... period = Pwm_Init(5000, 1, 1, 2)
Example
page
mikroElektronika: Development tools - Books - Compilers
281
making it simple...
Pwm_Set_Duty
Prototype Description Requires Example
sub procedure Pwm_Set_Duty(dim duty, channel as word)
Changes PWM duty ratio. Parameter duty takes values from 0 to 65535. You need a dsPIC30/33 and PIC24 with motor control PWM module to use this library. To use this function, module needs to be initalized see Pwm_Init. Set duty ratio to 50%:
dim period as word ... period = Pwm_Init(5000, 1, 0, 2) ... Pwm_Set_Duty(period div 2)
Pwm_Start
Prototype Description Requires
sub procedure Pwm_Start(dim enable_channel_x as byte)
Starts PWM on given channel enable_channel_x. You need a OC module to use this library. To use this function, module needs to be initalized see Pwm_Init.
Pwm_Start(1)
Example
Pwm_Stop
Prototype Description Requires
sub procedure Pwm_Stop(dim enable_channel_x as byte)
Stops PWM on given channel enable_channel_x. You need a OC module to use this library. To use this function, module needs to be initalized see Pwm_Init.
Pwm_Stop(1)
Example
page
282
Library Example
This is a simple demonstration on usage of the PWM library for dsPIC MCUs. PWM channels 1-4 are initialized for PWM output. Channels 1 and 3 have the same period (5kHz frequency) using timer2. Channels 2 and 4 have the same period (10kHz frequency) using timer3. Duty rate of channels 3 and 4 is changed continously in main loop, while duty rate for channels 1 and 2 is set to 50%.
program PWM_Test dim pwm_period1, pwm_period2, i1, i2 as word main: i1 = 0 i2 = 0 pwm_period1 = Pwm_Init(5000, 1, 1, 2) Pwm_Init(5000, 3, 1, 2) pwm_period2 = Pwm_Init(10000, 2, 1, 3) Pwm_Init(10000, 4, 1, 3) Pwm_Start(1) Pwm_Start(2) Pwm_Start(3) Pwm_Start(4) Pwm_Set_Duty(pwm_period1 div 2, 1) Pwm_Set_Duty(pwm_period2 div 2, 2) while(true) Pwm_Set_Duty(i1, 3) Pwm_Set_Duty(i2, 4) if (i1 = pwm_period1) then i1 = 0 end if if (i2 = pwm_period2) then i2 = 0 end if Inc(i1) Inc(i2) Delay_ms(1) wend end.
page
mikroElektronika: Development tools - Books - Compilers
283
making it simple...
Hardware Connection
RE0 RE1
26 25
300R
dsPIC2010
300R
10 Mhz
LD25
LD26
page
284
Library Routines
Pwm_Mc_Init Pwm_Mc_Set_Duty Pwm_Mc_Start Pwm_Mc_Stop
Pwm_Mc_Init
Prototype
sub function Pwm_Mc_Init(dim freq_hz, pair_output_mode, enable_output_x, clock_prescale_output_postscale as word ) as word
Returns Description
Nothing. Initializes the PWM module with duty ratio 0. Parameter freq is a desired PWM frequency in Hz (refer to device data sheet for correct values in respect with Fosc).
Pwm_Init needs to be called before using other functions from PWM Library.
Function parameters Parameters: - freq_hz - Desired PWM frequency, in Hz; - pair_output_mode - output mode for output pin pairs: 0- independent,1- complementary, - enable_output_x: (pin4h.pin3h.pin2h.pin1h.pin4l.pin3l.pin2l.pin1l): 0- disabled (pin is standard I/O), 1- enabled (pin is PWM output); - clock_prescale_output_postscale: PWM clock prescale/postscale settings:<0..3><0..15> - <1:1, 1:4, 1:16, 1:64><1:1, 1:2, ..., 1:16> This function (as well as the entire library) works on dsPIC30/33 that have the motor control PWM unit, e.g. dsPIC30F3010. Initializes PWM module at 5KHz, complementary pin-pair output, output enabled on pins 4l..1l, no clock prescale and no clock postscale:
Pwm_Mc_Init(5000,1,$0F,0)
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
285
making it simple...
Pwm_Mc_Set_Duty
Prototype Description Requires Example
sub procedure Pwm_Mc_Set_Duty(dim duty, channel as word )
Changes PWM duty ratio. Parameter duty takes values from 0 to 65535, value of the 50% of the duty ratio for active settings is retuned upon PWM init. You need a dsPIC30/33 with motor control PWM module to use this library. To use this function, module needs to be initalized see Pwm_Mc_Init.
Pwm_Mc_Init(5000,1,$0F,0) ... Pwm_Mc_Set_Duty(32767, 1)
Pwm_Mc_Start
Prototype Description Requires
sub procedure Pwm_Mc_Start
Starts PWM. You need a CCP module to use this library. To use this function, module needs to be initalized see Pwm_Mc_Init.
Pwm_Start
Example
Pwm_Mc_Stop
Prototype Description Requires
sub procedure Pwm_Mc_Stop
Stops PWM. You need a CCP module to use this library. To use this function, module needs to be initalized see Pwm_Mc_Init.
Pwm_Stop
Example
page
286
Library Example
This is a simple example on usage of the PWM library for dsPIC MCUs. Upon reset, PWM module is set up to 50% duty ratio. Then, this ratio is being decreased to zero, and then restored up to approx. 100%, in an infinite loop. The ratio decrease can be observed by turning the PWM output LED on or in digital form on PORTB.
program PWM dim i, duty_50 as word main: ADPCFG = $FFFF TRISE = 0 PORTB = $AAAA TRISB = 0 Delay_ms(1000) duty_50 = Pwm_Mc_Init(5000,1,0x01,0) ' Pwm_Mc_Init returns 50% of the duty i = duty_50 Pwm_Mc_Set_Duty(i, 1) Pwm_Mc_Start do i = i - 1 Pwm_Mc_Set_Duty(i,1) Delay_ms(1) if (i = 0) then i = duty_50 * 2 - 1 ' Do not allow the overflow end if PORTB = i loop until false; end.
page
mikroElektronika: Development tools - Books - Compilers
287
making it simple...
Hardware Connection
RE0 RE1
26 25
300R
dsPIC2010
300R
10 Mhz
LD25
LD26
page
288
RS-485 Library
RS-485 is a multipoint communication which allows multiple devices to be connected to a single signal cable. mikroBasic for dsPIC30/33 and PIC24 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. Each Slave has its unique address and receives only the packets addressed to it. Slave can never initiate communication. It is programmers responsibility to ensure that only one device transmits via 485 bus at a time. RS-485 routines require UART module on PORTF. Pins of UART need to be attached to RS-485 interface transceiver, such as LTC485 or similar. Pins of transceiver (Receiver Output Enable and Driver Outputs Enable) should be connected to PORTF, pin 0 (check the figure at end of the chapter). Note: Address 50 is the common address for all Slaves (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: dsPIC30/33 and PIC24 need to have a hardware UART module. Requires UART module to be initialized via UartX Library. Therefore library will work with UART module which has been initialized by user.
Library Routines
RS485Master_Init RS485Master_Receive RS485Master_Send RS485Slave_Init RS485Slave_Receive RS485Slave_Send
page
mikroElektronika: Development tools - Books - Compilers
289
making it simple...
RS485Master_Init
Prototype Description
sub procedure Rs485master_Init(dim byref port as word, dim pin as word)
Initializes dsPIC30/33 and PIC24 MCU as Master in RS-485 communication. Parameters port and pin determine the position (port and pin) of the Chip Select (CS) pin..
Requires Example
RS485Master_Receive
Prototype Description
sub procedure RS485Master_Receive(dim byref data as byte[5])
Receives any message sent by Slaves. Messages are multi-byte, so this function 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 the message, data[3] is number of message bytes received, 13, data[4] is set to 255 when message is received, data[5] is set to 255 if error has occurred, data[6] is the address of the Slave which sent the message.
Function automatically adjusts data[4] and data[5] upon every received message. These flags need to be cleared from the program. Requires Example MCU must be initialized as Master in RS-485 communication in order to be assigned an address. See RS485Master_Init.
RS485Master_Receive(msg)
page
290
RS485Master_Send
Prototype Description
sub procedure RS485Master_Send(dim byref data as byte[2], dim datalen, address as byte)
Sends data from buffer to Slave(s) specified by address via RS-485; datalen is a number of bytes in message (1 <= datalen <= 3). MCU must be initialized as Master in RS-485 communication in order to be assigned an address. See RS485Master_Init. It is programmers responsibility to ensure (by protocol) that only one device sends data via 485 bus at a time.
Requires
Example
RS485Master_Send(msg, 3, $12)
RS485Slave_Init
Prototype
sub procedure Rs485slave_Init(dim byref port as word, dim pin as word, dim address as byte)
Description
Initializes dsPIC30/33 and PIC24 MCU as a Slave in RS-485 communication. Parameters port and pin determine the position (port and pin) of the Chip Select (CS) pin. Slave address can take any value between 0 and 255, except 50, which is common address for all slaves.
Requires Example
UART HW module needs to be initialized. See UartX_Init. Initialize MCU as Slave with address 160:
Rs485slave_Init(PORTC, 13, 160) ' intialize mcu as slave, address 160
page
mikroElektronika: Development tools - Books - Compilers
291
making it simple...
RS485Slave_Receive
Prototype Description
sub procedure RS485Slave_Receive(dim byref data as byte[5])
Receives message addressed to it. Messages are multi-byte, so this function 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 the message, data[3] is number of message bytes received, 13, data[4] is set to 255 when message is received, data[5] is set to 255 if error has occurred, data[6] is the address of the Slave which sent the message.
Function automatically adjusts data[4] and data[5] upon every received message. These flags need to be cleared from the program. Requires MCU must be initialized as Slave in RS-485 communication in order to be assigned an address. See RS485Slave_Init.
RS485Slave_Read(msg)
Example
RS485Slave_Send
Prototype Description
sub procedure RS485Slave_Write(dim byref data as byte[2], dim datalen as byte)
Sends data from buffer to Master via RS-485; datalen is a number of bytes in message (1 <= datalen <= 3). MCU must be initialized as Slave in RS-485 communication in order to be assigned an address. See RS485Slave_Init. It is programmers responsibility to ensure (by protocol) that only one device sends data via 485 bus at a time.
Requires
Example
RS485Slave_Send(msg, 2)
page
292
Library Example
This is a simple demonstration on how to use the mikroBasic's RS485 library. It is being used in pair with the Rs485_Slave_Example project. Master (this machine) initiates communication with slave by sending 1 byte of data to the slave with designated slave address (160). The slave accepts data, increments it and sends it back to the master. The data received is shown on PORTB, Error on receive (0xAA) and number of consecutive unsuccessful retries on PORTD.
program rs485Transmiter dim dat as byte[10] i,j as integer you as longint '-------------- Interrupt routine sub procedure interrupt_uart() org 0x44 Rs485master_Receive(dat) IFS1.8 = 0 end sub main: you ADPCFG PORTD TRISD TRISB ' buffer for receving/sending messages
= = = = =
0 0xFFFF 0 0 0
UartX_Init(2, 9600) Rs485master_Init(PORTC, 13) dat[0] = 0xAa dat[1] = 0xF0 dat[2] = 0x0F dat[5] = 0 dat[6] = 0 Rs485master_Send(dat, 1, 160) PORTB = 0 PORTD = 0 dat[4] = 0 dat[5] = 0 U1STA.6 = 0 INTCON1.15 = 1 IFS1.8 = 0 IEC1.8 = 1 ' continues...
' ensure that message received flag is 0 ' ensure that error flag is 0
' no nesting of interrupts ' ensure interrupt not pending ' enable intterupt
page
mikroElektronika: Development tools - Books - Compilers
293
making it simple...
' continued...
while true ' upon completed valid message receiving ' data[4] is set to 255 you = you + 1 if dat[5] <> 0 then ' if error detected, signal it by PORTD = 0xAA ' setting PORTD to 0xAA end if if dat[4] <> 0 then ' if message received successfully you = 0 dat[4] = 0 ' clear message received flag j = dat[3] for i = 1 to j PORTB = dat[i-1] ' show data on PORTB next i ' increment received dat[0] dat[0] = dat[0] + 1 ' and send it to slave Delay_ms(100) Rs485master_Send(dat, 1, 160) end if if (you > 100000) then ' if in 100000 poll-cycles the answer PORTD = PORTD + 1 ' was not detected, signal
you = 0 ' failure of send-message Rs485master_Send(dat, 1, 160) if(PORTD > 10) then ' if sending failed 10 times PORTD = 0 Rs485master_Send(dat, 1, 50) ' send message on broadcast address end if end if wend end.
page
294
Hardware Connection
dsPIC4013
56R
VCC
11
4K7
VCC
56R 10K 1
12 13 14
30 28 27
R0
RE
DE
Vcc B A
GND
8 7 6 5
4K7
2 3 4
10 MhZ
DI
LTC485
VCC
10K 1 4K7 56R 56R
R0
RE
DE
Vcc B A
GND
8 7 6 5
4K7
2 3 4
DI
LTC485
4.7uF +
C1+
MAX232
4.7uF +
V+ C1C2+
+ 4.7uF
PC
C2VT2out R2in
4.7uF
RTS GND TX RX
page
mikroElektronika: Development tools - Books - Compilers
295
making it simple...
Library Routines
Soft_I2C_Init Soft_I2C_Start Soft_I2C_Read Soft_I2C_Write Soft_I2C_Stop
Soft_I2C_Init
Prototype Description
sub procedure Soft_I2C_Init(dim byref portOut as word, dim sda, clk as word)
Configures software IC. Parameters sda and sck specify the SDA and SCK pins, repectively; parameters cannot point at the same pin.
Soft_I2C_Init needs to be called before using other functions from Soft IC Library.
Example
Soft_I2C_Init(PORTD, 8, 9)
page
296
Soft_I2C_Start
Prototype Description Requires Example
sub procedure Soft_I2C_Start
Issues START signal. Needs to be called prior to sending and receiving data. Soft IC must be configured before using this function. See Soft_I2C_Init.
Soft_I2C_Start()
Soft_I2C_Read
Prototype Returns Description
sub function Soft_I2C_Read(dim ack as byte) as byte
Returns one byte from the slave. Reads one byte from the slave, and sends not acknowledge signal if parameter ack is 0, otherwise it sends acknowledge. START signal needs to be issued in order to use this function. See Soft_I2C_Start.
tmp = Soft_I2C_Read(0)
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
297
making it simple...
Soft_I2C_Write
Prototype Returns Description Requires Example
sub function Soft_I2C_Write(dim data as byte) as byte
Returns 0 if there were no errors. Sends data byte (parameter data) via IC bus. START signal needs to be issued in order to use this function. See Soft_I2C_Start.
Soft_I2C_Write(0xA3)
Soft_I2C_Stop
Prototype Description Requires Example
sub procedure Soft_I2C_Stop
Issues STOP signal. START signal needs to be issued in order to use this function. See Soft_I2C_Start.
Soft_I2C_Stop()
page
298
Library Example
The example demonstrates use of Software IC Library. dsPIC30/33 and PIC24 is connected (SCL, SDA pins) to 24C02 EEPROM. Program sends data to EEPROM (data is written at address 2). Then, we read data via IC from EEPROM and send its value to PORTC, to check if the cycle was successful. Check the hardware connection scheme at hardware I2C Library.
program i2c_test dim ee_adr, ee_data as byte dim jj as word main: Soft_I2C_Init(PORTG, 2, 3) TRISC = 0 PORTC = 0xFF Soft_I2C_Start() Soft_I2C_Write(0xA2) ee_adr = 2 Soft_I2C_Write(ee_adr) ee_data = 0xAA Soft_I2C_Write(ee_data) Soft_I2C_Stop() for jj = 0 to 65500 nop next jj Soft_I2C_Start() Soft_I2C_Write(0xA2) ee_adr = 2 Soft_I2C_Write(ee_adr) Soft_I2C_Start() Soft_I2C_Write(0xA3) ee_data = Soft_I2C_Read(0) Soft_I2C_Stop() PORTC = ee_data while TRUE nop wend end. ' ' ' ' ' Initialize full master mode PORTC is output Initialize PORTC Issue I2C start signal Send byte via I2C(command to 24cO2)
' Send byte(address for EEPROM) ' Send data(data that will 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 Display data on PORTC
page
mikroElektronika: Development tools - Books - Compilers
299
making it simple...
Library Routines
Soft_Spi_Config Soft_Spi_Init Soft_Spi_Read Soft_Spi_Write
Soft_Spi_Config
Prototype Returns Description
sub procedure Soft_Spi_Config(dim byref port as word, dim SCK, SDI, SDO as word)
Nothing.. Configures and initializes software SPI. 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 015 and cannot point at the same pin. Soft_Spi_Config needs to be called before using other functions from Soft SPI Library.
Requires Example
Nothing. 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:
Soft_Spi_Config(PORTB, 1, 2, 3)
page
300
Soft_Spi_Init
Prototype Description
sub procedure Soft_Spi_Init(dim byref port as word)
Configures and initializes software SPI. Parameter port specifies port of MCU on which SDI(pin 7), SDO(pin 8), and SCK(pin 6) will be located. Soft_Spi_Init needs to be called before using other functions from Soft SPI Library.
Example
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 RB7, SDO pin is RB8 and SCK pin is RB6:
Soft_Spi_Init(PORTB)
Soft_Spi_Read
Prototype Returns Description Requires
sub function Soft_Spi_Read(dim buffer as byte) as byte
Returns the received data. Provides clock by sending buffer and receives data. Soft SPI must be initialized and communication established before using this function. See Soft_Spi_Init.
tmp = Soft_Spi_Read(buffer)
Example
page
mikroElektronika: Development tools - Books - Compilers
301
making it simple...
Soft_Spi_Write
Prototype Description Requires
sub procedure Soft_Spi_Write(dim data as byte)
Immediately transmits data. Soft SPI must be initialized and communication established before using this function. See Soft_Spi_Init.
Soft_Spi_Write(1)
Example
Library Example
program Soft_spi_test dim value as word as word)
sub procedure Dac_Output(dim out_value dim temp as word PORTC = PORTC and $FD temp = (out_value >> 8) and 0x0F temp = temp or 0x30 Soft_SPI_Write(temp) temp = out_value Soft_SPI_Write(temp) PORTC = PORTC or 2 end sub
' Prepare hi-byte for transfer ' It's a 12-bit number, so only ' lower nibble of high byte is used ' Prepare lo-byte for transfer
main: ADPCFG=$FFFF PORTC = PORTC and 0xFFFE TRISC = TRISC and 0xFFFE PORTC = PORTC or 1 TRISC = TRISC and $FD ' CS pin is on the LATC.1 Soft_Spi_Config(PORTG, 6, 7, 8) while true value = 1 while value < $FFF DAC_Output(value) Delay_ms(10) value = value + 1 wend wend end.
page
302
Library Routines
Soft_Uart_Init Soft_Uart_Read Soft_Uart_Write
Soft_Uart_Init
Prototype Description
sub procedure Soft_Uart_Init(dim byref select_port as word, dim byref rx, tx as word, dim baud, inverted, stop_bits as word)
Initalizes software UART. Parameter select_port specifies Soft_Uart port. Parameters rx and tx specify the RX and TX pins (the two cannot point at the same pin). Parameter baud is the desired baud rate. Maximum baud rate depends on dsPICs clock and working conditions. Parameter inverted, if set to non-zero value, indicates inverted logic on output. Parameter stop_bits specifies the number of stop bits, and can take the following values:
const _UART_ONE_STOPBIT = 0 ' for 1 stop bit const _UART_TWO_STOPBITS = 1 ' for 2 stop bits Soft_Uart_Init needs to be called before using other routines of this library.
Example
This will initialize software UART and establish the communication at 9,600 bps:
Soft_Uart_Init(PORTF, 2, 3, 9600, 0 , 0)
page
mikroElektronika: Development tools - Books - Compilers
303
making it simple...
Soft_Uart_Read
Prototype Returns Description
sub function Soft_Uart_Read(dim byref error as byte) as byte
Returns a received byte. Function receives a byte via software UART. Parameter error will be zero if the transfer was successful. This is a non-blocking function call, so you should test the error manually (check the example below). Soft UART must be initialized and communication established before using this function. See Soft_Uart_Init.
' Here's a loop which holds until some datas been received: error = 1 do data = Soft_Uart_Read(error) loop until error <> 0
Requires
Example
Soft_Uart_Write
Prototype Description Requires
sub procedure Soft_Uart_Write(dim data as byte)
Function transmits a byte (data) via UART. Soft UART must be initialized and communication established before using this function. See Soft_Uart_Init. 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.
Example
Soft_Uart_Write(0x0A)
page
304
Library Example
The example demonstrates a simple data exchange via software UART. When the MCU receives data, it immediately sends it back. If dsPIC is connected to the PC, you can test the example from the mikroBasic terminal for RS-232 communication, menu item Tools > Terminal.
program Soft_Uart_example dim rx, _err as word
main: ADPCFG=$FFFF Soft_Uart_Init(PORTF, 2, 3, 9600, 0 , 0) while true rx=Soft_Uart_Read(_err) Soft_Uart_Write(rx) wend end.
page
mikroElektronika: Development tools - Books - Compilers
305
making it simple...
SPI Library
SPI module is available with all dsPIC30/33 and PIC24micros. mikroBasic provides a library for initializing Slave mode and comfortable work with Master mode. dsPIC30/33 and PIC24 can easily communicate with other devices via SPI: A/D converters, D/A converters, MAX7219, LTC1290, etc. Note: For dsPIC33 and PIC24 MCU's with multiple SPI modules there are Spi1 (supports Spi1 module), Spi2 (supports Spi2 module) and Spi (supports Spi1 module same as Spi1 library) libraries. Spi and Spi1 libraries are equal due to compatibility reasons. SpiX library is SPI selectable (user can select Spi1 or Spi2 module).
Library Routines
SpiX_Init SpiX_Init_Advanced SpiX_Data_Ready SpiX_Read SpiX_Write SpiX_Stop SPIX_TxBuffer_Empty Spi1_Init Spi1_Init_Advanced Spi1_Data_Ready Spi1_Read Spi1_Write Spi1_Stop SPI1_TxBuffer_Empty Spi_Init Spi_Init_Advanced Spi_Data_Ready Spi_Read Spi_Write Spi_Stop SPI_TxBuffer_Empty Spi2_Init Spi2_Init_Advanced Spi2_Data_Ready Spi2_Read Spi2_Write Spi2_Stop SPI2_TxBuffer_Empty
SpiX_Init
Prototype Description
sub procedure SpiX_Init(dim port_num as word)
Configures and initializes SPI module port_num with standard settings. SpiX_Init_Advanced or SpiX_Init needs to be called before using other functions of the SPI Library. Default settings are: Master mode, _SPI_PRESCALE_PRI_64, _SPI_PRESCALE_SEC_1, clock idle state low, data transmitted on low to high edge, and input data sampled at the middle of interval. For a custom configuration, use SpiX_Init_Advanced. You dont need to configure ports manually for using the module; library will take care of the initialization.
SpiX_Init(1)
Example page
306
SpiX_Init_Advanced
Prototype
sub procedure SpiX_Init_Advanced(dim port_num, master_mode, mode16, fcy_div, prescaler, slave_select, data_sample, clock_idle, edge as word)
Description
Configures and initializes SPI module port_num. SpiX_Init_Advanced or SpiX_Init needs to be called before using other functions of SPI Library. Parameter mode determines the work mode for SPI; can have the following values:
const const MASTER SLAVE = $20; = $00; // Master mode // Slave mode
Parameter fcy_div determines frequency divider (additional prescaler); can have the following values:
const const const const _SPI_PRESCALE_PRI_1 _SPI_PRESCALE_PRI_4 _SPI_PRESCALE_PRI_16 _SPI_PRESCALE_PRI_64 = = = = 0x0003; 0x0002; 0x0001; 0x0000; // // // // primary primary primary primary prescale prescale prescale prescale 1:1 4:1 16:1 64:1
Parameter prescale determines frequency divider (base prescaler); can have the following values:
const const const const const const const const _SPI_PRESCALE_SEC_1 _SPI_PRESCALE_SEC_2 _SPI_PRESCALE_SEC_3 _SPI_PRESCALE_SEC_4 _SPI_PRESCALE_SEC_5 _SPI_PRESCALE_SEC_6 _SPI_PRESCALE_SEC_7 _SPI_PRESCALE_SEC_8 = = = = = = = = 0x001C; 0x0018; 0x0014; 0x0010; 0x000C; 0x0008; 0x0004; 0x0000; // // // // // // // // secondary secondary secondary secondary secondary secondary secondary secondary prescale prescale prescale prescale prescale prescale prescale prescale 1:1 2:1 3:1 4:1 5:1 6:1 7:1 8:1
Parameter slave_ss enables or disables Slave Select; can have the following values:
const SLAVE_SS_ENABLE const SLAVE_SS_DIS = $80; = $00; // Slave Select enabled // Slave Select disabled
Parameter data_sample determines when data is sampled; can have the following values:
const DATA_SAMPLE_MIDDLE = $200; const DATA_SAMPLE_END = $00; // in middle of interval // at the end of interval
continues .. page
mikroElektronika: Development tools - Books - Compilers
307
making it simple...
Description (continued)
.. continued Parameter clock_idle determines idle state for clock; can have the following values:
const CLK_IDLE_HIGH const CLK_IDLE_LOW = $00; // Clock idle HIGH = $100; // Clock idle LOW
You dont need to configure ports manually for using the module; library will take care of the initialization. Example
// 10MHz Fosc -> 2.5MHz Fcy -> Fspi = 4.88KHz: SpiX_Init_Advanced(1, _SPI_MASTER,_SPI_8_BIT,_SPI_FCY_DIV64,_SPI_PRESCALE_8, _SPI_SS_DIS,_SPI_DATA_SAMPLE_MIDDLE,_SPI_CLK_IDLE_HIGH,_SPI_IDLE_2 _ACTIVE)
SpiX_Data_Ready
Prototype Returns Description Requires
sub function SpiX_Data_Ready as word
Function returns 1 if data is ready or 0 if there is no data on line. Use the function to test if data is ready for transmission. SPI must be initialized and communication established before using this function. See SpiX_Init_Advanced or SpiX_Init.
if SpiX_Data_Ready() = 1 then receive = SpiX_Read() end if
Example
page
308
SpiX_Read
Prototype Returns Description Requires
sub function SpiX_Read(dim data_out as word) as word
Returns the received data. Receives data via SPI. SPI must be initialized and communication established before using this function. See SpiX_Init_Advanced or SpiX_Init.
buffer = SpiX_Read(0)
Example
SpiX_Write
Prototype Description Requires
sub procedure SpiX_Write(dim data_out as word)
Writes 16-bit data to SPIxBUF, and immediately starts the transmission via SPI. SPI must be initialized and communication established before using this function. See SpiX_Init_Advanced or SpiX_Init.
SpiX_Write($1A)
Example
SpiX_Stop
Prototype Description Requires
sub procedure SpiX_Stop
Stops the transimission and shuts down the SPI module. SPI must be initialized and communication established before using this function. See SpiX_Init_Advanced or SpiX_Init.
SpiX_Stop
Example
page
mikroElektronika: Development tools - Books - Compilers
309
making it simple...
SpiX_TxBuffer_Empty
Prototype Returns Description Requires Example
sub function SpiX_TxBuffer_Empty as word
TRUE - SPI sending data transmission is over. FALSE - SPI sending data transmission is not over. Checks if SPI sending data transimission is over. SPI must be initialized and communication established before using this function. See SpiX_Init_Advanced or SpiX_Init.
check = SpiX_TxBuffer_Empty
Spi1_Init
Prototype Description
sub procedure Spi1_Init
Configures and initializes SPI with default settings. Spi_Init_Advanced or Spi_Init needs to be called before using other functions from SPI Library. Default settings are: Master mode, clock Fosc/4, clock idle state low, data transmitted on low to high edge, and input data sampled at the middle of interval. For a custom configuration, use Spi1_Init_Advanced.
Example
Spi1_Init()
page
310
Spi1_Init_Advanced
Prototype
sub procedure Spi1_Init_Advanced(dim master_mode, mode16, fcy_div, prescaler, slave_ss, data_sample, clock_idle, edge as word)
Description
Configures and initializes SPI. Spi1_Init_Advanced or Spi1_Init needs to be called before using other functions of SPI Library. Parameter mode determines the work mode for SPI; can have the following values:
const const MASTER SLAVE = 0x20 = 0x00 ' Master mode ' Slave mode
Parameter fcy_div determines frequency divider (additional prescaler); can have the following values:
const const const const FCY_DIV1 FCY_DIV4 FCY_DIV16 FCY_DIV64 = = = = 0x03 0x02 0x01 0x00 ' ' ' ' frequency frequency frequency frequency divided divided divided divided by by by by 1 4 16 64
Parameter prescale determines frequency divider (base prescaler); can have the following values:
const const const const const const const const PRESCALE_8 PRESCALE_7 PRESCALE_6 PRESCALE_5 PRESCALE_4 PRESCALE_3 PRESCALE_2 PRESCALE_1 = = = = = = = = 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C ' ' ' ' ' ' ' ' prescaler prescaler prescaler prescaler prescaler prescaler prescaler prescaler set set set set set set set set to to to to to to to to 1:8 1:7 1:6 1:5 1:4 1:3 1:2 1:1
Parameter slave_ss enables or disables Slave Select; can have the following values:
const SLAVE_SS_ENABLE const SLAVE_SS_DIS = 0x80 = 0x00 ' Slave Select enabled ' Slave Select disabled
Parameter data_sample determines when data is sampled; can have the following values:
const DATA_SAMPLE_MIDDLE = 0x200 const DATA_SAMPLE_END = 0x00 ' in middle of interval ' at the end of interval
continues .. page
mikroElektronika: Development tools - Books - Compilers
311
making it simple...
Description (continued)
.. continued Parameter clock_idle determines idle state for clock; can have the following values:
const CLK_IDLE_HIGH const CLK_IDLE_LOW = 0x00 ' Clock idle HIGH = 0x100 ' Clock idle LOW
You dont need to configure ports manually for using the module; library will take care of the initialization. Example
' 10MHz Fosc -> 2.5MHz Fcy -> Fspi = 4.88KHz: SPI1_Init_Advanced(_SPI_MASTER, _SPI_8_BIT, _SPI_FCY_DIV64, _SPI_PRESCALE_8, _SPI_SS_DIS, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_HIGH, _SPI_IDLE_2_ACTIVE)
Spi1_Data_Ready
Prototype Returns Description Requires
sub function Spi1_Data_Ready as word
Function returns 1 if data is ready or 0 if there is no data on line. Use the function to test if data is ready for transmission. SPI must be initialized and communication established before using this function. See Spi1_Init_Advanced or Spi1_Init.
if Spi1_Data_Ready() = 1 then receive = Spi1_Read() end if
Example
page
312
Spi1_Read
Returns the received data. Receives data via SPI. SPI must be initialized and communication established before using this function. See Spi_Init_Advanced or Spi_Init.
buffer = Spi1_Read()
Spi1_Write
Writes 16-bit data to SPIxBUF, and immediately starts the transmission via SPI. SPI must be initialized and communication established before using this function. See Spi_Init_Advanced or Spi_Init.
Spi1_Write(0x1A)
Spi1_Stop
Prototype Description Requires Example
sub procedure Spi1_Stop as word
Stops the transimission and shuts down the SPI module. SPI must be initialized and communication established before using this function. See Spi_Init_Advanced or Spi_Init.
Spi1_Stop()
page
mikroElektronika: Development tools - Books - Compilers
313
making it simple...
SPI1_TxBuffer_Empty
Prototype Returns Description Requires Example
sub function SPI1_TxBuffer_Empty as word
TRUE - SPI sending data transmission is over. FALSE - SPI sending data transmission is not over. Checks if SPI sending data transimission is over. SPI must be initialized and communication established before using this function. See Spi1_Init_Advanced or Spi1_Init.
check = SPI1_TxBuffer_Empty
Spi2_Init
Prototype Description
sub procedure Spi2_Init
Configures and initializes SPI with default settings. Spi_Init_Advanced or Spi_Init needs to be called before using other functions from SPI Library. Default settings are: Master mode, clock Fosc/4, clock idle state low, data transmitted on low to high edge, and input data sampled at the middle of interval. For a custom configuration, use Spi2_Init_Advanced.
Example
Spi2_Init()
page
314
Spi2_Init_Advanced
Prototype
sub procedure Spi2_Init_Advanced(dim master_mode, mode16, fcy_div, prescaler, slave_ss, data_sample, clock_idle, edge as word)
Description
Configures and initializes SPI. Spi1_Init_Advanced or Spi1_Init needs to be called before using other functions of SPI Library. Parameter mode determines the work mode for SPI; can have the following values:
const const MASTER SLAVE = 0x20 = 0x00 ' Master mode ' Slave mode
Parameter fcy_div determines frequency divider (additional prescaler); can have the following values:
const const const const FCY_DIV1 FCY_DIV4 FCY_DIV16 FCY_DIV64 = = = = 0x03 0x02 0x01 0x00 ' ' ' ' frequency frequency frequency frequency divided divided divided divided by by by by 1 4 16 64
Parameter prescale determines frequency divider (base prescaler); can have the following values:
const const const const const const const const PRESCALE_8 PRESCALE_7 PRESCALE_6 PRESCALE_5 PRESCALE_4 PRESCALE_3 PRESCALE_2 PRESCALE_1 = = = = = = = = 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C ' ' ' ' ' ' ' ' prescaler prescaler prescaler prescaler prescaler prescaler prescaler prescaler set set set set set set set set to to to to to to to to 1:8 1:7 1:6 1:5 1:4 1:3 1:2 1:1
Parameter slave_ss enables or disables Slave Select; can have the following values:
const SLAVE_SS_ENABLE const SLAVE_SS_DIS = 0x80 = 0x00 ' Slave Select enabled ' Slave Select disabled
Parameter data_sample determines when data is sampled; can have the following values:
const DATA_SAMPLE_MIDDLE = 0x200 const DATA_SAMPLE_END = 0x00 ' in middle of interval ' at the end of interval
continues .. page
mikroElektronika: Development tools - Books - Compilers
315
making it simple...
Description (continued)
.. continued Parameter clock_idle determines idle state for clock; can have the following values:
const CLK_IDLE_HIGH const CLK_IDLE_LOW = 0x00 ' Clock idle HIGH = 0x100 ' Clock idle LOW
You dont need to configure ports manually for using the module; library will take care of the initialization. Example
' 10MHz Fosc -> 2.5MHz Fcy -> Fspi = 4.88KHz: SPI2_Init_Advanced(_SPI_MASTER, _SPI_8_BIT, _SPI_FCY_DIV64, _SPI_PRESCALE_8, _SPI_SS_DIS, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_HIGH, _SPI_IDLE_2_ACTIVE)
Spi2_Data_Ready
Prototype Returns Description Requires
sub function Spi2_Data_Ready as word
Function returns 1 if data is ready or 0 if there is no data on line. Use the function to test if data is ready for transmission. SPI must be initialized and communication established before using this function. See Spi1_Init_Advanced or Spi1_Init.
if Spi2_Data_Ready() = 1 then receive = Spi1_Read() end if
Example
page
316
Spi2_Read
Returns the received data. Receives data via SPI. SPI must be initialized and communication established before using this function. See Spi_Init_Advanced or Spi_Init.
buffer = Spi2_Read()
Spi2_Write
Writes 16-bit data to SPIxBUF, and immediately starts the transmission via SPI. SPI must be initialized and communication established before using this function. See Spi_Init_Advanced or Spi_Init.
Spi2_Write(0x1A)
Spi2_Stop
Prototype Description Requires Example
sub procedure Spi2_Stop as word
Stops the transimission and shuts down the SPI module. SPI must be initialized and communication established before using this function. See Spi_Init_Advanced or Spi_Init.
Spi2_Stop()
page
mikroElektronika: Development tools - Books - Compilers
317
making it simple...
SPI2_TxBuffer_Empty
Prototype Returns Description Requires Example
sub function SPI2_TxBuffer_Empty as word
TRUE - SPI sending data transmission is over. FALSE - SPI sending data transmission is not over. Checks if SPI sending data transimission is over. SPI must be initialized and communication established before using this function. See Spi1_Init_Advanced or Spi1_Init.
check = SPI2_TxBuffer_Empty
page
318
Library Example
The code demonstrates communication with DAC on RB1 via Serial Peripheral Interface, module SPI1.
program SPITest const LOAD_PIN const CS_PIN dim value as word sub procedure InitMain() TRISC.LOAD_PIN = 0 ' LOAD pin TRISC.CS_PIN = 0 ' CS pin LATC.CS_PIN = 1 ' Set CS to inactive LATC.LOAD_PIN = 0 ' Set LOAD to inactive Spi2_Init_Advanced(_SPI_MASTER, _SPI_16_BIT, _SPI_PRESCALE_PRI_1, _SPI_PRESCALE_SEC_1, _SPI_SS_DISABLE, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_HIGH, _SPI_ACTIVE_2_IDLE) ' Init SPI end sub ' DAC increments (0..4095) --> output voltage (0..Vref) sub procedure DAC_Output(dim valueDAC as word) dim temp as word while (SPI2STAT.1 = 1) ' wait for SPI module nop wend LATC.CS_PIN = 0 ' CS enable SPI2BUF = 0x3000 or valueDAC ' Write CurrentValue to DAC (0x3 is required while (SPI2STAT.1 = 1) ' Wait for nop wend LATC.CS_PIN end sub = 1 to finish, if doing something = 2 = 1 ' DAC load pin ' DAC CS pin
main: InitMain() while true value = 1 while value < $FFF DAC_Output(value) Delay_ms(10) value = value+1 wend wend end.
page
mikroElektronika: Development tools - Books - Compilers
319
making it simple...
UART Library
UART hardware module is available with all dsPIC30/33 and PIC24micros. mikroBasic UART Library provides comfortable work with the Asynchronous (full duplex) mode. Note: For dsPIC33 and PIC24 MCU's with multiple SPI modules there are Uart1 (supports Uart1 module), Uart2 (supports Uart2 module) and Uart (supports Uart1 module same as Uart1 library) libraries. Uart and Uart1 libraries are equal due to compatibility reasons. UartX library is Uart selectable (user can select Uart1 or Uart2 module).
Library Routines
Uart1_Init Uart1_Init_Advanced Uart1_Enable Uart1_Disable Uart1_Data_Ready Uart1_Read_Char Uart1_Read_Text Uart1_Write_Char Uart1_Write_Text UartX_Init UartX_Init_Advanced UartX_Enable UartX_Disable UartX_Data_Ready UartX_Read_Char UartX_Read_Text UartX_Write_Char UartX_Write_Text Uart2_Init Uart2_Init_Advanced Uart2_Enable Uart2_Disable Uart2_Data_Ready Uart2_Read_Char Uart2_Read_Text Uart2_Write_Char Uart2_Write_Text Uart_Init Uart_Init_Advanced Uart_Enable Uart_Disable Uart_Data_Ready Uart_Read_Char Uart_Read_Text Uart_Write_Char Uart_Write_Text
page
320
UartX_Init
Prototype Description
sub procedure UartX_Init( dim uart_no as word, dim baud_rate as longint)
Initializes uart_no UART module with the desired baud rate, 8 bits, no parity, and one stop bit. 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. For custom configuration, use the UartX_Init_Advanced. The module is automatically enabled by this routine; you are not required to enable it manually with UartX_Enable.
UartX_Init or UartX_Init_Advanced need to be called before using other functions of the UART Library. 'Initialize HW UART and establish communication at 2400 bps: UartX_Init(1, 2400)
Requires Example
UartX_Init_Advanced
Prototype Description
sub procedure UartX_Init_Advanced( dim uart_no as word, dim baud_rate as longint, dim parity, stop_bits as word)
Initializes UART module with custom settings: Parameter baud_rate specifies the desired baud rate. Refer to the device data sheet for rates allowed for specific Fosc. If you specify the unsupported baud rate, compiler will report an error. Parameter parity specifies the parity, and can take the following values:
_UART_8BIT_NOPARITY _UART_8BIT_EVENPARITY _UART_8BIT_ODDPARITY _UART_9BIT_NOPARITY = = = = $000; $002; $004; $006; // // // // for for for for 8 8 8 9 bits, bits, bits, bits, no parity even parity odd parity no parity
Parameter stop_bits specifies the number of stop bits, and can take the values:
_UART_ONE_STOPBIT _UART_TWO_STOPBITS = $000; // for 1 stop bit = $001; // for 2 stop bits
You dont need to configure ports manually for using the module; library will take care of the initialization. The module is automatically enabled by this routine; you are not required to enable it manually with UartX_Enable. Requires Example
UartX_Init or UartX_Init_Advanced need to be called before using other functions of the UART Library. UartX_Init_Advanced(1, 2400, _UART_8BIT_NOPARITY, _UART_ONE_STOPBIT)
page
mikroElektronika: Development tools - Books - Compilers
321
making it simple...
UartX_Enable
Prototype Description
sub procedure UartX_Enable
Enables the UART1 or UART2 module depending on initialization settings. This is the default state after calling UartX_Init or UartX_Init_Advanced. Use this routine if you have disabled the module with the UartX_Disable.
UartX_Enable
Example
UartX_Disable
Prototype Description
sub procedure UartX_Disable
Disables the UART1 or UART2 module depending on initialization settings. All UART1 or UART 2 pins can be used as general I/O pins under the control of their corresponding PORT and TRIS bits.
UartX_Disable
Example
UartX_Data_Ready
Prototype Returns Description Requires Example
sub function UartX_Data_Ready as word
Function returns 1 if data is ready or 0 if there is no data on line. Use the function to test if data in receive buffer is ready for reading. Communication must be established before using the function. See Uart1_Init.
if UartX_Data_Ready = 1 then receive = UartX_Read_Char end if
page
322
UartX_Read_Char
Prototype Returns Description
sub function UartX_Read_Char as word
Returns the received byte. If byte is not received, returns 0. Function receives a byte via UART. Use the function UartX_Data_Ready to test if data is ready first. Communication must be established before using the function. See UartX_Init.
if UartX_Data_Ready = 1 then receive = UartX_Read_Char end if
Requires Example
UartX_Read_Text
Prototype Description
sub procedure UartX_Read_Text(dim byref output, delimiter as char[20])
Reads characters received via USART until the delimiter sequence is detected. The read sequence is stored in the parameter output; delimiter sequence is stored in the parameter delimiter. This is a blocking call: the delimiter sequence is expected, otherwise the procedure exits after 20 recieved characters. USART HW module must be initialized and communication established before using this function. See UartX_Init.
Requires
Example
//Read text until the sequence OK is received, and send it back UartX_Init(9600); delim = "OK" while TRUE if UartX_Data_Ready() = 1 then UartX_Read_Text(txt, delim) UartX_Write_Text(txt) end if wend
page
mikroElektronika: Development tools - Books - Compilers
323
making it simple...
UartX_Write_Char
Prototype Description Requires
sub procedure UartX_Write_Char(dim character as word)
Function transmits a character via UART. UART HW module must be initialized and communication established before using this function. See UartX_Init.
UartX_Write_Char("e") ' send character "e" via UART
Example
UartX_Write_Text
Prototype Description Requires
sub procedure UartX_Write_Text(dim text as char[20])
Function transmits text via UART. UART HW module must be initialized and communication established before using this function. See UartX_Init.
UartX_Write_Text("Hello world!") ' send message via UART
Example
Uart1_Init
Prototype Description
sub procedure Uart1_Init(dim baud_rate as longint)
Initializes UART module with the desired baud rate, 8 bits, no parity, and one stop bit. 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. For custom configuration, use the Uart1_Init_Advanced. The module is automatically enabled by this routine; you are not required to enable it manually with Uart1_Enable.
Uart1_Init or Uart1_Init_Advanced need to be called before using other functions of the UART Library. ' Initialize HW UART and establish communication at 2400 bps: Uart1_Init(2400)
Requires Example
page
324
Uart1_Init_Advanced
Prototype Description
sub procedure Uart1_Init_Advanced(dim baud_rate as longint, dim parity, stop_bits as word)
Initializes UART module with custom settings: Parameter baud_rate specifies the desired baud rate. Refer to the device data sheet for rates allowed for specific Fosc. If you specify the unsupported baud rate, compiler will report an error. Parameter parity specifies the parity, and can take the following values:
_UART_8BIT_NOPARITY _UART_8BIT_EVENPARITY _UART_8BIT_ODDPARITY _UART_9BIT_NOPARITY = = = = 0x000 0x002 0x004 0x006 ' ' ' ' for for for for 8 8 8 9 bits, bits, bits, bits, no parity even parity odd parity no parity
Parameter stop_bits specifies the number of stop bits, and can take the values:
_UART_ONE_STOPBIT _UART_TWO_STOPBITS = 0x000 = 0x001 ' for 1 stop bit ' for 2 stop bits
You dont need to configure ports manually for using the module; library will take care of the initialization. The module is automatically enabled by this routine; you are not required to enable it manually with Uart1_Enable. Requires Example
Uart1_Init or Uart1_Init_Advanced need to be called before using other functions of the UART Library. ' Initialize hardware UART and establish communication ' at 2400 bps, no parity, one stop bit: Uart1_Init_Advanced(2400, _UART_8BIT_NOPARITY, _UART_ONE_STOPBIT)
page
mikroElektronika: Development tools - Books - Compilers
325
making it simple...
Uart1_Enable
Prototype Description
sub procedure Uart1_Enable
Enables the UART1 module. This is the default state after calling Uart1_Init or Uart1_Init_Advanced. Use this routine if you have disabled the module with the Uart1_Disable.
Uart1_Enable()
Example
Uart1_Disable
Prototype Description
sub procedure Uart1_Disable
Disables the UART1 module. All UART1 pins can be used as general I/O pins under the control of their corresponding PORT and TRIS bits.
Uart1_Disable()
Example
Uart1_Data_Ready
Prototype Returns Description Requires Example
sub function Uart1_Data_Ready as word
Function returns 1 if data is ready or 0 if there is no data on line. Use the function to test if data in receive buffer is ready for reading. Communication must be established before using the function. See Uart1_Init.
' If data is ready, read it: if Uart1_Data_Ready() = 1 then receive = Uart1_Read() end if
page
326
Uart1_Read
Prototype Returns Description
sub function Uart1_Read as word
Returns the received byte. If byte is not received, returns 0. Function receives a byte via UART. Use the function Uart1_Data_Ready to test if data is ready first. Communication must be established before using the function. See Uart1_Init.
' If data is ready, read it: if Uart1_Data_Ready() = 1 then receive = Uart1_Read() end if
Requires Example
Uart1_Read_Text
Prototype Description
sub procedure Uart1_Read_Text(dim byref output, delimiter as string[20])
Reads characters received via USART until the delimiter sequence is detected. The read sequence is stored in the parameter output; delimiter sequence is stored in the parameter delimiter. This is a blocking call: the delimiter sequence is expected, otherwise the procedure exits after 20 recieved characters. Communication must be established before using the function. See Uart1_Init.
' Read text until the sequence "OK" is received, and send it back Uart1_Init(9600) delim = "OK" while TRUE if Uart1_Data_Ready() = 1 then Uart1_Read_Text(txt, delim) Uart1_Write_Text(txt) end if wend
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
327
making it simple...
Uart1_Write_Char
Prototype Description Requires Example
sub procedure Uart1_Write_Char(dim character as word)
Function transmits a character via UART. Communication must be established before using the function. See Uart1_Init.
Uart1_Write_Char("e") ' send character "e" via UART
Uart1_Write_Text
Prototype Description Requires Example
sub procedure Uart1_Write_Text(dim text as string[20])
Function transmits text via UART. Communication must be established before using the function. See Uart1_Init.
Uart1_Write_Char("Hello world!") ' send message via UART
page
328
Uart2_Init
Prototype Description
sub procedure Uart2_Init(dim baud_rate as longint)
Initializes UART module with the desired baud rate, 8 bits, no parity, and one stop bit. 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. For custom configuration, use the Uart2_Init_Advanced. The module is automatically enabled by this routine; you are not required to enable it manually with Uart2_Enable.
Uart2_Init or Uart2_Init_Advanced need to be called before using other functions of the UART Library. ' Initialize HW UART and establish communication at 2400 bps: Uart2_Init(2400)
Requires Example
Uart2_Init_Advanced
Prototype Description
sub procedure Uart2_Init_Advanced(dim baud_rate as longint, dim parity, stop_bits as word)
Initializes UART module with custom settings: Parameter baud_rate specifies the desired baud rate. Refer to the device data sheet for rates allowed for specific Fosc. If you specify the unsupported baud rate, compiler will report an error. Parameter parity specifies the parity, and can take the following values:
_UART_8BIT_NOPARITY _UART_8BIT_EVENPARITY _UART_8BIT_ODDPARITY _UART_9BIT_NOPARITY = = = = 0x000 0x002 0x004 0x006 ' ' ' ' for for for for 8 8 8 9 bits, bits, bits, bits, no parity even parity odd parity no parity
Parameter stop_bits specifies the number of stop bits, and can take the values:
_UART_ONE_STOPBIT _UART_TWO_STOPBITS = 0x000 = 0x001 ' for 1 stop bit ' for 2 stop bits
You dont need to configure ports manually for using the module; library will take care of the initialization. The module is automatically enabled by this routine; you are not required to enable it manually with Uart2_Enable. Requires Example
Uart2_Init or Uart2_Init_Advanced need to be called before using other functions of the UART Library. ' Initialize hardware UART and establish communication ' at 2400 bps, no parity, one stop bit: Uart2_Init_Advanced(2400, _UART_8BIT_NOPARITY, _UART_ONE_STOPBIT)
page
mikroElektronika: Development tools - Books - Compilers
329
making it simple...
Uart2_Enable
Prototype Description
sub procedure Uart2_Enable
Enables the UART2 module. This is the default state after calling Uart2_Init or Uart2_Init_Advanced. Use this routine if you have disabled the module with the Uart2_Disable.
Uart2_Enable()
Example
Uart2_Disable
Prototype Description
sub procedure Uart2_Disable
Disables the UART2 module. All UART2 pins can be used as general I/O pins under the control of their corresponding PORT and TRIS bits.
Uart2_Disable()
Example
Uart2_Data_Ready
Prototype Returns Description Requires Example
sub function Uart2_Data_Ready as word
Function returns 1 if data is ready or 0 if there is no data on line. Use the function to test if data in receive buffer is ready for reading. Communication must be established before using the function. See Uart2_Init.
' If data is ready, read it: if Uart2_Data_Ready() = 1 then receive = Uart2_Read() end if
page
330
Uart2_Read
Prototype Returns Description
sub function Uart2_Read as word
Returns the received byte. If byte is not received, returns 0. Function receives a byte via UART. Use the function Uart2_Data_Ready to test if data is ready first. Communication must be established before using the function. See Uart2_Init.
' If data is ready, read it: if Uart2_Data_Ready() = 1 then receive = Uart2_Read() end if
Requires Example
Uart2_Read_Text
Prototype Description
sub procedure Uart2_Read_Text(dim byref output, delimiter as string[20])
Reads characters received via USART until the delimiter sequence is detected. The read sequence is stored in the parameter output; delimiter sequence is stored in the parameter delimiter. This is a blocking call: the delimiter sequence is expected, otherwise the procedure exits after 20 recieved characters. Communication must be established before using the function. See Uart2_Init.
' Read text until the sequence "OK" is received, and send it back Uart2_Init(9600) delim = "OK" while TRUE if Uart2_Data_Ready() = 1 then Uart2_Read_Text(txt, delim) Uart2_Write_Text(txt) end if wend
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
331
making it simple...
Uart2_Write_Char
Prototype Description Requires Example
sub procedure Uart2_Write_Char(dim character as word)
Function transmits a character via UART. Communication must be established before using the function. See Uart2_Init.
Uart2_Write_Char("e") ' send character "e" via UART
Uart2_Write_Text
Prototype Description Requires Example
sub procedure Uart2_Write_Text(dim text as string[20])
Function transmits text via UART. Communication must be established before using the function. See Uart2_Init.
Uart2_Write_Char("Hello world!") ' send message via UART
page
332
Library Example
The following example demonstrates simple data exchange via UART. When microcontroller receives data, it immediately sends it back. If dsPIC is connected to the PC (see the figure on the following page), you can test the example from the mikroBasics terminal for the RS-232 communication, menu item Tools > Terminal.
program Uart_Test dim text, delimiter as string[15] dim test as word main: Uart1_Init(9600) delimiter = "stop" while TRUE if Uart1_Data_Ready() = 1 then Uart1_Read_Text(text, delimiter) ' only if you send "stop" Uart1_Write_Text(text) end if wend end.
page
mikroElektronika: Development tools - Books - Compilers
333
making it simple...
Hardware Connection
PC
RS-232 CON
6 1
9 5
CN3 SUB-D 9p
RS-232 CON
CN3 SUB-D 9p
2 7 3
VCC
C18 100nF
4 9 5
dsPICxxxx
VCC
U6
13 8 11 10 1 T2 IN C1+ C16 15 VGND R1 IN R2 IN T1 IN R1 OUT R2 OUT T1 OUT T2 OUT C2+ C2V+ VCC 2 16 7 4 5 12 9 14
Rx
11 12 13 14
MAX232
10 Mhz
RF2 RF3
26 25
VCC
page
334
Util Library
Util library contains miscellaneous routines useful for project development.
Button
Prototype Description
sub function Button(dim byref port as word, dim pin as byte, dim Time as word, dim ActiveState as byte) as word
Function eliminates the influence of contact flickering upon pressing a button (debouncing). Parameters port, pin specifies the location of the button (e.g. PORTB, 5); parameter time is a debounce period in milliseconds; parameter active_state can be either 0 or 1, and it determines if the button is active upon logical zero or logical one.
Example
page
mikroElektronika: Development tools - Books - Compilers
335
making it simple...
Conversions Library
mikroBasic Conversions Library provides routines for converting numerals to decimal and hexadecimal strings. You can get text representation of numerical value by passing it to one of the following routines:
Library Routines
ByteToStr WordToStr WordToStrWithZeros IntToStr LongintToStr WordToHex FloatToStr StrToInt StrToWord
ByteToStr
Prototype Description
sub procedure ByteToStr(dim input as byte, dim byref output as string[3])
Procedure creates string out of input (lower 8 bits of a 16-bit numerical value). Parameter output accepts the created string. Output string has fixed width of 3 characters, right aligned; remaining positions on the left (if any) are filled with blanks. Note: the term byte is only an alias for the word type; the routine actually works with the lower byte of a 16-bit input. See Simple Types for more information.
Example
page
336
WordToStr
Prototype Description
sub procedure WordToStr(dim input as word, dim byref output as string[5])
Procedure creates string out of input (numerical value of word type). Parameter output accepts the created string. Output string has fixed width of 5 characters, right aligned; remaining positions on the left (if any) are filled with blanks. Heres an example which prints value of a word variable on LCD:
dim input as word dim output as string[5] '... main: input = 437 WordToStr(input, output) Lcd_Out_Cp(output) ' Print "
Example
WordToStrWithZeros
Prototype Description
sub procedure WordToStrWithZeros(dim input as word, dim byref output as char[5])
Procedure creates an output string out of an unsigned number (numerical value of word type). Output string has fixed width of 5 characters; remaining positions on the left (if any) are filled with zeros. The output string should have the exact length as specified in the procedure prototype (5 characters). Heres an example which prints value of a word variable on LCD:
dim t as word dim txt as char[5] t = 437 WordToStrWithZeros(t, txt)
Example
IntToStr
Prototype Description
sub procedure IntToStr(dim input as integer, dim byref output as string[6])
Procedure creates string out of input (numerical value of integer type). Parameter output accepts the created string. Output string has fixed width of 6 characters, right aligned; remaining positions on the left (if any) are filled with blanks. Heres an example which prints value of an integer variable on LCD:
dim input as integer dim output as string[6] '... main: input = -4220 IntToStr(input, output) Lcd_Out_Cp(output) ' Print " -4220" (one blank here) on LCD
Example
page
mikroElektronika: Development tools - Books - Compilers
337
making it simple...
LongintToStr
Prototype Description
sub procedure LongintToStr(dim input as longint, dim byref output as string[11])
Procedure creates string out of input (numerical value of longint type). Parameter output accepts the created string. Output string has fixed width of 11 characters, right aligned; remaining positions on the left (if any) are filled with blanks. Heres an example which prints value of a longint variable on LCD:
dim input as longint dim output as string[11] '... main: input = -12345678 LongintToStr(input, output) Lcd_Out_Cp(output) ' Print "
Example
WordToHex
Prototype Description
sub procedure WordToHex(dim input as word, dim byref output as string[4])
Procedure creates string of hexadecimal digits out of input (numerical value of word type). Parameter output accepts the created string. Output string has fixed width of 4 characters, right aligned; remaining positions on the left (if any) are filled with zeroes. Heres an example which prints value of a word variable on LCD:
dim input as word dim output as string[4] '... main: input = 26 WordToHex(input, output) Lcd_Out_Cp(output) ' Print "001A" on LCD
Example
page
338
FloatToStr
Prototype Description
sub procedure FloatToStr(dim input as float, dim byref output as string[17])
Procedure creates string out of the input parameter, which should be a floating point number in the longint range (2147483648). Parameter output accepts the created string. The result is given in format "integer.fraction", left aligned. Note: Procedure wont return the correct result if input exceeds the longint range! Youll need to create a custom routine if you want to handle such large numbers. The integer part has flexible width of up to 11 characters (10 digits + sign). If the actual integer part is shorter than that, string will wrap to the integers length. The fraction part is always 5 characters long. If the actual fraction is shorter than 5 digits, remaining chars on the right will be filled with zeroes; if the fraction exceeds 5 digits, the fraction part will be trimmed.
Requires
If you want to use the FloatToStr for printing on LCD, ensure that your program clears/refreshes the display with each printing of a string. Otherwise, LCD will display the remnants (rightmost digits) of the previous string, if it was longer than the presently displayed one.
// An example which prints value of a float variable on LCD: dim input as float dim output as string[17] main: input = -3.1415 FloatToStr(input, output) Lcd_Out_Cp(output) ' Print "-3.14150" on LCD
Example
page
mikroElektronika: Development tools - Books - Compilers
339
making it simple...
StrToInt
Prototype Returns Description Requires Example
sub function StrToInt(dim byref input as string[6]) as integer
Integer variable. Converts a string to integer. The string is assumed to be a correct representation of a number. Heres an example which prints value of a longint variable on LCD:
dim ii as integer main: ii = StrToInt('-1234')
StrToWord
Prototype Returns Description Requires Example
sub function StrToWord(dim byref input as string[5]) as word
The string is assumed to be a correct representation of a number. Heres an example which prints value of a word variable on LCD:
dim ww as word main: ww = StrToword('65432')
page
340
Math Library
mikroBasic provides a set of library functions for floating point math handling.
Library Routines
acos asin atan atan2 ceil cos cosh exp fabs floor frexp ldexp log log10 modf pow power sin sinh sqrt tan tanh
acos
Prototype Description
sub function acos(dim x as float) as float
Function returns the arc cosine of parameter x; that is, the value whose cosine is x. Input parameter x must be between -1 and 1 (inclusive). The return value is in radians, between 0 and pi (inclusive).
page
mikroElektronika: Development tools - Books - Compilers
341
making it simple...
asin
Prototype Description
sub function asin(dim x as float) as float
Function returns the arc sine of parameter x; that is, the value whose sine is x. Input parameter x must be between -1 and 1 (inclusive). The return value is in radians, between -pi/2 and pi/2 (inclusive).
atan
Prototype Description
sub function atan(dim x as float) as float
Function computes the arc tangent of parameter x; that is, the value whose tangent is x. The return value is in radians, between -pi/2 and pi/2 (inclusive).
atan2
Prototype Description
sub function atan2(dim x, y as float) as float
This is the two argument arc tangent function. It is similar to computing the arc tangent of y/x, except that the signs of both arguments are used to determine the quadrant of the result, and x is permitted to be zero. The return value is in radians, between -pi and pi (inclusive).
ceil
Prototype Description
sub function ceil(dim num as float) as float
Function returns value of parameter num rounded up to the next whole number.
page
342
cos
Prototype Description
sub function cos(dim x as float) as float
cosh
Prototype Description
sub function cosh(dim x as float) as float
Function returns the hyperbolic cosine of x, defined mathematically as (ex+e-x)/2. If the value of x is too large (if overflow occurs), the function fails.
exp
Prototype Description
sub function exp(dim x as float) as float
Function returns the value of e the base of natural logarithms raised to the power of x (i.e. ex).
fabs
Prototype Description
sub function fabs(dim num as float) as float
page
mikroElektronika: Development tools - Books - Compilers
343
making it simple...
floor
Prototype Description
sub function floor(dim num as float) as float
Function returns value of parameter num rounded down to the nearest integer.
frexp
Prototype Description
sub function frexp(dim num as float, dim byref n as integer) as float
Function splits a floating-point value num into a normalized fraction and an integral power of 2. Return value is the normalized fraction, and the integer exponent is stored in the parameter n.
ldexp
Prototype Description
sub function ldexp(dim num as float, dim n as integer) as float
Function returns the result of multiplying the floating-point number num by 2 raised to the power n (i.e. returns x*2n).
log
Prototype Description
sub function log(dim x as float) as float
page
344
log10
Prototype Description
sub function log10(dim x as float) as float
modf
Prototype Description
sub function modf(dim num as float, dim byref whole as float) as float
Function returns the signed fractional component of num, placing its whole number component into the variable pointed to by whole.
pow
Prototype Description
sub function pow(dim x, y as float) as float
Function returns the value of x raised to the power of y (i.e. xy). If the x is negative, function will automatically cast the y into unsigned long.
power
Prototype Description
sub function power(dim x, y as longint) as longint
Function returns the value of an integer x raised to the power of y (i.e. xy).
sin
Prototype Description
sub function sin(dim x as float) as float
page
mikroElektronika: Development tools - Books - Compilers
345
making it simple...
sinh
Prototype Description
sub function sinh(dim x as float) as float
Function returns the hyperbolic sine of x, defined mathematically as (ex-e-x)/2. If the value of x is too large (if overflow occurs), the function fails.
sqrt
Prototype Description
sub function sqrt(dim num as float) as float
tan
Prototype Description
sub function tan(dim x as float) as float
Function returns the tangent of x in radians. The return value spans the allowed range of floating point in mikroBasic.
tanh
Prototype Description
sub function tanh(dim x as float) as float
page
346
Delays Library
mikroBasic provides a basic utility routines for creating software delay. You can create more advanced and flexible versions based on this library. Note: Routines do not provide an entirely accurate delay as it depends on the clock specified in the Project settings.
Library Routines
Delay_us Delay_ms Delay_Cyc
Delay_us
Prototype Description
sub procedure Delay_us(const time_us as word)
Causes a software delay in duration of time_us microseconds (a constant). Range of applicable constants depends on the oscillator frequency.
Delay_us(10) ' Ten microseconds pause
Example
Delay_ms
Prototype Description
sub procedure Delay_ms(const time_ms as word)
Causes a software delay in duration of time_ms milliseconds (a constant). Range of applicable constants depends on the oscillator frequency.
Delay_ms(1000) ' One second pause
Example
page
mikroElektronika: Development tools - Books - Compilers
347
making it simple...
Delay_Cyc
Prototype Description
sub procedure Delay_Cyc(dim x, y as word)
Example
page
348
String Library
mikroBasic includes a library which automatizes string related tasks.
Memchr Memcmp Memcpy Memmove Memset Strcat Strchr Strcmp Strcpy Strcspn Strlen Strncat Strncmp Strncpy Strpbrk Strrchr Strspn Strstr
page
mikroElektronika: Development tools - Books - Compilers
349
making it simple...
Memchr
Prototype Description
sub function Memchr(dim p as word, dim ch as char, dim n as word) as word;
Function locates the first occurrence of byte ch in the initial n bytes of memory area starting at the address p. Function returns the offset of this occurrence from the memory address p or $FFFF if the character was not found. For parameter p you can use either a numerical value (literal/variable/constant) indicating memory address or a dereferenced value of an object, for example @mystring or @PORTB.
Memcmp
Prototype Description
sub function Memcmp(dim p1, p2, n as word) as integer;
Function returns a positive, negative, or zero value indicating the relationship of first n bytes of memory areas starting at addresses p1 and p2. The Memcmp function compares two memory areas starting at addresses p1 and p2 for n bytes and returns a value indicating their relationship as follows: Value <0 =0 >0 Meaning p1 "less than" p2 p1 "equal to" p2 p1 "greater than" p2
The value returned by function is determined by the difference between the values of the first pair of bytes that differ in the strings being compared. For parameters p1 and p2 you can use either a numerical value (literal/variable/constant) indicating memory address or a dereferenced value of an object, for example @mystring or @PORTB.
page
350
Memcpy
Prototype Description
sub procedure Memcpy(dim p1, p2, n as word);
Function copies n bytes from the memory area starting at the address p2 to the memory area starting at p1. If these memory buffers overlap, the memcpy function cannot guarantee that bytes are copied before being overwritten. If these buffers do overlap, use the Memmove function. For parameters p1 and p2 you can use either a numerical value (literal/variable/constant) indicating memory address or a dereferenced value of an object, for example @mystring or @PORTB.
Memmove
Prototype Description
sub procedure Memmove(dim p1, p2, n as word);
Function copies n bytes from the memory area starting at the address p2 to the memory area starting at p1. If these memory buffers overlap, the Memmove function ensures that bytes in p2 are copied to p1 before being overwritten. For parameters p1 and p2 you can use either a numerical value (literal/variable/constant) indicating memory address or a dereferenced value of an object, for example @mystring or @PORTB.
Memset
Prototype Description
sub procedure Memset(dim p as word, dim ch as char, dim n as word);
Function fills the first n bytes in the memory area starting at the address p with the value of byte ch. For parameter p you can use either a numerical value (literal/variable/constant) indicating memory address or a dereferenced value of an object, for example @mystring or @PORTB.
page
mikroElektronika: Development tools - Books - Compilers
351
making it simple...
Strcat
Prototype Description
sub procedure Strcat(dim byref s1, s2 as string[100]);
Function appends the value of string s2 to string s1 and terminates s1 with a null character.
Strchr
Prototype Description
sub function Strchr(dim byref s as string[100], dim ch as char) as word;
Function searches the string s for the first occurrence of the character ch. The null character terminating s is not included in the search. Function returns the position (index) of the first character ch found in s; if no matching character was found, function returns $FFFF.
Strcmp
Prototype Description
sub function Strcmp(dim byref s1, s2 as string[100]) as word;
Function lexicographically compares the contents of strings s1 and s2 and returns a value indicating their relationship: Value <0 =0 >0 Meaning s1 "less than" s2 s1 "equal to" s2 s1 "greater than" s2
The value returned by function is determined by the difference between the values of the first pair of bytes that differ in the strings being compared.
page
352
Strcpy
Prototype Description
sub procedure Strcpy(dim byref s1, s2 as string[100]);
Function copies the value of string s2 to the string s1 and appends a null character to the end of s1.
Strcspn
Prototype Description
sub function Strcspn(dim byref s1, s2 as string[100]) as word;
Function searches the string s1 for any of the characters in the string s2. Function returns the index of the first character located in s1 that matches any character in s2. If the first character in s1 matches a character in s2, a value of 0 is returned. If there are no matching characters in s1, the length of the string is returned (not including the terminating null character).
Strlen
Prototype Description
sub function Strlen(dim byref s as string[100]) as word;
Function returns the length, in words, of the string s. The length does not include the null terminating character.
page
mikroElektronika: Development tools - Books - Compilers
353
making it simple...
Strncat
Prototype Description
sub procedure Strncat(dim byref s1, s2 as string[100]; n as word);
Function appends at most n characters from the string s2 to the string s1 and terminates s1 with a null character. If s2 is shorter than n characters, s2 is copied up to and including the null terminating character.
Strncmp
Prototype Description
sub function Strncmp(dim byref s1, s2 as string[100], dim n as word) as integer;
Function lexicographically compares the first n bytes of the strings s1 and s2 and returns a value indicating their relationship: Value <0 =0 >0 Meaning s1 "less than" s2 s1 "equal to" s2 s1 "greater than" s2
The value returned by function is determined by the difference between the values of the first pair of bytes that differ in the strings being compared (within first n bytes).
Strncpy
Prototype Description
sub procedure Strncpy(dim byref s1, s2 as string[100], dim n as word);
Function copies at most n characters from the string s2 to the string s1. If s2 contains fewer characters than n, s1 is padded out with null characters up to the total length of n characters.
page
354
Strpbrk
Prototype Description
sub procedure Strpbrk(dim byref s1, s2 as string[100]);
Function searches s1 for the first occurrence of any character from the string s2. The null terminator is not included in the search. Function returns an index of the matching character in s1. If s1 contains no characters from s2, function returns $FFFF.
Strrchr
Prototype Description
sub function Strrchr(dim byref s as string[100], dim ch as char) as word;
Function searches the string s for the last occurrence of character ch. The null character terminating s is not included in the search. Function returns an index of the last ch found in s; if no matching character was found, function returns $FFFF.
Strspn
Prototype Description
sub function Strspn(dim byref s1, s2 as string[100]) as word;
Function searches the string s1 for characters not found in the s2 string. Function returns the index of first character located in s1 that does not match a character in s2. If the first character in s1 does not match a character in s2, a value of 0 is returned. If all characters in s1 are found in s2, the length of s1 is returned (not including the terminating null character).
Strstr
Prototype Description
sub function strstr( dim byref s1, s2 as char[100] ) as byte
Function locates the first occurrence of the string s2 in the string s1 (excluding the terminating null character). Function returns a number indicating the position of the first occurrence of s2 in s1; if no string was found, function returns $FF. If s2 is a null string, the function returns 0.
page
mikroElektronika: Development tools - Books - Compilers
355
making it simple...
DSP Library
mikroBasic includes a libraries for DSP engine.
Library Routines :
FIR_Radix IIR_Radix FFT IFFT BitReverseComplex Vector_Set VectorPower Vector_Subtract VectorScale Vector_Negate Vector_Multiply Vector_Min Vector_Max Vector_Dot Vector_Correlate Vector_Convolve Vector_Add Matrix_Transponse Matrix_Subtract Matrix_Scale Matrix_Multiply Matrix_Add
page
356
FIR_Radix
Prototype
sub function FIR_Radix(dim FilterOrder as Word, dim ptrCoeffs as LongInt, dim BuffLength as Word, dim ptrInput as Word, dim Index as Word)as Word;
Description
This function applies FIR filter to ptrInput. Input samples must be in Y data space. FilterOrder is order of the filter + 1. ptrCoeffs is address of filter coeffitients in program memory. BuffLength represents number of samples ptrInput points to. ptrInput is address of input samples. Index index of current sample.
sum(k=0..N-1)(coef[k]*input[N-k]) - Current sample of processed signal(B[n]) N - buffer length k - Current index
Returns
IIR_Radix
Prototype
sub function IIR_Radix(dim BScale as Integer, dim AScale as Integer, dim ptrB as LongInt, dim ptrA as LongInt, dim FilterOrder as Word, dim ptrInput as Word, dim Input_Len as Word, dim ptrOutput as Word, dim Index as Word)as Word;
Description
This function applies IIR filter to ptrInput. Input and output samples must be in Y data space. AScale A Scale factor BScale B Scale factor ptrB Address of B coefficients (In program memory) ptrA Address of A coefficients (In program memory) FilterOrder is order of the filter + 1. ptrInput is address of input samples. Input_Len represents number of samples ptrInput points to. ptrOutput is address of output samples. Output length is equal to Input length. Index index of current sample.
Returns
y[n]=sum(k=0..N)(Acoef[k]*x[n-k]) - sum(k=1..M)(Bcoef[k]*y[n-k])
page
mikroElektronika: Development tools - Books - Compilers
357
making it simple...
FFT
Prototype sub procedure FFT(dim log2N as word, dim TwiddleFactorsAddress as LongInt, dim byref Samples as array[1024] of word); Function applies FFT transformation to input samples, input samples must be in Y data space. N - buffer length (must be the power of 2). TwiddleFactorsAddress is address of costant array which contains complex twiddle factors.The array is expected to be in program memory. Samples - array of input samples. Upon completion complex array of FFT samples is placed in the Samples parameter.
Description
Operation
F(k) = 1/N*sum_n (f(n)*WN(kn)), WN(kn) = exp[-(j*2*pi*k*n)/N] Fn - array of complex input samples n in {0, 1,... , N-1}, and k in {0, 1,... , N-1}, with N = 2^m, m element of Z. WN - TwiddleFactors The amplitude of current FFT sample is calculated as: F[k]=sqrt(Re[k]^2+ Im[k]^2)
Note
Complex array of FFT samples is placed in Samples parameter. Input Samples are arranged in manner Re,Im,Re,Im... (where Im is always zero). Output samples are arranged in the same manner but Im parts are different from zero. Output samples are symmetrical (First half of output samples (index from 0 to N/2) is identical as second half of output samples(index from N/2 to N). Input data is a complex vector such that the magnitude of the real and imaginary parts of each of its elements is less than 0.5. If greater or equal to this value the results could produce saturation. Note that the output values are scaled by a factor of 1/N, with N the length of the FFT. input is expected in natural ordering, while output is produced in bit reverse ordering.
page
358
IFFT
Prototype Description sub procedure IFFT(dim log2N as word, dim TwiddleFactorsAddress as LongInt, dim byref Samples as array[1024] of word); Function applies IFFT transformation to input samples, input samples must be in Y data space. N - buffer length (must be the power of 2). TwiddleFactorsAddress is address of costant array which contains complex twiddle factors.The array is expected to be in program memory. Samples array of input samples. Upon completion complex array of IFFT samples is placed in the Samples parameter. f(k) = 1/N*sum_n (F(n)*WN(kn)), WN(kn) = exp[(j*2*pi*k*n)/N] Fn - array of complex input samples n in {0, 1,... , N-1}, and k in {0, 1,... , N-1}, with N = 2^m, m element of Z. WN - TwiddleFactors Complex array of IFFT samples is placed in Samples parameter. Input Samples are arranged in manner Re,Im,Re,Im... (where Im is always zero). Input data is a complex vector such that the magnitude of the real and imaginary parts of each of its elements is less than 0.5. If greater or equal to this value the results could produce saturation. Note that the output values are scaled by a factor of 1/N, with N the length of the IFFT. Input is expected in bit reverse ordering, while output is produced in natural ordering.
Operation
Note
page
mikroElektronika: Development tools - Books - Compilers
359
making it simple...
BitReverseComplex
Prototype Description sub procedure BitReverseComplex(dim log2N as word, dim byref ReIm as array[1024] of word); This function does Complex (in-place) Bit Reverse re-organization. N - buffer length (must be the power of 2). ReIm - Output Sample(from FFT). f(k) = 1/N*sum_n (F(n)*WN(kn)), WN(kn) = exp[(j*2*pi*k*n)/N] Fn - array of complex input samples n in {0, 1,... , N-1}, and k in {0, 1,... , N-1}, with N = 2^m, m element of Z. WN - TwiddleFactors Input samples must be in Y data space.
Operation
Note
Vector_Set
Prototype sub procedure Vector_Set(dim byref input as array[1024] of word, dim size, value as word); Sets size elements of input to value, starting from the first element. Size must be > 0. Length of input is limited by available ram.
Description
VectorPower
Prototype sub function VectorPower(dim N as word, dim byref Vector as array[1024] of word) as word; Function returns result of power value (powVal) in radix point 1.15 powVal = sum (srcV[n] * srcV[n]) with n in {0, 1,... , numElems-1} Input samples must be in Y data space. AccuA used, not restored CORCON saved, used, restored
page
360
Vector_Subtract
Prototype Description sub procedure Vector_Subtract(dim byref dest, v1, v2 as array[1024] of word, dim numElems as word); This procedure does substraction of two vectors. numElems must be less or equal to minimum size of two vectors. v1 - First Vector v2 - Second Vector dest - Result Vector dstV[n] = srcV1[n] - srcV2[n] with n in {0, 1,... , numElems-1} AccuA used, not restored. CORCON saved, used, restored.
Operation
Note
VectorScale
Prototype Description sub procedure VectorScale(dim N as word, dim ScaleValue as integer, dim byref SrcVector, DestVector as array[1024] of word); This procedure does vector scaling with scale value. N - Buffer length SrcVector - original vector DestVector - scaled vector ScaleValue - Scale Value dstV[n] = sclVal * srcV[n], with n in {0, 1,... , numElems-1} AccuA used, not restored. CORCON saved, used, restored
Operation
Note
page
mikroElektronika: Development tools - Books - Compilers
361
making it simple...
Vector_Negate
Prototype Description sub procedure Vector_Negate(dim byref srcVector, DestVector as array[1024] of word ,dim numElems as word); This procedure does negation of vector. srcVector - Original vector destVector - Result vector numElems - Number of Elements dstV[n] = (-1)*srcV1[n] + 0, 0 <= n < numElems Negate of 0x8000 is 0x7FFF. AccuA used, not restored. CORCON saved, used, restored.
Operation
Note
Vector_Multiply
Prototype Description sub procedure Vector_Multiply(dim byref v1, v2, dest as array[1024] of word, dim numElems as word); This procedure does multiplication of two vectors. numElems must be less or equal to minimum size of two vectors. v1 - First Vector v2 - Second Vector dest - Result Vector dstV[n] = srcV1[n] * srcV2[n] with n in {0, 1,... , numElems-1} AccuA used, not restored. CORCON saved, used, restored
Operation
Note
page
362
Vector_Min
Prototype Description sub function Vector_Min(dim byref Vector as array[1024] of word, dim numElems as word, dim byref MinIndex as word) as word; This function find min. value in vector. Vector - Original vector. numElems - Number of elements MinIndex - Index of minimum value minVal = min {srcV[n], n in {0, 1,...numElems-1} if srcV[i] = srcV[j] = minVal, and i < j, then minIndex = j minimum value (minVal)
Operation
Returns
Vector_Max
Prototype Description sub function Vector_Max(dim byref Vector as array[1024] of word, dim numElems as word, dim byref MaxIndex as word)as word; This function find max. value in vector. Vector - Original vector. numElems - Number of elements MaxIndex - Index of maximum value maxVal = max {srcV[n], n in {0, 1,...numElems-1} } if srcV[i] = srcV[j] = maxVal, and i < j, then maxIndex = j maximum value (maxVal)
Operation
Returns
page
mikroElektronika: Development tools - Books - Compilers
363
making it simple...
Vector_Dot
Prototype Description sub function Vector_Dot(dim byref v1, v2 as array[1024] of word, dim numElems as word) as word; Procedure calculates vector dot product. v1 - First vector. v2 - Second vector numElems - Number of elements dotVal = sum (srcV1[n] * srcV2[n]), with n in {0, 1,... , numElems-1} AccuA used, not restored. CORCON saved, used, restored.
Operation
Note
Vector_Correlate
Prototype Description sub procedure Vector_Correlate(dim byref v1, v2, dest as array[1024] of word, dim numElemsV1, numElemsV2 as word); Procedure calculates Vector correlation (using convolution). v1 - First vector. v2 - Second vector numElemsV1 - Number of first vector elements numElemsV2 - Number of second vector elements dest - Result vector r[n] = sum_(k=0:N-1){x[k]*y[k+n]}, where: x[n] defined for 0 <= n < N, y[n] defined for 0 <= n < M, (M <= N), r[n] defined for 0 <= n < N+M-1.
Operation
page
364
Vector_Convolve
Prototype Description sub procedure Vector_Convolve(dim byref v1, v2, dest as array[1024] of word, dim numElemsV1, numElemsV2 as word); Procedure calculates Vector using convolution. v1 - First vector. v2 - Second vector numElemsV1 - Number of first vector elements numElemsV2 - Number of second vector elements dest - Result vector y[n] = sum_(k=0:n){x[k]*h[n-k]}, 0 <= n < M y[n] = sum_(k=n-M+1:n){x[k]*h[n-k]}, M <= n < N y[n] = sum_(k=n-M+1:N-1){x[k]*h[n-k]}, N <= n < N+M-1 AccuA used, not restored. CORCON saved, used, restored.
Operation
Note
Vector_Add
Prototype Description sub procedure Vector_Add(dim byref dest, v1, v2 as array[1024] of word, dim numElems as word); Procedure calculates vector addition. v1 - First vector. v2 - Second vector numElemsV1 - Number of vector elements dest - Result vector dstV[n] = srcV1[n] + srcV2[n], with n in {0, 1,... , numElems-1} AccuA used, not restored. CORCON saved, used, restored.
Operation
Note
page
mikroElektronika: Development tools - Books - Compilers
365
making it simple...
Matrix_Transponse
Prototype Description sub procedure Matrix_Transponse(dim byref src, dest as array[1024]of word, dim numRows, numCols as word); Procedure does matrix transposition. src - Original matrix. dest - Result matrix numRows - Number of matrix rows numCols - Number of matrix columns dstM[i][j] = srcM[j][i]
Operation
Matrix_Subtract
Prototype Description sub procedure Matrix_Subtract(dim byref src1, src2, dest as array[1024] of word, dim numRows, numCols as word); Procedure does matrix substraction. src1 - First matrix. src2 - Second matrix dest - Result matrix numRows - Number of matrix rows numCols - Number of matrix columns dstM[i][j] = srcM1[i][j] - srcM2[i][j] AccuA used, not restored. AccuB used, not restored. CORCON saved, used, restored.
Operation Note
page
366
Matrix_Scale
Prototype Description sub procedure Matrix_Scale(dim ScaleValue as word, dim byref src1, dest as array[1024] of word, dim numRows, numCols as word); Procedure does matrix scale. ScaleValue - Scale Value src1 - Original matrix dest - Result matrix numRows - Number of matrix rows numCols - Number of matrix columns dstM[i][j] = srcM[j][i] AccuA used, not restored. CORCON saved, used, restored.
Operation Note
Matrix_Multiply
Prototype Description sub procedure Matrix_Multiply(dim byref src1, src2, dest as array[1024] of word, dim numRows1, numCols2, numCols1Rows2 as word); Procedure does matrix multiply. src1 - First Matrix src2 - Second Matrix dest - Result Matrix numRows1 - Number of first matrix rows numCols2 - Number of second matrix columns numCols1Rows2 - Number of first matrix columns and second matrix rows dstM[i][j] = sum_k(srcM1[i][k]*srcM2[k][j]), with i in {0, 1, ..., numRows1-1} j in {0, 1, ..., numCols2-1} k in {0, 1, ..., numCols1Rows2-1} AccuA used, not restored. CORCON saved, used, restored.
Operation
Note
page
mikroElektronika: Development tools - Books - Compilers
367
making it simple...
Matrix_Add
Prototype Description procedure Matrix_Add(dim byref src1, src2, dest as array[1024] of word, dim numRows, numCols as word); Procedure does matrix addition. src1 - First Matrix src2 - Second Matrix dest - Result Matrix numRows1 - Number of first matrix rows numCols2 - Number of second matrix columns dstM[i][j] = srcM1[i][j] + srcM2[i][j] AccuA used, not restored. CORCON saved, used, restored.
Operation Note
page
368
Library Routines
Basic routines:
Spi_Glcd_Config Spi_Glcd_Set_Side Spi_Glcd_Set_Page Spi_Glcd_Set_X Spi_Glcd_Read_Data Spi_Glcd_Write_Data
Advanced routines:
Spi_Glcd_Fill Spi_Glcd_Dot Spi_Glcd_Line Spi_Glcd_V_Line Spi_Glcd_H_Line Spi_Glcd_Rectangle Spi_Glcd_Box Spi_Glcd_Circle Spi_Glcd_Set_Font Spi_Glcd_Write_Char Spi_Glcd_Write_Text Spi_Glcd_Image
page
mikroElektronika: Development tools - Books - Compilers
369
making it simple...
Spi_Glcd_Config
Prototype
sub procedure Spi_Glcd_Config(dim DeviceAddress as byte, dim byref RstPort as word, dim RstPin as word, dim byref CSPort as word, dim CSPin as word)
Description
Initializes Graphic LCD 128x64 via SPI. RstPort and RstPin - Sets pin connected on reset pin of spi expander. CSPort and CSPin - Sets pin connected on CS pin of spi expander. device address - address of spi expander (hardware setting of A0, A1 and A2 pins (connected on VCC or GND) on spi expander). This procedure needs to be called before using other routines of SPI GLCD library.
Spi_Glcd_Config(0, PORTF, 0, PORTF, 1)
Requires Example
Spi_Glcd_Set_Side
Prototype Description
sub procedure Spi_Glcd_Set_Side(dim x as byte)
Selects side of GLCD, left or right. Parameter x specifies the side: values from 0 to 63 specify the left side, and values higher than 64 specify the right side. Use the functions Spi_Glcd_Set_Side, Spi_Glcd_Set_X, and Spi_Glcd_Set_Page to specify an exact position on GLCD. Then, you can use Spi_Glcd_Write_Data or Spi_Glcd_Read_Data on that location. GLCD needs to be initialized. See Spi_Glcd_Init.
Spi_Glcd_Select_Side(0) Spi_Glcd_Select_Side(10)
Requires Example
page
370
Spi_Glcd_Set_Page
Prototype Description Requires Example
sub procedure Spi_Glcd_Set_Page(dim page as byte)
Selects page of GLCD, technically a line on display; parameter page can be 0..7. GLCD needs to be initialized. See Spi_Glcd_Init.
Spi_Glcd_Set_Page(5)
Spi_Glcd_Set_X
Prototype Description Requires Example
sub procedure Spi_Glcd_Set_X(dim x as byte)
Positions to x dots from the left border of GLCD within the given page. GLCD needs to be initialized. See Spi_Glcd_Init.
Spi_Glcd_Set_X(25)
Spi_Glcd_Read_Data
Prototype Returns Description
sub function Spi_Glcd_Read_Data as byte
One word from the GLCD memory. Reads data from from the current location of GLCD memory. Use the functions Spi_Glcd_Set_Side, Spi_Glcd_Set_X, and Spi_Glcd_Set_Page to specify an exact position on GLCD. Then, you can use Spi_Glcd_Write_Data or Spi_Glcd_Read_Data on that location. Reads data from from the current location of GLCD memory.
tmp = Spi_Glcd_Read_Data
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
371
making it simple...
Spi_Glcd_Write_Data
Prototype Description Requires Example
sub procedure Spi_Glcd_Write_Data(dim data as byte)
Writes data to the current location in GLCD memory and moves to the next location. GLCD needs to be initialized. See Spi_Glcd_Init.
Spi_Glcd_Write_Data(data)
Spi_Glcd_Fill
Prototype Description
sub procedure Spi_Glcd_Fill(dim pattern as byte)
Fills the GLCD memory with byte pattern. To clear the GLCD screen, use Spi_Glcd_Fill(0); to fill the screen completely, use Spi_Glcd_Fill($FF). GLCD needs to be initialized. See Spi_Glcd_Init.
Spi_Glcd_Fill(0) ' Clear screen
Requires Example
Spi_Glcd_Dot
Prototype Description
sub procedure Spi_Glcd_Dot(dim x, y, color as byte)
Draws a dot on the GLCD at coordinates (x, y). Parameter color determines the dot state: 0 clears dot, 1 puts a dot, and 2 inverts dot state. GLCD needs to be initialized. See Spi_Glcd_Init.
Spi_Glcd_Dot(0, 0, 2)
Requires Example
page
372
Spi_Glcd_Line
Prototype Description
sub procedure Spi_Glcd_Line(dim x1, y1, x2, y2, color as byte)
Draws a line on the GLCD from (x1, y1) to (x2, y2). Parameter color determines the dot state: 0 draws an empty line (clear dots), 1 draws a full line (put dots), and 2 draws a smart line (invert each dot). GLCD needs to be initialized. See Spi_Glcd_Init.
Spi_Glcd_Line(0, 63, 50, 0, 2)
Requires Example
Spi_Glcd_V_Line
Prototype Description
sub procedure Spi_Glcd_V_Line(dim y1, y2, x, color as byte)
Similar to GLcd_Line, draws a vertical line on the GLCD from (x, y1) to (x, y2). GLCD needs to be initialized. See Spi_Glcd_Init.
Spi_Glcd_V_Line(0, 63, 0, 1)
Requires Example
Spi_Glcd_H_Line
Prototype Description
sub procedure Spi_Glcd_H_Line(dim x1, x2, y, color as byte)
Similar to GLcd_Line, draws a horizontal line on the GLCD from (x1, y) to (x2, y). GLCD needs to be initialized. See Spi_Glcd_Init.
Spi_Glcd_H_Line(0, 127, 0, 1)
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
373
making it simple...
Spi_Glcd_Rectangle
Prototype Description
sub procedure Spi_Glcd_Rectangle(dim x1, y1, x2, y2, color as byte)
Draws a rectangle on the GLCD. Parameters (x1, y1) set the upper left corner, (x2, y2) set the bottom right corner. Parameter color defines the border: 0 draws an empty border (clear dots), 1 draws a solid border (put dots), and 2 draws a smart border (invert each dot). GLCD needs to be initialized. See Spi_Glcd_Init.
Spi_Glcd_Rectangle(10, 0, 30, 35, 1)
Requires Example
Spi_Glcd_Box
Prototype Description
sub procedure Spi_Glcd_Box(dim x1, y1, x2, y2, color as byte)
Draws a box on the GLCD. Parameters (x1, y1) set the upper left corner, (x2, y2) set the bottom right corner. Parameter color defines the fill: 0 draws a white box (clear dots), 1 draws a full box (put dots), and 2 draws an inverted box (invert each dot). GLCD needs to be initialized. See Spi_Glcd_Init.
Spi_Glcd_Box(10, 0, 30, 35, 1)
Requires Example
Spi_Glcd_Circle
Prototype Description
sub procedure Spi_Glcd_Circle(dim x, y, radius, color as integer)
Draws a circle on the GLCD, centered at (x, y) with radius. Parameter color defines the circle line: 0 draws an empty line (clear dots), 1 draws a solid line (put dots), and 2 draws a smart line (invert each dot). GLCD needs to be initialized. See Spi_Glcd_Init.
Spi_Glcd_Circle(63, 31, 25, 1)
Requires Example
page
374
Spi_Glcd_Set_Font
Prototype Description
sub procedure Spi_Glcd_Set_Font(dim font_address as longint, dim font_width, font_height as byte, dim offset as word)
Sets the font for text display routines, Spi_Glcd_Write_Char and Spi_Glcd_Write_Text. Font needs to be formatted as an array of byte. Parameter font_address specifies the address of the font; you can pass a font name with the @ operator. Parameters font_width and font_height specify the width and height of characters in dots. Font width should not exceed 128 dots, and font height should not exceed 8 dots. Parameter font_offset determines the ASCII character from which the supplied font starts. Demo fonts supplied with the library have an offset of 32, which means that they start with space. If no font is specified, Spi_Glcd_Write_Char and Spi_Glcd_Write_Text will use the default 5x8 font supplied with the library. You can create your own fonts by following the guidelines given in the file GLCD_Fonts.dpas. This file contains the default fonts for GLCD, and is located in your installation folder, Extra Examples > GLCD.
Requires Example
Spi_Glcd_Write_Char
Prototype Description
sub procedure Spi_Glcd_Write_Char(dim character, x, page, color as byte)
Prints character at page (one of 8 GLCD lines, 0..7), x dots away from the left border of display. Parameter color defines the fill: 0 writes a white letter (clear dots), 1 writes a solid letter (put dots), and 2 writes a smart letter (invert each dot). Use routine Spi_Glcd_Set_Font to specify font, or the default 5x7 font (included with the library) will be used.
Requires
GLCD needs to be initialized, see Spi_Glcd_Init. Use the Spi_Glcd_Set_Font to specify the font for display; if no font is specified, the default 5x8 font supplied with the library will be used.
Spi_Glcd_Write_Char('C', 0, 0, 1)
Example
page
mikroElektronika: Development tools - Books - Compilers
375
making it simple...
Spi_Glcd_Write_Text
Prototype Description
sub procedure Spi_Glcd_Write_Text(dim text as string[20], dim x, page, color as byte)
Prints text at page (one of 8 GLCD lines, 0..7), x dots away from the left border of display. Parameter color defines the fill: 0 prints a white letters (clear dots), 1 prints solid letters (put dots), and 2 prints smart letters (invert each dot). Use routine Spi_Glcd_Set_Font to specify font, or the default 5x7 font (included with the library) will be used.
Requires
GLCD needs to be initialized, see Spi_Glcd_Init. Use the Spi_Glcd_Set_Font to specify the font for display; if no font is specified, the default 5x8 font supplied with the library will be used.
Spi_Glcd_Write_Text('Hello world!', 0, 0, 1)
Example
Spi_Glcd_Image
Prototype Description
sub procedure Spi_Glcd_Image(dim image as byte[1024])
Displays bitmap image on the GLCD. Parameter image should be formatted as an array of 1024 bytes. Use the mikroBasics integrated Bitmap-to-LCD editor (menu option Tools > Graphic LCD Editor) to convert image to a constant array suitable for display on GLCD. GLCD needs to be initialized. See Spi_Glcd_Init.
Spi_Glcd_Image(my_image)
Requires Example
page
376
Library Example
The example demonstrates how to communicate to KS0108 GLCD via SPI module, using serial to parallel convertor MCP23S17.
program SerialGLCD include __Lib_images dim ii as byte jj as word someText as string[20] sub procedure delay2S delay_ms(2000) end sub main: ADPCFG = 0xFFFF SpiX_Init(1) Spi_Glcd_Init() Spi_Glcd_Fill(0xAA) delay2S while TRUE Spi_Glcd_Fill(0x00) Spi_Glcd_Image( truck_bmp ) delay2S for jj = 1 to 40 Spi_Glcd_Dot(jj,jj,1) next jj delay2S Spi_Glcd_Fill(0x00) Spi_Glcd_Line(120, 1, 5,60, 1) delay2S Spi_Glcd_Line(12, 42, 5,60, 1) delay2S Spi_Glcd_Rectangle(12, 20, 93,57, 1) delay2S
' continues...
page
mikroElektronika: Development tools - Books - Compilers
377
making it simple...
' continues... Spi_Glcd_Line(120, 12, 12,60, 1) delay2S Spi_Glcd_H_Line(5, 15, 6, 1) Spi_Glcd_Line(0, 12, 120, 60, 1) Spi_Glcd_V_Line(7, 63, 127, 1) delay2S for ii = 1 to 10 Spi_Glcd_Circle(63, 32, 3*ii, 1) next ii delay2S Spi_Glcd_Box(12, 20, 70, 57, 2) delay2S Spi_Glcd_Fill(0x00) Spi_Glcd_Set_Font(@System3x6, 3, 6, 32) someText = "SMALL FONT: 3X6" Spi_Glcd_Write_Text(someText, 20, 5, 1) Spi_Glcd_Set_Font(@FontSystem5x8, 5, 8, 32) someText = "Large Font 5x8" Spi_Glcd_Write_Text(someText, 3, 4, 1) delay2S wend end.
page
378
Hardware Connection
MCP23S17
D0 D1 D2 D3 D4 D5 D6 D7 1 2 3 4 5 6 7 8 9 10 RF1 11 RF6 12 RF3 13 RF2 14 GPB4 GPB5 GPB6 GPB7 VDD VSS CS SCK SI SO GPB0 GPB1 GPB2 GPB3 GPA7 GPA6 GPA5 GPA4 GPA3 GPA2 GPA1 GPA0 INTA 19 INTB RESET A2 A1 15 A0 18 17 16
10 MhZ
dsPIC4013
VCC
11 12 13 14 VCC GND OSC1 OSC2
VCC
RF0 RF1
30 29
RF0
26 25 24
Vee
VCC
Contrast Adjustment
Vo
VCC
P1 5K
mikroElektronika EasydsPIC2
Development system
20
page
mikroElektronika: Development tools - Books - Compilers
379
making it simple...
Sound Library
mikroBasic for dsPIC30/33 and PIC24 provides a Sound Library which allows you to use sound signalization in your applications. You need a simple piezo speaker (or other hardware) on designated port.
Library Routines
Sound_Init Sound_Play
Sound_Init
Prototype Description
sub procedure Sound_Init(dim byref port as word, dim pin as byte)
Prepares hardware for output at specified port and pin. Parameter pin needs to be within range 07.
Sound_Init(PORTB, 2) ' Initialize sound on RB2
Example
Sound_Play
Prototype Description
sub procedure Sound_Play(dim freq_in_hz, duration_ms as word)
Plays the sound at the specified port and pin (see Sound_Init). Parameter 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). To hear the sound, you need a piezo speaker (or other hardware) on designated port. Also, you must call Sound_Init to prepare hardware for output before using this function. To play sound of 1KHz: T = 1/f = 1ms = 1000 cycles @ 4MHz. This gives us our first parameter: 1000/10 = 100. Play 150 periods like this:
Sound_Play(100, 150)
Requires
Example
page
380
Library Example
The example 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. Sound frequencies in this example are generated by reading the buttons on PORTB.
program sound main: ' initialize sound lib Sound_Init(PORTB, 3); ' three beeps Sound_Play(1000, delay_ms(50) Sound_Play(1000, delay_ms(50) Sound_Play(1000, delay_ms(50) Sound_Play(1200, end.
500) 500) 500) 500) ' frequency is 1200 Hz and duration is 900ms
Hardware Connection
300
RB0
PIEZO SPEAKER
RB4
RB1 RB2
7 8
dsPIC4013
RD0
34
RB5
8 9
RB6
VCC
11 12 13
RB7
VCC
14
10 Mhz
page
mikroElektronika: Development tools - Books - Compilers
381
making it simple...
Library Routines
Expander_Init PortExpanderSelect PortExpanderUnSelect Expander_Read_Byte Expander_Write_Byte Expander_Set_Mode Expander_Read_Array Expander_Write_Array Expander_Read_PortA Expander_Read_PortB Expander_Read_ArrayPortA Expander_Read_ArrayPortB Expander_Write_PortA Expander_Write_PortB Expander_Set_DirectionPortA Expander_Set_DirectionPortB Expander_Set_PullUpsPortA Expander_Set_PullUpsPortB
Expander_Init
Prototype
sub procedure Expander_Init( dim ModuleAddress as byte, dim byref RstPort as word, dim RstPin as word, dim byref CSPort as word, dim CSPin as word)
Description
Establishes communication with the expander and initializes the expander. RstPort and RstPin - Sets pin connected on reset pin of spi expander. CSPort and CSPin - Sets pin connected on CS pin of spi expander. moduleaddress - address of spi expander (hardware setting of A0, A1 and A2 pins (connected on VCC or GND) on spi expander). SpiX_Init; must be called before initializing Port Expander. This procedure needs to be called before using other routines of PORT Expander library.
Expander_Init(0, PORTB, 0, PORTB, 1)
Requires
Example
page
382
PortExpanderSelect
Prototype Description Requires Example
sub procedure PortExpanderSelect
Selects current port expander. PORT Expander must be initialized. See Expander_Init.
PortExpanderSelect
PortExpanderUnSelect
Prototype Description Requires Example
sub procedure PortExpanderUnSelect
Un-Selects current port expader. PORT Expander must be initialized. See Expander_Init.
PortExpanderUnSelect
Expander_Read_Byte
Prototype Returns Description Requires Example
sub function Expander_Read_Byte(dim ModuleAddress, RegAddress as byte) as byte
Byte read from port expander. Function reads byte from port expander on ModuleAddress and port on RegAddress. PORT Expander must be initialized. See Expander_Init.
Expander_Read_Byte(0,1)
Expander_Write_Byte
Prototype Returns Description Requires Example
sub procedure Expander_Write_Byte(dim ModuleAddress, RegAddress, Data as byte)
Nothing. This routine writes data to port expander on ModuleAddress and port on RegAddress. PORT Expander must be initialized. See Expander_Init.
Expander_Write_Byte(0,1,$FF)
page
mikroElektronika: Development tools - Books - Compilers
383
making it simple...
Expander_Set_Mode
Prototype Returns Description Requires Example
sub procedure Expander_Set_Mode(dim ModuleAddress, Mode as byte)
Nothing. Sets port expander mode on ModuleAddress. PORT Expander must be initialized. See Expander_Init.
Expander_Set_Mode(1,0)
Expander_Read_ArrayPortA
Prototype Returns Description
sub procedure Expander_Read_ArrayPortA(dim ModuleAddress, NoBytes as byte, dim byref DestArray as byte[100])
Nothing. This routine reads array of bytes (DestArray) from port expander on ModuleAddress and portA. NoBytes represents number of read bytes. PORT Expander must be initialized. See Expander_Init.
Expander_Read_PortA(0,1,data)
Requires Example
Expander_Read_Array
Prototype Returns Description
sub procedure Expander_Read_Array(dim ModuleAddress, StartAddress, NoBytes as byte, dim byref DestArray as byte[100])
Nothing. This routine reads array of bytes (DestArray) from port expander on ModuleAddress and StartAddress. NoBytes represents number of read bytes. PORT Expander must be initialized. See Expander_Init.
Expander_Read_Array(1,1,5,data)
Requires Example
page
384
Expander_Write_Array
Prototype
sub procedure Expander_Write_Array(dim ModuleAddress, StartAddress, NoBytes as byte, dim byref SourceArray as byte[100])
Nothing. This routine writes array of bytes (DestArray) to port expander on ModuleAddress and StartAddress. NoBytes represents number of read bytes. PORT Expander must be initialized. See Expander_Init.
Expander_Write_Array(1,1,5,data)
Expander_Read_PortA
Prototype Returns Description Requires Example
sub function Expander_Read_PortA(dim Address as byte) as byte
Read byte. This routine reads byte from port expander on Address and PortA. PORT Expander must be initialized. See Expander_Init.
Expander_Read_PortA(1)
Expander_Read_Array
Prototype Returns Description Requires Example
sub procedure Expander_Read_Array(dim ModuleAddress, StartAddress, NoBytes as byte, dim byref DestArray as byte[100])
Read byte. This routine reads byte from port expander on Address and PortB. PORT Expander must be initialized. See Expander_Init.
Expander_Read_Array(1,1,5,data)
page
mikroElektronika: Development tools - Books - Compilers
385
making it simple...
Expander_Read_ArrayPortB
Prototype Returns Description
sub procedure Expander_Read_ArrayPortB(dim ModuleAddress, NoBytes as byte, dim byref DestArray as byte[100])
Nothing. This routine reads array of bytes (DestArray) from port expander on ModuleAddress and portB. NoBytes represents number of read bytes. PORT Expander must be initialized. See Expander_Init.
Expander_Read_PortB(0,8,data)
Requires Example
Expander_Write_PortA
Prototype Returns Description Requires Example
sub procedure Expander_Write_PortA(dim ModuleAddress, Data as byte)
Nothing. This routine writes byte to port expander on ModuleAddress and portA. PORT Expander must be initialized. See Expander_Init.
Expander_write_PortA(3,$FF)
Expander_Write_PortB
Prototype Returns Description Requires Example
sub procedure Expander_Write_PortB(dim ModuleAddress, Data as byte)
Nothing. This routine writes byte to port expander on ModuleAddress and portB. PORT Expander must be initialized. See Expander_Init.
Expander_write_PortB(2,$FF)
page
386
Expander_Set_DirectionPortA
Prototype Description Requires Example
sub procedure Expander_Set_DirectionPortA(dim ModuleAddress, Data as byte)
Set port expander PortA pin as input or output. PORT Expander must be initialized. See Expander_Init.
Expander_Set_DirectionPortA(0,$FF)
Expander_Set_DirectionPortB
Prototype Description Requires Example
sub procedure Expander_Set_DirectionPortB(dim ModuleAddress, Data as byte)
Set port expander PortB pin as input or output. PORT Expander must be initialized. See Expander_Init.
Expander_Set_DirectionPortB(0,$FF)
Expander_Set_PullUpsPortA
Prototype Description Requires Example
sub procedure Expander_Set_PullUpsPortA(dim ModuleAddress, Data as byte)
This routine sets port expander PortA pin as pullup or pulldown. PORT Expander must be initialized. See Expander_Init.
Expander_Set_PullUpsPortA(0,$FF)
Expander_Set_PullUpsPortB
Prototype Description Requires Example
sub procedure Expander_Set_PullUpsPortB(dim ModuleAddress, Data as byte)
This routine sets port expander PortB pin as pullup or pulldown. PORT Expander must be initialized. See Expander_Init.
Expander_Set_PullUpsPortB(0,$FF)
page
mikroElektronika: Development tools - Books - Compilers
387
making it simple...
Library Example
The example demonstrates how to communicate to port expander MCP23S17.
program PortExpander dim i as byte main: ADPCFG = 0xFFFF TRISB = 0x00 PORTB = 0xFF SpiX_Init(1) Delay_ms(200) Expander_Init(0, PORTF, 0, PORTF, 1) Expander_Set_DirectionPortA(0, 0) ' set expander's porta to be output Expander_Set_DirectionPortB(0, 0xFF) ' set expander's porta to be input Expander_Set_PullUpsPortB(0, 0xFF) ' set pull ups to all of the expander's portb pins i = 0 while true Expander_Write_PortA(0, i) ' write i to expander's porta i = i + 1 PORTB = Expander_Read_PortB(0) ' read expander's portb and write it to dsPICs LATB Delay_ms(20) wend end.
' all pins digital ' PORTB input ' initialize SPI ' initialize port expander
page
388
Hardware Connection
MCP23S17
1 2 3 4 5 6 7 8 GPB4 GPB5 GPB6 GPB7 VDD VSS CS SCK SI RF2 14 SO GPB0 GPB1 GPB2 GPB3 GPA7 GPA6 GPA5 GPA4 GPA3 GPA2 GPA1 GPA0 INTA 19 INTB RESET A2 A1 15 A0 18 RF0 17 16
10 MhZ
28 27 26 25 24 23 22 21 20
dsPIC4013
VCC
11 12 13 14 VCC GND OSC1 OSC2
VCC
RF0 RF1
30 29
26 25 24
1 3 5 7 9 VCC
2 4 6 8 10
1 3 5 7 9 VCC
2 4 6 8 10
PORTB
PORTA
page
mikroElektronika: Development tools - Books - Compilers
389
making it simple...
Library Routines
Spi_Lcd_Config Spi_Lcd_Init Spi_Lcd_Out Spi_Lcd_Out_Cp Spi_Lcd_Chr Spi_Lcd_Chr_Cp Spi_Lcd_Cmd
Spi_Lcd_Config
Prototype
sub procedure Spi_Lcd_Config(dim DeviceAddress as byte, dim byref rstport as word, dim rstpin as word, dim byref csport as word, dim cspin as word)
Description
Initializes LCD via SPI interface with pin settings (Reset pin and Chip Select pin) you specify.
Spi_Init must be called before initializing SPI LCD.
Requires
Example
page
390
Spi_Lcd_Init
Prototype Description
sub procedure Spi_Lcd_Init
Initializes LCD at port with default pin settings (see the connection scheme at the end of the chapter).
Spi_Init must be called before initializing SPI LCD. Spi_Lcd_Init
Requires Example
Spi_Lcd_Out
Prototype Description Requires Example
sub procedure Spi_Lcd_Out(dim row, column as byte, dim byref text as string[20])
Prints text on LCD at specified row and column (parameters row and col). Both string variables and literals can be passed as text. Port with LCD must be initialized. See Spi_Lcd_Config or Spi_Lcd_Init.
Spi_Lcd_Out(1, 3, "Hello!")
Spi_Lcd_Out_Cp
Prototype Description
sub procedure Spi_Lcd_Out_CP(dim byref text as string[40])
Prints text on LCD at current cursor position. Both string variables and literals can be passed as text. Port with LCD must be initialized. See Spi_Lcd_Config or Spi_Lcd_Init.
Spi_Lcd_Out_Cp("Here!") Print "Here!" at current cursor position
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
391
making it simple...
Spi_Lcd_Chr
Prototype Description
sub procedure Spi_Lcd_Chr(dim Row, Column, Out_Char as byte)
Prints character on LCD at specified row and column (parameters row and col). Both variables and literals can be passed as character. Port with LCD must be initialized. See Spi_Lcd_Config or Spi_Lcd_Init.
Spi_Lcd_Chr(2, 3, "i")
Requires Example
Spi_Lcd_Chr_Cp
Prototype Description
sub procedure Spi_Lcd_Chr_CP(dim Out_Char as byte)
Prints character on LCD at current cursor position. Both variables and literals can be passed as character. Port with LCD must be initialized. See Spi_Lcd_Config or Spi_Lcd_Init.
Spi_Lcd_Chr_Cp("e") Print "e" at current cursor position
Requires Example
Spi_Lcd_Cmd
Prototype Description
sub procedure Spi_Lcd_Cmd(dim out_char as byte)
Sends command to LCD. You can pass one of the predefined constants to the function. The complete list of available commands is shown below. Port with LCD must be initialized. See Spi_Lcd_Config or Spi_Lcd_Init.
Spi_Lcd_Cmd(Spi_Lcd_Clear) Clear LCD display
Requires Example
page
392
LCD Commands
LCD 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 Lcd_Move_Cursor_Right LCD_TURN_ON LCD_TURN_OFF LCD_SHIFT_LEFT LCD_SHIFT_RIGHT
Purpose Move cursor to 1st row Move cursor to 2nd row Move cursor to 3rd row Move cursor to 4th row Clear display Return cursor to home position, returns a shifted display to original position. Display data RAM is unaffected. Turn off cursor Underline cursor on Blink cursor on Move cursor left without changing display data RAM Move cursor right without changing display data RAM Turn LCD display on Turn LCD display off Shift display left without changing display data RAM Shift display right without changing display data RAM
page
mikroElektronika: Development tools - Books - Compilers
393
making it simple...
Hardware Connection
MCP23S17
1 2 RS E D4 D5 D6 D7 3 4 5 6 7 8 9 10 RF1 11 RF6 12 RF3 13 RF2 14 GPB4 GPB5 GPB6 GPB7 VDD VSS CS SCK SI SO GPB0 GPB1 GPB2 GPB3 GPA7 GPA6 GPA5 GPA4 GPA3 GPA2 GPA1 GPA0 INTA 19 INTB RESET A2 A1 15 A0
10 MhZ
28 27 26 25 24 23 22 21 20
dsPIC4013
VCC
VCC
RF0
13 14 VCC GND OSC1 OSC2
18 17 16
RF0 RF1
30 29
26 25 24
VCC
P4 5K
Contrast Adjustment
1
GND VCC VEE RS R/W E D0 D1 D2 D3 D4 D5 D6 D7
14
page
394
Library Routines
Spi_Lcd8_Config Spi_Lcd8_Init Spi_Lcd8_Out Spi_Lcd8_Out_Cp Spi_Lcd8_Chr Spi_Lcd8_Chr_Cp Spi_Lcd8_Cmd
Spi_Lcd8_Config
Prototype
sub procedure Spi_Lcd8_Config(dim DeviceAddress as byte, dim byref rstport as word, dim rstpin as word, dim byref csport as word, dim cspin as word)
Description
Initializes LCD via SPI interface with pin settings (Reset pin and Chip Select pin) you specify.
Spi_Init must be called before initializing SPI LCD8. Spi_Lcd8_Config(0, PORTB, 1, PORTB, 0)
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
395
making it simple...
Spi_Lcd8_Init
Prototype Description
sub procedure Spi_Lcd8_Init
Initializes LCD at Control port (ctrlport) and Data port (dataport) with default pin settings (see the connection scheme at the end of the chapter).
Spi_Init must be called before initializing SPI LCD8. Spi_Lcd8_Init
Requires Example
Spi_Lcd8_Out
Prototype Description
sub procedure Spi_LCD8_Out(dim row, column as byte, dim byref Text as string[20])
Prints text on LCD at specified row and column (parameters row and col). Both string variables and literals can be passed as text. Ports with LCD must be initialized. See Spi_Lcd8_Config or Spi_Lcd8_Init.
Spi_Lcd8_Out(1, 3, "Hello!") Print "Hello!" at line 1, char 3
Requires Example
Spi_Lcd8_Out_Cp
Prototype Description
sub procedure Spi_LCD8_Out_CP(dim byref text as string[20])
Prints text on LCD at current cursor position. Both string variables and literals can be passed as text. Ports with LCD must be initialized. See Spi_Lcd8_Config or Spi_Lcd8_Init.
Spi_Lcd8_Out_Cp("Here!") Print "Here!" at current cursor position
Requires Example
page
396
Spi_Lcd8_Chr
Prototype Description
sub procedure Spi_LCD8_Chr(dim row, column, out_char as byte)
Prints character on LCD at specified row and column (parameters row and col). Both variables and literals can be passed as character. Ports with LCD must be initialized. See Spi_Lcd8_Config or Spi_Lcd8_Init.
Spi_LCD8_Chr(1,1,"e") Print "e" at line 1, char 1
Requires Example
Spi_Lcd8_Chr_Cp
Prototype Description
sub procedure Spi_LCD8_Chr_CP(dim out_char as byte)
Prints character on LCD at current cursor position. Both variables and literals can be passed as character. Ports with LCD must be initialized. See Spi_Lcd8_Config or Spi_Lcd8_Init.
Spi_Lcd8_Chr_Cp("e"); Print "e" at current cursor position
Requires Example
Spi_Lcd8_Cmd
Prototype Description
sub procedure Spi_LCD8_Cmd(dim out_char as byte)
Sends command to LCD. You can pass one of the predefined constants to the function. The complete list of available commands is shown below. Ports with LCD must be initialized. See Spi_Lcd8_Config or Spi_Lcd8_Init.
Spi_Lcd8_Cmd(LCD_Clear) Clear LCD display
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
397
making it simple...
LCD Commands
LCD 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 Lcd_Move_Cursor_Right LCD_TURN_ON LCD_TURN_OFF LCD_SHIFT_LEFT LCD_SHIFT_RIGHT
Purpose Move cursor to 1st row Move cursor to 2nd row Move cursor to 3rd row Move cursor to 4th row Clear display Return cursor to home position, returns a shifted display to original position. Display data RAM is unaffected. Turn off cursor Underline cursor on Blink cursor on Move cursor left without changing display data RAM Move cursor right without changing display data RAM Turn LCD display on Turn LCD display off Shift display left without changing display data RAM Shift display right without changing display data RAM
page
398
Hardware Connection
MCP23S17
D0 D1 D2 D3 D4 D5 D6 D7 1 2 3 4 5 6 7 8 9 10 RF1 11 RF6 12 RF3 13 RF2 14 GPB4 GPB5 GPB6 GPB7 VDD VSS CS SCK SI SO GPB0 GPB1 GPB2 GPB3 GPA7 GPA6 GPA5 GPA4 GPA3 GPA2 GPA1 GPA0 INTA 19 INTB RESET A2 A1 15 A0
10 MhZ
28 27 26 25 24 23 22 21 20 E RS
dsPIC4013
VCC
VCC
RF0
13 14 VCC GND OSC1 OSC2
18 17 16
RF0 RF1
30 29
26 25 24
VCC
P4 5K
Contrast Adjustment
1
GND VCC VEE RS R/W E D0 D1 D2 D3 D4 D5 D6 D7
14
page
mikroElektronika: Development tools - Books - Compilers
399
making it simple...
Library Routines
Spi_T6963C_Init Spi_T6963C_writeData Spi_T6963C_writeCommand Spi_T6963C_setPtr Spi_T6963C_waitReady Spi_T6963C_fill Spi_T6963C_dot Spi_T6963C_write_char Spi_T6963C_write_text Spi_T6963C_line Spi_T6963C_rectangle Spi_T6963C_box Spi_T6963C_circle Spi_T6963C_image Spi_T6963C_sprite Spi_T6963C_set_cursor Spi_T6963C_clearBit Spi_T6963C_setBit Spi_T6963C_negBit Spi_T6963C_displayGrPanel Spi_T6963C_displayTxtPanel
Spi_T6963C_setGrPanel Spi_T6963C_setTxtPanel Spi_T6963C_panelFill Spi_T6963C_grFill Spi_T6963C_txtFill Spi_T6963C_cursor_height Spi_T6963C_graphics Spi_T6963C_text Spi_T6963C_cursor Spi_T6963C_cursor_blink Spi_T6963C_Init_240x128 Spi_T6963C_Init_240x64
page
400
Spi_T6963C_Init
Prototype
sub procedure Spi_T6963C_Init(dim width, height, fntW as word, dim DeviceAddress as byte, dim byref rstport as word, dim rstpin as word, dim byref csport as word, dim cspin as word, dim wr, rd, cd, rst as byte)
Description
Initalizes the Graphic Lcd controller. This function must be called before all Spi T6963C Library Routines. width - Number of horizontal (x) pixels in the display. height - Number of vertical (y) pixels in the display. fntW - Font width, number of pixels in a text character, must be set accordingly to the hardware. data - Address of the port on which the Data Bus is connected. cntrl - Address of the port on which the Control Bus is connected. wr - !WR line bit number in the *cntrl port. rd - !RD line bit number in the *cntrl port. cd - !CD line bit number in the *cntrl port. rst - !RST line bit number in the *cntrl port. DeviceAddress - Device Address. Display RAM : The library doesn't know the amount of available RAM. The library cuts the RAM into panels : a complete panel is one graphics panel followed by a text panel, The programer has to know his hardware to know how much panel he has.
Requires Example
Spi_Init must be called before initializing SPI Toshiba T6963C Graphic LCD. SpiX_Init(1) Spi_T6963C_Init(240, 64, 8, PORTF, 0, PORTF, 1, 0, 1, 3, 4, 0) ' ' ' ' ' ' ' ' ' ' init display for 240 pixel width and 64 pixel height 8 bits character width reset pin on PORTB.1 chip select pin on PORTB.0 bit 0 is !WR bit 1 is !RD bit 3 is !CD bit 4 is RST chip enable, reverse on, 8x8 font internaly set in library device address is 0
page
mikroElektronika: Development tools - Books - Compilers
401
making it simple...
Spi_T6963C_writeData
Prototype Description Requires Example
sub procedure Spi_T6963C_writeData(dim data as byte)
Routine that writes data to Spi T6963C controller. GLCD needs to be initialized, see Spi_T6963C_Config.
Spi_T6963C_writeData(AddrL)
Spi_T6963C_writeCommand
Prototype Description Requires Example
sub procedure Spi_T6963C_writeCommand(dim data as byte)
Routine that writes command to Spi T6963C controller GLCD needs to be initialized, see Spi_T6963C_Config.
Spi_T6963C_writeCommand(T6963C_CURSOR_POINTER_SET)
Spi_T6963C_setPtr
Prototype Description Requires Example
sub procedure Spi_T6963C_setPtr(dim p as word, dim c as byte)
This routine sets the memory pointer p for command c. GLCD needs to be initialized, see Spi_T6963C_Config.
Spi_T6963C_setPtr(T6963C_grHomeAddr + start, T6963C_ADDRESS_POINTER_SET)
Spi_T6963C_waitReady
Prototype Description Requires Example
sub procedure Spi_T6963C_waitReady
This routine pools the status byte, and loops until ready. GLCD needs to be initialized, see Spi_T6963C_Config.
Spi_T6963C_waitReady
page
402
Spi_T6963C_fill
Prototype Description Requires Example
sub procedure Spi_T6963C_fill(dim v as byte, dim start, len as word)
This routine fills length with bytes to controller memory from start address. GLCD needs to be initialized, see Spi_T6963C_Config.
Spi_T6963C_fill(0x33,0x00FF,0x000F)
Spi_T6963C_dot
Prototype Description Requires Example
sub procedure Spi_T6963C_dot(dim x, y as integer, dim color as byte)
This routine sets current graphic work panel. It sets the pixel dot (x0, y0). pcolor = T6963C_[WHITE[BLACK]. GLCD needs to be initialized, see Spi_T6963C_Config.
Spi_T6963C_dot(x0, y0, pcolor)
Spi_T6963C_write_char
Prototype Description
sub procedure Spi_T6963C_write_char(dim c, x, y, mode as byte)
This routine sets current text work panel. It writes char c row x line y. mode = T6963C_ROM_MODE_[OR|EXOR|AND] GLCD needs to be initialized, see Spi_T6963C_Config.
Spi_T6963C_write_char('A',22,23,AND)
Requires Example
Spi_T6963C_write_text
Prototype Description
sub procedure Spi_T6963C_write_text(dim byref str as byte[10], dim x, y, mode as byte)
This sets current text work panel. It writes string str row x line y. mode = T6963C_ROM_MODE_[OR|EXOR|AND] GLCD needs to be initialized, see Spi_T6963C_Config.
Spi_T6963C_write_text("GLCD LIBRARY DEMO, WELCOME !", 0, 0, T6963C_ROM_MODE_XOR)
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
403
making it simple...
Spi_T6963C_line
Prototype Description
sub procedure Spi_T6963C_line(dim x0, y0, x1, y1 as integer, dim pcolor as byte)
This routine current graphic work panel. It's draw a line from (x0, y0) to (x1, y1). pcolor = T6963C_[WHITE[BLACK] GLCD needs to be initialized, see Spi_T6963C_Config.
Spi_T6963C_line(0, 0, 239, 127, T6963C_WHITE)
Requires Example
Spi_T6963C_rectangle
Prototype Description
sub procedure Spi_T6963C_rectangle(dim x0, y0, x1, y1 as integer, dim pcolor as byte)
It sets current graphic work panel. It draws the border of the rectangle (x0, y0)-(x1, y1). pcolor = T6963C_[WHITE[BLACK]. GLCD needs to be initialized, see Spi_T6963C_Config.
Spi_T6963C_rectangle(20, 20, 219, 107, T6963C_WHITE)
Requires Example
Spi_T6963C_box
Prototype Description
sub procedure Spi_T6963C_box(dim x0, y0, x1, y1 as integer, dim pcolor as byte)
This routine sets current graphic work panel. It draws a solid box in the rectangle (x0, y0)-(x1, y1). pcolor = T6963C_[WHITE[BLACK]. GLCD needs to be initialized, see Spi_T6963C_Config.
Spi_T6963C_box(0, 119, 239, 127, T6963C_WHITE)
Requires Example
page
404
Spi_T6963C_circle
Prototype Description
sub procedure Spi_T6963C_circle(dim x, y as integer, dim r as longint, dim pcolor as word)
This routine sets current graphic work panel. It draws a circle, center is (x, y), diameter is r. pcolor = T6963C_[WHITE[BLACK] GLCD needs to be initialized, see Spi_T6963C_Config.
Spi_T6963C_circle(120, 64, 110, T6963C_WHITE)
Requires Example
Spi_T6963C_image
Prototype Description
sub procedure Spi_T6963C_image(const pic as ^byte)
This routine sets current graphic work panel : It fills graphic area with picture pointer by MCU. MCU must fit the display geometry. For example : for a 240x128 display, MCU must be an array of (240/8)*128 = 3840 bytes . GLCD needs to be initialized, see Spi_T6963C_Config.
Spi_T6963C_image(my_image)
Requires Example
Spi_T6963C_sprite
Prototype Description
sub procedure Spi_T6963C_sprite(dim px, py as byte, const pic as ^byte, dim sx, sy as byte)
This routine sets current graphic work panel. It fills graphic rectangle area (px, py)-(px + sx, py + sy) witch picture pointed by MCU. Sx and sy must be the size of the picture. MCU must be an array of sx*sy bytes. GLCD needs to be initialized, see Spi_T6963C_Config.
Spi_T6963C_sprite(76, 4, einstein, 88, 119) draw a sprite
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
405
making it simple...
Spi_T6963C_set_cursor
Prototype Description Requires Example
sub procedure Spi_T6963C_set_cursor(dim x, y as byte)
This routine sets cursor row x line y. Ports must be initialized. See Spi_T6963C_init.
Spi_T6963C_set_cursor(cposx, cposy)
Spi_T6963C_clearBit
Prototype Description Requires Example
sub procedure Spi_T6963C_clearBit(b as byte)
Spi_T6963C_setBit
Prototype Description Requires Example
sub procedure Spi_T6963C_setBit(dim b as byte)
Spi_T6963C_negBit
Prototype Description Requires Example
sub procedure Spi_T6963C_negBit(dim b as byte)
page
406
Spi_T6963C_displayGrPanel
Prototype Description Requires Example
sub procedure Spi_T6963C_displayGrPanel(dim n as word)
Spi_T6963C_displayTxtPanel
Prototype Description Requires Example
sub procedure Spi_T6963C_displayTxtPanel(dim n as word)
Spi_T6963C_setGrPanel
Prototype Description Requires Example
sub procedure Spi_T6963C_setGrPanel(dim n as word)
Compute graphic start address for panel number n. GLCD needs to be initialized, see Spi_T6963C_Config.
Spi_T6963C_setGrPanel(n)
Spi_T6963C_setTxtPanel
Prototype Description Requires Example
sub procedure Spi_T6963C_setTxtPanel(dim n as word)
Compute text start address for panel number n. GLCD needs to be initialized, see Spi_T6963C_Config.
Spi_T6963C_setTxtPanel(n)
page
mikroElektronika: Development tools - Books - Compilers
407
making it simple...
Spi_T6963C_panelFill
Prototype Description Requires Example
sub procedure Spi_T6963C_panelFill(dim v as word)
Fill full #n panel with v bitmap (0 to clear). GLCD needs to be initialized, see Spi_T6963C_Config.
Spi_T6963C_panelFill(v)
Spi_T6963C_grFill
Prototype Description Requires Example
sub procedure Spi_T6963C_grFill(dim v as word)
Fill graphic #n panel with v bitmap (0 to clear). GLCD needs to be initialized, see Spi_T6963C_Config.
Spi_T6963C_grFill(v)
Spi_T6963C_txtFill
Prototype Description Requires Example
sub procedure Spi_T6963C_txtFill(dim v as word)
Fill text #n panel with char v + 32 (0 to clear). GLCD needs to be initialized, see Spi_T6963C_Config.
Spi_T6963C_txtFill(v)
Spi_T6963C_cursor_height
Prototype Description Requires Example
sub procedure Spi_T6963C_cursor_height(dim n as word)
page
408
Spi_T6963C_graphics
Prototype Description Requires Example
sub procedure Spi_T6963C_graphics(dim n as word)
Spi_T6963C_text
Prototype Description Requires Example
sub procedure Spi_T6963C_text(dim n as word)
Spi_T6963C_cursor
Prototype Description Requires Example
sub procedure Spi_T6963C_cursor(dim n as word)
Spi_T6963C_cursor_blink
Prototype Description Requires Example
sub procedure Spi_T6963C_cursor_blink(dim n as word)
page
mikroElektronika: Development tools - Books - Compilers
409
making it simple...
Spi_T6963C_Init_240x128
Prototype Description Requires Example
sub procedure Spi_T6963C_Init_240x128
Initialize T6963C based GLCD (240x128 pixels) with default settings for mE GLCD's. Spi_Init; must be called before initializing SPI Toshiba T6963C Graphic LCD.
Spi_T6963C_Init_240x128
Spi_T6963C_Init_240x64
Prototype Description Requires Example
sub procedure Spi_T6963C_Init_240x64
Initialize T6963C based GLCD (240x64 pixels) with default settings for mE GLCD's. Spi_Init; must be called before initializing SPI Toshiba T6963C Graphic LCD.
Spi_T6963C_Init_240x64
Library Example
The following drawing demo tests advanced routines of SPI T6963C GLCD library.
program Spi_T6963C_240x128 include T6963C_Consts include bitmap include bitmap2 dim panel as byte i as word curs as byte cposx, cposy as word txtcols as byte '* current panel '* general purpose register '* cursor visibility '* cursor x-y position '* number of text coloms
page
410
' continued ... '* '* '* '* '* '* '* '* '* init display for 240 pixel width and 128 pixel height 8 bits character width data bus on MCP23S17 portB control bus on MCP23S17 portA bit 2 is !WR bit 1 is !RD bit 0 is !CD bit 4 is RST chip enable, reverse on, 8x8 font internaly set in library
SpiX_Init(1) Spi_T6963C_Init_240x128() Spi_T6963C_panelFill(0) '* enable both graphics and text display at the same time Spi_T6963C_graphics(1) Spi_T6963C_text(1) panel = 0 i = 0 curs = 0 cposy = 0 cposx = 0 txtcols = 240 div 8 '* calculate number of text colomns '* (grafic display width divided by font width) '* text messages Spi_T6963C_write_text(" GLCD LIBRARY DEMO, WELCOME !", 0, 0, T6963C_ROM_MODE_XOR) Spi_T6963C_write_text(" EINSTEIN WOULD HAVE LIKED mE", 0, 15, T6963C_ROM_MODE_XOR) '* cursor Spi_T6963C_cursor_height(8) Spi_T6963C_set_cursor(0, 0) Spi_T6963C_cursor(0) '* draw rectangles Spi_T6963C_rectangle(0, 0, 239, 127, T6963C_WHITE) Spi_T6963C_rectangle(20, 20, 219, 107, T6963C_WHITE) Spi_T6963C_rectangle(40, 40, 199, 87, T6963C_WHITE) Spi_T6963C_rectangle(60, 60, 179, 67, T6963C_WHITE) ' continues ... '* 8 pixel height '* move cursor to top left '* cursor off
page
mikroElektronika: Development tools - Books - Compilers
411
making it simple...
' continued ... '* draw a cross Spi_T6963C_line(0, 0, 239, 127, T6963C_WHITE) Spi_T6963C_line(0, 127, 239, 0, T6963C_WHITE) '* draw solid boxes Spi_T6963C_box(0, 0, 239, 8, T6963C_WHITE) Spi_T6963C_box(0, 119, 239, 127, T6963C_WHITE) '* draw circles Spi_T6963C_circle(120, Spi_T6963C_circle(120, Spi_T6963C_circle(120, Spi_T6963C_circle(120, Spi_T6963C_circle(120, Spi_T6963C_circle(120, Spi_T6963C_circle(120, 64, 64, 64, 64, 64, 64, 64, 10, T6963C_WHITE) 30, T6963C_WHITE) 50, T6963C_WHITE) 70, T6963C_WHITE) 90, T6963C_WHITE) 110, T6963C_WHITE) 130, T6963C_WHITE) '* draw a sprite
Spi_T6963C_image(mikroPascal_logo_glcd_bmp) '* fill the graphic screen with a picture while true '* if RB1 is pressed, toggle the display between graphic panel 0 '* and graphic 1 if(PORTB.1 <> 0) then panel = panel + 1 panel = panel and 1 Spi_T6963C_displayGrPanel(panel) Delay_ms(300) '* if RB2 is pressed, display only graphic panel else if(PORTB.2 <> 0) then Spi_T6963C_graphics(1) Spi_T6963C_text(0) Delay_ms(300)
page
412
' continued ... else if(PORTB.3 <> 0) then Spi_T6963C_graphics(0) Spi_T6963C_text(1) Delay_ms(300) else if(PORTB.4 <> 0) then Spi_T6963C_graphics(1) Spi_T6963C_text(1) Delay_ms(300) else if(PORTB.5 <> 0) then curs = curs + 1 if(curs = 3) then curs = 0 end if select case curs case 0 Spi_T6963C_cursor(0) case 1 Spi_T6963C_cursor(1) Spi_T6963C_cursor_blink(1) case 2 Spi_T6963C_cursor(1) Spi_T6963C_cursor_blink(0) end select Delay_ms(300) end if end if end if end if end if cposx = cposx + 1 if(cposx = txtcols) then cposx = 0 cposy = cposy + 1 if(cposy = (128 div T6963C_CHARACTER_HEIGHT)) then '* if y end cposy = 0 '* grafic height (128) div character height end if end if Spi_T6963C_set_cursor(cposx, cposy) Delay_ms(100) wend end.
page
mikroElektronika: Development tools - Books - Compilers
413
making it simple...
Hardware Connection
MCP23S17
D0 D1 D2 D3 D4 D5 D6 D7 1 2 3 4 5 6 7 8 9 10 RF1 11 RF6 12 RF3 13 RF2 14 GPB4 GPB5 GPB6 GPB7 VDD VSS CS SCK SI SO GPB0 GPB1 GPB2 GPB3 GPA7 GPA6 GPA5 GPA4 GPA3 GPA2 GPA1 GPA0 INTA 19 INTB RESET A2 A1 15 A0
10 MhZ
28 27 26 25 24 23 22 21 20 FS MD RST CE E RW RS
dsPIC4013
VCC
VCC
RF0
13 14 VCC GND OSC1 OSC2
18 17 16
RF0 RF1
30 29
26 25 24
Contrast Adjustment
P1 10K
VCC VCC
R1 50
page
414
20
mikroE
EasydsPIC3
Dev. tool
Setjmp Library
This library contains functions and types definitions for bypassing the normal function call and return discipline. The type declared is jmp_buf which is an array of unsigned int type suitable for holding the information needed to restore a calling environment. Type declaration is contained in sejmp.h header file which can be found in the include folder of the compiler.
Library Routines
Setjmp Longjmp
Setjmp
Prototype Returns Description
sub function setjmp(dim byref env as word[4]) as integer
if the return is from direct invocation it returns 0 if the return is from a call to the longjmp it returns nonzero value This function saves calling position in jmp_buf for later use by longjmp. The parameter env: array of type (jmp_buf) suitible for holding the information needed for restoring calling environment. Nothing.
setjmp(buf)
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
415
making it simple...
Longjmp
Prototype Returns Description
sub procedure longjmp(dim byref env as word[4], dim val as integer)
longjmp causes setjmp to return val, if val is 0 it will return 1. Restores calling environment saved in jmp_buf by most recent invocation of setjmp macro. If there has been no such invocation, or function conatinig the invocation of setjmp has terminated in the interim, the behaviour is undefined.Parameter env: array of type (jmp_buf) holding the information saved by corresponding setjmp invocation, val: char value, that will return corresponding setjmp. Invocation of Longjmp must occur before return from the function in which Setjmp was called encounters.
longjmp(buf, 2)
Requires Example
Library Example
Example demonstrates function cross calling using setjmp and longjmp functions. When called, Setjmp() saves its calling environment in its jmp_buf argument for later use by the Longjmp(). Longjmp(), on the other hand, restores the environment saved by the most recent invocation of the Setjmp() with the corresponding jmp_buf argument. This example can be found in mikroBasic for dsPIC30/33 and PIC24 Setjmp example folder.
page
416
Time Library
The Time Library contains functions and type definitions for time calculations in UNIX time format. UNIX time counts the number of seconds since an "epoch". This is very convenient for programs that work with time intervals: the difference between two UNIX time values is a real-time difference measured in seconds, within the accuracy of the local clock. What is the epoch? Originally it was defined as the beginning of 1970 GMT. ( Jan. 1st 1970 Julian day ) GMT, Greenwich Mean Time, is a traditional term for the time zone in England. The type declared is TimeStruct which is an structure type suitable for time and date storage. Type declaration is contained in timelib.h which can be found in mikroBasic Time Library Demo example folder.
Library Routines
Time_dateToEpoch Time_epochToDate Time_dateDiff
Time_dateToEpoch
Prototype Returns Description
sub function Time_dateToEpoch(dim byref ts as TimeStruct) as longint
This function returns number of seconds. This function returns the unix epoch : number of seconds since Jan. 1st 1970 0h00mn00s of the time struct pointed by ts. Nothing.
Time_dateToEpoch(ts1)
Requires Example
page
mikroElektronika: Development tools - Books - Compilers
417
making it simple...
Time_epochToDate
Prototype Returns Description Requires Example
sub procedure Time_epochToDate(dim e as longint, dim byref ts as TimeStruct)
This function returns number of seconds since 1970. Convert the unix epoch e (number of seconds since 1970) into a time struct ts. Nothing.
Time_epochToDate(epoch, ts2)
Time_dateDiff
Prototype Returns Description
sub function Time_dateDiff(dim byref t1, t2 as TimeStruct) as longint
This function returns return time difference in seconds as a signed long. This function compares two dates, returns time difference in seconds as a signed long. Result is positive if t1 is before t2, result is null if t1 is the same as t2 and result is negative if t1 is after t2. Note: This function is implemented in mikroBasic Time Library Demo example folder.
diff = Time_dateDiff(ts1, ts2)
Requires Example
page
418
Library Example
Demonstration of Time library routines usage for time calculations in UNIX time format.
program Time_Demo '* '* simple time structure '* structure TimeStruct dim ss as byte ' seconds dim mn as byte ' minutes dim hh as byte ' hours dim md as byte ' day in month, from 1 to 31 dim wd as byte ' day in week, monday=0, tuesday=1, .... sunday=6 dim mo as byte ' month number, from 1 to 12 (and not from 0 to 11 as with ' unix C time !) dim yy as word ' year Y2K compliant, from 1892 to 2038 end structure dim ts1, ts2 as TimeStruct buf as byte[256] epoch, diff as longint
= = = = = =
0 7 17 23 5 2006
'* '* what is the epoch of the date in ts ? '* epoch = Time_dateToEpoch(ts1) ' epoch = 1148404020
//continues...
page
mikroElektronika: Development tools - Books - Compilers
419
making it simple...
//continued... '* '* what date is epoch 1234567890 ? '* epoch = 1234567890 Time_epochToDate(epoch, ts2)
= = = = = = =
30 31 23 13 4 2 2009
'* '* how much seconds between this two dates ? '* diff = Time_dateDiff(ts1, ts2) ' diff = 86163870 end.
page
420
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 the 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 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: office@mikroe.com Support: support@mikroe.com Web: www.mikroe.com
page
mikroElektronika: Development tools - Books - Compilers
421