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

📄 chapter5.htm

📁 嵌入式软件开发.rar
💻 HTM
📖 第 1 页 / 共 5 页
字号:
        Error_handler *temp = error_();
          
        if(tp->number >4)  /* error must be between 1 and 4 */

             	return FALSE;
        if(tp->OC1_connect>4)	
    	      return FALSE;        /* got a bad OC1_connect */
        if(tp->connect_data >4)
    		return FALSE;        /* got bad connect_data*/
        this=(Timer*) malloc(sizeof(Timer));
        if(this==NULL)
    		error_handler(temp,TYPE_1,TIMER);
        memmove(this, temp, sizeof(Error_handler));
        error__(temp);
        /* initialize the GPT  */
        GPT_MCR.IARB=GPT_IARB; /* pick an IARB for the timers */  
        ICR.IRL=GPT_LEVEL;     /* interrupt level 6 */                           
        ICR.VBA=GPT_VBA;       /* vectors start at 0x50 */        
        this->who_am_I=tp->number; /* save the number of the timer */
        this->ms_tick=tp->tick;
        this->reset=reset;     /* put reset function in place */
        if(tp->OC1_connect>0 && tp->OC1_connect<5)	 /* set up the OC1        		
    			         		        connections */
        {
    	   	switch(tp->OC1_connect)
    		{
    	   	     case 1 : OC1M.OC1M3=ON;
    	                  OC1D.OC1D3=tp->connect_data;
    			       	break;
    	         case 2 : OC1M.OC1M4=ON;
    			    	OC1D.OC1D4=tp->connect_data;
    		    	      break;
                 case 3 : OC1M.OC1M5=ON;
    			    	OC1D.OC1D5=tp->connect_data;
    	   		    	break;    
    	         case 4 : OC1M.OC1M6=ON;
    			    	OC1D.OC1D6=tp->connect_data;
    		          	break;
    	    }
        }
        this->hook_object=NULL;
        this->hook_method=NULL;
        switch(tp->number)
        {
    	case 1: TFLG1.OC1F=OFF;    	 /* reset event flag */       
    	        TOC1=TCNT+tp->tick;	 /* set output compare register */
    		    vector(OC1Isr,VAL*(GPT_VBA*0x10+OC1_offset));
    		                      /* put vector in place */
    		    if(tp->interrupt)  	 /* do we need an interrupt? */
    			    TMSK1.OC1I=ON; 	 /* enable the interrupt*/
    		    OC1_T=this;        	 /* keep Timer pointer */
    		    break;			   
     	case 2: TFLG1.OC2F=OFF;           
        	    OMLREG.OML2=tp->action; 
    		    TOC2=TCNT+tp->tick;
    		    vector(OC2Isr,VAL*(GPT_VBA*0x10+OC2_offset));
        		if(tp->interrupt) 
        		    TMSK2.OC2I=ON;
        		OC2_T=this;
    		    break;
     	case 3: TFLG1.OC3F=OFF;           
        		OMLREG.OML3=tp->action; 
    		    TOC3=TCNT+tp->tick;
        		vector(OC3Isr,VAL*(GPT_VBA*0x10+OC3_offset));
        		if(tp->interrupt) 
        			TMSK2.OC3I=ON;
        		OC3_T=this;
    		    break;
     	case 4: TFLG1.OC4F=OFF;           
        		OMLREG.OML4=tp->action; 
    		    TOC4=TCNT+tp->tick;
        		vector(OC4Isr,VAL*(GPT_VBA*0x10+OC4_offset));
        		if(tp->interrupt) 
        			TMSK2.OC4I=ON;
        		OC4_T=this;
    		    break;
    	   }
        return this;
    }

    void timer__(Timer* this)
    {
        switch(this->who_am_I)
        {

            case 1 : TMSK1.OC1I=OFF;  /* turn off the timer interrupt */
                     break;
            case 2 : TMSK1.OC2I=OFF; 
                     break;
            case 3 : TMSK1.OC3I=OFF; 
                     break;
            case 4 : TMSK1.OC4I=OFF; 
                     break;
         }
         free(this);
    }

    /* interrupt service routines */

    @port void OC1Isr(void) 
    { 
        TFLG1.OC1F=OFF;           
        TOC1+=OC1_T->ms_tick;
        do_hook(OC1_T);       
    }

    @port void OC2Isr(void) 
    { 
        TFLG1.OC2F=OFF;           
        TOC2+=OC2_T->ms_tick;
        do_hook(OC2_T);       
    }
      
    @port void OC3Isr(void) 
    { 
        TFLG1.OC3F=OFF;           
        TOC3+=OC3_T->ms_tick;
        do_hook(OC3_T);       
    }

    @port void OC4Isr(void) 
    { 
        TFLG1.OC4F=OFF;           
        TOC4+=OC4_T->ms_tick;
        do_hook(OC4_T);       
    }

    /* function that allows external access to isr */

    static void do_hook(Timer *time)
    {
        if(time->hook_method !=NULL)
           (*time->hook_method)(time->hook_object);
    }
</code></pre>
<h4><pre>
	Listing 5.2 Timer Class Implementation File
</pre></h4>
<p>	The above basic timer class will provide a starting point for several other example 
classes to be developed in the following examples.  Timer is a very good example of a 
software component.  It will be used in conjunction with several other classes that are all 
based on working in time.  Assuming that the class has been completely debugged, object 
of the type Timer can be used without fear of either failure to perform its designated task 
or unexpected side effects caused by leakage between memory areas.  None of the 
attributes of  Timer should be accessed except through the methods provided.  If it 
becomes necessary to access an attribute, a separate method, perhaps created in an 
inherited class, should be created to handle this contingency.  Usually, the code in a 
header file and its associated implementation file should never be changed.  A case 
where we will allow such a change is for the addition of macro methods.  These cases 
pose a dilemma.  Such a change should be associated with the class code, and we do not 
want to alter the class code directly.  Use inheritance in any but the most basic of 
changes, and then put any new macros into the header file of the affected class.  Do not 
change the implementation file ever.  If it is necessary to change features found in the 
implementation file, use inheritance to isolate the changed code from the known working 
and debugged code.  
	
<h3><a name="delay">Delay</a></h3>

<p>	The first example that will make use of  Timer is to create a delay.  Often it is 
necessary to delay execution of a program by a specified amount of time.  It is expected 
that in these cases, a Timer can be made available to effect the delay.  Recall, Timer 
needs a tick value that is usually aimed to produce an event on a relatively short time 
basis.  Certainly, the size of the number to be added to the output compare register should 
be represented in an unsigned integer which is the size of the Timer Counter Register.  
With the microcontroller running at 16 mHz, the time required to overflow this register is  
16 milliseconds.  With proper set-up of the timer prescaler, this time can be extended to 
approximately 4000 milliseconds.  Therefore, most timers have periods that lie in this 
range of values.  Also, you should have noted that if a Timer is properly instantiated, it 
will run periodically with an interrupt occurring each time the Timer Counter Register 
matches the corresponding Output Compare Register.  This arrangement makes Timer a 
perfect base for a delay.  A Timer will be created that has some convenient base 
frequency or time of interrupt.  The delay is set up to count the number of interrupts, and 
when the specified number of interrupts occur, the delay is released.  Here is a case 
where the <a href="chapter7.htm#semaphore">semaphore</a> as discussed in Chapter 3 can be used to an advantage.  The calling 
program that initiates the delay will create a semaphore.  This semaphore will be 
attached to the delay, and the calling program will be put into a wait_for_semaphore() 
call which will stop the execution of the calling program until the semaphore is released 
by the delay program.  The delay program will wait until the proper number of ticks from 
the base Timer and then delete itself which will automatically release the semaphore 
allowing the calling program to proceed.  
<p>	In the delay header file shown below, you will note that these objects will access 
error.h, timer.h, semaphore.h and defines.h.  The class is set-up to have delay inherit the 
error_handler.  There are three attributes, the delay time, a pointer to the specified timer 
and a pointer to the semaphore.  These three parameters are passed to the delay 
constructor as arguments.
<pre><code>
    #ifndef DELAY_H 
    #define DELAY_H

    #include "error.h"
    #include "timer.h"
    #include "semaphor.h"
    #include "defines.h"

    #define DELAY_CLASS  \
    			ERROR_HANDLER   \
    			unsigned int delay_time; \
    			struct time *Time;\
    			Semaphore *semaphore;

    typedef struct delay              
    {
    	DELAY_CLASS    
    }Delay;
    		
    struct delay *delay_(struct time*, Semaphore*,unsigned int);
    void delay__(struct delay *);
    #endif
<h4>
	Listing 5.3 Delay Class Definition File
    </h4>
</code></pre><p>
 	The implementation of delay needs access to a function that we will call 
exercise().  The Timer interrupt occurs at a rate specified when the timer is instantiated.  
Normally, this rate is relatively fast, and when a program delay is needed, that time is 
usually longer than the timer interrupt rate.  Therefore, we must pass a number to the 
delay that is the number of timer interrupts needed to be executed during the delay time.  
This number is the third argument of the delay constructor.  This number, called 
delay_time, is stored in the object.  The function exercise() decrements this number until 
it becomes zero.  At that time, the delay object is deleted.  The operations done during 
delete are discussed below.
<p>	The delay constructor, delay_(), follows the general plan used in most other 
constructors.  Delay is inherited from the Error_handler, so, a temporary Error_handler 
object is created .  Space is allocated to hold the delay object and the temporary 
Error_handler is moved into this space.  The Error_handler is then deleted.  The timer 
pointer and the semaphore pointer are moved into the newly created object and the 
semaphore is attached to the delay.  The delay time passed into the constructor is stored 
in the delay_time location of the new object.  Finally, a pointer to the delay is placed in 
the hook object location of the timer object and a pointer to the function exercise is put 
into the hook method location in the timer object.  Therefore, the function exercise for 
this delay will be executed during each timer interrupt service routine. Lastly, a pointer to 
the newly created delay object is returned to the calling program.
<pre><code>
    #include "delay.h"

    static void exercise(Delay *delay)
    {
        if(--delay->delay_time==0)
        {
            delay__(delay); /* delete the delay */
        }
    }

    Delay* delay_(Timer *Time,Semaphore *sem, unsigned int delay_time)
    {
        Delay *this;
        Error_handler *temp=error_();
        
        this = (Delay* ) malloc(sizeof(Delay));
        if(this==NULL)
    		error_handler(temp,TYPE_1,DELAY);
        memmove(this,temp,sizeof(Error_handler));
        error__(temp);
        this->Time=Time;
        this->semaphore=sem;                                      
        attach_semaphore(this->semaphore); /* attach semaphore 
    								to process */                                                                         
        this->delay_time=delay_time;
        attach_object(Time,(void*)this); 	 /* put hook object in             
    				                   place */
        attach_method(Time,exercise);	    /* and the hook method */

⌨️ 快捷键说明

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