这对于检测一些事件是有用的。例如,如果我将一个簧片开关连接到一扇门上,那么我的微控制器上的程序可以根据簧片开关所连接的引脚上的值变化来判断门刚刚打开还是刚刚关闭,如图1所示。
外部中断标志 让我们假设与前面的示例类似,我们试图检测的事件是pin值从1变化到0时。在GPIO外围设备内部,将有一块硬件来检测这种变化,并通过将所谓的中断标志设置为1来指示这种变化已经发生。
图2,在检测到应该产生中断的事件后,设置GPIO pin中断标志。 中断控制器和中断控制器标志 在微控制器中有许多外设,并且每个can都有它自己的中断集。大多数微控制器都有一个硬件,通常称为中断控制器,它管理来自外设的所有中断,决定哪个中断运行,并中断CPU,使其执行正确的ISR。
例如,对于CC2544,有一组8个引脚,它们是称为PORT0的GPIO的一部分。每个引脚都被标记为P0_0、P0_1,以此类推,直到P0_7。虽然每个pin都有自己的中断标志,但中断控制器对整个端口只有一个中断,P0INT。每当GPIO外设中的任何一个引脚标志被设置时,中断控制器中的整个端口的标志也被设置。
图3,设置GPIO引脚中断标志,在检测到需要产生中断的事件后,在中断控制器中为GPIO设置中断标志。
例如,对于CC2544,它使用8501微控制器体系结构,PORT0的中断向量是内存地址0x6B。当中断控制器告诉CPU某个特定向量发生了中断时,CPU会做一些记录,然后从那个中断向量开始执行ISR。如图4所示。
配置中断的行为 GPIO之类的外围设备通常允许您配置导致外围设备生成中断的事件类型。对于GPIO来说,典型的选项是当值从0变化到1时,当值从1变化到0时,值的任何变化(即,0到1或1到0,但与哪个无关),或者当值保持1或0时。
此外,一些微控制器要求将感兴趣的pin配置为一个输入,以便在事件发生时设置中断标志(例如,CC2544)。其他(例如,ATmega328P)将设置标志,而不管pin被配置为输出还是输入。
禁用CPU中的所有中断实际上会停止中断控制器和CPU之间的通信。这意味着GPIO外设的pin标志和控制器中对应的中断标志将被设置;然而,CPU不会得到中断请求。如图5所示。
中断的例子:CC2544 举个具体的例子。假设我们正在使用CC2544,并且禁用了PORT0。假设pin P0_3更改了它的值,以便在GPIO外围设备中设置它的标志。PORT0中断标志随后也将在中断控制器中设置,但是中断控制器忽略该标志。
中断控制器忽略中断向量标志的情况如图6所示。
在我遇到的所有微控制器中,当我们所寻找的事件发生在GPIO外设时,中断标志总是设置的,不管那个pin的中断是启用还是禁用。例如,如果pin P0_3以我们正在寻找的方式更改了它的值,那么它的标志将在GPIO外围设备中设置。然而,GPIO外围设备将不会向中断控制器发出此警报,因此将不会设置中断控制器中的PORT0中断标志,而且由于我们需要设置该标志才能中断CPU,因此中断将不会发生。如图7所示。
中断必须在外设中启用(如果适用)。 它在中断控制器中的相应中断也必须被启用。 所有中断都必须由CPU启用(例如,CPU和中断控制器之间的通信必须为可屏蔽中断启用)。
每当多个事件同时发生并导致多个中断在中断控制器上挂起时,中断控制器就会选择优先级最高的中断供CPU处理。中断可以中断(或抢占)已经运行中断,所以如果一个低优先级中断是由CPU、和事件关联到一个更高的优先级中断发生时,控制器将中断CPU处理中断的优先级更高,和CPU将恢复处理的低优先级中断抢占时完成。图9说明了中断的优先级和抢占是如何工作的。
检查和清除中断标志 我们前面看到,对于一些微控制器,如CC2544,当ISR代码开始执行时,我们只知道哪个端口导致了中断,但不知道具体的pin。例如,如果P0_3更改了它的值,它的标志将在GPIO外围设备内设置,但是CPU只执行ISR来响应中断控制器的PORT0中断标志。检查ISR内的GPIO外设中断标志可以告诉我们哪个特定的pin产生了中断,这样我们就可以做出相应的响应。
为了避免这种情况,我们需要清除中断标志。有时中断标志被中央处理器自动清除时,它开始运行ISR;其他时候,你必须自己清除旗帜。微控制器的技术文件会让你知道是哪种情况。例如,CC2544不会自动清除引脚中断的标志,但ATmega328P可以。如果您必须自己清除中断,这通常是您在ISR代码中要做的第一件事,通常是在弄清楚是哪个pin中断导致ISR被执行之后。
写一个ISR,在里面你 确保清除所有需要清除的标志 用所需的动作响应中断 将ISR与正确的中断向量相关联 配置要触发中断的GPIO事件。对于特定的微控制器,可能的选项并不都是可用的,它们只是从0到1的变化,从1到0的变化,任何变化(0到1或1到0),稳定在1或稳定在0。 为GPIO内部的pin启用中断。通常建议在启动引脚中断前清除引脚的标志。 在中断控制器中启用中断。 确保CPU启用了所有中断。
如果您对我上面描述的GPIO中断有疑问,请在下面的评论中与我们分享。
|