C Programming For Embedded System Applications PDF
C Programming For Embedded System Applications PDF
V. P. Nelson
Spring 2013 ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
Outline
Program organization and microcontroller memory Data types, constants, variables Microcontroller register/port addresses Operators: arithmetic, logical, shift Control structures: if, while, for Functions Interrupt routines
Spring 2013 ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
Address
0x0000 0x0400 0x0800 0x1000 0x4000
Control registers for I/O [0x0000..0x03FF] 2K byte RAM [0x0800..0x0FFF] for variable & stack storage
0x8000
0xC000
0xFF00
Spring 2013
Spring 2013
0..65535
Read TCNT timer value (16-bit unsigned) Read 10-bit value from ADC (unsigned)
unsigned int a; a = ADC; int ctrl; ctrl = (x + y)*z;
System control value range [-1000+1000] Loop counter for 100 program loops (unsigned)
unsigned char cnt; for (cnt = 0; cnt < 20; cnt++) {
ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
Spring 2013
Constant/literal values
Decimal is the default number format Hexadecimal: preface value with 0x or 0X m = 0xF312; n = -0x12E4; Octal: preface value with zero (0) m = 0453; n = -023;
int m,n; //16-bit signed numbers m = 453; n = -25;
Character: character in single quotes, or ASCII value following slash m = a; //ASCII value 0x61 n = \13; //ASCII value 13 is the return character String (array) of characters: unsigned char k[7]; strcpy(m,hello\n); //k[0]=h, k[1]=e, k[2]=l, k[3]=l, k[4]=o, //k[5]=13 or \n (ASCII new line character), //k[6]=0 or \0 (null character end of string)
Spring 2013 ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
Dont use leading zeros on decimal values. They will be interpreted as octal.
C variables
A variable is an addressable storage location to information to be used by the program
Each variable must be declared to indicate size and type of information to be stored, plus name to be used to reference the information int x,y,z; //declares 3 variables of type int char a,b; //declares 2 variables of type char Space for variables can be allocated in registers, RAM, or ROM/Flash (for constants) Variables can be automatic, static, or volatile
ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
Spring 2013
C variable arrays
An array is a set of data, stored in consecutive memory locations, beginning at a named address
Declare array name and number of data elements, N Elements are indexed, with indices [0 .. N-1]
n[0] Address: n n+2 n+4 n+6 n+8
n[4]
Automatic variables
Declare within a function/procedure Variable is visible (has scope) only within that function
Space for the variable is allocated on the system stack when the procedure is entered
Deallocated, to be re-used, when the procedure is exited
If only 1 or 2 variables, the compiler may allocate them to registers within that procedure, instead of allocating memory. Values are not retained between procedure calls
Spring 2013 ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
CodeWarrior (in my example): allocated register D (B:A) for variable i and top word of the stack for variable j
Spring 2013 ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
Static variables
Retained for use throughout the program in RAM locations that are not reallocated during program execution. Declare either within or outside of a function
Use normal declarations. Example: int count;
If declared outside a function, the variable is global in scope, i.e. known to all functions of the program If declared within a function, insert key word static before the variable definition. The variable is local in scope, i.e. known only within this function.
static unsigned char bob; static int pressure[10];
ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
Spring 2013
Volatile variables
Value can be changed by outside influences, i.e. by factors other than program instructions
values applied to the pins of an input port bits within a timer register result of an analog to digital conversion
#define PORTA (*((volatile unsigned char*)(0x0000))) PORTA = 0x55; /* write value 0x55to PORTA */
Spring 2013 ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
/* read value from PORTB into variable c */ /* write value to PORTA from variable c */
C statement types
Simple variable assignments
Includes input/output data transfers
Function calls
User-defined and/or library functions
Spring 2013 ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
Arithmetic operations
C examples with standard arithmetic operators
int i, j, k; // 16-bit signed integers unsigned char m,n,p; // 8-bit unsigned numbers i = j + k; // add 16-bit integers m = n - 5; // subtract 8-bit numbers j = i * k; // multiply 16-bit integers m = n / p; // quotient of 8-bit divide m = n % p; // remainder of 8-bit divide i = (j + k) * (i 2); //arithmetic expression
*, /, % are higher in precedence than +, - (higher precedence applied 1st) Example: j * k + m / n = (j * k) + (m / n) Floating-point formats are not directly supported by HCS12 CPUs.
ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
Spring 2013
C = A | B; (OR)
C = A ^ B; (XOR)
B = ~A; (COMPLEMENT)
Spring 2013
Bit set/reset/complement/test
Use a mask to select bit(s) to be altered
C = A & 0xFE; A 0xFE C A 0xFE C A 0x01 C A 0x01 C a b c d e f g h 1 1 1 1 1 1 1 0 Clear selected bit of A a b c d e f g 0 a b c d e f g h 0 0 0 0 0 0 0 1 Clear all but the selected bit of A 0 0 0 0 0 0 0 h a b c d e f g h 0 0 0 0 0 0 0 1 Set selected bit of A a b c d e f g 1 a b c d e f g h 0 0 0 0 0 0 0 1 Complement selected bit of A a b c d e f g h
ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
C = A & 0x01;
C = A | 0x01;
C = A ^ 0x01;
Spring 2013
Examples:
if ( (PORTA & 0x80) != 0 ) //Or: ((PORTA & 0x80) == 0x80) bob(); // call bob() if bit 7 of PORTA is 1 c = PORTB & 0x04; // mask all but bit 2 of PORTB value if ((PORTA & 0x01) == 0) // test bit 0 of PORTA PORTA = c | 0x01; // write c to PORTA with bit 0 set to 1
Spring 2013 ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
/*** PTT - Port T I/O Register; 0x00000240 ***/ CodeWarrior include file typedef union { defines C registers byte Byte; struct { as structures of bits, byte PTT0 :1; /* Port T Bit 0 */ allowing access to byte PTT1 :1; /* Port T Bit 1 */ byte PTT2 :1; /* Port T Bit 2 */ individual register bits. byte PTT3 :1; /* Port T Bit 3 */ (Read file to view names.) byte PTT4 :1; /* Port T Bit 4 */ byte PTT5 :1; /* Port T Bit 5 */ byte PTT6 :1; /* Port T Bit 6 */ byte is defined as unsigned char byte PTT7 :1; /* Port T Bit 7 */ } Bits; } PTTSTR; Equivalent C statements: extern volatile PTTSTR _PTT @(REG_BASE + 0x00000240UL); #define PTT _PTT.Byte #define PTT_PTT0 _PTT.Bits.PTT0 PTT = PTT | 0x01; #define PTT_PTT1 _PTT.Bits.PTT1 PTT_PTT0 = 1; #define PTT_PTT2 _PTT.Bits.PTT2 #define PTT_PTT3 _PTT.Bits.PTT3 #define PTT_PTT4 _PTT.Bits.PTT4 if ((PTT & 0x04) == 0x04) #define PTT_PTT5 _PTT.Bits.PTT5 If (PTT_PTT2 == 1) #define PTT_PTT6 _PTT.Bits.PTT6 #define PTT_PTT7 _PTT.Bits.PTT7fine TFLG1 _TFLG1.Byte
Spring 2013 ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
PORTB
Switch connected to bit 4 of PORTB unsigned char sw; sw = PORTB; sw = PORTB & 0x10; if (sw == 0x01) if (sw == 0x10) if (sw == 0) if (sw != 0) PORTB = 0x5a; PORTB_BIT4 = 0; if (PORTB_BIT4 == 1) if (PORTB_BIT4 == sw)
Spring 2013
//8-bit unsigned variable // sw = hgfedcba // sw = 000e0000 (mask all but bit 4) // Result is sw = 00000000 or 00010000 // NEVER TRUE for above sw, which is 000e0000 // TRUE if e=1 (bit 4 in result of PORTB & 0x10) // TRUE if e=0 in PORTB & 0x10 (sw=00000000) // TRUE if e=1 in PORTB & 0x10 (sw=00010000) // Write to 8 bits of PORTB; result is 01011010 // Sets only bit e=0 in PORTB (PORTB now hgf0dcba) // TRUE if e=1 (bit 4 of PORTB) // Mismatch: comparing bit to byte
ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
Shift operators
Shift operators: x >> y (right shift operand x by y bit positions) x << y (left shift operand x by y bit positions) Vacated bits are filled with 0s. Shift right/left fast way to multiply/divide by power of 2 B = A << 3; (Left shift 3 bits) B = A >> 2; (Right shift 2 bits) A B A B 1 0 1 0 1 1 0 1 0 1 1 0 1 0 0 0 1 0 1 1 0 1 0 1 0 0 1 0 1 1 0 1
B = 1; B = 0 0 1 1 0 0 0 1 (ASCII 0x31) C = 5; C = 0 0 1 1 0 1 0 1 (ASCII 0x35) D = (B << 4) | (C & 0x0F); (B << 4) = 0 0 0 1 0 0 0 0 (C & 0x0F) = 0 0 0 0 0 1 0 1 D = 0 0 0 1 0 1 0 1 (Packed BCD 0x15)
Spring 2013 ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
C control structures
Control order in which instructions are executed (program flow) Conditional execution
Iterative execution
Execute a set of statements if some condition is met Select one set of statements to be executed from several options, depending on one or more conditions Repeated execution of a set of statements
A specified number of times, or Until some condition is met, or While some condition is true
Spring 2013
IF-THEN structure
Execute a set of statements if and only if some condition is met
TRUE/FALSE condition
a<b ?
No
Yes
S1; S2;
Spring 2013
Relational Operators
Test relationship between two variables/expressions
Test (m == b) (m != b) (m < b) (m <= b) (m > b) (m >= b) (m) (1) (0) TRUE condition m equal to b m not equal to b m less than b m less than or equal to b m greater than b m greater than or equal to b m non-zero always TRUE always FALSE
ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
Notes Double = 1 1 1 1
1. Compiler uses signed or unsigned comparison, in accordance with data types Example: unsigned char a,b; int j,k; if (a < b) unsigned if (j > k) - signed
Spring 2013
Boolean operators
Boolean operators && (AND) and || (OR) produce TRUE/FALSE results when testing multiple TRUE/FALSE conditions
if ((n > 1) && (n < 5)) //test for n between 1 and 5 if ((c = q) || (c = Q)) //test c = lower or upper case Q
Note the difference between Boolean operators &&, || and bitwise logical operators &, |
if ( k && m) //test if k and m both TRUE (non-zero values) if ( k & m) //compute bitwise AND between m and n, //then test whether the result is non-zero (TRUE)
Spring 2013 ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
Common error
Note that == is a relational operator, whereas = is an assignment operator.
if ( m == n) //tests equality of values of variables m and n if (m = n) //assigns value of n to variable m, and then
//tests whether that value is TRUE (non-zero)
The second form is a common error (omitting the second equal sign), and usually produces unexpected results, namely a TRUE condition if n is 0 and FALSE if n is non-zero.
Spring 2013 ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
IF-THEN-ELSE structure
Execute one set of statements if a condition is met and an alternate set if the condition is not met.
if (a == 0) { statement s1; statement s2; } else { statement s3; statement s4: }
Spring 2013
S1; S2;
Yes
a == 0 ?
No
S3; S4;
if (n > 0) { Braces force proper association if (a > b) z = a; } else //else goes with first if (n > 0) z = b;
ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
Spring 2013
SWITCH statement
Compact alternative to ELSE-IF structure, for multiway decision that tests one variable or expression for a number of constant values /* example equivalent to that on preceding slide */ switch ( n) { //n is the variable to be tested case 0: statement1; //do if n == 0 case 1: statement2; // do if n == 1 case 2: statement3; // do if n == 2 default: statement4; //if for any other n value } Any statement above can be replaced with a set of statements: {s1; s2; s3; }
Spring 2013 ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
a<b ?
No
Yes
while (AD_PORT <= MAX_ALLOWED) { LIGHT_PORT = LIGHT_ON; delay(); LIGHT_PORT = LIGHT_OFF; delay(); }
AD_PORT: EQU $91 ; A/D Data port MAX_ALLOWED:EQU 128 ; Maximum Temp LIGHT_ON: EQU 1 LIGHT_OFF: EQU 0 LIGHT_PORT: EQU $258 ; Port P ; --; Get the temperature from the A/D ldaa AD_PORT ; WHILE the temperature > maximum allowed WHILE_START: cmpa MAX_ALLOWED bls END_WHILE ; DO - Flash light 0.5 sec on, 0.5 sec off ldaa LIGHT_ON staa LIGHT_PORT ; Turn the light jsr delay ; 0.5 sec delay ldaa LIGHT_OFF staa LIGHT_PORT ; Turn the light off jsr delay ; End flashing the light, Get temperature from the A/D ldaa AD_PORT ; END_DO bra WHILE_START END_WHILE:
Spring 2013
Yes
a<b ?
No
The condition is tested after executing the set of statements, so the statements are guaranteed to execute at least once.
Spring 2013
DO-WHILE example
C version: #define MAX_ALLOWED 128 #define LIGHT_ON 1 #define LIGHT_OFF 0 do { LIGHT_PORT = LIGHT_ON; delay(); LIGHT_PORT = LIGHT_OFF; delay(); } while (AD_PORT <= MAX_ALLOWED);
;Assembly Language Version ; DO ; Flash light 0.5 sec on, 0.5 sec off ldaa LIGHT_ON staa LIGHT_PORT ; Turn light on jsr delay ; 0.5 sec delay ldaa LIGHT_OFF staa LIGHT_PORT ; Turn light off jsr delay ; End flashing the light ; Get the temperature from the A/D ldaa AD_PORT ; END_DO bra WHILE_START ; END_WHILE: ; END_WHILE temperature > maximum allowed ; Dummy subroutine delay: rts
Spring 2013
WHILE examples
/* Add two 200-element arrays. */
int M[200],N[200],P[200]; int k; /* Method 1 using DO-WHILE */ k = 0; //initialize counter/index do { M[k] = N[k] + P[k]; //add k-th array elements k = k + 1; //increment counter/index } while (k < 200); //repeat if k less than 200 /* Method 2 using WHILE loop k = 0; //initialize counter/index while (k < 200} { //execute the loop if k less than 200 M[k] = N[k] + P[k]; //add k-th array elements k = k + 1; //increment counter/index }
Spring 2013 ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
WHILE example
PORTA bit0 0
1 Read PORTB No operation
while ( (PORTA & 0x01) == 0) // test bit 0 of PORTA {} // do nothing & repeat if bit is 0 c = PORTB; // read PORTB after above bit = 1
Spring 2013
Spring 2013
Spring 2013
C functions
Functions partition large programs into a set of smaller tasks
Helps manage program complexity Smaller tasks are easier to design and debug Functions can often be reused instead of starting over Can use of libraries of functions developed by 3rd parties, instead of designing your own
ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
Spring 2013
C functions
A function is called by another program to perform a task
The function may return a result to the caller One or more arguments may be passed to the function/procedure
Spring 2013
Function definition
Type of value to be returned to the caller* Parameters passed by the caller
int math_func (int k; int n) { //local variable int j; j = n + k - 5; //function body return(j); //return the result }
* If no return value, specify void
Spring 2013 ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
Parameters passed to
Function arguments
Calling program can pass information to a function in two ways
By value: pass a constant or a variable value
function can use, but not modify the value
Values/addresses are typically passed to the function by pushing them onto the system stack
Function retrieves the information from the stack
Spring 2013 ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
In the above, main tells square the location of its local variable, so that square can write the result to that variable.
Spring 2013 ELEC 3040/3050 Embedded Systems Lab V. P. Nelson
Tutorial to be continued ..
Spring 2013
Spring 2013