📄 chapter 9 structures -- valvano.htm
字号:
<DIR>
<P> </P></DIR></DIR>
<P><FONT face="Times New Roman,Times"><A name=FSMDEFINITION></A>To place a
structure in ROM, we define it as a global constant. In the following example
the structure fsm[3] will be allocated and initialized in ROM-space. The
linked-structure finite syatem machine is a good example of a ROM-based
structure. For more information about finite state machines see Chapter 2 of the
book <U>Embedded Microcomputer Systems: Real Time Interfacing</U> by Jonathan
Valvano published by Brooks-Cole.</FONT></P>
<DIR>
<P><CODE>const struct State{<BR> unsigned char Out; /* Output to Port H */<BR> unsigned int Wait; /* Time (E cycles) to wait */<BR> unsigned char AndMask[4];<BR> unsigned char EquMask[4];<BR> const struct State *Next[4];}; /* Next states */<BR>typedef const struct State StateType;<BR>typedef StateType * StatePtr;<BR>#define stop &fsm[0]<BR>#define turn &fsm[1]<BR>#define bend &fsm[2]<BR>StateType fsm[3]={<BR>{0x34, 2000, // stop 1 ms<BR> {0xFF, 0xF0, 0x27, 0x00},<BR> {0x51, 0xA0, 0x07, 0x00},<BR> {turn, stop, turn, bend}},<BR>{0xB3,5000, // turn 2.5 ms<BR> {0x80, 0xF0, 0x00, 0x00},<BR> {0x00, 0x90, 0x00, 0x00},<BR> {bend, stop, turn, turn}},<BR>{0x75,4000, // bend 2 ms<BR> {0xFF, 0x0F, 0x01, 0x00},<BR> {0x12, 0x05, 0x00, 0x00},<BR> {stop, stop, turn, stop}}};</CODE></P></DIR>
<ADDRESS>Listing 9-2: Example of initializing a structure in ROM</ADDRESS>
<P> </P>
<P><B><I><FONT face=Helvetica,Arial><A name=POINTERS></A>Using pointers to
access structures</FONT></I></B></P>
<P><FONT face="Times New Roman,Times">Just like other variables we can use
pointers to access information stored in a structure. The syntax is illustrated
in the following examples:</FONT></P>
<DIR>
<P><CODE><BR>void Setp(void){ path
*ppt;<BR> ppt=&p; //
pointer to an existing global
variable<BR> ppt->L1.x1=5; // black line from 5,6
to
10,12<BR> ppt->L1.y1=6;<BR> ppt->L1.x2=10;<BR> ppt->L1.y2=12;<BR> ppt->L1.color=255;<BR> ppt->L2={5,6,10,12,255}; //
black line from 5,6 to
10,12<BR> ppt->direction=-1;<BR> (*ppt).direction=-1;<BR>};</CODE></P></DIR>
<ADDRESS>Listing 9-3: Examples of accessing a structure using a
pointer</ADDRESS>
<P><FONT face="Times New Roman,Times">Notice that the syntax
<B>ppt->direction</B> is equivalent to <B>(*ppt).direction</B>. The
parentheses in this access are required, because along with () and [], the
operators <B>. </B>and <B>-> </B>have the highest precedence and associate
from left to right. Therefore <B>*ppt.direction</B> would be a syntax error
because <B>ppt.direction</B> can not be evaluated.</FONT></P>
<P><FONT face="Times New Roman,Times">As an another example of pointer access
consider the finite state machine controller for the fsm[3] structure shown
above. The state machine is illustrated in Figure 9-1, and the program shown in
Listing 9-4. There is </FONT><A
href="http://www.ece.utexas.edu/~valvano/embed/chap10/chap10.htm#FSM">an example
in Chapter 10</A><FONT face="Times New Roman,Times"> that extends this machine
to implement function pointers.</FONT></P>
<P><IMG height=205 src="Chapter 9 Structures -- Valvano.files/fsm.gif"
width=387></P>
<ADDRESS>Figure 9-1: State machine</ADDRESS>
<P><A name=FSMPROGRAM></A> </P>
<DIR>
<P><CODE>void control(void){ StatePtr Pt;<BR> unsigned char Input; int Endt; unsigned int i;<BR> TSCR
|=0x80; //
TEN(enable)<BR> TMSK2=0xA2; // TOI arm,
TPU(pullup) timer/4
(500ns)<BR> DDRH=0xFF; // PortH bits 7-0 are outputs<BR> DDRJ=0x00; // PortJ bits 7-0 are inputs<BR> PUPSJ=0xFF; // Pullups J7-J0<BR> PULEJ=0xFF; // Enable pull up/down PortJ<BR> Pt=stop; // Initial State <BR> while(1){<BR> PORTH=Pt->Out; // 1) output<BR> Endt=TCNT+Pt->Wait; // Time (500
ns
each) to wait<BR> while(Endt-TCNT>0); // 2) wait <BR> Input=PORTJ; // 3) input <BR> for(i=0;i<4;i++)<BR> if((Input&Pt->AndMask[i])==Pt->EquMask[i]){<BR> Pt=Pt->Next[i]; // 4) next depends on input<BR> i=4; }}};</CODE></P></DIR>
<ADDRESS>Listing 9-4: Finite state machine controller for MC68HC812A4</ADDRESS>
<P> </P>
<P><B><I><FONT face=Helvetica,Arial><A name=FUNCTIONS></A>Passing Structures to
Functions</FONT></I></B></P>
<P><FONT face="Times New Roman,Times">Like any other data type, we can pass
structures as parameters to functions. Because most structures occupy a large
number of bytes, it makes more sense to pass the structure by reference rather
than by value. In the following "call by value" example, the entire 6-byte
structure is copied on the stack when the function is called.</FONT></P>
<DIR>
<P><CODE>unsigned char Input(port thePort){<BR> return (*thePort.addr);}</CODE></P></DIR>
<P><FONT face="Times New Roman,Times">When we use "call by reference", a pointer
to the structure is passed when the function is called.</FONT></P>
<DIR>
<P><CODE>typedef const struct {<BR> int mode; // 0 for I/O, 1 for in only -1 for out only<BR> unsigned char volatile *addr; // address<BR> unsigned char volatile *ddr;}port; // direction reg<BR>port PortJ={<BR> 0, <BR> (unsigned char volatile *)(0x0028),<BR> (unsigned char volatile *)(0x0029)};<BR>int MakeOutput(port *ppt){<BR> if(ppt->mode==1) return 0; // input only<BR> if(ppt->mode==-1) return 1; // OK, output only<BR> (*ppt->ddr)=0xff; // make output<BR> return 1;}<BR>int MakeInput(port *ppt){<BR> if(ppt->mode==-1) return 0; // output only<BR> if(ppt->mode==1) return 1; // OK, input only<BR> (*ppt->ddr)=0x00; // make input<BR> return 1;}<BR>unsigned char Input(port *ppt){<BR> return (*ppt->addr);}<BR>void Output(port *ppt, unsigned char data){<BR> (*ppt->addr)=data;<BR>}<BR>void main(void){ unsigned char MyData;<BR> MakeInput(&PortJ);<BR> MakeOutput(&PortJ);<BR> Output(&PortJ,0);<BR> MyData=Input(&PortJ);<BR>}</CODE></P></DIR>
<ADDRESS>Listing 9-5: Port access organized with a data structure</ADDRESS>
<P> </P>
<P><B><I><FONT face=Helvetica,Arial><A name=EXTENDEDADDRESS></A>Extended Address
Data Page Interface to the MC68HC812A4</FONT></I></B></P>
<P><FONT face="Times New Roman,Times">One of the unique features of the
MC68HC812A4 is its ability to interface large RAM and ROM using the data page
and program page memory respectively. Up to 1Meg bytes can be configured using
the data page system. In this example, two 128K by 8 bit RAM chips are
interfaced to the 6812 using 18 address pins (A17-A0). The 628128 is a 128K by 8
bit static RAM. When the paged memory is enabled Port G will contain address
lines A21-A16 (although the data page system can only use up to A19). The
built-in address decoder CSD must be used with the data page system. The details
of this interface can be found in Chapter 9 of the book <U>Embedded
Microcomputer Systems: Real Time Interfacing</U> by Jonathan Valvano published
by Brooks Cole.</FONT></P>
<P><IMG height=240 src="Chapter 9 Structures -- Valvano.files/Image41.gif"
width=427></P>
<ADDRESS>Figure 9-2: Extended data memory interface for the
MC68HC812A4</ADDRESS>
<P> </P>
<P><FONT face="Times New Roman,Times">We divide the software into initialization
and access. The initialization software performs the usual steps:</FONT></P>
<DIR>
<P><FONT face="Times New Roman,Times">enable E, LSTRB, CSD, R/W
outputs</FONT><FONT face=Monaco><BR></FONT><FONT
face="Times New Roman,Times">clear bit 4 in the CSCTL1 to set up CSD for the
$7000-$7FFF range</FONT><FONT face=Monaco><BR></FONT><FONT
face="Times New Roman,Times">select 1 cycle stretch on CSD</FONT></P></DIR>
<P><FONT face="Times New Roman,Times">To enable the data page system we must
also</FONT></P>
<DIR>
<P><FONT face="Times New Roman,Times">set bit 7 in WINDEF to enable the Data
Page Window</FONT><FONT face=Monaco><BR></FONT><FONT
face="Times New Roman,Times">set bits 1,0 in MXAR to enable memory expansion
pins A17-A16</FONT></P>
<P><CODE>void
RAMinit(void){<BR> MODE=0x7B //
special expanded wide
mode<BR> PEAR=0x2C; //
enable E, R/W,
LSTRB<BR> WINDEF=WINDEF|0x80; //
enable
DPAGE<BR> MXAR=0x03; //
enable A17, A16 on Port
G<BR> CSCTL0=CSCTL0|0x10; //
enable
CSD<BR> CSCTL1=CSCTL1&0xEF; //
CSD $7000 to
$7FFF<BR> CSSTR0=(CSSTR0&0xFC)|0x01;} // 1
cycle stretch on CSD</CODE></P></DIR>
<ADDRESS>Listing 9-6: Extended memory initialization on the
MC68HC812A4</ADDRESS>
<P><FONT face="Times New Roman,Times">Let A17-A0 be the desired 256K RAM
location. To access that location requires two steps</FONT></P>
<DIR>
<P><FONT face="Times New Roman,Times">set the most significant addresses A17-A12
into DPAGE register</FONT><FONT face=Monaco><BR></FONT><FONT
face="Times New Roman,Times">access $7000 to $7FFF, with the least significant
addresses A11-A0 </FONT></P>
<P><CODE>struct addr20<BR>{ unsigned char msb; // bits
19-12, only 17-12 used here<BR> unsigned int
lsw; // bits 11-0<BR>};<BR>typedef struct addr20
addr20Type;<BR>char ReadMem(addr20Type addr){ char
*pt;<BR> DPAGE=addr.msb; // set
addr bits 19-12, only 17-12 used<BR> pt=(char
*)(0x7000+addr.lsw); // set address bits
11-0<BR> return
*pt;} // read
access<BR>void WriteMem(addr20Type addr, char data){ char
*pt;<BR> DPAGE=addr.msb; //
set addr bits 19-12, only 17-12 used<BR> pt=(char
*)(0x7000+addr.lsw); // set address bits
11-0<BR> *pt=data;} //
write access</CODE></P></DIR>
<ADDRESS>Listing 9-7: Extended memory access on the MC68HC812A4</ADDRESS>
<P> </P>
<P><FONT face="Times New Roman,Times">When MXAR is active, the MC68HC812A4 will
convert all 16 addresses to the extended 22 bit addresses. When an access is
outside the range of any active page window (EPAGE, DPAGE or PPAGE), the upper 6
bits are 1. In the following table it is assumed that only the DPAGE is active,
the DPAGE register contains DP7-DP0, and MXAR is 0x3F (activating all 22 address
bits)</FONT></P>
<DIV align=right>
<P>
<TABLE cellSpacing=0 width=615 border=0>
<TBODY>
<TR>
<TD vAlign=top width="12%"><FONT
face="Times New Roman,Times">internal</FONT></TD>
<TD vAlign=top width="7%"><FONT face="Times New Roman,Times">A21</FONT></TD>
<TD vAlign=top width="7%"><FONT face="Times New Roman,Times">A20</FONT></TD>
<TD vAlign=top width="8%"><FONT face="Times New Roman,Times">A19</FONT></TD>
<TD vAlign=top width="7%"><FONT face="Times New Roman,Times">A18</FONT></TD>
<TD vAlign=top width="8%"><FONT face="Times New Roman,Times">A17</FONT></TD>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -