暂时禁用定时器中断

时间:2012-12-11 12:28:34

标签: timer embedded interrupt stm32 irq

我正在使用stm32f4xx uC的C中的嵌入式项目。

我有一部分代码连续执行循环操作XYZ,并且TIM4中断有时会更改某些全局参数并导致操作XYZ重新启动。

代码是这样的:

for (;;) {
       //line A
    XYZ;
       //line B
}

XYZ是一项涉及缓冲区与其他数据之间传输数据的复杂操作。

TIM4中断处理程序执行此操作:停止XYZ&改变一些影响XYZ操作的全局变量。

基本上我希望XYZ重复执行,TIM4中断停止XYZ,更改参数和然后必须通过使用新的全局参数重新启动XYZ来重启循环。

问题是:由于XYZ有很多指令,TIM4 IRQ可能就在它的中间,在IRQHandler更改全局变量之后,操作从XYZ中间恢复,这会破坏程序

MY INITIAL SOLUTION:使用__disable_irq()禁用A行上的中断,并使用__enable_irq()

在B行恢复它们

失败,因为XYZ复杂操作必须使用其他中断(TIM4除外)。

NEXT SOLUTION 仅在A行禁用TIM4中断:

TIM_ITConfig(TIM4, TIM_IT_Update , DISABLE) 

并使用以下命令将其启用回B行:

TIM_ITConfig(TIM4, TIM_IT_Update , ENABLE)

失败因为我正在丢失中断:当int恢复时,忽略在XYZ期间到达的中断。这是一个很大的问题(其中一个原因是TIM4 IRQHandler更改全局变量然后再次激活TIM4以产生中断,我这样做是因为中断之间的时间间隔不同)。

有人能帮我解决这个问题吗?有没有更好的方法来禁用/恢复TIM4 IRQ和不丢失任何中断?

5 个答案:

答案 0 :(得分:1)

完成XYZ后,您可以操作全局变量的副本并从中断交换新值。

从问题中不清楚是否需要在全局变化时立即停止处理XYZ,或者是否可以等到XYZ完成处理以交换变量的新副本。我会假设你需要打破XYZ的处理,但很容易就不行。

代码看起来像这样:

volatile int x;
int x_prime;

int main(void)
{
    while(1)
    {
        //copy in new global parameter value
        x_prime = x;

        while(1)
        {
            //do stuff with x_prime
            if (x_prime != x)
            {
                break;
            }

            //do more stuff with x_prime
            if (x_prime != x)
            {
                break;
            }
        }
    }
}

// interrupt handler
void TIM_IT_Update(void)
{
    x++;
}

break模式假设您没有更改x_prime。如果您需要修改x_prime,则需要另一份副本。

由于永远不会禁用中断,因此您永远不必担心丢失任何中断。并且由于您正在操作中断更改的参数副本,因此中断在执行过程中更改参数并不重要,因为在您复制之前不会查看这些值。

答案 1 :(得分:1)

有一些可能的选项(我不是100%在ARM架构上):

  • 更改中断优先级/级别屏蔽寄存器,仅屏蔽TIM4,使其他中断发生。希望如果TIM4在被屏蔽的情况下被触发,在恢复等级掩码时它会记住&解雇ISR。
  • 屏蔽中断并手动检查在XYZ期间设置的TIM4中断标志
  • 将XYZ分成较小的部分,仅在绝对必要时屏蔽TIM4。
  • 操作数据副本,可选择检查TIM4中断标志以决定是继续/保留结果还是丢弃&重新启动。
  • 检查时间&如果TIM4可能很快发生,或者在TIM4发生后仅运行XYZ N次,则避免启动XYZ。

答案 2 :(得分:1)

当我发现自己处于类似情况时,处理可能需要比中断时间更长的时间,我使用FIFO将处理与传入数据分离。 I.E:TIM4填充FIFO。 XYZ(或管理器)使用FIFO并处理数据。

(我觉得你的设计可能是错的,因为你不应该使用全局变量来控制数据或流程。 关于此事的研究的书籍参考:制作嵌入式系统:伟大软件的设计模式)

答案 3 :(得分:0)

在XYZ从缓冲区复制所有内容并使用副本之前。我认为这是最好的方式,在编写gps解析器时有所帮助。

答案 4 :(得分:0)

您是否考虑过为您的系统使用 RTOS?我意识到这需要进行一些重组,但它可以为您提供系统所需的任务处理灵活性和分辨率。如果您使用的是 STM32 的 CubeIDE,那么启用、配置和运行 RTOS 非常简单。