關於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;
}
}