|
8楼
![](static/image/common/ico_lz.png)
楼主 |
发表于 2017-3-6 17:28:08
|
只看该作者
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; RC pulse processing interrupt routine
;
; No assumptions
; Can come from int0 or icp
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
void rcp_int(void):// ; Used for RC pulse timing
{
I_Sreg = SREG;
//; Get the timer counter values
Get_Rcp_Capture_Values();// I_Temp1, I_Temp2
//; Disable RCP interrupts
Flags2 &= ~(1<<RCP_INT_NESTED_ENABLED);// ; Set flag default to disabled
if (0 != Get_Rcp_Int_Enable_State())// XL ; Get rcp interrupt state
{
Flags2 |= (1<<RCP_INT_NESTED_ENABLED);// ; Set flag to enabled
}
Rcp_Int_Disable();// XL ; Disable rcp interrupts
T0_Int_Disable();// XL ; Disable timer0 interrupts
sei();// ; Enable interrupts
//; Check which edge it is
if(0 == (Flags2 & (1 << RCP_EDGE_NO)))// ; Is it a first edge trig?
{
Rcp_Int_Second();// XL ; Yes - set second edge trig
Flags2 |= (1<<RCP_EDGE_NO);// ; Set second edge flag
//; Read RC signal level
//Test RC signal level
if(0 == (Read_Rcp_Int() & (1 << Rcp_In)))// ; Is it high?
{
//; Prepare for next interrupt
Rcp_Int_First();// XL ; Set interrupt trig to first again
Rcp_Clear_Int_Flag();// XL ; Clear interrupt flag
Flags2 &= ~(1<<RCP_EDGE_NO);// ; Set first edge flag
if(0 == (Flags2 & (1 << RCP_PPM)))
{
I_Temp1 = RCP_MIN;// ; Set RC pulse value to minimum
if(0 == (Read_Rcp_Int() & (1 << Rcp_In)))// ; Is it high?
{
//; RC pulse value accepted
New_Rcp = I_Temp1;// ; Store new pulse length
Flags2 |= (1<<RCP_UPDATED);// ; Set updated flag
if(0 != (Flags0 & (1 << RCP_MEAS_PWM_FREQ)))// ; Is measure RCP pwm frequency flag set?
{
//Clear all pwm frequency flags
Flags3 &= ~((1<<RCP_PWM_FREQ_1KHZ)+(1<<RCP_PWM_FREQ_2KHZ)+(1<<RCP_PWM_FREQ_4KHZ)+(1<<RCP_PWM_FREQ_8KHZ)+(1<<RCP_PWM_FREQ_12KHZ));
Flags3 |= I_Temp4;// ; Store pwm frequency value in flags
Flags2 &= ~(1<<RCP_PPM);// ; Default, flag is not set (PWM)
if(0 == I_Temp4)// ; Check if all flags are cleared
{
Flags2 |= (1<<RCP_PPM);// ; Flag is set (PPM)
}
}
}
}
Rcp_Timeout_Cntd = RCP_TIMEOUT;// ; Set timeout count to start value
if(0 != (Flags2 & (1 << RCP_PPM)))
{
Rcp_Timeout_Cntd = RCP_TIMEOUT_PPM;// ; No flag set means PPM. Set timeout count
}
if((0 == (Flags0 & (1 << RCP_MEAS_PWM_FREQ))) && // ; Is measure RCP pwm frequency flag set?
(0 == (Flags2 & (1 << RCP_PPM))))
{
Flags2 &= ~(1<<RCP_INT_NESTED_ENABLED);// ; Set flag to disabled
}
}
else
{
//; RC pulse was high, store RC pulse start timestamp
Rcp_Prev_Edge_L = I_Temp1;
Rcp_Prev_Edge_H = I_Temp2;
}
goto rcp_int_exit;// ; Exit
}
rcp_int_second_meas_pwm_freq:
//; Prepare for next interrupt
Rcp_Int_First();// XL ; Set first edge trig
Flags2 &= ~(1<<RCP_EDGE_NO);// ; Set first edge flag
//; Check if pwm frequency shall be measured
if(0 != (Flags0 & (1 << RCP_MEAS_PWM_FREQ)))// ; Is measure RCP pwm frequency flag set?
{
//; Set second edge trig only during pwm frequency measurement
Rcp_Int_Second();// XL ; Set second edge trig
Rcp_Clear_Int_Flag();// XL ; Clear interrupt flag
Flags2 |= (1<<RCP_EDGE_NO);// ; Set second edge flag
//; Store edge data to RAM
Rcp_Edge_L = I_Temp1;
Rcp_Edge_H = I_Temp2;
//; Calculate pwm frequency
*((uint16_t *)&I_Temp1) -= ((uint16_t)Rcp_PrePrev_Edge_H * 256 + Rcp_PrePrev_Edge_L);
I_Temp3 = 0;
I_Temp4 = 0;
//; Check if pulse is too short
if(*((uint16_t *)&I_Temp1) < 140) //If pulse below 70us, not accepted
{
Rcp_Period_Diff_Accepted = 0;// ; Set not accepted
}
else if(0 == Pgm_Enable_PWM_Input)// ; Check if PWM input is enabled
{
}
//; Check if pwm frequency is 12kHz
else if(*((uint16_t *)&I_Temp1) < 200)// ; If below 100us, 12kHz pwm is assumed
{
I_Temp4 = (1<<RCP_PWM_FREQ_12KHZ);
I_Temp3 = 10;// ; Set period tolerance requirement (LSB)
}
//; Check if pwm frequency is 8kHz
else if(*((uint16_t *)&I_Temp1) < 360)// ; If below 180us, 8kHz pwm is assumed
{
I_Temp4 = (1<<RCP_PWM_FREQ_8KHZ);
I_Temp3 = 15;// ; Set period tolerance requirement (LSB)
}
//; Check if pwm frequency is 4kHz
else if(*((uint16_t *)&I_Temp1) < 720)// ; If below 360us, 4kHz pwm is assumed
{
I_Temp4 = (1<<RCP_PWM_FREQ_4KHZ);
I_Temp3 = 30;// ; Set period tolerance requirement (LSB)
}
//; Check if pwm frequency is 2kHz
else if(*((uint16_t *)&I_Temp1) < 1440)// ; If below 1440us, 2kHz pwm is assumed
{
I_Temp4 = (1<<RCP_PWM_FREQ_2KHZ);
I_Temp3 = 60;// ; Set period tolerance requirement (LSB)
}
//; Check if pwm frequency is 1kHz
else if(*((uint16_t *)&I_Temp1) < 2200)// ; If below 1100us, 1kHz pwm is assumed __zlf__???
{
I_Temp4 = (1<<RCP_PWM_FREQ_1KHZ);
I_Temp3 = 120;// ; Set period tolerance requirement (LSB)
}
//; Calculate difference between this period and previous period
if(*((uint16_t *)&I_Temp1) >= ((uint16_t)Rcp_PrePrev_Period_H * 256 + Rcp_PrePrev_Period_L))
{
*((uint16_t *)&I_Temp5) = *((uint16_t *)&I_Temp1) - ((uint16_t)Rcp_PrePrev_Period_H * 256 + Rcp_PrePrev_Period_L);
}
else
{
*((uint16_t *)&I_Temp5) = ((uint16_t)Rcp_PrePrev_Period_H * 256 + Rcp_PrePrev_Period_L) - *((uint16_t *)&I_Temp1);
}
//; Check difference
Rcp_Period_Diff_Accepted = 0;// ; Set not accepted as default
if(0 == I_Temp3)//; Check if no tolerance requirement is set
{
XL = 8;
}
else
{
XL = 0;
}
if(*((uint16_t *)&I_Temp5) < ((uint16_t)XL * 256 + I_Temp3))
{
Rcp_Period_Diff_Accepted = 1;// ; Set accepted
}
//; Store previous period
Rcp_Prev_Period_L = I_Temp1;
Rcp_Prev_Period_H = I_Temp2;
//; Restore edge data from RAM
I_Temp1 = Rcp_Edge_L;
I_Temp2 = Rcp_Edge_H;
//; Store pre previous edge
Rcp_PrePrev_Edge_L = I_Temp1;
Rcp_PrePrev_Edge_H = I_Temp2;
I_Temp1 = RCP_VALIDATE
}
else
{
//; RC pulse edge was second, calculate new pulse length
*((uint16_t *)&I_Temp1) -= ((uint16_t)Rcp_PrePrev_Edge_H * 256 + Rcp_PrePrev_Edge_L);
if((0 == (Flags3 & (1 << RCP_PWM_FREQ_12KHZ))) &&// ; Is RC input pwm frequency 12kHz?
(0 == (Flags3 & (1 << RCP_PWM_FREQ_8KHZ))))// ; Is RC input pwm frequency 8kHz?
{
if(0 != (Flags3 & (1 << RCP_PWM_FREQ_2KHZ)))// ; Is RC input pwm frequency 2kHz?
{
(*((uint16_t *)&I_Temp1)) >>= 1;//; 2kHz. Divide by 2
}
if(0 != (Flags3 & (1 << RCP_PWM_FREQ_1KHZ)))// ; Is RC input pwm frequency 1kHz?
{
(*((uint16_t *)&I_Temp1)) >>= 2;//; 1kHz. Divide by 2 again
}
if((0 == (Flags3 & (1 << RCP_PWM_FREQ_4KHZ))) &&// ; Is RC input pwm frequency 4kHz?
(0 == (Flags3 & (1 << RCP_PWM_FREQ_2KHZ))) &&// ; Is RC input pwm frequency 2kHz?
(0 == (Flags3 & (1 << RCP_PWM_FREQ_1KHZ))))// ; Is RC input pwm frequency 1kHz?
{
if(0 != (Flags3 & (1 << RCP_PPM_ONESHOT125)))
{
(*((uint16_t *)&I_Temp5)) = (*((uint16_t *)&I_Temp1));// ; Oneshot125 - move to I_Temp5/6
}
else
{
(*((uint16_t *)&I_Temp5)) = ((*((uint16_t *)&I_Temp1)) >> 3);//PPM. Divide by 2 (to bring range to 256) and move to I_Temp5/6
}
//; Skip range limitation if pwm frequency measurement
if((0 == (Flags0 & (1 << RCP_MEAS_PWM_FREQ))) &&
//; Check if 2160us or above (in order to ignore false pulses)
((((*((uint16_t *)&I_Temp5)) >= 540) ||// ; Is pulse 2160us or higher?
//; Check if below 800us (in order to ignore false pulses)
((*((uint16_t *)&I_Temp5)) < 200)))) //Is pulse below 800us?
{
//__zlf__????? 255的处理是否合理
XL = Rcp_Outside_Range_Cnt + 1;
if(XL != 0)
{
Rcp_Outside_Range_Cnt++;
}
if(XL >= 10)// ; Allow a given number of outside pulses
{
New_Rcp = Zero;// ; Set pulse length to zero
Flags2 |= (1<<RCP_UPDATED);// ; Set updated flag
}
goto rcp_int_set_timeout;
}
//; Decrement outside range counter
if(0 != Rcp_Outside_Range_Cnt)
{
Rcp_Outside_Range_Cnt--;
}
//; Calculate "1000us" plus throttle minimum
I_Temp3 = 0;// ; Set 1000us as default minimum
I_Temp2 = Pgm_Direction;// ; Check if bidirectional operation (store in I_Temp2)
if(0 == (Flags3 & (1 << FULL_THROTTLE_RANGE)))// ; Check if full range is chosen
{
I_Temp3 = Pgm_Ppm_Min_Throttle;// ; Min throttle value is in 4us units
#if MODE >= 1 //; Tail or multi
if(I_Temp2 == 3)
{
I_Temp3 = Pgm_Ppm_Center_Throttle;// ; Center throttle value is in 4us units
}
#endif
}
(*((uint16_t *)&I_Temp5)) -= ((uint16_t)I_Temp3 + 250);// Subtract minimum// Add 1000us to minimum
I_Temp1 = SREG & (1<<SREG_C);
#if MODE >= 1 //; Tail or multi
if(I_Temp2 == 3)// ; Check if bidirectional operation
{
if(I_Temp1 != 0)
{
if(0 == (Flags2 & (1 << RCP_DIR_REV)))
{
Flags2 |= (1<<RCP_DIR_REV);
}
}
else
{
if(0 != (Flags & (1 << RCP_DIR_REV)))
{
Flags2 &= ~(1<<RCP_DIR_REV);
}
}
}
#endif
if(0 != I_Temp1)
{
#if MODE >= 1 // ; Tail or multi
if(I_Temp2 == 3)// ; Check if bidirectional operation
{
//; Change sign - invert and subtract minus one
(*((uint16_t *)&I_Temp5)) = 0x10000 - (*((uint16_t *)&I_Temp5));
}
else
#endif
{
*((uint16_t *)&I_Temp1) = RCP_MIN;
goto rcp_int_pwm_divide_done
}
}
#if MODE >= 1 //; Tail or multi
if(I_Temp2 == 3)// ; Check if bidirectional operation
{
(*((uint16_t *)&I_Temp5)) <<= 1;// ; Multiply value by 2
if(*((uint16_t *)&I_Temp5) < 10)
{
*((uint16_t *)&I_Temp5) = 10;
}
}
#endif
if(*((uint16_t *)&I_Temp5)) < RCP_MAX)// ; Check that RC pulse is within legal range (max 255)
{
I_Temp1 = (uint16_t)I_Temp5 * Ppm_Throttle_Gain / 256;// ; Multiply throttle value by gain
Mul_Res_L = (uint16_t)I_Temp5 * Ppm_Throttle_Gain % 256;//
if(0 != (I_Temp1 & 0x80))
{
*((uint16_t *)&I_Temp1) = RCP_MAX;
}
else
{
*((uint16_t *)&I_Temp1) = (I_Temp1 << 1) + (Mul_Res_L >> 7);
}
goto rcp_int_limited;
}
*((uint16_t *)&I_Temp1) = RCP_MAX;
}
else
{
*((uint16_t *)&I_Temp1) >>= 1;
}
}
if(0 != (Flags3 & (1 << RCP_PWM_FREQ_12KHZ)))// ; Is RC input pwm frequency 12kHz?
{
if(0 != I_Temp2)// ; Yes - check that value is not more than 255
{
I_Temp1 = RCP_MAX;
}
*((uint16_t *)&I_Temp1) += (I_Temp1 >> 1);// ; Multiply by 1.5
}
//; Check that RC pulse is within legal range
if(*((uint16_t *)&I_Temp1)) >= RCP_MAX)
{
I_Temp1 = RCP_MAX;
}
}
rcp_int_limited:
//; RC pulse value accepted
New_Rcp = I_Temp1;// ; Store new pulse length
Flags2 |= (1<<RCP_UPDATED);// ; Set updated flag
if(0 != (Flags0 & (1 << RCP_MEAS_PWM_FREQ)))// ; Is measure RCP pwm frequency flag set?
{
//Clear all pwm frequency flags
Flags3 &= ~((1<<RCP_PWM_FREQ_1KHZ)+(1<<RCP_PWM_FREQ_2KHZ)+(1<<RCP_PWM_FREQ_4KHZ)+(1<<RCP_PWM_FREQ_8KHZ)+(1<<RCP_PWM_FREQ_12KHZ));
Flags3 |= I_Temp4;// ; Store pwm frequency value in flags
Flags2 &= ~(1<<RCP_PPM);// ; Default, flag is not set (PWM)
if(0 == I_Temp4)// ; Check if all flags are cleared
{
Flags2 |= (1<<RCP_PPM);// ; Flag is set (PPM)
}
}
rcp_int_set_timeout:
Rcp_Timeout_Cntd = RCP_TIMEOUT;// ; Set timeout count to start value
if(0 != (Flags2 & (1 << RCP_PPM)))
{
Rcp_Timeout_Cntd = RCP_TIMEOUT_PPM;// ; No flag set means PPM. Set timeout count
}
rcp_int_ppm_timeout_set:
if((0 == (Flags0 & (1 << RCP_MEAS_PWM_FREQ))) && // ; Is measure RCP pwm frequency flag set?
(0 == (Flags2 & (1 << RCP_PPM))))
{
Flags2 &= ~(1<<RCP_INT_NESTED_ENABLED);// ; Set flag to disabled
}
rcp_int_exit:// ; Exit interrupt routine
if(0 == (Flags2 & (1 << RCP_PPM)))// ; If flag is set (PPM) - branch
{
Rcp_Skip_Cntd = RCP_SKIP_RATE;// ; Load number of skips
}
cli(); ; Disable interrupts
T0_Int_Enable();// XL ; Enable timer0 interrupts
if(0 != (Flags2 & (1 << RCP_INT_NESTED_ENABLED)))// Restore rcp interrupt state
{
Rcp_Int_Enable();
}
rcp_int_ret:
SREG = I_Sreg;
}
|
|