可以通过代码设置中断标志,如下例所示,或者该行只是一个思考错误?这只是主要功能。在这段代码下面snipet是它自己的中断,清除代码末尾的中断标志是否正确和必要?
if(duty != (uint8_t) (SOFT_PWM_PERIOD - 1))
{
// Request an immediate interrupt if the timer counter has
// already the initial period. This helps minimize glitches
// when changing duty cycles
if(duty < TMR4)
PIR3bits.TMR4IF = 1;
// Finally (re-)start the timer
T4CON =
0 << 3 | // 1x post-scaler
1 << 2 | // Active
2 /* << 0 */; // 16x pre-scaler
IPR3bits.TMR4IP = 1; // TMR4 Overflow Interrupt Priority bit High
PIE3bits.TMR4IE = 1; // TMR4 Overflow Interrupt Enable bit
}
Intrrupt代码 - &gt;
// Deal with PWM timer interrupts. Add this to the high-priority interrupt handler.
void SoftPWM_Interrupt(void)
{
volatile uint8_t _SoftPWM_Toggle; // Is this variable really accessed by both the ISR and mainline functions? (C.G)
/* Has a flank been reached yet? */
if(PIR3bits.TMR4IF)
{
/* Alternate between the low and high periods */
PR4 ^= _SoftPWM_Toggle;
/* Try to deal gracefully with the new period already having been reached. */
/* The hardware timer works by checking if TMR4 = PR4 when it is time to increase */
/* counter, in which case TMR4 is reset instead. Thus if is already TMR4 > PR4 due to */
/* interrupt latency then we've missed the period and an extra interrupt is needed. */
/* First acknowledging the flag and then conditionally setting it is necessary to */
/* avoid a race between reading TMR4 and changing the flag. */
/* Finally the the TMR4 > PR4 test is actually implemented as skip if TMR4 < PR4 + 1 */
/* but the increment cannot overflow since the interrupt won't be used for 0% or 100% */
/* duty cycles */
PIR3bits.TMR4IF = 0;
_asm
INCF PR4,0,ACCESS
CPFSLT TMR4,ACCESS
_endasm
/* if(TMR4 > PR4) */
PIR3bits.TMR4IF = 1; // Cant only the harware set this flag? (C.G)
/* Finally toggle the output pin */
SOFT_PWM_PIN ^= 1;
/*Important?*/
PIR3bits.TMR4IF = 0;
}
}
答案 0 :(得分:1)
是的,您可以通过soft设置中断标志。但IMO并不是一个很好的做法......
如果您真的希望在正常情况下执行ISR的行为,为什么不在您可以在主函数中调用的函数中将ISR代码外部化?
关于中断标志,如果你不清除它,ISR将循环执行,你永远不会回到你的主程序。