Microcontroller based applied digital control (D. Ibrahim, 2006)
.pdf
SOME POPULAR PIC MICROCONTROLLERS |
73 |
|
|
AN7 |
|
|
AN6 |
|
|
AN5 |
|
|
AN4 |
|
A/D |
AN3 |
|
converter |
AN2 |
|
|
AN1 |
|
|
AN0 |
|
|
|
|
CHS2:CHS0
Figure 3.19 A/D converter block diagram
inputs can directly be applied to these inputs and the A/D converter generates 10-bit digital signals. The A/D module has four registers:
A/D result high register (ADRESH);
A/D result low register (ADRESL);
A/D control register0 (ADCON0);
A/D control register1 (ADCON1).
The bit definitions of the ADCON0 register are shown in Figure 3.20. This register controls the operation of the A/D converter. The conversion frequency, A/D channels, the A/D status and the conversion command are set by this register.
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
ADCS1 |
ADCS0 |
CHS2 |
CHS1 |
CHS0 |
GO/DONE |
– |
ADON |
|
|
|
|
|
|
|
|
Bit 7-6: ADSC1:ADSC0 A/D converter clock selection 00: fosc/2
01: fosc/8
10:fosc/32
11:frc
Bit 5-3: CHS2:CHS0 analog channel select bits 000: Select channel 0 (AN0)
001: Select channel 1 (AN1) 010: Select channel 2 (AN2) 011: Select channel 3 (AN3)
100:Select channel 4 (AN4)
101:Select channel 5 (AN5)
110:Select channel 6 (AN6)
111:Select channel 7 (AN7)
Bit 2: GO/DONE A/D conversion status bit
1: A/D conversion in progress (setting it starts the A/D conversion)
0: A/D converter not in progress (cleared by hardware when conversion is complete)
Bit 1: Not used
Bit 0: A/D on bit
1: A/D module is operating 0: A/D module is shut
Figure 3.20 ADCON0 bit definitions
74 |
THE PIC MICROCONTROLLER |
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
|
ADFM |
– |
– |
– |
PCFG3 |
PCFG2 |
PCFG1 |
PCFG0 |
|
|
|
|
|
|
|
|
|
Bit 7: ADFM A/D result format
1: Right-justified. Six most significant bits of ADRESH are cleared to 0 0: Left-justified. Six least significant bits of ADRESL are cleared to 0
Bit 6-4: Not used
1: Enable EEPROM write complete interrupt 0: Disable EEPROM write complete interrupt
Bit 3-0: PCFG3-PCFG0 A/D port pin configuration
Figure 3.21 ADCON1 bit definitions
The ADCON1 register configures the functions of the A/D input pins and is used to select the A/D converter reference voltage. The bit definitions of ADCON1 are shown in Figure 3.21. Bit 7 of ADCON1 is called the ADFM bit and controls the format of the converted data. When set to 1, the 10-bit result is right-justified and the six most significant bits of ADRESH are read as 0. When ADFM is cleared to 0, the 10-bit result is left-justified with the six least significant bits of ADRESL read as 0. Bits 0–3 of ADCON1 are used to configure the A/D converter input pins as shown in Figure 3.22.
Note that Vref+ and Vref− in Figure 3.22 are the A/D converter positive and negative reference voltages, respectively. The programmer has the choice of using an external reference voltage, but in most applications Vref+ is programmed to be equal to Vdd (the supply voltage) and Vref− is programmed to be equal to Vss (the supply ground).
The A/D conversion operation must be started by setting the GO/DONE bit of register ADCON0. The end of conversion can be detected in one of two ways. The easiest method is to poll the GO/DONE bit continuously until this bit is cleared. The result is then available in register pair ADRESH:ADRESL. The second method is to program the device to generate interrupts when a conversion is complete.
PCFG3: |
AN7 |
AN6 |
AN5 |
AN4 |
AN3 |
AN2 |
AN1 |
AN0 |
Vref+ |
Vref− |
PCFG0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
0000 |
A |
A |
A |
A |
A |
A |
A |
A |
VDD |
VSS |
|
|
|
|
|
|
|
|
|
|
|
0001 |
A |
A |
A |
A |
Vref+ |
A |
A |
A |
RA3 |
VSS |
0010 |
D |
D |
D |
A |
A |
A |
A |
A |
VDD |
VSS |
0011 |
D |
D |
D |
A |
Vref+ |
A |
A |
A |
RA3 |
VSS |
0100 |
D |
D |
D |
D |
A |
D |
A |
A |
VDD |
VSS |
0101 |
D |
D |
D |
D |
Vref+ |
D |
A |
A |
RA3 |
VSS |
0110 |
D |
D |
D |
D |
D |
D |
D |
D |
VDD |
VDD |
|
|
|
|
|
|
|
|
|
|
|
0111 |
D |
D |
D |
D |
D |
D |
D |
D |
VDD |
VSS |
|
|
|
|
|
|
|
|
|
|
|
1000 |
A |
A |
A |
A |
Vref+ |
Vref– |
A |
A |
RA3 |
RA2 |
1001 |
D |
D |
A |
A |
A |
A |
A |
A |
VDD |
VSS |
1010 |
D |
D |
A |
A |
Vref+ |
A |
A |
A |
RA3 |
VSS |
1011 |
D |
D |
A |
A |
Vref+ |
Vref– |
A |
A |
RA3 |
RA2 |
1100 |
D |
D |
D |
A |
Vref+ |
Vref– |
A |
A |
RA3 |
RA2 |
1101 |
D |
D |
D |
D |
Vref+ |
Vref– |
A |
A |
RA3 |
RA2 |
1110 |
D |
D |
D |
D |
D |
D |
D |
A |
VDD |
VSS |
1111 |
D |
D |
D |
D |
Vref+ |
Vref– |
D |
A |
RA3 |
RA2 |
A = analog input D = digital input
Figure 3.22 A/D converter input pin configuration
EXERCISES 75
The steps required for doing an A/D conversion are listed below:
Configure the A/D converter module.
◦Configure analog pins and reference voltage.
◦Select A/D input channel.
◦Select A/D conversion clock.
◦Turn on A/D module.
Configure A/D interrupts (if required).
Start A/D conversion.
Set GO/DONE bit of ADCON0 to 1.
Wait for conversion to complete.
Poll the GO/DONE bit until it is clear or wait for an A/D interrupt.
Read A/D converter result from ADRESH and ADRESL.
Repeat the above as required.
3.4 EXERCISES
1.Explain the basic features common to all PIC microcontrollers.
2.Explain how a PIC microcontroller can be reset using an external push-button switch.
3.Draw the circuit diagram of a minimum PIC system using a 4 MHz crystal.
4.Draw the circuit diagram of a minimum PIC system using a resistor and a capacitor to generate a clock frequency of about 2 MHz.
5.Explain the differences between a crystal and a resonator. Which one would you use if precision timing is required?
6.What is a register file map? Where can it be used?
7.A PIC16F84 microcontroller is to be used in a system. Port A pins RA0 and RA2 are required to be inputs and all port B pins outputs. Determine the values to be loaded into the port A and port B direction registers.
8.Explain the differences between the PIC16F84 and the PIC16F877 microcontrollers.
9.How many banks are there in the PIC16F877? Why are there more banks than in the PIC16F84?
10.Explain where an A/D converter can be used. How many A/D converter channels are there on the PIC16F877? What are the resolutions of these channels?
11.Explain the steps necessary to read data from an A/D channel on the PIC16F877 microcontroller.
12.You are required to generate timer interrupts at 120 µs intervals using a 4 MHz crystal as the timing device. Determine the value to be loaded into timer register TMR0. What will be the pre-scaler value?
13.Describe the steps necessary to operate the A/D converter to read analog data from channel AN2. What is the format of this data? How can you right-justify the data?
76 THE PIC MICROCONTROLLER
FURTHER READING
[Anon, 2005a] Microchip Data on CDROM. Microchip Technology Inc., www.microchip.com. [Anon, 2005b] Microchip Databook. Microchip Technology Inc., www.microchip.com. [Anon, 2005c] PICC Lite User’s Guide. Hi-Tech Software, www.htsoft.com.
[Ibrahim, 2002] Ibrahim, D. Microcontroller Based Temperature Monitoring and Control. Newnes, London, 2002. [Iovine, 2000] Iovine, J. PIC Microcontroller Project Book. McGraw-Hill, New York, 2000.
[James, 1977] James, M.R. Microcontroller Cookbook PIC and 8051. Newnes, London, 1977.
[Kalani, 1989] Kalani, G. Microprocessor Based Distributed Control Systems. Prentice Hall, Englewood Cliffs, NJ, 1989.
4
Programming PIC Microcontrollers in C
Microcontrollers have traditionally been programmed using the assembly language. This language consists of various mnemonics which describe the instructions of the target microcontroller. An assembly language is unique to a microcontroller and cannot be used for any other type of microcontroller. Although the assembly language is very fast, it has some major disadvantages. Perhaps the most important of these is that the assembly language can become very complex and difficult to maintain. It is usually a very time-consuming task to develop large projects using the assembly language. Program debugging and testing are also considerably more complex, requiring more effort and more time.
Microcontrollers can also be programmed using the high-level languages. For example, it is possible to use BASIC, PASCAL, FORTRAN and C compilers to program the PIC family of microcontrollers. Most of these compilers generate native machine code which can be directly loaded into the program memory of the target microcontroller.
In this chapter we shall look at the principles of programming PIC microcontrollers using the C language. C is one of the most popular programming languages used today and there are several C compilers available for the PIC microcontrollers. We shall look at how to program the PIC microcontrollers using one of the popular C compilers known as the PICC Lite C compiler, developed by the Hi-Tech Software.
PICC Lite is an efficient compiler which can be used to program the PIC16F84, PIC16F877, PIC16F627 and PIC16F629 family of microcontrollers. This compiler is distributed free of charge and is a subset of the PICC programming language, manufactured by Hi-Tech Software. PICC Lite is equipped with an integral editor with syntax highlighting, which makes program development relatively easy. A large number of library functions are provided which can easily be used by the programmer. Some of the reasons for choosing the PICC Lite compiler are:
support for floating point arithmetic;
availability of a large number of mathematical functions;
direct support for LCD displays;
ease of availability.
As a programming language, C is similar to PASCAL and FORTRAN where values are stored in variables and programs are structured by operating on variables and by defining and calling
Microcontroller Based Applied Digital Control D. Ibrahim
C 2006 John Wiley & Sons, Ltd. ISBN: 0-470-86335-8
78 PROGRAMMING PIC MICROCONTROLLERS IN C
functions. Program flow is controlled using if statements, while statements and loops. Inputs can be read from switches, keyboards and sensors, and outputs can be sent to LEDs, LCDs, screens, sound devices, motors and so on. Related data can be stored in arrays or structures.
The program development cycle using C is relatively straightforward. High-level user programs are normally developed on a PC using the integral editor. The code is then compiled and if there are no errors the object code is downloaded into the program memory of the target PIC microcontroller. Depending on the type of microcontroller used, either a flash memory programmer device or an EPROM programmer device is used to load the program memory of the target microcontroller. This cycle is repeated until the developed program operates as required.
4.1 PICC LITE VARIABLE TYPES
The PICC Lite compiler supports the following basic data types:
bit
unsigned char
signed char
unsigned int
signed int
long
unsigned long
float
double
4.1.1 Bit
A bit can store a Boolean variable (a 0 or a 1). Bit variables are usually used as flags in programs. In the following example, the variable answer can only take the values 0 or 1:
bit answer;
4.1.2 Unsigned Char
An unsigned char is 8 bits wide and can store a single ASCII character or an integer number in the range 0 to 255 (bit pattern ‘11111111’). In the following example, variables count and initial are declared as unsigned char and count is assigned a decimal value 120, and initial is assigned the ASCII character ‘T’:
unsigned char count, initial; count = 120;
initial = ’T’;
PICC LITE VARIABLE TYPES |
79 |
4.1.3 Signed Char
A signed char (or simply char) is 8 bits wide and is used to store signed decimal numbers in the range –128 (bit pattern ‘10000000’) to +127 (bit pattern ‘01111111’). In the following example, the variable first is assigned the decimal value −180, and the variable count is assigned a decimal value 25:
signed char first, count; first = -180;
count = 25;
4.1.4 Unsigned Int
An unsigned int is 16 bits wide and can be used to store decimal numbers in the range 0 to +65 535 (bit pattern ‘1111111111111111’). In the following example, the variable result is assigned the decimal value 28 512:
unsigned int result; result = 28512;
4.1.5 Signed Int
A signed int (or simply int) is 16 bits wide and it is used to store signed numbers in the range −32 768 (bit pattern ‘1000000000000000’) to +32 767 (bit pattern ‘0111111111111111’). In the following example, the variable count is declared as a signed int and the negative value − 25 000 is assigned to it:
signed int count; count = -25000;
4.1.6 Long
A long data type is 32 bits wide and is used to store large signed integer numbers. The range of numbers that can be stored in a long are −2 147 483 648 to +2 147 483 647. In the following example, the variable sum stores the integer value 45 000:
long sum; sum = 45000;
4.1.7 Unsigned Long
An unsigned long data type is 32 bits wide and is used to store large unsigned integer numbers. Numbers in the range 0 to 4 294 967 295 can be stored in an unsigned long data type. In the following example, the large number 3 200 000 is stored in the variable cnt:
unsigned long cnt; cnt = 3200000;
80 PROGRAMMING PIC MICROCONTROLLERS IN C
4.1.8 Float
A float data type is 24 bits wide and is used to store noninteger fractional numbers (i.e. floatingpoint real numbers). Variables of this type are implemented using the IEEE 754 truncated 24-bit format. In this format a number consists of:
a 1-bit sign bit;
an 8-bit exponent which is stored as excess 127 (i.e. an exponent of 0 is stored as 127);
a 15-bit mantissa. An implied bit to the left of the radix point is assumed, which is always 1, unless the number is zero itself, when the implied bit is 0.
The value of a number in float representation is given by:
(−1)sign × 2(exponent−127) × 1.mantissa
For example, the real number 48.03125 is represented by the following bit pattern:
0 10000100 100 0000 0010 0000
Here the exponent equals 132, and the mantissa is
1 + 2−1 + 2−10 = 1.500 976 562 5.
Multiplying the mantissa by 32 gives the required number 48.03125.
In the following example, the variable temp is loaded with the fractional number 2.35:
float temp; temp = 2.35;
4.1.9 Double
A double data type is 24 bits or 32 bits wide (selected during the compilation) and is used to store double-precision floating-point numbers. The truncated IEEE 754 24-bit format is used in 24-bit mode. The 32-bit format is based in the IEEE 754 32-bit standard where the number consists of:
a 1-bit sign bit;
an 8-bit exponent stored as excess 127;
a 23-bit mantissa.
In the following example, the variable temp stores the number 12.34567 as a double-precision floating-point number:
double temp; temp = 12.34567;
4.2 VARIABLES
In C, a variable must be declared before it can be used in a program. Variables are usually declared at the beginning of any block of code. Every variable has a name and a value – the
COMMENTS IN PROGRAMS |
81 |
name identifies the variable and the value stores data. There is a rule governing what a variable name can be. Every variable name in C must start with a letter, and the rest of the name can consist of letters, numbers and underscore characters. In C, lower-case and upper-case variable names are different. Also, keywords such as if, while and switch cannot be used as variable names.
Examples of valid variable names are:
Xx |
|
sum result |
total |
outfile |
infile x1 |
Xz |
Total result |
sum1 highest no |
no 1 |
cnt |
COUNT |
A variable declaration begins with the data type, followed by the name of one or more variables, and is terminated with the semicolon character. For example,
int sum, low, high;
Values can be stored in variables after the declaration of the variable types:
int low, high, sum; unsigned char name; low = 0;
high = 200; sum = 10; name = ’R’;
Variables can also be initialized when they are declared. For example, the above statements can also be written as:
int low = 0; int high = 200; int sum = 10;
unsigned char name = ’R’;
4.3 COMMENTS IN PROGRAMS
Comments can be used in programs for clarification purposes. The comment lines are ignored by the compiler. There are two ways of including comments in a program. One way is to use double slashes (‘//’) before a comment line. Any characters after the double slashes (‘//’) are ignored by the compiler. For example,
j = |
0; |
// |
clear variable j |
sum |
= sum + 1; |
// |
increment variable sum |
//
// The following code clears variables k and m
//
k = 0; m = 0;
Comment lines starting with the ‘//’ characters can be used anywhere in a program.
Another way of creating comment lines in a program is to start the comments with the characters ‘/*’, insert the comments, and then terminate the comments with the ‘*/’ characters.
82 PROGRAMMING PIC MICROCONTROLLERS IN C
This method has the advantage that the comments can extend to several lines. An example is given below:
/* This program adds two integer numbers
x and y. The result is stored in variable z. z is then incremented by 1
*/
z = x + y; z = z + 1;
The two methods of creating comments can be mixed in a program. For example,
/* This program multiplies two integer numbers x and y and stores the result in variable z
*/ |
|
z = x*y; |
// Multiply the numbers |
4.4 STORING VARIABLES IN THE PROGRAM MEMORY
In PICC Lite, variables are normally stored in the RAM memory of the target microcontroller since the value of a variable is expected to change during the running of a program. There are many variables whose values do not change during the lifetime of a program, and these variables are known as constants. It is possible to store the constants in the flash (or EPROM) program memory of the target microcontroller. The size of the RAM memory is very limited in many microcontrollers and storing some of the variables in the program memory releases valuable RAM memory locations. A variable is stored in the program memory if it is preceded by the keyword const. In the following example, the variable sum is stored in the RAM memory, but the variable pi is stored in the program memory of the microcontroller:
float sum; const float pi;
Any data type can be stored as a constant in the program memory.
4.5 STATIC VARIABLES
Static variables are usually used in functions. A static variable can only be accessed from the function in which it was declared. The value of a static variable is not destroyed on exit from the function, instead its value is preserved and becomes available again when the function is next called. Static variables can be initialized like other normal variables, but the initialization is done once only when the program starts. Static variables are declared by preceding them with the keyword static. For example,
static int sum;
