【问题标题】:Disable Timer 0 interrupt on Arduino without breaking Serial在不中断串行的情况下禁用 Arduino 上的 Timer 0 中断
【发布时间】:2015-06-01 11:07:07
【问题描述】:

背景:

我需要在 Arduino 环境中为我自己的 ISR 提供​​非常可重复的中断执行时序。 Arduino 核心库使用 Timer0 溢出中断来提供 millis()。有时,在执行 Timer0 溢出中断时,会满足触发我的中断的条件。默认情况下,AVR 不允许一个中断“中断”另一个。看到这个Nested interrupts question

Timer0 ISR 阻止我的 ISR 执行,直到它完成。此延迟最多可能需要 7 µs,这在我的应用程序中是不可接受的。 (我知道!)

我的应用程序中不需要millis(),所以我尝试在void setup() 中禁用Timer0 溢出中断:

TIMSK0 = 0;

问题:不幸的是,这破坏了硬件串行功能。我查看了核心库源,但我不明白硬件串行方法如何依赖 Timer 0。

约束:我希望我的草图能够编译并使用标准的 Arduino 发行版,所以我只能控制我的草图目录(不是 Arduino 目录)中的内容,而 Arduino 草图隐藏“包含”来自您,所以我不确定是否可以避免包含“HardwareSerial.h”。

确切的问题:

  1. Serial 类如何依赖 Timer0?
  2. 有没有办法在不修改核心库的情况下再次调用“Serial”类?
  3. 一般来说,我可以重新定义在别处定义的类的(或整个)方法吗?

【问题讨论】:

  • 我不确定答案是什么,但我很想知道应用程序是什么,7us 延迟会导致问题???
  • 我想如果您仍然需要串行通信,您可能可以轮询 USART 上的字节,而不是依赖中断。这样,当您的关键 ISR 没有运行时,您就可以做到这一点,但我以前从未与 Arduino 合作过,所以我不确定您在草图中被限制在什么范围内。
  • 好吧,你抓住了我。 7us 还不是完全不可接受的。我正在构建一个ECU for a van 这个问题目前只给系统增加了大约 0.3% 的错误,但表明我受制于其他人的代码运行时间紧张。我宁愿控制它,也不愿希望它保持足够好。
  • 我熟悉如何使用轮询来实现串行函数,但是我可以编写自己的例程,与内核中已经包含的函数同名吗?我希望另一个开发人员能够使用 Serial.println("hey");逐字逐句。
  • 你能把自己的中断设置为更高的优先级吗? courses.cs.washington.edu/courses/csep567/10wi/lectures/…

标签: c++ arduino embedded interrupt


【解决方案1】:

虽然您禁用了 Timer 0,但串行仍然有效。这个简单的实验得出结论。

#include "avr/pgmspace.h"
#include "avr/io.h"

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))


void setup() {
  Serial.begin(9600);
  cbi (TIMSK0, TOIE0); // disable Timer0 !!! delay() is now not available
}

void loop() {
  if (Serial.available()){
    Serial.write(Serial.read());
  }
  delay(1000);              // this is not working since Timer 0 disabled
}

【讨论】:

猜你喜欢
  • 2012-04-29
  • 2020-11-25
  • 1970-01-01
  • 2020-03-07
  • 1970-01-01
  • 2016-05-04
  • 1970-01-01
  • 2015-04-09
  • 1970-01-01
相关资源
最近更新 更多