首页 > 应用与设计 > 电器 > Service Robots > 服务型机器人 > TI-RSLK 模块 14 - 实时系统 >

服务型机器人

最新课程

热门课程

TI-RSLK 模块 14 - 讲座视频 - 实时系统 - 理论

大家好,我是 Jon Valvano。 在前一个视频中, 我们讨论了什么是实时系统。 在前一个视频中, 我们讨论了什么是实时系统。 在本视频中,我将向您展示如何实现它。 此外,我将向您展示 如何证明它确实正常运行了。 我们要在实验中解决的问题是, 如果机器人撞到墙, 我想让电机停止,我要做的是 在边沿触发中断中设置它, 从而在发生碰撞事件时, 它将根据硬件电路的实现方式, 在一个 GPIO 引脚上检测到 一个上升沿或下降沿。 在一个 GPIO 引脚上检测到 一个上升沿或下降沿。 我要做的是,设置好 这个 GPIO 引脚,使它在该边沿触发一个中断, 这样,我们就可以实现很低的延迟 和很短的响应时间,从而使机器人碰撞和 电机停止之间的时间间隔 变得很短、很有限。 在此期间,我们将再次讨论中断 和嵌套向量中断控制器。 我们将讨论优先级, 然后引导您完成一些必需的步骤, 以便您在您的工具库中加入边沿触发中断 这个新工具。 好,让我们开始吧。 请注意,我们以前已经看到过这个, 这是我们的中断向量表。 这基本上为我们提供了我们可以 在 MSP432 上实现的所有中断。 我们之前已经看到过 Systick 中断, 这是我们第一次接触中断。 之后,我们看到过周期性定时器, 有四个周期性定时器, 它们都可以产生中断。 现在,我将介绍另外 6 个可能发生的中断, 分别是端口 1、2、3、4、5等, 这些端口上的任何引脚上的上升沿或下降沿 分别是 Port 1、2、3、4、5等, 这些端口上的任何引脚上的上升沿或下降沿 经过设置都可以触发中断。 您应该注意到,它没有 7、8、9 和 10,因此, 为了完成本实验, 我们必须将碰撞开关 接到这六个端口之一。 接到这六个端口之一。 这张表中还有其他什么内容呢? 还有中断序号, 每个中断有一个中断向量。 例如我将使用端口 1, 它对应的中断向量在这里, 所以它将是中断 35, 它有这个特定的中断向量名, 叫做 port 1_IRQ handler。 用于设置端口 1 优先级的三个寄存器位 在这里,在嵌套向量中断控制器 在这里,在嵌套向量中断控制器 优先级寄存器 8 , 它位于第 31、30 和 29 位。 让我们继续。 这是对以前所学知识的回顾, 我们以前已经看到过中断, 我们知道,有四件事情是 要产生中断时必须发生的。 在本例中 -- 这四件事可以是任何顺序 我将按照相反的顺序来执行它们 -- 我们有硬件触发信号, 它是触发中断所必需的信号, 在本例中,它将是上升沿或下降沿, 嗯,它将是 P1.4 上的下降沿, 这将是我们的触发信号, 这个信号将会把端口 1 的 中断标志寄存器的第 4 位置为 1。 这就是硬件触发信号。 接下来,在软件上有三个地方需要进行初始化, 接下来,在软件上有三个地方需要进行初始化, 我们有中断使能位(ARM), 端口 1 的所有中断不一定要全部开启, 我们只需设置 P1.4 的中断使能位, 以便它发出一个中断请求。 然后,我们将通知嵌套向量中断控制器 我想要使用这个中断, 具体来说,我要启用第 35 号中断, 具体来说,我要启用第 35 号中断, 请注意,对于 Systick, 我们不需要执行该步骤, 但对于定时器,我们需要执行该步骤。 最后,所有中断在 primask 中都有 一个统一的使能位, primask 中的 i 位必须是 0, 这全部四个事件,如果它们同时为真, 那么将产生一个中断请求。 现在,如果这个中断是优先级 2, 那么如果有一个优先级 0、1、 或 2 的中断正在运行, 那么新的中断会被延迟,但假如 没有其他中断正在运行, 它将执行完当前指令,令八个寄存器入栈, 从低位 ROM 表中取出向量, 具体到 C 语言中,我们要做的是, 编写 PORT1_IRQ 这个函数, 这将为我们设置该向量。 接下来会自动发生的是, 在处理器中的某个位置, 您有一个寄存器,它说, 嘿,我要运行 35 号中断, 连接寄存器具有一个特殊代码, 然后,嘣,我们开始运行中断了。 好了,我们现在正在运行与该触发信号 关联的中断服务函数。 好了,我们现在正在运行与该触发信号 关联的中断服务函数。 我们将执行一个称为确认的步骤, 它将清除该同一个标志位, 因此我们实际上将清除 IFG bit 4。 我们将执行该服务。 现在,在本例中, 我将使计数器递增, 但在实验中,我们将停止电机, 因为您刚刚撞上了墙。 然后,当它执行该 BXLR, 并且 LR 具有该特殊代码时, 它将从堆栈中重新弹出所有这些寄存器, 包括程序计数器, 这将使您返回到中断发生时您所处的位置。 这就是通常中断发生时, 包括边沿触发中断发生时, 所产生的具体现象。 那么,这里是初始化, 它发生一次。 对于负逻辑接触开关, 硬件具有内部上拉电阻器, 对于负逻辑接触开关, 硬件具有内部上拉电阻器, 因此开关接通时会产生下降沿。 正如我说过的,中断服务中所执行的实际代码是 使计数器递增。 这碰巧是一个常规 GPIO 函数, 因此我们将清除引脚功能复用, 因此我们将清除引脚功能复用, 这是第 4 位,因为这是引脚 4, 这是端口 1,这也是端口 1。 这是端口 1,这也是端口 1。 这是一个输入引脚,因此要清除方向寄存器。 这两个位,正如我们在前一个视频中看到的, 将设置内部上拉, 这样,如果开关未被按下,将是高电平。 这条线之上的所有内容是我们 已经针对 GPIO 完成的事情。 这是对我们这个学期多次学习内容的 一个回顾。 接下来的是新内容, 是关于中断的。 您需要区分上升沿和下降沿, 这是 IES 寄存器,正如您在这里看到的, 我要将第 4 位设置为 1, 在这里,该寄存器中的 1 意味着下降沿。 您应该能想到 0 意味着 上升沿,如果您需要上升沿的话。 接下来,我要清除中断标志位, 以确保第一个中断在边沿之后 才会发生,而不是因为 以确保第一个中断在边沿之后 才会发生,而不是因为 处理器在上电时执行了意想之外的操作。 因此我将清除该中断标志位, 以及我的所有初始化项, 这是作为一项预防措施, 以确保第一个中断 在我完成所有初始化之后再发生。 因此,这是一个可选的步骤。 下面这个步骤不是可选的。 我们必须对中断进行使能, IE 寄存器是用于 使能端口 1 边沿触发中断的寄存器, 将它置为 1 意味着已进行使能。 很显然,0 意味着未使能。 因此,我可以设置端口 1 的其他七位, 清除这些位,从而不让它们的中断被引发。 我们讨论过优先级设置, 它位于第 31、30、29 位, 如果我把这三位设置为 1 0 1, 这将把端口 1 中断设为优先级 2。 这将把端口 1 中断设为优先级 2。 这样它将打断优先级 3、4、5、6 的中断, 但如果在中断触发时碰巧有优先级0、1 或 2 的中断正在运行,它将被延迟。 但如果在中断触发时碰巧有优先级0、1 或 2 的中断正在运行,它将被延迟。 下一步是在嵌套向量中断控制器中启用这个中断, 如果我们用 35 减去 32, 这是因为其中的每个寄存器只有 32 位宽, 我可以看到中断 35 实际上是 该寄存器的第 3 位。 下面这部分听起来有点奇怪, 请不要怪我,我只是个送信的, 我没有编造这段内容。 这个部分有点奇怪, 它是由 ARM 架构决定的,也就是说,该寄存器 具有一个特殊之处。 如果您向这个寄存器写入 1,将启用该中断, 但如果您向这个寄存器写入 0, 并不会禁用该中断, 将不会发生任何事情。 有另外一个叫 Disable Interrupt 的寄存器, 您可以向它写入 1 来禁用中断, 但这实际上是个友好的操作, 因为我仅想要设置第 3 位, 尽管代码上看起来我要清除其他 31 个位, 但实际上不会,因为这是一个特殊的寄存器。 现在,很显然,我们必须启用全局中断, 我们应在所有初始化完成之后执行该操作。 上面这些初始化将执行一次, 以在按键被按下时启用下降沿中断。 上面这些初始化将执行一次, 以在按键被按下时启用下降沿中断。 现在,当我按下按键时会发生的是, 我将得到一个中断。 产生中断的四件事情刚刚发生, 因此,如果您查看 P1.4, 会看到按键按下的动作导致了一个下降沿, 我们将这个动作称为触发信号, 或是需要做出响应的事件。 如果使用双通道示波器 或双通道逻辑分析仪, 可以测量到从触发信号发生 到中断服务函数运行之间的时间间隔。 这个时间会很短, 如果没有优先级为 0、1 或 2 的中断在运行, 但是,如果有上述优先级的中断在运行, 该时间将会延长, 这就是所谓的延迟。 延迟是触发信号和中断服务函数 开始运行之间的时间间隔。 延迟是触发信号和中断服务函数 开始运行之间的时间间隔。 而响应时间 则是触发信号到中断服务函数运行结束之间的时间, 则是触发信号到中断服务函数运行结束之间的时间, 这段时间称为响应时间。 这里的重点是,我可以使用双通道 示波器来测量中断请求和 中断服务开始之间的时间,称为延迟时间, 或测量请求和中断服务结束之间的时间, 称为响应时间。 这里调试时所用到的三次电平切换 也可以从更大的时间范围来看。 在这里,我缩小了时间轴, 因此,现在其中的每个按键按下的动作 -- 因为三次切换之间的时间非常短 -- 看起来都将是一个边沿。 正如我提到过的,Systick 以外的每个 中断服务例程都必须具有一个 步骤称为确认,即清除发生请求的中断标志位。 步骤称为确认,即清除发生请求的中断标志位。 上述是一个碰撞开关时的情况。 如果您有多个开关怎么办? 我将通过三种方法来处理它, 因此请坐好,听我慢慢道来。 这是最简单的一种。 那么,如果我有多个 需要在后台进行中断服务的开关, 我可以做的最简单的事情是, 使用我在模块 13 中学到的知识, 换句话说,用一个周期性中断, 让这个中断的周期快于我按下的速度, 但慢于开关弹回的速度, 让这个中断的周期快于开关被按下的频率, 但慢于开关弹回的速度, 具体来说, 我将每 10 毫秒进入一次中断服务函数, 在该 10 毫秒中, 我将查看开关是否按下。 那么显然,如果这里的第 3 位 是高电平,这将为真 -- 抱歉,这是第 2 位 -- 那么,如果 P6.2 被置为高电平, 那么这个中断服务函数将被执行。 这些是正逻辑开关, 因此这意味着开关 1 被按下。 因此这意味着开关 1 被按下。 另一个开关是 P6.3。 但这里的问题是延迟。 如果我看这个引脚,P6.2, 来看开关按下的时刻,当我按下开关, 它变成了高电平, 这个动作触发了延迟。 现在,我需要添加周期性测试。 那么,这是一个10 毫秒周期性中断, 这是 -- 这是下一个 -- 我来看看这些中断, 未按下,未按下,现在 我看到按键被按下。 现在程序运行到这个位置。 可以看到,该延迟, 即开关被按下和软件识别 这个动作之间的时间, 将在零和10 毫秒之间变化。 如果它们未同步,平均值将是 5 毫秒。 好了,这个方法可能不是足够好,但它就是这样, 它是一种非常简单的解决方案。 我使用一个周期性中断, 每个一个周期查看是否有事件发生。 每个一个周期查看是否有事件发生。 但是,如果我想让程序反应更快, 需要使用边沿触发中断。 第二种方法也不太难, 我将使用不同的端口。 请注意,我移动了我的开关,所以一个开关 位于端口 5 上,而另一个开关 位于端口 6 上。 那么,我要做的是,将我在第一个 示例中执行的操作执行两次, 一次针对端口 5,一次针对端口 6。 这里发生的是上升沿事件, 而不是刚才的下降沿。 我使用的是中断 39 和 40, 因为端口 5 是中断 39, 端口 6 是中断 40。 顺便补充一句, 如果您在后续实验中执行边沿中断操作, 那么端口 4 将是中断 38,但那是实验部分。 现在,我将使能这两个中断, 并在嵌套向量中断控制器中启用这两者。 并在嵌套向量中断控制器中启用这两者。 再重复一次,这里的操作是一个友好的操作, 因为它不会撤消另一个操作。 现在,我有两个不同的中断向量, 每个中断向量用于一个开关。 我的中断向量很简单。 如果开关 1 被按下, 将进入端口 5 中断,我将清除中断标志位 并编写中断服务程序。 如果开关 2 被按下, 将进入端口 6 中断。 由于它们具有相同的优先级, 因此它们不会相互影响。 换句话说,它们不会 -- 不会相互打断, 如果一个中断正在进行,那么另一个将延迟, 被延迟的中断将被触发,它不会被忽略, 也不会丢失, 只是会延迟。 因此,这是一个非常简单的解决方案, 仅使用端口 1、2、3、4、5 和 6 作为单独的中断。 请注意,这种方法可能比较便利,也可能不便利。 下面我们来看轮询解决方案, 刚刚是中断向量解决方案。 这是轮询解决方案,我回看原始硬件设计, 看到有多个开关位于同一个端口上。 因此我将两个引脚都设置为上升沿中断, 引脚 2 和引脚 3, 然后我将进行初始化清除操作。 引脚 2 和引脚 3, 然后我将进行初始化清除操作。 我将两个引脚都设为输入, 让它们都作为 GPIO。 我还需要使能这两者中断。 现在,它们都将通过中断向量 40 来进入中断, 但问题是,它们将引发相同的 IRQ, 那么,如果它们碰巧同时发生, 我将只进入一个中断,我必须处理好这个问题。 有几种方法来处理这种情况, 最简单的方法是,使用一个特殊寄存器, 它的名字叫做 IV 寄存器。 那么,如果同一个端口的多个引脚 都有可能引发中断,我要做的是, 读取该 IV 寄存器,IV 寄存器提供的是 此端口中的最低位编号。 接下来会发生的是,它将为您提供 -- 它不会告诉您有两个中断, 它只告诉您有一个中断。 那么,具体来说,如果它碰巧是 -- 对于 IV 寄存器,如果是第 0 位发生中断, 您会看到寄存器读取结果将会是 2。 如果中断在第 1 位, 您将在寄存器中读到 4。 如果是第 2 位,就是图中这一位, 将得到 6。 第 3 位将得到 8。 第 4 位将得到 10。 第 5 位应该是 12。 第 6 位应该是 14,第 7 位应该是 16。 如果您读到 0,说明它出错了。 但是,如果您有多个中断,多个边沿, 您将获得具有最低引脚编号的那个。 但它不会 -- 它仅 -- 您会注意到,它不会清除其他中断, 因此,如果两个中断碰巧同时发生, 您将读到第一个中断, 并识别开关 1。 之后,您可以再次读取状态, 然后它将 -- 因为之前的中断服务已经完成。 因此,读取 IV 寄存器将为您 提供这些中断之一, 在图中所示情况下为 6 或 7(口误,应为8), 并且将自动清除另一个。 那么,通过这个方法,您将能够 同时使用这些中断, 同时使用这些中断, 响应其中一个或者两者同时响应, 并且不会因为任何关键部分或任何意外事件 而丢失或是忽略任何一个中断。 并且不会因为任何关键部分或任何意外事件 而丢失或是忽略任何一个中断。 这种方法更复杂一点, 如果您有六个中断同时发生, 您必须逐个检查该列表中的项目, 然后使用 IV 为下一个重新加载状态。 这就是德州仪器 (TI) 的特殊方式来 处理同一个端口上的多个边沿触发中断。 处理同一个端口上的多个边沿触发中断。 总结一下,我们讨论了边沿触发中断, 在对应实验中,我们将讨论碰撞事件, 该事件会使用同一个端口下的多个引脚, 您将学习使用 IV 寄存器 来分辨是哪一个引脚发生了中断。 然后,您将使用示波器 来看看需要多长时间来识别碰撞事件 并让电机停止转动。 这将是一个有趣的实验, 希望您喜欢它。 本章有许多基础知识是关于 中断、优先级、中断使能, 以及示波器和逻辑分析仪的, 希望您喜欢本次实验。 392

大家好,我是 Jon Valvano。

在前一个视频中, 我们讨论了什么是实时系统。

在前一个视频中, 我们讨论了什么是实时系统。

在本视频中,我将向您展示如何实现它。

此外,我将向您展示

如何证明它确实正常运行了。

我们要在实验中解决的问题是,

如果机器人撞到墙,

我想让电机停止,我要做的是

在边沿触发中断中设置它,

从而在发生碰撞事件时,

它将根据硬件电路的实现方式,

在一个 GPIO 引脚上检测到 一个上升沿或下降沿。

在一个 GPIO 引脚上检测到 一个上升沿或下降沿。

我要做的是,设置好

这个 GPIO 引脚,使它在该边沿触发一个中断,

这样,我们就可以实现很低的延迟

和很短的响应时间,从而使机器人碰撞和 电机停止之间的时间间隔

变得很短、很有限。

在此期间,我们将再次讨论中断

和嵌套向量中断控制器。

我们将讨论优先级,

然后引导您完成一些必需的步骤,

以便您在您的工具库中加入边沿触发中断

这个新工具。

好,让我们开始吧。

请注意,我们以前已经看到过这个,

这是我们的中断向量表。

这基本上为我们提供了我们可以

在 MSP432 上实现的所有中断。

我们之前已经看到过 Systick 中断,

这是我们第一次接触中断。

之后,我们看到过周期性定时器,

有四个周期性定时器,

它们都可以产生中断。

现在,我将介绍另外 6 个可能发生的中断,

分别是端口 1、2、3、4、5等, 这些端口上的任何引脚上的上升沿或下降沿

分别是 Port 1、2、3、4、5等, 这些端口上的任何引脚上的上升沿或下降沿

经过设置都可以触发中断。

您应该注意到,它没有

7、8、9 和 10,因此, 为了完成本实验,

我们必须将碰撞开关

接到这六个端口之一。

接到这六个端口之一。

这张表中还有其他什么内容呢?

还有中断序号,

每个中断有一个中断向量。

例如我将使用端口 1, 它对应的中断向量在这里,

所以它将是中断 35,

它有这个特定的中断向量名,

叫做 port 1_IRQ handler。

用于设置端口 1 优先级的三个寄存器位

在这里,在嵌套向量中断控制器

在这里,在嵌套向量中断控制器

优先级寄存器 8 , 它位于第 31、30 和 29 位。

让我们继续。

这是对以前所学知识的回顾,

我们以前已经看到过中断,

我们知道,有四件事情是

要产生中断时必须发生的。

在本例中 -- 这四件事可以是任何顺序

我将按照相反的顺序来执行它们 --

我们有硬件触发信号,

它是触发中断所必需的信号,

在本例中,它将是上升沿或下降沿,

嗯,它将是 P1.4 上的下降沿,

这将是我们的触发信号, 这个信号将会把端口 1 的

中断标志寄存器的第 4 位置为 1。

这就是硬件触发信号。

接下来,在软件上有三个地方需要进行初始化,

接下来,在软件上有三个地方需要进行初始化,

我们有中断使能位(ARM),

端口 1 的所有中断不一定要全部开启,

我们只需设置 P1.4 的中断使能位,

以便它发出一个中断请求。

然后,我们将通知嵌套向量中断控制器

我想要使用这个中断,

具体来说,我要启用第 35 号中断,

具体来说,我要启用第 35 号中断,

请注意,对于 Systick, 我们不需要执行该步骤,

但对于定时器,我们需要执行该步骤。

最后,所有中断在 primask 中都有

一个统一的使能位,

primask 中的 i 位必须是 0,

这全部四个事件,如果它们同时为真,

那么将产生一个中断请求。

现在,如果这个中断是优先级 2,

那么如果有一个优先级 0、1、 或 2 的中断正在运行,

那么新的中断会被延迟,但假如

没有其他中断正在运行,

它将执行完当前指令,令八个寄存器入栈,

从低位 ROM 表中取出向量,

具体到 C 语言中,我们要做的是, 编写 PORT1_IRQ 这个函数,

这将为我们设置该向量。

接下来会自动发生的是,

在处理器中的某个位置, 您有一个寄存器,它说,

嘿,我要运行 35 号中断,

连接寄存器具有一个特殊代码,

然后,嘣,我们开始运行中断了。

好了,我们现在正在运行与该触发信号 关联的中断服务函数。

好了,我们现在正在运行与该触发信号 关联的中断服务函数。

我们将执行一个称为确认的步骤,

它将清除该同一个标志位, 因此我们实际上将清除

IFG bit 4。

我们将执行该服务。

现在,在本例中,

我将使计数器递增,

但在实验中,我们将停止电机,

因为您刚刚撞上了墙。

然后,当它执行该 BXLR,

并且 LR 具有该特殊代码时,

它将从堆栈中重新弹出所有这些寄存器,

包括程序计数器,

这将使您返回到中断发生时您所处的位置。

这就是通常中断发生时,

包括边沿触发中断发生时, 所产生的具体现象。

那么,这里是初始化, 它发生一次。

对于负逻辑接触开关, 硬件具有内部上拉电阻器,

对于负逻辑接触开关, 硬件具有内部上拉电阻器,

因此开关接通时会产生下降沿。

正如我说过的,中断服务中所执行的实际代码是

使计数器递增。

这碰巧是一个常规 GPIO 函数,

因此我们将清除引脚功能复用,

因此我们将清除引脚功能复用,

这是第 4 位,因为这是引脚 4,

这是端口 1,这也是端口 1。

这是端口 1,这也是端口 1。

这是一个输入引脚,因此要清除方向寄存器。

这两个位,正如我们在前一个视频中看到的,

将设置内部上拉,

这样,如果开关未被按下,将是高电平。

这条线之上的所有内容是我们

已经针对 GPIO 完成的事情。

这是对我们这个学期多次学习内容的

一个回顾。

接下来的是新内容,

是关于中断的。

您需要区分上升沿和下降沿,

这是 IES 寄存器,正如您在这里看到的,

我要将第 4 位设置为 1,

在这里,该寄存器中的 1 意味着下降沿。

您应该能想到 0 意味着

上升沿,如果您需要上升沿的话。

接下来,我要清除中断标志位,

以确保第一个中断在边沿之后 才会发生,而不是因为

以确保第一个中断在边沿之后 才会发生,而不是因为

处理器在上电时执行了意想之外的操作。

因此我将清除该中断标志位,

以及我的所有初始化项,

这是作为一项预防措施, 以确保第一个中断

在我完成所有初始化之后再发生。

因此,这是一个可选的步骤。

下面这个步骤不是可选的。

我们必须对中断进行使能, IE 寄存器是用于

使能端口 1 边沿触发中断的寄存器,

将它置为 1 意味着已进行使能。

很显然,0 意味着未使能。

因此,我可以设置端口 1 的其他七位,

清除这些位,从而不让它们的中断被引发。

我们讨论过优先级设置,

它位于第 31、30、29 位, 如果我把这三位设置为 1 0 1,

这将把端口 1 中断设为优先级 2。

这将把端口 1 中断设为优先级 2。

这样它将打断优先级 3、4、5、6 的中断,

但如果在中断触发时碰巧有优先级0、1 或 2 的中断正在运行,它将被延迟。

但如果在中断触发时碰巧有优先级0、1 或 2 的中断正在运行,它将被延迟。

下一步是在嵌套向量中断控制器中启用这个中断,

如果我们用 35 减去 32,

这是因为其中的每个寄存器只有 32 位宽,

我可以看到中断 35 实际上是

该寄存器的第 3 位。

下面这部分听起来有点奇怪,

请不要怪我,我只是个送信的,

我没有编造这段内容。

这个部分有点奇怪,

它是由 ARM 架构决定的,也就是说,该寄存器

具有一个特殊之处。

如果您向这个寄存器写入 1,将启用该中断,

但如果您向这个寄存器写入 0,

并不会禁用该中断,

将不会发生任何事情。

有另外一个叫 Disable Interrupt 的寄存器,

您可以向它写入 1 来禁用中断,

但这实际上是个友好的操作, 因为我仅想要设置第 3 位,

尽管代码上看起来我要清除其他 31 个位,

但实际上不会,因为这是一个特殊的寄存器。

现在,很显然,我们必须启用全局中断,

我们应在所有初始化完成之后执行该操作。

上面这些初始化将执行一次, 以在按键被按下时启用下降沿中断。

上面这些初始化将执行一次, 以在按键被按下时启用下降沿中断。

现在,当我按下按键时会发生的是,

我将得到一个中断。

产生中断的四件事情刚刚发生,

因此,如果您查看 P1.4,

会看到按键按下的动作导致了一个下降沿,

我们将这个动作称为触发信号,

或是需要做出响应的事件。

如果使用双通道示波器

或双通道逻辑分析仪,

可以测量到从触发信号发生

到中断服务函数运行之间的时间间隔。

这个时间会很短,

如果没有优先级为 0、1 或 2 的中断在运行,

但是,如果有上述优先级的中断在运行,

该时间将会延长,

这就是所谓的延迟。

延迟是触发信号和中断服务函数 开始运行之间的时间间隔。

延迟是触发信号和中断服务函数 开始运行之间的时间间隔。

而响应时间

则是触发信号到中断服务函数运行结束之间的时间,

则是触发信号到中断服务函数运行结束之间的时间,

这段时间称为响应时间。

这里的重点是,我可以使用双通道

示波器来测量中断请求和

中断服务开始之间的时间,称为延迟时间,

或测量请求和中断服务结束之间的时间,

称为响应时间。

这里调试时所用到的三次电平切换

也可以从更大的时间范围来看。

在这里,我缩小了时间轴,

因此,现在其中的每个按键按下的动作 --

因为三次切换之间的时间非常短 --

看起来都将是一个边沿。

正如我提到过的,Systick 以外的每个

中断服务例程都必须具有一个

步骤称为确认,即清除发生请求的中断标志位。

步骤称为确认,即清除发生请求的中断标志位。

上述是一个碰撞开关时的情况。

如果您有多个开关怎么办?

我将通过三种方法来处理它, 因此请坐好,听我慢慢道来。

这是最简单的一种。

那么,如果我有多个

需要在后台进行中断服务的开关,

我可以做的最简单的事情是,

使用我在模块 13 中学到的知识,

换句话说,用一个周期性中断,

让这个中断的周期快于我按下的速度, 但慢于开关弹回的速度,

让这个中断的周期快于开关被按下的频率, 但慢于开关弹回的速度,

具体来说,

我将每 10 毫秒进入一次中断服务函数,

在该 10 毫秒中,

我将查看开关是否按下。

那么显然,如果这里的第 3 位 是高电平,这将为真 --

抱歉,这是第 2 位 --

那么,如果 P6.2 被置为高电平, 那么这个中断服务函数将被执行。

这些是正逻辑开关,

因此这意味着开关 1 被按下。

因此这意味着开关 1 被按下。

另一个开关是 P6.3。

但这里的问题是延迟。

如果我看这个引脚,P6.2,

来看开关按下的时刻,当我按下开关,

它变成了高电平,

这个动作触发了延迟。

现在,我需要添加周期性测试。

那么,这是一个10 毫秒周期性中断,

这是 --

这是下一个 -- 我来看看这些中断,

未按下,未按下,现在

我看到按键被按下。

现在程序运行到这个位置。

可以看到,该延迟,

即开关被按下和软件识别 这个动作之间的时间,

将在零和10 毫秒之间变化。

如果它们未同步,平均值将是

5 毫秒。

好了,这个方法可能不是足够好,但它就是这样,

它是一种非常简单的解决方案。

我使用一个周期性中断,

每个一个周期查看是否有事件发生。

每个一个周期查看是否有事件发生。

但是,如果我想让程序反应更快,

需要使用边沿触发中断。

第二种方法也不太难,

我将使用不同的端口。

请注意,我移动了我的开关,所以一个开关

位于端口 5 上,而另一个开关

位于端口 6 上。

那么,我要做的是,将我在第一个 示例中执行的操作执行两次,

一次针对端口 5,一次针对端口 6。

这里发生的是上升沿事件,

而不是刚才的下降沿。

我使用的是中断 39 和 40,

因为端口 5 是中断 39,

端口 6 是中断 40。

顺便补充一句, 如果您在后续实验中执行边沿中断操作,

那么端口 4 将是中断 38,但那是实验部分。

现在,我将使能这两个中断,

并在嵌套向量中断控制器中启用这两者。

并在嵌套向量中断控制器中启用这两者。

再重复一次,这里的操作是一个友好的操作,

因为它不会撤消另一个操作。

现在,我有两个不同的中断向量,

每个中断向量用于一个开关。

我的中断向量很简单。

如果开关 1 被按下,

将进入端口 5 中断,我将清除中断标志位

并编写中断服务程序。

如果开关 2 被按下,

将进入端口 6 中断。

由于它们具有相同的优先级,

因此它们不会相互影响。

换句话说,它们不会 --

不会相互打断,

如果一个中断正在进行,那么另一个将延迟,

被延迟的中断将被触发,它不会被忽略,

也不会丢失,

只是会延迟。

因此,这是一个非常简单的解决方案,

仅使用端口 1、2、3、4、5 和 6 作为单独的中断。

请注意,这种方法可能比较便利,也可能不便利。

下面我们来看轮询解决方案,

刚刚是中断向量解决方案。

这是轮询解决方案,我回看原始硬件设计,

看到有多个开关位于同一个端口上。

因此我将两个引脚都设置为上升沿中断,

引脚 2 和引脚 3, 然后我将进行初始化清除操作。

引脚 2 和引脚 3, 然后我将进行初始化清除操作。

我将两个引脚都设为输入,

让它们都作为 GPIO。

我还需要使能这两者中断。

现在,它们都将通过中断向量 40 来进入中断,

但问题是,它们将引发相同的 IRQ,

那么,如果它们碰巧同时发生,

我将只进入一个中断,我必须处理好这个问题。

有几种方法来处理这种情况,

最简单的方法是,使用一个特殊寄存器,

它的名字叫做 IV 寄存器。

那么,如果同一个端口的多个引脚

都有可能引发中断,我要做的是,

读取该 IV 寄存器,IV 寄存器提供的是

此端口中的最低位编号。

接下来会发生的是,它将为您提供 --

它不会告诉您有两个中断,

它只告诉您有一个中断。

那么,具体来说,如果它碰巧是 --

对于 IV 寄存器,如果是第 0 位发生中断,

您会看到寄存器读取结果将会是 2。

如果中断在第 1 位,

您将在寄存器中读到 4。

如果是第 2 位,就是图中这一位,

将得到 6。

第 3 位将得到 8。

第 4 位将得到 10。

第 5 位应该是 12。

第 6 位应该是 14,第 7 位应该是 16。

如果您读到 0,说明它出错了。

但是,如果您有多个中断,多个边沿,

您将获得具有最低引脚编号的那个。

但它不会 -- 它仅 --

您会注意到,它不会清除其他中断,

因此,如果两个中断碰巧同时发生,

您将读到第一个中断,

并识别开关 1。

之后,您可以再次读取状态,

然后它将 --

因为之前的中断服务已经完成。

因此,读取 IV 寄存器将为您

提供这些中断之一, 在图中所示情况下为 6 或 7(口误,应为8),

并且将自动清除另一个。

那么,通过这个方法,您将能够

同时使用这些中断,

同时使用这些中断,

响应其中一个或者两者同时响应,

并且不会因为任何关键部分或任何意外事件 而丢失或是忽略任何一个中断。

并且不会因为任何关键部分或任何意外事件 而丢失或是忽略任何一个中断。

这种方法更复杂一点,

如果您有六个中断同时发生,

您必须逐个检查该列表中的项目,

然后使用 IV 为下一个重新加载状态。

这就是德州仪器 (TI) 的特殊方式来

处理同一个端口上的多个边沿触发中断。

处理同一个端口上的多个边沿触发中断。

总结一下,我们讨论了边沿触发中断,

在对应实验中,我们将讨论碰撞事件,

该事件会使用同一个端口下的多个引脚,

您将学习使用 IV 寄存器

来分辨是哪一个引脚发生了中断。

然后,您将使用示波器

来看看需要多长时间来识别碰撞事件

并让电机停止转动。

这将是一个有趣的实验,

希望您喜欢它。

本章有许多基础知识是关于

中断、优先级、中断使能,

以及示波器和逻辑分析仪的, 希望您喜欢本次实验。 392

视频报错
手机看
扫码用手机观看
收藏本课程

相关下载

视频简介

TI-RSLK 模块 14 - 讲座视频 - 实时系统 - 理论

所属课程:TI-RSLK 模块 14 - 实时系统 发布时间:2018.08.27 视频集数:3 本节视频时长:17:53
在该模块中,你将会学习如何创建一个用于碰撞检测的实时系统。
已有7人参与了讨论去论坛跟帖交流