Embedded C Programming Embedded C Programming Techniques and Applications of C and PIC® MCUS Mark Siegesmund AMSTERDAM • BOSTON • HEIDELBERG • LONDON • NEW YORK • OXFORD PARIS • SAN DIEGO • SAN FRANCISCO • SINGAPORE • SYDNEY • TOKYO Newnes is an imprint of Elsevier Newnes Newnes is an imprint of Elsevier The Boulevard, Langford Lane, Kidlington, Oxford OX5 1GB, UK 225 Wyman Street, Waltham, MA 02451, USA First edition 2014 Copyright © 2014 Elsevier Inc. All rights reserved No part of this publication may be reproduced, stored in a retrieval system or transmitted in any form or by any means electronic, mechanical, photocopying, recording or otherwise without the prior written permission of the publisher Permissions may be sought directly from Elsevier’s Science & Technology Rights Depart- ment in Oxford, UK: phone ( 44) (0) 1865 843830; fax ( 44) (0) 1865 853333; email: + + [email protected]. Alternatively you can submit your request online by visiting the Elsevier web site at http://elsevier.com/locate/permissions, and selecting Obtaining permission to use Elsevier material Notice No responsibility is assumed by the publisher for any injury and/or damage to persons or property as a matter of products liability, negligence or otherwise, or from any use or operation of any methods, products, instructions or ideas contained in the material herein. Because of rapid advances in the medical sciences, in particular, independent verification of diagnoses and drug dosages should be made British Library Cataloguing in Publication Data A catalogue record for this book is available from the British Library Library of Congress Cataloging-in-Publication Data A catalog record for this book is available from the Library of Congress ISBN: 978-0-12-801314-4 For information on all Newnes publications visit our web site at books.elsevier.com Printed and bound in United States of America 14 15 16 17 18 10 9 8 7 6 5 4 3 2 1 Introduction Microcontrollers are computers on a chip. When they power up they start running a pro- gram from internal program memory, also called ROM for read only memory, or Flash. Microcomputers are found in appliances, toys, automobiles, and computer peripherals, such as a keyboard or mouse, and are finding their way in as support electronics for almost every- thing electronic from battery chargers to RADAR systems. The Microchip PIC® microcontrollers have become the most popular choice for new designs based on their high speed, of up to 70 million instructions per second as of this writing; low cost, some under $1; and large number of interfaces like USB, Ethernet, and analog signals. The C programming language, originally developed by AT&T Labs by authors Brian Kernighan and Dennis Ritchie, known as K&R C, became an international standard by ANSI in 1989, known as C89. A new standard derived from C defined the C language and was ++ released in 1998. C has some complex language elements that make it impractical for use ++ on a microcontroller as opposed to a desktop PC. C is the most commonly used language for programming microcontrollers. C is in a category of computer languages called high order languages. High order languages use a tool called a compiler to convert the C text files to a machine readable file. The first part of this book emphasizes the C language. Previous experience with a program- ming language will help but is not required. Formal definitions of the language elements are used and all areas of the language that apply to microcontrollers are covered in detail. Starting with Chapter 15, this book covers the PIC® microcontroller, its peripherals, and how to use those peripherals from C in detail. Prior knowledge of basic electronics to interface to hard- ware devices will help, but is not required to understand this book. There are variations in the C language extensions between compiler vendors and between microcontroller families. Throughout the book are indications where there may be compat- ibility issues between compilers and/or processors. Each chapter will also supply hints for good programming practices, including documentation. Exercises and quizzes are provided Introduction for each chapter to help solidify the concepts learned. This book uses examples ready to compile using the CCS C compiler. It is the most popular compiler for the Microchip PIC® processors. Trademarks: PIC® MCU, dsPIC® DSC, and MPLAB® are registered trademarks of Microchip Technology, Inc., in the USA and other countries. xvi CHAPTER 1 C Overview and Program Structure C Source Code This is what C source code looks like: This program may look very cryptic to you now. When you have finished reading this book and doing the experiments, this program and much more complex ones will no longer seem cryptic. As you read the next few chapters, you can refer to this program to see how the topics relate to this program. For now, let’s make some observations about the overall look of the program. Comments Comments help anyone (including you) who reads your code understand what it does. There are two styles. E mbedded C Programming.http://dx.doi.org/10.1016/B978-0-12-801314-4.00001-6 1 Copyright © 2014 Elsevier Inc. 2 Chapter 1 /* */ Comments between /* and */ (can span multiple lines, but may not be nested) // Comments between // and end of line (one line only). The compiler ignores all comments. Both styles are shown in the sample program. Program Structure C programs are made up of compilation units, sometimes called translation units. A compila- tion unit is a set of files that are compiled together by a compiler. For most examples in this book we will be using a single compilation unit. A compilation unit is made up of global data and functions. A function is a callable group of code that in some other languages is referred to as a procedure or subroutine. Functions are made up of local data accessible only to the function and of statements within the function. C Preprocessor Directives An interesting feature of C is that it has what is referred to as a preprocessor. Think of the pre- processor as a tool that goes through the code first and makes some modifications to what is actually compiled. Preprocessor directives start with a # and occupy the entire line. They will be covered in more detail in Chapter 3. In the above example the #include d irective causes whatever lines are in the file (e3.h) to appear at this spot in the code for the compilation. For example, if you created a file named delay.inc and put in the file one line: delay_ms(500); then you could replace the two delay lines in the above program with #include <delay.inc> and the program would compile exactly the same. In the first step of compilation the compiler preprocessor would read the delay.inc file when it got to that line and replace the #include with delay_ms(500); where the #include were. The preprocessor can be a powerful feature in C that can increase program readability, maxi- mize code reuse, and significantly help in program maintenance. As we examine the sample program shown, you see the first line is a preprocessor directive to include the e3.h file. It is very common for the first non-comment line in a program to include a file with various project- and/or hardware-specific definitions. The .h extension (for header) is frequently used for this kind of file. In our case all the declarations needed for the E3 hard- ware are in this include file. Functions Next we find a function definition for “main”. All programs must have exactly one function named main(). This is where the program begins execution. When referring to a function www.newnespress.com C Overview and Program Structure 3 name in this book we will follow the name with () so it is clear that it is a function name. The void before the name indicates this function returns nothing and the void inside the () indicates this function gets nothing from the caller. The { and } are grouping symbols. All functions start and end with these symbols. Functions will be dealt with in detail in Chapter 7; however, to lay a foundation for what they are, consider some examples of a function being used: x=sin(y); sin is a function with one argument and a return value x=sin(y*3.1415/180); the argument may be any expression x=180*sin(y)/3.1415; the return value may be used in an expression. Declarations The “int i” is a data declaration for the variable named with the identifier i. int indicates the variable is an integer. In this case i may only be used inside the main() function. If this line was above the start of the function (outside the function) then i could be accessed by other functions. The range that a variable is accessible from is referred to as the variable scope. Scope will be covered in more detail in Chapter 4. Statements and Expressions The for line is a statement. Statements are executed at run time. This particular statement has three expressions within. Expressions will be covered in Chapter 5 and statements in Chapter 6. The quick overview of the for statement is: It executes the first expression once i=1 Repeats the following: Tests the second expression and exits the loop if false i<=10 Executes the statement following the ) The third expression is executed. i=i+1 In this example the four lines are executed 10 times with the variable i going from 1 to 10 and then, when 11, the loop stops because 11 <= 10 is false. Expressions are some combination of constants, variables, operators, and function calls. Expressions always have a resulting value. Some simple examples of an operator are + - * / and the very special =. In our case since we have four statements to execute in the for we need to group them together with the { and }. This is called a compound statement. The braces may contain zero or more statements. Without those, only the output_high() function would be called in the loop 10 times. Then the other three lines would execute once afterwards. www.newnespress.com 4 Chapter 1 Each of the four lines in our loop is a function call. These functions are not defined by the programmer but rather are functions built into the compiler. Function calls are recognized by the ( following the function name. The expression(s) inside the () of a function call is the data passed into a function. These are called arguments in the call and parameters in the function. In C a special case of a valid statement is any expression followed by a ;. Note that just because it is valid does not mean it makes sense. For example, this is a valid C statement: 1+2; However, it does not do anything. Some compilers might do the addition and that may take some time but nothing more is done. A good compiler will throw a warning on this line because the programmer might have made a typo. A ; with no expression before it is a special case of a statement called the null statement. It does nothing. In C there is not an assignment statement as in some other languages, but rather an assignment operator, the =. Consider: x=3; This is an expression x = 3 consisting of a variable, operator, and constant. With the ; it makes a statement. It always assigns the value on the right side (rvalue) to the variable on the left side (lvalue). Time The ms in delay_ms is milliseconds. Time units frequently used in programs are: ns nanosecond 0.000,000,001 seconds us microsecond 0.000,001 seconds ms millisecond 0.001 seconds For example, there are 1 million microseconds in 1 second. Typing Accuracy Typing accuracy is very important when creating C source code. A punctuation mark, either typed by mistake or omitted, can cause a lot of head scratching because your program will not compile. The compiler sees exactly what you type. For example, if the { was missing on the for line then the compiler would trigger an error when it got to the } line four lines down from where the actual error was. The ; that follows many statements and declarations is important to help the compiler to know when a definition or statement ends. It is never used at the end of a preprocessor www.newnespress.com C Overview and Program Structure 5 directive that starts with #. Missing or extra ; or { can create confusing error messages. A good C editor will highlight matching { } and () and as well as highlight syntactical ele- ments to prevent errors as you type. Text Formatting Formatting white spaces such as spaces, tabs, carriage returns, etc., are ignored by the c ompiler. Formatting makes code readable to us. White space, resulting from laying out a program so it appears better organized, is a good thing. This comes from using spaces, tabs, and blank lines. Use tabs for indentation instead of several spaces. The number of spaces per tab is usually adjustable. Three spaces per tab work well. Notice the lines inside the above function are indented and the lines inside the loop are further indented. Indentation and other white space are optional, but highly recommended. There is no right or wrong as far as the c ompiler is c oncerned. Some companies will have companywide coding standards that will specify indentation, comments, maximum function size, and other readability items. Compatibility Notes The // comment is a C construct not supported by all C compilers. ++ Most C Compilers are sensitive to case. For example, Output_High() would not be rec- ognized but output_high() is. By default, the CCS C compiler is not case sensitive. To make it case sensitive, you must use a #case preprocessor directive. Built-in functions like output_high() and delay_ms() are not in the C standard. These are unique to the CCS C compiler. Summary • Programs are made up of one or more compilation (or translation) units. • Compilation units have preprocessor directives that are resolved before anything else. • Comments and most white space are ignored. • A compilation unit is a file with some number functions and global data declarations in any order. • Functions have local data declarations and statements all enclosed in { }. • Functions may return data and the caller may pass data known as arguments to the caller and parameters to the function. • Groups of statements may be enclosed in { } to make a compound statement. • Some statements have expressions within them. • A statement may be any expression followed by a ;. • Expressions are made up of constants, variables, operators, and function calls and always evaluate to some value. www.newnespress.com