NXP MPC574X eTimer

關於eTimer模塊

1、概述

MPC574X的eTimer模塊主要用於實現

2、功能介紹

2.1、計數模式

  • Stop Mode
  • Count Mode
  • Edge Count Mode
  • Gated Count Mode
  • Quadrature Count Mode
  • Signed Count Mode
  • Triggered Count Mode
  • OneShot Mode
  • Cascade Count Mode
  • Pulse Output Mode(脈衝輸出模式)
  • FixedFrequency PWM Mode(固定頻率PWM模式)
  • Variable Frequency PWM Mode(可變頻率的PWM模式)

2.2、輸入捕獲

輸入捕獲模式用來測量脈衝的寬度和波形的週期。

3、代碼實現

void eTimer1_Init(void)
{
    ETIMER_1.ENBL.R = 0x0;					// disable Timer1 channels

    ETIMER_1.CH[0].CTRL1.R = 0x3805;		// Counts only rising edge of the MC_CLK (100MHz in RUN0), divide by 1, count up, count repeatedly, rollover
    ETIMER_1.CH[0].COMP1.R = 0xFFFF;
    ETIMER_1.CH[0].CCCTRL.R = 0x0264;		// compare on COMP1 when counting up, COMP2 when counting down
    										// CAPT2 on falling edge, CAPT1 on rising edge, 2 entries
    										// free-running mode
    ETIMER_1.CH[0].CTRL3.R	= 1;

    ETIMER_1.CH[5].CTRL1.R  = 0xF005;		// cascaded mode, count up, rollover, count repeatedly
    ETIMER_1.CH[5].COMP1.R  = 0xFFFF;
    ETIMER_1.CH[5].CCCTRL.R = 0x0264;		// compare on COMP1 when counting up, COMP2 when counting down
    										// CAPT2 on falling edge, CAPT1 on rising edge, 2 entries
    										// free-running mode
    ETIMER_1.CH[5].CTRL3.R	= 1;

    SIUL2.MSCR[PA5].B.IBE = 1;    /* PA5: Enable pad for input - eTimer1 ch5 */
    SIUL2.IMCR[70].B.SSS = 1;   /* eTimer0 ch1: connected to pad PA5 */

    ETIMER_1.ENBL.R = 0x0021;			// Enable Timer1 channel 0 5
}
void eTimer1_StartInputCapture()
{
    ETIMER_1.CH[0].CCCTRL.B.ARM = 1;		// starts the input capture process
    ETIMER_1.CH[5].CCCTRL.B.ARM = 1;
}
void eTimer1_CalculatePulse()
{
	uint32_t counts, edge1,edge2,edge3,edge4 ;
	uint32_t capture_ch0[8],capture_ch1[8];

	float freq, period, duty,pulseH, pulseL;

	while(!(0x0080 & ETIMER_1.CH[5].STS.R)){}  // wait for channel 1's capture2 flag
	while(!(0x0080 & ETIMER_1.CH[0].STS.R)){}

	capture_ch1[0] = ETIMER_1.CH[5].CAPT1.R;
	capture_ch1[1] = ETIMER_1.CH[5].CAPT2.R;
	capture_ch1[2] = ETIMER_1.CH[5].CAPT1.R;
	capture_ch1[3] = ETIMER_1.CH[5].CAPT2.R;

	capture_ch0[0] = ETIMER_1.CH[0].CAPT1.R;
	capture_ch0[1] = ETIMER_1.CH[0].CAPT2.R;
	capture_ch0[2] = ETIMER_1.CH[0].CAPT1.R;
	capture_ch0[3] = ETIMER_1.CH[0].CAPT2.R;

	capture_ch1[4] = ETIMER_1.CH[5].CAPT1.R;
	capture_ch1[5] = ETIMER_1.CH[5].CAPT2.R;
	capture_ch1[6] = ETIMER_1.CH[5].CAPT1.R;
	capture_ch1[7] = ETIMER_1.CH[5].CAPT2.R;

	capture_ch0[4] = ETIMER_1.CH[0].CAPT1.R;
	capture_ch0[5] = ETIMER_1.CH[0].CAPT2.R;
	capture_ch0[6] = ETIMER_1.CH[0].CAPT1.R;
	capture_ch0[7] = ETIMER_1.CH[0].CAPT2.R;

	edge1 = capture_ch1[0]*65536 + capture_ch0[0];	// save 1st rising edge
	edge2 = capture_ch1[1]*65536 + capture_ch0[1];	// save 1st falling edge
	edge3 = capture_ch1[2]*65536 + capture_ch0[2];	// save 2nd rising edge
	edge4 = capture_ch1[3]*65536 + capture_ch0[3];	// save 2nd falling edge

	// calculate period, pulseH, pulseL, freq and duty
	if(edge3>edge1)
	{
		counts = edge3 - edge1;
	}
	else
	{
		counts = (0xFFFFFFFF - edge1 +1) + edge3;
	}

	freq = (float)100000000.0/counts;
	period = counts / (float)100000.0;

	if(edge2 > edge1)
	{
		counts = edge2 - edge1;
	}
	else
	{
		counts = (0xFFFFFFFF - edge1 +1) + edge2;
	}

	pulseH = counts / (float)100000.0;
	pulseL = period-pulseH;

	duty = pulseH/period*100;

    ETIMER_1.CH[5].STS.R = 0x00C0;		// clear eTimer0 channel 1's capture1/2 flags
    ETIMER_1.CH[0].STS.R = 0x00C0;		// clear eTimer0 channel 0's capture1/2 flags
}
void eTimer1_OutputInit(void)
{
    ETIMER_1.ENBL.R = 0x0;					// disable Timer1 channels

    ETIMER_1.CH[5].COMP1.R  = 24999;
    ETIMER_1.CH[5].COMP2.R  = 3999;

    ETIMER_1.CH[5].CMPLD1.R = 5999;
    ETIMER_1.CH[5].CMPLD2.R = 8999;

    ETIMER_1.CH[5].CCCTRL.B.CLC1 = 2;
    ETIMER_1.CH[5].CCCTRL.B.CLC2 = 5;


    ETIMER_1.CH[5].CTRL1.B.PRISRC = 0x18;
    ETIMER_1.CH[5].CTRL1.B.ONCE = 0;
    ETIMER_1.CH[5].CTRL1.B.DIR = 0;
    ETIMER_1.CH[5].CTRL1.B.LENGTH = 1;

    ETIMER_1.CH[5].CTRL1.B.CNTMODE = 1;

    ETIMER_1.CH[5].CTRL2.B.OEN = 1;
    ETIMER_1.CH[5].CTRL2.B.OUTMODE = 4;

    ETIMER_1.CH[5].CTRL3.B.DBGEN   = 1;

    ETIMER_1.CH[5].STS.R = 0xffff;
    /*
     * Interrupt an DMA Enable
     * */
    ETIMER_1.CH[5].INTDMA.B.TCF1IE = 1;
    ETIMER_1.CH[5].INTDMA.B.TCF2IE = 1;

    /*
     * Pin Port assign
     * */
    SIUL2.MSCR[PA5].B.OBE = 1;    /* PA5: Enable pad for output - eTimer1 ch5 */
    SIUL2.MSCR[PA5].B.SRC = 3;    //Maximum slew rate
    SIUL2.MSCR[PA5].B.SSS = 2;    /* eTimer0 ch5: connected to pad PA5 */

	cmp1_cnt = 1;
	cmp2_cnt = 1;

    ETIMER_1.ENBL.R = 0x0020;			// Enable Timer1 channel 0 5

    INTC_0.PSR[627].R = 0x8009; //set priority and core for eTimer1 Channel5 interrupt
}

void eTimer1_Channel5_Isr(void)
{
	if(ETIMER_1.CH[5].STS.B.TCF == 1)
	{
		cmp2_cnt++;
		if( cmp2_cnt % 2 )//comp1
		{
			if(cmp2_cnt < 6)// 1 3 5
			{
				ETIMER_1.CH[5].CMPLD1.R = cmp_value_array[(cmp2_cnt + 1) / 2 + 1][0];
			}
			else if(cmp2_cnt == 7)
			{
				ETIMER_1.CH[5].CMPLD1.R = cmp_value_array[0][0];
			}
		}
		else
		{
			if(cmp2_cnt < 7)// 2 4 6
			{
				ETIMER_1.CH[5].CMPLD2.R = cmp_value_array[cmp2_cnt/2 + 1][1];
			}
			else if(cmp2_cnt == 8)
			{
				ETIMER_1.CH[5].CMPLD2.R = cmp_value_array[0][1];
				ETIMER_1.CH[5].CTRL1.B.ONCE = 1;
			}
			else if(cmp2_cnt == 10)
			{
				eTimer1Channel5OutputStop();
			}
			else
			{

			}
		}
		ETIMER_1.CH[5].STS.B.TCF = 1;
	}

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章