【发布时间】:2018-01-30 02:43:19
【问题描述】:
我正在尝试使用 atmel xmega avr 微控制器进行 正交解码。 Xmega 只有16-bit 计数器。此外,我已经用完了所有可用的计时器。
现在要制作32-bit 计数器,我使用了一个16-bit 计数器,并在其over/under flow interrupt 中增加/减少了一个16 位全局变量,因此通过组合它们我们可以制作32 位计数器。
ISR(timer_16bit)
{
if(quad_enc_mov_forward)
{
timer_over_flow++;
}
else if (quad_enc_mov_backward)
{
timer_over_flow--;
}
}
到目前为止,它工作正常。但我需要在并行运行的各种任务中使用这个 32 位值。我正在尝试读取 32 位值,如下所示
uint32_t current_count = timer_over_flow;
current_count = current_count << 16;
current_count = current_count + timer_16bit_count;
`timer_16_bit_count` is a hardware register.
现在我面临的问题是,当我在第一条语句中读取timer_over_flow 到current_count 时,当我添加timer_16bit_count 时可能会溢出,16bit 计时器可能已变为@ 987654333@。这可能会导致总的错误值。
我正在尝试在多个任务中读取这个 32 位值。
有没有办法防止这种数据损坏并获得 32 位值的工作模型。
不同成员寻求的详细信息:
我的电机可以向前或向后移动,并相应地计数器递增/递减。
1234563 /p>
在 ISR 中修改的变量声明为
volatile。多任务意味着我使用的 RTOS 内核包含大约 6 个任务(大部分是 3 个并行运行的任务)。
在 XMEGA 中,我直接读取
TCCO_CNT寄存器的低字节。
【问题讨论】:
-
代码需要在
uint32_t current_count = timer_over_flow;发生时防止短时间的中断。解决方案取决于实现。真的需要minimal reproducible example 才能得到一个好的答案。 -
不可能的。因为我们将丢失运动数据。
-
我期望的唯一问题是当定时器溢出被读取为零然后发生溢出时,硬件寄存器计数再次从零开始。因此,我们最终会读取一个非常低的值,而不是读取更高的值。
-
仍然需要 minimal reproducible example 。需要查看
quad_enc_mov_forward, timer_over_flow, quad_enc_mov_backward, timer_16bit_count的声明及其所有用途和初始化。 -
@chux:不,我们不需要 MVCE。这个问题已经得到了充分的描述并且是经典的。
标签: c embedded microcontroller