Text

advertisement
The HCS12/MC9S12 Microcontroller
Chapter 5: C Language Programming
The HCS12 Microcontroller
Han-Way Huang
Minnesota State University, Mankato
September 2009
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-1
The HCS12/MC9S12 Microcontroller
Introduction to C
- C has gradually replaced assembly language in many embedded applications.
- A summary of C language constructs that will be used in HCS12 programming.
- Books on C language
1. Kernighan & Ritchie, “The C Programming Language”, Prentice Hall, 1988.
2. Deitel & Deitel, “C: How to Program”, Prentice Hall, 2008.
3. Kelly & Pohl, “A Book on C: Programming in C”, Addison-Wesley, 1998.
- A C program consists of functions and variables.
- A function contains statements that specify the operations to be performed.
- Types of statements:
1. Declaration
2. Assignment
3. Function call
4. Control
5. Null
- A variable stores a value to be used during the computation.
- The main () function is required in every C program.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-2
The HCS12/MC9S12 Microcontroller
A C Program Example
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
(9)
(10)
(11)
#include <stdio.h>
/* this is where program execution begins */
int main ()
{
int a, b, c;
a = 3;
b = 5;
c = a + b;
printf (“ a + b = %d\n”, c);
return 0;
}
-- causes the file stdio.h to be included
-- a comment
-- program execution begins
-- marks the start of the program
-- declares three integer variables a, b, and c
-- assigns 3 to variable a
-- assigns 5 to variable b
-- assigns the sum of a and b to variable c
-- prints the string a + b = followed by value of c
-- returns 0 to the caller of main( )
-- ends the main( ) function
Types, Operators, and Expressions
- Variables must be declared before they can be used.
- A variable declaration must include the name and type of the variable and may
optionally provide its initial value.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-3
The HCS12/MC9S12 Microcontroller
- The name of a variable consists of letters and digits.
- The underscore character “_” can be used to improve readability of long
variables.
Data Types
-
C has five basic data types: void, char, int, float, and double.
The void type represents nothing and is mainly used with function.
A variable of type char can hold a single byte of data.
A variable of type int is an integer that is the natural size for a particular machine.
The type float refers to a 32-bit single-precision floating-point number.
The type double refers to a 64-bit double-precision floating-point number.
Qualifiers short and long can be applied to integers. For GNU C compiler,
short is 16 bits and long is 32 bits.
- Qualifiers signed and unsigned may be applied to data types char and integer.
Declarations
- A declaration specifies a type, and contains a list of one or more variables of that
type.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-4
The HCS12/MC9S12 Microcontroller
Examples of declarations
int i, j, k;
char cx, cy;
int m = 0;
char echo = ‘y’; /* the ASCII code of letter y is assigned to variable echo. */
Constants
- Types of constants: integers, characters, floating-point numbers, and strings.
- A character constant is written as one character within single quotes, such as ‘x’.
A character constant is represented by the ASCII code of the character.
- A string constant is a sequence of zero or more characters surrounded by double
quotes, as “MC9S12DP256 is made by Motorola” or “”, which represented an empty
string. Each individual character in the string is represented by its ASCII code.
- An integer constant like 1234 is an int. A long constant is written with a terminal
l or L, as in 44332211L.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-5
The HCS12/MC9S12 Microcontroller
- A number in C can be specified in different bases.
- The method to specify the base of a number is to add a prefix to the number.
Arithmetic Operators
+
*
/
add and unary plus
subtract and unary minus
multiply
divide
-- truncate quotient to integer when both operands are integers.
%
++
--
modulus (or remainder) -- cannot be applied to float or double
increment (by 1)
decrement (by 1)
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-6
The HCS12/MC9S12 Microcontroller
Bitwise Operators
 C provides six operators for bit manipulations; they may only be applied to
integral operands.
&
|
^
~
>>
<<
AND
OR
XOR
NOT
right shift
left shift
 & is often used to clear one or more bits of an integral variable to 0.
PTH = PTH & 0xBD
// clears bit 6 and bit 1 of PTH to 0
// PTH is of type char
 | is often used to set one or more bits to 1.
PTB = PTB | 0x40;
// sets bit 6 to 1 (PTB is of type char)
 ^ can be used to toggle a bit.
abc = abc ^ 0xF0;
// toggles upper four bits (abc is of type char)
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-7
The HCS12/MC9S12 Microcontroller
 >> can be used to shift the involved operand to the right for the specified number
of places.
xyz
= xyz >> 3;
-- shift right 3 places
 << can be used to shift the involved operand to the left for the specified number
of places.
xyz
= xyz << 4;
-- shift left 4 places
 The assignment operator = is often combined with the operator. For example,
PTH
PTB
xyz
xyz
&= 0xBD;
|= 0x40;
>>= 3;
<<= 4;
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-8
The HCS12/MC9S12 Microcontroller
Relational and Logical Operators
- Relational operators are used in expressions to compare the values of two operands.
- The value of the expression is 1 when the result of comparison is true. Otherwise,
the value of the expression is 0.
- Relational and logical operators:
==
!=
>
>=
<
<=
&&
||
!
equal to
not equal to
greater than
greater than or equal to
less than
less than or equal to
and
or
not (one’s complement)
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-9
The HCS12/MC9S12 Microcontroller
Examples of Relational and Logical Operators
if (!(ATD0STAT0 & 0x80))
statement1;// if bit 7 is 0, then execute statement1
if (i > 0 && i < 10)
statement2;// if 0 < i < 10 then execute statement2
if (a1 == a2)
statement3;// if a1 == a2 then execute statement3
Control Flow
- The control-flow statements specify the order in which computations are
performed.
- Semicolon is a statement terminator.
- Braces { and } are used to group declarations and statements together into a
compound statement, or block.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-10
The HCS12/MC9S12 Microcontroller
If-Else Statement
if (expression)
statement1
else
statement2
-- The else part is optional.
Example
if (a != 0)
r = b;
else
r = c;
A more concise way for this statement is
r = (a != 0)? b : c;
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-11
The HCS12/MC9S12 Microcontroller
Multiway Conditional Statement
if (expression1)
statement1
else if (expression2)
statement2
else if (expression3)
statement3
…
else
statementn
Example
if (abc > 0) return 5;
else if (abc = 0) return 0;
else return -5;
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-12
The HCS12/MC9S12 Microcontroller
Switch Statement
switch (expression) {
case const_expr1;
statement1;
break;
case const_expr2;
statement2;
break;
…
default:
statementn;
}
Copyright © 2010 Delmar Cengage Learning
Example
switch (i) {
case 1: pay = 10;
break;
case 2: pay = 20;
break;
case 3: pay = 30;
break;
case 4: pay = 40;
break;
case 5: pay = 50;
break;
}
H. Huang Transparency No.5-13
The HCS12/MC9S12 Microcontroller
For-Loop Statement
for (expr1; expr2; expr3)
statement;
where, expr1 and expr2 are assignments or function calls and expr3 is a
relational expression.
Example
sum = 0;
for (i = 1; i < 10; i++)
sum += i * i;
for (i = 1; i < 20; i++)
if (i % 2) printf(“%d “, i);
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-14
The HCS12/MC9S12 Microcontroller
While Statement
while (expression)
statement
Example
int_cnt = 5;
while (int_cnt);
Do-While Statement
do
statement
while (expression);
Copyright © 2010 Delmar Cengage Learning
// do nothing while the variable int_cnt  0
Example
int digit = 9;
do
printf(“%d “, digit--);
while (digit >= 1);
H. Huang Transparency No.5-15
The HCS12/MC9S12 Microcontroller
Input and Output
Examples
- Not part of the C language itself.
- Four I/O functions will be discussed.
1. int getchar ( ).
-- returns a character when called
char
xch;
xch = getchar ();
2. int putchar (int).
-- outputs a character on a standard
output device
3. int puts (const char *s).
-- outputs the string pointed by s on
a standard output device
putchar(‘a’);
puts (“Welcome to USA! \n”);
4. int printf (formatting string, arg1, arg2, …).
-- converts, formats, and prints its arguments
on the standard output device.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-16
The HCS12/MC9S12 Microcontroller
Formatting String for Printf
- The arguments of printf can be written as constants, single variable or array
names, or more complex expressions.
- The formatting string is composed of individual groups of characters, with one
character group associated with each output data item.
- The character group starts with %.
- The simplest form of a character group consists of the percent sign followed by
a conversion character indicating the type of the corresponding data item.
- Multiple character groups can be contiguous, or they can be separated by other
characters, including whitespace characters. These “other characters” are simply
sent to the output device for display.
- Examples
printf (“this is a challenging course ! \n”);
printf(%d %d %d”, x1, x2, x3); // outputs x1, x2, and x3 using minimal number
// of digits with one space separating each value
printf(“Today’s temperature is %4.1d\n”, temp);
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-17
The HCS12/MC9S12 Microcontroller
Rules for Conversion String
- Between the % and the conversion character there may be, in order:
1.
2.
3.
4.
A minus sign, -- specify left adjustment.
A number that specifies the minimum field width.
A period that separates the field width from precision.
A number, the precision, that specifies the maximum number of characters to
be printed from a string, or the number of digits after the decimal point, or
the minimum of digits for an integer.
5. An h if the integer is to be printed as a short, or l (letter ell) if as a long.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-18
The HCS12/MC9S12 Microcontroller
Functions and Program Structure
 Every C program consists of one or more functions.
 Definition of a function cannot be embedded within another function.
 A function will process information passed to it from the calling portion of the
program, and return a single value.
 Syntax of a function definition:
return_type function_name (declarations of arguments)
{
declarations and statements
}
Example
char lower2upper (char cx)
{
if cx > ‘a’ && cx <= ‘z’) return (cx - (‘a’ - ‘A’));
else return cx;
}
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-19
The HCS12/MC9S12 Microcontroller
Example 5.4 Write a function to find the square root of a 32-bit integer using the successive
approximation method.
Solution:
unsigned long int FindSqr (unsigned long int xval)
{
unsigned long int mask, temp, sar;
unsigned int ix;
mask = 0x8000; // Initialize mask for making bit value guessing
sar
= 0;
for (ix = 0; ix < 16; ix++){
temp = sar | mask;
if((temp * temp) <= xval)
sar
= temp;
mask >>= 1;
}
if ((xval - (sar * sar)) > ((sar+1)*(sar+1) - xval))
sar
+= 1;
return sar;
}
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-20
The HCS12/MC9S12 Microcontroller
Example 5.5 Write a function to test whether a 32-bit nonnegative integer is a prime
number
Solution: An integer is a prime if it cannot be divided by any integer between 2 and its
square root.
unsigned int PrimeTest(unsigned long int xval)
{
unsigned long int TLimit;
unsigned int ptest;
if ((xval == 1) || (xval == 2))
return 0;
TLimit = FindSqr(xval);
// call FIndSqr() to find the limit for test divide
for (ptest = 2; ptest <= TLimit; ptest++){
if ((xval % ptest) == 0)
// is remainder zero?
return 0;
}
return 1;
}
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-21
The HCS12/MC9S12 Microcontroller
Example 5.6 Write a program to find the number of prime numbers between 100 and
1000.
Solution:
#include "c:\cwHCS12\include\hcs12.h"
unsigned long int FindSqr (unsigned long int xval);
unsigned int PrimeTest(unsigned long int xval);
unsigned int prime_count;
void main(void) {
unsigned long int i;
prime_count = 0;
for (i = 100; i <= 1000; i++) {
if (PrimeTest(i))
prime_count ++;
}
while(1);
}
#Include PrimeTest here
#Include FindSqr here
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-22
The HCS12/MC9S12 Microcontroller
Function Prototype
 A function cannot be called before it has been defined.
 This dilemma is resolved by using the function prototype statement.
 The syntax for a function prototype statement is as follows:
return_type function_name (declarations of arguments);
Exmaple
unsigned int PrimeTest (unsigned long int xval);
Creating Header File
 To reuse functions that we have created, we can collect the set of functions that are of
the same nature into one file and also put the prototype declarations of these functions
into one header file.
 When reusing these functions, we need to add the C file that contains them into the
project and also add the header file into the file that invoke these functions.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-23
The HCS12/MC9S12 Microcontroller
Pointers and Addresses
- A pointer is a variable that holds the address of a variable.
- Pointers provide a way to return multiple data items from a function via function
arguments.
- Pointers also permit references to other functions to be specified as arguments to
a given function.
- Syntax for pointer declaration:
type_name *pointer_name;
Examples
int *ax;
char *cp;
- Use the dereferencing operator * to access the value pointed by a pointer.
int a, *b;
…
a = *b;
/* assigns the value pointed by b to a */
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-24
The HCS12/MC9S12 Microcontroller
- Use the unary operator & to assign the address of a variable to a pointer. For example,
int x, y;
int *ip;
ip = &x;
y = *ip;
// y gets the value of x
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-25
The HCS12/MC9S12 Microcontroller
Example 5.7 Write a bubble sort function to sort an array of integers.
Solution:
void swap (int *px, int *py);
/* function prototype declaration */
void bubble (int a[], int n)
/* n is the array count */
{
int i, j;
for (i = 0; i < n - 1; i++)
for (j = 0; j < n – i - 1; j++)
if (a[j] > a[j+1])
swap (&a[j], & a[j+1]);
}
void swap(int *px, int *py)
{
int temp;
temp = *px;
*px = *py;
*py = temp;
}
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-26
The HCS12/MC9S12 Microcontroller
Arrays
 An array consists of a sequence of data items that have common characteristics.
 Each array is referred to by specifying the array name followed by one or more subscripts,
with each subscript enclosed in brackets. Each subscript is a nonnegative integer.
 The number of subscripts determines the dimensionality of the array. For example,
x[i]
is an element of an one-dimensional array
y[i][j] refers to an element of a two-dimensional array
 Syntax for one-dimensional array declaration:
data-type array_name [expression];
 Syntax for two-dimensional array declaration:
data-type array_name [expr1] [expr2];
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-27
The HCS12/MC9S12 Microcontroller
Pointers and Arrays
 Any operations that can be achieved by array subscripting can also be done with pointers.
 The pointer version will in general be faster but, somewhat harder to understand.
 For example,
int ax[20];
int *ip;
/* array of 20 integers */
/* ip is an integer pointer */
ip = &ax[0]
/* ip contains the address of ax[0] */
x = *ip;
/* copy the contents of ax[0] into x.
 If ip points to ax[0], then ip + 1 points to ax[1], and ip + i points to ax[i], etc.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-28
The HCS12/MC9S12 Microcontroller
Passing Arrays to a Function
- An array name can be used as an argument to a function.
- To pass an array to a function, the array name must appear by itself, without brackets or
subscripts, as an actual argument within the function call.
- When declaring a one-dimensional array as a formal argument, the array name is written with
a pair of empty square brackets.
- When declaring a two-dimensional array as a formal argument, the array name is written with
two pairs of empty square brackets.
int average (int n, int arr[ ]);
main ( )
{
int n, avg;
int arr[50];
…
avg = average (n, arr);
/* function call with array name as an argument */
…
}
int average (int k, int brr [ ]) /* function definition */
{
…
}
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-29
The HCS12/MC9S12 Microcontroller
Structures
- A group of related variables that can be accessed through a common name.
- Each item within a structure has its own data type, which can be different.
- The syntax of a structure is as follows:
struct struct_name {
type1 member1;
type2 member2;
…
};
/* struct_name is optional */
The struct_name is optional and if it exists, defines a structure tag that defines a type. For
example,
struct catalog_tag {
char
author [40];
char
title [40];
char
pub [40];
unsigned int date;
unsigned char rev;
} card;
where, the variable card is of type catalog_tag.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-30
The HCS12/MC9S12 Microcontroller
Unions
 A variable that may hold (at different times) objects of different types and sizes, with
the compiler keeping track of size and alignment requirements.
 The syntax is as follows:
union union_name {
type-name1
type-name2
…
type-namen
};
element1;
element2;
elementn;
where, union_name is optional. When exists, it defines a union-tag.
 The current temperature can be represented as follows:
union u_tag {
int i;
char c[4];
} temp;
 A member of a union can be accessed as
union-name.member
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-31
The HCS12/MC9S12 Microcontroller
Writing C Programs to Perform Simple I/O
 The user needs to configure the direction of each I/O pin
 A pin can be configured for output by setting the corresponding bit
in the associated data direction register to 1. For example,
DDRB = 0xFF; // configure Port B for output
DDRA = 0x0F; // configure Port A upper 4 pins for input, lower
// four pins for output
DDRT = 0x20; // configure Port T pin 5 for output, other pins
// for input
 The following instructions perform simple I/O operations:
PTB = 0x56; // output 0x56 to Port B
PTP |= 0x20; // pull Port P pin 5 to high
PTJ
&= 0xFD; // pull Port J pin 1 to low
xyz
= PTA; // read the value of Port A and store it in xyz.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-32
The HCS12/MC9S12 Microcontroller
Example 5.8 Write a program to display one LED at a time from the circuit in Figure
4.16 with each LED to be lighted for 200 ms.
Solution:
#include "c:\cwHCS12\include\hcs12.h"
void SetClk8(void); // need to include SetClk.c to project
void delayby100ms(int k); // include delay.c to project
void main (void)
{
unsigned char led_tab[16]=
{0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
char i;
DDRB = 0xFF; // configure Port B for output
DDRJ |= 0x02;// configure PJ1 pin for output
PTJ
&= 0xFD; // enable LEDs to light
SetClk8(); // set E clock to 24-MHz
while (1) {
for (i = 0;i < 16; i++) {
PTB = led_tab[i]; // output a new LED pattern
delayby100ms(2);// wait for 200 ms
}
}
}
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-33
The HCS12/MC9S12 Microcontroller
PB6
PB1
PB0
Example 5.9 Write a program to display the following patterns from the seven-segment
display circuit shown in Figure 4.18 from display #0 to #5 and repeat with each pattern
lasting for 600 ms:
123456
234567
345678
#0
#1
#5
456789
800
a
a
. . . a
. . . b
b
b
567890
.
.
.
678901
.
800 g
. g
. . . g
.
789012
74HC244
common
common
common
890123
cathode
cathode
cathode
901234
74HC367
012345
A0
Y0
PP0
Solution:
PP1
A1
Y1
PP2
A2
Y2
PP3
A3
Y3
PP4
A4
Y4
PP5
A5
Y5
.
.
.
Figure 4.18 Port B and Port P together drive six seven-segment displays (MC9S12DG256)
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-34
The HCS12/MC9S12 Microcontroller
Solution: There are ten different pattern sequences and two adjacent sequences are
offset by 1. The overlapping these sequences are shown in Figure 5.2.
Let SegPat, i, j, and k represent the segment table of 15 segment patterns, the start index
of the sequence to be displayed, the number of times of the current sequence remained
to be repeated, and the display to be lighted at the moment.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-35
The HCS12/MC9S12 Microcontroller
#include "c:\cwHCS12\include\hcs12.h"
#include "c:\cwHCS12\include\delay.h“ // include delay.c to the project
void SetClk8(void); // include SetClk.c to the project
unsigned char SegPat[16] = {0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67,0x3F,
0x06,0x5B,0x4F,0x66,0x6D};
unsigned char digit[6] = {0xFE,0xFD,0xFB,0xF7,0xEF,0xDF};
void main(void) {
int i, j, k;
SetClk8(); // set E clock frequency to 24 MHz
DDRB = 0xFF; //configure Port B for output
DDRP = 0xFF; //configure Port P for output
while(1) {
for (i = 0; i < 10; i++) { // pattern array start index
for (j = 0; j < 100; j++) { // repeat loop for each pattern sequence
for (k = 0; k < 6; k++) { // select the display # to be lighted
PTB
= SegPat[i+k]; // output segment pattern
PTP
= digit[k]; // output digit select value
delayby1ms(1);
// display one digit for 1 ms
}
}
}
}
}
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-36
The HCS12/MC9S12 Microcontroller
External Variables
-
A variable declared inside a function is called an internal variable.
A variable defined outside of a function is called an external variable.
An external variable is available to many functions.
External variables provide an alternative to function arguments and return values for
communicating data between functions.
- Any function may access an external variable by referring to it by name if the name has
been declared somewhere.
- The use of static with a local variable declaration inside a block or a function causes a
variable to maintain its value between entrances to the block or function.
Scope Rules
-
The functions and external variables that make up a C program can be compiled separately.
The source text of the program may be kept in several files.
The scope of a name is the part of the program within which the name can be used.
For a variable declared at the beginning of a function, the scope is the function in which the
name is declared.
- Local (internal) variables of the same name in different functions are unrelated.
- The scope of an external variable or a function lasts from the point at which it is declared
to the end of the file being compiled.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-37
The HCS12/MC9S12 Microcontroller
In the following program segment
The use of external variables are illustrated
in the following 2-file C program
…
void f1 (…)
{
…
}
in file 1
extern int xy;
extern long arr [ ];
main ( )
{
…
}
void foo (int abc) { … }
long soo (void) { … }
int a, b, c;
void f2(…)
{
…
}
Variables a, b, and c are accessible to
function f2 but not f1.
Copyright © 2010 Delmar Cengage Learning
in file 2
int xy;
long arr [100];
H. Huang Transparency No.5-38
The HCS12/MC9S12 Microcontroller
Type Casting
 Type casting forces a variable of some type into a variable of different type.
 The format is (type) variable.
 It is often used to avoid size mismatch among operands for computation.
long result;
int x1, x2;
…
result = x1 * x2;
 The value of the product of x1 and x2 would be truncated when it exceeds 16 bits.
 The solution to the problem is to use type casting:
result = ((long)x1) *((long)x2);
 Type casting also allows one to treat a variable of certain type as a variable of different
type to simplify the computation.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-39
The HCS12/MC9S12 Microcontroller
For the following declaration:
struct personal {
char name[10];
char addr [20];
char sub1[5];
char sub2[5];
char sub3[5];
char sub4[5];
} ptr1;
char *cp;
One can use type casting technique to treat the variable ptr1 as a string:
cp = (char *)&ptr1;
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-40
The HCS12/MC9S12 Microcontroller
Using the C Compilers
 The special edition C compiler from CodeWarrior has a size limit of 32 kB.
 The demo version of ImageCraft C compiler has a size limit of 8 kB.
 The GNU C compiler does not have size limit but the EGNU IDE cannot program flash
memory which limits it to download program into the on-chip SRAM only.
Accessing Peripheral Registers
Depending on the size of a peripheral register, it can be declared in one of the following
methods:
#define reg_name *(volatile unsigned char *) reg_addr // 8-bit wide register
#define reg_name *(volatile unsigned int *) reg_addr
// 16-bit wide register
The HCS12 allows all of the peripheral registers to be relocated as a block. For this reason,
the ImageCraft uses the following method to define peripheral registers:
#define
#define
#define
reg_base
reg_name1
reg_name2
0x0000
// base address
*(volatile unsigned char *) (reg_base + offset1)
*(volatile unsigned int *) (reg_base + offset2)
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-41
The HCS12/MC9S12 Microcontroller
The header file hcs12.h provided in the complementary CD uses the following format:
#define IOREGS_BASE
0x0000
#define _IO8(off) *(unsigned char volatile *)(IOREGS_BASE + off)
#define _IO16(off) *(unsigned short volatile *)(IOREGS_BASE + off)
#define PORTA
_IO8(0x00)
// port A data register
#define PTA _IO8(0x00)
// alternate name for PORTA
#define ATD0DR0 _IO16(0x90)
// ADC result 0 register (a 16-bit register
Peripheral Register Bit Definitions
 A value is assigned to each bit in the peripheral register that represents its weight.
 For example, the ADPU bit of the ATD0CTL2 register is defined to be 0x80 that is the
positional weight (bit 7) of this bit. It is defined as follows:
ADPU equ
$80
This bit can be set using the following statement:
ATD0CTL2 |= ADPU;
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-42
The HCS12/MC9S12 Microcontroller
In-line Assembly Instructions
Syntax
asm (“string”);
Examples
asm(“swi”);
asm(“cli”);
Copyright © 2010 Delmar Cengage Learning
// string is one of the valid assembly instructions
// software interrupt
// enable interrupt globally
H. Huang Transparency No.5-43
The HCS12/MC9S12 Microcontroller
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-44
The HCS12/MC9S12 Microcontroller
Using the ImageCraft C Compiler
 ICC12 IDE can work with Dragon12 demo board programmed with the D-Bug12 monitor.
 The startup screen of the ICC12 is shown in Figure 5.25.
 ICC12 is a simple IDE that consists of a text editor, a project manager, and a C compiler.
 When the user uses the ICC12 IDE for the first time, he or she needs to set up the
compiler options.
 Compiler options can be brought up by pressing the Project menu in Figure 5.25 and
selecting Options…
 A dialog box as shown in Figure 5.26 appears to allow the user to set up all options.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-45
The HCS12/MC9S12 Microcontroller
 The setting in Figure 5.26 works for the Dragon12 demo board.
 After setting up the options and clicking OK, the ICC12 C compiler will remember
all the settings until the user change them.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-46
The HCS12/MC9S12 Microcontroller
Creating a New Project
 A new project is created by pressing the Project menu and select New.
 A dialog as shown in Figure 5.27 will appear to allow the user to enter the project
name and select the project directory.
 Suppose the user enters icctutor as the project name and set project directory at
c:\books\hcs12\programs\ch05 and then clicks Save. The screen will change to that
in Figure 5.28.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-47
The HCS12/MC9S12 Microcontroller
Adding Files to the Project
 A new file can be created by pressing the File menu and selecting New to convert the
work space pane in Figure 5.25 into an editor work space.
 We will enter the program that finds the greatest common divisor (gcd) into the editor
work space as shown in Figure 5.29.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-48
The HCS12/MC9S12 Microcontroller
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-49
The HCS12/MC9S12 Microcontroller
 ICC12 Compiler requires a putchar function for the printf function to work. We
created this function and add it to this example project. This is done by pressing the
Project menu and selecting Add File(s)… to bring up the dialog for adding a file.
 The add file dialog is shown in Figure 5.30.
 After adding gcd.c and putchar.c into the project, the screen changes to that in
Figure 5.31.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-50
The HCS12/MC9S12 Microcontroller
Build the Project
 A project can be built by pressing function key F9 or pressing the Project menu and
selecting Make Project.
 Figure 5.32 shows the project build screen without any errors.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-51
The HCS12/MC9S12 Microcontroller
 ICC12 IDE does not allow the user to set up a watch list to monitor the change of program
variables. The user needs to find out the address of program variables by looking at the
program map file.
 For example, by making result a global variable and recompiling the program and browse
the icctutor.mp file, we find that result is assigned to location $1000 as shown in Figure
5.33.
 The user can then use the D-Bug12 command md $1000 to display the value of result.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-52
The HCS12/MC9S12 Microcontroller
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-53
The HCS12/MC9S12 Microcontroller
Activating the Terminal Window
 The user needs to activate the terminal window before he/she can download the
program onto the demo board.
 Terminal window is activated by pressing Terminal menu and selecting Show terminal
Window. After this, the ICC12 screen changes to that in Figure 5.34.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-54
The HCS12/MC9S12 Microcontroller
Setup Terminal Window
 The user needs to setup options of the terminal window when using it for the first
time.
 To set up the terminal window options, press the Tools menu and select Environment
Options to bring out the dialog as shown in Figure 5.35.
 The user should set the baud rate to 9600 and set flow control to none for the Dragon12
demo board. Click OK and the screen change to that in Figure 5.36.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-55
The HCS12/MC9S12 Microcontroller
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-56
The HCS12/MC9S12 Microcontroller
Downloading Program for Execution
 The first step to communicate with the D-Bug12 monitor of the demo board from
the ICC12 is to press the Open Com Port button in Figure 5.36.
 The user can then press the Enter key to bring out the D-Bug12 monitor prompt in
Figure 5.36.
 To download a file to the demo board for execution, type the command Load and then
press the Enter key. After this, the user can use the mouse to browse the directory to
select the appropriate .s19 file (icctutor.s19) to download.
 Click on the Open button in Figure 5.37 causes Windows to transfer the selected file into
main memory from the hard disk.
 Click on the Download! button in Figure 5.37 starts the download operation.
 After icctutor.s19 is downloaded, the screen will change to that in Figure 5.38.
 To execute the downloaded program, type g 1500 and then press the Enter key.
 After executing the program, the user can examine the value of result by typing the
md 1000 command.
 The user can use all of the D-Bug12 monitor commands described in in Chapter 3 to
perform program debugging.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-57
The HCS12/MC9S12 Microcontroller
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-58
The HCS12/MC9S12 Microcontroller
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-59
The HCS12/MC9S12 Microcontroller
C Programming Style
 Programming style refers to a set of rules and guidelines used when writing a program.
 The essence of good programming style is communication.
 The objective of a good programming style is to make the program easy to understand
and debug.
 A programmer uses three primary tools to communicate their intentions: comment,
naming of variables, constants, and functions, and program appearance (spacing,
alignment, and indentation).
General Guidelines to Comments
 The programmer should explain what every function does, what every variable does,
and every tricky expression or section of code.
 The comment should be added before the programmer defines a variable or writing a
function or section of code.
 Avoid obscure programming language constructs and reliance on language-specific
precedence rules.
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-60
The HCS12/MC9S12 Microcontroller
Program Documentation
All programs should include, at the beginning of the program, a comment block that
Includes at least:
 The programmer’s name
 The date of creation
 The operating system and IDE for which the program was written
 Hardware environment (circuit connection) to run the program
 Program structure (organization)
 Algorithm and data structures of the program
 How to run the program
An Example is in the next page:
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-61
The HCS12/MC9S12 Microcontroller
// ---------------------------------------------------------------------------------------------------------------// Program: RtiMultiplex7segs
// Author: Han-Way Huang
// Build Environment: CodeWarrior IDE under Windows XP
// Date: 07/09/2008
// Hardware connection: shown in Figure 4.18 of Huang’s HCS12 text
// Operation: This program shifts seven-segment patterns of 4 consecutive BCD digits
//
by using time-multiplexing technique with each pattern lasting for 0.5 s. The
//
time-multiplexing operation is controlled by the real-time interrupt. The patterns are
//
1234
//
2345
//
3456
//
4567
//
5678
//
6789
//
7890
//
8901
//
9012
//
0912
// ------------------------------------------------------------------------------------------------------------------
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-62
The HCS12/MC9S12 Microcontroller
Function Documentation
Every function should be preceded by a comment describing the purpose and use of that
Function. An example is as follows:
//-------------------------------------------------------------------------------------------------------// Function: FindSquareRoot
// Purpose: Computes and returns the square root of a 32-bit unsigned integer
// Parameter: A 32-bit unsigned integer of which the square root is to be found
// Called by: PrimeTest()
// Returned value: the square root of a 32-bit unsigned integer
// Side effects: none
//--------------------------------------------------------------------------------------------------------Code Appearance
Program reability can be improved by
 Proper spacing
 Proper indentation
 Vertical alignment
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-63
The HCS12/MC9S12 Microcontroller
Proper Spacing
for (i=0;i<15;i++)
&
for (i = 0; i < 15; i++)
easier to read
Proper Indentation
The following code is hard to read without proper indentation:
while(TRUE) {
for (i = 0; i < 10; i++) { // pattern array start index
for (j = 0; j < 100; j++) { // repeat loop for each pattern sequence
for (k = 0; k < 6; k++) { // select the display # to be lighted
PTB
= SegPat[i+k]; // output segment pattern
PTP
= digit[k]; // output digit select value
delayby1ms(1);
// display one digit for 1 ms
}
}
}
}
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-64
The HCS12/MC9S12 Microcontroller
With proper indentation, the code section becomes easier to read:
while(TRUE) {
for (i = 0; i < 10; i++) { // pattern array start index
for (j = 0; j < 100; j++) { // repeat loop for each pattern sequence
for (k = 0; k < 6; k++) {
// select the display # to be lighted
PTB
= SegPat[i+k]; // output segment pattern
PTP
= digit[k];
delayby1ms(1);
// output digit select value
// display one digit for 1 ms
}
}
}
}
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-65
The HCS12/MC9S12 Microcontroller
Vertical Alignment
It is often helpful to align similar elements vertically, to make typo-generated bugs
more obvious.
Compare the next two sections of code. It is obvious that the second one is easier to
Identify errors:
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-66
The HCS12/MC9S12 Microcontroller
Naming of Variables, Constants, and Functions
 The names of variables, constants, and functions should spell out their meaning or
purpose.
 A variable name may have one word or multiple words. Use lowercase when the name
contains only one word. For example, sum, limit, and average.
 A multiple-word variable name should be in mixed case starting with lowercase.
For example, inBuf, outBuf, squareRoot, and arrayMax.
 Function names should follow the same principle. A few examples follow:
sevenSegShift(), putcSPI(), putsSPI(), openLCD(), and putsLCD()
 Named constants should be all uppercase using underscore (_) to separate words.
SONG_TOTAL_NOTES, HI_DELAY_COUNT, LO_DELAY_COUNT
Copyright © 2010 Delmar Cengage Learning
H. Huang Transparency No.5-67
Download