Basic Pic Programming
Basic Pic Programming
Nebojsa Matic
Author
January / 2003
1
CHAPTER I CHAPTER II CHAPTER III CHAPTER IV CHAPTER V CHAPTER VI CHAPTER VII APPENDIX A APPENDIX B
THE FUNDAMENTS OF PIC BASIC BASIC ELEMENTS OF PIC BASIC LANGUAGE OPERATORS INSTRUCTIONS SAMPLE PROGRAMS FOR SUBSYSTEMS WITHIN THE MICROS SAMPLES WITH PIC16F84 MICROCONTROLLER SAMPLES WITH PIC16F877 MICROCONTROLLER MPLAB MicroCode studio
In this book you can find: Practical connection samples for: Temperature sensors, AD and DA converters LCD and LED displays, relays. Every example is commented in details with detailed connection scheme Program writing Learn how to write your own program, correct mistakes and use it to start a microcontroller. Instruction Set Every instruction is explained in detail with the example how to use it. MicroCode studio How to install it, how to use it MPLAB program package How to install it, how to start the first program, how to connect BASIC and MPLAB etc
Preface
In order to simplify things and crash some prejudices, I will allow myself to give you some advice before reading this book. You should start reading it from the chapter that interests you the most, in order you find suitable. As the time goes by, read the parts you may need at that exact moment.If something starts functioning without you knowing exactly how, it shouldn't bother you too much. Anyway, it is better that your program works than that it doesn't.Always stick to the practical side of life. It is much better for the program to be finished on time, to be reliable and, of course, to be paid for it as well as possible. In other words, it doesn't matter if the exact manner in which the electrons move within the PN junctions your microcontroller is composed of escapes your knowledge. You are not supposed to know the whole history of electronics in order to assure the income for you or your family.Do not expect that you will find everything you need in one single book. The information are dispersed literally everywhere around you, so it is necessary to collect them diligently and sort them out carefully. If you do so, success is inevitable.With all my hopes of having done something worthy investing your time in. Yours Nebojsa Matic
Chapter 1
THE FUNDAMENTS OF PIC BASIC
Introduction 1.1 BASIC for PIC microcontrollers 1.2 PIC microcontrollers 1.3 First program written in PIC BASIC 1.4 Writing and compilation of a BASIC program 1.5 Loading a program into the microcontroller memory 1.6 Running your program 1.7 Problem with starting your program (what if it doesn't work)
Introduction
Simplicity and ease, which the higher programming languages bring for program writing as well as broader application of the microcontrollers, was enough to incite some companies as Microengeneering to embark on the development of BASIC programming language. What did we thereby get? Before all, the time of writing was shortened by employment of prepared functions that BASIC brings in (whose programming in assembler would have taken the biggest portion of time). In this way, the programmer can concentrate on solving the essential task without losing his time on writing the code for LCD display. To avoid any confusion in the further text, it is necessary to clarify three terms one encounters very often. Programming language is understood as a set of commands and rules according to which we write the program and therefore we distinguish various programming languages such as BASIC, C, PASCAL etc. On the BASIC programming language the existing literature is pretty extensive so that most of the attention in this book will be dedicated to the part concretely dealing with the programming of microcontrollers. Program consists of sequence of commands of language that our microcontroller executes one after another. The structure of BASIC program is explained with more detailed in the second chapter. BASIC compiler is the program run on PC and it's task is to translate the original BASIC code into the language of 0 and 1 understandable to the microcontroller. The process of translation of a BASIC program into an executive HEX code is shown on the image below. The program written in PIC BASIC and registered as a file Program.bas is converted into an assembler code (Program.asm). So obtained assembler code is further translated into executive HEX code which is written to the microcontroller memory by a programmer. (programmer is a device used for transferring HEX files from PC to the microcontroller memory)
BASIC enables quicker and relatively easier program writing for PIC microcontrollers in comparison with the Microchip's assembling language MPASM. During the program writing, the programmer encounters always the same problems such as serial way of sending messages, writing of a variable on LCD display, generating of PWM signals etc. All for the purpose of facilitating programming, PIC BASIC contains its built-in commands intended for solving of the problems often encountered in praxis. As far as the speed of execution and the size of the program are concern, MPASM is in small advantage in respect with PIC BASIC (therefore exists the possibility of combining PIC BASIC and assembler). Usually, the part of the program in which the same commands are executed many times or time of the execution critical, are written in assembler. Modern microcontrollers such as PIC execute the instructions in a single cycle lasting for 4 tact of the oscillator. If the oscillator of the microcontroller is 4MHz, (one single tact lasts 250nS), then one assembler instruction requires 250nS x 4 = 1uS for the execution. Each BASIC command is in effect the sequence of the assembler instructions and the exact time necessary for its execution may be obtained by simply summing up the times necessary for the execution of assembler instructions within one single BASIC command.
The program examples worked out throughout this book are mostly to be run on the microcontrollers PIC16F84 or PIC6F877, but could be, with small or almost no corrections, run on any other PIC microcontroller.
STUDIO. The advantage of these program packages is that they take care of the code syntax, free memory and provide more comfortable environment when writing a program (appendices A and B describe MPLAB and MicroCODE STUDIO editors).
When the original BASIC program is finished and saved as a single file with .BAS ending it is necessary to start PIC BASIC compiler. The compiling procedure takes place in two consecutive steps. Step 1. In the first step compiler will convert BAS file in assembler s code and save it as BLINK.ASM file. Step 2. In the second step compiler automatically calls assembler, which converts ASM - type file into an executable HEX code ready for reading into the programming memory of a microcontroller. The transition between first and second step is for a user - programmer an invisible one, as everything happens completely automatically and is thereby wrapped up as an indivisible process. In case of a syntax error of a program code, the compilation will not be successful and HEX file will not be created at all. Errors must be then corrected in original BAS file and repeat the whole compilation process. The best tactics is to write and test small parts of the program, than write one gigantic of 1000 lines or more and only then embark on error finding.
- BLINK.HEX - executable file which is written into the programming memory File with the HEX ending is in effect the program that is written into the programming memory of a microcontroller. The programming device with accessory software installed on the PC is used for this operation. Programming device is a contrivance in charge of writing physical contents of a HEX file into the internal memory of a microcontroller. The PC software reads HEX file and sends to the programming device the information about an exact location onto which a certain value is to be inscribed in the programming memory. PIC BASIC creates HEX file in a standard 8-bit Merged Intel HEX format accepted by the vast majority of the programming software. In the text bellow the contents of a file BLINK.HEX is given.
Besides reading of a program code into the programming memory, the programming device serves to set the configuration of a microcontroller. Here belongs the type of the oscillator, protection of the memory against reading, switching on of a watchdog timer etc. The connection between PC, programming device and the microcontroller is shown.
The programming software is used exclusively for the communication with the programming device and is not suitable for any code writing. The one comprising text editor, software for programming microcontroller and possibly the simulator as an entity bears the name IDE i.e. Integrated Development Environment. One such environment is a Microchip's software package MPLAB.
The oscillator of the microcontroller can be a 4MHz crystal and either two 22pF capacitors or the ceramic resonator of the same frequency (ceramic resonator already contains the mentioned capacitors, but contrary to the oscillator has three termination instead of only two). The speed at which the microcontroller operates i.e. the speed at which the program runs depends heavily on this frequency of an oscillator. In the course of an application development the easiest to do is to use the internal reset circuit in a manner that MCLR pin is connected to +5V through a 10K resistor. In the sequence of text the scheme of a rectifier with circuit of LM7805 which gives the output of stable +5V, as well as the minimal configuration relevant for the operation of a PIC microcontroller.
Minimal hardware configuration necessary for the operation of PIC microcontroller After the supply is brought to the circuit structured according to the previous pictures, PIC microcontroller should look animated, and its LED diode should be twinkling once each second. If the signal is completely missing (LED diode doesn't twinkle), the check is to be done to ascertain if the +5V is present at all the corresponding tentacles on PIC microcontroller.
Step 3. Check the supply. PIC microcontroller spends very little energy but the supply must be pretty well filtrated. At the rectifier exit, the current is direct but pulsing and as such is by no means suitable for the supply of microcontroller. To avoid this pulsing, the electrolytic capacitor of high order of capacitance (say 470 F) is placed at the exit of a rectifier. If PIC microcontroller supervises the devices that pull lot of energy from the energy source they can in their own rights provoke enough malfunctioning on the supply lines so that the microcontroller can stop working normally and start revealing somewhat strange behavior. Even seven-segmented LED display may well induce tension drops (the worst scenario is when all the digits are 8, for then LED display needs most power), if the source itself is not capable to procure enough current (for the case of 9V battery just for an example). Some PIC microcontrollers have multi-functional entrance\exit pins, as it is the case with PIC16C62x family (PIC16C620, 621 and 622). The microcontrollers belonging to this family are provided with analogue comparators at port A. After putting those chips to work, port A is set onto an analogue mode, which brings about the unexpected behavior of the pin functions on this port. Any PIC microcontroller with analogue entrances will after reset show itself in an analogue mode (if the same pins are used as digital lines they must then be set into a digital mode). One of the possible sources of troubles is that the fourth pin of the port A shows singular behavior when it is used as exit (because this pin has open collectors exit instead of usual bipolar state). That implies that the inscription of the logical zero on this pin will nevertheless set it on the low level, but the inscription of logical unit will let it float somewhere in between instead of setting it at high level. To coerce this pin react in a proper way the pull-up resistor is placed between RA4 and 5V. The magnitude of this resistor may be between 4.7K and 10K, depending on the intensity of the current necessary for the convected entrance. This pin functions as any other pin used as an entrance (all the pins are after reset procedure set as exits). During the work with PIC microcontrollers more problems are to be expected. Sometimes what is being tried seems like going to work, but it doesn't happen to be the case regardless of how hard had we put an effort. Normally there is more than one way to solve something. A different angle approach may bring a solution with the same effort.
Chapter 2
BASIC ELEMENTS OF PIC BASIC LANGUAGE
Introduction 2.1 Identifiers 2.2 Labels 2.3 Constants 2.4 Variables 2.5 Sequences 2.6 Modifiers 2.7 Symbols 2.8 Direction INCLUDE 2.9 Comments 2.10 Programming line with more instructions 2.11 Transfer of a instruction into another line 2.12 Define 2.13 DISABLE 2.14 ENABLE 2.15 ON INTERRUPT 2.16 RESUME
Introduction
Next chapter describes the basic elements of a PIC BASIC language and the mode to use them in the efficient program writing. It is somewhat of an artistry to write a code that is both readable and easy to handle. Program is supposed to be understandable, before all, to the programmer himself and then later to his colleagues in charge of doing some corrections and adding as well. In the further text is given one example of the program written in a clear and manifest way.
Extensive use of comments, symbols, labels and other elements supported by PIC BASIC, program can be rendered considerably clearer and more understandable what is in later corrections and enlargement of the program offering programmer a great deal of help. In order to make it even more understandable it is advisable to separate the program into logical entities as those parts to which a jump with the goto instruction can be performed or subprograms to be called with the gosub instruction. Labels indicating the beginning of the segments of programs should have meaning making some obvious sense. If it, say, exists such segment of a program that switches on and off LED diodes on some of the ports, the label indicating the beginning of that part of the program could well be for example "Blink" (LED diodes shine or go dark - therefore they blink) or the like. Elements determining one BASIC program are the following: - Identifiers - Labels - Constants - Variables - Sequences - Modifiers - Symbols - Comments - Include - DEFINE - _ (continuation of a instruction transferred into another line) - On interrupt - Disable - Enable - Resume Although they are many at first glance only but a few of them is fair enough for writing approximately 90% of all programs. Nevertheless for the sake of completeness on all the elements will be treated on the following pages.
10
2.1 Identifiers
Identifier represents the name of some PIC BASIC element. Identifiers are used in PIC BASIC in order to sign program lines and the names of various symbols. Identifier itself could be any string of letters, numbers or even dashes with the limit that it is not allowed to begin with a number. Identifiers don't distinguish small and capital letters, so that the strings TASTER and Taster are treated the same way. The maximum length for such strings is 32 characters.
2.2 Labels
Label represents textual sign for some programming line or respectively some of its fragments on which the program can jump through some of the instructions used to change the program flow. It is obligatory to end the label with. Contrary to many old BASIC versions, PIC BASIC doesn't allow numerical values as labels.
2.3 Constants
Name_constants con value_constants With this declaration is to some chosen name assigned the value that is constant. For example the constant minute has the value of 60 seconds, bearing the recollection to the number of seconds in a minute. Written at whatever program position, minute will be interpreted by complier as if it had been written 60. There are two very important reasons for such habit in program writing. The first one is the programmers wish to be more manifest. Good visibility is achieved by giving to the variables and constants those names that could be associated with the very function they assume within the program. On the other hand, the bigger flexibility of the program is obtained as well. It is for an example so that if it becomes necessary in some future work to use the same code but with a change value of the constant, it is enough make a change in the part for declaration instead performing search and replace throughout the program.
Constants can be equally written in decimal, hexadecimal and binary form. Decimal constants are written without any prefix. Hexadecimal constants start all with a sign $ and binary with %. To make the programming easier, single letters are converted into their ASCII counterparts. The sign constants must be placed into the inverted comas and they 11
contain only one letter as a rule (in adverse case they are string constants).
2.4 Variables
Name_variable var Type_variable Variables serve for temporary storing of data and results of various arithmetic and logical operations. Variables are stored on the microcontrollers RAM locations, which means that the total number of the variables that can be used depend on the size of RAM. Accordingly for the 36-byte microcontroller, 22 bytes are reserved for variables. Variable defining is achieved with the formal word var at the beginning of the program. PIC BASIC supports variables like bit, byte and word. Variable type is selected with reference to the expected value that this same variable can assume in the course of the program run. Therefore the variable of the bit type can take value of 0 or 1, the variable of the byte values from 0 to 256 and finally, word from 0 to 65535.
2.5 Sequences
Name_sequence var type_element [number of the elements] Sequences of the variables are defined in a similar way as we have done with the variables. "Type_element" represents the value of every element of the sequence, and can be bit, byte or word. The number of the elements of the sequence is given through value between "[]".Each element of the sequence is accessible by an index. Index starts with zero. When we come to define the number of the elements of the sequence one must always have in mind that the number of locations in RAM memory on which we intend to store variables finite. The next table shows the maximal number of the elements of various types. The size of the sequence Element of the sequence BIT BYTE WORD * Depends on microcontroller Maximal number of elements 256 96* 48*
12
Sequence1 [0] represents the first element of the sequence and sequence1 [9] the last element of the sequence "sequence1". Sequence2 var byte[8] ' the sequence of 8 elements of the type byte
Sequence2 [0] represents the first element of the sequence and sequence2 [7] the last element of the sequence "sequence2".
2.6 Modifiers
new_name var old_name By means of modifier it is possible to introduce a new name for the variable already defined. This direction is used relatively rarely but it ought to be mentioned for the sake of completeness. It is used in an identical way as a direction for the definition of the variables. Introduction of a new name is effectuated through the official word var.
2.7 Symbols
symbol old_name = new_name Symbols are granted the function exactly the same as direction for modifying variables, i.e. they serve for assigning the new names to the variables and constants. Symbols are introduced for the compatibility of the programs written for Basic Stamp and cannot be used for introducing variables.
13
2.9 Comments
' .... Comment.... ' In the course of program writing there's a space for lot of comments even if it may be self-evident what is the main purpose of the program. Although it may well seem as a shear waste of time, it may play later a crucial role (comments don't occupy an additional memory space in the memory of a microcontroller). Comments should give useful instructions about all that the program is doing. Comment as Set Pin0 to 1 simply explains the syntax of the language but fails to pinpoint the purpose of the act. Something of a sort Turn the Relay on may prove itself to be much more useful. At the beginning of the program it should be described what is the program used for, who were the authors and when was it written. Stipulating the information concerning revision and the exact date may be useful too. Even every concrete statement about connection to each pin can be crucial in an effort to memorize the very hardware for which this program was designed to operate.
14
2.12 Define
DEFINE the value parameter Instructions of the PIC BASIC language can have some parameters from which depends the exact way the instructions are executed. Those parameters assume some predefined values that appear in the most of the cases. A frequency of an oscillator is a good example for that. If not otherwise stated the tact of the oscillator is taken by default as 4MHz. In case that the used oscillator is of a different frequency from 4MHz it is necessary using the DEFINE direction to specify that frequency and communicate it to all the programs that contain within instructions depending on the tact of the microcontroller. One such instruction is for the serial transfer. In case that the instruction DEFINE is omitted and in gear is 8Mhz instead of 4Mhz oscillator, all the instructions that depend on the tact of microcontroller will be executed 2 times quicker. For instance, if the parameter of the speed of transfer amounts to 9600 bauds by using SERIN instruction, the data transfer would be effectuated at the speed 19200. In the same way the instruction pause 1000 the delay realized would be 0.5s instead 1.0s. It is also possible similarly to upgrade the resolution of the instructions. What is next is the review of the usage for DEFINE direction in case of adjusting of parameters explained within each particular instruction.
parameter
description
I2C_HOLD
I2C_INTERNAL
internal EEPROM in series I2COUT, I2COUT 16Cexxx and 12Cxxx of the PIC microcontroller serial tact is a bipolar at the place of an open collector for the tact > BMHz OSC with the devices of a standard velocity LCD data port I2CWRITE, I2CREAD
I2C_SCLOUT
I2C_SLOW
I2CWRITE, I2CREAD
LCD_DREG
PORTD
LCDOUT, LCDIN
LCD_DBIT
LCDOUT, LCDIN
LCD_RSREG
PORTD
LCDOUT, LCDIN
LCD_RSBIT
LCDOUT, LCDIN
the time of delay of instruction in microseconds (us) the time of delay of data in microseconds tact of the oscillator in MHz: 3(3.58) 4 8 10 12 16 20 25 32 33 40
LCDOUT, LCDIN
LCDOUT, LCDIN all instructions of the serial transfer and next pause
OSC
1 1 8 50 10 1000
setting of OSCCAL for PIC12C671/CE673 microcontrollers the number of data bits the slowing of the tact of transfer instruction LFSR in 18Cxxx microcontrollers SHIFTOUT, SHIFTIN LFSR BUTTON SEROUT, SERIN HSEROUT, HSERIN HSEROUT, HSERIN HSEROUT, HSERIN HSEROUT, HSERIN HSEROUT, HSERIN HSEROUT, HSERIN
SHIFT_PAUSEUS BUTTON_PAUSE CHAR_PACING HSER_BAUD HSER_SPBRG HSER_RCSTA HSRE_TXSTA HSER_EVEN HSER_ODD Example:
2.13 DISABLE
DISABLE Before entering the interrupt routine, it is necessary to switch off the interrupts in order to avoid any new interruption in the course of data processing. The interruptions are forbidden in a manner that the instruction "DISABLE" reset the bit GIE in the register INTCON.
16
2.14 ENABLE
ENABLE In the course of execution of the interruption routine, the interrupts must be forbidden by resetting the bit GIE in the INTCON register. When the interruption processing is finished, the interruptions must be allowed once again with the instruction "ENABLE".
2.15 ON INTERRUPT
On interrupt LABEL With instruction "On interrupt" is indicated the label on which the program will "jump" when the interruption happened, i.e. from which label the interruption routine starts.
2.16 RESUME
RESUME Return from the interruption routine to the main program.
17
Chapter 3
OPERATORS
Introduction 3.1 Expressions 3.2 Instructions 3.3 Arithmetical operators 3.3.1 Multiplication 3.3.2 Division 3.3.3 Shift 3.3.4 ABS 3.3.5 COS 3.3.7 DIG 3.3.8 MAX and MIN 3.3.9 NCD 3.3.10 REV 3.3.11 SIN 3.3.12 SQR 3.4 Bit operators 3.5 The operators of comparison 3.6 Logical operators
Introduction
The PIC BASIC language possesses the operator set used to assign the values, compare objects and perform multitude of other operations. The objects manipulated for that purposes are called operands (which themselves can be variables or constants). The operators of PIC BASIC language must have at least two operands. They serve to create instructions and expressions that together with variables, constants and comments in effect compose the program.
3.1 Expressions
Combinations of operators and operands are called expressions. The expression does the computation and furnishes the result or starts some other activity. A= B+ C ' The expression that sums up the values of the variables B and C and ' stores the result into the variable A
In application of any expression the attention must be paid that the result of the computation must be within the range of variable A in order to avoid the overflow and therefore the evident computational error. If the result of expression amounts to 428, and the variable A is of BYTE type having range between 0 and 255, the result accordingly obtained will be 172 - obviously the wrong one.
3.2 Instructions
Each instruction determines an action to be performed. As a rule, the instructions are being executed in an exact order in which they are written in the program. However, the order of their execution can be changed as well employing the instructions for the change of the flow of a program to another segment of the program such as the instructions of the ramification, jump or interrupt. 18
Instruction IF...THEN contains the conducting expression Time=60 composed in its own rights of two operands, the variable Time, constant 60 and the operator of comparison (=). The instructions of PIC BASIC language can be distinguished as the instructions of choice (decision making) repeating (loops), jump and specific instruction for an access to the peripheries of the microcontrollers. Each of these instructions is explained in detail in Chapter 4.
Operators are numerous, but for almost 90% of all the programs it is necessary to know only few of them. It suffices to look how many operators are used in the examples in Chapter 5, 6 and 7.
After the activities they perform, the operators can be classified into the following categories: - Arithmetic operators - Bit operators? - The operators of comparison - Logical operators
19
3.3.1 Multiplication
Syntax: L0 = W1 * 100 L1 = W1 ** W2 L2 = W1 */ W2
Description: PIC BASIC pro does not support directly the work with the 32-bit numbers. It is usual to present a 32-bit variable as a two 16-bit variables. Operator '*' reverts lower 16 bits of a 32-bit result. Operator '**' reverts higher 16 bits of a 32-bit result. These two operators can be used in a combined way for computing 16x16 multiplications in order to produce 32-bit results. Example:
3.3.2 Division
Syntax: W0 = W1 / 100 W2 = W1 // 100
Description: As it is the case with multiplication, the operation of division is done over the 16 bit operands. Operator '/' reverts 16-bit integer result while the operator '//' reverts the remainder. Example:
20
3.3.3 Shift
Syntax: W0 = W0 << 3 W0 = W0 >> 1
Description: Operators of the shift perform the shift towards left or right from 0 to 15 times. All the new bits that enter from the side have value 0. These two operators belong to the operators over the bits. Example:
Description: ABS gives the absolute value of a number. If ABS gets applied to the variable of the BYTE type greater then 127 (set MSB) the result is 256. If the ABS gets applied to the variable of WORD type greater then 32767 (the bit set is of the biggest weight - MSB) result is 65536. Example:
21
Description: COS reverts the 8-bit value of the cosine. The result is in the second complement (i.e. within the range -127 to 127). For that reason it is necessary to use the lookup table in order to determine the result (cosine of an angle goes in the binary range between 0 and 255 in contrast with usual 0 to 359 degrees). Example:
Description: DCD gives the decoded bit value of the operand whose value is in the range within 015. If the operand is 0 then the zeroth bit of the result 1, and if the operand reads as 7, the seventh bit of the result is 1. Example:
22
Description: DIG furnishes the value of the digit of a decimal number. The number whose digits are looked for is 0-3 where 0 is a last right digit i.e. digit of the smallest weight (it is most often used for the work with seven-segment digits for extraction of the digits to be displayed). Example:
Description: The operator's maximum and minimum are used whenever it is necessary to revert one out of two values that are being compared. If those numbers are for example 100 and 200 operator Max will revert the value 200 and operator Min, value 100. To the difference from the operators "bigger then" and "less then" they revert the entire value and not only the quantification whether some value is smaller or bigger then the other. Example:
23
Description: NCD furnishes the value that is coded with the priority code. That gives the position of the first unit, which it encounters from the left side. If the operand is 0 the result is 0 as well. Example:
Description: REV reverts the order of the lowest bits of the operand. The number of the bits that can be reverted goes from 1 to 16. Example:
Description: SIN reverts the 8-bit value of the sine. The result is in the second Complement (i.e. within the range -127 to 127). For that reason it is necessary to use the lookup table in order to determine the result (sine of an angle goes in the binary range between 0 and 255 in contrast with usual 0 to 359 degrees). Example:
24
Description: SQR reverts a value of a square root. Result is stored into the variable of BYTE type. Example:
The value result of the expression depends on the fact which of the listed logical operations is executed over the bits of the operand. In that way, it is possible to extract, delete, set or invert the certain bit of the operand. Example1: B0 = B0 & %00000001 The upper instruction extracts the value of the lowest bit of the variable B0. When the logical "AND" is performed with the zero, there will be 0 at the position of a corresponding bit (so that all the bits 1-7 will be zeroes). The value will depend on bit 0 in the variable B0 and if it is "0", the value of variable B0 will be "0" and if it is "1" the value of B0 will accordingly be "1". Example2: B0 = B0 & %00000100 The upper instruction sets bit2 in the variable B0. When the logical "or" is performed with the unity the result is always equal to "1" regardless of the state of the corresponding bit from B0.
25
Example 3: B0 = B0 & %00000010 The upper instruction inverts the bit 1 in variable B0. If the bit was "1" then it turns into "0" and vice versa. The other logical operators are used only rarely so there's no need for their detailed explanation.
These operators are most often used in examination of the conditions by the instructions such as IF...THEN. Example: If Seconds = 60 then minutes = minutes + 1 Seconds = Seconds + 1 If the variable " Seconds" equals 60 the condition of the comparison is true and the instruction "Minutes=Minutes+1" will be executed then. Unless the expression is not true the instruction "Seconds=Seconds+1" will be executed instead.
26
27
Chapter 4
INSTRUCTIONS (1/4)
Introduction 4.1 @ 4.2 ASM..ENDASM 4.3 ADCIN 4.4 BRANCH 4.5 BRANCHL 4.6 BUTTON 4.7 CALL 4.8 CLEAR 4.9 CLEARWDT 4.10 COUNT 4.11 DATA 4.12 DTMFOUT 4.13 EEPROM 4.14 END 4.15 FREQOUT 4.16 FOR-NEXT 4.17 GOSUB 4.18 GOTO 4.19 HIGH 4.20 HSERIN 4.21 HPWM 4.22 HSEROUT 4.23 I2CREAD 4.24 I2CWRITE 4.25 INPUT 4.26 IF-THEN-ELSE 4.27 LCDOUT 4.28 LCDIN 4.29 {LET} 4.30 LOOKDOWN 4.31 LOOKDOWN2 4.32 LOOKUP 4.33 LOOKUP2 4.34 LOW 4.35 NAP 4.36 OUTPUT 4.37 OWIN 4.38 OWOUT 4.39 PAUSE 4.40 PAUSEUS 4.41 POT 4.42 PULSIN 4.43 PULSOUT 4.44 PWM 4.45 RANDOM 4.46 RCTIME 4.47 READ 4.48 READCODE 4.49 RETURN 4.50 REVERSE 4.51 SELECT-CASE 4.52 SERIN 4.53 SERIN2 4.54 SEROUT 4.55 SEROUT2 4.56 SHIFTIN 4.57 SHIFTOUT 4.58 SLEEP 4.59 SOUND 4.60 STOP 4.61 SWAP 4.62 TOGGLE 4.63 WRITE 4.64 WRITECODE 4.65 WHILE-WEND
Introduction
All the programs regardless of the fact how complicated or simple they may be are nothing else but a strict flow of the executions of instructions. Instructions of branching are used in program for the decision-making (in which one of two or more program paths is being chosen). The basic instruction of branching in PIC BASIC language is instruction if. This instruction has several variations that furnish necessary flexibility required for the realization of the logic of the decision-making (these variations comprise the use of term else and insertion of the instructions). Instructions of repeating give the possibility of repeating one or more single instructions. The conducting expression determines how many times the repetition will be performed. The set of those instructions is composed of WHILE ... WEND and FOR ... NEXT. Instructions of jump serve to change the flow of the program execution. The basic instruction of jump, GOTO, transfers the execution of the program to a signed instruction in a main program or inside subroutines. Other instructions of jump are BRANCH, BRANCHL, CALL, GOSUB, RETURN (these instructions are unavoidable in programs but their use is subject to certain restrictions). Instructions of access to the peripheral devices facilitate the programmer's job. Now programmer can concentrate on the essence of the program he set out to solve, avoiding unnecessary waste of time in writing routine for LCD display or some other peripheral device he uses in his set. The set of instructions is such to satisfy the large part of needs in the design of even the most complicated microcontrollers systems.
28
instructions
Description:
ASM and ENDASM instructions give the information that the code between ASM and ENDASM assembler type. Maximal size of the assembler code depends on the size of the programming memory of a microcontroller. In case of a PIC16F877 microcontroller the maximal value of an assembler code is 8K.
Example: Main : asm bsf PORTA, 0 bcf PORTB, 3 endasm Loop : goto Loop end ' Beginning of asm part of the program ' set RA0 to "1" ' set RB3 to "0" ' End of asm part of the program
29
4.3 ADCIN Write the values from the input of the internal AD converter
Syntax: ADCIN channel, variable
Description:
ADCIN performs A/D conversion of an input analogue signal in microcontrollers that have A/D converter built in chip (i.e. PIC16F877). The value read in is stored into a designated variable. Before use of ADCIN instruction the appropriate TRIS register must be initiated so that the given is designated input one. Beside that in ADCON1 register one has to set the input pins for analogue working regime, format of the results and tact of A/D converter.
Example: DEFINE ADC_BITS 8 DEFINE ADC_CLOCK 3 DEFINE ADC_SAMPLEUS 10 ' Converted result will have 8, 10 or 12 bits ' Clock for A/D converter ' Sampling time expressed in us
B0 var byte Main : TRISA = $FF ADCON1 = 0 adcin 0 B0 ' All pins of port A are input ' PORTA is analog 30 ' Read the channel 0 and store the result into variable B0
Example: B0 var byte Main : branch B0, [lab1, lab2, lab3] Loop : goto Main lab1 : lab2 : lab3 : end ' Labels where the program execution resumes after ' the jump initiated by instruction BRANCH
Example: W0 var word Main : branchl W0, [lab1, lab2, lab3] Loop : goto Loop lab1 : lab2 : lab3 : end ' Labels where the program execution resumes after ' the jump initiated by instruction BRANCHL
31
Description:
The Button instruction eliminates the influence of contact flickering due to the pressing on the button (debouncing), what could be interpreted by the program as the pressing of the button more then one time instead of only once. Beside this function, instruction Button secures the function of auto-repeat which enables execution of determinate instruction as long as we keep pressing the button. The time between consecutive execution of two instructions is specified with the argument Speed. Pin - Pin on which we have button. State - State of the pin when the button is pressed (0...1). Delay - Countdown time before we initiate auto-repeat (0...255). At value 0, there will be no autorepeat. At value 255, the debouncing will be effectuated but without auto-repeat. Speed - Time of auto-repeat (0..255). Variable - Auxiliary variable of byte type (which must be defined at the very beginning of program
Example:
The example below will at each pressing of the button, which is connected to RA0, change the state of pin. If the diode is tied to the same pin the effect of the twinkling of the diode will be manifested.
32
33
Description:
Example:
Description:
Counts the impulses that appear on a specified pin during the time interval defined with the Period variable. The number of the impulses is stored into the No_Inpulse variable. Pin is automatically designated as input Period is specified in milliseconds If the oscillator is a 4Mhz one check of a
Example:
4.11 DATA Effectuates writing into the EEPROM at the first programming
34
Example:
In order to obtain the desired sinusoidal signal at the output, the installation of a sort of filter is required. Example:
EEPROM or FLASH programming memory built in the chip. The date are saved in the EEPROM space when the programming of microcontroller is definitely finished. For inwriting and reading of EEPROM memory in the course of the operation of the microcontroller, the instructions WRITE and READ are being used. Example:
Example:
In order to obtain the desired sinusoidal signal at output the installation of a sort of filter is required
36
Example:
Description:
The instructions of repeating one or more instructions. The conducting expression will determine how many times will repeating take place. "Index" is usually the variable employed for the control of how many times is for...next loop executed. If the parameter "Step" is not specified, it is understood that the variable "Index" is increased by one. (Index = Index + 1). auxiliary variable the program turns on and off the diodes at port B with 1s pause 200 times.
Example:
auxiliary variable the program turns on and off the diodes at port B with 1s pause 100 times
auxiliary variable the program turns on and off the diodes at port B with 1s pause 900 times
37
Example:
The program above does exactly the same thing as the previous one, but without GOSUB instruction.
38
Description:
Sets the appropriate pin on the high level. Pin is thereby automatically designated output.
Example:
39
Example:
Example:
When calculating transfer rate, HSERIN assumes that microcontroller works with the 4MHz oscillator. If different oscillator is used, new frequency must be specified with the following directive: DEFINE OSC F t f Specific oscillator frequency ith 40 it bit d ith 1 t bit S th f t
i l d t i 8N1 8 d t bit
Format of serial data is 8N1 - 8 data bits, with no parity bit and with 1 stop bit. Some other formats, such as 7E1 (7 data bits, parity bit, 1 stop bit) or 7O1 (7 data bits, non-parity bit, 1 stop bit) may be used with the following DEFINE directives at the beginning of the program: DEFINE HSER_EVEN 1 Only when we want to verify the parity DEFINE HSER_ODD 1 Only when we want to verify the non-parity
Serial transfer is hardware based, so you might need an additional driver for adjusting to RS-232 (MAX232). Modifier {I}{S} BIN{1..16} {I}{S} DEC{1..5} {I}{S} HEX{1..4} REP c/n STR ArrayVar {\n} Sends binary number decimal number hexadecimal number character c repeated n times n character string
Example:
B0 var byte B0 = 4 Main : hserout [dec B0, 10] Loop: goto Loop end send decimal number from variable B0 and constant 10
41
Capacity 128 bytes 256 bytes 512 bytes 1K bytes 2K bytes 4K bytes 8K bytes
bbb = block selection ddd = device selection bits xxx = has no effect If 2-byte data (WORD) is received, higher byte is received first, and lower thereafter. For string transfer, STR goes before the name of the string, and number of clocks after \ . a var byte[8] I2CREAD PORTC.4, PORTC.3, $a0, 0, [STR a\8] If optional label is used, program will jump to the label if there is no response signal over the I2C interface. Standard transfer rate (100kHz) is achieved with 8MHz oscillator. For higher transfer rate (400kHz) 20MHz oscillator is used. If slower oscillator is used for the transfer, following directive should be used : DEFINE I2C_SLOW 1 In order to have bipolar I2C clock interface and not an open collector, following DEFINE directive should be used: DEFINE I2C_SCLOUT Operating any peripheral units with I2C communication demands that you read supplier manuals and specifications.
Example:
B0 var byte addr var byte cont con %10100000 Control address of EEPROM addr = 17 Main: I2CREAD PORTA.0, PORTA.1, cont, addr, [B0] Get data to variable B0 Loop: goto Loop end Data address is 17
42
Description:
I2WRITE sends control and address data via I2C interface. We define 8-bit or 16-bit address while defining variable put to address parameter (in order to correctly define address size, we must have accurate information on device we are communicating with). B0 var byte addr var byte
Example:
43
end
The simplest form of instruction is shown on the picture above. Sample program below tests the button connected to RB0 - when the button is pressed program jumps onto the label Add where value of variable w is increased. If the button is not pressed, program jumps back onto the label Main.
44
Example:
w var byte
More complex form of instruction is program branching with the ELSE part of instruction.
w var byte Main : IF PORTB.0=0 THEN Add ELSE Subtract ENDIF goto Main Add W W 1
45
w var byte Main : IF PORTB.0=0 THEN W=W+1 ELSE W=W-1 ENDIF goto Main End
Modifier {I}{S} BIN{1..16} {I}{S} DEC{1..5} {I}{S} HEX{1..4} REP c/n STR ArrayVar {\n}
Sends binary number decimal number hexadecimal number character c repeated n times n character string
Before the first instruction is sent to LCD, program should wait for at least half a second for LCD to initialize. LCD display can be connected to PIC microcontrollers by either 4-bit or 8-bit bus. If 8-bit bus is used, all of 8 bits must be connected to the same port, while in the f 4 bit b ll 4 bit tb ith i th th l t fb t
46
case of 4-bit bus all 4 bits must be either in the upper or the lower part of byte. R/W line should be connected to ground if LCD is used only for data display. PIC BASIC assumes that LCD is connected to specific pins if DEFINE directives do not say otherwise. Default is 4-bit bus with lines DB4-DB7 connected to RA0-RA3, RS pin connected to RA4 and E pin connected to RB 3. Also, it is assumed that LCD is 2x16. For changing any of the default settings, appropriate DEFINE directives can be used. If LCD is connected to some other microcontroller lines it has to be defined with DEFINE directives, as shown in the following example.
DEFINE LCD_RSREG PORTB port Register select DEFINE LCD_RSBIT DEFINE LCD_EREG DEFINE LCD_EBIT DEFINE LCD_BITS DEFINE LCD_LINES 1 Register Select bit
PORTB Enable port 0 4 2 Enable bit bus size 4 or 8 bits number of LCD lines command delay in microseconds
Definitions above define 2-line LCD on 4-bit bus on the upper 4 bits of microcontroller port D. Register Select (RS pin) is on PORTD.2 and Enable is on PORTD.3. Every LCD controller is in charge of certain commands. Commands are sent by instruction: LCDOUT $FE, $Kod. List of commands is shown in table below.
47
Command $FE, 1 $FE, 2 $FE, $0C $FE, $0E $FE, $0F $FE, $10 $FE, $14 $FE, $C0 $FE, $94 $FE, $D4 Example:
Operation clear display Return home (beginning of the first line) Turn off cursor Underline cursor on Blinking cursor on Shifting cursor left Shifting cursor right set cursor to the beginning of the second line set cursor to the beginning of the third line set cursor to the beginning of the fourth line
B0 var byte B1 var byte Main: lcdout $FE, 1, Hello Clear display and print Hello
lcdout $FE, $C0 switch to second line lcdout B0 lcdout #B1 Loop: goto Loop end Display the value of B0 Display the value of B1 in ASCII code
Main: Lcdin $40, B0 Read data from LCD location $40 and store it into B0
48
Example:
let B0 = B1 * B2 + B3 B0 = B1 * B2 + B3 The two expressions are identical. The latter expression is missing command word let.
Example:
Main: lookdown B0, (01234567890ABCDEF), B1 convert hexadecimal character from B0 to a decimal value and store it into variable B1
49
Description:
LOOKDOWN2 searches the list of values and determines the presence of given value. If Search value matches some of the Value values, index of the appropriate constant is stored into Var.
If Search matches the first value of the list, Var set to zero. If it matches the second value of the list, Var is set to one, etc. If Search value isnt present in the list, Var remains unchanged. Optional parameter Test is used for testing if Search value is greater or lesser than a certain value. If > is used, index of the first matching constant is stored to Var. List of values can consist of 16-bit numbers, characters or variables. Every character of a string is treated as a separate ASCII value of that character (arrays of variables cannot be used with LOOKDOWN2 instruction). LOOKDOWN2 generates the code about 3 times greater than LOOKDOWN instruction does. Thus, when searching the list consisting of 8-bit constants and strings, use of LOOKDOWN is prefferrable.
Digit var byte Mask var byte Main: for i=0 to 9 Digit=i
Lookup Digit, [$3F, $06, $5B, $4F, $66, $6D, $7D, $07, $7F, $6F], Mask
PORTB=Mask
pause 500 delay allowing to see digits changing next i goto Main end Increase i by one Repeat the whole program
Gets
value
from
the
table
of
Instruction LOOKUP2 can be used for reading values from the table of values by index. If Index equals zero, Var attains the value of the first element in the list. If Index equals one, Var attains value of the second element in the list, etc. If Index is equal or greater than number of elements in the Look-up table Var remains unchanged. List of values can consist of 16-bit numbers, characters or variables. Every character of a string is treated as a separate ASCII value of that character. Arrays of variables cannot be used with LOOKUP2 instruction. LOOKUP2 generates the code about 3 times greater than LOOKUP instruction does. Thus, when searching the list consisting of 8-bit constants and strings, use of LOOKUP is prefferrable.
Example:
For B0=0, W0 will have value of 256 For B0=1, W0 will have value of 1024
For B0=2,3,... W0 will remain unchanged 51
4.35 NAP Turns off the processor for a short period of time
Syntax: Description: NAP period Instruction sets PIC microcontroller to low power mode (state of low energy consumption) for a short period of time. During this "nap", energy consumption is minimized. Stated periods are just approximations because these values were taken from watch dog timer and depend on chip and temperature: Period Delay [ms] 0 18 1 36 2 72 3 144 4 288 5 576 6 1152 7 2304
Example:
Main: nap 7 take a nap for 2.304 seconds Loop: goto Loop End
52
Main: output PORTB.7 Pin RB7 is output TRISB.0 = 0 Loop : goto Loop End Same effect as above
Parameter Pin is a variable containing the microcontroller pin connected to the element which has one-wire communication.
Parameter Mode is value defined by parameters of communication.
"Mode" bit 0 1 2
How it works 1 = sending the reset signal ahead of data 1 = sending the reset signal after data 0 = 8-bit data 1= 1-bit data
Parameters Var1 and Var2 are variables for containing the read data. Example:
Temperature var byte Main: OWIN PORTC.0, 0, [Temperature] PORTB=Temperature diodes read the temp. display temperature on port B
53
Parameter Pin is variable containing the microcontroller pin connected to the element which has one-wire communication. Parameter Mode is value defined by parameters of communication.
"Mode" bit 0 1 2 1= 1-bit data How it works 1 = sending the reset signal ahead of data 1 = sending the reset signal after data 0 = 8-bit data
Parameters Var1 and Var2 are variables for containing the read data. Example: Main :
sends
reset
signal
and
values
Example:
TRISB = 0 Main: PORTB = 255 pause 1000 Delay execution of next instruction line for 1 sec. PORTB = 0 pause 2000 Delay execution of next instruction line for 2 sec.
54
Description:
PAUSEUS stops the program for Period miliseconds. Period is 16-bit (WORD), allowing delay to be as long as 65 535ms (a bit over a minute). Unlike other delay instructions (NAP and SLEEP), PAUSE does not put the microcontroller to low power mode. PAUSEUS consumes more energy than PAUSE, but gets much more accurate timing. Minimal delay of PAUSEUS depends on the crystal frequency.
OSC 3 (3.58) 4 8 10 12 16 20
Minimal delay 20 us 24 us 12 us 8 us 7 us 5 us 3 us
PAUSEUS works with default 4MHz crystal frequency. If frequency differs from default it is Example: TRISB = 0
Main: PORTB = 255 pauseus 100 microsec PORTB = 0 pauseus 3450 goto Main End
55
Example:
B0 var byte skala var byte Main : FOR skala=1 TO 255 pot PORTA.0, scale, B0 IF B0>253 Then Over NEXT skala Over : PORTB=scale goto Main End display value of the scale on port B diodes read value of potentiometer on RA0
Example:
Main : pulsout PORTB.7, 100 goto Main End Generate 1ms impulse to RB7 pin
Example:
Main : pwm PORTB.7, 127, 100 Send pwm cycle with 50% of signal (ON) to RB7 goto Main End
Example:
READ 6, W.BYTE0 load 16-bit data READ 7, W.BYTE1 from addresses 6 and 7 to variable W Loop: goto Loop End
58
4.48 READCODE Reads 2 bytes (word) of program code from the address
Syntax: Description: READCODE Address, Variable READCODE reads program code from a given address and puts the result to 16-bit variable. PIC16F87X microcontroller family allows reading and writing program code while microcontroller is in operation. Wo var word Main : readcode 100, W0 Loop : goto Loop End load data from program FLASH memory, address 100 to var. W0
Example:
portb_on: PORTB=$FF return End Light all port B diodes return from subroutine
Description:
Although conditional SELECT-CASE branching can be made with multiple IF-THEN instructions, it is easier and more sensible to use this instruction in certain situations. Instruction allows "Expression" to be a constant, one of the constants or a comparison to a certain constant.
Example:
60
PORTB=B Pause 3000 CASE ELSE B=FF PORTB=B Pause 3000 END SELECT NEXT W END
The example above cycles numbers from 0 to 9 in the SELECT CASE branching. If W equals zero port B diodes will take value of 1. If W equals 1, 2 or 3 port B diodes will take value of 2. If W equals 4 or 5 port B diodes will take value of 255 because 4 and 5 havent been defined therefore, value from CASE ELSE part of the instruction is taken. If W is greater than 5, port B diodes will take value of 3.
Instead of numerical value ranging from 0 to 15, Mode can be a name if "modedefs.inc" library is included ahead.
Mode number 0 1 2 3 4 5 6 7
Baud rate 2400 1200 9600 300 2400 1200 9600 300
State
True
Inverted
SERIN instruction can include label (parameter "Label") which the program will jump onto if there is no data received during the specified time period (parameter "Timeout" - default value is 1ms).
61
There can be qualifier within brackets [] ahead of every data. SERIN must receive these bytes in correct order before receiving data words. If any received byte doesnt match next bytes qualifier, marking process begins anew - next received byte is compared to the first on the qualifying list. Qualifying content can be a constant, variable or character string. Every character in a string is treated as a separate qualifier. When qualifiers are set, SERIN tries to save data to variables. If there is character # ahead of variable SERIN converts decimal value to ASCII and stores the result in that variable. SERIN works with 4MHz oscillator by default. In order to achieve certain transfer rate with other oscillators, it is neccessary to use appropriate "DEFINE Osc" directive.
Example:
B0 var byte Main : Wait for character "A" to be received on serial line on pin RB0 and store next received character to variable serin PORTB.0, N2400, ["A"], B0 variable B0 lcdout B0 Display content of B0 on LCD
62
Mode number 0 1 2 3 4 5 6 7
Baud rate 2400 1200 9600 300 2400 1200 9600 300
State
True
Inverted
Optional "FlowPin" can be used to prevent eventual data loss in high speed transfers. If used, "FlowPin" is automatically set to regular state (depends on polarity from Mode parameter - table above) in order to allow transfer of every character. Mode can be used for defining baud rate and serial transfer parameters. Lower 13 bits determine baud rate. Bit 13 selects (non)parity check. Bit 14 selects inverted or true level, while bit 15 is unused. Transfer rate determines bit duration in microseconds. To determine bit duration for a given transfer rate, following equation is used : (1000000 / baud rate) - 20 Table below shows several standard transfer rates:
Baud Rate 300 600 1200 2400 4800 9600 19200 bit 0-12 3313 1646 813 396 188 84 32
Bit 13 enables parity check if bit 13 equals 1 and disables it for 0. For bit13 = 0 transfer format is 8N1. In case that parity check is needed, following directive should be used :
DEFINE SER2_ODD
Bit 14 selects data level of flow control pins. If bit 14 equals 0 data is received true, while bit14 = 1 receives inverted data.
63
(9600 baud, no parity check, true) (2400 baud, no parity check, inverted) (300 baud, parity check, inverted)
Optional label "ParityLabel" specifies label which program jumps onto if transfer error occurs (this label makes sense only if parity bit is on). "Timeout" and "Label" allow program to proceed from designated label if there is no data in specified time period. Waiting time is expressed in miliseconds. DEFINE directive allows transfer of data with size greater than 8, that is 7 with parity check. SER2_BITS allows transfer of data ranging from 4 to 8 bits. SERIN2 supports many different data modifiers that can be combined to allow various input data formats.
Modifier BIN{1..16} DEC{1..5} HEX{1..4} SKIP n STR ArrayVar\n{\c} WAIT ( ) WAITSTR ArrayVar{\n}
How it works Takes binary digits Takes decimal digits Takes hexadecimal digits Skips next n characters Takes the sequence of n characters that ends with the character c (optional) waits for character sequence waits for a string
If prefix BIN is used ahead of variable, ASCII character in binary value of variable will be received. For example, if we write BIN B0 and received value is "1000" B0 will take value of 8. If prefix DEC is used ahead of variable, ASCII character in decimal value of variable will be received. For example, if we write DEC B0 and received value is "123" B0 will take value of 123. If prefix HEX is used ahead of variable, ASCII character in hexadecimal value of variable will be received. For example, if we write HEX B0 and received value is "FE" B0 will take value of 254.
Key word SKIP followed by a number enables that many characters from input row t b ki d F l SKIP 4 ld ki 4 h t
64
to be skipped. For example, SKIP 4 would skip 4 characters. If key word STR is followed by variable of string type, number "n" and optional ending char, character string will be received. String length is defined with "n" or with appearing of final element of a string. Data bytes received usually go after one or more identification bytes. Identification bytes come within small brackets after WAIT. It means that the sequence of received bytes must match the sequence of identification bytes. Otherwise, if one of received bytes doesnt match following byte in identifier sequence, identification process starts anew - next received byte is compared to the first identification byte. Identification byte can be a constant, variable or array of constants. In the last case, every constant is treated as a separate identifier. WAITSTR is used in a similar way as WAIT, except for the fact that the key is character string instead of byte sequence. Instruction SERIN2 assumes that microcontroller clock works at 4MHz. In case of different oscillator it is necessary to make adjustment with following directive : DEFINE OSC.
Example:
wait for character "A" to be received to RB0 pin and store next received character to variable B0.
SERIN sends one or more values to a specified pin "Pin" using the standard asynchronous format 8N1 (8 data bits, no parity check and one stop bit). Transfer modes ("Mode") include :
65
Mode T2400 T1200 T9600 T300 N2400 N1200 N9600 N300 OT2400 OT1200 OT9600 OT300 ON2400 ON1200 ON9600 ON300
Mode number 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Baud Rate 2400 1200 9600 300 2400 1200 9600 300 2400 1200 9600 300 2400 1200 9600 300
State
Driven True
Driven Inverted
Open True
Open Inverted
Instead of numerical value from 0 to 15, Mode can be a name if "modedefs.inc" library is included ahead. If there is character # ahead of variable SEROUT converts decimal value to ASCII and sends it. For example, if B equals 34 then #B sends 3 and 4. SEROUT works with 4MHz oscillator by default. In case of different oscillator it is necessary to make adjustment with following directive : DEFINE OSC. In cases of slower receiving device, it is necessary to wait for a certain amount of time when sending next data. DEFINE directive enables delay ranging from 1 to 65 535 microseconds (0.001 to 65.535 miliseconds) between sending 2 characters. DEFINE CHAR_PACING 1000 1ms delay between 2 chars
Example:
B0 var byte Main: B0 = 25 13 to L serout PORTA.3, N2400, [#B0, 13] Send ASCII value of B0 and constant RA3 via serial line t L
66
SEROUT2 sends one or more values to pin determined with parameter "Pin". "Pin" is automatically designated output, while optional "FlowPin" is designated input. Optional "FlowPin" is used for indicating data loss at receiver. Level of permission depends on data transfer mode determined by "Mode". Optional parameters "Timeout" and "Label" allow program to proceed and in case that "FlowPin" doesnt change to state of transfer allowed in a given time period. Wait time "Timeout" is entered in miliseconds. In some cases transfer rate of SEROUT2 can be too high for receiving device. Then, it is more efficient to set delay between 2 characters using the "pace" parameter instead of using extra pin as "FlowPin". In this way, it is possible to provide sufficient delay when sending data. Mode is used to determine baud rate and important parameters of serial transfer. Lower 13 bits determine baud rate. Bit 13 selects (non)parity check. Bit 14 selects inverted or true level, while bit 15 is used to determine if connection is currently in transfer or not. Transfer rate determines bit duration in microseconds. To determine bit duration for a given transfer rate, following equation is used : (1000000 / baud rate) - 20 Table below shows several standard transfer rates:
Baud Rate 300 600 1200 2400 4800 9600 19200 bits 0-12 3313 1646 813 396 188 84 32
If set, bit 13 enables parity check. Transfer format is standard 8N1 (8 data bits, no parity check, one stop bit) and for bit13 = 1 format is 7E1 (7 data bits, parity bit and one stop bit). Bit 14 selects data level of "flow control" pins. If bit 14 equals 0 data is received true, while bit14 = 1 receives inverted data (this can used to avoid installation of RS232 i ti d i MAX232)
67
RS232 communication driver - MAX232). Bit 15 determines if data pin is still connected (bit15 = 0) or disconnected from data transfer line. This option is useful in case of connecting multiple devices to common serial line.
Some of standard settings include : Mode = 84 Mode = 16780 Mode = 27889 (9600 baud, no parity check, true) (2400 baud, no parity check, inverted) (300 baud, parity check, inverted)
DEFINE directive SER2_BITS allows transfer of data with size different than 8 (7 with parity check). SER2_BITS allows transfer of data ranging from 4 to 8 bits. Default value is 8 bits. SEROUT2 supports many different data modifiers that can be combined in order to allow various input data formats.
Modifier {I}{S} BIN{1..16} {I}{S} DEC{1.16} {I}{S} HEX{1..16} REP c\n STR ArrayVar\n{\c} How it works Sends binary digits
If prefix BIN is used ahead of variable, ASCII character in binary value of variable will be sent. For example, if we write BIN B0 and B0 = 8, bits 1000 will be sent serial. If prefix DEC is used ahead of variable, ASCII character in decimal value of variable will be sent. For example, if we write DEC B0 and B0 = 123, data "123" will be sent. If prefix HEX is used ahead of variable, ASCII character in hexadecimal value of variable will be sent. For example, if we write HEX B0 and B0 = 254, SEROUT2 will send "FE". REP followed by a character and a number of repeating provides more compact form of writing long strings of same characters. For example, REP "0"\4 stands for "0000" STR followed by variable of string type and an optional numerical parameter "count" executes sending of character string. String length is determined by "count" or by appearance of character "0" in a string. Optional parameters can be used ahead or behind BIN, DEC and HEX. In case th t "I" i d h d f f th t td t ill b i ith %@ #@ $@
68
that "I" is used ahead of any of these, output data will begin with %@, #@ or $@ in order to mark current value as binary, decimal or hexadecimal. In case that "S" (signed) is used ahead of BIN, DEC or HEX , output data will begin with "-" if highest data bit is set to 1. This allows transfer of negative values. You should bear in mind, though, that all mathematical and comparison operations work with unsigned numbers. Still, unsigned numbers arithmetic allows signed values as results. For example, in case of B0 = 9 - 10, DEC B0 gets value of "255", whereas SDEC B0 sends "1" after the transfer of the highest bit. BIN, DEC and HEX can be followed by a number. It is common practice to write numerical data in exact number of digits needed, so that leading zeros are erased and not sent. In case that BIN, DEC and HEX are followed by a number, SEROUT2 will always send that exact number of data, adding leading zeros if needed. For example, BIN6 8 sends BIN "001000", while BIN2 8 sends "00". All these modifies can be used simultaneously (i.e. ISDEC4 B0). Instruction SEROUT2 assumes that microcontroller clock works at 4MHz. In case of different oscillator it is necessary to make adjustment with following directive : DEFINE OSC
Example: B0 = 25 SEROUT2 PORTA.3, 16780, [DEC B0, 10] Send decimal value of variable B0 and "LineFeed" via serial line (2400 bauds) to pin RA3. B0 = 25 SEROUT2 PORTA.1, 84, ["B0=", IHEX4 B0] Send string "B=" and 4-character hexadecimal value of variable B0 to RA1 at 9600 bauds.
4 5 6 7
inactive on a logical zero. First, the highest bit is shifted. Data is read ahead of sending clock. Clock is inactive on a logical one. First, the lowest bit is shifted. Data is read ahead of sending clock. Clock is inactive on a logical one. First, the highest bit is shifted. Data is read after sending clock. Clock is inactive on a logical one. First, the lowest bit is shifted. Data is read after sending clock. Clock is inactive on a logical one.
Shifting frequency is about 50KHz, depending on oscillator used. Active state lasts for at least 2 microseconds. Using the directive DEFINE enables additional delay (up to 65.535 miliseconds) for slowing down the clock. DEFINE SHIFT_PAUSEUS 100 Slowing down the clock for additional 100ms
Example:
shiftin Data, Clock, MSBPRE, [RxData] Sends the contents of input SHIFT register to variable RxData so that the first bit is MSB.
Sends the contents of variables B0 and B1 to output SHIFT register so that the first transferred bit is MSB shiftout PORTA.0, PORTA.1, MSBFIRST, [W0\4] Sends 4 bits of variable W0 so that the first transferred bit is MSB Loop : goto Loop End
4.58 SLEEP Turns off the processor for a given time period
Syntax: Description: SLEEP Period Instruction puts the microcontroller to a state of low energy consumption for "Period" of seconds. "Period" is a 16-bit value allowing maximal delay of 65 535 seconds (about 18h). SLEEP uses the watchdog timer (WDT) with granularity about 2.3 seconds. RC oscillator is less temperature stable than system clock, making WDT somewhat less accurate. Main : sleep 60 Loop : goto Loop End Go to low power mode for next 60 sec
Example:
Description: Example:
Instruction stops the program execution by commencing the infinite loop. This instruction does not put the microcontroller to low power mode. Main : STOP Stop the program execution in this line Loop : goto Loop End
toggle PORTB.0 Change state of pin RB0 to high level Loop : goto Loop End
72
Description:
Instruction writes "Value" to a specified address of EEPROM. WRITE can only be used with PIC microcontrollers that have EEPROM built in chip. If 2-byte variable is being stored, two bytes are written in sequence : WRITE Address, Variable.BYTE0 WRITE Address, Variable.BYTE1
Example:
B0 var byte Main : B0 = $EA write 5, B0 Writes value $EA to location 5 of EEPROM Loop : goto Loop End
73
Example:
i Var byte Main : i=1 WHILE i< 10 i=i+1 PORTB = i Pause 1000 WEND goto Main End when i reaches 10 program stops and port B has value of 9
74
Chapter 5
SAMPLE PROGRAMS FOR SUBSYSTEMS WITHIN THE MICROCONTROLLER
Introduction 5.1 Using the interrupt mechanism 5.2 Using the internal AD converter 5.3 Using the TMR0 timer 5.4 Using the TMR1 timer 5.5 Using the PWM subsystem 5.6 Using the hardware UART subsystem (RS-232 communication)
Introduction
Every microcontroller is supplied with at least a few integrated subsystems - commonly, these include timers, interrupt mechanisms and AD converters. More powerful microcontrollers can command greater number of built-in subsystems. Some of frequently encountered systems are detailed in this chapter.
75
Button T is connected to the external interrupt input INT (pin RB0/INT) so that pressing the button is considered an interrupt occurrence. In order to see the change caused by interrupt LED diodes are connected to the pins RB6 and RB7. LED_run diode signalizes that the main program is being executed, while LED_ini diode signalizes the interrupt caused by pressing the button T. Following instructions are used in PIC BASIC programs which contain interrupt routine : On Interrupt goto Address Disable Enable Resume Defines the interrupt vector (address of interrupt routine)
Disables the interrupts Enables the interrupts Return to the main program after handling the event
Following example demonstrates usage of external interrupt INT located on pin RB0. At the same time, program gives an example how to handle multiple interrupt sources.
76
77 Program which handles interrupt must have the main loop (program) and an interrupt routine. Program in the main loop keeps
Potentiometer gives 0V in one terminal position and 5V in the other, so that digitalized voltage can take values ranging from 0 to 256 due to the fact that 8-bit conversion is used. The following program reads voltage on RA0 pin and displays it on port B diodes. If not one diode is on, result is zero and if all of diodes are on, result is 255.
78
At the very beginning, it is necessary to properly initialize 2 bit registers ADCON1 and ADCON0. Afterwards, only thing required is to set ADCON0.2 bit which initializes the conversion and checks ADCON0.2 to determine if conversion is over. After the conversion is over, result is stored into ADRESH and ADRESL where from it can be copied. Former example can also be carried out via ADCIN instruction. Following example uses 10-bit resolution and ADCIN instruction.
79
As one port is insufficient, LCD can be used for displaying all of the 10 bits of result. Connection scheme is on the picture below and appropriate program follows.
80
81
Before the main program, TMR1 should be enabled by setting the zero bit in T1CON register. Besides that, first bit of the register should be set to zero, thus defining the internal clock for TMR1. Besides T1CON, other important registers for working with TMR1 include PIR1 and PIE1. The first contains overflow flag (zero bit) and the other is used to enable TMR1 interrupt (zero bit). When TMR1 interrupt is enabled and its flag reset only thing left to do is to enable global interrupts (bit 7) and peripheral interrupts (bit 6) in the INTCON register. The following program illustrates use of TMR1 register for generating 10 seconds time period. Prescaler is set to 00 so there is no dividing the internal clock and overflow occurs every 65.536 ms. If variable "Brojac" is increased every time interrupt takes place, we can measure one minute period according to the variable "Brojac". If "Brojac" is set to 152, time will total 152*65.536 ms = 9.960 second.
83
defines channel on RC2 pin. Ratio_S_P : defines the ratio of on and off signals on pin. "0" defines continual off state, whereas "255" defines continual on state. All values within these limits define appropriate ratio of on and off signals on pin. (i.e. "127" gives 50% of 0V on output and 50% of 5V on output). Frequency : defines PWM signal frequency. Top frequency for any oscillator is 32767Hz.
The following example demonstrates use of PWM for getting various light intensities on LED diode connected to RC1 pin (PWM channel 0). Parameter defining ratio of on and off signals is continually increased in the for-next loop and takes value from 0 to 255, resulting in continual intensifying of light on LED diode. After value of 255 has been reached, process begins anew.
84
UART contains special registers for receiving and transmitting data as well as BAUD RATE generator for determining data transfer rate. The program below illustrates use of hardware serial communication subsystem (serial communication can also be software based on any of 2 microcontroller pins). Data received from PC is stored into variable B0 and sent back to PC as confirmation of successful transfer. Thus, it is easy to check if communications works properly. Transfer format is 8N1 and transfer rate is 2400 baud. In order to achieve communication, PC must have the communication software. One such program is part of the MicroCode studio. It can be accessed by clicking View and then Serial Communication Window. New window will appear on screen and can be used for adjusting transfer settings. First it is necessary to set transfer rate by clicking Baudrate on the left of the window (set it to 2400, because microcontroller is set to that rate). Communication port is selected by clicking one of the 4 available depending on port connected to a serial cable. After making adjustments, clicking Connect starts the communication. Type your message and click Send Message message is sent to the microcontroller and back, where it is displayed on the screen. 85
86
Chapter 6
SAMPLES WITH PIC16F84 MICROCONTROLLER
Introduction 6.1 LED diode 6.2 Button 6.3 Generating sound 6.4 Potentiometer 6.5 Seven-segment displays 6.6 Step motor 6.7 Input shift register 6.8 Output shift register 6.9 Software serial communication 6.10 Building light control
Introduction
This chapter gives detailed examples of connecting PIC16F84 microcontroller to peripheral components and appropriate programs written in BASIC. All of the examples contain electrical connection scheme and program with comments and clarifications. You have the permission to directly copy these examples from the book or download them from the web site http://www.mikroelektronika.co.yu/ .
The positive pole is connected to anode, while ground is connected to cathode. For matter of differentiating the two, cathode is marked by mark on casing and shorter pin. Diode will emit light only if current flows from anode to cathode; in the other case there will be no current. Resistor is added serial to LED diode, limiting the maximal 87
current through diode and protecting it from damage. Resistor value can be calculated from the equation on the picture above, where Ur represents voltage on resistor. For +5V power supply and 10 mA current resistor used should have value of 330. LED diode can be connected to microcontroller in two ways. One way is to have microcontroller "turning on" LED diode with logical one and the other way is with logical zero. The first way is not so frequent (which doesn't mean it doesn't have applications) because it requires the microcontroller to be diode current source. The second way works with higher current LED diodes.
88
The following example uses instructions High, Low and Pause to turn on and off LED diode connected to seventh bit of port B every half second.
89
6.2 Button
Button is a mechanical component which connects or disconnects two points A and B over its contacts. By function, button contacts can be normally open or normally closed.
Pressing the button with normally open contact connects the points A and B, while pressing the button with normally closed contact disconnects A and B. Buttons can be connected to the microcontroller in one of two ways: In the first case, button is connected in a way that logical one (+5V) remains on microcontroller input pin while button is not pressed. Resistor between a button and power voltage has role of holding the input pin in defined state when the button is not pressed (in this case a logical one). This is necessary as a protection from glitch on input pin that might cause misinterpretation of program, i.e. as if button is pressed when it is not.
When the button is pressed, input pin is short circuited to the ground (0V) which indicates change on input pin. Voltage has dropped from 5V to 0V. This change is interpreted by program as if button was pressed and part of program code tied to a button (for example turn on LED diode) is then executed. This way of defining pin states is called defining with "pull-up" resistors, associating that the line is held up on the logical one level. In the other case, button is connected in a way that logical zero remains on input pin. Now, resistor is between input pin and a logical zero, meaning that pressing the button brings logical one to input pin. Voltage goes up from 0V to +5V. Microcontroller program should recognize change on input pin and execute the specific part of program code. This way of defining pin states is called defining with "pull-down" resistors, associating that the line is held down on the logical zero level. 90
Common way to connect the button is with pull-up resistors, meaning that pressing the button changes pin state from logical one to logical zero. Following picture displays four button connected to the microcontroller using the pull-up resistors.
91
Problem that occurs when working with buttons is contact debounce in the moment when button is pressed. Debounce is consequence of the contact and heavily depends on the very button. One of the ways to solve the contact debounce problem is given in the following part of program code :
Pressing the Button0 causes the program to jump to address Wait0 where it remains in the loop until the button is released (this achieves that single button push is just once handled in program). When Button0 is released program continues executing instructions (in this case variable W is increased by one). Pressing Button1 causes the same effect, except that variable W is decreased by one. Problem might arise if an interrupt or some other source slows down the program execution, so that program finds itself on Wait0 or Wait1 lines after the button is released. This might cause program blocking until button is pressed again. In the following program for reading the button states, BASIC instruction Button is used which eliminates the contact debounce. The program reads buttons T0 and T1 which are connected to the pins RA0 and RA1, respectively. Pressing the button 0 executes part of program code which turns on LED diode on pin RB0. Pressing the button 1 executes part of program code which turns off LED diode on the same pin. The mentioned instruction is among the most complex instructions of BASIC program language. Besides few arguments that should be defined, instruction has an argument for setting the delay time between recognition of two different button pressures (the third argument). Its setting depends on the purpose of the button as well as mechanical properties of the button. Still, it came clear over time that maximal value of last argument represents the best solution for most applications, because of great disproportion in human reaction and microcontroller speed.
92
93
Buttons are connected to pins RA0, RA1 and RA2. Pressing any of these executes part of the code for generating impulse sequence on RA3 pin, which can be heard as one monotonous sound or a melody on mini speaker. Consecutive execution of instruction Sound with different parameters allows composing various melodies. In the following program, pressing the button T0 generates one monotonous sound on a mini speaker, while pressing the buttons T1 and T2 executes sequences of Sound instructions which can be heard as two different melodies on a mini speaker.
94
95
6.4 Potentiometer
In order to measure and display analog values, besides the microcontroller, it is necessary to have an AD converter. This can be an expensive solution if some less precise measuring is required, for example potentiometer voltage. For this reason PIC BASIC features the POT instruction for using the microcontroller without AD converter.
RC pair which consists of potentiometer (typical resistance in 5-50k range) and a 100nF capacitor is connected to RA0 pin. Reading the potentiometer is based upon measuring the time period between capacitor discharging and charging. Measuring scale ranges from 0 to 255 as if 8-bit AD converter was used. The following program reads potentiometer value in 0-255 range and displays it on LED diodes connected to the port B.
96
As seven-segment digits have better temperature features as well as visibility than LCD displays, they are very common in industrial applications. Their use satisfies all criteria including the financial one. Simple application would be displaying value read from a certain sensor.
97
One of the ways to connect seven-segment display to the microcontroller is given on a picture above. System is connected to use seven-segment digits with common cathode. This means that segments emit light when logical one is brought to them, and that output of all segments must be a transistor connected to common cathode, as shown on the picture. If transistor is in conducting mode any segment with logical one will emit light, and if not no segment will emit light, regardless of its pin state. If we use the scheme from the picture above, one of the ways to realize the display in BASIC could be the following program code :
98
Variables LEDDisp1 and LEDDisp2 are actually pins 1 and 0 of port A, which bases of transistors T1 and T2 are connected to. Setting logical one on those pins turns on the transistor, allowing every segment from "a" to "h", with logical one on it, to emit light. If there is logical zero on transistor base, none of the segments will emit light, regardless of the pin state. Tens digit is disabled at the very beginning of program, ahead of label Main (LEDDisp2=0). Purpose of the program is to display figures from 0 to 9 on the ones digit, with 0.5 seconds pause in between. In order to display any number, it's mask must be sent to port B. For example, if we need to display "1", segments "b" and "c" must be set to 1 and the rest must be zero. If (according to the scheme above) segments b and c are connected to the first and the second pin of port B, values 0000 and 0110 should be set to port B. These values which are set to port are commonly called "masks". Mask for number "1" is value 0000 0110 or $06 (hexadecimal). The following table contains corresponding mask values for numbers 0-9 : Digit 0 1 2 3 4 5 6 7 8 9 Seg. h 0 0 0 0 0 0 0 0 0 0 Seg. g 0 0 1 1 1 1 1 0 1 1 Seg. f 1 0 0 0 1 1 1 0 1 1 Seg. e 1 0 1 0 0 0 1 0 1 0 Seg. d 1 0 1 1 0 1 1 0 1 1 Seg. c 1 1 0 1 1 1 1 1 1 1 Seg. b 1 1 1 1 1 0 0 1 1 1 Seg. a 1 0 1 1 0 1 1 1 1 1 HEX $3F $06 $5B $4F $66 $6D $7D $07 $7F $6F
Program uses the instruction Lookup to apply an appropriate mask to numerical value. Instruction Lookup works very simply - it puts a character from a sequence, its position defined by numerical value Digit, to variable Mask. For example, Mask will take value $5B if Digit has value 2. In that manner, we can easily get mask for any decimal digit. Continual display of Mask (PORTB=Mask) for appropriate value of variable Digit, with 0.5sec pause, will produce an effect of digits rotating from 0 to 9. 99
Problem with multiplexing occurs when displaying more than one digit is needed on two or more displays. It is necessary to put one mask on one digit quickly enough and activate it's transistor, then put the second mask and activate the second transistor (of course, if one of the transistors is in conducting mode, the other should not work because both digits will display the same value). New program differs from the one above in converting 2-digits value to 2 masks, which are displayed in a way that human eye gets impression of simultaneous existence of both figures (this is the reason for calling it "multiplexing" only one display actually emits in any given moment). Let's say we need to display number 35. First, the number should be separated into tens and ones (in this case, digits 3 and 5) and their masks sent to port B. This separation can be done with instruction Dig. For example, Digit1= W dig 0 will extract ones digit from variable W and store it into variable Digit1. If 0 is substituted with 1, tens digit will be extracted. Following the same logic, 2 extracts number of hundreds, 3 number of thousands, etc.
This part of program code prints value 35 on two seven-segment displays. The rest of the program is very similar to the last example, except for having one transition caused by displaying one digit after another. This transition can be spotted when LEDDisp1 is being turned off and LEDDisp2 turned on with a new mask. Lookup table is still the same and may be called as a subroutine when needed. The multiplexing problem is solved for now, but the program doesn't have a sole purpose to print values on displays. It is commonly just a subroutine for displaying certain information. However, this kind of solution for printing data on display will make essence of the program much more complicated. This newly encountered problem may be solved by moving part of the program for refreshing the digits (part of the program code for handling the masks and controlling the transistors) to interrupt routine. The following program shows how to use interrupt for refreshing the display. Main program increases the value of variable W from 0 to 99 and that value is printed on displays. After reaching the value of 99, counter begins anew. 100
101
Interrupt initialized in this way will generate interrupt every time TMR0 timer changes state from 255 to 0. Every time interrupt takes place, interrupt routine will be executed so that human eye gets impression that both displays print values simultaneously. As can be seen from the program code, everything tied to displaying digits is moved to interrupt routine. However, part of the code for forming the masks to be displayed is in the special subroutine (Gosub Prepare) in order to make interrupt routine code as short as possible. Another reason for this kind of organization is also the need to create masks only when variable W is changed and not every time interrupt takes place. In the course of main program, programmer doesn't have to take care of refreshing the display nor anything about displays whatsoever. It is only necessary to call subroutine "Preparation" every time value that will be displayed changes. As 2-digit values don't satisfy most needs, the following step is adding two additional digits. Program for realization of 4 seven-segment displays is just an expansion of the program above. The main difference is in the part for separating values to ones, tens, hundreds and thousands.
102
103
Data transfer between shift registers and a microcontroller is serial. The following program reads states of input shift registers, transfers them to variable RxData and then displays the contents of RxData on diodes connected to port B. For data transfer between shift register and a microcontroller, BASIC instruction SHIFTIN is used.
104
105
When data is transferred to shift register, Latch signal sends it to output pins. The following program alternately turns on upper and lower LED diodes. For data transfer between shift register and a microcontroller, BASIC instruction SHIFTOUT is used.
106
107
The program above uses Serin and Serout instructions for sending and receiving data. Data received via Serin instruction is stored into variable B0 and sent back to PC via Serout as a confirmation of successful transfer. Any microcontroller I/O pin can be used for described data transfer.
108
109
110
Chapter 7
SAMPLES WITH PIC16F877 MICROCONTROLLER
Introduction 7.1 Keyboard 7.2 Driver for seven-segment displays - MAX7912 7.3 LCD display 7.4 Serial EEPROM 7.5 RS-485 7.6 12-bit A/D converter LTC1290 7.7 12-bit D/A converter LTC1257 7.8 16-bit electrical current D/A converter AD421 7.9 Real time clock PCF8583 7.10 Digital thermometer DS1820
Introduction
This chapter gives detailed examples of connecting PIC16F877 microcontroller to peripheral components and appropriate programs written in BASIC. All of the examples contain electrical connection scheme and program with comments and clarifications. You have the permission to directly copy these examples from the book or download them from the web site http://www.mikroelektronika.co.yu/ .
7.1 Keyboard
In more demanding applications that require greater number of buttons, it is possible to use buttons connected in matrix to keep microcontroller I/O lines free. The following sample includes scheme of connecting the keyboard and accompanying program which reads keyboard keys and prints the read value on LED diodes of port D.
111
The keys are connected into shared rows and columns. 10K resistors between input pins and the ground determine the state of input pins when the key is not pressed. It means that the logical zero is on input pins when the keys are not pressed. In order to avoid short-circuits between two pressed keys, 1K resistor is added to each row. Reading the keyboard is done by subroutine "ScanKeys". The keyboard is connected to port B, it's pins being designated as input for rows (RB7, RB6, RB5 and RB4) and output for columns (RB3, RB2 and RB1).
112
The program sets value of the last read key on port D. If none of the keys is pressed all diodes of port D are on. "*" and "#" are represented with values 10 and 11. The greatest task is on the subroutine ScanKey. It sets logical one on keyboard columns and then calls the subroutine Row which checks if any of the 4 keys in that columns is pressed (which is signalized by variable Flag). In case that one of the keys from the column is pressed, variable KeyPress takes value from 0 to 3 (zero for the first row of that column, one for the second row of that column, etc. ). By calling the appropriate Lookup table, real value of the key is stored into variable Result and then to variable OldResult where from it is displayed on port D. In case that no key is pressed value of variable is 12.
113
114
115
116
117
Besides these, there are control lines E (enable), R/W (read/write) and RS (register select) for a total of 7 lines. R/W signal is on the ground, because there is one-way communication toward the LCD display. Some displays feature built-in back-light that can be turned on with RD1 pin via PNP transistor BC557. The following program uses the BASIC instruction Lcdout for printing the data on LCD display. At the beginning of the program DEFINE directives are used to configure the LCD display.
118
119
EEPROM is connected to microcontroller via SCL and SDA lines. SCL line is clock for synchronizing the data sent via SDA line. Frequency for transferring the data via SCL and SDA lines goes up to 1MHz. BASIC instructions I2CWRITE and I2CREAD make reading and writing data to EEPROM pretty simple. To write or read data from EEPROM it is required to write an address of EEPROM (in this case $A2) and address of data in memory as parameters of instruction. EEPROM address is formed in the following way :
I2C communication allows connecting multiple devices on one line. Therefore, bits A1 and A0 have an option of assigning addresses to certain I2C devices by connecting the pins A1 and A0 to the ground and +5V (one I2C line could be EEPROM on address $A2 and, say, real time clock PCF8583 on address $A0). R/W bit of address byte selects the operation of reading or writing data to memory. More detailed data on I2C communication can be found in the technical documentation of any I2C device. The following program uses the instruction I2CWRITE to write data from variable EE_byteOut to EEPROM, and then uses the instruction I2CREAD to transfer the same data from EEPROM to variable EE_byteIn and display it on port D diodes.
120
121
7.5 RS-485
Communication between two devices is easiest to achieve via serial RS232 communication. However, there are certain limitations of this type of communication. First of all, it is meant for local devices in 10-15m radius. The second drawback is that it can be used with only one device (for example, only one mouse can be connected to one COM port of PC). RS-485 communication goes past these shortcomings, supporting up to 32 devices (even 128) with maximal network length of up to 1500m. The example of connecting 485 interface is shown on the picture below.
The role of the line interface LTC485 is similar to MAX232 interface with serial communication (adjusting the level). Using the shielded wire is not necessary, but is recommended for reducing the glitch. Ending resistor Rt should set the specific impendence on the line and usually has value about 100-200 ohms. With lines shorter than 300m, there is no need for ending resistor. Resistors Rb are placed in order to avoid incorrect reading when all the drivers are in receiving mode. Value of these resistors should be 680 ohms if they are placed on single device or 4K7 if they are placed on more than 8 devices in the network. RS485 is a half-duplex communication which uses 2 lines (marked as A and B) for data transfer. The information if data on the receiver side equals binary one or not can be read from the voltage difference of lines A and B. If voltage difference between lines A and B exceeds 200mV data is binary one and if it is lower than -200mV data is binary zero. This method proved very efficient for eliminating great deal of glitch which can occur on the line. As data transfer commences via two lines, organization of sending and receiving the data must be regulated to avoid interference of data on the line. Direction of data (sending or receiving) is determined by state of input pins RE and DE of line interface RS485. When states of pins are RE=0 and DE=1, line interface is set to the receiving mode. When states change to RE=1 and DE=0 line interface changes to the sending mode. One of the typical solutions for RS485 communication is master/slave communication, where one master device takes over the control while other slave devices get the address which upon they can be called. Communication is initiated by master device sending the same N byte message to all slave devices and going to receiving mode. This N bye sequence contains the address of the specific slave device that is to receive data. Address is commonly located at the beginning of the sequence and consists of one byte (8 bits). When all of the slave devices receive the sequence, they extract the address from it and compare it to their own identification address. Slave device with matching address sends its address to the master device as a confirmation of successful transfer and receives data, while other slave devices return to the receiving mode. Master device receives the address of the mentioned slaved device and that ends the transfer between master and slave devices. In case that slave device does not send its address in some specified (Time out) period of time, master will declare that slave device inactive. This time out period ranges from 10ms to 100ms. The following picture shows format of the sequence that master sends to slave devices.
122
Newer systems consist of PC as master and multiple microcontroller slave devices. One such network is shown on the picture below.
As there is no output for RS485 on PC it is necessary to create RS232 to RS485 converter, while the microcontroller can be directly connected to LTC485 line interface. For physical connection of master and slave devices in RS485 network, RS485 interfaces other than LTC485 may be used - for example, SN75176 manufactured by Texas Instruments. The following program is an example of connecting one master and up to 8 slave devices. Role of the master is given to the PC which is connected to the network via RS232/RS485 converter. Slave devices are PIC16F877 microcontrollers which are connected to the network via line RS485 interface LTC485 and each one of them owns unique address given as number in 0-7 range. In order to make data received from the master "visible", diodes are 123
connected to port B of every PIC. In the sample, master changes the states of LED diodes on the slaves devices. The following picture represents a window of PC software for communication with PICs via RS485 line.
When the button "Send to slave" is clicked, PC sends the address of slave device from the field "Address of slave device" to the RS485 network and it also sends the states of LED diodes as they are set in the group "Set LED's" (total of 2 bytes). All of the PICs receive the address and LED states, but only one of them actually changes LED diode state. That PIC answers by sending its address to PC in 50ms as confirmation of successful receipt and marks the end of the transfer between PC (master device) and PICs (slave devices). In case that PIC does not answer in the expected 50ms, PC will interpret it as if PIC with specified address is not present in the network and will report an error (data transfer is serial, asynchronous at 9600 bauds). Communication with PICs is software based via instructions SERIN2 and SEROUT. The instruction SERIN2 expects a data that matches the address of slave device (in this case, "1" ASCII). Upon receiving the address, next received data is stored into variable B0, it's contents being displayed on port B LED diodes.
124
125
126
127
128
129
130
131
132
133
134
135
136
Appendix A
PIC BASIC AND MPLAB
Introduction A.1 Installation of the program / MPLAB A.2 Connection of PIC BASIC and MPLAB A.3 Toolbar
Introduction
MPLAB is a Windows programming package that facilitates writing and the development of the program. The easiest way to describe it would be to characterize it as a development environment for some standard programming language intended for PC programming. Using MPLAB technically facilitates some of the operations which all the way up to the appearance of the IDE environment, were operating out of the command line with very big number of parameters. Nevertheless, out of different tastes, some programmers even today prefer standard editors and compilers operating out of the command line. In any case the written code is very manifest and provided with a relatively well-provided HELP menu (the abbreviation IDE was born out of the initials Integrated Development Environment).
The grouping of the files belonging to the same project (Project Manager) The creation of the program and its elaboration (Text Editor) Simulator of the code whereby its work on the microcontroller is simulated.
137
Besides there exist support for Microchips products such as PICStart Plus i ICD (In Circuit Debugger). As this book doesnt rely upon them, they'll be mentioned as options only.
Compatible PC of 486 class or higher Microsoft Windows 3.1x or Windows 95 and more recent Windows OS versions VGA graphic card 8MB of memory space (32 MB recommended) 20MB space on hard disk The mouse
To start MPLAB it is necessary to install it first, which is understood as a process of copying of MPLAB files from CD onto the hard disk of the PC. On each newly opened window there is button for going back to the previous window so mistakes should not represent any problem. The installation itself flows similarly as those of almost all Windows programs. The welcome screen pops up first and then you have the option choice and the installation menu in order to finally get the message that your installed program is ready to be started.
Steps in the installation: 1. 2. 3. 4. 5. 6. 7. The starting of the Microsoft Windows Put the Microchip CD disk into the CD ROM Click onto the START in the lower left corner of the screen and choose the RUN option Click onto the BROWSE and select CD ROM drive for your PC On the CD ROM find the directory under the name of MPLAB Click onto the SETUP.EXE and then on the OK button Click once again on OK button in the RUN window
After these seven consecutive steps the installation will start. The following pictures explain the meaning of single steps in the installation process.
138
At the very beginning it is necessary to choose those components of MPLAB with which we are going to work. As it is supposed that there are no original Microchips hardware additions such as programming devices or emulators, only the MPLAB environment, Assembler, Simulator and the instructions for use will be installed.
139
The second supposition is that the OS will be Windows 95 (or some more recent version), so that in the selection of the assembler language is taken out everything that is connected to DOS operating system. However if you nevertheless wish to work in DOS, it is necessary to perform the deselecting of all the options connected with Windows, and choose the corresponding DOS components.
Selection of the assembler and OS As it is normal for any program, MPLAB should be installed into a defined directory. This option can be changed into any directory on any hard disk of your PC. Unless you have some specific reason, it should be left on the selected location.
140
The next option is necessary for the users who already had some previous MPLAB version (different from one that is being installed). It's purpose is to save all the file copies that are subject to change upon the transition to an updated version. In our case the selection of NO assumes that the installation in course is the first one.
The option necessary to the users who install the new version of MPLAB over some already existing installation
The start menu is the set of the pointers onto the programs opened by the click onto the START button in the lower left corner of the screen. It is necessary to leave this option exactly as it is offered, since MPLAB is going to be started from here.
141
Location mentioned next is related to the part of MPLAB which will not be explained here as it is insignificant for users. By selecting an apposite directory, MPLAB will keep all the files in connection with the linker in that directory.
142
Every Windows program has the system files, usually stored in the same directory as the Windows itself. After numerous installations, the Windows directory has a tendency of becoming too big and encumbered. Therefore, some of the programs permit their system files to be kept in the same directory as the program itself. MPLAB is one such program so that the option below should be selected.
Following all steps up to now after pressing the button Next the installation is under way
The installation itself is brief and the course of the copying can be monitored on the small screen in the right corner.
When the installation is terminated, two dialog boxes are present on the screen one for the last information concerning corrections and the version of the program, the other greeting one. If the text files (Readme.txt) are opened they should be closed.
The last information concerning version and the corrections on the program By clicking on the Finish button the installation of the program is thereby terminated.
144
You just start the MPLAB and choose Install Language Tool from the Project menu. The dialog box where the corresponding options is to be set, the manufacturer first, (whereby directly in the next option comes the list of compilers by the same manufacturer) and accordingly the compiler itself in our case Pic Basic Pro Compiler- and exactly as the one on the picture bellow will appear then. At the end on should click at the option browse and find PBP.EXE file on the disk (in this case C: PBP\). By clicking on OK the basic settings are completed.
Start MPLAB and choose the Install Language Tool from the Project menu.
Next step is the creation of the project that is done in a standard way by selecting New Project from the Project menu and by assigning the project name e.g. probe.pjt. A special care is to be given to the project storage location. The new project and all its components must be located in the same directory as PicBasic Pro! For this case, the project must be stored in C:/PBP.
Creating project by selecting New Project from Project menu and assigning the project name as, e.g. probe.pjt.
145
By clicking OK the new window Edit Project appears. In Language Tool microEngeneering Labs is to be selected (answer the incoming question with OK). It is, hence, necessary to click on probe [.hex] in the lower part of the window whereby the option Node Properties is activated.
The New window Edit Project for the definition of the manufacturer. Choose microEngeneering Labs
The purpose oh this window is to set the microcontroller for which the program is written. By clicking Change button, the new window for choosing the available microcontrollers appears. As an option, Editor only is to be left in the absence of any available Microchips tools (this option states the use of MPLAB as a shell for PIC Basic compiler). Bu clicking Node Properties the window shown on the picture below appears. Choose "PM" version in the assembler selection. Clicking the OK returns us to the previous window.
146
The Add Node button is active now, and through it the name to the file with basic program is assigned. It is in our case, probe.bas. it is to take notice that the present action is only assigning name of the file into the project. Its actual creation is done in next step.
Window for naming the program in writing. Opening of the file is done in next step.
So far we defined microcontroller and the programming language. It still remains to open the file, write the code and register it under the name given in previous step. (proba.bas). By clicking File-> New the window in which the basic program will be written appears. Before we start the program writing, file must be registered with the command File-> Save as, file
147
name being obviously proba.bas. The code writing can start now. The program here serving as an example is a very simple one and its only function is to make the diode on a port B twinkle.
Upon finishing the code writing, the click on PROJECT-> Build All is performing the compilation of the program. Unless there have been some errors, the obtained file is C:/PBP/probe.hex readable into the microcontroller.
148
A.3 Toolbar
Since MPLAB is composed of several separate parts, each of them possesses its own toolbar. However, there exists a toolbar being a sort of a combination of all the others, which may be considered as a common one. This toolbar is sufficient for our needs so it will be the explained in details. On the picture bellow this toolbar is given with the brief explanations of the icons. Out of the limited format of this book, the basic toolbar is displayed as the free one and in a standard position is always bellow the menu, displaced horizontally along the entire screen.
If, for whatever reason, currently used toolbar does not respond, upon clicking this icon the next toolbar becomes available. The change goes into circle so that upon the 4th click, the same toolbar is obtained again.
149
If the current toolbar for some reason does not respond to a click on this icon, the next One appears. Changeover is repeated so that on the fourth click we will get the same toolbar again. Icon for opening a project. Project opened in this way contains all screen adjustments and adjustment of all elements which are crucial to the current project. Icon for saving a project. Saved project will keep all window adjustments and all Parameter adjustments. When we read in a program again, everything will return to the screen as when theproject was closed. Searching for a part of the program, or words is operation we need when searching Through bigger assembler or other programs. By using it, we can find quickly a part of the program, label, macro, etc. Cutting a part of the text out. This one and the following three icons are standard in all Programs that deal with processing textual files. Since each program is actually a common text file, those operations are useful. Copying a part of the text. There is a difference between this one and the previous icon. With cut operation, when you cut a part of the text out, it disappears from the screen (and from a program) and is copied afterwards. But with copy operation, text is copied but not cut out, and it remains on the screen. When a part of the text is copied, it is moved into a part of the memory which serves For transferring data in Windows operational system. Later, by clicking on this icon it can be 'pasted' in the text where the cursor is. Saving a program (assembler file). Start program execution in full speed. It is recognized by appearance of a yellow status line. With this kind of program execution, simulator executes a program in full speed until it is interrupted by clicking on the red traffic light icon. Stop program execution in full speed. After clicking on this icon, status line becomes gray again, and program execution can continue step by step. Step by step program execution. By clicking on this icon, we begin executing an instruction from the next program line in relation to the current one. Skip requirements. Since simulator is still a software simulation of real work, it is possible to simply skip over some program requirements. This is especially handy with instructions which are waiting for some requirement following which program can proceed further. That part of the program which follows a requirement is the part that's interesting to a programmer. Resetting a microcontroller. By clicking on this icon, program counter is positioned at the beginning of a program and simulation can start. By clicking on this icon we get a window with a program, but this time as program memory where we can see which instruction is found at which address. With the help of this icon we get a window with the contents of RAM memory of a microcontroller. By clicking on this icon, window with SFR register appears. Since SFR registers are used in every program, it is recommended that in simulator this window is always active. If a program contains variables whose values we need to keep track of (ex. counter), a Window needs to be added for each of them, which is done by using this icon. When certain errors in a program are noticed during simulation process, program has to be corrected. Since simulator uses HEX file as its input, so we need to translate a program again so that all changes would be transferred to a simulator. By clicking on this icon, entire project is translated again, and we get the newest version of HEX file for the simulator.
150
Appendix B
MicroCODE STUDIO
Introduction B.1 Installation of the PIC Basic Pro compiler B.2 Installation of a MicroCODE studio B.3 Connecting MicroCODE Studio and PBP compiler B.4 Connecting MicroCODE Studio and the programmer B.5 Code writing and compilation in MicroCODE studio
Introduction
Although the code writing can be done with the simplest editor and compiled in command line (those who had programmed in DOS probably remember well those acrobatics) using special editors appropriate for programming language is far better. Such specialized editors are called Integrated Development Environments - IDE. Using them makes code writing easier as the programmer is able to supervise which variables, labels or similar program elements have already been used. At the same time, they make command words bold and even write them in another color rendering thereby program more intelligible. The option for automatic call up of the programmer is also available together with many other facilities. Simply put, having those facilities without using them is like climbing on foot to the 13th floor of a building with elevator.
151
The first window after the installation starts. It is necessary to click on button Next
Next question is whether you accept the license and copyright rules or not. By accepting these rules by clicking on the Yes button, the installation goes forward. The next image corresponds to that phase of the installation.
The directory for editor location is the next question. In case of failed statement of the directory, the installation is to be effectuated in C:\ProgramFiles\Mecaniqe.
152
The choice of an installation directory. The best choice is to leave the option by default. It is necessary to click on OK button in order to proceed
The name and address of directory is without any special meaning for further programming. The real issue is the available memory space on the hard disk or on the need for keeping all items associated with a single program in the same directory. The next question refers to the name of programming group. The name already offered corresponds to the program name so it should be left as such.
The program group is to be named MicroCodeStudio. Clicking on Next, the installation goes on
153
154
To connect MicroCode Studio and PBP compiler a new window is to be opened. Its done by clicking on the Options from the View menu. If the compiler is already copied into a hard disk directory clicking on the Find Automatically button whereupon will the program itself search for the directory with compiler through the hard disk. When the program finds the compiler, above the button the path C:\PBP will appear above the button Find Automatically.
Connecting MicroCode studio and PBP compiler. If the PBP compiler is already copied into a directory on a hard disk, it is enough to click on the Find Automatically button and the program will find it on its own
155
Beside the path to the compiler, it is still necessary to define the path to the include data file. By clicking on Add the paths C:/PBP and C:/PBP/inc are added within Includes.
Include data files are necessary for successful compilation of the program. Clicking the Add, the new window appears with the inc directory into which the PBP compiler is copied
156
Options window after setting the path to the compiler and include data files. Notice that there are include data files in the very C:\PBP directory so that their path should be specified as well
This step finishes the setting part referring to the compiler. MicroCode studio is now ready for program reading and compiling.
The setting of the programmer starts by clicking on Programmers whereupon two distinct options appear, one for adding of programmer into the list and another for their removal. The programmer that is to be used here ranks as the simplest economic programmers of PIC microcontrollers that are available at the moment. The name of this programmer is ICprog and it uses the serial pin of the computers port in order to communicate with the microcontroller (more details can be found in the special appendix contained in this book).
157
Before installing the programmer, it has to be copied in a directory on the hard disc, e.g. C:\Programmer. Clicking the Add new Programmer, the brief procedure of selecting the path to programmer begins. The first step is writing the name of the programmer or any abbreviation that could bear resemblance to it. As Icprog programmer is used it is logical to name it ICprog.
In this option the name of the programmer is to be written. It can well be any of the names bearing resemblance to the programmer we wish to install
158
The next step is the writing of the exact name of the programmer. It is very important not to make any mistake; otherwise the program will not be able to locate it on a hard disk.
In this option, the exact name of the executive data file of the programmer is to be indicated. In this case its icprog.exe
Finally, by clicking on Find Automatically, the program then finds on its own the path towards the programmer.
By clicking on Find Automatically the program finds the path to the programmer on its own
159
Option to define additional parameters is next. Nevertheless, it is to be omitted due to the fact that it will be used in a later phase of the operation when the longer programs are written and the program name is not changed very often. Clicking on Finished overrides this option.
The option to define the additional parameters of the programmer is not to be used here; therefore it is to be omitted by clicking on Finished
The window Option out of the View menu with the set parameters for the compiler and the programmer now looks like exactly as on the image bellow. Thereby all relevant settings of the MicroCode Studio are finished.
Window Option with all the parameters for the compiler and the programmer set
160
Besides the setting of the compiler and the programmer, there are somewhat less important settings as that of an editor. Since those parameters are already well set we will not take them into consideration now.
The menu line contains all standard submenus as File, Edit, Search, View and Help. The toolbar contains but a few basic icons and their purpose we will not explain in details. What separates the MicroCode studio from the other development environments is its simplicity and legibility. Its most important part is located in the left part by the name Code Explorer. When necessary, that part of the window can be shut down by clicking on View Code Explorer
161
although it is recommended to leave it as it is for it contributes to the better legibility and organization of the program. The code writing is done in the right part of the window. The process of code writing itself is largely facilitated by thickening of the commands, and by the excellent solution for the complicated commands with the greater number of parameters as button command is. Namely, after writing of this command and the first empty (blank) character, the yellow frame with all parameters of the respective command appear. Upon having written the code, by clicking on icon Compile Only (in triangular shape on the right side) the compilation of program starts. If an error occurs, its reported in a special part at the bottom of the window. By clocking on Error, the cursor is positioned exactly at the row in which the error occurred. After correction, the program is compiled as long as the compilation process becomes successful. If the programmer is already configured, then the icon right next to the Compile Only can be used instead, which will, upon a successfully accomplished compilation, call the programmer.
Clicking on the icon in the port form, the special window for examining the serial connection with the microcontroller opens. The Serial communication window serves for the serial communication between PC and the microcontroller. An additional option exists which enables the change of all the transfer parameters such as the port on which the microcontroller is attached, the transfer rate or the transfer format.
162
163