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

📄 chapter5.htm

📁 嵌入式软件开发.rar
💻 HTM
📖 第 1 页 / 共 5 页
字号:
they should be changed within the #define statements shown earlier.  
<p>	The input-output control block pointer is given a value, and the parameters 
call_complete and io_command are initialized.  This component is used as an output only 
so the command should never change during the program.
<p>	An instance of a timer is needed with this program.  The timer parameter block is 
filled with the appropriate values.  Timer number 3 is used, the tick value of 
TIMECOUNT will provide 1 ms interrupts. There is no output compare 1 connection or 
action with this timer object, and we will need an interrupt.  The timer is then 
instantiated as t3.  We will then attach a pointer to the function count_ticks() to the 
hook_method and a pointer to the memory location count to the hook_object in the 
instance of the timer t3.
<p>	In a final bit of initialization, the value of count is set to zero, and the system 
interrupts are enabled.  After this initialization, the system should be operating properly 
with all interrupts enabled and occurring when called for.
<pre><code>
main()
    {
    	/* initialize the program */
    	 
        /* initialize the SIM registers */
        SYNCR.X=ON;     /* double the clock speed--16.00 mHz */
        SYPCR.SWE=OFF;  /* disable the watchdog */
        CSORBT.DSACK=0; /* use zero wait states for now */              
      
        /* set up the serial communications */
        sio=serial_io_(SERIO_BAUD_19200,     /* set the baud rate   */ 
    			   SERIO_INT_VECTOR,     /* interrupt vector */
    		        SERIO_IARB,           /* iarb   */
    			   SERIO_INT_LEVEL);     /* and interrupt level */
                                        
        /* set up the io block */      
        oob1=&ob1;
        oob1->call_complete=TRUE;   /* start with no message in progress */                      
        oob1->io_command=OUTPUT;    /* make this block for outputs */
                                        
        /* set up the timer parameter structure */
        tp.number=3;    	/* use output compare number 3 */
        tp.tick=TIMECOUNT;  /* 1 ms interrupts */
        tp.action=0;        /* no output action */
        tp.OC1_connect=0;   /* OC1 not connected to another OC */
        tp.connect_data=0;
        tp.interrupt=YES;   /* need an interrupt here */
        t3=timer_(&tp);	  	/* instantiate the timer */
        attach_object(t3,&count); /* attach object and method to timer*/
        attach_method(t3,count_ticks);  
     
        /* initialize application program details */
        count=0;
        cli();          /* enable the system interrupts */
</code></pre><p>

	The next program section is usually called the applications section.  It is in this 
section that all continuing business that must be executed by the program is processed.  
In this case, the applications section is relatively simple.  Note that, as usual, the 
applications section is comprised of a code loop that executes FOREVER.  That is not to 
say that the code never exits this loop, but rather the loop is executed and interrupts will 
remove control to the interrupt service routines within the program.  When ever there is 
no interrupt service being handled, control will be returned to the FOREVER loop.
<p>	The code within the loop in this case will maintain a time-of-day clock.  
Whenever the value stored in count exceeds or equals the value ONE_SECOND, count is 
reset to zero and seconds is incremented.  If the incremented value of seconds is greater 
than or equal to 60, seconds is reset to zero and minutes is incremented.  And so forth, for 
the minutes and the hours.  You will note that hours, minutes, seconds, and count are 
each of the type WORD which is an unsigned integer.  Therefore, these parameters can 
never have a negative value.  Also the test to determine the value in each case is greater 
than or equal to.  We should expect that these values will never exceed the test values 
shown.  However if any should by some accident, the greater than or equal along with the 
use of the unsigned variable type will guarantee that the values of these parameters will 
be kept within their acceptable ranges of values. 
<p>The range of minutes and seconds is from zero to fifty-nine.  If the value of either 
of these variables is ever found to be sixty, it is reset to zero.  The range of hours is from 
one to twelve.  Note that hours is reset to one whenever its incremented value becomes 
thirteen or greater.
<p>	Note that the code to keep the time is executed only when the value of count 
becomes ONE_SECOND.  Also, build_time() and output_time() are executed at this 
time.  Therefore, a new time will be sent to the serial port once each second.
<pre><code>		
        /* end of initialization and beginning of the applications
           section of the program */
        FOREVER
        {
	    	if(count>=ONE_SECOND)
	    	{
	    		count=0;
	    		if(++seconds>=60)
	    		{
	    			seconds=0;
	    			if(++minutes>=60)
	    			{        
	    				minutes=0;
	    				if(++hours>=13)
	    					hours=1;
	    			}
	    		}
	    		build_time();
	    		output_time();
	    	}
        }
    }
</code></pre><p>
	The next portion of the program is the inclusion of the functions needed for the 
applications portion of the program.  There are three functions in this case.  These 
functions are output_time(), build_time(), and convert_itoa().  They are shown below.  
Let us examine build_time() first.  This function receives no arguments, but it uses the 
values stored in the external variables hours, minutes, and seconds.  These values are 
integer values that must be converted to character values before they can be sent to the 
serial port.  A pointer to the message area pszMessage and the value of hours is sent to 
the function convert_itoa().  This function converts the integer value to two characters 
less than 100 and puts these characters in the memory area pointed to by the argument p.  
A character ':' is then put into the message area, and the value of minutes is converted to 
two characters and placed into the message area.  Finally, this sequence is repeated for 
the seconds, and the data are then ready to be sent to the serial port.  
<p>	The  data are converted to character form by the function convert_itoa()  This 
function receives two parameters: first the value to be converted and second a pointer to 
the memory area where the result is to be stored.  The conversion merely evaluates the 
number of tens in the value and adds a character zero to this value.  It then evaluates the 
number of units in the number and adds a character zero to the number of units.  These 
characters are put into the proper memory locations as they are calculated.  
<p>	The final function needed to complete the applications portion of the program is 
called output_time().  This function first waits until there is no message being sent out 
the serial port.  When the serial port is available, new values are placed in the io 
command block, and the output message is sent to the serial_io object.  This object in 
turn sends the message contained in pszMessage[] to the serial port.
<pre><code>
    /* functions needed for the applications portion of the program */             
    		
    /* send out the time message  */

    void output_time(void)
    {
    	while(!oob1->call_complete)
    		;                     /* wait until any other message is out */     
    	oob1->buffer=pszMessage;  /* clear out the background */
    	oob1->buffer_length= sizeof pszMessage;
    	serial_io(sio,oob1);      /* message to the i/o object */
    }

    /* This routine builds the time message to be sent out. */

    void build_time(void)
    {
        BYTE *p=pszMessage;

        convert_itoa(hours,p);
        p+=2;
        *p++=':';
        convert_itoa(minutes,p);
        p+=2;
        *p++=':';
        convert_itoa(seconds,p);
        p+=2;
        *p++='\r';
        *p='\0';
    }

    /* This routine converts an unsigned integer, a, into an ascii
       string of the value and puts the results into the string pointed
       to by p.  */

    void convert_itoa(WORD a,BYTE *p)
    {
        *p++=(a/10)+'0';
        *p=(a%10)+'0';
    }
</code></pre><p>

	There is only one function left that is needed to complete this program.  Recall 
that count_ticks() is attached to the hook of the timer object.  In this case the hook 
method is very simple.  All it must do is to increment count and return.  In later cases, the 
hook method will be somewhat more complicated. 
<pre><code>
    /* function needed for the interrupt service routine */
    /* the timer is interrupted each millisecond.  
       count_ticks keeps track of the number of 
       interrupts that have occurred. */


    void count_ticks(WORD *a)
    {
    	++*a;
    }
</code></pre><p>
	Usually when a program is shown in small pieces as was done above, the whole 
program is listed immediately following the description.  In this case, I plan to expand on 
this program significantly in the next two programs.  Therefore, the total listing of the 
above program will not be included here, nor anywhere, but it will be replaced by a total 
listing of one of the following programs.  The above program shows the insertion of a 
single function into the hook part of the timer object.  The program that follows will 
expand on that idea a little.  In this case, rather than a single function being put into the 
timer object, a linked list of several programs will be used.  Each timer interrupt will 
cause the several functions in the link list to be executed.  Again the program will be 
broken into small segments for descriptive purposes.  The changes in this program are 
incremental changes in the above program.  Therefore, only the changes will be 
examined.  The changes will be highlighted so they can be easily seen.
<h3><a name="clock1">Clock1</a></h3>

<p>	In this program, we are going to make use of the linked list developed in Chapter 
3. Recall that the linked list hooked link objects together into a list.  Each link object 
contained a pointer to a single object.  The linked list class contains a method called 
walk_list().   When walk_list() is executed, the object method named exercise() is 
executed for each object in the linked list.  These capabilities can be used to advantage 
when it is needed to have more than one distinct function executed at each timer 
interrupt.
<p>	The #include files needed for this program are shown in the program segment 
below.  The new files here are object.h, link.h and linklist.h.  The class object differs 
from the class object in that it allows  the routine exercise to be specified as a parameter 
to the constructor that creates the various instances of the type <a href="chapter7.htm#object">Object</a>.   We saw 
applications of <a href="chapter7.htm#link">link.h</a> and 
<a href="chapter7.htm#link_list">linklist.h</a> in Chapter 3.   
<pre><code>                              
    #include "HC16Y1.H"
    #include "gpt.h"
    #include "mcci.h"
    #include "scim.h" 
    #include "serio.h"
    #include "timer.h"
    #include "defines.h"
    <strong>#include "object.h"
    #include "link.h"
    #include "linklist.h"</strong>
</code></pre><p>
The same #define constants are needed with this program.  One additional piece 
of business will be added to the program.  Here we will have a timer function that will 
cause a transaction to take place each half second.  We must, therefore, add a value 
named ONE_HALF_SECOND to our list of #defined constants as shown below.   Also, a 
function that is used to determine the occurrence of half second periods is needed.  The 
function prototype of this function is added to the function prototype list.

<pre><code>
    #define SERIO_BAUD_19200 19200
    #define SERIO_INT_VECTOR 0x40
    #define SERIO_IARB 10
    #define SERIO_INT_LEVEL 3
    #define TIMECOUNT 4000
    #define ONE_SECOND 1000
    <strong>#define ONE_HALF_SECOND 500</strong>

    /* function prototypes */

    void output_time(void);
    void build_time(void);
    void convert_itoa(WORD a,BYTE *p);
    <strong>void count_half_second_ticks(void);</strong>
    void count_second_ticks(void);
</code></pre><p>
	Some objects of the type <a href="chapter7.htm#object">Object</a>, 
<a href="chapter7.htm#link">Link</a> and <a href="chapter7.htm#link_list">Link_list</a>
 are needed for this program.  
Pointers to variables of these types are defined in the external memory area below.  There 
will be two Object types that will be placed in the linked list.  These objects are 
identified as l1 and l2.  Also, the linked list must be preloaded with a null object.  This 
object is called null.  These objects are embedded in link objects named lnk1, lnk2 and 
lnknull.  Finally, they will all be hooked together in a single linked list named list1.
<pre><code>					           
    BYTE pszMessage[]="         \r"; /* array to hold the time */
    io_command_block *oob1,ob1;
    WORD hours, minutes, seconds;
    WORD count_half_seconds,count_seconds;
    Boolean second_flag,one_

⌨️ 快捷键说明

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