我们希望构建一个简单的线路跟随器机器人,而在讨论PIC编程时遇到了一个问题。

但是我们的一位朋友告诉我们,使用计时器中断在确定的时间段内生成中断,并在每个中断中检查传感器面板的读数并进行相应的读取。

但是我们无法确定哪个是最好的:main方法或定时器中断方法中的无限循环。

什么是最好的方法,为什么?

评论

您忘了问“有没有最好的方法?”对于简单的系统,有时最好使用计时器硬件设置标志,然后在设置标志时运行控制循环。对于复杂的系统,ISR(通常是某种OS内核或至少是任务切换器)通常是最好的。

#1 楼

处理器必须执行某些操作。即使您在中断处理程序中进行某些工作,也始终会有一个“无尽”的循环。 />使用中断的主要优点是它们可以让您在主程序执行其他操作时实时处理事件。计时器中断专门使您可以在进行一些其他处理的同时,在相当准确的时基上执行一些定期活动。

对于大多数控制算法,具有某种时基(或固定的频率)。如果这就是CPU的全部工作,则可以通过控制控制循环中的周期/指令数或轮询计时器来轻松地做到这一点而不会中断。与使用中断相比,这两种方法将更简单,更高效。在更复杂的系统中,同时执行许多操作(I / O,时间保持,调度等)时,中断更有用。

如果不进行循环而没有轮询计时器或校准运行一次循环所需的时间,则必须小心在循环中添加更多代码会改变时序的情况和控制系统的行为。

如果在定时器中断中实现控制算法,则必须小心,不要试图执行超出CPU一次处理能力的工作”插槽”,否则将再次影响控制系统的行为。

#2 楼

除了盖伊的答案,使用计时器中断来生成准确的间隔可以增加确定性。例如,在任何给定时间,您都可以确切知道处理器在做什么,并且所有活动都以指定的速率执行。

您还应该按确定的速率进行计划,否则您将没有时间常数等基础,这对于您的过滤至关重要。

最后,这意味着如果添加其他任务,则不会降低现有任务的速度。


如果这是您的系统所有工作,那么简单轮询就可以了-但是时隙调度是一个很小的开销在一个琐碎的系统中,从一开始就添加它可以实现增长和扩展,而不必稍后重新构造所有内容。

评论


$ \ begingroup $
在某些情况下,与从中断中获得的结果相比,从循环中获得更多的确定性性能。下降到一个抖动周期。如果你只是做一件事...
$ \ endgroup $
– Guy Sirton
13年8月19日在21:17

#3 楼

我只想在其他帖子中添加几点。我个人的观点是,无尽的while循环在从snss读取或写入执行器的系统中没有意义,因为两者都有一些物理约束,例如。如果传感器在100Hz准确测量之前具有稳定周期,则以1Mhz的速度读取传感器毫无意义。电机驱动器也是如此。您可以发送1百万个指令来移动电动机,但它只能承受其在惯性方面的物理限制。我创建了定时器中断,每隔1ms左右触发一次,然后在该中断例程中递减一些全局变量。在主while循环中,我检查变量是否为0并执行由该变量定义的命令。在那种情况下,我可以以125Hz的频率驱动电动机,以20Hz的频率读取传感器,并以0.5Hz的频率输出LED。

我希望你明白了。

#4 楼

我还想强调一下,轮询(即检查是否设置了中断标志)与中断向量(即ISR或在发生中断时加载的函数)之间的比较应该不仅仅是评估效率/执行一块反动代码的简单性。大多数现代微控制器的中断控制器都具有更多功能,尤其是考虑到外设信号(例如DMA)时。

例如,德州仪器(TI)TMS320F28335微控制器可让您触发ADC的启动直接来自PWM的上升沿或下降沿的转换脉冲。除此之外,微控制器还具有六通道DMA控制器,例如,还可以对其进行编程以触发相同的PWM信号(这可以让您通过设备的并行总线来启动存储器读取,例如,已连接到高速delta sigma转换器)。然后,可以使用相同的DMA控制器将从ADC和外部delta sigma读取的值缓冲到内部RAM。然后,可以将DMA控制器配置为仅对总共128个ADC和ΔΣ读数采样后才触发正常的中断服务程序。所有这些都将在没有任何CPU干预的情况下发生(使您有更多的精力做其他事情)。有一个ISR控制所有的使能标志或存储器读取(由于与中断等待时间相关的开销)。向量链方法允许您以50 KHz(例如)进行采样,而ISR驱动的方法仅允许您以5 KHz(例如)进行采样。

也如Andrew所述,使用中断向量比轮询状态寄存器更具确定性或可重复性。

我强烈建议订阅Phil Koopman的博客,或者至少阅读以下文章:


使用中断的规则
为什么短中断服务例程很重要
使主循环调度时序更具确定性

软件时序循环(以及为什么应该使用硬件计时器)


#5 楼

旧帖子,仍然在回答别人的参考。

我正在从事类似的项目。甚至对我来说,一个朋友也建议使用计时器。

最后,我的建议是尽可能使用高速控制器(我的频率为80MHz)。使用5us定时器中断(调度程序)。在此Scheduler中断例程中执行以下操作:电动机需要运行)
StateChange()/ ApplicationRoutine()/ SwitchContext()(有关状态机的更多信息,请参见:https://barrgroup.com/Embedded-Systems/How-To/State-Machines-Event -Driven-Systems)(坦率地说,无法消化本文的结尾部分,但有了主意。我在StateChange()中使用简单的Switch Case。) while(1)循环:


检查键盘/触摸屏/串行通讯等的输入。
更新显示(如果该时间太长,会使键盘响应变慢,请尝试进行上述步骤,即检查键盘/触摸/串行中断。)


评论


$ \ begingroup $
欢迎来到Krishnananda Hegde的机器人技术。看来您可能不小心创建了两个帐户(Krishnananda Hegde和Krishnananda。K. Hegde)。 Stack Exchange仅允许个人积极使用一个帐户,因此请按照我不小心创建两个帐户的说明进行操作;如何合并它们?遗憾的是,主持人无法为您合并帐户,但可以删除他们认为是袜子木偶的帐户。
$ \ endgroup $
– Mark Booth♦
17-2-21在10:28



#6 楼

尽管使用轮询或中断不会在简单的线路跟随器机器人中造成任何重大变化,但是使用中断通常是很好的。

虽然在很多情况下都很好地使用了定时器中断,但是我建议在这种情况下,最好使用简单的中断,当传感器的特定输入(例如检测到白色,并且传感器发出逻辑高电平)。这样做可以确保您的微控制器在遇到白色补丁时到底在做什么。同样,在获取输入和执行相应的输出之间的延迟最小。

但是,对于简单的行跟随器,您可以留下中断并继续进行轮询。但是,如果您要与机器人进行多任务处理(例如具有多个传感器来执行各种操作),则可能需要中断。另一个好处是您可以为中断中的这些事件设置优先级。就像如果您正在执行任务A并且遇到中断并要求执行任务B时会发生什么。您可以通过将其中一个设置为更高的优先级来使其中一个变得更重要。这样做,将首先完成优先级更高的操作。