PROGRAMMING PIC MICROCONTROLLERS IN C:ASCII CONSTANTS

ASCII CONSTANTS

The PICC Lite compiler supports a number of ASCII constants which can be used in programs instead of their numeric values. The following are constants the frequently used:

Programming PIC Microcontrollers in C-0114

Character constants are used by enclosing them in single quotes. For example, the variable

temp can be assigned the null character by writing:

temp = ’’;

ARITHMETIC AND LOGIC OPERATORS

The PICC Lite compiler supports a large number of arithmetic and logical operators. The most commonly used operators are summarized below:

Programming PIC Microcontrollers in C-0115

Some of the operators are unique to the C language and need further clarification. The pre- increment and post-increment operators and their equivalents are:

Programming PIC Microcontrollers in C-0116

It is important to realize that if the operator occurs after a variable name in an expression, the value of the variable is used in the expression, and then the variable is changed afterwards. Similarly, if the operator occurs before the variable name, the value of the variable is changed before evaluating the expression and then the expression is evaluated:

Programming PIC Microcontrollers in C-0117

In C, these logical connectors employ a technique known as lazy evaluation. This means that the expressions evaluate left to right and the right expression is only evaluated if it is required. For example, false && false is always false and if the first expression is false there is no need to evaluate the second one. Similarly, true || true is always true and if the first expression is true the second one is not evaluated.

An example is given here to clarify the use of the operators.

Example 4.1

sum and count and total are two 8-bits-wide unsigned char type variables. If sum = 65 and count = 240, find the values of the following expressions:

Programming PIC Microcontrollers in C-0118

Programming PIC Microcontrollers in C-0119Programming PIC Microcontrollers in C-0120

 

PROGRAMMING PIC MICROCONTROLLERS IN C:BANK1 QUALIFIER AND ARRAYS

BANK1 QUALIFIER

The bank1 type qualifier is used to store static variables in RAM bank 1 of the microcontroller. By default, variables are stored in bank 0 of the RAM. In the following example, the static integer variable temp is stored in bank 1:

static bank1 int temp;

ARRAYS

An array is a collection of variables of the same type. For example, an integer array called

results and consisting of 10 elements is declared as follows:

int results[10];

As shown in Figure 4.1, each array element has an index and the indices starts at 0. In this example, the first element has index 0 and the last element has index 9. An element of the array is accessed by specifying the index of the required element in a square bracket. For example, the first element of the array is results[0], the second element is results[1], and the last element is results[9]. Any element of an array can be assigned a value which is same type as the type of the array. For example, the integer value 25 can be assigned to the second element of the above array as:

results[1] = 25;

Initial values can be assigned to all elements of an array by separating the values by commas and enclosing them in a curly bracket. The size of the array should not be specified in such declarations. In the following example, odd numbers are assigned to the elements of array results and the size of this array is set automatically to 10:

int results[] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19};

The elements of an array can be stored in either the RAM memory or the program memory of a PIC microcontroller. If the array elements never change in a program then they should be stored in the program memory so that the valuable RAM locations can be used for other purposes. Array elements are stored in the program memory if the array name is preceded by the keyword const. In the following example, it is assumed that the array elements never change in a program and thus they are stored in the program memory of the microcontroller:

const int results[] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19};

Arrays can also store characters. In the following example, the characters COMPUTER is stored in a character array called device:

Programming PIC Microcontrollers in C-0110

In this example, the size of array device is set to 8 and the elements of this array are:

Programming PIC Microcontrollers in C-0111

Another way of storing characters in an array is as string variables. Strings are a collection of characters stored in an array and terminated with the null character (ASCII 0). For example, the characters COMPUTER can be stored as a string in array device as:

unsigned char device[] = ’COMPUTER’;

In this example, the array size is set to 9 and the last element of the array is the null character,

i.e. the elements of array device are:

Programming PIC Microcontrollers in C-0112

Arrays can have multiple dimensions. For example, a two-dimensional array is declared by specifying the size of its rows followed by the size of its columns. In the example below, a two-dimensional integer array having three rows and five columns is declared. The array is given the name temp:

int temp[3][5];

This array has a total of 15 elements as shown in Figure 4.2. The first element (top left-hand) is indexed as temp[0][0] and the last element (bottom-right) is indexed as temp[2][4]. Values can be loaded into the array elements by specifying the row and the column index of the location to be loaded. For example, integer number 50 is loaded into the first row and third column of array temp:

Programming PIC Microcontrollers in C-0113

 

PROGRAMMING PIC MICROCONTROLLERS IN C:PERSISTENT VARIABLES AND ABSOLUTE ADDRESS VARIABLES

PERSISTENT VARIABLES

Normally, the initial values of variables are cleared to zero when the program starts up (i.e. whenever reset is applied to the microcontroller). The persistent qualifier prevents a variable from being cleared at start-up. In the following example, the variable max is declared persistent and as a result its value is not cleared after a reset:

persistent int max

ABSOLUTE ADDRESS VARIABLES

It is possible to declare a variable such that it holds the address of an absolute location in the microcontroller memory. This is done by typing the character ‘@’ after the name of the variable. For example,

unsigned char Portbit @ 0×06

In this code, the variable Portbit is assigned the absolute hexadecimal address 0 × 06. It is important to realize that the compiler does not create a location for the variable Portbit, it simply assigns the variable to the specified absolute address.

The bit data type and absolute address variables can be used together to access individual bits of a register. For example, the PORTA register is at absolute address 5. We can declare a variable called PA1 to access bit 1 of PORTA as follows:

unsigned char PORTA @ 0×05; bit PA1 @ (unsigned)&PORTA*8+1;

 

PROGRAMMING PIC MICROCONTROLLERS IN C: STATIC VARIABLES AND VOLATILE VARIABLES

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;

VOLATILE VARIABLES

A variable should be declared volatile whenever its value can be changed by something beyond the control of the program in which it appears, such as an interrupt service routine. The volatile qualifier tells the compiler that the value of the variable may change at any time without any action being taken by the code the compiler finds nearby. All I/O based variables and variables shared by the main code and interrupt service routines should be declared volatile. In the following example, the variable count is declared volatile:

volatile int count;

 

PROGRAMMING PIC MICROCONTROLLERS IN C:STORING VARIABLES IN THE PROGRAM MEMORY

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:

Programming PIC Microcontrollers in C-0109

 

PROGRAMMING PIC MICROCONTROLLERS IN C:COMMENTS IN PROGRAMS

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,

Programming PIC Microcontrollers in C-0107

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.

This method has the advantage that the comments can extend to several lines. An example is given below:

Programming PIC Microcontrollers in C-0108

 

PROGRAMMING PIC MICROCONTROLLERS IN C:PICC LITE VARIABLE TYPES

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

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;

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’:

Programming PIC Microcontrollers in C-0098Signed 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:

Programming PIC Microcontrollers in C-0099

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:

Programming PIC Microcontrollers in C-0100

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:

Programming PIC Microcontrollers in C-0101

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:

Programming PIC Microcontrollers in C-0102

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:

Programming PIC Microcontrollers in C-0103

Float

A float data type is 24 bits wide and is used to store noninteger fractional numbers (i.e. floating- point 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.

Programming PIC Microcontrollers in C-0104

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:

Programming PIC Microcontrollers in C-0105

 

PROGRAMMING PIC MICROCONTROLLERS IN C:VARIABLES

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 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:

Programming PIC Microcontrollers in C-0106

 

PROGRAMMING PIC MICROCONTROLLERS IN C

Microcontrollers have traditionally been programmed using the assembly language. This lan- guage consists of various mnemonics which describe the instructions of the target microcon- troller. 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 disad- vantages. 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 functions. Program flow is controlled using if statements, while statements and loops. In- puts 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 pro- grams 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.