📄 chapter 1 program structure -- valvano.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0056)http://www.ece.utexas.edu/~valvano/embed/chap1/chap1.htm -->
<HTML><HEAD><TITLE>Chapter 1: Program Structure -- Valvano</TITLE>
<META http-equiv=content-type content=text/html;charset=iso-8859-1>
<META content="MSHTML 5.50.3825.1300" name=GENERATOR>
<META
content="Power HD:Applications:Microsoft Office 98:Templates:Web Pages:Blank Web Page"
name=Template></HEAD>
<BODY vLink=#800080 link=#0000ff>
<P><!--Developing Embedded Software in C using ICC11/ICC12/Hiware by Jonathan W. Valvano--><B><FONT
face=Helvetica,Arial size=4>Chapter 1: Program Structure </FONT></B></P>
<P><B><I><FONT face=Helvetica,Arial>What's in Chapter 1?</FONT></I></B></P>
<DIR>
<P><A href="http://www.ece.utexas.edu/~valvano/embed/chap1/chap1.htm#SAMPLE">A
sample program introduces C</A> <FONT face=Monaco><BR></FONT><A
href="http://www.ece.utexas.edu/~valvano/embed/chap1/chap1.htm#OVERALL">C is a
free field language</A> <FONT face=Monaco><BR></FONT><A
href="http://www.ece.utexas.edu/~valvano/embed/chap1/chap1.htm#PRECEDENCE">Precedence
of the operator determines the order of operation</A><FONT
face=Monaco><BR></FONT><A
href="http://www.ece.utexas.edu/~valvano/embed/chap1/chap1.htm#COMMENTS">Comments
are used to document the software</A> <FONT face=Monaco><BR></FONT><A
href="http://www.ece.utexas.edu/~valvano/embed/chap1/chap1.htm#PREPROCESSOR">Prepreocessor
directives are special operations that occur first </A><FONT
face=Monaco><BR></FONT><A
href="http://www.ece.utexas.edu/~valvano/embed/chap1/chap1.htm#GLOBAL">Global
declarations provide modular building blocks</A> <FONT face=Monaco><BR></FONT><A
href="http://www.ece.utexas.edu/~valvano/embed/chap1/chap1.htm#DECLARATIONS">Declarations
are the basic operations</A> <FONT face=Monaco><BR></FONT><A
href="http://www.ece.utexas.edu/~valvano/embed/chap1/chap1.htm#FUNCTIONS">Function
declarations allow for one routine to call another</A> <FONT
face=Monaco><BR></FONT><A
href="http://www.ece.utexas.edu/~valvano/embed/chap1/chap1.htm#COMPOUND">Compound
statements are the more complex operations</A> <FONT face=Monaco><BR></FONT><A
href="http://www.ece.utexas.edu/~valvano/embed/chap1/chap1.htm#GVARIABLES">Global
variables are permanent and can be shared</A> <FONT face=Monaco><BR></FONT><A
href="http://www.ece.utexas.edu/~valvano/embed/chap1/chap1.htm#LVARIABLES">Local
variables are temporary and are private</A> <FONT face=Monaco><BR></FONT><A
href="http://www.ece.utexas.edu/~valvano/embed/chap1/chap1.htm#SOURCE">Source
files make it easier to maintain large projects</A> </P></DIR>
<P>This chapter gives a basic overview of programming in C for an embedded
system. We will introduce some basic terms so that you get a basic feel for the
language. Since this is just the first of many chapters it is not important yet
that you understand fully the example programs. The examples are included to
illustrate particular features of the language.</P>
<P><B><I><FONT face=Helvetica,Arial>Case Study 1: Microcomputer-Based
Lock</FONT></I></B><FONT
size=4><BR> </FONT>To illustrate the software
development process, we will implement a simple digital lock. The lock system
has 7 toggle switches and a solenoid as shown in the following figure. If the
7-bit binary pattern on Port A bits 6-0 becomes 0100011 for at least 10 ms, then
the solenoid will activate. The 10 ms delay will compensate for the switch
bounce. For information on switches and solenoids see Chapter 8 of <U>Embedded
Microcomputer Systems: Real Time Interfacing</U> by Jonathan W. Valvano. For now
what we need to understand is that Port A bits 6-0 are input signals to the
computer and Port A bit 7 is an output signal.<BR><IMG height=317
src="Chapter 1 Program Structure -- Valvano.files/AssFig0.gif" width=429><FONT
face=Helv,Helvetica> </FONT></P>
<P>Before we write C code, we need to develop a software plan. Software
development is an iterative process. Even though we list steps the development
process in a 1,2,3... order, in reality we iterative these steps over and over.
<BR> 1) We begin with a list of the inputs
and outputs. We specify the range of values and their significance. In this
example we will use PORTA. Bits 6-0 will be inputs. The 7 input signals
represent an unsigned integer from 0 to 127. Port A bit 7 will be an output. If
PA7 is 1 then the solenoid will activate and the door will be unlocked. In
assembly language, we use #define MACROS to assign a symbolic names, <B><FONT
face="Courier New" color=#ff00ff>PORTA DDRA</FONT></B>, to the corresponding
addresses of the ports, <B><FONT face="Courier New" color=#0000ff>$0000
$0002</FONT></B>.<BR><CODE>#define PORTA *(unsigned char volatile
*)(0x0000)</CODE><FONT face="Courier,Courier New" color=#008000
size=2><BR></FONT><CODE>#define DDRA *(unsigned char volatile
*)(0x0002)</CODE><FONT face="Courier,Courier New" color=#008000
size=2><BR></FONT><BR> 2) Next, we make a
list of the required data structures. Data structures are used to save
information. If the data needs to be permanent, then it is allocates in global
space. If the software will change its value then it will be allocated in RAM.
In this example we need a 16-bit unsigned counter. <FONT
face="Courier,Courier New" color=#008000 size=2><BR></FONT><FONT
face="Courier,Courier New" size=2>unsigned int cnt;</FONT></P>
<P>If data structure can be defined at compile time and will remain fixed, then
it can be allocated in EEPROM. In this example we will define an 8 bit fixed
constant to hold the key code, which the operator needs to set to unlock the
door. The compiler will place these lines with the program so that they will be
defined in ROM or EEPROM memory. <FONT face="Courier,Courier New" color=#008000
size=2><BR></FONT><FONT face="Courier,Courier New" size=2>const unsigned char
key=0x23; // key code</FONT></P>
<P>It is not real clear at this point exactly where in EEPROM this constant will
be, but luckily for us, the compiler will calculate the exact address
automatically. After the program is compiled, we can look in the listing file or
in the map file to see where in memory each structure is
allocated.<BR> 3) Next we develop the
software algorithm, which is a sequence of operations we wish to execute. There
are many approaches to describing the plan. Experienced programmers can develop
the algorithm directly in C language. On the other hand, most of us need an
abstractive method to document the desired sequence of actions. Flowcharts and
pseudo code are two common descriptive formats. There are no formal rules
regarding pseudo code, rather it is a shorthand for describing what to do and
when to do it. We can place our pseudo code as documentation into the comment
fields of our program. The following shows a flowchart on the left and pseudo
code and C code on the right for our digital lock example.<BR><IMG height=368
src="Chapter 1 Program Structure -- Valvano.files/AssFig7.gif" width=428></P>
<P><FONT face=Helv,Helvetica><BR></FONT>Normally we place the programs in ROM or
EEPROM. Typically, the compiler will initialize the stack pointer to the last
location of RAM. On the 6812, the stack is initialized to 0x0C00. Next we write
C code to implement the algorithm as illustrated in the above flowchart and
pseudo code. </P>
<P> 4) The last stage is debugging. For information on
debugging see Chapter 2 of <U>Embedded Microcomputer Systems: Real Time
Interfacing</U> by Jonathan W. Valvano. </P>
<P> </P>
<P><B><I><FONT face=Helvetica,Arial><A name=SAMPLE></A>Case Study 2: A Serial
Port 6811 Program</FONT></I></B></P>
<P>Let's begin with a small program. This simple program is typical of the
operations we perform in an embedded system. This program will read 8 bit data
from parallel port C and transmit the information in serial fashion using the
SCI, serial communication interface. The numbers in the first column are not
part of the software, but added to simplify our discussion.</P>
<DIR>
<P><CODE><A name=LISTING></A>1 /* Translates parallel input data to
serial outputs */<BR>2 #define PORTC *(unsigned char volatile
*)(0x1003)<BR>3 #define DDRC *(unsigned char volatile
*)(0x1007)<BR>4 #define BAUD *(unsigned char volatile
*)(0x102B)<BR>5 #define SCCR2 *(unsigned char volatile
*)(0x102D)<BR>6 #define SCSR *(unsigned char volatile
*)(0x102E)<BR>7 #define SCDR *(unsigned char volatile
*)(0x102F)<BR>8 void OpenSCI(void) { <BR>9
BAUD=0x30; /* 9600 baud */<BR>10
SCCR2=0x0C;} /* enable SCI, no interrupts */<BR>11
#define TDRE 0x80<BR>12 /* Data is 8 bit value to send
out serial port */<BR>13 void OutSCI(unsigned char Data){<BR>14
while ((SCSR & TDRE) == 0); /* Wait for TDRE to be
set */ <BR>15 SCDR=Data; } /* then output */<BR>16
void main(void){ unsigned char Info;<BR>17
OpenSCI(); /* turn on SCI serial port */<BR>18
DDRC=0x00; /* specify Port C as input */<BR>19
while(1){<BR>20
Info=PORTC; /* input 8 bits from parallel
port C */<BR>21 OutSCI(Info);}} /* output 8
bits to serial port */<BR>22 </CODE><FONT face="Courier,Courier New"
size=2>extern void _start(); /* entry point in crt11.s */</FONT><CODE><BR>23
</CODE><FONT face="Courier,Courier New" size=2>#pragma
abs_address:0xfffe</FONT><CODE><BR>24 </CODE><FONT
face="Courier,Courier New" size=2>void (*reset_vector[])()
={_start};</FONT><CODE><BR>25 </CODE><FONT
face="Courier,Courier New" size=2>#pragma end_abs_address</FONT></P></DIR>
<P><I>Listing 1-1: Sample ICC11 Program</I></P>
<P>The first line of the program is a <B>comment</B> giving a brief description
of its function. Lines 2 through 7 define <B>macros</B> that provide programming
access to I/O ports of the 6811. These macros specify the format (unsigned 8
bit) and address (the Motorola microcomputers employ memory mapped I/O). The
<B>#define</B> invokes the preprocessor that replaces each instance of
<B>PORTC</B> with <B>*(unsigned char volatile *)(0x1003</B>). For more
information see <A
href="http://www.ece.utexas.edu/~valvano/embed/chap11/chap11.htm#MACRO">the
section on macros in the preprocessor chapter</A>. </P>
<P>Lines 8,9,10 define a <B>function</B> or procedure that when executed will
initialize the SCI port. The assignment statement is of the form
<CODE>address=data;</CODE> In particular line 9 (<CODE>BAUD=0x30;</CODE>) will
output a hexadecimal $30 to I/O configuration register at location $102B.
Similarly line 10 will output a hexadecimal $0C to I/O configuration register at
location $102D. Notice that comments can be added virtually anywhere in order to
clarify the software function. <B>OpenSCI</B> is an example of a function that
is executed only once at the beginning of the program. Another name for an
initialization function is <B>ritual</B>.</P>
<P>Line 11 is another <B>#define</B> that specifies the transmit data ready
empty (TDRE) bit as bit 7. This <B>#define</B> illustrates the usage of macros
that make the software more readable. Line 12 is a comment Lines 13,14,15 define
another function, <B>OutSCI</B>, having an 8 bit input parameter that when
executed will output the data to the SCI port. In particular line 14 will read
the SCI status register at $102E over and over again until bit 7 (TDRE) is set.
Once TDRE is set, it is safe to start another serial output transmission. This
is an example of Gadfly or I/O polling. Line 15 copies the input parameter,
Data, to the serial port starting a serial transition. Line 15 is an example of
an I/O output operation. </P>
<P>Lines 16 through 21 define the main program. After some brief initialization
this is where the software will start after a reset or after being powered up.
The sequence <B>unsigned char Info</B> in line 16 will define a local variable.
Notice that the size (<B>char</B> means 8 bit), type (<B>unsigned</B>) and name
(<B>Info</B>) are specified. Line 17 calls the ritual function <B>OpenSCI</B>.
Line 8 writes a 0 to the I/O configuration register at $1007, specifying all 8
bits of PORTC will be inputs (writing ones to a direction register specifies the
current bits as outputs.) The sequence <B>while(1){ }</B> defines a control
structure that executes forever and never finishes. In particular lines 20 and
21 are repeated over and over without end. Most software on embedded systems
will run forever (or until the power is removed.) Line 20 will read the input
port C and copy the voltage levels into the variable Info. This is an example of
an I/O input operation. Each of the 8 lines that compose PORTC corresponds to
one of the 8 bits of the variable Info. A digital logic high, voltage above +2V,
is translated into a 1. A digital logic low, voltage less than 0.7V) is
translated into a 0. Line 21 will execute the function <B>OutSCI</B> that will
transmit the 8 bit data via the SCI serial port.</P>
<P>With ICC11/ICC12 lines 22 through 25 define the reset vector so that
execution begins at the<B> _start</B> location. With Hiware, we would delete
lines 22-25, and specify the reset vector in the linker file, *.prm. With both
the Hiware and Imagecraft compilers, the system will initialize then jump to the
main program. </P>
<P><B><I><FONT face=Helvetica,Arial><A name=OVERALL></A>Free field
language</FONT></I></B></P>
<P>In most programming languages the column position and line number affect the
meaning. On the contrary, C is a free field language. Except for preprocessor
lines (that begin with <B>#</B>, see <A
href="http://www.ece.utexas.edu/~valvano/embed/chap11/chap11.htm">Chapter
11</A>), spaces, tabs and line breaks have the same meaning. The other situation
where spaces, tabs and line breaks matter is string constants. We can not type
tabs or line breaks within a string constant. For more information see <A
href="http://www.ece.utexas.edu/~valvano/embed/chap3/chap3.htm#STRING">the
section on strings in the constants chapter</A>. This means we can place more
than one statement on a single line, or place a single statement across multiple
lines. For example the function <B>OpenSCI</B> could have been written without
any line breaks</P>
<DIR>
<P><CODE>void OpenSCI(void){BAUD=0x30;SCCR2=0x0C;}</CODE></P></DIR>
<P><I><FONT face="Times New Roman,Times">"Since we rarely make hardcopy
printouts of our software, it is not necessary to minimize the number of line
breaks."</FONT></I></P>
<P>Similarly we could have added extra line breaks</P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -