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

📄 mc_timer.c

📁 simulink real-time workshop for dragon12 development board from
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Author  : Frank Wornle
 *
 * File    : mc_timer.c (Freescale 9S12DP256C - ECT)
 *
 */

/* Microcontroller specific and system headers */
#include <mc9s12dp256.h>		      /* port definitions etc. */
#include <float.h>
#include <math.h>                 /* floor */

/* System macros (EXT_MODE, etc.) -- generated by 'gen_cpp_req_defines_h.tlc' */
#include "cpp_req_defines.h"

/* RTW headers */
#include "tmwtypes.h"
#include "mc_main.h"      				/* model_run() */
#include "mc_timer.h"					/* macros... */



/* global variables */
static uint32_T  timerTicks;          /* timer runs with a resolution of 100 us... fw-02-05 */
static uint32_T  timerTicksReload;    /* reload value for 'timerTicks' */


#if CORE_TIMER == CORE_RTI	/* RTI */
/* Function: init_timebase =============================================================
 *
 * Abstract:
 *      Initialise 'time base' (core time RTI)
 */
void init_timebase(time_T sampleTime) {

time_T    temp;
uint16_T  RTR = 0x0010;
uint16_T  p = 1;


	#if TARGET_BOARD == 1
		#define  MIN_PERIOD         0.000256		// RTI minimum period
		#define  MAX_PERIOD			0.262144		// RTI maximum period
		#define  MIN_FREQ			3906.25
	#endif
	#if ((TARGET_BOARD == 2) | (TARGET_BOARD == 3))
		#define  MIN_PERIOD         0.000064		// RTI minimum period
		#define  MAX_PERIOD			0.065526		// RTI maximum period
		#define  MIN_FREQ			15625
	#endif

	/* check if variable 'timerTicks' has to be used to extend range of timer */
	if(sampleTime >= MAX_PERIOD) {

		RTICTL = 0x10; // RTI control register, setup timer for a base resolution of 0.256us(0.064us for MiniDragon+)

		/* sample period in units of base resolution */
		timerTicks = (uint32_T)(sampleTime*MIN_FREQ);	//timerTicks = (uint32_T)(sampleTime/base resolution);
		timerTicksReload = timerTicks;	  
	  
	} else {
	  
	  /* no -> program exact value */
		/* determine settings of the core timer RTI */
		while(sampleTime*MIN_FREQ>(time_T)p && RTR != 0x007F){
			temp = sampleTime*MIN_FREQ - (time_T)p;
			RTR++;
			p = ((RTR & 0x000F) + 1) << ((RTR >> 4) - 1);
		}
		if ( ((time_T)p-sampleTime*MIN_FREQ) > temp ) RTR--;
		RTICTL = (uint8_T)RTR; // RTI control register
	
		/* reset 'timerTicks' -> every interrupt counts... */
		timerTicks = 1;
		timerTicksReload = timerTicks;	  
	  
	}
	
} /* End of init_timebase */

#endif	/* CORE_TIMER == CORE_RTI */


#if CORE_TIMER == CORE_T7ISR	/* TC7 */
/* Function: init_timebase =============================================================
 *
 * Abstract:
 *      Initialise 'time base' (core time TC7)
 */
void init_timebase(void) {

uint16_T	n = 1;			/* base period multiplier: 1 = 2.73 ms, 2 = 5.46 ms, ... 128 = 349.5 ms */
uchar_T   PR0_2 = 0;    	/* bits PR0, PR1, PR2 (see TSCR2) */
time_T		sampleTime;		/* time base as set in the block diagram */


#define  MIN_PERIOD			0.002730625		// Timer 7 minimum period : 2.73 ms  (65536*42 ns = 2.73 ms)
#define  MAX_PERIOD			MIN_PERIOD*128	// maximum period : 349.5 ms (MIN_PERIOD * 2^7 = 349.5 ms)

	/* Determine the base sample rate (sampletime) -> this one is used by the 'solvers' (minor integration step)
	 * continuous states also use this minimum value
	 */
	sampleTime = rtmGetStepSize(S);

  /* setup core timer T7 */
  /* note these three lines have to precede the remaining initialisation to allow the code to run 
   * in release mode (otherwise only debug/monitor mode is possible... strangely! supposedly a timing 
   * timing issue.  --  fw-03-05  (see /microcontroller/_work/_oddErrors/myOddTimer for further details)
   */
  TIOS  |= 0x80;      // Configure channel 7 for output compare (OC) mode
  TCTL1 &= 0x3F;      // 00xx.xxxx -> OM7 = OM7 = 0 (disconnect pin 'IOC7' from o/p logic)
  OC7M   = 0x00;      // do not affect any of the linked output pins (IOC0 - IOC6)


	/* check if variable 'timerTicks' has to be used to extend range of timer */
	if(sampleTime >= MAX_PERIOD) {

		/* yes -> setup timer for a base resolution of 100 us */
		/* Bottom three bits of TSCR2 (PR2,PR1,PR0) determine TCNT period
				 divider   resolution   maximum period  
		  000      1          42ns         2.73ms
		  001      2          84ns         5.46ms
		  010      4         167ns         10.9ms
		  011      8         333ns         21.8ms
		  100     16         667ns         43.7ms
		  101     32        1.33us         87.4ms
		  110     64        2.67us        174.8ms
		  111    128        5.33us        349.5ms    */ 
		TSCR2  = 0x08;    // Divide clock by 1, disable TOI (timer overflow interrupt)
						  // TCRE = 1 (reset TCNT upon output compare match of channel 7)
		TC7 = 2400;       /* actual period : 2400 * 1/24e6 = 100 us */

	/* sample period in units of base resolution */
		timerTicks = (uint32_T)(sampleTime*10000);		//timerTicks = (uint32_T)(sampleTime/1e-4);
		timerTicksReload = timerTicks;	  
	  
	} else {
	  
	  /* no -> program exact value */
		/* determine settings of the core timer T7 */
		while (sampleTime > ((time_T)MIN_PERIOD)*n)	{
			n <<= 1;					/* insufficiently long maximum period -> try next slower period */
			PR0_2++;          /* new value of PR0, PR1, PR2 */
		}
		TSCR2  = 0x08|PR0_2;	// Divide clock by 128, disable TOI (timer overflow interrupt)
								// TCRE = 1 (reset TCNT upon output compare match of channel 7)
		/* Calculate reload value for timer T7 */
		TC7 = (uint16_T)(65536 * sampleTime/(((time_T)MIN_PERIOD)*n));
	
    /* reset 'timerTicks' -> every interrupt counts... */
    timerTicks = 1;
    timerTicksReload = timerTicks;	  
	  
	}
	
	TSCR1  = 0x80;      // enable timer 7 (set TEN bit)
	TFLG1  = 0x80;      // initially clear C7F (event flag for channel 7)
  
} /* End of init_timebase */

#endif	/* CORE_TIMER == CORE_T7ISR */



#if CORE_TIMER == CORE_RTI
/* Function: RTI_isr =============================================================
 *
 * Abstract:
 *      The actual control algorithm (triggered by RTI, interrupt vector 07)
 */
#pragma CODE_SEG __NEAR_SEG NON_BANKED /* Interrupt section for this module. Placement will be in NON_BANKED area. */
__interrupt void RTI_isr(void) {
  
        //PORTB |= 0x01;
        
  /* first thing to do: acknowledge interrupt -> otherwise there's no real-time operation!  --  fw-03-05 */
  CRGFLG = 0x80;     // acknowledge, clear RTIF flag

  /* disable RTI interrupt */
  CRGINT_RTIE = 0;                       // avoid pre-emption...
  

  /* re-enable all interrupts (to allow servicing of RxD interrupt) */
  asm cli                // re-enable interrupts to allow this one to be interrupted
  
        
        /* check if sampletime interval has elapsed */
        if(--timerTicks == 0) {
          
          /* yes -> reset 'timerTicks' to reload value */
          timerTicks = timerTicksReload;
          
        /* -----------------------   payload section : start   ----------------------- */
          // set cyctime_pin high (timing -> scope)
          #ifdef TIMING
          setCycTiPin;
          #endif

          /* run model code */
          model_run();
          
          // reset cyctime_pin (timing -> scope)
          #ifdef TIMING
          clrCycTiPin;
          #endif
        /* -----------------------   payload section : end     ----------------------- */

        }

  /* re-enable RTI interrupt */
  CRGINT_RTIE = 1;

        //PORTB &= ~0x01;
  
} /* End of RTI_isr */

#pragma CODE_SEG DEFAULT
#endif

#if CORE_TIMER == CORE_T7ISR
/* Function: isr_timer7 =============================================================
 *
 * Abstract:
 *      The actual control algorithm (triggered by timer T7, interrupt vector 15)
 */
#pragma CODE_SEG __NEAR_SEG NON_BANKED /* Interrupt section for this module. Placement will be in NON_BANKED area. */
__interrupt void isr_timer7(void) {
  
	//PORTB |= 0x01;
	
  /* first thing to do: acknowledge interrupt -> otherwise there's no real-time operation!  --  fw-03-05 */
  TFLG1 = 0x80;          // acknowledge interrupt (clears C7F)
  
  /* disable (channel 7) timer interrupt */
  TIE &= ~0x80;          // avoid pre-emption...
  
  /* re-enable all interrupts (to allow servicing of RxD interrupt) */
  asm cli                // re-enable interrupts to allow this one to be interrupted
  
	
	/* check if sampletime interval has elapsed */
	if(--timerTicks == 0) {
	  
	  /* yes -> reset 'timerTicks' to reload value */
	  timerTicks = timerTicksReload;
	  
  	/* -----------------------   payload section : start   ----------------------- */
	  // set cyctime_pin high (timing -> scope)
	  #ifdef TIMING
	  setCycTiPin;
	  #endif

	  /* run model code */
	  model_run();
	  
  	  // reset cyctime_pin (timing -> scope)
	  #ifdef TIMING
	  clrCycTiPin;
	  #endif
  	/* -----------------------   payload section : end     ----------------------- */

	}

  /* re-enable (channel 7) timer interrupt */
  TIE |= 0x80;

	//PORTB &= ~0x01;
  
} /* End of isr_timer7 */

#pragma CODE_SEG DEFAULT
#endif





/* ===================================================================================== */



#if ((HAS_TIMERBLOCKS > 0) | (HAS_RFCOMMS > 0))
/* This section is only included if the block diagram has timer blocks or RFComms blocks. 
   In this case, the ECT unit is configured using 'ECT_Init' and each timer channel can 
   be set up using 'TChannel_Conf' 

   fw-09-06 
*/


/* global variables: reload values */
#if T0_MODE == TMode_OC
unsigned int  TC0_ReloadValue;
#endif

#if T1_MODE == TMode_OC
unsigned int  TC1_ReloadValue;
#endif

#if T2_MODE == TMode_OC
unsigned int  TC2_ReloadValue;
#endif

#if T3_MODE == TMode_OC
unsigned int  TC3_ReloadValue;
#endif

#if T4_MODE == TMode_OC
unsigned int  TC4_ReloadValue;
#endif

#if T5_MODE == TMode_OC
unsigned int  TC5_ReloadValue;
#endif

#if T6_MODE == TMode_OC
unsigned int  TC6_ReloadValue;
#endif

#if T7_MODE == TMode_OC
unsigned int  TC7_ReloadValue;
#endif


#if T0_MODE == TMode_IC
unsigned int  TC0_Capture_last;
unsigned int  TC0_diff;
#endif

#if T1_MODE == TMode_IC
unsigned int  TC1_Capture_last;
unsigned int  TC1_diff;
#endif

#if T2_MODE == TMode_IC
unsigned int  TC2_Capture_last;
unsigned int  TC2_diff;
#endif

#if T3_MODE == TMode_IC
unsigned int  TC3_Capture_last;
unsigned int  TC3_diff;
#endif

#if T4_MODE == TMode_IC
unsigned int  TC4_Capture_last;
unsigned int  TC4_diff;
#endif

#if T5_MODE == TMode_IC
unsigned int  TC5_Capture_last;
unsigned int  TC5_diff;
#endif

#if T6_MODE == TMode_IC
unsigned int  TC6_Capture_last;
unsigned int  TC6_diff;
#endif

#if T7_MODE == TMode_IC
unsigned int  TC7_Capture_last;
unsigned int  TC7_diff;
#endif

unsigned int         TCx_latch;

unsigned long        myTOFcounter;
float                myECTperiod = MIN_ECT_PERIOD;  // initialize with smalles possible base period (2.73 ms)


/* timer unit initialization (base rate) */
void ECT_Init(void) {

#ifdef ERASE /* ====================================================================================== */
/* no longer used... fw-09-06 */
unsigned int    n = 1;			    /* base period multiplier: 1 = 2.73 ms, 2 = 5.46 ms, ... 128 = 349.5 ms */
unsigned char   PR0_2 = 0;    	/* bits PR0, PR1, PR2 (see TSCR2) */

	/* work out prescaler value */
	while (myECTperiod < TIMER_BASEPERIOD) {
		
		n <<= 1;					  /* insufficiently long maximum period -> try next slower period */
		
		if(n > 128) break;  /* max prescaler is '128' -> this should really throw an error... */
		
		PR0_2++;            /* new value of PR0, PR1, PR2 */
			
	  /* update maximum period */
	  myECTperiod = ((float)MIN_ECT_PERIOD)*n;

	}
		
  TSCR2  = 0x80|PR0_2;    // TOF = 1 (enable timer overflow interrupt)
  
#endif /* ERASE ====================================================================================== */

  /* set ECT period (used in TChannel_Conf) */
  myECTperiod = (float)(MIN_ECT_PERIOD*TIMER_PRESCALER);
  
  TSCR2  = 0x80|TIMER_PRESCALER_MASK;  
  OC7M   = 0x00;      		// OC mode: do not affect any of the linked output pins (IOC0 - IOC6)
	
  /* OC mode: output logic always disconnected -> everything is controlled from within the ISR */
  TCTL1 = 0x00;     /* channel 4 - 7 */
  TCTL2 = 0x00;     /* channel 0 - 3 */

}

  
/* start timer unit */
void ECT_Start(void) {

  /* activate ECT  */
  TSCR1  |= 0x80;                    // start timer (set TEN bit)
  
}

/* stop timer unit */
void ECT_Stop(void) {

  /* deactivate ECT  */

⌨️ 快捷键说明

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