Introduction to C Notes

Embed Size (px)

Citation preview

  • 8/12/2019 Introduction to C Notes

    1/15

    1

    Introduction to C Notes

    Introduction

    This set of notes is to assist you in getting started with microcontrollers for your ECE2100 labs.

    A microcontroller is a very small computer on a chip. The microcontroller chip not only contains logic circuits, arithmetic circuits and registers, but it also contains various types of memories and peripherals such a timers (to time tasks), Analog to Digital converters , Digital to Analog converters , PWM (Pulse Wave Modulation) modules and peripherals to decode Quadrature signals coming from a motor etc.

    In these labs you will use the C programming language to program a microcontroller . You will

    not be required to write C programs from scratch; instead you will be modifying and adding to programs we have already written for you. The syntax of the MATLAB scripting language is superficially similar to the C programming language so you should have little difficulty in understanding the statements of the C programming language .

    The PC application you will use to write , edit, run and debug programs in C is called Code

    Composer Studio (CCS). You will be using version 5 of this software (CCSv5). Applications like CCS run on your PC and have multiple interactive windows for editing , managing projects and debugging and are known as IDEs (Integrated Development Environments ).

    This document will introduce you to those basic concepts of the C programming language which are needed to follow your labs.

    Texas Instruments C2000 F28x Peripheral Explorer Kit:

    You will be using the versatile TMS320F28335 microcontroller manufactured by Texas Instruments (TI). This microcontroller has an onboard floating point unit as well as peripherals suitable for filter design and motor control . In our labs the TMS320F28335 microcontroller will be hosted on a control card that will be plugged into Texas Instruments C200 Peripheral Explorer Kit. This kit is an evaluation board designed to allow for experimentation with many of the peripherals available on the TMS320F28335 microcontroller . The kit (without the control card hosting the microcontroller chip) is shown in Fig. 1 below. Fig. 2 shows the kit with the control card installed. You use a USB cable to connect the kit (using the USB connector on the

    left of the board in Fig. 1) to the USB connector on your PC running CCS. Power is provided to the board via. the USB connection. Make sure that the switch SW1 (upper left of the board, Fig. 1) is toggled to the position shown in the figures.

  • 8/12/2019 Introduction to C Notes

    2/15

    2

    Fig. 1

    Fig. 2

    TMS320F28335 microcontroller

    Control Card

    USB Connector

    Switch SW1

    USB Connector

    Switch SW1

    Slot for the Control Card

  • 8/12/2019 Introduction to C Notes

    3/15

    3

    A microcontroller program:

    Appendix A contains the sample C program we will use in this document to illustrate the basic structure of a simple C program . A C program is a high level program in the sense that it

    contains statements

    that

    are

    easy

    for

    humans

    to

    comprehend,

    such

    as

    if

    else

    or

    switch

    statements. Code written at this high level is also known as source code . We say that a file containing a C program is a source code file. C source code files end with a .c postfix, e.g., myCode.c etc. In practice a program is not typically based on a single source code file but is actually a collection of source code files (as well as other types of files that carry special instructions for the microcontroller ). These files are managed by CCS as a collection known as a project .

    Source code files reside only on your PC and are never moved directly to a microcontroller since a microcontroller is not able to directly process source code (which is meant for human

    comprehension). The code first needs to be compiled and converted into machine language , since it is code at machine language level that a microcontroller can process directly; to a human, machine level code is just a long sequence of 1s and 0s and considerable effort is required (by a human) to directly decipher code at this level. In these labs we will not be dealing directly with machine level code , instead we will let CCS convert C level source code to machine level code . We do this in CCS by using the command Build Project . When you select this command CCS first compiles the source files into machine language and then links the various files in the project together to produce code that can be loaded and run on the

    microcontroller . After building a project we will use CCS to directly load the machine code into

    the microcontroller . We will then use CCS to run the project on the microcontroller and also use the debugger built into CCS to debug our programs as they execute on the microcontroller .

    Anatomy of a C program:

    Let us now concentrate on the sample program contained in Appendix A. To follow this document please pay attention to the line numbers that appears as the left most numbers on a line of code . For example, 43 is the number of the line on which the following statement appears in the source code file:

    43 int i = 0;

    You should know that line numbers are not part of the source code ; they are simply included there by CCS to help us keep track of the source code lines . For example, to see where the above statement appears in the sample program, simply go to line number 43 of the code

    contained in Appendix A.

  • 8/12/2019 Introduction to C Notes

    4/15

    4

    C is a case sensitive language, e.g., MyVariable is distinct from myVariable . Pay attention to the case of the names of variables and functions !

    For these labs you need to be familiar with the following C program concepts structures:

    Semicolons Unlike MATLAB a semicolon at the end of a statement is mandatory in C! Do not drop semicolons in the C programs given to you in these labs, otherwise you will get compile time errors when you build the program!

    Variables

    Values are stored in variables . In the C programming language variables need to be declared before they can be used. For example, below, variable i is declared and a value of 0 is stored in

    the variable named i, 43 int i = 0;

    Here a variable named j is declared but no value is assigned to it,

    247 unsigned int j;

    Here a variable named y is declared and no value of assigned to it,

    248 double y;

    A value is assigned to it later, 252 y = sin (j*2*PI/512.0);

    Types

    The C programming language is a strongly typed language . What this means is that each

    variable has a type associated with it, which instructs the microcontroller about how to store the value of the variable in registers (memory ). For example in the above examples int is the

    type of variable i, the type of j is an unsigned int and type of y is a double .

    Here is how these types are stored in registers :

    int: integer (no fractional part ) stored as twos complement signed number in a 32 bit memory

    location (register )

    unsigned int: integer( no fractional part ) stored as an unsigned binary number in a 32 bit

    memory location (register )

  • 8/12/2019 Introduction to C Notes

    5/15

    5

    double: (number with a fractional part ) stored in a special format for storing numbers with fractional parts in a 32 bit memory location (register )

    Besides these we will also be using the following integer types in our labs:

    long: integer (no fractional part ) stored as twos complement signed number in a 64 bit memory location (register )

    unsigned long: integer (no fractional part ): stored as an unsigned binary number in a 64 bit memory location (register )

    Arrays

    We save collection of values in an array just like in MATLAB. Here we are setting aside space

    for any array of size 512 accessed via a global variable named sineTable . Each value stored in

    this array

    is

    of

    type

    double

    and

    is

    stored

    in

    the

    memory

    of

    the

    microcontroller .

    46 double sineTable[512];

    Note that unlike MATLAB the indexing of arrays in the C programming language starts from 0 and not from 1. i.e. sineTable[0] refers to the first value stored in the array and sineTable[511] refers to the last value. It is an error to try to access sineTable using the index 512 , i.e., sineTable[512] refers to a memory location outside the memory space reserved for sineTable . It is important to keep this difference (from MATLAB) in mind when accessing array elements in C.

    Functions

    A C program consists of a collection of functions . The functions in C are conceptually similar to functions in MATLAB. Below is a function in C:

    245 void generate_sineTable ( void ) 246 { 247 unsigned int j; 248 double y; 249 250 for (j = 0; j < 512; j++) 251 { 252 y = sin (j*2*PI/512.0);

    253 sineTable[j] = y; 254 } 255 }

    In general a C function has the following structure:

    retunn_type function_name (list of arguments and their types )

    {

  • 8/12/2019 Introduction to C Notes

    6/15

    6

    Body of the function

    }

    Function_name is the name of the function

    A function can return a value, return_type is the type of the value being returned (e.g. int , double etc.). If a function does not return a value then we use the keyword void .

    A function has a list of arguments and their types . These are the input variables to the function . For

    example, the following function has two input variables number and weight , number is of type int and weight is of type double .

    void myFunction (int count , double weight )

    {

    }

    If a function has no input parameters then we use the keyword void .

    The body of the Function contains all the statements that implement the logic of the function .

    The function named main

    Every C program should exactly have one function with the name main . This function is the entry point of a C program , i.e., execution of the program starts from the fist statement in the body of the function main function. Here is the main function in our sample program ,

    48 //########################################################################### 49 // main code 50 //########################################################################### 51 void main ( void ) 52 {

    // body of function main 68 }

    Typically other functions are called (invoked) from the body of this function named main , just

    like in

    MATLAB

    if

    you

    have

    multiple

    functions

    in

    the

    same

    m

    file.

    The

    functions

    invoked

    from

    main may themselves invoke other functions based on the desired logic. In general it is good programming practice to split the program into smaller functions .

    Local and Global Scope

  • 8/12/2019 Introduction to C Notes

    7/15

    7

    Everything (variable declarations , statements etc.) in a C program either exists inside the body of a function or outside the body of a function . The region inside the body of a function is

    known as local scope . The region outside the body of a function is known as global scope .

    Local Variables

    Variables defined in local scope are known as local variables . For example j and y are local variables defined in the body of the function named generate_SinTable ,

    245 void generate_sineTable ( void ) 246 { 247 unsigned int j; 248 double y;

    255 }

    Local variables are only visible within the body of the function they are defined in. Therefore variables j and y can only be accessed within the body of the function named generate_SinTable . Other functions have no idea about the existence of these variables .

    Global Variables

    Variables defined at global scope are known as global variables . For example the variable named i is a global variables defined outside the body of any function in our sample program ,

    43 int i = 0;

    A global variable is visible to all the functions in the program and all these functions can read and write to this variable . For example the global variable i is visible in the function named LED_blink1 which increments it by one in the statement,

    101 i++;

    By the way, the increment operator ++ applied on i, i.e , i++, is a short hand for the operation, i = i + 1.

    Function Prototypes

    Just like variables need to be declared before they can be used, a function needs to know the prototype of another function before it can use that function in its body. A prototype is the name of the function as well as the types of its list of arguments and its return type. Function

    prototypes are defined in global scope at the beginning of a C program . Below are a few function prototypes declared in our sample program ,

  • 8/12/2019 Introduction to C Notes

    8/15

    8

    35 void generate_sineTable ( void ); 36 void LED_blink1 ( void ); 37 void LED_blink2 ( void );

    40 interrupt void cpu_timer0_isr ( void );

    The following are also function prototypes , 31 extern void Intro_to_CCSv5_Setup ( void ); 32 extern void Intro_to_CCSv5_InterruptMapping ( void );

    Recall that a C program is composed of a collection of source files that comprise the complete program. The keyword extern simply means the function is not defined in the current source file but is defined in some other source file in the project. As you can see the function Intro_to_CCSv5_Setup is not defined anywhere in the sample program ; it is instead defined in a different source file in the project named Intro_to_CCSv5_setup.c .

    Interrupt Service Routines (ISRs)

    Typically in a C program one function calls another function and statements are executed one after another in a predictable sequence as they appear in the body of the functions . However sometimes the microcontroller needs to interrupt this regular execution of the program and lets you invoke code out of the regular sequence of statements . For example your microcontroller is equipped with a peripheral known as a timer . The job of the timer is to let you do something (i.e invoke your own code ) immediately after a certain amount of time has expired. The microcontroller accomplishes this by raising an interrupt when a certain event (i.e.

    certain time having being expired) has occurred. An interrupt can happen at any completely out of sequence of the regular execution of the sequence of statements . Every interrupt is associated with a function known as an Interrupt Service Routine (ISR). Whenever an interrupt is raised the regular invocation of the sequence of statements is abandoned and the code in the body of the ISR associated with that interrupt is executed immediately . The regular execution of the statements of the program is resumed on exit from the body of the ISR as if no interrupt had happened. It is the responsibility of the author of the code to write code for the body of the ISR. In short, the microcontroller (typically one of its peripherals ) raises the interrupt and starts executing the body of the ISR, it is your job to provide the code for the associated ISR.

    An interrupt can be illustrated by the following scenario is a class room. Imagine that the professor in your class is delivering a lecture by following a sequence of teaching instructions and you need to ask a question. You interrupt the class by raising your hand (i.e. you raise an interrupt). The professor then interrupts the sequence of teaching instructions and answers your question (i.e., executes the code in the ISR), after answering your question the professor resumes the regular sequence of teaching instructions.

  • 8/12/2019 Introduction to C Notes

    9/15

    9

    Below is the ISR for a timer event in your sample code,

    70 interrupt void cpu_timer0_isr ( void ) 71 { 72 EALLOW; 73 SysCtrlRegs. WDKEY = 0xAA; // service WD #2 74 EDIS; 75 76 switch (PatternSelect) 77 { 78 case 1: 79 LED_blink1(); 80 break ; 81 case 2: 82 LED_blink2(); 83 break ; 84 default : 85 LED_blink1(); 86 break ; 87 } 88 89 // Acknowledge PIE Group 1 90 PieCtrlRegs. PIEACK. bit . ACK1 = 1; 91 }

    The keyword interrupt is used to indicate that this function is an ISR. Note that the code inside the body of the function has been provided by us. Whenever a timer event occurs (i.e. a certain

    time expires) the normal execution of the program is halted immediately and code in the body

    of this function is invoked. Normal execution of the code resumes as soon as we exit this function .

    Communicating with the Peripherals

    As mentioned earlier a microcontroller contains a number of peripherals , like timers , Analog to Digital and Digital to Analog converters etc. Each peripheral is equipped with a set of registers . Your C program communicates with these peripherals by reading or writing to these registers .

    Your sample program uses these registers in a number of places.

    Here we are starting timer0 by writing a 0 to the register named CpuTimer0Regs. TCR. bit . TSS belonging to the timer0 peripheral ,

    59 CpuTimer0Regs. TCR. bit . TSS = 0; // start timer0

    Here we are turning on an LED connected to a GPIO (General Purpose Input Output) pin.

  • 8/12/2019 Introduction to C Notes

    10/15

    10

    111 GpioDataRegs. GPASET. bit . GPIO9 = 1;

    Switch and Case Statements

    You will need to use the switch statement in a number of places in these labs. A switch

    statement lets you execute different blocks of code based on the value of a variable . As an example, your sample code contains the following switch construct which switches to different code blocks based on the value of the integer variable i,

    107 switch (i) 108 { 109 case 0: // LEDs: 0001 110 { 111 GpioDataRegs. GPASET. bit . GPIO9 = 1; 112 GpioDataRegs. GPACLEAR. bit . GPIO11 = 1; 113 GpioDataRegs. GPBCLEAR. bit . GPIO34 = 1; 114 GpioDataRegs. GPBCLEAR. bit . GPIO49 = 1;

    115 break ; 116 } 117 case 1: // LEDs: 0010 118 { 119 GpioDataRegs. GPACLEAR. bit . GPIO9 = 1; 120 GpioDataRegs. GPASET. bit . GPIO11 = 1; 121 GpioDataRegs. GPBCLEAR. bit . GPIO34 = 1; 122 GpioDataRegs. GPBCLEAR. bit . GPIO49 = 1; 123 break ; 124 }

    149 case 5: // LEDs: 0010

    150 { 151 GpioDataRegs. GPACLEAR. bit . GPIO9 = 1; 152 GpioDataRegs. GPASET. bit . GPIO11 = 1; 153 GpioDataRegs. GPBCLEAR. bit . GPIO34 = 1; 154 GpioDataRegs. GPBCLEAR. bit . GPIO49 = 1; 155 break ; 156 } 157 default : // LEDs: 0000 158 { 159 GpioDataRegs. GPACLEAR. bit . GPIO9 = 1; 160 GpioDataRegs. GPACLEAR. bit . GPIO11 = 1; 161 GpioDataRegs. GPBCLEAR. bit . GPIO34 = 1; 162 GpioDataRegs. GPBCLEAR. bit . GPIO49 = 1;

    163 break ; 164 } 165 }

    If the value of i equals 0 (case 0) then the block of code associated with case 0 is executed, otherwise if the value of i equals 1 (case 1) then the block of code associated with case 1 is executed, etc. If the value of i is not equal to any of the values associated with case statements

  • 8/12/2019 Introduction to C Notes

    11/15

    11

    then the default block is executed. Pay particular attention to the break keywords, do not drop them by mistake.

    If Statement

    The if statement is similar to the if condition in MATLAB. Here is an if statement in your sample code ,

    95 if (i >= 6) 96 { 97 i = 0; 98 } 99 else100 { 101 i++; 102 }

    This code is self explanatory. Note that the conditional operators in C are. ==, >=, >.

  • 8/12/2019 Introduction to C Notes

    12/15

    12

    Now we will give a short explanation of the functionality of the sample code given to you. Your C2000 Peripheral Explorer kit contains an array of four green LEDs (Light Emitting Diodes) shown in Fig. 3 below:

    These LEDs are wired to the following four GPIO (General Purpose Input Output) pins of the microcontroller: GPIO9, GPIO11, GPIO34 and GPIO49. You turn the LEDs on and off by writing directly to the GPIO registers; this is made very simple when you are using the C programming language. For example, if you want to turn on the LED connected to GPIO9 then you simply use the command:

    111 GpioDataRegs. GPASET. bit . GPIO9 = 1;

    You turn off this LED by the following statement:

    Green LEDs

    GPIO9

    GPIO11

    GPIO34

    GPIO49

  • 8/12/2019 Introduction to C Notes

    13/15

    13

    119 GpioDataRegs. GPACLEAR. bit . GPIO9 = 1;

    The main logic of the program is contained in the timer ISR cpu_timer0_isr

    70 interrupt void cpu_timer0_isr ( void ) 71 { 72 EALLOW; 73 SysCtrlRegs. WDKEY = 0xAA; // service WD #2 74 EDIS; 75 76 switch (PatternSelect) 77 { 78 case 1: 79 LED_blink1(); 80 break ; 81 case 2: 82 LED_blink2(); 83 break ; 84 default : 85 LED_blink1(); 86 break ; 87 } 88 89 // Acknowledge PIE Group 1 90 PieCtrlRegs. PIEACK. bit . ACK1 = 1; 91 }

    This ISR is invoked every time a timer event is emitted. The timer has been set in the Intro_to_CCSv5_setup.c file to emit an event every 100 milliseconds . Based on the value of the global variable PatternSelect either the function LED_blink1 or LED_blink2 is invoked every time this ISR is invoked. These functions use a switch statement (based on the value of the global variable i) to tune the LEDs on and off in specified patters. Not that because of the if statement in these functions the global variable i increases from 0 to 5 and then switches back to 0 to repeat this pattern. Depending on the value of i a different set of LEDs are turned on and off .

    Getting Started with CCSv5:

    This section will get you started with using CCSv5 (Code Composer Studio version 5). CCS is an IDE (Integrated Development Environment) which runs as an application on your PC. In these labs you will use CCS is to write C programs for your microcontroller , compile/build these programs, and load and run them on the microcontroller . You will also use CCS to debug programs running on the microcontroller .

    A C program consists of a collection if C source code files as well as other files that contain special instructions for the microcontroller . A collection of all these files is kept together in CCS

  • 8/12/2019 Introduction to C Notes

    14/15

    14

    in the form of a project . Fig.3 shows the project associated with the sample project you are going to use in this lab, as it appears in CCSv5.

    Note that Appendix A contains the source code contained the file named Intro_to_CCSv5.c .

    All the files of a project live in a folder on your PC or a disc drive which has the same name as the name of the project , i.e, in this case the name of the folder is intro_to_CCSv5 . In these labs

    you will be given pre written projects which you will modify. A project will be given to you in a folder and you will use CCS to import this project folder into your own workspace as described below.

    CCS Workspace

    CCS keeps projects in entities known as workspaces . A workspace is actually a folder that contains a number of project folders . When you open CCS it asks you to choose a workspace , i.e., it asks you to navigate to the workspace folder of your choice on your PC. In these labs you

    will operate from a single workspace , i.e. all your projects will be in the same workspace folder. One of your first jobs before starting these labs would be to create a workspace folder somewhere on your PC (preferably not on your desktop ). Once this folder is created, you will open CCS and use the import command to import the project given to you from its folder to your workspace folder .

  • 8/12/2019 Introduction to C Notes

    15/15

    15

    Instructions to do these and other tasks you can perform in CCSv5 are given in a series of screen casts named:

    Introduction to CCSv5 Part I Introduction to CCSv5 Part II

    Introduction to CCSv5 Part III