STM32 µC:SysTick延迟在中断处理程序中不起作用

时间:2018-09-14 12:30:06

标签: c microcontroller stm32 stm32f1

因此,我使用RTC(实时时钟)和显示模块为C中的STM32F103C8T6微控制器编写了一个程序。

RTC和显示都可以正常工作,但是当我尝试从RTC中断处理程序内部更新显示时,它不起作用。

当我从main()内部向显示器中写入内容时,它就可以正常工作。

中断处理程序也可以正常工作,因此我认为问题在于写入显示器的函数之内。

此功能使用较小的延迟来与显示控制器进行通信。

我以前使用SysTick来生成这样的延迟:

void delay(uint32_t n){
    uint32_t start =  systick_count;
    while (systick_count - start < n);
    return;
}

但是以某种方式,在RTC的中断处理程序中它不起作用。因此,我用此功能代替了延迟功能,而不是使用SysTick:

for (; i>0; i--) {
    for (int j = 0; j < 72; ++j) {
        __asm__ __volatile__("nop\n\t":::"memory");
    }
}

,现在一切正常。

我试图理解为什么SysTick显然在RTC中断处理程序中不起作用。

我认为这可能是由中断优先级引起的,但是根据数据表,默认情况下,SysTick Interrupt的优先级高于RTC中断优先级。

也许有人可以解释,为什么会这样?

EDIT1:好的,所以我阅读了有关中断优先级的更多信息,看来我需要正确配置NVIC_IRQChannelPreemptionPriority。我将尽快尝试...

关于中断内部的延迟,我知道这不是正确的方法,但是我仍然想了解程序的行为

EDIT2:我只是尝试通过以下方式更改中断优先级:

// set RTC interrupt priority to 15 (lowest)
NVIC_SetPriority(RTC_IRQn, 15);
// set interrupt priority of SysTick to 0 (highest)
NVIC_SetPriority(SysTick_IRQn, 0);

,现在SysTick延迟在RTC中断处理程序中起作用。

1 个答案:

答案 0 :(得分:5)

您使用SysTick实现延迟的方式与来自ST的HAL库中的HAL_Delay相同。它的工作方式是SysTick连续递增(通常以1毫秒为间隔)一个变量-在您的情况下为systick_count-该变量与延迟函数内部的一个局部变量-start比较。

这里要注意两件事:

    需要使
  1. systick_count不稳定,以便在每次比较之前强制重新读取其值。它是通过中断而不是在函数内部进行修改的。您的编译器可能选择优化代码的这一部分。

  2. 调用延迟函数时,SysTick中断需要“正在运行”。如果不是因为您处于较高优先级(数字较低)的中断中,所以您处于死锁状态,并且延迟功能将永远不会完成,因为SysTick不会使计数器递增,而这永远不会发生。关于这一点-不要做任何事情,而只依赖数据表。继续并实际验证它是否正在延迟运行。要么在调用延迟功能时检查NVIC寄存器值,要么在RTC中断中简单地在SysTick中设置一个断点-当您在延迟功能中时,它应该达到该断点。如果没有,您可能需要调整中断优先级。

关于在您的中断中添加延迟的整个想法-通常被认为是不好的做法。中断应该被用来非常快地完成很小的一部分工作,例如设置一个标志,表明需要在主程序代码中进行某些操作,或者将接收到的字节放入队列中以便以后处理。尽管在一个只有一个中断(如果算上Systick则为两个)的简单程序中,这似乎并不明显,但是一旦添加更多的中断,它将很快成为问题,并且会遇到诸如丢失信息之类的问题,因为中断会阻塞每个中断其他,他们打电话的速度不够快。