⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chapter 1 program structure -- valvano.htm

📁 Developing Embedded Software in C
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<!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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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; //&nbsp;key&nbsp;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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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>&nbsp;&nbsp;&nbsp;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>&nbsp;</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 &nbsp;&nbsp;/* Translates parallel input data to 
serial outputs */<BR>2 &nbsp;&nbsp;#define PORTC *(unsigned char volatile 
*)(0x1003)<BR>3 &nbsp;&nbsp;#define DDRC *(unsigned char volatile 
*)(0x1007)<BR>4 &nbsp;&nbsp;#define BAUD *(unsigned char volatile 
*)(0x102B)<BR>5 &nbsp;&nbsp;#define SCCR2 *(unsigned char volatile 
*)(0x102D)<BR>6 &nbsp;&nbsp;#define SCSR *(unsigned char volatile 
*)(0x102E)<BR>7 &nbsp;&nbsp;#define SCDR *(unsigned char volatile 
*)(0x102F)<BR>8 &nbsp;&nbsp;void OpenSCI(void) { <BR>9 
&nbsp;&nbsp;&nbsp;&nbsp;BAUD=0x30; /* 9600 baud */<BR>10 
&nbsp;&nbsp;&nbsp;SCCR2=0x0C;} /* enable SCI, no interrupts */<BR>11 
&nbsp;&nbsp;#define TDRE 0x80<BR>12 &nbsp;&nbsp;/* Data is 8 bit value to send 
out serial port */<BR>13 &nbsp;&nbsp;void OutSCI(unsigned char Data){<BR>14 
&nbsp;&nbsp;&nbsp;&nbsp;while ((SCSR &amp; TDRE) == 0); /* Wait for TDRE to be 
set */ <BR>15 &nbsp;&nbsp;&nbsp;&nbsp;SCDR=Data; } /* then output */<BR>16 
&nbsp;&nbsp;void main(void){ unsigned char Info;<BR>17 
&nbsp;&nbsp;&nbsp;&nbsp;OpenSCI(); /* turn on SCI serial port */<BR>18 
&nbsp;&nbsp;&nbsp;&nbsp;DDRC=0x00; /* specify Port C as input */<BR>19 
&nbsp;&nbsp;&nbsp;&nbsp;while(1){<BR>20 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Info=PORTC; /* input 8 bits from parallel 
port C */<BR>21 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OutSCI(Info);}} /* output 8 
bits to serial port */<BR>22 &nbsp;&nbsp;</CODE><FONT face="Courier,Courier New" 
size=2>extern void _start(); /* entry point in crt11.s */</FONT><CODE><BR>23 
&nbsp;&nbsp;</CODE><FONT face="Courier,Courier New" size=2>#pragma 
abs_address:0xfffe</FONT><CODE><BR>24 &nbsp;&nbsp;</CODE><FONT 
face="Courier,Courier New" size=2>void (*reset_vector[])() 
={_start};</FONT><CODE><BR>25 &nbsp;&nbsp;</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 + -