在没有运行任何操作系统的微控制器上,当它进入一个例程并忙于执行一些冗长的循环时,如何使微控制器过早地从该例程中止(即返回调用例程)作为响应中断(例如,当用户按下按钮时产生的中断)?
有没有比以下更好的解决方案: 1)轮询循环之间的按钮或共享变量, 2)手动修改堆栈中的返回地址, 3)使用OS,和 4)在ISR中硬编码POP和JUMP指令?
非常感谢!
答案 0 :(得分:1)
如果你想让一个冗长的函数成为一个中断的快捷方式,并且在干净的事情中做到这一点,那么在函数中只需要一种方法来构建一个干净的返回。如何判断返回的函数可以让中断设置共享资源(例如变量),前台循环/函数可以返回。或者你可以对前景循环进行轮询(例如gpio引脚,定时器等)。
通常你想做的事情是不同的。你允许前台任务做低优先级的事情,比如更新显示或处理用户输入或类似的事情,你不要强迫它过早地退出函数,而是在你处理的任何事情中你需要做的事情是优先。
如果您愿意并且有不同的线程可以创建一个迷你操作系统,那些捕获需要处理的硬件事件的中断会保留该信息和/或交换线程(保存当前使用的所有寄存器的副本)运行代码,用处理程序代码替换所有寄存器并返回处理程序代码)。如果isr没有交换,那么周期性定时器会出现,看优先级事件和交换,然后周期性定时器将在优先级处理程序空闲时交换回来。或者优先级处理程序可以在空闲之前调用函数以使切换回到前台线程。没有复杂,比简单的更复杂,是的,但仍然不是很复杂。
答案 1 :(得分:0)
微控制器利用通常在代码的第一部分配置的硬件中断。可以将单个引脚配置为外部中断,并可以创建相关功能。
向我们提供:
然后我们可以为您的问题提供更具体的解决方案
答案 2 :(得分:0)
对于PIC或AVR,所有操作系统都倾向于使用堆栈,所以我认为2 - 4是相同的选项(除了其他人已经实现的操作系统并测试了堆栈操作。)
我建议选项1,因为它是最便携的。在代码中执行此操作的一种非常快捷的方法:
//Consider using static int if all the code is in one file
int WasButtonPressed;
//Change this to match your complier for interrupts
void __attribute__((__interrupt__,no_auto_psv)) _Interrupt
{
//Rewrite this to use whatever button polling method
if (PORTAbits.RA0) {
WasButtonPressed = 1;
}
}
//Testing to see if the interrupt fired and then get out of the function
#define HANDLE_BUTTON() { if (WasButtonPressed) return; }
然后你可以通过HANDLE_BUTTON();
电话来调整你的循环。