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

📄 chapter 1 program structure -- valvano.htm

📁 介绍了在嵌入式系统中如何用c来设计嵌入式软件
💻 HTM
📖 第 1 页 / 共 5 页
字号:
href="http://www.ece.utexas.edu/~valvano/embed/app1/app1.htm#CPPCOMMENT">compiler 
option dialog</A>). The start comment sequence is <CODE>// </CODE>and the 
comment ends at the next line break or end of file. Thus, the following two 
lines are equivalent:</P>
<DIR>
<P><CODE>OpenSCI(); /* turn on SCI serial port */<BR>OpenSCI(); // turn on SCI 
serial port</CODE></P></DIR>
<P>C does allow the comment start and stop sequences within character constants 
and string constants. For example the following string contains all 7 
characters, not just the <FONT face=Monaco>ac</FONT>:</P>
<DIR>
<P><CODE>str="a/*b*/c";</CODE></P></DIR>
<P>ICC11 and ICC12 unfortunately do not support comment nesting. This makes it 
difficult to comment out sections of logic that are themselves commented. For 
example, the following attempt to comment-out the call to <CODE>OpenSCI</CODE> 
will result in a compiler error.</P>
<DIR>
<P><CODE>void main(void){ unsigned char 
Info;<BR>/*<BR>&nbsp;&nbsp;&nbsp;OpenSCI();&nbsp;&nbsp;&nbsp;&nbsp;/* turn on 
SCI serial port 
*/<BR>*/<BR>&nbsp;&nbsp;&nbsp;DDRC=0x00;&nbsp;&nbsp;&nbsp;&nbsp;/* specify Port 
C as input 
*/<BR>&nbsp;&nbsp;&nbsp;while(1){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Info=PORTC;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* 
input 8 bits from parallel port C 
*/<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OutSCI(Info);}}&nbsp;&nbsp;/* output 8 bits 
to serial port */</CODE></P></DIR>
<P>The<A 
href="http://www.ece.utexas.edu/~valvano/embed/chap11/chap11.htm#CONDITION"> 
conditional compilation</A> feature can be used to temporarily remove and 
restore blocks of code.</P>
<P><B><I><FONT face=Helvetica,Arial><A name=PREPROCESSOR></A>Preprocessor 
Directives</FONT></I></B></P>
<P>Preprocessor directives begin with <CODE># </CODE>in the first column. As the 
name implies preprocessor commands are processed first. I.e., the compiler 
passes through the program handling the preprocessor directives. Although there 
are many possibilities (assembly language, conditional compilation, interrupt 
service routines), I thought I'd mention the two most important ones early in 
this document. We have already seen the macro definition (<B>#define</B>) used 
to define I/O ports and bit fields. A second important directive is the 
<CODE>#include</CODE>, which allows you to include another entire file at that 
position within the program. The following directive will define all the 6811 
I/O port names. </P>
<DIR>
<P><CODE>#include "HC11.h"</CODE></P></DIR>
<P>Examples of <CODE>#include</CODE> are shown <A 
href="http://www.ece.utexas.edu/~valvano/embed/chap1/chap1.htm#SOURCE">below</A>, 
and more in <A 
href="http://www.ece.utexas.edu/~valvano/embed/chap11/chap11.htm#INCLUDE">Chapter 
11</A>.</P>
<P><B><I><FONT face=Helvetica,Arial><A name=GLOBAL></A>Global 
Declarations</FONT></I></B></P>
<P>An object may be a data structure or a function. Objects that are not defined 
within functions are global. Objects that may be declared in ICC11/ICC12/Hiware 
include:</P>
<DIR>
<P>integer variables (16 bit signed or unsigned) <B><FONT 
face=Monaco><BR></FONT></B>character variables (8 bit signed or 
unsigned)<B><FONT face=Monaco><BR></FONT></B>arrays of integers or characters 
<B><FONT face=Monaco><BR></FONT></B>pointers to integers or characters <B><FONT 
face=Monaco><BR></FONT></B>arrays of pointers<B><FONT 
face=Monaco><BR></FONT></B>structure (grouping of other objects)<B><FONT 
face=Monaco><BR></FONT></B>unions (redefinitions of storage)<B><FONT 
face=Monaco><BR></FONT></B>functions </P></DIR>
<P>Both Hiware and ICC12 support 32 bit long integers and floating point. In 
this document we will focus on 8 and 16 bit objects. Oddly the object code 
generated with the these compilers is often more efficient using 16 bit 
parameters rather than 8 bit ones.</P>
<P><B><I><FONT face=Helvetica,Arial><A name=DECLARATIONS></A>Declarations and 
Definitions</FONT></I></B></P>
<P>It is important for the C programmer two distinguish the two terms 
<I>declaration</I> and <I>definition</I>. A function declaration specifies its 
name, its input parameters and its output parameter. Another name for a function 
declaration is <I>prototype</I>. A data structure declaration specifies its type 
and format. On the other hand, a function definition specifies the exact 
sequence of operations to execute when it is called. A function definition will 
generate object code (machine instructions to be loaded into memory that perform 
the intended operations). A data structure definition will reserve space in 
memory for it. The confusing part is that the definition will repeat the 
declaration specifications. We can declare something without defining it, but we 
cannot define it without declaring it. For example the declaration for the 
function <CODE>OutSCI</CODE><FONT face=Monaco> </FONT>could be written as</P>
<DIR>
<P><CODE>void OutSCI(unsigned char);</CODE></P></DIR>
<P>We can see that the declaration shows us how to use the function, not how the 
function works. Because the C compilation is a one-pass process, an object must 
be declared or defined before it can be used in a statement. (Actually the 
preprocess performs a pass through the program that handles the preprocessor 
directives.) Notice that the function <CODE>OutSCI</CODE><FONT face=Monaco> 
</FONT>was defined before it was used in the above <A 
href="http://www.ece.utexas.edu/~valvano/embed/chap1/chap1.htm#LISTING">listing</A>. 
The following alternative approach first declares the functions, uses them, and 
lastly defines the functions:</P>
<DIR>
<P><CODE>/* Translates parallel input data to serial outputs */<BR>#define PORTC 
*(unsigned char volatile *)(0x1003)<BR>#define DDRC *(unsigned char volatile 
*)(0x1007)<BR>#define BAUD *(unsigned char volatile *)(0x102B)<BR>#define SCCR2 
*(unsigned char volatile *)(0x102D)<BR>#define SCSR *(unsigned char volatile 
*)(0x102E)<BR>#define SCDR *(unsigned char volatile *)(0x102F)<BR>void 
OpenSCI(void);<BR>void OutSCI(unsigned char);<BR>void main(void){ unsigned char 
Info;<BR>&nbsp;&nbsp;OpenSCI(); /* turn on SCI serial port 
*/<BR>&nbsp;&nbsp;&nbsp;DDRC=0x00; /* specify Port C as input 
*/<BR>&nbsp;&nbsp;&nbsp;while(1){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Info=PORTC; 
/* input 8 bits from parallel port C 
*/<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OutSCI(Info);}} /* output 8 bits to serial 
port */<BR>void OpenSCI(void) { <BR>&nbsp;&nbsp;&nbsp;BAUD=0x30; /* 9600 baud 
*/<BR>&nbsp;&nbsp;&nbsp;SCCR2=0x0C;} /* enable SCI, no interrupts */<BR>/* Data 
is 8 bit value to send out serial port */<BR>#define TDRE 0x80<BR>void 
OutSCI(unsigned char Data){<BR>&nbsp;&nbsp;while ((SCSR &amp; TDRE) == 0); /* 
Wait for TDRE to be set */ <BR>&nbsp;&nbsp;SCDR=Data; } /* then output 
*/</CODE></P></DIR>
<P><I>Listing 1-7: Alternate ICC11 Program</I></P>
<P>An object may be said to exist in the file in which it is defined, since 
compiling the file yields a module containing the object. On the other hand, an 
object may be declared within a file in which it does not exist. Declarations of 
data structures are preceded by the keyword <B>extern</B>. Thus,</P>
<DIR>
<P><CODE>short RunFlag;</CODE></P></DIR>
<P>defines a 16 bit signed integer called <CODE>RunFlag</CODE>; whereas,</P>
<DIR>
<P><CODE>extern short RunFlag;</CODE></P></DIR>
<P>only declares the <CODE><B>RunFlag</B> </CODE>to exist in another, separately 
compiled, module. We will use external function declarations in the ICC11/ICC12 
VECTOR.C file when we create the reset/interrupt vector table. Thus the line</P>
<DIR>
<P><CODE>extern void TOFhandler();</CODE></P></DIR>
<P>declares the function name and type just like a regular function declaration. 
The <B>extern</B><FONT face=Monaco> </FONT>tells the compiler that the actual 
function exists in another module and the linker will combine the modules so 
that the proper action occurs at run time. The compiler knows everything about 
extern objects except where they are. The linker is responsible for resolving 
that discrepancy. The compiler simply tells the assembler that the objects are 
in fact external. And the assembler, in turn, makes this known to the 
linker.</P>
<P><B><I><FONT face=Helvetica,Arial><A 
name=FUNCTIONS></A>Functions</FONT></I></B></P>
<P>A <I>function</I> is a sequence of operations that can be invoked from other 
places within the software. We can pass 0 or more parameters into a function. 
The code generated by the ICC11 and ICC12 compilers pass the first input 
parameter in Register D and the remaining parameters are passed on the stack. A 
function can have 0 or 1 output parameter. The code generated by the ICC11 and 
ICC12 compilers pass the return parameter in Register D (8 bit return parameters 
are promoted to 16 bits.) The <CODE>add</CODE> function below has two 16 bit 
signed input parameters, and one 16 bit output parameter. Again the numbers in 
the first column are not part of the software, but added to simplify our 
discussion.</P>
<DIR>
<P><CODE>1 &nbsp;&nbsp;short add(short x, short y){ short z;<BR>2 
&nbsp;&nbsp;&nbsp;&nbsp;z=x+y; <BR>3 
&nbsp;&nbsp;&nbsp;&nbsp;if((x&gt;0)&amp;&amp;(y&gt;0)&amp;&amp;(z&lt;0))z=32767; 
<BR>4 
&nbsp;&nbsp;&nbsp;&nbsp;if((x&lt;0)&amp;&amp;(y&lt;0)&amp;&amp;(z&gt;0))z=-32768; 
<BR>5 &nbsp;&nbsp;&nbsp;&nbsp;return(z);} <BR>6 &nbsp;&nbsp;void main(void){ 
short a,b;<BR>7 &nbsp;&nbsp;&nbsp;&nbsp;a=add(2000,2000)<BR>8 
&nbsp;&nbsp;&nbsp;&nbsp;b=0<BR>9 &nbsp;&nbsp;&nbsp;&nbsp;while(1){<BR>10 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b=add(b,1);<BR>11 
&nbsp;&nbsp;}</CODE></P></DIR>
<P><I>Listing 1-8: Example of a function call</I></P>
<P>The interesting part is that after the operations within the function are 
performed control returns to the place right after where the function was 
called. In C, execution begins with the <B>main</B> program. The execution 
sequence is shown below:</P>
<DIR>
<P><CODE>6 &nbsp;&nbsp;void main(void){ short a,b;<BR>7 
&nbsp;&nbsp;&nbsp;&nbsp;a=add(2000,2000);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* 
call to add*/<BR>1 &nbsp;&nbsp;short add(short x, short y){ short z;<BR>2 
&nbsp;&nbsp;&nbsp;&nbsp;z=x+y; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* 
z=4000*/<BR>3 
&nbsp;&nbsp;&nbsp;&nbsp;if((x&gt;0)&amp;&amp;(y&gt;0)&amp;&amp;(z&lt;0))z=32767; 
<BR>4 
&nbsp;&nbsp;&nbsp;&nbsp;if((x&lt;0)&amp;&amp;(y&lt;0)&amp;&amp;(z&gt;0))z=-32768; 
<BR>5 &nbsp;&nbsp;&nbsp;&nbsp;return(z);} 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* 
return 4000 from call*/<BR>8 &nbsp;&nbsp;&nbsp;&nbsp;b=0<BR>9 
&nbsp;&nbsp;&nbsp;&nbsp;while(1){<BR>10 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b=add(b,1); 
}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* call 
to add*/<BR>1 &nbsp;&nbsp;short add(short x, short y){ short z;<BR>2 
&nbsp;&nbsp;&nbsp;&nbsp;z=x+y; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* 
z=1*/<BR>3 
&nbsp;&nbsp;&nbsp;&nbsp;if((x&gt;0)&amp;&amp;(y&gt;0)&amp;&amp;(z&lt;0))z=32767; 
<BR>4 
&nbsp;&nbsp;&nbsp;&nbsp;if((x&lt;0)&amp;&amp;(y&lt;0)&amp;&amp;(z&gt;0))z=-32768; 
<BR>5 &nbsp;&nbsp;&nbsp;&nbsp;return(z);} 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* 
return 1 from call*/<BR>11 &nbsp;&nbsp;}<BR>9 
&nbsp;&nbsp;&nbsp;&nbsp;while(1){<BR>10 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b=add(b,1); 
}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* call 
to add*/<BR>1 &nbsp;&nbsp;short add(short x, short y){ short z;<BR>2 
&nbsp;&nbsp;&nbsp;&nbsp;z=x+y; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* 
z=2*/<BR>3 
&nbsp;&nbsp;&nbsp;&nbsp;if((x&gt;0)&amp;&amp;(y&gt;0)&amp;&amp;(z&lt;0))z=32767; 
<BR>4 
&nbsp;&nbsp;&nbsp;&nbsp;if((x&lt;0)&amp;&amp;(y&lt;0)&amp;&amp;(z&gt;0))z=-32768; 
<BR>5 &nbsp;&nbsp;&nbsp;&nbsp;return(z);} 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* 
return 2 from call*/<BR>11 &nbsp;&nbsp;}</CODE></P></DIR>
<P>Notice that the return from the first call goes to line 8, while all the 
other returns go to line 11. The execution sequence repeats lines 
9,10,1,2,3,4,5,11 indefinitely.</P>
<P>The programming language Pascal distinguishes between functions and 
procedures. In Pascal a function returns a parameter while a procedure does not. 
C eliminates the distinction by accepting a bare or <CODE>void</CODE> expression 
as its return parameter. </P>
<P>C does not allow for the nesting of procedural declarations. In other words 
you can not define a function within another function. In particular all 
function declarations must occur at the global level. </P>
<P>A function declaration consists of two parts: a <I>declarator</I> and a 
<I>body</I>. The declarator states the name of the function and the names of 
arguments passed to it. The names of the argument are only used inside the 
function. In the add function above, the declarator is <B>(short x, short y)</B> 
meaning it has two 16 bit input parameters. ICC11 and ICC12 accept both 
approaches for defining the input parameter list. The following three statements 
are equivalent:</P>
<DIR>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -