microcontroller - ICR1 时间会错误地同步到溢出计数器吗?
问题描述
我有一个 Atmega328p,我想对其进行编程以精确捕获输入事件的时间。
但是,如果我的代码在所有情况下都可以工作,现在我遇到了一个问题。我认为这个问题与 Atmega 平台上中断的一般处理有关。
所以我的代码看起来像这样(总结):
volatile uint16_t overflow = 0;
ISR(TIMER1_CAPT_vect) {
uint16_t captureCount = ICR1;
uint32_t t = ((uint32_t) overflow << 16) | captureCount;
}
ISR(TIMER1_OVF_vect) {
overflow++;
}
这应该在中断 ISR(TIMER1_CAPT_vect) 内发生输入事件时捕获,此外,定时器 1 的溢出与另一个中断一起计数。据我了解,ICR1 准确地存储了输入事件发生时 timer1 的时间,然后在短时间内触发中断以通知代码该事件发生,然后我使用当前溢出计数器计算实时时间。
我从这个答案中知道,中断内的代码不会被另一个中断(例如溢出中断)中断,因此在形式 t 中添加溢出和捕获计数是“原子的”/“线程安全的”。但我现在想知道的是,如果 ICR1 由当前的 timer1 值设置并且在发生溢出之后,在 ISR(TIMER1_CAPT_vect)通知我的代码之前会发生什么。有了这个,也许溢出中断在事件捕获中断之前运行。这将导致溢出计数器增加 1 但 ICR1 仍保持对应于旧溢出范围的时间的可能性,从而给出错误的 t。
所以一般来说,这个问题只有在触发事件捕获中断之前触发溢出中断才会发生,尽管真正的捕获事件(当 ICR1 设置为当前 timer1 时)发生在溢出之前。
这让我想到了一个普遍的问题:中断的处理顺序是否与 Atmega 上发生的实际真实事件的顺序相同?
特别是关于我的两个定时器1中断?
解决方案
ATmega328P 数据表听起来像是地址较低的中断具有较高的优先级。因此,如果多个中断试图同时运行,我希望 AVR 选择具有最低地址的中断并运行它。
从第 6.7 节,复位和中断处理开始:
向量的完整列表显示在第 11 节“中断”(第 49 页)中。该列表还确定了不同中断的优先级。地址越低,优先级越高。RESET 具有最高优先级,其次是 INT0——外部中断请求 0。
如果 AVR 要按照您的建议运行,并记住每个中断发生的顺序,则需要大量额外的机器。
如果我们转到上面引用中提到的数据表的第 11 节,我们会看到 Timer 1 捕捉中断比 Timer 1 溢出中断具有更高的优先级(因为它具有较低的地址)。
推荐阅读
- javascript - IE 和 Windows Server 2012 上的 JavaScript 音频元素
- html - 在引导轮播中每个图像的底部添加链接
- c# - 带有共享选项列表的纯文本给出错误
- asp.net - ASP.NET CORE 2:模型绑定的复杂类型不能是抽象类型或值类型,并且必须具有无参数构造函数
- android - 即使出现错误(root),如何强制 gradle 构建我的应用程序?
- r - 如何根据距离标准将值从一个数据帧添加到另一个数据帧。
- javascript - Chrome 扩展在页面上获取元属性的内容并传回扩展
- php - LDAP 过滤器:仅获取自给定日期以来更新的用户
- python - python代码返回错误:ufunc'subtract'不包含签名匹配类型dtype('
我正在关注带有 Python 介绍的视频实用机器学习教程(https://www.y
- url-rewriting - 将子域重定向到发布 URL