因此,我使用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中断处理程序中起作用。
答案 0 :(得分:5)
您使用SysTick实现延迟的方式与来自ST的HAL库中的HAL_Delay
相同。它的工作方式是SysTick连续递增(通常以1毫秒为间隔)一个变量-在您的情况下为systick_count
-该变量与延迟函数内部的一个局部变量-start
比较。
这里要注意两件事:
systick_count
不稳定,以便在每次比较之前强制重新读取其值。它是通过中断而不是在函数内部进行修改的。您的编译器可能选择优化代码的这一部分。
调用延迟函数时,SysTick中断需要“正在运行”。如果不是因为您处于较高优先级(数字较低)的中断中,所以您处于死锁状态,并且延迟功能将永远不会完成,因为SysTick不会使计数器递增,而这永远不会发生。关于这一点-不要做任何事情,而只依赖数据表。继续并实际验证它是否正在延迟运行。要么在调用延迟功能时检查NVIC寄存器值,要么在RTC中断中简单地在SysTick中设置一个断点-当您在延迟功能中时,它应该达到该断点。如果没有,您可能需要调整中断优先级。
关于在您的中断中添加延迟的整个想法-通常被认为是不好的做法。中断应该被用来非常快地完成很小的一部分工作,例如设置一个标志,表明需要在主程序代码中进行某些操作,或者将接收到的字节放入队列中以便以后处理。尽管在一个只有一个中断(如果算上Systick则为两个)的简单程序中,这似乎并不明显,但是一旦添加更多的中断,它将很快成为问题,并且会遇到诸如丢失信息之类的问题,因为中断会阻塞每个中断其他,他们打电话的速度不够快。